diff options
| -rw-r--r-- | llvm/include/llvm/Analysis/MustExecute.h | 46 | ||||
| -rw-r--r-- | llvm/lib/Analysis/MustExecute.cpp | 16 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LICM.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LoopUnswitch.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp | 2 | 
6 files changed, 48 insertions, 22 deletions
diff --git a/llvm/include/llvm/Analysis/MustExecute.h b/llvm/include/llvm/Analysis/MustExecute.h index d78b38bdead..6a6a127b7c3 100644 --- a/llvm/include/llvm/Analysis/MustExecute.h +++ b/llvm/include/llvm/Analysis/MustExecute.h @@ -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() {};  };  } diff --git a/llvm/lib/Analysis/MustExecute.cpp b/llvm/lib/Analysis/MustExecute.cpp index bce941be26c..618e2e3e30d 100644 --- a/llvm/lib/Analysis/MustExecute.cpp +++ b/llvm/lib/Analysis/MustExecute.cpp @@ -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); diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index 6c899289593..e72342b88b6 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -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 diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index 9a45551f64b..4b375956a12 100644 --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -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; diff --git a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp index cd49f51283f..4a089dfa7db 100644 --- a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -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 diff --git a/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp b/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp index c17a64f0187..8949c603a84 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp @@ -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");  | 

