summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Analysis/MustExecute.h16
-rw-r--r--llvm/lib/Analysis/MustExecute.cpp17
-rw-r--r--llvm/lib/Transforms/Scalar/LICM.cpp15
3 files changed, 35 insertions, 13 deletions
diff --git a/llvm/include/llvm/Analysis/MustExecute.h b/llvm/include/llvm/Analysis/MustExecute.h
index e643e4ec563..d78b38bdead 100644
--- a/llvm/include/llvm/Analysis/MustExecute.h
+++ b/llvm/include/llvm/Analysis/MustExecute.h
@@ -49,6 +49,9 @@ class LoopSafetyInfo {
// may throw.
bool HeaderMayThrow = false; // Same as previous, but specific to loop header
+ // Used to update funclet bundle operands.
+ DenseMap<BasicBlock *, ColorVector> BlockColors;
+
/// Collect all blocks from \p CurLoop which lie on all possible paths from
/// the header of \p CurLoop (inclusive) to BB (exclusive) into the set
/// \p Predecessors. If \p BB is the header, \p Predecessors will be empty.
@@ -56,9 +59,16 @@ class LoopSafetyInfo {
const Loop *CurLoop, const BasicBlock *BB,
SmallPtrSetImpl<const BasicBlock *> &Predecessors) const;
+protected:
+ /// Computes block colors.
+ void computeBlockColors(const Loop *CurLoop);
+
public:
- // Used to update funclet bundle operands.
- DenseMap<BasicBlock *, ColorVector> BlockColors;
+ /// Returns block colors map that is used to update funclet operand bundles.
+ const DenseMap<BasicBlock *, ColorVector> &getBlockColors() const;
+
+ /// Copy colors of block \p Old into the block \p New.
+ void copyColors(BasicBlock *New, BasicBlock *Old);
/// Returns true iff the header block of the loop for which this info is
/// calculated contains an instruction that may throw or otherwise exit
@@ -83,7 +93,7 @@ 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(Loop *);
+ void computeLoopSafetyInfo(const Loop *CurLoop);
/// Returns true if the instruction in a loop is guaranteed to execute at
/// least once (under the assumption that the loop is entered).
diff --git a/llvm/lib/Analysis/MustExecute.cpp b/llvm/lib/Analysis/MustExecute.cpp
index 7f0912de26b..bce941be26c 100644
--- a/llvm/lib/Analysis/MustExecute.cpp
+++ b/llvm/lib/Analysis/MustExecute.cpp
@@ -22,6 +22,17 @@
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
+const DenseMap<BasicBlock *, ColorVector> &
+LoopSafetyInfo::getBlockColors() const {
+ return BlockColors;
+}
+
+void LoopSafetyInfo::copyColors(BasicBlock *New, BasicBlock *Old) {
+ ColorVector &ColorsForNewBlock = BlockColors[New];
+ ColorVector &ColorsForOldBlock = BlockColors[Old];
+ ColorsForNewBlock = ColorsForOldBlock;
+}
+
bool LoopSafetyInfo::headerMayThrow() const {
return HeaderMayThrow;
}
@@ -35,7 +46,7 @@ bool LoopSafetyInfo::anyBlockMayThrow() const {
return MayThrow;
}
-void LoopSafetyInfo::computeLoopSafetyInfo(Loop *CurLoop) {
+void LoopSafetyInfo::computeLoopSafetyInfo(const Loop *CurLoop) {
assert(CurLoop != nullptr && "CurLoop can't be null");
BasicBlock *Header = CurLoop->getHeader();
// Iterate over header and compute safety info.
@@ -51,6 +62,10 @@ void LoopSafetyInfo::computeLoopSafetyInfo(Loop *CurLoop) {
(BB != BBE) && !MayThrow; ++BB)
MayThrow |= !isGuaranteedToTransferExecutionToSuccessor(*BB);
+ computeBlockColors(CurLoop);
+}
+
+void LoopSafetyInfo::computeBlockColors(const Loop *CurLoop) {
// Compute funclet colors if we might sink/hoist in a function with a funclet
// personality routine.
Function *Fn = CurLoop->getHeader()->getParent();
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 9bf75a4ffbf..6c899289593 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -798,7 +798,7 @@ static bool isFreeInLoop(const Instruction &I, const Loop *CurLoop,
static bool isNotUsedOrFreeInLoop(const Instruction &I, const Loop *CurLoop,
const LoopSafetyInfo *SafetyInfo,
TargetTransformInfo *TTI, bool &FreeInLoop) {
- const auto &BlockColors = SafetyInfo->BlockColors;
+ const auto &BlockColors = SafetyInfo->getBlockColors();
bool IsFree = isFreeInLoop(I, CurLoop, TTI);
for (const User *U : I.users()) {
const Instruction *UI = cast<Instruction>(U);
@@ -833,7 +833,7 @@ CloneInstructionInExitBlock(Instruction &I, BasicBlock &ExitBlock, PHINode &PN,
const LoopSafetyInfo *SafetyInfo) {
Instruction *New;
if (auto *CI = dyn_cast<CallInst>(&I)) {
- const auto &BlockColors = SafetyInfo->BlockColors;
+ const auto &BlockColors = SafetyInfo->getBlockColors();
// Sinking call-sites need to be handled differently from other
// instructions. The cloned call-site needs a funclet bundle operand
@@ -913,7 +913,7 @@ static bool canSplitPredecessors(PHINode *PN, LoopSafetyInfo *SafetyInfo) {
// it require updating BlockColors for all offspring blocks accordingly. By
// skipping such corner case, we can make updating BlockColors after splitting
// predecessor fairly simple.
- if (!SafetyInfo->BlockColors.empty() && BB->getFirstNonPHI()->isEHPad())
+ if (!SafetyInfo->getBlockColors().empty() && BB->getFirstNonPHI()->isEHPad())
return false;
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
BasicBlock *BBPred = *PI;
@@ -967,7 +967,7 @@ static void splitPredecessorsOfLoopExit(PHINode *PN, DominatorTree *DT,
// LE:
// %p = phi [%p1, %LE.split], [%p2, %LE.split2]
//
- auto &BlockColors = SafetyInfo->BlockColors;
+ const auto &BlockColors = SafetyInfo->getBlockColors();
SmallSetVector<BasicBlock *, 8> PredBBs(pred_begin(ExitBB), pred_end(ExitBB));
while (!PredBBs.empty()) {
BasicBlock *PredBB = *PredBBs.begin();
@@ -979,14 +979,11 @@ static void splitPredecessorsOfLoopExit(PHINode *PN, DominatorTree *DT,
// Since we do not allow splitting EH-block with BlockColors in
// canSplitPredecessors(), we can simply assign predecessor's color to
// the new block.
- if (!BlockColors.empty()) {
+ if (!BlockColors.empty())
// Grab a reference to the ColorVector to be inserted before getting the
// reference to the vector we are copying because inserting the new
// element in BlockColors might cause the map to be reallocated.
- ColorVector &ColorsForNewBlock = BlockColors[NewPred];
- ColorVector &ColorsForOldBlock = BlockColors[PredBB];
- ColorsForNewBlock = ColorsForOldBlock;
- }
+ SafetyInfo->copyColors(NewPred, PredBB);
}
PredBBs.remove(PredBB);
}
OpenPOWER on IntegriCloud