forked from OSchip/llvm-project
[NFC] Encapsulate work with BlockColors in LoopSafetyInfo
llvm-svn: 344590
This commit is contained in:
parent
c9163855dd
commit
8d56be7070
|
@ -49,6 +49,9 @@ class LoopSafetyInfo {
|
||||||
// may throw.
|
// may throw.
|
||||||
bool HeaderMayThrow = false; // Same as previous, but specific to loop header
|
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
|
/// 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
|
/// 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.
|
/// \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,
|
const Loop *CurLoop, const BasicBlock *BB,
|
||||||
SmallPtrSetImpl<const BasicBlock *> &Predecessors) const;
|
SmallPtrSetImpl<const BasicBlock *> &Predecessors) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Computes block colors.
|
||||||
|
void computeBlockColors(const Loop *CurLoop);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Used to update funclet bundle operands.
|
/// Returns block colors map that is used to update funclet operand bundles.
|
||||||
DenseMap<BasicBlock *, ColorVector> BlockColors;
|
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
|
/// Returns true iff the header block of the loop for which this info is
|
||||||
/// calculated contains an instruction that may throw or otherwise exit
|
/// calculated contains an instruction that may throw or otherwise exit
|
||||||
|
@ -83,7 +93,7 @@ public:
|
||||||
/// as argument. Updates safety information in LoopSafetyInfo argument.
|
/// as argument. Updates safety information in LoopSafetyInfo argument.
|
||||||
/// Note: This is defined to clear and reinitialize an already initialized
|
/// Note: This is defined to clear and reinitialize an already initialized
|
||||||
/// LoopSafetyInfo. Some callers rely on this fact.
|
/// 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
|
/// Returns true if the instruction in a loop is guaranteed to execute at
|
||||||
/// least once (under the assumption that the loop is entered).
|
/// least once (under the assumption that the loop is entered).
|
||||||
|
|
|
@ -22,6 +22,17 @@
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
using namespace llvm;
|
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 {
|
bool LoopSafetyInfo::headerMayThrow() const {
|
||||||
return HeaderMayThrow;
|
return HeaderMayThrow;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +46,7 @@ bool LoopSafetyInfo::anyBlockMayThrow() const {
|
||||||
return MayThrow;
|
return MayThrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopSafetyInfo::computeLoopSafetyInfo(Loop *CurLoop) {
|
void LoopSafetyInfo::computeLoopSafetyInfo(const Loop *CurLoop) {
|
||||||
assert(CurLoop != nullptr && "CurLoop can't be null");
|
assert(CurLoop != nullptr && "CurLoop can't be null");
|
||||||
BasicBlock *Header = CurLoop->getHeader();
|
BasicBlock *Header = CurLoop->getHeader();
|
||||||
// Iterate over header and compute safety info.
|
// Iterate over header and compute safety info.
|
||||||
|
@ -51,6 +62,10 @@ void LoopSafetyInfo::computeLoopSafetyInfo(Loop *CurLoop) {
|
||||||
(BB != BBE) && !MayThrow; ++BB)
|
(BB != BBE) && !MayThrow; ++BB)
|
||||||
MayThrow |= !isGuaranteedToTransferExecutionToSuccessor(*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
|
// Compute funclet colors if we might sink/hoist in a function with a funclet
|
||||||
// personality routine.
|
// personality routine.
|
||||||
Function *Fn = CurLoop->getHeader()->getParent();
|
Function *Fn = CurLoop->getHeader()->getParent();
|
||||||
|
|
|
@ -798,7 +798,7 @@ static bool isFreeInLoop(const Instruction &I, const Loop *CurLoop,
|
||||||
static bool isNotUsedOrFreeInLoop(const Instruction &I, const Loop *CurLoop,
|
static bool isNotUsedOrFreeInLoop(const Instruction &I, const Loop *CurLoop,
|
||||||
const LoopSafetyInfo *SafetyInfo,
|
const LoopSafetyInfo *SafetyInfo,
|
||||||
TargetTransformInfo *TTI, bool &FreeInLoop) {
|
TargetTransformInfo *TTI, bool &FreeInLoop) {
|
||||||
const auto &BlockColors = SafetyInfo->BlockColors;
|
const auto &BlockColors = SafetyInfo->getBlockColors();
|
||||||
bool IsFree = isFreeInLoop(I, CurLoop, TTI);
|
bool IsFree = isFreeInLoop(I, CurLoop, TTI);
|
||||||
for (const User *U : I.users()) {
|
for (const User *U : I.users()) {
|
||||||
const Instruction *UI = cast<Instruction>(U);
|
const Instruction *UI = cast<Instruction>(U);
|
||||||
|
@ -833,7 +833,7 @@ CloneInstructionInExitBlock(Instruction &I, BasicBlock &ExitBlock, PHINode &PN,
|
||||||
const LoopSafetyInfo *SafetyInfo) {
|
const LoopSafetyInfo *SafetyInfo) {
|
||||||
Instruction *New;
|
Instruction *New;
|
||||||
if (auto *CI = dyn_cast<CallInst>(&I)) {
|
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
|
// Sinking call-sites need to be handled differently from other
|
||||||
// instructions. The cloned call-site needs a funclet bundle operand
|
// 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
|
// it require updating BlockColors for all offspring blocks accordingly. By
|
||||||
// skipping such corner case, we can make updating BlockColors after splitting
|
// skipping such corner case, we can make updating BlockColors after splitting
|
||||||
// predecessor fairly simple.
|
// predecessor fairly simple.
|
||||||
if (!SafetyInfo->BlockColors.empty() && BB->getFirstNonPHI()->isEHPad())
|
if (!SafetyInfo->getBlockColors().empty() && BB->getFirstNonPHI()->isEHPad())
|
||||||
return false;
|
return false;
|
||||||
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
|
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
|
||||||
BasicBlock *BBPred = *PI;
|
BasicBlock *BBPred = *PI;
|
||||||
|
@ -967,7 +967,7 @@ static void splitPredecessorsOfLoopExit(PHINode *PN, DominatorTree *DT,
|
||||||
// LE:
|
// LE:
|
||||||
// %p = phi [%p1, %LE.split], [%p2, %LE.split2]
|
// %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));
|
SmallSetVector<BasicBlock *, 8> PredBBs(pred_begin(ExitBB), pred_end(ExitBB));
|
||||||
while (!PredBBs.empty()) {
|
while (!PredBBs.empty()) {
|
||||||
BasicBlock *PredBB = *PredBBs.begin();
|
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
|
// Since we do not allow splitting EH-block with BlockColors in
|
||||||
// canSplitPredecessors(), we can simply assign predecessor's color to
|
// canSplitPredecessors(), we can simply assign predecessor's color to
|
||||||
// the new block.
|
// the new block.
|
||||||
if (!BlockColors.empty()) {
|
if (!BlockColors.empty())
|
||||||
// Grab a reference to the ColorVector to be inserted before getting the
|
// Grab a reference to the ColorVector to be inserted before getting the
|
||||||
// reference to the vector we are copying because inserting the new
|
// reference to the vector we are copying because inserting the new
|
||||||
// element in BlockColors might cause the map to be reallocated.
|
// element in BlockColors might cause the map to be reallocated.
|
||||||
ColorVector &ColorsForNewBlock = BlockColors[NewPred];
|
SafetyInfo->copyColors(NewPred, PredBB);
|
||||||
ColorVector &ColorsForOldBlock = BlockColors[PredBB];
|
|
||||||
ColorsForNewBlock = ColorsForOldBlock;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PredBBs.remove(PredBB);
|
PredBBs.remove(PredBB);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue