summaryrefslogtreecommitdiffstats
path: root/polly/lib/CodeGen/CodeGeneration.cpp
diff options
context:
space:
mode:
authorMichael Kruse <llvm@meinersbur.de>2017-04-05 20:09:59 +0000
committerMichael Kruse <llvm@meinersbur.de>2017-04-05 20:09:59 +0000
commit895f5d8080632e45dfdac8a1c197e246899c2449 (patch)
treedc8fb5af01a176316166891ac68f5fe2d39cc483 /polly/lib/CodeGen/CodeGeneration.cpp
parent13acc0d521b742c843acd0097e95a47f15da819a (diff)
downloadbcm5719-llvm-895f5d8080632e45dfdac8a1c197e246899c2449.tar.gz
bcm5719-llvm-895f5d8080632e45dfdac8a1c197e246899c2449.zip
Remove llvm.lifetime.start/end in original region.
The current StackColoring algorithm does not correctly handle the situation when some, but not all paths from a BB to the entry node cross a llvm.lifetime.start. According to an interpretation of the language reference at http://llvm.org/docs/LangRef.html#llvm-lifetime-start-intrinsic this might be correct, but it would cost too much effort to handle in StackColoring. To be on the safe side, remove all lifetime markers even in the original code version (they have never been copied to the optimized version) to ensure that no path to the entry block will cross a llvm.lifetime.start. The same principle applies to paths the a function return and the llvm.lifetime.end marker, so we remove them as well. This fixes llvm.org/PR32251. Also see the discussion at http://lists.llvm.org/pipermail/llvm-dev/2017-March/111551.html llvm-svn: 299585
Diffstat (limited to 'polly/lib/CodeGen/CodeGeneration.cpp')
-rw-r--r--polly/lib/CodeGen/CodeGeneration.cpp54
1 files changed, 54 insertions, 0 deletions
diff --git a/polly/lib/CodeGen/CodeGeneration.cpp b/polly/lib/CodeGen/CodeGeneration.cpp
index 835f1d27dba..ea98ef740ad 100644
--- a/polly/lib/CodeGen/CodeGeneration.cpp
+++ b/polly/lib/CodeGen/CodeGeneration.cpp
@@ -112,6 +112,59 @@ public:
OrigTerminator->eraseFromParent();
}
+ /// Remove all lifetime markers (llvm.lifetime.start, llvm.lifetime.end) from
+ /// @R.
+ ///
+ /// CodeGeneration does not copy lifetime markers into the optimized SCoP,
+ /// which would leave the them only in the original path. This can transform
+ /// code such as
+ ///
+ /// llvm.lifetime.start(%p)
+ /// llvm.lifetime.end(%p)
+ ///
+ /// into
+ ///
+ /// if (RTC) {
+ /// // generated code
+ /// } else {
+ /// // original code
+ /// llvm.lifetime.start(%p)
+ /// }
+ /// llvm.lifetime.end(%p)
+ ///
+ /// The current StackColoring algorithm cannot handle if some, but not all,
+ /// paths from the end marker to the entry block cross the start marker. Same
+ /// for start markers that do not always cross the end markers. We avoid any
+ /// issues by removing all lifetime markers, even from the original code.
+ ///
+ /// A better solution could be to hoist all llvm.lifetime.start to the split
+ /// node and all llvm.lifetime.end to the merge node, which should be
+ /// conservatively correct.
+ void removeLifetimeMarkers(Region *R) {
+ for (auto *BB : R->blocks()) {
+ auto InstIt = BB->begin();
+ auto InstEnd = BB->end();
+
+ while (InstIt != InstEnd) {
+ auto NextIt = InstIt;
+ ++NextIt;
+
+ if (auto *IT = dyn_cast<IntrinsicInst>(&*InstIt)) {
+ switch (IT->getIntrinsicID()) {
+ case llvm::Intrinsic::lifetime_start:
+ case llvm::Intrinsic::lifetime_end:
+ BB->getInstList().erase(InstIt);
+ break;
+ default:
+ break;
+ }
+ }
+
+ InstIt = NextIt;
+ }
+ }
+ }
+
/// Generate LLVM-IR for the SCoP @p S.
bool runOnScop(Scop &S) override {
AI = &getAnalysis<IslAstInfo>();
@@ -146,6 +199,7 @@ public:
// code generating this scop.
BasicBlock *StartBlock =
executeScopConditionally(S, Builder.getTrue(), *DT, *RI, *LI);
+ removeLifetimeMarkers(R);
auto *SplitBlock = StartBlock->getSinglePredecessor();
IslNodeBuilder NodeBuilder(Builder, Annotator, *DL, *LI, *SE, *DT, S,
OpenPOWER on IntegriCloud