diff options
author | Chris Lattner <sabre@nondot.org> | 2008-05-22 03:22:42 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-05-22 03:22:42 +0000 |
commit | 19d9d4364e514f316f8757b577bb8bb33c22dbfc (patch) | |
tree | 5a3937d493e57aa5834b945d27c16957942c9b32 | |
parent | 64a4c11e2fe39624353a8f1789c5d9b635fe7272 (diff) |
rewrite the validity checking for memory promotion to be simpler,
more aggressive, and more correct. Verify that we only attempt to
promote loads and stores.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51406 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/LICM.cpp | 101 |
1 files changed, 52 insertions, 49 deletions
diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp index 8ebe2b6812..e227713d4e 100644 --- a/lib/Transforms/Scalar/LICM.cpp +++ b/lib/Transforms/Scalar/LICM.cpp @@ -726,30 +726,32 @@ void LICM::PromoteValuesInLoop() { // want to insert one copy of the code in each exit block, though the loop may // exit to the same block more than once. // - std::set<BasicBlock*> ProcessedBlocks; + SmallPtrSet<BasicBlock*, 16> ProcessedBlocks; SmallVector<BasicBlock*, 8> ExitBlocks; CurLoop->getExitBlocks(ExitBlocks); - for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) - if (ProcessedBlocks.insert(ExitBlocks[i]).second) { - // Copy all of the allocas into their memory locations. - BasicBlock::iterator BI = ExitBlocks[i]->begin(); - while (isa<PHINode>(*BI)) - ++BI; // Skip over all of the phi nodes in the block. - Instruction *InsertPos = BI; - unsigned PVN = 0; - for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i) { - // Load from the alloca. - LoadInst *LI = new LoadInst(PromotedValues[i].first, "", InsertPos); - - // If this is a pointer type, update alias info appropriately. - if (isa<PointerType>(LI->getType())) - CurAST->copyValue(PointerValueNumbers[PVN++], LI); - - // Store into the memory we promoted. - new StoreInst(LI, PromotedValues[i].second, InsertPos); - } + for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) { + if (!ProcessedBlocks.insert(ExitBlocks[i])) + continue; + + // Copy all of the allocas into their memory locations. + BasicBlock::iterator BI = ExitBlocks[i]->begin(); + while (isa<PHINode>(*BI)) + ++BI; // Skip over all of the phi nodes in the block. + Instruction *InsertPos = BI; + unsigned PVN = 0; + for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i) { + // Load from the alloca. + LoadInst *LI = new LoadInst(PromotedValues[i].first, "", InsertPos); + + // If this is a pointer type, update alias info appropriately. + if (isa<PointerType>(LI->getType())) + CurAST->copyValue(PointerValueNumbers[PVN++], LI); + + // Store into the memory we promoted. + new StoreInst(LI, PromotedValues[i].second, InsertPos); } + } // Now that we have done the deed, use the mem2reg functionality to promote // all of the new allocas we just created into real SSA registers. @@ -771,14 +773,8 @@ void LICM::FindPromotableValuesInLoop( 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()); - } + SmallVector<BasicBlock*, 4> ExitingBlocks; + CurLoop->getExitingBlocks(ExitingBlocks); // Loop over all of the alias sets in the tracker object. for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end(); @@ -809,34 +805,41 @@ void LICM::FindPromotableValuesInLoop( continue; } - // If one use of value V inside the loop is safe then it is OK to promote - // this value. On the otherside if there is not any unsafe use inside the - // loop then also it is OK to promote this value. Otherwise it is - // unsafe to promote this value. - bool oneSafeUse = false; - bool oneUnsafeUse = false; - for(Value::use_iterator UI = V->use_begin(), UE = V->use_end(); - UI != UE; ++UI) { + // It isn't safe to promote a load/store from the loop if the load/store is + // conditional. For example, turning: + // + // for () { if (c) *P += 1; } + // + // into: + // + // tmp = *P; for () { if (c) tmp +=1; } *P = tmp; + // + // is not safe, because *P may only be valid to access if 'c' is true. + // + // It is safe to promote P if all uses are direct load/stores and if at + // least one is guaranteed to be executed. + bool GuaranteedToExecute = false; + bool InvalidInst = false; + for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); + UI != UE; ++UI) { + // Ignore instructions not in this loop. Instruction *Use = dyn_cast<Instruction>(*UI); if (!Use || !CurLoop->contains(Use->getParent())) continue; - - for (SmallVector<Instruction *, 4>::iterator - ExitI = LoopExits.begin(), ExitE = LoopExits.end(); - ExitI != ExitE; ++ExitI) { - Instruction *Ex = *ExitI; - if (!isa<PHINode>(Use) && DT->dominates(Use, Ex)) { - oneSafeUse = true; - break; - } else - oneUnsafeUse = true; - } - if (oneSafeUse) + if (!isa<LoadInst>(Use) && !isa<StoreInst>(Use)) { + InvalidInst = true; break; + } + + if (!GuaranteedToExecute) + GuaranteedToExecute = isSafeToExecuteUnconditionally(*Use); } - if (!oneSafeUse && oneUnsafeUse) + // If there is an non-load/store instruction in the loop, we can't promote + // it. If there isn't a guaranteed-to-execute instruction, we can't + // promote. + if (InvalidInst || !GuaranteedToExecute) continue; const Type *Ty = cast<PointerType>(V->getType())->getElementType(); |