summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/BuiltinGCs.cpp4
-rw-r--r--llvm/lib/CodeGen/GCRootLowering.cpp79
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;
+ }
}
}
}
OpenPOWER on IntegriCloud