diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/BuiltinGCs.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GCRootLowering.cpp | 79 |
2 files changed, 33 insertions, 50 deletions
diff --git a/llvm/lib/CodeGen/BuiltinGCs.cpp b/llvm/lib/CodeGen/BuiltinGCs.cpp index 8b33b50943a..1b1b683904b 100644 --- a/llvm/lib/CodeGen/BuiltinGCs.cpp +++ b/llvm/lib/CodeGen/BuiltinGCs.cpp @@ -28,7 +28,6 @@ namespace { class ErlangGC : public GCStrategy { public: ErlangGC() { - InitRoots = false; NeededSafePoints = 1 << GC::PostCall; UsesMetadata = true; CustomRoots = false; @@ -57,7 +56,6 @@ public: class ShadowStackGC : public GCStrategy { public: ShadowStackGC() { - InitRoots = true; CustomRoots = true; } }; @@ -74,7 +72,6 @@ public: UseStatepoints = true; // These options are all gc.root specific, we specify them so that the // gc.root lowering code doesn't run. - InitRoots = false; NeededSafePoints = 0; UsesMetadata = false; CustomRoots = false; @@ -108,7 +105,6 @@ public: UseStatepoints = true; // These options are all gc.root specific, we specify them so that the // gc.root lowering code doesn't run. - InitRoots = false; NeededSafePoints = 0; UsesMetadata = false; CustomRoots = false; diff --git a/llvm/lib/CodeGen/GCRootLowering.cpp b/llvm/lib/CodeGen/GCRootLowering.cpp index 31ddeadbd97..8e8917664af 100644 --- a/llvm/lib/CodeGen/GCRootLowering.cpp +++ b/llvm/lib/CodeGen/GCRootLowering.cpp @@ -38,7 +38,7 @@ namespace { /// directed by the GCStrategy. It also performs automatic root initialization /// and custom intrinsic lowering. class LowerIntrinsics : public FunctionPass { - bool PerformDefaultLowering(Function &F, GCStrategy &S); + bool DoLowering(Function &F, GCStrategy &S); public: static char ID; @@ -102,13 +102,6 @@ void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const { AU.addPreserved<DominatorTreeWrapperPass>(); } -static bool 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(); -} - /// doInitialization - If this module uses the GC intrinsics, find them now. bool LowerIntrinsics::doInitialization(Module &M) { GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); @@ -188,19 +181,17 @@ bool LowerIntrinsics::runOnFunction(Function &F) { GCFunctionInfo &FI = getAnalysis<GCModuleInfo>().getFunctionInfo(F); GCStrategy &S = FI.getStrategy(); - bool MadeChange = false; - - if (NeedsDefaultLoweringPass(S)) - MadeChange |= PerformDefaultLowering(F, S); - - return MadeChange; + return DoLowering(F, S); } -bool LowerIntrinsics::PerformDefaultLowering(Function &F, GCStrategy &S) { - bool LowerWr = !S.customWriteBarrier(); - bool LowerRd = !S.customReadBarrier(); - bool InitRoots = S.initializeRoots(); - +/// Lower barriers out of existance (if the associated GCStrategy hasn't +/// already done so...), and insert initializing stores to roots as a defensive +/// measure. Given we're going to report all roots live at all safepoints, we +/// need to be able to ensure each root has been initialized by the point the +/// first safepoint is reached. This really should have been done by the +/// frontend, but the old API made this non-obvious, so we do a potentially +/// redundant store just in case. +bool LowerIntrinsics::DoLowering(Function &F, GCStrategy &S) { SmallVector<AllocaInst *, 32> Roots; bool MadeChange = false; @@ -209,37 +200,33 @@ bool LowerIntrinsics::PerformDefaultLowering(Function &F, GCStrategy &S) { 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(); - } + default: break; + case Intrinsic::gcwrite: { + // Replace a write barrier with a simple store. + Value *St = new StoreInst(CI->getArgOperand(0), + CI->getArgOperand(2), CI); + CI->replaceAllUsesWith(St); + CI->eraseFromParent(); + MadeChange = true; 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(); - } + } + case Intrinsic::gcread: { + // Replace a read barrier with a simple load. + Value *Ld = new LoadInst(CI->getArgOperand(1), "", CI); + Ld->takeName(CI); + CI->replaceAllUsesWith(Ld); + CI->eraseFromParent(); + MadeChange = true; 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. - Roots.push_back( - cast<AllocaInst>(CI->getArgOperand(0)->stripPointerCasts())); - } + } + case Intrinsic::gcroot: { + // Initialize the GC root, but do not delete the intrinsic. The + // backend needs the intrinsic to flag the stack slot. + Roots.push_back( + cast<AllocaInst>(CI->getArgOperand(0)->stripPointerCasts())); break; - default: - continue; } - - MadeChange = true; + } } } } |