diff options
author | Philip Reames <listmail@philipreames.com> | 2018-05-04 21:35:00 +0000 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2018-05-04 21:35:00 +0000 |
commit | 5b39acd111e082e2ba91eb83de7ecb9763f76115 (patch) | |
tree | 523b7404a40150c719aabf6d6154fdeb9a903efb /llvm/lib/Transforms | |
parent | a2e053638bbfea50b29a29ee687f1bdd6abd427f (diff) | |
download | bcm5719-llvm-5b39acd111e082e2ba91eb83de7ecb9763f76115.tar.gz bcm5719-llvm-5b39acd111e082e2ba91eb83de7ecb9763f76115.zip |
[LICM] Compute a must execute property for the prefix of the header as we go
Computing this property within the existing walk ensures that the cost is linear with the size of the block. If we did this from within isGuaranteedToExecute, it would be quadratic without some very fancy caching.
This allows us to reliably catch a hoistable instruction within a header which may throw at some point *after* our hoistable instruction. It doesn't do anything for non-header cases, but given how common single block loops are, this seems very worthwhile.
llvm-svn: 331557
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Scalar/LICM.cpp | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index e3e6056201f..b9d10d9f4c8 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -449,6 +449,11 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, if (inSubLoop(BB, CurLoop, LI)) continue; + // Keep track of whether the prefix of instructions visited so far are such + // that the next instruction visited is guaranteed to execute if the loop + // is entered. + bool IsMustExecute = CurLoop->getHeader() == BB; + for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) { Instruction &I = *II++; // Try constant folding this instruction. If all the operands are @@ -496,10 +501,16 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, // if (CurLoop->hasLoopInvariantOperands(&I) && canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, SafetyInfo, ORE) && - isSafeToExecuteUnconditionally( - I, DT, CurLoop, SafetyInfo, ORE, - CurLoop->getLoopPreheader()->getTerminator())) + (IsMustExecute || + isSafeToExecuteUnconditionally( + I, DT, CurLoop, SafetyInfo, ORE, + CurLoop->getLoopPreheader()->getTerminator()))) { Changed |= hoist(I, DT, CurLoop, SafetyInfo, ORE); + continue; + } + + if (IsMustExecute) + IsMustExecute = isGuaranteedToTransferExecutionToSuccessor(&I); } } |