diff options
-rw-r--r-- | polly/lib/CodeGen/CodeGeneration.cpp | 54 | ||||
-rw-r--r-- | polly/test/Isl/CodeGen/intrinsics_lifetime.ll | 6 |
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 ; |