diff options
| author | Philip Reames <listmail@philipreames.com> | 2015-04-26 19:48:03 +0000 |
|---|---|---|
| committer | Philip Reames <listmail@philipreames.com> | 2015-04-26 19:48:03 +0000 |
| commit | 63294cbb6a2bc9a48aa2367e61136b13ab1ac12d (patch) | |
| tree | 81462744b76fd93bdfb6bc343e2c3f11ac065b80 /llvm/lib/Transforms/Scalar | |
| parent | 2e78fa49a82c496a0701b996bacf2868204bef64 (diff) | |
| download | bcm5719-llvm-63294cbb6a2bc9a48aa2367e61136b13ab1ac12d.tar.gz bcm5719-llvm-63294cbb6a2bc9a48aa2367e61136b13ab1ac12d.zip | |
[RewriteStatepointsForGC] Exclude constant values from being considered live at a safepoint
There can be various constant pointers in the IR which do not get relocated at a safepoint. One example is the address of a global variable. Another example is a pointer created via inttoptr. Note that the optimizer itself likes to create such inttoptrs when locally propagating constants through dynamically dead code.
To deal with this, we need to exclude uses of constants from contributing to the liveness of a safepoint which might reach that use. At some later date, it might be worth exploring what could be done to support the relocation of various special types of "constants", but that's future work.
Differential Revision: http://reviews.llvm.org/D9236
llvm-svn: 235821
Diffstat (limited to 'llvm/lib/Transforms/Scalar')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp index ba48e0a74b0..3da3559ca1f 100644 --- a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -1504,9 +1504,7 @@ static void relocationViaAlloca( store->insertAfter(inst); } } else { - assert((isa<Argument>(def) || isa<GlobalVariable>(def) || - isa<ConstantPointerNull>(def)) && - "Must be argument or global"); + assert(isa<Argument>(def)); store->insertAfter(cast<Instruction>(alloca)); } } @@ -1958,11 +1956,6 @@ bool RewriteStatepointsForGC::runOnFunction(Function &F) { // TODO: Consider using bitvectors for liveness, the set of potentially // interesting values should be small and easy to pre-compute. -/// Is this value a constant consisting of entirely null values? -static bool isConstantNull(Value *V) { - return isa<Constant>(V) && cast<Constant>(V)->isNullValue(); -} - /// Compute the live-in set for the location rbegin starting from /// the live-out set of the basic block static void computeLiveInValues(BasicBlock::reverse_iterator rbegin, @@ -1984,9 +1977,17 @@ static void computeLiveInValues(BasicBlock::reverse_iterator rbegin, for (Value *V : I->operands()) { assert(!isUnhandledGCPointerType(V->getType()) && "support for FCA unimplemented"); - if (isHandledGCPointerType(V->getType()) && !isConstantNull(V) && - !isa<UndefValue>(V)) { - // The choice to exclude null and undef is arbitrary here. Reconsider? + if (isHandledGCPointerType(V->getType()) && !isa<Constant>(V)) { + // The choice to exclude all things constant here is slightly subtle. + // There are two idependent reasons: + // - We assume that things which are constant (from LLVM's definition) + // do not move at runtime. For example, the address of a global + // variable is fixed, even though it's contents may not be. + // - Second, we can't disallow arbitrary inttoptr constants even + // if the language frontend does. Optimization passes are free to + // locally exploit facts without respect to global reachability. This + // can create sections of code which are dynamically unreachable and + // contain just about anything. (see constants.ll in tests) LiveTmp.insert(V); } } @@ -2002,9 +2003,7 @@ static void computeLiveOutSeed(BasicBlock *BB, DenseSet<Value *> &LiveTmp) { Value *V = Phi->getIncomingValueForBlock(BB); assert(!isUnhandledGCPointerType(V->getType()) && "support for FCA unimplemented"); - if (isHandledGCPointerType(V->getType()) && !isConstantNull(V) && - !isa<UndefValue>(V)) { - // The choice to exclude null and undef is arbitrary here. Reconsider? + if (isHandledGCPointerType(V->getType()) && !isa<Constant>(V)) { LiveTmp.insert(V); } } |

