llvm.org GIT mirror llvm / a6c9925
Use getIntrinsicID instead of looking up intrinsic prototypes. Also fixes a bug with indirect calls. (Test case will be included with ocaml collector patch.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45316 91177308-0d34-0410-b5e6-96231b3b80d8 Gordon Henriksen 12 years ago
1 changed file(s) with 29 addition(s) and 28 deletion(s). Raw diff Collapse all Expand all
3434 /// directed by the Collector. It also performs automatic root initialization
3535 /// and custom intrinsic lowering.
3636 class VISIBILITY_HIDDEN LowerIntrinsics : public FunctionPass {
37 /// GCRootInt, GCReadInt, GCWriteInt - The function prototypes for the
38 /// llvm.gc* intrinsics.
39 Function *GCRootInt, *GCReadInt, *GCWriteInt;
40
4137 static bool NeedsDefaultLoweringPass(const Collector &C);
4238 static bool NeedsCustomLoweringPass(const Collector &C);
4339 static bool CouldBecomeSafePoint(Instruction *I);
137133 char LowerIntrinsics::ID = 0;
138134
139135 LowerIntrinsics::LowerIntrinsics()
140 : FunctionPass((intptr_t)&ID),
141 GCRootInt(0), GCReadInt(0), GCWriteInt(0) {}
136 : FunctionPass((intptr_t)&ID) {}
142137
143138 const char *LowerIntrinsics::getPassName() const {
144139 return "Lower Garbage Collection Instructions";
151146
152147 /// doInitialization - If this module uses the GC intrinsics, find them now.
153148 bool LowerIntrinsics::doInitialization(Module &M) {
154 GCReadInt = M.getFunction("llvm.gcread");
155 GCWriteInt = M.getFunction("llvm.gcwrite");
156 GCRootInt = M.getFunction("llvm.gcroot");
157
158149 // FIXME: This is rather antisocial in the context of a JIT since it performs
159150 // work against the entire module. But this cannot be done at
160151 // runFunction time (initializeCustomLowering likely needs to change
276267 bool MadeChange = false;
277268 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
278269 for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) {
279 if (CallInst *CI = dyn_castInst>(II++)) {
270 if (IntrinsicInst *CI = dyn_castInst>(II++)) {
280271 Function *F = CI->getCalledFunction();
281 if (F == GCWriteInt && LowerWr) {
282 // Replace a write barrier with a simple store.
283 Value *St = new StoreInst(CI->getOperand(1), CI->getOperand(3), CI);
284 CI->replaceAllUsesWith(St);
285 CI->eraseFromParent();
286 } else if (F == GCReadInt && LowerRd) {
287 // Replace a read barrier with a simple load.
288 Value *Ld = new LoadInst(CI->getOperand(2), "", CI);
289 Ld->takeName(CI);
290 CI->replaceAllUsesWith(Ld);
291 CI->eraseFromParent();
292 } else if (F == GCRootInt && InitRoots) {
293 // Initialize the GC root, but do not delete the intrinsic. The
294 // backend needs the intrinsic to flag the stack slot.
295 Roots.push_back(cast(
296 IntrinsicInst::StripPointerCasts(CI->getOperand(1))));
297 } else {
272 switch (F->getIntrinsicID()) {
273 case Intrinsic::gcwrite:
274 if (LowerWr) {
275 // Replace a write barrier with a simple store.
276 Value *St = new StoreInst(CI->getOperand(1), CI->getOperand(3), CI);
277 CI->replaceAllUsesWith(St);
278 CI->eraseFromParent();
279 }
280 break;
281 case Intrinsic::gcread:
282 if (LowerRd) {
283 // Replace a read barrier with a simple load.
284 Value *Ld = new LoadInst(CI->getOperand(2), "", CI);
285 Ld->takeName(CI);
286 CI->replaceAllUsesWith(Ld);
287 CI->eraseFromParent();
288 }
289 break;
290 case Intrinsic::gcroot:
291 if (InitRoots) {
292 // Initialize the GC root, but do not delete the intrinsic. The
293 // backend needs the intrinsic to flag the stack slot.
294 Roots.push_back(cast(
295 IntrinsicInst::StripPointerCasts(CI->getOperand(1))));
296 }
297 break;
298 default:
298299 continue;
299300 }
300301