diff --git a/llvm/include/llvm/Analysis/MustExecute.h b/llvm/include/llvm/Analysis/MustExecute.h --- a/llvm/include/llvm/Analysis/MustExecute.h +++ b/llvm/include/llvm/Analysis/MustExecute.h @@ -30,6 +30,54 @@ class DominatorTree; class Loop; +/// The common interface for the loop safety information. +struct LoopSafetyInfoInterface { + + /// 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. + 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. + virtual bool anyBlockMayThrow() const = 0; + + /// Computes safety information for a loop checks loop body & header for + /// the possibility of may throw exception, it takes LoopSafetyInfo and loop + /// 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. + 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). + virtual bool isGuaranteedToExecute(const Instruction &Inst, + const DominatorTree *DT, + const Loop *CurLoop) const = 0; + + /// Return true if we must reach the block \p BB under assumption that the + /// loop \p CurLoop is entered. + virtual bool allLoopPathsLeadToBlock(const Loop *CurLoop, + const BasicBlock *BB, + const DominatorTree *DT) const = 0; + + /// Inform the safety info that we are planning to insert a new instruction + /// \p Inst before \p PosI. It will make all cache updates to keep it correct + /// after this insertion. + virtual void insertInstructionBefore(const Instruction *NewI, + const Instruction *PosI) = 0; + + /// Inform the safety info that we are planning to insert a new instruction + /// \p Inst after \p PosI. It will make all cache updates to keep it correct + /// after this insertion. + virtual void insertInstructionAfter(const Instruction *NewI, + const Instruction *PosI) = 0; + + /// Inform safety info that we are planning to remove the instruction \p Inst + /// from its block. It will make all cache updates to keep it correct after + /// this removal. + virtual void removeInstruction(const Instruction *Inst) = 0; +}; + /// Captures loop safety information. /// It keep information for loop blocks may throw exception or otherwise /// exit abnormaly on any iteration of the loop which might actually execute @@ -44,7 +92,7 @@ /// LoopSafetyInfo needs to be recomputed. If a meaningful modifications to the /// loop were made and the info wasn't recomputed properly, the behavior of all /// methods except for computeLoopSafetyInfo is undefined. -class LoopSafetyInfo { +class LoopSafetyInfo : public LoopSafetyInfoInterface { // Used to update funclet bundle operands. DenseMap BlockColors; @@ -59,31 +107,10 @@ /// Copy colors of block \p Old into the block \p New. void copyColors(BasicBlock *New, BasicBlock *Old); - /// 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. - 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. - virtual bool anyBlockMayThrow() const = 0; - /// Return true if we must reach the block \p BB under assumption that the /// loop \p CurLoop is entered. bool allLoopPathsLeadToBlock(const Loop *CurLoop, const BasicBlock *BB, - const DominatorTree *DT) const; - - /// Computes safety information for a loop checks loop body & header for - /// the possibility of may throw exception, it takes LoopSafetyInfo and loop - /// 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. - 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). - virtual bool isGuaranteedToExecute(const Instruction &Inst, - const DominatorTree *DT, - const Loop *CurLoop) const = 0; + const DominatorTree *DT) const override; LoopSafetyInfo() = default; @@ -94,7 +121,7 @@ /// 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 { +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 @@ -110,6 +137,14 @@ const DominatorTree *DT, const Loop *CurLoop) const; + void insertInstructionBefore(const Instruction *NewI, + const Instruction *PosI) {} + + void insertInstructionAfter(const Instruction *NewI, + const Instruction *PosI) {} + + void removeInstruction(const Instruction *Inst) {} + SimpleLoopSafetyInfo() : LoopSafetyInfo() {}; virtual ~SimpleLoopSafetyInfo() {}; @@ -154,6 +189,18 @@ /// it correct after this insertion. void insertInstructionTo(const Instruction *Inst, const BasicBlock *BB); + /// See LoopSafetyInfoInterface::insertInstructionBefore(...). + void insertInstructionBefore(const Instruction *NewI, + const Instruction *PosI) { + insertInstructionTo(NewI, PosI->getParent()); + } + + /// See LoopSafetyInfoInterface::insertInstructionAfter(...). + void insertInstructionAfter(const Instruction *NewI, + const Instruction *PosI) { + insertInstructionTo(NewI, PosI->getParent()); + }; + /// Inform safety info that we are planning to remove the instruction \p Inst /// from its block. It will make all cache updates to keep it correct after /// this removal. diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -863,13 +863,13 @@ auto One = llvm::ConstantFP::get(Divisor->getType(), 1.0); auto ReciprocalDivisor = BinaryOperator::CreateFDiv(One, Divisor); ReciprocalDivisor->setFastMathFlags(I.getFastMathFlags()); - SafetyInfo->insertInstructionTo(ReciprocalDivisor, I.getParent()); + SafetyInfo->insertInstructionBefore(ReciprocalDivisor, &I); ReciprocalDivisor->insertBefore(&I); auto Product = BinaryOperator::CreateFMul(I.getOperand(0), ReciprocalDivisor); Product->setFastMathFlags(I.getFastMathFlags()); - SafetyInfo->insertInstructionTo(Product, I.getParent()); + SafetyInfo->insertInstructionAfter(Product, &I); Product->insertAfter(&I); I.replaceAllUsesWith(Product); eraseInstruction(I, *SafetyInfo, CurAST, MSSAU); @@ -1426,7 +1426,7 @@ ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater *MSSAU) { SafetyInfo.removeInstruction(&I); - SafetyInfo.insertInstructionTo(&I, Dest.getParent()); + SafetyInfo.insertInstructionBefore(&I, &Dest); I.moveBefore(&Dest); if (MSSAU) if (MemoryUseOrDef *OldMemAcc = cast_or_null(