bool LowerIntrinsics::NeedsDefaultLoweringPass(const GCStrategy &C) { // Default lowering is necessary only if read or write barriers have a default // action. The default for roots is no action. return !C.customWriteBarrier() || !C.customReadBarrier() || C.initializeRoots(); }
bool LowerIntrinsics::PerformDefaultLowering(Function &F, GCStrategy &S) { InsertAutomaticGCRoots(F, S); // FIXME: Turn this back on after fixing gcregroot in SelectionDAG. //InsertGCRegisterRoots(F, S); bool LowerWr = !S.customWriteBarrier(); bool LowerRd = !S.customReadBarrier(); bool InitRoots = S.initializeRoots(); SmallVector<Instruction *, 32> Roots; bool MadeChange = false; for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE; ++BB) { for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE;) { if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++)) { Function *F = CI->getCalledFunction(); switch (F->getIntrinsicID()) { case Intrinsic::gcwrite: if (LowerWr) { // Replace a write barrier with a simple store. Value *St = new StoreInst(CI->getArgOperand(0), CI->getArgOperand(2), CI); CI->replaceAllUsesWith(St); CI->eraseFromParent(); } break; case Intrinsic::gcread: if (LowerRd) { // Replace a read barrier with a simple load. Value *Ld = new LoadInst(CI->getArgOperand(1), "", CI); Ld->takeName(CI); CI->replaceAllUsesWith(Ld); CI->eraseFromParent(); } break; case Intrinsic::gcroot: if (InitRoots) { // Initialize the GC root, but do not delete the intrinsic. The // backend needs the intrinsic to flag the stack slot. Value *V = CI->getArgOperand(0)->stripPointerCastsOnly(); Roots.push_back(cast<Instruction>(V)); } break; default: continue; } MadeChange = true; } } } if (Roots.size()) MadeChange |= InsertRootInitializers(F, Roots.begin(), Roots.size()); return MadeChange; }
GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) { assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!"); assert(F.hasGC()); finfo_map_type::iterator I = FInfoMap.find(&F); if (I != FInfoMap.end()) return *I->second; GCStrategy *S = getOrCreateStrategy(F.getParent(), F.getGC()); GCFunctionInfo *GFI = S->insertFunctionInfo(F); FInfoMap[&F] = GFI; return *GFI; }
void LowerIntrinsics::InsertAutomaticGCRoots(Function &F, GCStrategy &S) { if (!S.usesAutomaticRoots()) return; LLVMContext &C = F.getParent()->getContext(); for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) { for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE; ++II) { AllocaInst *AI = dyn_cast<AllocaInst>(&*II); if (!AI) continue; Value *Index = ConstantInt::get(Type::getInt32Ty(C), 0); ArrayRef<Value *> Indices(&Index, 1); AutomaticallyRootValue(*AI, AI->getAllocatedType(), Indices); } } }
bool LowerIntrinsics::NeedsCustomLoweringPass(const GCStrategy &C) { // Custom lowering is only necessary if enabled for some action. return C.customWriteBarrier() || C.customReadBarrier() || C.customRoots(); }