forked from OSchip/llvm-project
Probably overwritten loads should not be considered hoistable
Do not assume a load to be hoistable/invariant if the pointer is used by another instruction in the SCoP that might write to memory and that is always executed. llvm-svn: 287272
This commit is contained in:
parent
50dfbc572a
commit
6cd59e9076
|
@ -385,10 +385,11 @@ llvm::Value *getConditionFromTerminator(llvm::TerminatorInst *TI);
|
|||
/// @param R The analyzed region.
|
||||
/// @param LI The loop info.
|
||||
/// @param SE The scalar evolution analysis.
|
||||
/// @param DT The dominator tree of the function.
|
||||
///
|
||||
/// @return True if @p LInst can be hoisted in @p R.
|
||||
bool isHoistableLoad(llvm::LoadInst *LInst, llvm::Region &R, llvm::LoopInfo &LI,
|
||||
llvm::ScalarEvolution &SE);
|
||||
llvm::ScalarEvolution &SE, const llvm::DominatorTree &DT);
|
||||
|
||||
/// Return true iff @p V is an intrinsic that we ignore during code
|
||||
/// generation.
|
||||
|
|
|
@ -314,7 +314,7 @@ bool ScopDetection::onlyValidRequiredInvariantLoads(
|
|||
return false;
|
||||
|
||||
for (LoadInst *Load : RequiredILS)
|
||||
if (!isHoistableLoad(Load, CurRegion, *LI, *SE))
|
||||
if (!isHoistableLoad(Load, CurRegion, *LI, *SE, *DT))
|
||||
return false;
|
||||
|
||||
Context.RequiredILS.insert(RequiredILS.begin(), RequiredILS.end());
|
||||
|
@ -680,7 +680,7 @@ bool ScopDetection::hasValidArraySizes(DetectionContext &Context,
|
|||
auto *V = dyn_cast<Value>(Unknown->getValue());
|
||||
if (auto *Load = dyn_cast<LoadInst>(V)) {
|
||||
if (Context.CurRegion.contains(Load) &&
|
||||
isHoistableLoad(Load, CurRegion, *LI, *SE))
|
||||
isHoistableLoad(Load, CurRegion, *LI, *SE, *DT))
|
||||
Context.RequiredILS.insert(Load);
|
||||
continue;
|
||||
}
|
||||
|
@ -889,7 +889,7 @@ bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
|
|||
Instruction *Inst = dyn_cast<Instruction>(Ptr.getValue());
|
||||
if (Inst && Context.CurRegion.contains(Inst)) {
|
||||
auto *Load = dyn_cast<LoadInst>(Inst);
|
||||
if (Load && isHoistableLoad(Load, Context.CurRegion, *LI, *SE)) {
|
||||
if (Load && isHoistableLoad(Load, Context.CurRegion, *LI, *SE, *DT)) {
|
||||
Context.RequiredILS.insert(Load);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -436,15 +436,35 @@ Value *polly::getConditionFromTerminator(TerminatorInst *TI) {
|
|||
}
|
||||
|
||||
bool polly::isHoistableLoad(LoadInst *LInst, Region &R, LoopInfo &LI,
|
||||
ScalarEvolution &SE) {
|
||||
ScalarEvolution &SE, const DominatorTree &DT) {
|
||||
Loop *L = LI.getLoopFor(LInst->getParent());
|
||||
const SCEV *PtrSCEV = SE.getSCEVAtScope(LInst->getPointerOperand(), L);
|
||||
auto *Ptr = LInst->getPointerOperand();
|
||||
const SCEV *PtrSCEV = SE.getSCEVAtScope(Ptr, L);
|
||||
while (L && R.contains(L)) {
|
||||
if (!SE.isLoopInvariant(PtrSCEV, L))
|
||||
return false;
|
||||
L = L->getParentLoop();
|
||||
}
|
||||
|
||||
for (auto *User : Ptr->users()) {
|
||||
auto *UserI = dyn_cast<Instruction>(User);
|
||||
if (!UserI || !R.contains(UserI))
|
||||
continue;
|
||||
if (!UserI->mayWriteToMemory())
|
||||
continue;
|
||||
|
||||
auto &BB = *UserI->getParent();
|
||||
bool DominatesAllPredecessors = true;
|
||||
for (auto Pred : predecessors(R.getExit()))
|
||||
if (R.contains(Pred) && !DT.dominates(&BB, Pred))
|
||||
DominatesAllPredecessors = false;
|
||||
|
||||
if (!DominatesAllPredecessors)
|
||||
continue;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -385,7 +385,7 @@ if.entry: ; preds = %for.body
|
|||
%.reload153 = load i16, i16* %.reg2mem152
|
||||
%.reload151 = load i16, i16* %.reg2mem150
|
||||
%.reload = load i16, i16* %.reg2mem
|
||||
%37 = load i16, i16* %Output, align 2
|
||||
%37 = load i16, i16* %In1, align 2
|
||||
%cmp77 = icmp slt i16 %37, 128
|
||||
br i1 %cmp77, label %A0, label %B0
|
||||
|
||||
|
|
Loading…
Reference in New Issue