1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

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.

llvm-svn: 51406
This commit is contained in:
Chris Lattner 2008-05-22 03:22:42 +00:00
parent f2a62165ee
commit fd83f89e21

View File

@ -726,12 +726,14 @@ 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) {
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))
@ -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();
// 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 (!oneSafeUse && oneUnsafeUse)
if (!GuaranteedToExecute)
GuaranteedToExecute = isSafeToExecuteUnconditionally(*Use);
}
// 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();