1 //===- StripGCRelocates.cpp - Remove gc.relocates inserted by RewriteStatePoints===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This is a little utility pass that removes the gc.relocates inserted by 10 // RewriteStatepointsForGC. Note that the generated IR is incorrect, 11 // but this is useful as a single pass in itself, for analysis of IR, without 12 // the GC.relocates. The statepoint and gc.result intrinsics would still be 13 // present. 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/Transforms/Utils/StripGCRelocates.h" 17 #include "llvm/IR/Function.h" 18 #include "llvm/IR/InstIterator.h" 19 #include "llvm/IR/Instructions.h" 20 #include "llvm/IR/Statepoint.h" 21 22 using namespace llvm; 23 24 static bool stripGCRelocates(Function &F) { 25 // Nothing to do for declarations. 26 if (F.isDeclaration()) 27 return false; 28 SmallVector<GCRelocateInst *, 20> GCRelocates; 29 // TODO: We currently do not handle gc.relocates that are in landing pads, 30 // i.e. not bound to a single statepoint token. 31 for (Instruction &I : instructions(F)) { 32 if (auto *GCR = dyn_cast<GCRelocateInst>(&I)) 33 if (isa<GCStatepointInst>(GCR->getOperand(0))) 34 GCRelocates.push_back(GCR); 35 } 36 // All gc.relocates are bound to a single statepoint token. The order of 37 // visiting gc.relocates for deletion does not matter. 38 for (GCRelocateInst *GCRel : GCRelocates) { 39 Value *OrigPtr = GCRel->getDerivedPtr(); 40 Value *ReplaceGCRel = OrigPtr; 41 42 // All gc_relocates are i8 addrspace(1)* typed, we need a bitcast from i8 43 // addrspace(1)* to the type of the OrigPtr, if the are not the same. 44 if (GCRel->getType() != OrigPtr->getType()) 45 ReplaceGCRel = new BitCastInst(OrigPtr, GCRel->getType(), "cast", GCRel); 46 47 // Replace all uses of gc.relocate and delete the gc.relocate 48 // There maybe unncessary bitcasts back to the OrigPtr type, an instcombine 49 // pass would clear this up. 50 GCRel->replaceAllUsesWith(ReplaceGCRel); 51 GCRel->eraseFromParent(); 52 } 53 return !GCRelocates.empty(); 54 } 55 56 PreservedAnalyses StripGCRelocates::run(Function &F, 57 FunctionAnalysisManager &AM) { 58 if (!stripGCRelocates(F)) 59 return PreservedAnalyses::all(); 60 61 // Removing gc.relocate preserves the CFG, but most other analysis probably 62 // need to re-run. 63 PreservedAnalyses PA; 64 PA.preserveSet<CFGAnalyses>(); 65 return PA; 66 } 67