[Mlir-commits] [mlir] e63b574 - [mlir][LLVMIR] Add lifetime start and end marker instrinsics

Jeff Niu llvmlistbot at llvm.org
Wed Sep 14 13:15:24 PDT 2022


Author: Jeff Niu
Date: 2022-09-14T13:15:14-07:00
New Revision: e63b574ff6a827ac64128490f117c94a54859992

URL: https://github.com/llvm/llvm-project/commit/e63b574ff6a827ac64128490f117c94a54859992
DIFF: https://github.com/llvm/llvm-project/commit/e63b574ff6a827ac64128490f117c94a54859992.diff

LOG: [mlir][LLVMIR] Add lifetime start and end marker instrinsics

This patch adds the `llvm.intr.lifetime.start` and `llvm.intr.lifetime.end`
intrinsics which are used to indicate to LLVM the lifetimes of allocated
memory.

These ops have the requirement that the first argument (the size) be an
"immediate argument". I added an OpTrait to check this, but it is
possible that an approach like GEPArg would work too.

Reviewed By: rriddle, dcaballe

Differential Revision: https://reviews.llvm.org/D133867

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
    mlir/test/Dialect/LLVMIR/roundtrip.mlir
    mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index 8324408f0ef73..3577447f0a040 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -98,6 +98,32 @@ def LLVM_MemsetOp : LLVM_ZeroResultIntrOp<"memset", [0, 2]> {
                    LLVM_Type:$isVolatile);
 }
 
+//===----------------------------------------------------------------------===//
+// Lifetime Markers
+//===----------------------------------------------------------------------===//
+
+/// Base operation for lifetime markers. The LLVM intrinsics require the size
+/// operand to be an immediate. In MLIR it is encoded as an attribute.
+class LLVM_LifetimeBaseOp<string opName> : LLVM_ZeroResultIntrOp<opName> {
+  let arguments = (ins I64Attr:$size, LLVM_AnyPointer:$ptr);
+
+  // Custom builder to convert the size attribute to an integer.
+  let llvmBuilder = [{
+    llvm::Module *module = builder.GetInsertBlock()->getModule();
+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(
+        module, llvm::Intrinsic::}] # llvmEnumName # [{, {}] #
+        !interleave(ListIntSubst<LLVM_IntrPatterns.operand, [0]>.lst, ", ")
+        # [{});
+    builder.CreateCall(fn, {builder.getInt64(op.getSizeAttr().getInt()),
+                            moduleTranslation.lookupValue(op.getPtr())});
+  }];
+
+  let assemblyFormat = "$size `,` $ptr attr-dict `:` type($ptr)";
+}
+
+def LLVM_LifetimeStartOp : LLVM_LifetimeBaseOp<"lifetime.start">;
+def LLVM_LifetimeEndOp : LLVM_LifetimeBaseOp<"lifetime.end">;
+
 // Intrinsics with multiple returns.
 
 def LLVM_SAddWithOverflowOp

diff  --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index ad0050e251397..37a7905f9c584 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -522,3 +522,13 @@ llvm.func @vararg_func(%arg0: i32, ...) {
   // CHECK: llvm.return
   llvm.return
 }
+
+// CHECK-LABEL: @lifetime
+// CHECK-SAME: %[[P:.*]]: !llvm.ptr
+llvm.func @lifetime(%p: !llvm.ptr) {
+  // CHECK: llvm.intr.lifetime.start 16, %[[P]]
+  llvm.intr.lifetime.start 16, %p : !llvm.ptr
+  // CHECK: llvm.intr.lifetime.end 16, %[[P]]
+  llvm.intr.lifetime.end 16, %p : !llvm.ptr
+  llvm.return
+}

diff  --git a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
index c87ff8551002b..b8bf5abf0e568 100644
--- a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
@@ -635,13 +635,13 @@ llvm.func @vector_predication_intrinsics(%A: vector<8xi32>, %B: vector<8xi32>,
          (vector<8xi1>, vector<8xi32>, vector<8xi32>, i32) -> vector<8xi32>
 
   // CHECK: call void @llvm.vp.store.v8i32.p0
-  "llvm.intr.vp.store" (%A, %iptr, %mask, %evl) : 
+  "llvm.intr.vp.store" (%A, %iptr, %mask, %evl) :
          (vector<8xi32>, !llvm.ptr<i32>, vector<8xi1>, i32) -> ()
   // CHECK: call <8 x i32> @llvm.vp.load.v8i32.p0
   "llvm.intr.vp.load" (%iptr, %mask, %evl) :
          (!llvm.ptr<i32>, vector<8xi1>, i32) -> vector<8xi32>
   // CHECK: call void @llvm.experimental.vp.strided.store.v8i32.p0.i32
-  "llvm.intr.experimental.vp.strided.store" (%A, %iptr, %i, %mask, %evl) : 
+  "llvm.intr.experimental.vp.strided.store" (%A, %iptr, %i, %mask, %evl) :
          (vector<8xi32>, !llvm.ptr<i32>, i32, vector<8xi1>, i32) -> ()
   // CHECK: call <8 x i32> @llvm.experimental.vp.strided.load.v8i32.p0.i32
   "llvm.intr.experimental.vp.strided.load" (%iptr, %i, %mask, %evl) :
@@ -707,6 +707,15 @@ llvm.func @vector_insert_extract(%f256: vector<8xi32>, %f128: vector<4xi32>,
   llvm.return
 }
 
+// CHECK-LABEL: @lifetime
+llvm.func @lifetime(%p: !llvm.ptr) {
+  // CHECK: call void @llvm.lifetime.start
+  llvm.intr.lifetime.start 16, %p : !llvm.ptr
+  // CHECK: call void @llvm.lifetime.end
+  llvm.intr.lifetime.end 16, %p : !llvm.ptr
+  llvm.return
+}
+
 // Check that intrinsics are declared with appropriate types.
 // CHECK-DAG: declare float @llvm.fma.f32(float, float, float)
 // CHECK-DAG: declare <8 x float> @llvm.fma.v8f32(<8 x float>, <8 x float>, <8 x float>) #0
@@ -814,3 +823,5 @@ llvm.func @vector_insert_extract(%f256: vector<8xi32>, %f128: vector<4xi32>,
 // CHECK-DAG: declare <8 x i32> @llvm.vector.extract.v8i32.nxv4i32(<vscale x 4 x i32>, i64 immarg) #0
 // CHECK-DAG: declare <4 x i32> @llvm.vector.extract.v4i32.nxv4i32(<vscale x 4 x i32>, i64 immarg) #0
 // CHECK-DAG: declare <2 x i32> @llvm.vector.extract.v2i32.v8i32(<8 x i32>, i64 immarg) #0
+// CHECK-DAG: declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
+// CHECK-DAG: declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)


        


More information about the Mlir-commits mailing list