1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[NFCI] Update according to style.

clang-tidy + clang-format
This commit is contained in:
Alina Sbirlea 2020-02-04 16:29:04 -08:00
parent 909a964504
commit 5f84616692
8 changed files with 183 additions and 182 deletions

View File

@ -155,7 +155,7 @@ static bool pointerInvalidatedByLoop(MemoryLocation MemLoc,
static bool pointerInvalidatedByLoopWithMSSA(MemorySSA *MSSA, MemoryUse *MU, static bool pointerInvalidatedByLoopWithMSSA(MemorySSA *MSSA, MemoryUse *MU,
Loop *CurLoop, Loop *CurLoop,
SinkAndHoistLICMFlags &Flags); SinkAndHoistLICMFlags &Flags);
static Instruction *CloneInstructionInExitBlock( static Instruction *cloneInstructionInExitBlock(
Instruction &I, BasicBlock &ExitBlock, PHINode &PN, const LoopInfo *LI, Instruction &I, BasicBlock &ExitBlock, PHINode &PN, const LoopInfo *LI,
const LoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU); const LoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU);
@ -1364,7 +1364,7 @@ static bool isNotUsedOrFreeInLoop(const Instruction &I, const Loop *CurLoop,
return true; return true;
} }
static Instruction *CloneInstructionInExitBlock( static Instruction *cloneInstructionInExitBlock(
Instruction &I, BasicBlock &ExitBlock, PHINode &PN, const LoopInfo *LI, Instruction &I, BasicBlock &ExitBlock, PHINode &PN, const LoopInfo *LI,
const LoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU) { const LoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU) {
Instruction *New; Instruction *New;
@ -1477,7 +1477,7 @@ static Instruction *sinkThroughTriviallyReplaceablePHI(
if (It != SunkCopies.end()) if (It != SunkCopies.end())
New = It->second; New = It->second;
else else
New = SunkCopies[ExitBlock] = CloneInstructionInExitBlock( New = SunkCopies[ExitBlock] = cloneInstructionInExitBlock(
*I, *ExitBlock, *TPN, LI, SafetyInfo, MSSAU); *I, *ExitBlock, *TPN, LI, SafetyInfo, MSSAU);
return New; return New;
} }

View File

@ -342,7 +342,7 @@ public:
}; };
char LoopPredicationLegacyPass::ID = 0; char LoopPredicationLegacyPass::ID = 0;
} // end namespace llvm } // end namespace
INITIALIZE_PASS_BEGIN(LoopPredicationLegacyPass, "loop-predication", INITIALIZE_PASS_BEGIN(LoopPredicationLegacyPass, "loop-predication",
"Loop predication", false, false) "Loop predication", false, false)

View File

