diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2012-02-17 06:59:21 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2012-02-17 06:59:21 +0000 |
commit | 81266c5c9358d71331886a98e750ac9409cc640c (patch) | |
tree | 70d61056257c6a311e8353773fef542a13adf21f /lib | |
parent | 38bdc5762f58b64d652864d154bf1b4dffb5ed39 (diff) | |
download | external_llvm-81266c5c9358d71331886a98e750ac9409cc640c.zip external_llvm-81266c5c9358d71331886a98e750ac9409cc640c.tar.gz external_llvm-81266c5c9358d71331886a98e750ac9409cc640c.tar.bz2 |
Add support for invariant.start inside the static constructor evaluator. This is
useful to represent a variable that is const in the source but can't be constant
in the IR because of a non-trivial constructor. If globalopt evaluates the
constructor, and there was an invariant.start with no matching invariant.end
possible, it will mark the global constant afterwards.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150794 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/IPO/GlobalOpt.cpp | 59 |
1 files changed, 47 insertions, 12 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index d959a22..f395176 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -2295,6 +2295,7 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal, DenseMap<Constant*, Constant*> &MutatedMemory, std::vector<GlobalVariable*> &AllocaTmps, SmallPtrSet<Constant*, 8> &SimpleConstants, + SmallPtrSet<GlobalVariable*, 8> &Invariants, const TargetData *TD, const TargetLibraryInfo *TLI); @@ -2307,6 +2308,7 @@ static bool EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB, DenseMap<Constant*, Constant*> &MutatedMemory, std::vector<GlobalVariable*> &AllocaTmps, SmallPtrSet<Constant*, 8> &SimpleConstants, + SmallPtrSet<GlobalVariable*, 8> &Invariants, const TargetData *TD, const TargetLibraryInfo *TLI) { // This is the main evaluation loop. @@ -2415,14 +2417,39 @@ static bool EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB, // Cannot handle inline asm. if (isa<InlineAsm>(CS.getCalledValue())) return false; - if (MemSetInst *MSI = dyn_cast<MemSetInst>(CS.getInstruction())) { - if (MSI->isVolatile()) return false; - Constant *Ptr = getVal(Values, MSI->getDest()); - Constant *Val = getVal(Values, MSI->getValue()); - Constant *DestVal = ComputeLoadResult(getVal(Values, Ptr), - MutatedMemory); - if (Val->isNullValue() && DestVal && DestVal->isNullValue()) { - // This memset is a no-op. + if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) { + if (MemSetInst *MSI = dyn_cast<MemSetInst>(II)) { + if (MSI->isVolatile()) return false; + Constant *Ptr = getVal(Values, MSI->getDest()); + Constant *Val = getVal(Values, MSI->getValue()); + Constant *DestVal = ComputeLoadResult(getVal(Values, Ptr), + MutatedMemory); + if (Val->isNullValue() && DestVal && DestVal->isNullValue()) { + // This memset is a no-op. + ++CurInst; + continue; + } + } + + if (II->getIntrinsicID() == Intrinsic::lifetime_start || + II->getIntrinsicID() == Intrinsic::lifetime_end) { + ++CurInst; + continue; + } + + if (II->getIntrinsicID() == Intrinsic::invariant_start) { + // We don't insert an entry into Values, as it doesn't have a + // meaningful return value. + if (!II->use_empty()) + return false; + ConstantInt *Size = cast<ConstantInt>(II->getArgOperand(0)); + if (Size->isAllOnesValue()) { + Value *PtrArg = getVal(Values, II->getArgOperand(1)); + Value *Ptr = PtrArg->stripPointerCasts(); + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Ptr)) + Invariants.insert(GV); + } + // Continue even if we do nothing. ++CurInst; continue; } @@ -2453,8 +2480,8 @@ static bool EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB, Constant *RetVal; // Execute the call, if successful, use the return value. if (!EvaluateFunction(Callee, RetVal, Formals, CallStack, - MutatedMemory, AllocaTmps, SimpleConstants, TD, - TLI)) + MutatedMemory, AllocaTmps, SimpleConstants, + Invariants, TD, TLI)) return false; InstResult = RetVal; @@ -2521,6 +2548,7 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal, DenseMap<Constant*, Constant*> &MutatedMemory, std::vector<GlobalVariable*> &AllocaTmps, SmallPtrSet<Constant*, 8> &SimpleConstants, + SmallPtrSet<GlobalVariable*, 8> &Invariants, const TargetData *TD, const TargetLibraryInfo *TLI) { // Check to see if this function is already executing (recursion). If so, @@ -2552,7 +2580,7 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal, while (1) { BasicBlock *NextBB; if (!EvaluateBlock(CurInst, NextBB, CallStack, Values, MutatedMemory, - AllocaTmps, SimpleConstants, TD, TLI)) + AllocaTmps, SimpleConstants, Invariants, TD, TLI)) return false; if (NextBB == 0) { @@ -2607,12 +2635,16 @@ static bool EvaluateStaticConstructor(Function *F, const TargetData *TD, // simple enough to live in a static initializer of a global. SmallPtrSet<Constant*, 8> SimpleConstants; + // Invariants - These global variables have been marked invariant by the + // static constructor. + SmallPtrSet<GlobalVariable*, 8> Invariants; + // Call the function. Constant *RetValDummy; bool EvalSuccess = EvaluateFunction(F, RetValDummy, SmallVector<Constant*, 0>(), CallStack, MutatedMemory, AllocaTmps, - SimpleConstants, TD, TLI); + SimpleConstants, Invariants, TD, TLI); if (EvalSuccess) { // We succeeded at evaluation: commit the result. @@ -2622,6 +2654,9 @@ static bool EvaluateStaticConstructor(Function *F, const TargetData *TD, for (DenseMap<Constant*, Constant*>::iterator I = MutatedMemory.begin(), E = MutatedMemory.end(); I != E; ++I) CommitValueTo(I->second, I->first); + for (SmallPtrSet<GlobalVariable*, 8>::iterator I = Invariants.begin(), + E = Invariants.end(); I != E; ++I) + (*I)->setConstant(true); } // At this point, we are done interpreting. If we created any 'alloca' |