mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-02 17:09:05 +00:00
Avoid unsafe promotion.
llvm-svn: 42149
This commit is contained in:
parent
ec83699473
commit
648d7a1074
@ -759,15 +759,24 @@ void LICM::PromoteValuesInLoop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// FindPromotableValuesInLoop - Check the current loop for stores to definite
|
/// FindPromotableValuesInLoop - Check the current loop for stores to definite
|
||||||
/// pointers, which are not loaded and stored through may aliases. If these are
|
/// pointers, which are not loaded and stored through may aliases and are safe
|
||||||
/// found, create an alloca for the value, add it to the PromotedValues list,
|
/// for promotion. If these are found, create an alloca for the value, add it
|
||||||
/// and keep track of the mapping from value to alloca.
|
/// to the PromotedValues list, and keep track of the mapping from value to
|
||||||
///
|
/// alloca.
|
||||||
void LICM::FindPromotableValuesInLoop(
|
void LICM::FindPromotableValuesInLoop(
|
||||||
std::vector<std::pair<AllocaInst*, Value*> > &PromotedValues,
|
std::vector<std::pair<AllocaInst*, Value*> > &PromotedValues,
|
||||||
std::map<Value*, AllocaInst*> &ValueToAllocaMap) {
|
std::map<Value*, AllocaInst*> &ValueToAllocaMap) {
|
||||||
Instruction *FnStart = CurLoop->getHeader()->getParent()->begin()->begin();
|
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.
|
// Loop over all of the alias sets in the tracker object.
|
||||||
for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end();
|
for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
@ -791,14 +800,37 @@ void LICM::FindPromotableValuesInLoop(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If GEP base is NULL then the calculated address used by Store or
|
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
|
||||||
// Load instruction is invalid. Do not promote this value because
|
// If GEP base is NULL then the calculated address used by Store or
|
||||||
// it may expose load and store instruction that are covered by
|
// Load instruction is invalid. Do not promote this value because
|
||||||
// condition which may not yet folded.
|
// it may expose load and store instruction that are covered by
|
||||||
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V))
|
// condition which may not yet folded.
|
||||||
if (isa<ConstantPointerNull>(GEP->getOperand(0)))
|
if (isa<ConstantPointerNull>(GEP->getOperand(0)))
|
||||||
PointerOk = false;
|
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) {
|
if (PointerOk) {
|
||||||
const Type *Ty = cast<PointerType>(V->getType())->getElementType();
|
const Type *Ty = cast<PointerType>(V->getType())->getElementType();
|
||||||
AllocaInst *AI = new AllocaInst(Ty, 0, V->getName()+".tmp", FnStart);
|
AllocaInst *AI = new AllocaInst(Ty, 0, V->getName()+".tmp", FnStart);
|
||||||
|
@ -23,4 +23,39 @@ clear_modes.exit: ; preds = %blah.i
|
|||||||
unreachable
|
unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i32 @f(i8* %ptr) {
|
||||||
|
entry:
|
||||||
|
br label %loop.head
|
||||||
|
|
||||||
|
loop.head: ; preds = %cond.true, %entry
|
||||||
|
%x = phi i8* [ %ptr, %entry ], [ %ptr.i, %cond.true ] ; <i8*> [#uses=1]
|
||||||
|
%tmp3.i = icmp ne i8* %ptr, %x ; <i1> [#uses=1]
|
||||||
|
br i1 %tmp3.i, label %cond.true, label %exit
|
||||||
|
|
||||||
|
cond.true: ; preds = %loop.head
|
||||||
|
%ptr.i = getelementptr i8* %ptr, i32 0 ; <i8*> [#uses=2]
|
||||||
|
store i8 0, i8* %ptr.i
|
||||||
|
br label %loop.head
|
||||||
|
|
||||||
|
exit: ; preds = %loop.head
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @f2(i8* %p, i8* %q) {
|
||||||
|
entry:
|
||||||
|
br label %loop.head
|
||||||
|
|
||||||
|
loop.head: ; preds = %cond.true, %entry
|
||||||
|
%tmp3.i = icmp eq i8* null, %q ; <i1> [#uses=1]
|
||||||
|
br i1 %tmp3.i, label %exit, label %cond.true
|
||||||
|
|
||||||
|
cond.true: ; preds = %loop.head
|
||||||
|
%ptr.i = getelementptr i8* %p, i32 0 ; <i8*> [#uses=2]
|
||||||
|
store i8 0, i8* %ptr.i
|
||||||
|
br label %loop.head
|
||||||
|
|
||||||
|
exit: ; preds = %loop.head
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
declare void @exit(i32)
|
declare void @exit(i32)
|
||||||
|
Loading…
Reference in New Issue
Block a user