aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2012-02-17 06:59:21 +0000
committerNick Lewycky <nicholas@mxc.ca>2012-02-17 06:59:21 +0000
commit81266c5c9358d71331886a98e750ac9409cc640c (patch)
tree70d61056257c6a311e8353773fef542a13adf21f /lib
parent38bdc5762f58b64d652864d154bf1b4dffb5ed39 (diff)
downloadexternal_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.cpp59
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'