summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/lib/CodeGen/CodeGeneration.cpp54
-rw-r--r--polly/test/Isl/CodeGen/intrinsics_lifetime.ll6
2 files changed, 55 insertions, 5 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,
diff --git a/polly/test/Isl/CodeGen/intrinsics_lifetime.ll b/polly/test/Isl/CodeGen/intrinsics_lifetime.ll
index 49d2435074a..1a9b5cba030 100644
--- a/polly/test/Isl/CodeGen/intrinsics_lifetime.ll
+++ b/polly/test/Isl/CodeGen/intrinsics_lifetime.ll
@@ -1,11 +1,7 @@
; RUN: opt %loadPolly -basicaa -polly-codegen -S < %s | FileCheck %s
;
-; Verify that we remove the lifetime markers from the optimized SCoP.
+; Verify that we remove the lifetime markers from everywhere.
;
-; CHECK: for.body:
-; CHECK: call void @llvm.lifetime.start
-; CHECK: for.end:
-; CHECK: call void @llvm.lifetime.end
; CHECK-NOT: call void @llvm.lifetime.start
; CHECK-NOT: call void @llvm.lifetime.end
;
OpenPOWER on IntegriCloud