diff options
author | Max Kazantsev <max.kazantsev@azul.com> | 2018-11-06 02:44:49 +0000 |
---|---|---|
committer | Max Kazantsev <max.kazantsev@azul.com> | 2018-11-06 02:44:49 +0000 |
commit | 69f6dfa0f8c54eacd02eebb2f2ef9f49c487675b (patch) | |
tree | 5bb760bf179fd6fca1c4f75b3aba0ffaba97a7d6 /llvm/lib | |
parent | 536a5c469193ccf4c57f70179a761d1ee731f21a (diff) | |
download | bcm5719-llvm-69f6dfa0f8c54eacd02eebb2f2ef9f49c487675b.tar.gz bcm5719-llvm-69f6dfa0f8c54eacd02eebb2f2ef9f49c487675b.zip |
[LICM] Use ICFLoopSafetyInfo in LICM
This patch makes LICM use `ICFLoopSafetyInfo` that is a smarter version
of LoopSafetyInfo that leverages power of Implicit Control Flow Tracking
to keep track of throwing instructions and give less pessimistic answers
to queries related to throws.
The ICFLoopSafetyInfo itself has been introduced in rL344601. This patch
enables it in LICM only.
Differential Revision: https://reviews.llvm.org/D50377
Reviewed By: apilipenko
llvm-svn: 346201
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Scalar/LICM.cpp | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index d379808cd7f..d6dfdc7efed 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -103,10 +103,10 @@ static bool isNotUsedOrFreeInLoop(const Instruction &I, const Loop *CurLoop, const LoopSafetyInfo *SafetyInfo, TargetTransformInfo *TTI, bool &FreeInLoop); static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop, - LoopSafetyInfo *SafetyInfo, + ICFLoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE); static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT, - const Loop *CurLoop, LoopSafetyInfo *SafetyInfo, + const Loop *CurLoop, ICFLoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE, bool FreeInLoop); static bool isSafeToExecuteUnconditionally(Instruction &Inst, const DominatorTree *DT, @@ -123,7 +123,8 @@ CloneInstructionInExitBlock(Instruction &I, BasicBlock &ExitBlock, PHINode &PN, const LoopInfo *LI, const LoopSafetyInfo *SafetyInfo); -static void eraseInstruction(Instruction &I, AliasSetTracker *AST); +static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo, + AliasSetTracker *AST); namespace { struct LoopInvariantCodeMotion { @@ -269,7 +270,7 @@ bool LoopInvariantCodeMotion::runOnLoop( BasicBlock *Preheader = L->getLoopPreheader(); // Compute loop safety information. - SimpleLoopSafetyInfo SafetyInfo; + ICFLoopSafetyInfo SafetyInfo(DT); SafetyInfo.computeLoopSafetyInfo(L); // We want to visit all of the instructions in this loop... that are not parts @@ -376,7 +377,7 @@ bool LoopInvariantCodeMotion::runOnLoop( bool llvm::sinkRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, DominatorTree *DT, TargetLibraryInfo *TLI, TargetTransformInfo *TTI, Loop *CurLoop, - AliasSetTracker *CurAST, LoopSafetyInfo *SafetyInfo, + AliasSetTracker *CurAST, ICFLoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE) { // Verify inputs. @@ -406,7 +407,7 @@ bool llvm::sinkRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, LLVM_DEBUG(dbgs() << "LICM deleting dead inst: " << I << '\n'); salvageDebugInfo(I); ++II; - eraseInstruction(I, CurAST); + eraseInstruction(I, *SafetyInfo, CurAST); Changed = true; continue; } @@ -423,7 +424,7 @@ bool llvm::sinkRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, if (sink(I, LI, DT, CurLoop, SafetyInfo, ORE, FreeInLoop)) { if (!FreeInLoop) { ++II; - eraseInstruction(I, CurAST); + eraseInstruction(I, *SafetyInfo, CurAST); } Changed = true; } @@ -440,7 +441,7 @@ bool llvm::sinkRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, /// bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, DominatorTree *DT, TargetLibraryInfo *TLI, Loop *CurLoop, - AliasSetTracker *CurAST, LoopSafetyInfo *SafetyInfo, + AliasSetTracker *CurAST, ICFLoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE) { // Verify inputs. assert(N != nullptr && AA != nullptr && LI != nullptr && DT != nullptr && @@ -481,7 +482,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, CurAST->copyValue(&I, C); I.replaceAllUsesWith(C); if (isInstructionTriviallyDead(&I, TLI)) - eraseInstruction(I, CurAST); + eraseInstruction(I, *SafetyInfo, CurAST); Changed = true; continue; } @@ -510,14 +511,16 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, auto One = llvm::ConstantFP::get(Divisor->getType(), 1.0); auto ReciprocalDivisor = BinaryOperator::CreateFDiv(One, Divisor); ReciprocalDivisor->setFastMathFlags(I.getFastMathFlags()); + SafetyInfo->insertInstructionTo(I.getParent()); ReciprocalDivisor->insertBefore(&I); auto Product = BinaryOperator::CreateFMul(I.getOperand(0), ReciprocalDivisor); Product->setFastMathFlags(I.getFastMathFlags()); + SafetyInfo->insertInstructionTo(I.getParent()); Product->insertAfter(&I); I.replaceAllUsesWith(Product); - eraseInstruction(I, CurAST); + eraseInstruction(I, *SafetyInfo, CurAST); hoist(*ReciprocalDivisor, DT, CurLoop, SafetyInfo, ORE); Changed = true; @@ -886,9 +889,11 @@ CloneInstructionInExitBlock(Instruction &I, BasicBlock &ExitBlock, PHINode &PN, return New; } -static void eraseInstruction(Instruction &I, AliasSetTracker *AST) { +static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo, + AliasSetTracker *AST) { if (AST) AST->deleteValue(&I); + SafetyInfo.removeInstruction(&I); I.eraseFromParent(); } @@ -999,7 +1004,7 @@ static void splitPredecessorsOfLoopExit(PHINode *PN, DominatorTree *DT, /// position, and may either delete it or move it to outside of the loop. /// static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT, - const Loop *CurLoop, LoopSafetyInfo *SafetyInfo, + const Loop *CurLoop, ICFLoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE, bool FreeInLoop) { LLVM_DEBUG(dbgs() << "LICM sinking instruction: " << I << "\n"); ORE->emit([&]() { @@ -1090,7 +1095,7 @@ static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT, Instruction *New = sinkThroughTriviallyReplaceablePHI(PN, &I, LI, SunkCopies, SafetyInfo, CurLoop); PN->replaceAllUsesWith(New); - eraseInstruction(*PN, nullptr); + eraseInstruction(*PN, *SafetyInfo, nullptr); Changed = true; } return Changed; @@ -1100,7 +1105,7 @@ static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT, /// is safe to hoist, this instruction is called to do the dirty work. /// static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop, - LoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE) { + ICFLoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE) { auto *Preheader = CurLoop->getLoopPreheader(); LLVM_DEBUG(dbgs() << "LICM hoisting to " << Preheader->getName() << ": " << I << "\n"); @@ -1120,6 +1125,8 @@ static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop, !SafetyInfo->isGuaranteedToExecute(I, DT, CurLoop)) I.dropUnknownNonDebugMetadata(); + SafetyInfo->removeInstruction(&I); + SafetyInfo->insertInstructionTo(Preheader); // Move the new node to the Preheader, before its terminator. I.moveBefore(Preheader->getTerminator()); @@ -1180,6 +1187,7 @@ class LoopPromoter : public LoadAndStorePromoter { int Alignment; bool UnorderedAtomic; AAMDNodes AATags; + ICFLoopSafetyInfo &SafetyInfo; Value *maybeInsertLCSSAPHI(Value *V, BasicBlock *BB) const { if (Instruction *I = dyn_cast<Instruction>(V)) @@ -1202,11 +1210,13 @@ public: SmallVectorImpl<BasicBlock *> &LEB, SmallVectorImpl<Instruction *> &LIP, PredIteratorCache &PIC, AliasSetTracker &ast, LoopInfo &li, DebugLoc dl, int alignment, - bool UnorderedAtomic, const AAMDNodes &AATags) + bool UnorderedAtomic, const AAMDNodes &AATags, + ICFLoopSafetyInfo &SafetyInfo) : LoadAndStorePromoter(Insts, S), SomePtr(SP), PointerMustAliases(PMA), LoopExitBlocks(LEB), LoopInsertPts(LIP), PredCache(PIC), AST(ast), LI(li), DL(std::move(dl)), Alignment(alignment), - UnorderedAtomic(UnorderedAtomic), AATags(AATags) {} + UnorderedAtomic(UnorderedAtomic), AATags(AATags), SafetyInfo(SafetyInfo) + {} bool isInstInList(Instruction *I, const SmallVectorImpl<Instruction *> &) const override { @@ -1243,7 +1253,10 @@ public: // Update alias analysis. AST.copyValue(LI, V); } - void instructionDeleted(Instruction *I) const override { AST.deleteValue(I); } + void instructionDeleted(Instruction *I) const override { + SafetyInfo.removeInstruction(I); + AST.deleteValue(I); + } }; @@ -1281,7 +1294,7 @@ bool llvm::promoteLoopAccessesToScalars( SmallVectorImpl<BasicBlock *> &ExitBlocks, SmallVectorImpl<Instruction *> &InsertPts, PredIteratorCache &PIC, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI, - Loop *CurLoop, AliasSetTracker *CurAST, LoopSafetyInfo *SafetyInfo, + Loop *CurLoop, AliasSetTracker *CurAST, ICFLoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE) { // Verify inputs. assert(LI != nullptr && DT != nullptr && CurLoop != nullptr && @@ -1500,7 +1513,7 @@ bool llvm::promoteLoopAccessesToScalars( SSAUpdater SSA(&NewPHIs); LoopPromoter Promoter(SomePtr, LoopUses, SSA, PointerMustAliases, ExitBlocks, InsertPts, PIC, *CurAST, *LI, DL, Alignment, - SawUnorderedAtomic, AATags); + SawUnorderedAtomic, AATags, *SafetyInfo); // Set up the preheader to have a definition of the value. It is the live-out // value from the preheader that uses in the loop will use. @@ -1520,7 +1533,7 @@ bool llvm::promoteLoopAccessesToScalars( // If the SSAUpdater didn't use the load in the preheader, just zap it now. if (PreheaderLoad->use_empty()) - eraseInstruction(*PreheaderLoad, CurAST); + eraseInstruction(*PreheaderLoad, *SafetyInfo, CurAST); return true; } |