[PATCH] D90689: [CodeExtractor] Replace uses of extracted bitcasts in out-of-region lifetime markers

Giorgis Georgakoudis via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 3 08:37:10 PST 2020


ggeorgakoudis created this revision.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.
ggeorgakoudis requested review of this revision.

CodeExtractor handles bitcasts in the extracted region that have
lifetime markers users in the outer region as outputs. That
creates unnecessary alloca/reload instructions and extra lifetime
markers. The patch identifies those cases, and replaces uses in
out-of-region lifetime markers with new bitcasts in the outer region.

Example
-------

define void @foo() {
entry:

  %0 = alloca i32
  br label %extract

extract:

  %1 = bitcast i32* %0 to i8*
  call void @llvm.lifetime.start.p0i8(i64 4, i8* %1)
  call void @use(i32* %0)
  br label %exit

exit:

  call void @use(i32* %0)
  call void @llvm.lifetime.end.p0i8(i64 4, i8* %1)
  ret void

}

Current extraction
------------------

define void @foo() {
entry:

  %.loc = alloca i8*, align 8
  %0 = alloca i32, align 4
  br label %codeRepl

codeRepl:                                         ; preds = %entry

  %lt.cast = bitcast i8** %.loc to i8*
  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %lt.cast)
  %lt.cast1 = bitcast i32* %0 to i8*
  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %lt.cast1)
  call void @foo.extract(i32* %0, i8** %.loc)
  %.reload = load i8*, i8** %.loc, align 8
  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %lt.cast)
  br label %exit

exit:                                             ; preds = %codeRepl

  call void @use(i32* %0)
  call void @llvm.lifetime.end.p0i8(i64 4, i8* %.reload)
  ret void

}

define internal void @foo.extract(i32* %0, i8** %.out) {
newFuncRoot:

  br label %extract

exit.exitStub:                                    ; preds = %extract

  ret void

extract:                                          ; preds = %newFuncRoot

  %1 = bitcast i32* %0 to i8*
  store i8* %1, i8** %.out, align 8
  call void @use(i32* %0)
  br label %exit.exitStub

}

Extraction with patch
---------------------

define void @foo() {
entry:

  %0 = alloca i32, align 4
  br label %codeRepl

codeRepl:                                         ; preds = %entry

  %lt.cast1 = bitcast i32* %0 to i8*
  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %lt.cast1)
  call void @foo.extract(i32* %0)
  br label %exit

exit:                                             ; preds = %codeRepl

  call void @use(i32* %0)
  %lt.cast = bitcast i32* %0 to i8*
  call void @llvm.lifetime.end.p0i8(i64 4, i8* %lt.cast)
  ret void

}

define internal void @foo.extract(i32* %0) {
newFuncRoot:

  br label %extract

exit.exitStub:                                    ; preds = %extract

  ret void

extract:                                          ; preds = %newFuncRoot

  %1 = bitcast i32* %0 to i8*
  call void @use(i32* %0)
  br label %exit.exitStub

}


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D90689

Files:
  llvm/lib/Transforms/Utils/CodeExtractor.cpp


Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp
===================================================================
--- llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -535,6 +535,46 @@
       continue;
     }
 
+    // Find bitcasts in the outlined region that have lifetime marker users
+    // outside that region. Replace the lifetime marker use with an
+    // outside region bitcast to avoid unnecessary alloca/reload instructions
+    // and extra lifetime markers.
+    SmallVector<Instruction *, 2> LifetimeBitcastUsers;
+    for (User *U : AI->users()) {
+      if(!definedInRegion(Blocks, U))
+        continue;
+
+      if (U->stripInBoundsConstantOffsets() != AI)
+        continue;
+
+      Instruction *Bitcast = cast<Instruction>(U);
+      for (User *BU : Bitcast->users()) {
+        IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(BU);
+        if (!IntrInst)
+          continue;
+
+        if(!IntrInst->isLifetimeStartOrEnd())
+          continue;
+
+        if(definedInRegion(Blocks, IntrInst))
+          continue;
+
+        LLVM_DEBUG(dbgs() << "Replace use of extracted region bitcast"
+                          << *Bitcast << " in out-of-region lifetime marker "
+                          << *IntrInst << "\n");
+        LifetimeBitcastUsers.push_back(IntrInst);
+      }
+    }
+
+    for (Instruction *I : LifetimeBitcastUsers) {
+      Module *M = AIFunc->getParent();
+      LLVMContext &Ctx = M->getContext();
+      auto Int8PtrTy = Type::getInt8PtrTy(Ctx);
+      CastInst *CastI =
+          CastInst::CreatePointerCast(AI, Int8PtrTy, "lt.cast", I);
+      I->replaceUsesOfWith(I->getOperand(1), CastI);
+    }
+
     // Follow any bitcasts.
     SmallVector<Instruction *, 2> Bitcasts;
     SmallVector<LifetimeMarkerInfo, 2> BitcastLifetimeInfo;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D90689.302594.patch
Type: text/x-patch
Size: 1839 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201103/94f63ee1/attachment.bin>


More information about the llvm-commits mailing list