aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2007-09-19 20:18:51 +0000
committerDevang Patel <dpatel@apple.com>2007-09-19 20:18:51 +0000
commitf8209dfca17528382d928118307c2fe3b833ab9d (patch)
tree2872fdb290cab0399ba44fe2e73d555c39771df2 /lib
parent59a99138b49f1e1155d78fba30b71b2a28c50754 (diff)
downloadexternal_llvm-f8209dfca17528382d928118307c2fe3b833ab9d.tar.gz
external_llvm-f8209dfca17528382d928118307c2fe3b833ab9d.tar.bz2
external_llvm-f8209dfca17528382d928118307c2fe3b833ab9d.zip
Avoid unsafe promotion.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42149 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Scalar/LICM.cpp50
1 files changed, 41 insertions, 9 deletions
diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp
index 6c5976ad3a..3058f74aab 100644
--- a/lib/Transforms/Scalar/LICM.cpp
+++ b/lib/Transforms/Scalar/LICM.cpp
@@ -759,15 +759,24 @@ void LICM::PromoteValuesInLoop() {
}
/// FindPromotableValuesInLoop - Check the current loop for stores to definite
-/// pointers, which are not loaded and stored through may aliases. If these are
-/// found, create an alloca for the value, add it to the PromotedValues list,
-/// and keep track of the mapping from value to alloca.
-///
+/// pointers, which are not loaded and stored through may aliases and are safe
+/// for promotion. If these are found, create an alloca for the value, add it
+/// to the PromotedValues list, and keep track of the mapping from value to
+/// alloca.
void LICM::FindPromotableValuesInLoop(
std::vector<std::pair<AllocaInst*, Value*> > &PromotedValues,
std::map<Value*, AllocaInst*> &ValueToAllocaMap) {
Instruction *FnStart = CurLoop->getHeader()->getParent()->begin()->begin();
+ SmallVector<Instruction *, 4> LoopExits;
+ SmallVector<BasicBlock *, 4> Blocks;
+ CurLoop->getExitingBlocks(Blocks);
+ for (SmallVector<BasicBlock *, 4>::iterator BI = Blocks.begin(),
+ BE = Blocks.end(); BI != BE; ++BI) {
+ BasicBlock *BB = *BI;
+ LoopExits.push_back(BB->getTerminator());
+ }
+
// Loop over all of the alias sets in the tracker object.
for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end();
I != E; ++I) {
@@ -791,14 +800,37 @@ void LICM::FindPromotableValuesInLoop(
break;
}
- // If GEP base is NULL then the calculated address used by Store or
- // Load instruction is invalid. Do not promote this value because
- // it may expose load and store instruction that are covered by
- // condition which may not yet folded.
- if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V))
+ if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
+ // If GEP base is NULL then the calculated address used by Store or
+ // Load instruction is invalid. Do not promote this value because
+ // it may expose load and store instruction that are covered by
+ // condition which may not yet folded.
if (isa<ConstantPointerNull>(GEP->getOperand(0)))
PointerOk = false;
+ // If GEP is use is not dominating loop exit then promoting
+ // GEP may expose unsafe load and store instructions unconditinally.
+ if (PointerOk)
+ for(Value::use_iterator UI = V->use_begin(), UE = V->use_end();
+ UI != UE && PointerOk; ++UI) {
+ Instruction *Use = dyn_cast<Instruction>(*UI);
+ if (!Use)
+ continue;
+ for (SmallVector<Instruction *, 4>::iterator
+ ExitI = LoopExits.begin(), ExitE = LoopExits.end();
+ ExitI != ExitE; ++ExitI) {
+ Instruction *Ex = *ExitI;
+ if (!DT->dominates(Use, Ex)){
+ PointerOk = false;
+ break;
+ }
+ }
+
+ if (!PointerOk)
+ break;
+ }
+ }
+
if (PointerOk) {
const Type *Ty = cast<PointerType>(V->getType())->getElementType();
AllocaInst *AI = new AllocaInst(Ty, 0, V->getName()+".tmp", FnStart);