[NFC] Make LoopSafetyInfo abstract to allow alternative implementations
llvm-svn: 344592
This commit is contained in:
parent
a5949439ca
commit
9c90ec2fae
|
@ -45,10 +45,6 @@ class Loop;
|
|||
/// loop were made and the info wasn't recomputed properly, the behavior of all
|
||||
/// methods except for computeLoopSafetyInfo is undefined.
|
||||
class LoopSafetyInfo {
|
||||
bool MayThrow = false; // The current loop contains an instruction which
|
||||
// may throw.
|
||||
bool HeaderMayThrow = false; // Same as previous, but specific to loop header
|
||||
|
||||
// Used to update funclet bundle operands.
|
||||
DenseMap<BasicBlock *, ColorVector> BlockColors;
|
||||
|
||||
|
@ -73,15 +69,15 @@ public:
|
|||
/// Returns true iff the header block of the loop for which this info is
|
||||
/// calculated contains an instruction that may throw or otherwise exit
|
||||
/// abnormally.
|
||||
bool headerMayThrow() const;
|
||||
virtual bool headerMayThrow() const = 0;
|
||||
|
||||
/// Returns true iff the block \p BB potentially may throw exception. It can
|
||||
/// be false-positive in cases when we want to avoid complex analysis.
|
||||
bool blockMayThrow(const BasicBlock *BB) const;
|
||||
virtual bool blockMayThrow(const BasicBlock *BB) const = 0;
|
||||
|
||||
/// Returns true iff any block of the loop for which this info is contains an
|
||||
/// instruction that may throw or otherwise exit abnormally.
|
||||
bool anyBlockMayThrow() const;
|
||||
virtual bool anyBlockMayThrow() const = 0;
|
||||
|
||||
/// Return true if we must reach the block \p BB under assumption that the
|
||||
/// loop \p CurLoop is entered.
|
||||
|
@ -93,14 +89,44 @@ public:
|
|||
/// as argument. Updates safety information in LoopSafetyInfo argument.
|
||||
/// Note: This is defined to clear and reinitialize an already initialized
|
||||
/// LoopSafetyInfo. Some callers rely on this fact.
|
||||
void computeLoopSafetyInfo(const Loop *CurLoop);
|
||||
virtual void computeLoopSafetyInfo(const Loop *CurLoop) = 0;
|
||||
|
||||
/// Returns true if the instruction in a loop is guaranteed to execute at
|
||||
/// least once (under the assumption that the loop is entered).
|
||||
bool isGuaranteedToExecute(const Instruction &Inst, const DominatorTree *DT,
|
||||
const Loop *CurLoop) const;
|
||||
virtual bool isGuaranteedToExecute(const Instruction &Inst,
|
||||
const DominatorTree *DT,
|
||||
const Loop *CurLoop) const = 0;
|
||||
|
||||
LoopSafetyInfo() = default;
|
||||
|
||||
virtual ~LoopSafetyInfo() = default;
|
||||
};
|
||||
|
||||
|
||||
/// Simple and conservative implementation of LoopSafetyInfo that can give
|
||||
/// false-positive answers to its queries in order to avoid complicated
|
||||
/// analysis.
|
||||
class SimpleLoopSafetyInfo: public LoopSafetyInfo {
|
||||
bool MayThrow = false; // The current loop contains an instruction which
|
||||
// may throw.
|
||||
bool HeaderMayThrow = false; // Same as previous, but specific to loop header
|
||||
|
||||
public:
|
||||
virtual bool headerMayThrow() const;
|
||||
|
||||
virtual bool blockMayThrow(const BasicBlock *BB) const;
|
||||
|
||||
virtual bool anyBlockMayThrow() const;
|
||||
|
||||
virtual void computeLoopSafetyInfo(const Loop *CurLoop);
|
||||
|
||||
virtual bool isGuaranteedToExecute(const Instruction &Inst,
|
||||
const DominatorTree *DT,
|
||||
const Loop *CurLoop) const;
|
||||
|
||||
SimpleLoopSafetyInfo() : LoopSafetyInfo() {};
|
||||
|
||||
virtual ~SimpleLoopSafetyInfo() {};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -33,20 +33,20 @@ void LoopSafetyInfo::copyColors(BasicBlock *New, BasicBlock *Old) {
|
|||
ColorsForNewBlock = ColorsForOldBlock;
|
||||
}
|
||||
|
||||
bool LoopSafetyInfo::headerMayThrow() const {
|
||||
bool SimpleLoopSafetyInfo::headerMayThrow() const {
|
||||
return HeaderMayThrow;
|
||||
}
|
||||
|
||||
bool LoopSafetyInfo::blockMayThrow(const BasicBlock *BB) const {
|
||||
bool SimpleLoopSafetyInfo::blockMayThrow(const BasicBlock *BB) const {
|
||||
(void)BB;
|
||||
return anyBlockMayThrow();
|
||||
}
|
||||
|
||||
bool LoopSafetyInfo::anyBlockMayThrow() const {
|
||||
bool SimpleLoopSafetyInfo::anyBlockMayThrow() const {
|
||||
return MayThrow;
|
||||
}
|
||||
|
||||
void LoopSafetyInfo::computeLoopSafetyInfo(const Loop *CurLoop) {
|
||||
void SimpleLoopSafetyInfo::computeLoopSafetyInfo(const Loop *CurLoop) {
|
||||
assert(CurLoop != nullptr && "CurLoop can't be null");
|
||||
BasicBlock *Header = CurLoop->getHeader();
|
||||
// Iterate over header and compute safety info.
|
||||
|
@ -200,9 +200,9 @@ bool LoopSafetyInfo::allLoopPathsLeadToBlock(const Loop *CurLoop,
|
|||
|
||||
/// Returns true if the instruction in a loop is guaranteed to execute at least
|
||||
/// once.
|
||||
bool LoopSafetyInfo::isGuaranteedToExecute(const Instruction &Inst,
|
||||
const DominatorTree *DT,
|
||||
const Loop *CurLoop) const {
|
||||
bool SimpleLoopSafetyInfo::isGuaranteedToExecute(const Instruction &Inst,
|
||||
const DominatorTree *DT,
|
||||
const Loop *CurLoop) const {
|
||||
// We have to check to make sure that the instruction dominates all
|
||||
// of the exit blocks. If it doesn't, then there is a path out of the loop
|
||||
// which does not execute this instruction, so we can't hoist it.
|
||||
|
@ -259,7 +259,7 @@ static bool isMustExecuteIn(const Instruction &I, Loop *L, DominatorTree *DT) {
|
|||
// TODO: merge these two routines. For the moment, we display the best
|
||||
// result obtained by *either* implementation. This is a bit unfair since no
|
||||
// caller actually gets the full power at the moment.
|
||||
LoopSafetyInfo LSI;
|
||||
SimpleLoopSafetyInfo LSI;
|
||||
LSI.computeLoopSafetyInfo(L);
|
||||
return LSI.isGuaranteedToExecute(I, DT, L) ||
|
||||
isGuaranteedToExecuteForEveryIteration(&I, L);
|
||||
|
|
|
@ -267,7 +267,7 @@ bool LoopInvariantCodeMotion::runOnLoop(
|
|||
BasicBlock *Preheader = L->getLoopPreheader();
|
||||
|
||||
// Compute loop safety information.
|
||||
LoopSafetyInfo SafetyInfo;
|
||||
SimpleLoopSafetyInfo SafetyInfo;
|
||||
SafetyInfo.computeLoopSafetyInfo(L);
|
||||
|
||||
// We want to visit all of the instructions in this loop... that are not parts
|
||||
|
|
|
@ -320,7 +320,7 @@ bool LoopIdiomRecognize::runOnCountableLoop() {
|
|||
|
||||
// The following transforms hoist stores/memsets into the loop pre-header.
|
||||
// Give up if the loop has instructions may throw.
|
||||
LoopSafetyInfo SafetyInfo;
|
||||
SimpleLoopSafetyInfo SafetyInfo;
|
||||
SafetyInfo.computeLoopSafetyInfo(CurLoop);
|
||||
if (SafetyInfo.anyBlockMayThrow())
|
||||
return MadeChange;
|
||||
|
|
|
@ -189,7 +189,7 @@ namespace {
|
|||
BasicBlock *loopPreheader = nullptr;
|
||||
|
||||
bool SanitizeMemory;
|
||||
LoopSafetyInfo SafetyInfo;
|
||||
SimpleLoopSafetyInfo SafetyInfo;
|
||||
|
||||
// LoopBlocks contains all of the basic blocks of the loop, including the
|
||||
// preheader of the loop, the body of the loop, and the exit blocks of the
|
||||
|
|
|
@ -761,7 +761,7 @@ bool llvm::isSafeToUnrollAndJam(Loop *L, ScalarEvolution &SE, DominatorTree &DT,
|
|||
}
|
||||
|
||||
// Check the loop safety info for exceptions.
|
||||
LoopSafetyInfo LSI;
|
||||
SimpleLoopSafetyInfo LSI;
|
||||
LSI.computeLoopSafetyInfo(L);
|
||||
if (LSI.anyBlockMayThrow()) {
|
||||
LLVM_DEBUG(dbgs() << "Won't unroll-and-jam; Something may throw\n");
|
||||
|
|
Loading…
Reference in New Issue