summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2016-01-28 15:51:58 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2016-01-28 15:51:58 +0000
commit7a2e2bed67cccec20e657abbdeac64564a0e5f7e (patch)
treedf24fb2b9c93fb744115db77cea45f9ba9cc4191 /llvm/lib/Transforms
parent3ada75f7e89beae88f0a893093c150048b322a57 (diff)
downloadbcm5719-llvm-7a2e2bed67cccec20e657abbdeac64564a0e5f7e.tar.gz
bcm5719-llvm-7a2e2bed67cccec20e657abbdeac64564a0e5f7e.zip
[LICM] Keep metadata on control equivalent hoists
Summary: If the instruction we're hoisting out of a loop into its preheader is guaranteed to have executed in the loop, then the metadata associated with the instruction (e.g. !range or !dereferenceable) is valid in the preheader. This is because once we're in the preheader, we know we're eventually going to reach the location the metadata was valid at. This change makes LICM smarter around this, and helps it recognize cases like these: ``` do { int a = *ptr; !range !0 ... } while (i++ < N); ``` to ``` int a = *ptr; !range !0 do { ... } while (i++ < N); ``` Earlier we'd drop the `!range` metadata after hoisting the load from `ptr`. Reviewers: igor-laevsky Subscribers: mcrosier, llvm-commits Differential Revision: http://reviews.llvm.org/D16669 llvm-svn: 259053
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/LICM.cpp25
1 files changed, 18 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index b866b25db4b..4fb06046c49 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -77,7 +77,8 @@ DisablePromotion("disable-licm-promotion", cl::Hidden,
static bool inSubLoop(BasicBlock *BB, Loop *CurLoop, LoopInfo *LI);
static bool isNotUsedInLoop(const Instruction &I, const Loop *CurLoop,
const LICMSafetyInfo *SafetyInfo);
-static bool hoist(Instruction &I, BasicBlock *Preheader);
+static bool hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
+ const LICMSafetyInfo *SafetyInfo);
static bool sink(Instruction &I, const LoopInfo *LI, const DominatorTree *DT,
const Loop *CurLoop, AliasSetTracker *CurAST,
const LICMSafetyInfo *SafetyInfo);
@@ -397,7 +398,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI,
canSinkOrHoistInst(I, AA, DT, TLI, CurLoop, CurAST, SafetyInfo) &&
isSafeToExecuteUnconditionally(I, DT, TLI, CurLoop, SafetyInfo,
CurLoop->getLoopPreheader()->getTerminator()))
- Changed |= hoist(I, CurLoop->getLoopPreheader());
+ Changed |= hoist(I, DT, CurLoop, SafetyInfo);
}
const std::vector<DomTreeNode*> &Children = N->getChildren();
@@ -716,16 +717,26 @@ static bool sink(Instruction &I, const LoopInfo *LI, const DominatorTree *DT,
/// When an instruction is found to only use loop invariant operands that
/// is safe to hoist, this instruction is called to do the dirty work.
///
-static bool hoist(Instruction &I, BasicBlock *Preheader) {
+static bool hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
+ const LICMSafetyInfo *SafetyInfo) {
+ auto *Preheader = CurLoop->getLoopPreheader();
DEBUG(dbgs() << "LICM hoisting to " << Preheader->getName() << ": "
<< I << "\n");
+
+ // Metadata can be dependent on conditions we are hoisting above.
+ // Conservatively strip all metadata on the instruction unless we were
+ // guaranteed to execute I if we entered the loop, in which case the metadata
+ // is valid in the loop preheader.
+ if (I.hasMetadataOtherThanDebugLoc() &&
+ // The check on hasMetadataOtherThanDebugLoc is to prevent us from burning
+ // time in isGuaranteedToExecute if we don't actually have anything to
+ // drop. It is a compile time optimization, not required for correctness.
+ !isGuaranteedToExecute(I, DT, CurLoop, SafetyInfo))
+ I.dropUnknownNonDebugMetadata();
+
// Move the new node to the Preheader, before its terminator.
I.moveBefore(Preheader->getTerminator());
- // Metadata can be dependent on the condition we are hoisting above.
- // Conservatively strip all metadata on the instruction.
- I.dropUnknownNonDebugMetadata();
-
if (isa<LoadInst>(I)) ++NumMovedLoads;
else if (isa<CallInst>(I)) ++NumMovedCalls;
++NumHoisted;
OpenPOWER on IntegriCloud