[NFC] Encapsulate work with BlockColors in LoopSafetyInfo

llvm-svn: 344590
This commit is contained in:
Max Kazantsev 2018-10-16 08:07:14 +00:00
parent c9163855dd
commit 8d56be7070
3 changed files with 35 additions and 13 deletions

View File

@ -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).

View File

@ -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();

View File

@ -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);
}