}
}
+static MemoryAccess *getClobberingMemoryAccess(MemorySSA &MSSA,
+ BatchAAResults &BAA,
+ SinkAndHoistLICMFlags &Flags,
+ MemoryUseOrDef *MA) {
+ // See declaration of SetLicmMssaOptCap for usage details.
+ if (Flags.tooManyClobberingCalls())
+ return MA->getDefiningAccess();
+
+ MemoryAccess *Source =
+ MSSA.getSkipSelfWalker()->getClobberingMemoryAccess(MA, BAA);
+ Flags.incrementClobberingCalls();
+ return Source;
+}
+
bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
Loop *CurLoop, MemorySSAUpdater &MSSAU,
bool TargetExecutesOncePerLoop,
// arbitrary number of reads in the loop.
if (isOnlyMemoryAccess(SI, CurLoop, MSSAU))
return true;
- // If there are more accesses than the Promotion cap or no "quota" to
- // check clobber, then give up as we're not walking a list that long.
- if (Flags.tooManyMemoryAccesses() || Flags.tooManyClobberingCalls())
+ // If there are more accesses than the Promotion cap, then give up as we're
+ // not walking a list that long.
+ if (Flags.tooManyMemoryAccesses())
+ return false;
+
+ auto *SIMD = MSSA->getMemoryAccess(SI);
+ BatchAAResults BAA(*AA);
+ auto *Source = getClobberingMemoryAccess(*MSSA, BAA, Flags, SIMD);
+ // Make sure there are no clobbers inside the loop.
+ if (!MSSA->isLiveOnEntryDef(Source) &&
+ CurLoop->contains(Source->getBlock()))
return false;
+
// If there are interfering Uses (i.e. their defining access is in the
// loop), or ordered loads (stored as Defs!), don't move this store.
// Could do better here, but this is conservatively correct.
// TODO: Cache set of Uses on the first walk in runOnLoop, update when
// moving accesses. Can also extend to dominating uses.
- auto *SIMD = MSSA->getMemoryAccess(SI);
for (auto *BB : CurLoop->getBlocks())
if (auto *Accesses = MSSA->getBlockAccesses(BB)) {
for (const auto &MA : *Accesses)
// Check if the call may read from the memory location written
// to by SI. Check CI's attributes and arguments; the number of
// such checks performed is limited above by NoOfMemAccTooLarge.
- ModRefInfo MRI = AA->getModRefInfo(CI, MemoryLocation::get(SI));
+ ModRefInfo MRI = BAA.getModRefInfo(CI, MemoryLocation::get(SI));
if (isModOrRefSet(MRI))
return false;
}
}
}
- auto *Source = MSSA->getSkipSelfWalker()->getClobberingMemoryAccess(SI);
- Flags.incrementClobberingCalls();
- // If there are no clobbering Defs in the loop, store is safe to hoist.
- return MSSA->isLiveOnEntryDef(Source) ||
- !CurLoop->contains(Source->getBlock());
+ return true;
}
assert(!I.mayReadOrWriteMemory() && "unhandled aliasing");
bool InvariantGroup) {
// For hoisting, use the walker to determine safety
if (!Flags.getIsSink()) {
- MemoryAccess *Source;
- // See declaration of SetLicmMssaOptCap for usage details.
- if (Flags.tooManyClobberingCalls())
- Source = MU->getDefiningAccess();
- else {
- Source = MSSA->getSkipSelfWalker()->getClobberingMemoryAccess(MU);
- Flags.incrementClobberingCalls();
- }
// If hoisting an invariant group, we only need to check that there
// is no store to the loaded pointer between the start of the loop,
// and the load (since all values must be the same).
// 2) the earliest access is at the loop header,
// if the memory loaded is the phi node
+ BatchAAResults BAA(MSSA->getAA());
+ MemoryAccess *Source = getClobberingMemoryAccess(*MSSA, BAA, Flags, MU);
return !MSSA->isLiveOnEntryDef(Source) &&
CurLoop->contains(Source->getBlock()) &&
!(InvariantGroup && Source->getBlock() == CurLoop->getHeader() && isa<MemoryPhi>(Source));