@ -109,7 +109,7 @@ public:
false, MaxHeaderSize, false); false, MaxHeaderSize, false);
} }
}; };
} } // end namespace
char LoopRotateLegacyPass::ID = 0; char LoopRotateLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(LoopRotateLegacyPass, "loop-rotate", "Rotate Loops", INITIALIZE_PASS_BEGIN(LoopRotateLegacyPass, "loop-rotate", "Rotate Loops",

View File

@ -673,13 +673,13 @@ static bool mergeBlocksIntoPredecessors(Loop &L, DominatorTree &DT,
static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI, static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI,
ScalarEvolution &SE, MemorySSAUpdater *MSSAU, ScalarEvolution &SE, MemorySSAUpdater *MSSAU,
bool &isLoopDeleted) { bool &IsLoopDeleted) {
bool Changed = false; bool Changed = false;
// Constant-fold terminators with known constant conditions. // Constant-fold terminators with known constant conditions.
Changed |= constantFoldTerminators(L, DT, LI, SE, MSSAU, isLoopDeleted); Changed |= constantFoldTerminators(L, DT, LI, SE, MSSAU, IsLoopDeleted);
if (isLoopDeleted) if (IsLoopDeleted)
return true; return true;
// Eliminate unconditional branches by merging blocks into their predecessors. // Eliminate unconditional branches by merging blocks into their predecessors.
@ -752,7 +752,7 @@ public:
getLoopAnalysisUsage(AU); getLoopAnalysisUsage(AU);
} }
}; };
} } // end namespace
char LoopSimplifyCFGLegacyPass::ID = 0; char LoopSimplifyCFGLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(LoopSimplifyCFGLegacyPass, "loop-simplifycfg", INITIALIZE_PASS_BEGIN(LoopSimplifyCFGLegacyPass, "loop-simplifycfg",

View File

@ -91,7 +91,7 @@ static cl::opt<unsigned> PragmaUnrollAndJamThreshold(
// Returns the loop hint metadata node with the given name (for example, // Returns the loop hint metadata node with the given name (for example,
// "llvm.loop.unroll.count"). If no such metadata node exists, then nullptr is // "llvm.loop.unroll.count"). If no such metadata node exists, then nullptr is
// returned. // returned.
static MDNode *GetUnrollMetadataForLoop(const Loop *L, StringRef Name) { static MDNode *getUnrollMetadataForLoop(const Loop *L, StringRef Name) {
if (MDNode *LoopID = L->getLoopID()) if (MDNode *LoopID = L->getLoopID())
return GetUnrollMetadata(LoopID, Name); return GetUnrollMetadata(LoopID, Name);
return nullptr; return nullptr;
@ -99,14 +99,14 @@ static MDNode *GetUnrollMetadataForLoop(const Loop *L, StringRef Name) {
// Returns true if the loop has any metadata starting with Prefix. For example a // Returns true if the loop has any metadata starting with Prefix. For example a
// Prefix of "llvm.loop.unroll." returns true if we have any unroll metadata. // Prefix of "llvm.loop.unroll." returns true if we have any unroll metadata.
static bool HasAnyUnrollPragma(const Loop *L, StringRef Prefix) { static bool hasAnyUnrollPragma(const Loop *L, StringRef Prefix) {
if (MDNode *LoopID = L->getLoopID()) { if (MDNode *LoopID = L->getLoopID()) {
// First operand should refer to the loop id itself. // First operand should refer to the loop id itself.
assert(LoopID->getNumOperands() > 0 && "requires at least one operand"); assert(LoopID->getNumOperands() > 0 && "requires at least one operand");
assert(LoopID->getOperand(0) == LoopID && "invalid loop id"); assert(LoopID->getOperand(0) == LoopID && "invalid loop id");
for (unsigned i = 1, e = LoopID->getNumOperands(); i < e; ++i) { for (unsigned I = 1, E = LoopID->getNumOperands(); I < E; ++I) {
MDNode *MD = dyn_cast<MDNode>(LoopID->getOperand(i)); MDNode *MD = dyn_cast<MDNode>(LoopID->getOperand(I));
if (!MD) if (!MD)
continue; continue;
@ -122,14 +122,14 @@ static bool HasAnyUnrollPragma(const Loop *L, StringRef Prefix) {
} }
// Returns true if the loop has an unroll_and_jam(enable) pragma. // Returns true if the loop has an unroll_and_jam(enable) pragma.
static bool HasUnrollAndJamEnablePragma(const Loop *L) { static bool hasUnrollAndJamEnablePragma(const Loop *L) {
return GetUnrollMetadataForLoop(L, "llvm.loop.unroll_and_jam.enable"); return getUnrollMetadataForLoop(L, "llvm.loop.unroll_and_jam.enable");
} }
// If loop has an unroll_and_jam_count pragma return the (necessarily // If loop has an unroll_and_jam_count pragma return the (necessarily
// positive) value from the pragma. Otherwise return 0. // positive) value from the pragma. Otherwise return 0.
static unsigned UnrollAndJamCountPragmaValue(const Loop *L) { static unsigned unrollAndJamCountPragmaValue(const Loop *L) {
MDNode *MD = GetUnrollMetadataForLoop(L, "llvm.loop.unroll_and_jam.count"); MDNode *MD = getUnrollMetadataForLoop(L, "llvm.loop.unroll_and_jam.count");
if (MD) { if (MD) {
assert(MD->getNumOperands() == 2 && assert(MD->getNumOperands() == 2 &&
"Unroll count hint metadata should have two operands."); "Unroll count hint metadata should have two operands.");
@ -190,7 +190,7 @@ static bool computeUnrollAndJamCount(
} }
// Check for unroll_and_jam pragmas // Check for unroll_and_jam pragmas
unsigned PragmaCount = UnrollAndJamCountPragmaValue(L); unsigned PragmaCount = unrollAndJamCountPragmaValue(L);
if (PragmaCount > 0) { if (PragmaCount > 0) {
UP.Count = PragmaCount; UP.Count = PragmaCount;
UP.Runtime = true; UP.Runtime = true;
@ -202,7 +202,7 @@ static bool computeUnrollAndJamCount(
return true; return true;
} }
bool PragmaEnableUnroll = HasUnrollAndJamEnablePragma(L); bool PragmaEnableUnroll = hasUnrollAndJamEnablePragma(L);
bool ExplicitUnrollAndJamCount = PragmaCount > 0 || UserUnrollCount; bool ExplicitUnrollAndJamCount = PragmaCount > 0 || UserUnrollCount;
bool ExplicitUnrollAndJam = PragmaEnableUnroll || ExplicitUnrollAndJamCount; bool ExplicitUnrollAndJam = PragmaEnableUnroll || ExplicitUnrollAndJamCount;
@ -317,8 +317,8 @@ tryToUnrollAndJamLoop(Loop *L, DominatorTree &DT, LoopInfo *LI,
// the unroller, so long as it does not explicitly have unroll_and_jam // the unroller, so long as it does not explicitly have unroll_and_jam
// metadata. This means #pragma nounroll will disable unroll and jam as well // metadata. This means #pragma nounroll will disable unroll and jam as well
// as unrolling // as unrolling
if (HasAnyUnrollPragma(L, "llvm.loop.unroll.") && if (hasAnyUnrollPragma(L, "llvm.loop.unroll.") &&
!HasAnyUnrollPragma(L, "llvm.loop.unroll_and_jam.")) { !hasAnyUnrollPragma(L, "llvm.loop.unroll_and_jam.")) {
LLVM_DEBUG(dbgs() << " Disabled due to pragma.\n"); LLVM_DEBUG(dbgs() << " Disabled due to pragma.\n");
return LoopUnrollResult::Unmodified; return LoopUnrollResult::Unmodified;
} }

View File

@ -676,32 +676,32 @@ unsigned llvm::ApproximateLoopSize(
// Returns the loop hint metadata node with the given name (for example, // Returns the loop hint metadata node with the given name (for example,
// "llvm.loop.unroll.count"). If no such metadata node exists, then nullptr is // "llvm.loop.unroll.count"). If no such metadata node exists, then nullptr is
// returned. // returned.
static MDNode *GetUnrollMetadataForLoop(const Loop *L, StringRef Name) { static MDNode *getUnrollMetadataForLoop(const Loop *L, StringRef Name) {
if (MDNode *LoopID = L->getLoopID()) if (MDNode *LoopID = L->getLoopID())
return GetUnrollMetadata(LoopID, Name); return GetUnrollMetadata(LoopID, Name);
return nullptr; return nullptr;
} }
// Returns true if the loop has an unroll(full) pragma. // Returns true if the loop has an unroll(full) pragma.
static bool HasUnrollFullPragma(const Loop *L) { static bool hasUnrollFullPragma(const Loop *L) {
return GetUnrollMetadataForLoop(L, "llvm.loop.unroll.full"); return getUnrollMetadataForLoop(L, "llvm.loop.unroll.full");
} }
// Returns true if the loop has an unroll(enable) pragma. This metadata is used // Returns true if the loop has an unroll(enable) pragma. This metadata is used
// for both "#pragma unroll" and "#pragma clang loop unroll(enable)" directives. // for both "#pragma unroll" and "#pragma clang loop unroll(enable)" directives.
static bool HasUnrollEnablePragma(const Loop *L) { static bool hasUnrollEnablePragma(const Loop *L) {
return GetUnrollMetadataForLoop(L, "llvm.loop.unroll.enable"); return getUnrollMetadataForLoop(L, "llvm.loop.unroll.enable");
} }
// Returns true if the loop has an runtime unroll(disable) pragma. // Returns true if the loop has an runtime unroll(disable) pragma.
static bool HasRuntimeUnrollDisablePragma(const Loop *L) { static bool hasRuntimeUnrollDisablePragma(const Loop *L) {
return GetUnrollMetadataForLoop(L, "llvm.loop.unroll.runtime.disable"); return getUnrollMetadataForLoop(L, "llvm.loop.unroll.runtime.disable");
} }
// If loop has an unroll_count pragma return the (necessarily // If loop has an unroll_count pragma return the (necessarily
// positive) value from the pragma. Otherwise return 0. // positive) value from the pragma. Otherwise return 0.
static unsigned UnrollCountPragmaValue(const Loop *L) { static unsigned unrollCountPragmaValue(const Loop *L) {
MDNode *MD = GetUnrollMetadataForLoop(L, "llvm.loop.unroll.count"); MDNode *MD = getUnrollMetadataForLoop(L, "llvm.loop.unroll.count");
if (MD) { if (MD) {
assert(MD->getNumOperands() == 2 && assert(MD->getNumOperands() == 2 &&
"Unroll count hint metadata should have two operands."); "Unroll count hint metadata should have two operands.");
@ -765,7 +765,7 @@ bool llvm::computeUnrollCount(
} }
// 2nd priority is unroll count set by pragma. // 2nd priority is unroll count set by pragma.
unsigned PragmaCount = UnrollCountPragmaValue(L); unsigned PragmaCount = unrollCountPragmaValue(L);
if (PragmaCount > 0) { if (PragmaCount > 0) {
UP.Count = PragmaCount; UP.Count = PragmaCount;
UP.Runtime = true; UP.Runtime = true;
@ -775,14 +775,14 @@ bool llvm::computeUnrollCount(
getUnrolledLoopSize(LoopSize, UP) < PragmaUnrollThreshold) getUnrolledLoopSize(LoopSize, UP) < PragmaUnrollThreshold)
return true; return true;
} }
bool PragmaFullUnroll = HasUnrollFullPragma(L); bool PragmaFullUnroll = hasUnrollFullPragma(L);
if (PragmaFullUnroll && TripCount != 0) { if (PragmaFullUnroll && TripCount != 0) {
UP.Count = TripCount; UP.Count = TripCount;
if (getUnrolledLoopSize(LoopSize, UP) < PragmaUnrollThreshold) if (getUnrolledLoopSize(LoopSize, UP) < PragmaUnrollThreshold)
return false; return false;
} }
bool PragmaEnableUnroll = HasUnrollEnablePragma(L); bool PragmaEnableUnroll = hasUnrollEnablePragma(L);
bool ExplicitUnroll = PragmaCount > 0 || PragmaFullUnroll || bool ExplicitUnroll = PragmaCount > 0 || PragmaFullUnroll ||
PragmaEnableUnroll || UserUnrollCount; PragmaEnableUnroll || UserUnrollCount;
@ -936,7 +936,7 @@ bool llvm::computeUnrollCount(
// 6th priority is runtime unrolling. // 6th priority is runtime unrolling.
// Don't unroll a runtime trip count loop when it is disabled. // Don't unroll a runtime trip count loop when it is disabled.
if (HasRuntimeUnrollDisablePragma(L)) { if (hasRuntimeUnrollDisablePragma(L)) {
UP.Count = 0; UP.Count = 0;
return false; return false;
} }

View File

@ -158,7 +158,7 @@ namespace {
// Returns true if another unswitching could be done within the cost // Returns true if another unswitching could be done within the cost
// threshold. // threshold.
bool CostAllowsUnswitching(); bool costAllowsUnswitching();
// Clone all loop-unswitch related loop properties. // Clone all loop-unswitch related loop properties.
// Redistribute unswitching quotas. // Redistribute unswitching quotas.
@ -173,20 +173,20 @@ namespace {
AssumptionCache *AC; AssumptionCache *AC;
// Used to check if second loop needs processing after // Used to check if second loop needs processing after
// RewriteLoopBodyWithConditionConstant rewrites first loop. // rewriteLoopBodyWithConditionConstant rewrites first loop.
std::vector<Loop*> LoopProcessWorklist; std::vector<Loop*> LoopProcessWorklist;
LUAnalysisCache BranchesInfo; LUAnalysisCache BranchesInfo;
bool OptimizeForSize; bool OptimizeForSize;
bool redoLoop = false; bool RedoLoop = false;
Loop *currentLoop = nullptr; Loop *CurrentLoop = nullptr;
DominatorTree *DT = nullptr; DominatorTree *DT = nullptr;
MemorySSA *MSSA = nullptr; MemorySSA *MSSA = nullptr;
std::unique_ptr<MemorySSAUpdater> MSSAU; std::unique_ptr<MemorySSAUpdater> MSSAU;
BasicBlock *loopHeader = nullptr; BasicBlock *LoopHeader = nullptr;
BasicBlock *loopPreheader = nullptr; BasicBlock *LoopPreheader = nullptr;
bool SanitizeMemory; bool SanitizeMemory;
SimpleLoopSafetyInfo SafetyInfo; SimpleLoopSafetyInfo SafetyInfo;
@ -198,14 +198,14 @@ namespace {
// NewBlocks contained cloned copy of basic blocks from LoopBlocks. // NewBlocks contained cloned copy of basic blocks from LoopBlocks.
std::vector<BasicBlock*> NewBlocks; std::vector<BasicBlock*> NewBlocks;
bool hasBranchDivergence; bool HasBranchDivergence;
public: public:
static char ID; // Pass ID, replacement for typeid static char ID; // Pass ID, replacement for typeid
explicit LoopUnswitch(bool Os = false, bool hasBranchDivergence = false) explicit LoopUnswitch(bool Os = false, bool HasBranchDivergence = false)
: LoopPass(ID), OptimizeForSize(Os), : LoopPass(ID), OptimizeForSize(Os),
hasBranchDivergence(hasBranchDivergence) { HasBranchDivergence(HasBranchDivergence) {
initializeLoopUnswitchPass(*PassRegistry::getPassRegistry()); initializeLoopUnswitchPass(*PassRegistry::getPassRegistry());
} }
@ -223,48 +223,46 @@ namespace {
AU.addRequired<MemorySSAWrapperPass>(); AU.addRequired<MemorySSAWrapperPass>();
AU.addPreserved<MemorySSAWrapperPass>(); AU.addPreserved<MemorySSAWrapperPass>();
} }
if (hasBranchDivergence) if (HasBranchDivergence)
AU.addRequired<LegacyDivergenceAnalysis>(); AU.addRequired<LegacyDivergenceAnalysis>();
getLoopAnalysisUsage(AU); getLoopAnalysisUsage(AU);
} }
private: private:
void releaseMemory() override { void releaseMemory() override { BranchesInfo.forgetLoop(CurrentLoop); }
BranchesInfo.forgetLoop(currentLoop);
}
void initLoopData() { void initLoopData() {
loopHeader = currentLoop->getHeader(); LoopHeader = CurrentLoop->getHeader();
loopPreheader = currentLoop->getLoopPreheader(); LoopPreheader = CurrentLoop->getLoopPreheader();
} }
/// Split all of the edges from inside the loop to their exit blocks. /// Split all of the edges from inside the loop to their exit blocks.
/// Update the appropriate Phi nodes as we do so. /// Update the appropriate Phi nodes as we do so.
void SplitExitEdges(Loop *L, void splitExitEdges(Loop *L,
const SmallVectorImpl<BasicBlock *> &ExitBlocks); const SmallVectorImpl<BasicBlock *> &ExitBlocks);
bool TryTrivialLoopUnswitch(bool &Changed); bool tryTrivialLoopUnswitch(bool &Changed);
bool UnswitchIfProfitable(Value *LoopCond, Constant *Val, bool unswitchIfProfitable(Value *LoopCond, Constant *Val,
Instruction *TI = nullptr); Instruction *TI = nullptr);
void UnswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val, void unswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val,
BasicBlock *ExitBlock, Instruction *TI); BasicBlock *ExitBlock, Instruction *TI);
void UnswitchNontrivialCondition(Value *LIC, Constant *OnVal, Loop *L, void unswitchNontrivialCondition(Value *LIC, Constant *OnVal, Loop *L,
Instruction *TI); Instruction *TI);
void RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC, void rewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
Constant *Val, bool isEqual); Constant *Val, bool IsEqual);
void EmitPreheaderBranchOnCondition(Value *LIC, Constant *Val, void emitPreheaderBranchOnCondition(Value *LIC, Constant *Val,
BasicBlock *TrueDest, BasicBlock *TrueDest,
BasicBlock *FalseDest, BasicBlock *FalseDest,
BranchInst *OldBranch, Instruction *TI); BranchInst *OldBranch, Instruction *TI);
void SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L); void simplifyCode(std::vector<Instruction *> &Worklist, Loop *L);
/// Given that the Invariant is not equal to Val. Simplify instructions /// Given that the Invariant is not equal to Val. Simplify instructions
/// in the loop. /// in the loop.
Value *SimplifyInstructionWithNotEqual(Instruction *Inst, Value *Invariant, Value *simplifyInstructionWithNotEqual(Instruction *Inst, Value *Invariant,
Constant *Val); Constant *Val);
}; };
@ -347,7 +345,7 @@ bool LUAnalysisCache::isUnswitched(const SwitchInst *SI, const Value *V) {
return (*CurLoopInstructions)[SI].count(V); return (*CurLoopInstructions)[SI].count(V);
} }
bool LUAnalysisCache::CostAllowsUnswitching() { bool LUAnalysisCache::costAllowsUnswitching() {
return CurrentLoopProperties->CanBeUnswitchedCount > 0; return CurrentLoopProperties->CanBeUnswitchedCount > 0;
} }
@ -396,8 +394,8 @@ INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
INITIALIZE_PASS_END(LoopUnswitch, "loop-unswitch", "Unswitch loops", INITIALIZE_PASS_END(LoopUnswitch, "loop-unswitch", "Unswitch loops",
false, false) false, false)
Pass *llvm::createLoopUnswitchPass(bool Os, bool hasBranchDivergence) { Pass *llvm::createLoopUnswitchPass(bool Os, bool HasBranchDivergence) {
return new LoopUnswitch(Os, hasBranchDivergence); return new LoopUnswitch(Os, HasBranchDivergence);
} }
/// Operator chain lattice. /// Operator chain lattice.
@ -411,15 +409,15 @@ enum OperatorChain {
/// Cond is a condition that occurs in L. If it is invariant in the loop, or has /// Cond is a condition that occurs in L. If it is invariant in the loop, or has
/// an invariant piece, return the invariant. Otherwise, return null. /// an invariant piece, return the invariant. Otherwise, return null.
// //
/// NOTE: FindLIVLoopCondition will not return a partial LIV by walking up a /// NOTE: findLIVLoopCondition will not return a partial LIV by walking up a
/// mixed operator chain, as we can not reliably find a value which will simplify /// mixed operator chain, as we can not reliably find a value which will
/// the operator chain. If the chain is AND-only or OR-only, we can use 0 or ~0 /// simplify the operator chain. If the chain is AND-only or OR-only, we can use
/// to simplify the chain. /// 0 or ~0 to simplify the chain.
/// ///
/// NOTE: In case a partial LIV and a mixed operator chain, we may be able to /// NOTE: In case a partial LIV and a mixed operator chain, we may be able to
/// simplify the condition itself to a loop variant condition, but at the /// simplify the condition itself to a loop variant condition, but at the
/// cost of creating an entirely new loop. /// cost of creating an entirely new loop.
static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed, static Value *findLIVLoopCondition(Value *Cond, Loop *L, bool &Changed,
OperatorChain &ParentChain, OperatorChain &ParentChain,
DenseMap<Value *, Value *> &Cache, DenseMap<Value *, Value *> &Cache,
MemorySSAUpdater *MSSAU) { MemorySSAUpdater *MSSAU) {
@ -479,7 +477,7 @@ static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed,
// If either the left or right side is invariant, we can unswitch on this, // If either the left or right side is invariant, we can unswitch on this,
// which will cause the branch to go away in one loop and the condition to // which will cause the branch to go away in one loop and the condition to
// simplify in the other one. // simplify in the other one.
if (Value *LHS = FindLIVLoopCondition(BO->getOperand(0), L, Changed, if (Value *LHS = findLIVLoopCondition(BO->getOperand(0), L, Changed,
ParentChain, Cache, MSSAU)) { ParentChain, Cache, MSSAU)) {
Cache[Cond] = LHS; Cache[Cond] = LHS;
return LHS; return LHS;
@ -487,7 +485,7 @@ static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed,
// We did not manage to find a partial LIV in operand(0). Backtrack and try // We did not manage to find a partial LIV in operand(0). Backtrack and try
// operand(1). // operand(1).
ParentChain = NewChain; ParentChain = NewChain;
if (Value *RHS = FindLIVLoopCondition(BO->getOperand(1), L, Changed, if (Value *RHS = findLIVLoopCondition(BO->getOperand(1), L, Changed,
ParentChain, Cache, MSSAU)) { ParentChain, Cache, MSSAU)) {
Cache[Cond] = RHS; Cache[Cond] = RHS;
return RHS; return RHS;
@ -503,11 +501,11 @@ static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed,
/// an invariant piece, return the invariant along with the operator chain type. /// an invariant piece, return the invariant along with the operator chain type.
/// Otherwise, return null. /// Otherwise, return null.
static std::pair<Value *, OperatorChain> static std::pair<Value *, OperatorChain>
FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed, findLIVLoopCondition(Value *Cond, Loop *L, bool &Changed,
MemorySSAUpdater *MSSAU) { MemorySSAUpdater *MSSAU) {
DenseMap<Value *, Value *> Cache; DenseMap<Value *, Value *> Cache;
OperatorChain OpChain = OC_OpChainNone; OperatorChain OpChain = OC_OpChainNone;
Value *FCond = FindLIVLoopCondition(Cond, L, Changed, OpChain, Cache, MSSAU); Value *FCond = findLIVLoopCondition(Cond, L, Changed, OpChain, Cache, MSSAU);
// In case we do find a LIV, it can not be obtained by walking up a mixed // In case we do find a LIV, it can not be obtained by walking up a mixed
// operator chain. // operator chain.
@ -516,22 +514,22 @@ FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed,
return {FCond, OpChain}; return {FCond, OpChain};
} }
bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) { bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPMRef) {
if (skipLoop(L)) if (skipLoop(L))
return false; return false;
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache( AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
*L->getHeader()->getParent()); *L->getHeader()->getParent());
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
LPM = &LPM_Ref; LPM = &LPMRef;
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
if (EnableMSSALoopDependency) { if (EnableMSSALoopDependency) {
MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA(); MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
MSSAU = std::make_unique<MemorySSAUpdater>(MSSA); MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
assert(DT && "Cannot update MemorySSA without a valid DomTree."); assert(DT && "Cannot update MemorySSA without a valid DomTree.");
} }
currentLoop = L; CurrentLoop = L;
Function *F = currentLoop->getHeader()->getParent(); Function *F = CurrentLoop->getHeader()->getParent();
SanitizeMemory = F->hasFnAttribute(Attribute::SanitizeMemory); SanitizeMemory = F->hasFnAttribute(Attribute::SanitizeMemory);
if (SanitizeMemory) if (SanitizeMemory)
@ -542,12 +540,12 @@ bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) {
bool Changed = false; bool Changed = false;
do { do {
assert(currentLoop->isLCSSAForm(*DT)); assert(CurrentLoop->isLCSSAForm(*DT));
if (MSSA && VerifyMemorySSA) if (MSSA && VerifyMemorySSA)
MSSA->verifyMemorySSA(); MSSA->verifyMemorySSA();
redoLoop = false; RedoLoop = false;
Changed |= processCurrentLoop(); Changed |= processCurrentLoop();
} while(redoLoop); } while (RedoLoop);
if (MSSA && VerifyMemorySSA) if (MSSA && VerifyMemorySSA)
MSSA->verifyMemorySSA(); MSSA->verifyMemorySSA();
@ -560,7 +558,7 @@ bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) {
bool LoopUnswitch::isUnreachableDueToPreviousUnswitching(BasicBlock *BB) { bool LoopUnswitch::isUnreachableDueToPreviousUnswitching(BasicBlock *BB) {
auto *Node = DT->getNode(BB)->getIDom(); auto *Node = DT->getNode(BB)->getIDom();
BasicBlock *DomBB = Node->getBlock(); BasicBlock *DomBB = Node->getBlock();
while (currentLoop->contains(DomBB)) { while (CurrentLoop->contains(DomBB)) {
BranchInst *BInst = dyn_cast<BranchInst>(DomBB->getTerminator()); BranchInst *BInst = dyn_cast<BranchInst>(DomBB->getTerminator());
Node = DT->getNode(DomBB)->getIDom(); Node = DT->getNode(DomBB)->getIDom();
@ -591,7 +589,7 @@ bool LoopUnswitch::isUnreachableDueToPreviousUnswitching(BasicBlock *BB) {
/// causing problems. Detail could be found in PR31652. Note if the /// causing problems. Detail could be found in PR31652. Note if the
/// func returns true, it is unsafe. But if it is false, it doesn't mean /// func returns true, it is unsafe. But if it is false, it doesn't mean
/// it is necessarily safe. /// it is necessarily safe.
static bool EqualityPropUnSafe(Value &LoopCond) { static bool equalityPropUnSafe(Value &LoopCond) {
ICmpInst *CI = dyn_cast<ICmpInst>(&LoopCond); ICmpInst *CI = dyn_cast<ICmpInst>(&LoopCond);
if (!CI || !CI->isEquality()) if (!CI || !CI->isEquality())
return false; return false;
@ -601,7 +599,7 @@ static bool EqualityPropUnSafe(Value &LoopCond) {
if (isa<UndefValue>(LHS) || isa<UndefValue>(RHS)) if (isa<UndefValue>(LHS) || isa<UndefValue>(RHS))
return true; return true;
auto hasUndefInPHI = [](PHINode &PN) { auto HasUndefInPHI = [](PHINode &PN) {
for (Value *Opd : PN.incoming_values()) { for (Value *Opd : PN.incoming_values()) {
if (isa<UndefValue>(Opd)) if (isa<UndefValue>(Opd))
return true; return true;
@ -610,10 +608,10 @@ static bool EqualityPropUnSafe(Value &LoopCond) {
}; };
PHINode *LPHI = dyn_cast<PHINode>(LHS); PHINode *LPHI = dyn_cast<PHINode>(LHS);
PHINode *RPHI = dyn_cast<PHINode>(RHS); PHINode *RPHI = dyn_cast<PHINode>(RHS);
if ((LPHI && hasUndefInPHI(*LPHI)) || (RPHI && hasUndefInPHI(*RPHI))) if ((LPHI && HasUndefInPHI(*LPHI)) || (RPHI && HasUndefInPHI(*RPHI)))
return true; return true;
auto hasUndefInSelect = [](SelectInst &SI) { auto HasUndefInSelect = [](SelectInst &SI) {
if (isa<UndefValue>(SI.getTrueValue()) || if (isa<UndefValue>(SI.getTrueValue()) ||
isa<UndefValue>(SI.getFalseValue())) isa<UndefValue>(SI.getFalseValue()))
return true; return true;
@ -621,7 +619,7 @@ static bool EqualityPropUnSafe(Value &LoopCond) {
}; };
SelectInst *LSI = dyn_cast<SelectInst>(LHS); SelectInst *LSI = dyn_cast<SelectInst>(LHS);
SelectInst *RSI = dyn_cast<SelectInst>(RHS); SelectInst *RSI = dyn_cast<SelectInst>(RHS);
if ((LSI && hasUndefInSelect(*LSI)) || (RSI && hasUndefInSelect(*RSI))) if ((LSI && HasUndefInSelect(*LSI)) || (RSI && HasUndefInSelect(*RSI)))
return true; return true;
return false; return false;
} }
@ -633,35 +631,36 @@ bool LoopUnswitch::processCurrentLoop() {
initLoopData(); initLoopData();
// If LoopSimplify was unable to form a preheader, don't do any unswitching. // If LoopSimplify was unable to form a preheader, don't do any unswitching.
if (!loopPreheader) if (!LoopPreheader)
return false; return false;
// Loops with indirectbr cannot be cloned. // Loops with indirectbr cannot be cloned.
if (!currentLoop->isSafeToClone()) if (!CurrentLoop->isSafeToClone())
return false; return false;
// Without dedicated exits, splitting the exit edge may fail. // Without dedicated exits, splitting the exit edge may fail.
if (!currentLoop->hasDedicatedExits()) if (!CurrentLoop->hasDedicatedExits())
return false; return false;
LLVMContext &Context = loopHeader->getContext(); LLVMContext &Context = LoopHeader->getContext();
// Analyze loop cost, and stop unswitching if loop content can not be duplicated. // Analyze loop cost, and stop unswitching if loop content can not be duplicated.
if (!BranchesInfo.countLoop( if (!BranchesInfo.countLoop(
currentLoop, getAnalysis<TargetTransformInfoWrapperPass>().getTTI( CurrentLoop,
*currentLoop->getHeader()->getParent()), getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
*CurrentLoop->getHeader()->getParent()),
AC)) AC))
return false; return false;
// Try trivial unswitch first before loop over other basic blocks in the loop. // Try trivial unswitch first before loop over other basic blocks in the loop.
if (TryTrivialLoopUnswitch(Changed)) { if (tryTrivialLoopUnswitch(Changed)) {
return true; return true;
} }
// Do not do non-trivial unswitch while optimizing for size. // Do not do non-trivial unswitch while optimizing for size.
// FIXME: Use Function::hasOptSize(). // FIXME: Use Function::hasOptSize().
if (OptimizeForSize || if (OptimizeForSize ||
loopHeader->getParent()->hasFnAttribute(Attribute::OptimizeForSize)) LoopHeader->getParent()->hasFnAttribute(Attribute::OptimizeForSize))
return false; return false;
// Run through the instructions in the loop, keeping track of three things: // Run through the instructions in the loop, keeping track of three things:
@ -680,7 +679,7 @@ bool LoopUnswitch::processCurrentLoop() {
SmallVector<IntrinsicInst *, 4> Guards; SmallVector<IntrinsicInst *, 4> Guards;
for (const auto BB : currentLoop->blocks()) { for (const auto BB : CurrentLoop->blocks()) {
for (auto &I : *BB) { for (auto &I : *BB) {
auto CS = CallSite(&I); auto CS = CallSite(&I);
if (!CS) continue; if (!CS) continue;
@ -696,11 +695,11 @@ bool LoopUnswitch::processCurrentLoop() {
} }
for (IntrinsicInst *Guard : Guards) { for (IntrinsicInst *Guard : Guards) {
Value *LoopCond = FindLIVLoopCondition(Guard->getOperand(0), currentLoop, Value *LoopCond = findLIVLoopCondition(Guard->getOperand(0), CurrentLoop,
Changed, MSSAU.get()) Changed, MSSAU.get())
.first; .first;
if (LoopCond && if (LoopCond &&
UnswitchIfProfitable(LoopCond, ConstantInt::getTrue(Context))) { unswitchIfProfitable(LoopCond, ConstantInt::getTrue(Context))) {
// NB! Unswitching (if successful) could have erased some of the // NB! Unswitching (if successful) could have erased some of the
// instructions in Guards leaving dangling pointers there. This is fine // instructions in Guards leaving dangling pointers there. This is fine
// because we're returning now, and won't look at Guards again. // because we're returning now, and won't look at Guards again.
@ -712,8 +711,9 @@ bool LoopUnswitch::processCurrentLoop() {
// Loop over all of the basic blocks in the loop. If we find an interior // Loop over all of the basic blocks in the loop. If we find an interior
// block that is branching on a loop-invariant condition, we can unswitch this // block that is branching on a loop-invariant condition, we can unswitch this
// loop. // loop.
for (Loop::block_iterator I = currentLoop->block_begin(), for (Loop::block_iterator I = CurrentLoop->block_begin(),
E = currentLoop->block_end(); I != E; ++I) { E = CurrentLoop->block_end();
I != E; ++I) {
Instruction *TI = (*I)->getTerminator(); Instruction *TI = (*I)->getTerminator();
// Unswitching on a potentially uninitialized predicate is not // Unswitching on a potentially uninitialized predicate is not
@ -723,7 +723,7 @@ bool LoopUnswitch::processCurrentLoop() {
// This is a workaround for the discrepancy between LLVM IR and MSan // This is a workaround for the discrepancy between LLVM IR and MSan
// semantics. See PR28054 for more details. // semantics. See PR28054 for more details.
if (SanitizeMemory && if (SanitizeMemory &&
!SafetyInfo.isGuaranteedToExecute(*TI, DT, currentLoop)) !SafetyInfo.isGuaranteedToExecute(*TI, DT, CurrentLoop))
continue; continue;
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
@ -738,11 +738,11 @@ bool LoopUnswitch::processCurrentLoop() {
if (BI->isConditional()) { if (BI->isConditional()) {
// See if this, or some part of it, is loop invariant. If so, we can // See if this, or some part of it, is loop invariant. If so, we can
// unswitch on it if we desire. // unswitch on it if we desire.
Value *LoopCond = FindLIVLoopCondition(BI->getCondition(), currentLoop, Value *LoopCond = findLIVLoopCondition(BI->getCondition(), CurrentLoop,
Changed, MSSAU.get()) Changed, MSSAU.get())
.first; .first;
if (LoopCond && !EqualityPropUnSafe(*LoopCond) && if (LoopCond && !equalityPropUnSafe(*LoopCond) &&
UnswitchIfProfitable(LoopCond, ConstantInt::getTrue(Context), TI)) { unswitchIfProfitable(LoopCond, ConstantInt::getTrue(Context), TI)) {
++NumBranches; ++NumBranches;
return true; return true;
} }
@ -752,7 +752,7 @@ bool LoopUnswitch::processCurrentLoop() {
Value *LoopCond; Value *LoopCond;
OperatorChain OpChain; OperatorChain OpChain;
std::tie(LoopCond, OpChain) = std::tie(LoopCond, OpChain) =
FindLIVLoopCondition(SC, currentLoop, Changed, MSSAU.get()); findLIVLoopCondition(SC, CurrentLoop, Changed, MSSAU.get());
unsigned NumCases = SI->getNumCases(); unsigned NumCases = SI->getNumCases();
if (LoopCond && NumCases) { if (LoopCond && NumCases) {
@ -796,7 +796,7 @@ bool LoopUnswitch::processCurrentLoop() {
if (!UnswitchVal) if (!UnswitchVal)
continue; continue;
if (UnswitchIfProfitable(LoopCond, UnswitchVal)) { if (unswitchIfProfitable(LoopCond, UnswitchVal)) {
++NumSwitches; ++NumSwitches;
// In case of a full LIV, UnswitchVal is the value we unswitched out. // In case of a full LIV, UnswitchVal is the value we unswitched out.
// In case of a partial LIV, we only unswitch when its an AND-chain // In case of a partial LIV, we only unswitch when its an AND-chain
@ -812,11 +812,11 @@ bool LoopUnswitch::processCurrentLoop() {
for (BasicBlock::iterator BBI = (*I)->begin(), E = (*I)->end(); for (BasicBlock::iterator BBI = (*I)->begin(), E = (*I)->end();
BBI != E; ++BBI) BBI != E; ++BBI)
if (SelectInst *SI = dyn_cast<SelectInst>(BBI)) { if (SelectInst *SI = dyn_cast<SelectInst>(BBI)) {
Value *LoopCond = FindLIVLoopCondition(SI->getCondition(), currentLoop, Value *LoopCond = findLIVLoopCondition(SI->getCondition(), CurrentLoop,
Changed, MSSAU.get()) Changed, MSSAU.get())
.first; .first;
if (LoopCond && UnswitchIfProfitable(LoopCond, if (LoopCond &&
ConstantInt::getTrue(Context))) { unswitchIfProfitable(LoopCond, ConstantInt::getTrue(Context))) {
++NumSelects; ++NumSelects;
return true; return true;
} }
@ -875,38 +875,38 @@ static BasicBlock *isTrivialLoopExitBlock(Loop *L, BasicBlock *BB) {
return nullptr; return nullptr;
} }
/// We have found that we can unswitch currentLoop when LoopCond == Val to /// We have found that we can unswitch CurrentLoop when LoopCond == Val to
/// simplify the loop. If we decide that this is profitable, /// simplify the loop. If we decide that this is profitable,
/// unswitch the loop, reprocess the pieces, then return true. /// unswitch the loop, reprocess the pieces, then return true.
bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val, bool LoopUnswitch::unswitchIfProfitable(Value *LoopCond, Constant *Val,
Instruction *TI) { Instruction *TI) {
// Check to see if it would be profitable to unswitch current loop. // Check to see if it would be profitable to unswitch current loop.
if (!BranchesInfo.CostAllowsUnswitching()) { if (!BranchesInfo.costAllowsUnswitching()) {
LLVM_DEBUG(dbgs() << "NOT unswitching loop %" LLVM_DEBUG(dbgs() << "NOT unswitching loop %"
<< currentLoop->getHeader()->getName() << CurrentLoop->getHeader()->getName()
<< " at non-trivial condition '" << *Val << " at non-trivial condition '" << *Val
<< "' == " << *LoopCond << "\n" << "' == " << *LoopCond << "\n"
<< ". Cost too high.\n"); << ". Cost too high.\n");
return false; return false;
} }
if (hasBranchDivergence && if (HasBranchDivergence &&
getAnalysis<LegacyDivergenceAnalysis>().isDivergent(LoopCond)) { getAnalysis<LegacyDivergenceAnalysis>().isDivergent(LoopCond)) {
LLVM_DEBUG(dbgs() << "NOT unswitching loop %" LLVM_DEBUG(dbgs() << "NOT unswitching loop %"
<< currentLoop->getHeader()->getName() << CurrentLoop->getHeader()->getName()
<< " at non-trivial condition '" << *Val << " at non-trivial condition '" << *Val
<< "' == " << *LoopCond << "\n" << "' == " << *LoopCond << "\n"
<< ". Condition is divergent.\n"); << ". Condition is divergent.\n");
return false; return false;
} }
UnswitchNontrivialCondition(LoopCond, Val, currentLoop, TI); unswitchNontrivialCondition(LoopCond, Val, CurrentLoop, TI);
return true; return true;
} }
/// Recursively clone the specified loop and all of its children, /// Recursively clone the specified loop and all of its children,
/// mapping the blocks with the specified map. /// mapping the blocks with the specified map.
static Loop *CloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM, static Loop *cloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM, LoopInfo *LI,
LoopInfo *LI, LPPassManager *LPM) { LPPassManager *LPM) {
Loop &New = *LI->AllocateLoop(); Loop &New = *LI->AllocateLoop();
if (PL) if (PL)
PL->addChildLoop(&New); PL->addChildLoop(&New);
@ -922,7 +922,7 @@ static Loop *CloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM,
// Add all of the subloops to the new loop. // Add all of the subloops to the new loop.
for (Loop *I : *L) for (Loop *I : *L)
CloneLoop(I, &New, VM, LI, LPM); cloneLoop(I, &New, VM, LI, LPM);
return &New; return &New;
} }
@ -930,7 +930,7 @@ static Loop *CloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM,
/// Emit a conditional branch on two values if LIC == Val, branch to TrueDst, /// Emit a conditional branch on two values if LIC == Val, branch to TrueDst,
/// otherwise branch to FalseDest. Insert the code immediately before OldBranch /// otherwise branch to FalseDest. Insert the code immediately before OldBranch
/// and remove (but not erase!) it from the function. /// and remove (but not erase!) it from the function.
void LoopUnswitch::EmitPreheaderBranchOnCondition(Value *LIC, Constant *Val, void LoopUnswitch::emitPreheaderBranchOnCondition(Value *LIC, Constant *Val,
BasicBlock *TrueDest, BasicBlock *TrueDest,
BasicBlock *FalseDest, BasicBlock *FalseDest,
BranchInst *OldBranch, BranchInst *OldBranch,
@ -997,11 +997,11 @@ void LoopUnswitch::EmitPreheaderBranchOnCondition(Value *LIC, Constant *Val,
/// that doesn't execute its body has no side-effects), unswitch it. This /// that doesn't execute its body has no side-effects), unswitch it. This
/// doesn't involve any code duplication, just moving the conditional branch /// doesn't involve any code duplication, just moving the conditional branch
/// outside of the loop and updating loop info. /// outside of the loop and updating loop info.
void LoopUnswitch::UnswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val, void LoopUnswitch::unswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val,
BasicBlock *ExitBlock, BasicBlock *ExitBlock,
Instruction *TI) { Instruction *TI) {
LLVM_DEBUG(dbgs() << "loop-unswitch: Trivial-Unswitch loop %" LLVM_DEBUG(dbgs() << "loop-unswitch: Trivial-Unswitch loop %"
<< loopHeader->getName() << " [" << L->getBlocks().size() << LoopHeader->getName() << " [" << L->getBlocks().size()
<< " blocks] in Function " << " blocks] in Function "
<< L->getHeader()->getParent()->getName() << L->getHeader()->getParent()->getName()
<< " on cond: " << *Val << " == " << *Cond << "\n"); << " on cond: " << *Val << " == " << *Cond << "\n");
@ -1011,9 +1011,9 @@ void LoopUnswitch::UnswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val,
SEWP->getSE().forgetTopmostLoop(L); SEWP->getSE().forgetTopmostLoop(L);
// First step, split the preheader, so that we know that there is a safe place // First step, split the preheader, so that we know that there is a safe place
// to insert the conditional branch. We will change loopPreheader to have a // to insert the conditional branch. We will change LoopPreheader to have a
// conditional branch on Cond. // conditional branch on Cond.
BasicBlock *NewPH = SplitEdge(loopPreheader, loopHeader, DT, LI, MSSAU.get()); BasicBlock *NewPH = SplitEdge(LoopPreheader, LoopHeader, DT, LI, MSSAU.get());
// Now that we have a place to insert the conditional branch, create a place // Now that we have a place to insert the conditional branch, create a place
// to branch to: this is the exit block out of the loop that we should // to branch to: this is the exit block out of the loop that we should
@ -1029,21 +1029,21 @@ void LoopUnswitch::UnswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val,
// Okay, now we have a position to branch from and a position to branch to, // Okay, now we have a position to branch from and a position to branch to,
// insert the new conditional branch. // insert the new conditional branch.
auto *OldBranch = dyn_cast<BranchInst>(loopPreheader->getTerminator()); auto *OldBranch = dyn_cast<BranchInst>(LoopPreheader->getTerminator());
assert(OldBranch && "Failed to split the preheader"); assert(OldBranch && "Failed to split the preheader");
EmitPreheaderBranchOnCondition(Cond, Val, NewExit, NewPH, OldBranch, TI); emitPreheaderBranchOnCondition(Cond, Val, NewExit, NewPH, OldBranch, TI);
// EmitPreheaderBranchOnCondition removed the OldBranch from the function. // emitPreheaderBranchOnCondition removed the OldBranch from the function.
// Delete it, as it is no longer needed. // Delete it, as it is no longer needed.
delete OldBranch; delete OldBranch;
// We need to reprocess this loop, it could be unswitched again. // We need to reprocess this loop, it could be unswitched again.
redoLoop = true; RedoLoop = true;
// Now that we know that the loop is never entered when this condition is a // Now that we know that the loop is never entered when this condition is a
// particular value, rewrite the loop with this info. We know that this will // particular value, rewrite the loop with this info. We know that this will
// at least eliminate the old branch. // at least eliminate the old branch.
RewriteLoopBodyWithConditionConstant(L, Cond, Val, false); rewriteLoopBodyWithConditionConstant(L, Cond, Val, /*IsEqual=*/false);
++NumTrivial; ++NumTrivial;
} }
@ -1054,8 +1054,8 @@ void LoopUnswitch::UnswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val,
/// produces no code duplications (equivalently, it produces a simpler loop and /// produces no code duplications (equivalently, it produces a simpler loop and
/// a new empty loop, which gets deleted). Therefore always unswitch trivial /// a new empty loop, which gets deleted). Therefore always unswitch trivial
/// condition. /// condition.
bool LoopUnswitch::TryTrivialLoopUnswitch(bool &Changed) { bool LoopUnswitch::tryTrivialLoopUnswitch(bool &Changed) {
BasicBlock *CurrentBB = currentLoop->getHeader(); BasicBlock *CurrentBB = CurrentLoop->getHeader();
Instruction *CurrentTerm = CurrentBB->getTerminator(); Instruction *CurrentTerm = CurrentBB->getTerminator();
LLVMContext &Context = CurrentBB->getContext(); LLVMContext &Context = CurrentBB->getContext();
@ -1080,7 +1080,7 @@ bool LoopUnswitch::TryTrivialLoopUnswitch(bool &Changed) {
// we can not reach any trivial condition candidates (unfoldable // we can not reach any trivial condition candidates (unfoldable
// branch instructions or switch instructions) and no unswitch // branch instructions or switch instructions) and no unswitch
// can happen. Exit and return false. // can happen. Exit and return false.
if (!currentLoop->contains(CurrentBB) || !Visited.insert(CurrentBB).second) if (!CurrentLoop->contains(CurrentBB) || !Visited.insert(CurrentBB).second)
return false; return false;
// Check if this loop will execute any side-effecting instructions (e.g. // Check if this loop will execute any side-effecting instructions (e.g.
@ -1127,7 +1127,7 @@ bool LoopUnswitch::TryTrivialLoopUnswitch(bool &Changed) {
if (!BI->isConditional()) if (!BI->isConditional())
return false; return false;
Value *LoopCond = FindLIVLoopCondition(BI->getCondition(), currentLoop, Value *LoopCond = findLIVLoopCondition(BI->getCondition(), CurrentLoop,
Changed, MSSAU.get()) Changed, MSSAU.get())
.first; .first;
@ -1140,11 +1140,11 @@ bool LoopUnswitch::TryTrivialLoopUnswitch(bool &Changed) {
// exit through a unique exit block without having any // exit through a unique exit block without having any
// side-effects. If so, determine the value of Cond that causes // side-effects. If so, determine the value of Cond that causes
// it to do this. // it to do this.
if ((LoopExitBB = isTrivialLoopExitBlock(currentLoop, if ((LoopExitBB =
BI->getSuccessor(0)))) { isTrivialLoopExitBlock(CurrentLoop, BI->getSuccessor(0)))) {
CondVal = ConstantInt::getTrue(Context); CondVal = ConstantInt::getTrue(Context);
} else if ((LoopExitBB = isTrivialLoopExitBlock(currentLoop, } else if ((LoopExitBB =
BI->getSuccessor(1)))) { isTrivialLoopExitBlock(CurrentLoop, BI->getSuccessor(1)))) {
CondVal = ConstantInt::getFalse(Context); CondVal = ConstantInt::getFalse(Context);
} }
@ -1153,16 +1153,16 @@ bool LoopUnswitch::TryTrivialLoopUnswitch(bool &Changed) {
if (!LoopExitBB || isa<PHINode>(LoopExitBB->begin())) if (!LoopExitBB || isa<PHINode>(LoopExitBB->begin()))
return false; // Can't handle this. return false; // Can't handle this.
if (EqualityPropUnSafe(*LoopCond)) if (equalityPropUnSafe(*LoopCond))
return false; return false;
UnswitchTrivialCondition(currentLoop, LoopCond, CondVal, LoopExitBB, unswitchTrivialCondition(CurrentLoop, LoopCond, CondVal, LoopExitBB,
CurrentTerm); CurrentTerm);
++NumBranches; ++NumBranches;
return true; return true;
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(CurrentTerm)) { } else if (SwitchInst *SI = dyn_cast<SwitchInst>(CurrentTerm)) {
// If this isn't switching on an invariant condition, we can't unswitch it. // If this isn't switching on an invariant condition, we can't unswitch it.
Value *LoopCond = FindLIVLoopCondition(SI->getCondition(), currentLoop, Value *LoopCond = findLIVLoopCondition(SI->getCondition(), CurrentLoop,
Changed, MSSAU.get()) Changed, MSSAU.get())
.first; .first;
@ -1180,7 +1180,7 @@ bool LoopUnswitch::TryTrivialLoopUnswitch(bool &Changed) {
for (auto Case : SI->cases()) { for (auto Case : SI->cases()) {
BasicBlock *LoopExitCandidate; BasicBlock *LoopExitCandidate;
if ((LoopExitCandidate = if ((LoopExitCandidate =
isTrivialLoopExitBlock(currentLoop, Case.getCaseSuccessor()))) { isTrivialLoopExitBlock(CurrentLoop, Case.getCaseSuccessor()))) {
// Okay, we found a trivial case, remember the value that is trivial. // Okay, we found a trivial case, remember the value that is trivial.
ConstantInt *CaseVal = Case.getCaseValue(); ConstantInt *CaseVal = Case.getCaseValue();
@ -1199,7 +1199,7 @@ bool LoopUnswitch::TryTrivialLoopUnswitch(bool &Changed) {
if (!LoopExitBB || isa<PHINode>(LoopExitBB->begin())) if (!LoopExitBB || isa<PHINode>(LoopExitBB->begin()))
return false; // Can't handle this. return false; // Can't handle this.
UnswitchTrivialCondition(currentLoop, LoopCond, CondVal, LoopExitBB, unswitchTrivialCondition(CurrentLoop, LoopCond, CondVal, LoopExitBB,
nullptr); nullptr);
// We are only unswitching full LIV. // We are only unswitching full LIV.
@ -1212,11 +1212,11 @@ bool LoopUnswitch::TryTrivialLoopUnswitch(bool &Changed) {
/// Split all of the edges from inside the loop to their exit blocks. /// Split all of the edges from inside the loop to their exit blocks.
/// Update the appropriate Phi nodes as we do so. /// Update the appropriate Phi nodes as we do so.
void LoopUnswitch::SplitExitEdges(Loop *L, void LoopUnswitch::splitExitEdges(
const SmallVectorImpl<BasicBlock *> &ExitBlocks){ Loop *L, const SmallVectorImpl<BasicBlock *> &ExitBlocks) {
for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) { for (unsigned I = 0, E = ExitBlocks.size(); I != E; ++I) {
BasicBlock *ExitBlock = ExitBlocks[i]; BasicBlock *ExitBlock = ExitBlocks[I];
SmallVector<BasicBlock *, 4> Preds(pred_begin(ExitBlock), SmallVector<BasicBlock *, 4> Preds(pred_begin(ExitBlock),
pred_end(ExitBlock)); pred_end(ExitBlock));
@ -1230,11 +1230,11 @@ void LoopUnswitch::SplitExitEdges(Loop *L,
/// We determined that the loop is profitable to unswitch when LIC equal Val. /// We determined that the loop is profitable to unswitch when LIC equal Val.
/// Split it into loop versions and test the condition outside of either loop. /// Split it into loop versions and test the condition outside of either loop.
/// Return the loops created as Out1/Out2. /// Return the loops created as Out1/Out2.
void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val, void LoopUnswitch::unswitchNontrivialCondition(Value *LIC, Constant *Val,
Loop *L, Instruction *TI) { Loop *L, Instruction *TI) {
Function *F = loopHeader->getParent(); Function *F = LoopHeader->getParent();
LLVM_DEBUG(dbgs() << "loop-unswitch: Unswitching loop %" LLVM_DEBUG(dbgs() << "loop-unswitch: Unswitching loop %"
<< loopHeader->getName() << " [" << L->getBlocks().size() << LoopHeader->getName() << " [" << L->getBlocks().size()
<< " blocks] in Function " << F->getName() << " when '" << " blocks] in Function " << F->getName() << " when '"
<< *Val << "' == " << *LIC << "\n"); << *Val << "' == " << *LIC << "\n");
@ -1252,7 +1252,7 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
// First step, split the preheader and exit blocks, and add these blocks to // First step, split the preheader and exit blocks, and add these blocks to
// the LoopBlocks list. // the LoopBlocks list.
BasicBlock *NewPreheader = BasicBlock *NewPreheader =
SplitEdge(loopPreheader, loopHeader, DT, LI, MSSAU.get()); SplitEdge(LoopPreheader, LoopHeader, DT, LI, MSSAU.get());
LoopBlocks.push_back(NewPreheader); LoopBlocks.push_back(NewPreheader);
// We want the loop to come after the preheader, but before the exit blocks. // We want the loop to come after the preheader, but before the exit blocks.
@ -1263,7 +1263,7 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
// Split all of the edges from inside the loop to their exit blocks. Update // Split all of the edges from inside the loop to their exit blocks. Update
// the appropriate Phi nodes as we do so. // the appropriate Phi nodes as we do so.
SplitExitEdges(L, ExitBlocks); splitExitEdges(L, ExitBlocks);
// The exit blocks may have been changed due to edge splitting, recompute. // The exit blocks may have been changed due to edge splitting, recompute.
ExitBlocks.clear(); ExitBlocks.clear();
@ -1277,11 +1277,11 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
// the instructions and blocks. // the instructions and blocks.
NewBlocks.reserve(LoopBlocks.size()); NewBlocks.reserve(LoopBlocks.size());
ValueToValueMapTy VMap; ValueToValueMapTy VMap;
for (unsigned i = 0, e = LoopBlocks.size(); i != e; ++i) { for (unsigned I = 0, E = LoopBlocks.size(); I != E; ++I) {
BasicBlock *NewBB = CloneBasicBlock(LoopBlocks[i], VMap, ".us", F); BasicBlock *NewBB = CloneBasicBlock(LoopBlocks[I], VMap, ".us", F);
NewBlocks.push_back(NewBB); NewBlocks.push_back(NewBB);
VMap[LoopBlocks[i]] = NewBB; // Keep the BB mapping. VMap[LoopBlocks[I]] = NewBB; // Keep the BB mapping.
} }
// Splice the newly inserted blocks into the function right before the // Splice the newly inserted blocks into the function right before the
@ -1291,7 +1291,7 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
NewBlocks[0]->getIterator(), F->end()); NewBlocks[0]->getIterator(), F->end());
// Now we create the new Loop object for the versioned loop. // Now we create the new Loop object for the versioned loop.
Loop *NewLoop = CloneLoop(L, L->getParentLoop(), VMap, LI, LPM); Loop *NewLoop = cloneLoop(L, L->getParentLoop(), VMap, LI, LPM);
// Recalculate unswitching quota, inherit simplified switches info for NewBB, // Recalculate unswitching quota, inherit simplified switches info for NewBB,
// Probably clone more loop-unswitch related loop properties. // Probably clone more loop-unswitch related loop properties.
@ -1304,10 +1304,10 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
ParentLoop->addBasicBlockToLoop(NewBlocks[0], *LI); ParentLoop->addBasicBlockToLoop(NewBlocks[0], *LI);
} }
for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) { for (unsigned EBI = 0, EBE = ExitBlocks.size(); EBI != EBE; ++EBI) {
BasicBlock *NewExit = cast<BasicBlock>(VMap[ExitBlocks[i]]); BasicBlock *NewExit = cast<BasicBlock>(VMap[ExitBlocks[EBI]]);
// The new exit block should be in the same loop as the old one. // The new exit block should be in the same loop as the old one.
if (Loop *ExitBBLoop = LI->getLoopFor(ExitBlocks[i])) if (Loop *ExitBBLoop = LI->getLoopFor(ExitBlocks[EBI]))
ExitBBLoop->addBasicBlockToLoop(NewExit, *LI); ExitBBLoop->addBasicBlockToLoop(NewExit, *LI);
assert(NewExit->getTerminator()->getNumSuccessors() == 1 && assert(NewExit->getTerminator()->getNumSuccessors() == 1 &&
@ -1317,7 +1317,7 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
// If the successor of the exit block had PHI nodes, add an entry for // If the successor of the exit block had PHI nodes, add an entry for
// NewExit. // NewExit.
for (PHINode &PN : ExitSucc->phis()) { for (PHINode &PN : ExitSucc->phis()) {
Value *V = PN.getIncomingValueForBlock(ExitBlocks[i]); Value *V = PN.getIncomingValueForBlock(ExitBlocks[EBI]);
ValueToValueMapTy::iterator It = VMap.find(V); ValueToValueMapTy::iterator It = VMap.find(V);
if (It != VMap.end()) V = It->second; if (It != VMap.end()) V = It->second;
PN.addIncoming(V, NewExit); PN.addIncoming(V, NewExit);
@ -1338,8 +1338,8 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
} }
// Rewrite the code to refer to itself. // Rewrite the code to refer to itself.
for (unsigned i = 0, e = NewBlocks.size(); i != e; ++i) { for (unsigned NBI = 0, NBE = NewBlocks.size(); NBI != NBE; ++NBI) {
for (Instruction &I : *NewBlocks[i]) { for (Instruction &I : *NewBlocks[NBI]) {
RemapInstruction(&I, VMap, RemapInstruction(&I, VMap,
RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
if (auto *II = dyn_cast<IntrinsicInst>(&I)) if (auto *II = dyn_cast<IntrinsicInst>(&I))
@ -1349,7 +1349,7 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
} }
// Rewrite the original preheader to select between versions of the loop. // Rewrite the original preheader to select between versions of the loop.
BranchInst *OldBR = cast<BranchInst>(loopPreheader->getTerminator()); BranchInst *OldBR = cast<BranchInst>(LoopPreheader->getTerminator());
assert(OldBR->isUnconditional() && OldBR->getSuccessor(0) == LoopBlocks[0] && assert(OldBR->isUnconditional() && OldBR->getSuccessor(0) == LoopBlocks[0] &&
"Preheader splitting did not work correctly!"); "Preheader splitting did not work correctly!");
@ -1362,7 +1362,7 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
} }
// Emit the new branch that selects between the two versions of this loop. // Emit the new branch that selects between the two versions of this loop.
EmitPreheaderBranchOnCondition(LIC, Val, NewBlocks[0], LoopBlocks[0], OldBR, emitPreheaderBranchOnCondition(LIC, Val, NewBlocks[0], LoopBlocks[0], OldBR,
TI); TI);
if (MSSAU) { if (MSSAU) {
// Update MemoryPhis in Exit blocks. // Update MemoryPhis in Exit blocks.
@ -1372,11 +1372,11 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
} }
// The OldBr was replaced by a new one and removed (but not erased) by // The OldBr was replaced by a new one and removed (but not erased) by
// EmitPreheaderBranchOnCondition. It is no longer needed, so delete it. // emitPreheaderBranchOnCondition. It is no longer needed, so delete it.
delete OldBR; delete OldBR;
LoopProcessWorklist.push_back(NewLoop); LoopProcessWorklist.push_back(NewLoop);
redoLoop = true; RedoLoop = true;
// Keep a WeakTrackingVH holding onto LIC. If the first call to // Keep a WeakTrackingVH holding onto LIC. If the first call to
// RewriteLoopBody // RewriteLoopBody
@ -1387,22 +1387,23 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
// Now we rewrite the original code to know that the condition is true and the // Now we rewrite the original code to know that the condition is true and the
// new code to know that the condition is false. // new code to know that the condition is false.
RewriteLoopBodyWithConditionConstant(L, LIC, Val, false); rewriteLoopBodyWithConditionConstant(L, LIC, Val, /*IsEqual=*/false);
// It's possible that simplifying one loop could cause the other to be // It's possible that simplifying one loop could cause the other to be
// changed to another value or a constant. If its a constant, don't simplify // changed to another value or a constant. If its a constant, don't simplify
// it. // it.
if (!LoopProcessWorklist.empty() && LoopProcessWorklist.back() == NewLoop && if (!LoopProcessWorklist.empty() && LoopProcessWorklist.back() == NewLoop &&
LICHandle && !isa<Constant>(LICHandle)) LICHandle && !isa<Constant>(LICHandle))
RewriteLoopBodyWithConditionConstant(NewLoop, LICHandle, Val, true); rewriteLoopBodyWithConditionConstant(NewLoop, LICHandle, Val,
/*IsEqual=*/true);
if (MSSA && VerifyMemorySSA) if (MSSA && VerifyMemorySSA)
MSSA->verifyMemorySSA(); MSSA->verifyMemorySSA();
} }
/// Remove all instances of I from the worklist vector specified. /// Remove all instances of I from the worklist vector specified.
static void RemoveFromWorklist(Instruction *I, static void removeFromWorklist(Instruction *I,
std::vector<Instruction*> &Worklist) { std::vector<Instruction *> &Worklist) {
Worklist.erase(std::remove(Worklist.begin(), Worklist.end(), I), Worklist.erase(std::remove(Worklist.begin(), Worklist.end(), I),
Worklist.end()); Worklist.end());
@ -1410,7 +1411,7 @@ static void RemoveFromWorklist(Instruction *I,
/// When we find that I really equals V, remove I from the /// When we find that I really equals V, remove I from the
/// program, replacing all uses with V and update the worklist. /// program, replacing all uses with V and update the worklist.
static void ReplaceUsesOfWith(Instruction *I, Value *V, static void replaceUsesOfWith(Instruction *I, Value *V,
std::vector<Instruction *> &Worklist, Loop *L, std::vector<Instruction *> &Worklist, Loop *L,
LPPassManager *LPM, MemorySSAUpdater *MSSAU) { LPPassManager *LPM, MemorySSAUpdater *MSSAU) {
LLVM_DEBUG(dbgs() << "Replace with '" << *V << "': " << *I << "\n"); LLVM_DEBUG(dbgs() << "Replace with '" << *V << "': " << *I << "\n");
@ -1423,7 +1424,7 @@ static void ReplaceUsesOfWith(Instruction *I, Value *V,
// Add users to the worklist which may be simplified now. // Add users to the worklist which may be simplified now.
for (User *U : I->users()) for (User *U : I->users())
Worklist.push_back(cast<Instruction>(U)); Worklist.push_back(cast<Instruction>(U));
RemoveFromWorklist(I, Worklist); removeFromWorklist(I, Worklist);
I->replaceAllUsesWith(V); I->replaceAllUsesWith(V);
if (!I->mayHaveSideEffects()) { if (!I->mayHaveSideEffects()) {
if (MSSAU) if (MSSAU)
@ -1436,7 +1437,7 @@ static void ReplaceUsesOfWith(Instruction *I, Value *V,
/// We know either that the value LIC has the value specified by Val in the /// We know either that the value LIC has the value specified by Val in the
/// specified loop, or we know it does NOT have that value. /// specified loop, or we know it does NOT have that value.
/// Rewrite any uses of LIC or of properties correlated to it. /// Rewrite any uses of LIC or of properties correlated to it.
void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC, void LoopUnswitch::rewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
Constant *Val, Constant *Val,
bool IsEqual) { bool IsEqual) {
assert(!isa<Constant>(LIC) && "Why are we unswitching on a constant?"); assert(!isa<Constant>(LIC) && "Why are we unswitching on a constant?");
@ -1474,7 +1475,7 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
for (Instruction *UI : Worklist) for (Instruction *UI : Worklist)
UI->replaceUsesOfWith(LIC, Replacement); UI->replaceUsesOfWith(LIC, Replacement);
SimplifyCode(Worklist, L); simplifyCode(Worklist, L);
return; return;
} }
@ -1488,7 +1489,7 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
// At this point, we know LIC is definitely not Val. Try to use some simple // At this point, we know LIC is definitely not Val. Try to use some simple
// logic to simplify the user w.r.t. to the context. // logic to simplify the user w.r.t. to the context.
if (Value *Replacement = SimplifyInstructionWithNotEqual(UI, LIC, Val)) { if (Value *Replacement = simplifyInstructionWithNotEqual(UI, LIC, Val)) {
if (LI->replacementPreservesLCSSAForm(UI, Replacement)) { if (LI->replacementPreservesLCSSAForm(UI, Replacement)) {
// This in-loop instruction has been simplified w.r.t. its context, // This in-loop instruction has been simplified w.r.t. its context,
// i.e. LIC != Val, make sure we propagate its replacement value to // i.e. LIC != Val, make sure we propagate its replacement value to
@ -1502,7 +1503,7 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
} }
} }
// This is a LIC user, push it into the worklist so that SimplifyCode can // This is a LIC user, push it into the worklist so that simplifyCode can
// attempt to simplify it. // attempt to simplify it.
Worklist.push_back(UI); Worklist.push_back(UI);
@ -1564,7 +1565,7 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
DT->addNewBlock(Abort, NewSISucc); DT->addNewBlock(Abort, NewSISucc);
} }
SimplifyCode(Worklist, L); simplifyCode(Worklist, L);
} }
/// Now that we have simplified some instructions in the loop, walk over it and /// Now that we have simplified some instructions in the loop, walk over it and
@ -1575,7 +1576,7 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
/// FIXME: When the loop optimizer is more mature, separate this out to a new /// FIXME: When the loop optimizer is more mature, separate this out to a new
/// pass. /// pass.
/// ///
void LoopUnswitch::SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L) { void LoopUnswitch::simplifyCode(std::vector<Instruction *> &Worklist, Loop *L) {
const DataLayout &DL = L->getHeader()->getModule()->getDataLayout(); const DataLayout &DL = L->getHeader()->getModule()->getDataLayout();
while (!Worklist.empty()) { while (!Worklist.empty()) {
Instruction *I = Worklist.back(); Instruction *I = Worklist.back();
@ -1589,7 +1590,7 @@ void LoopUnswitch::SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L) {
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
if (Instruction *Use = dyn_cast<Instruction>(I->getOperand(i))) if (Instruction *Use = dyn_cast<Instruction>(I->getOperand(i)))
Worklist.push_back(Use); Worklist.push_back(Use);
RemoveFromWorklist(I, Worklist); removeFromWorklist(I, Worklist);
if (MSSAU) if (MSSAU)
MSSAU->removeMemoryAccess(I); MSSAU->removeMemoryAccess(I);
I->eraseFromParent(); I->eraseFromParent();
@ -1602,7 +1603,7 @@ void LoopUnswitch::SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L) {
// 'false'. TODO: update the domtree properly so we can pass it here. // 'false'. TODO: update the domtree properly so we can pass it here.
if (Value *V = SimplifyInstruction(I, DL)) if (Value *V = SimplifyInstruction(I, DL))
if (LI->replacementPreservesLCSSAForm(I, V)) { if (LI->replacementPreservesLCSSAForm(I, V)) {
ReplaceUsesOfWith(I, V, Worklist, L, LPM, MSSAU.get()); replaceUsesOfWith(I, V, Worklist, L, LPM, MSSAU.get());
continue; continue;
} }
@ -1619,7 +1620,7 @@ void LoopUnswitch::SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L) {
assert(SinglePred == Pred && "CFG broken"); assert(SinglePred == Pred && "CFG broken");
// Make the LPM and Worklist updates specific to LoopUnswitch. // Make the LPM and Worklist updates specific to LoopUnswitch.
RemoveFromWorklist(BI, Worklist); removeFromWorklist(BI, Worklist);
auto SuccIt = Succ->begin(); auto SuccIt = Succ->begin();
while (PHINode *PN = dyn_cast<PHINode>(SuccIt++)) { while (PHINode *PN = dyn_cast<PHINode>(SuccIt++)) {
for (unsigned It = 0, E = PN->getNumOperands(); It != E; ++It) for (unsigned It = 0, E = PN->getNumOperands(); It != E; ++It)
@ -1627,7 +1628,7 @@ void LoopUnswitch::SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L) {
Worklist.push_back(Use); Worklist.push_back(Use);
for (User *U : PN->users()) for (User *U : PN->users())
Worklist.push_back(cast<Instruction>(U)); Worklist.push_back(cast<Instruction>(U));
RemoveFromWorklist(PN, Worklist); removeFromWorklist(PN, Worklist);
++NumSimplify; ++NumSimplify;
} }
// Merge the block and make the remaining analyses updates. // Merge the block and make the remaining analyses updates.
@ -1644,7 +1645,7 @@ void LoopUnswitch::SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L) {
/// Simple simplifications we can do given the information that Cond is /// Simple simplifications we can do given the information that Cond is
/// definitely not equal to Val. /// definitely not equal to Val.
Value *LoopUnswitch::SimplifyInstructionWithNotEqual(Instruction *Inst, Value *LoopUnswitch::simplifyInstructionWithNotEqual(Instruction *Inst,
Value *Invariant, Value *Invariant,
Constant *Val) { Constant *Val) {
// icmp eq cond, val -> false // icmp eq cond, val -> false

View File

@ -2465,7 +2465,7 @@ turnGuardIntoBranch(IntrinsicInst *GI, Loop &L,
/// unswitch candidates, making adequate predictions instead of wild guesses. /// unswitch candidates, making adequate predictions instead of wild guesses.
/// That requires knowing not just the number of "remaining" candidates but /// That requires knowing not just the number of "remaining" candidates but
/// also costs of unswitching for each of these candidates. /// also costs of unswitching for each of these candidates.
static int calculateUnswitchCostMultiplier( static int CalculateUnswitchCostMultiplier(
Instruction &TI, Loop &L, LoopInfo &LI, DominatorTree &DT, Instruction &TI, Loop &L, LoopInfo &LI, DominatorTree &DT,
ArrayRef<std::pair<Instruction *, TinyPtrVector<Value *>>> ArrayRef<std::pair<Instruction *, TinyPtrVector<Value *>>>
UnswitchCandidates) { UnswitchCandidates) {
@ -2754,7 +2754,7 @@ unswitchBestCondition(Loop &L, DominatorTree &DT, LoopInfo &LI,
// exponential behavior of loop-unswitch. // exponential behavior of loop-unswitch.
if (EnableUnswitchCostMultiplier) { if (EnableUnswitchCostMultiplier) {
int CostMultiplier = int CostMultiplier =
calculateUnswitchCostMultiplier(TI, L, LI, DT, UnswitchCandidates); CalculateUnswitchCostMultiplier(TI, L, LI, DT, UnswitchCandidates);
assert( assert(
(CostMultiplier > 0 && CostMultiplier <= UnswitchThreshold) && (CostMultiplier > 0 && CostMultiplier <= UnswitchThreshold) &&
"cost multiplier needs to be in the range of 1..UnswitchThreshold"); "cost multiplier needs to be in the range of 1..UnswitchThreshold");