From: Tobias Gysi Date: Wed, 31 May 2023 06:48:49 +0000 (+0000) Subject: [mlir][llvm] Add alias and access group info to call. X-Git-Tag: upstream/17.0.6~6700 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8e9baa9668e0d8da524ed1c98c2f5f5b0185cf18;p=platform%2Fupstream%2Fllvm.git [mlir][llvm] Add alias and access group info to call. The revision adds the alias analysis and access group interfaces to the call operation. Reviewed By: Dinistro Differential Revision: https://reviews.llvm.org/D151693 --- diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td index 3218701..53418cf 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -172,7 +172,7 @@ def LLVM_FNegOp : LLVM_UnaryFloatArithmeticOp< LLVM_ScalarOrVectorOf, "fneg", "FNeg">; // Memory-related operations. -def LLVM_AllocaOp : LLVM_Op<"alloca", +def LLVM_AllocaOp : LLVM_Op<"alloca", [DeclareOpInterfaceMethods, DeclareOpInterfaceMethods]>, LLVM_MemOpPatterns { @@ -328,7 +328,7 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load", DefaultValuedAttr< AtomicOrdering, "AtomicOrdering::not_atomic">:$ordering, OptionalAttr:$syncscope); - // Append the aliasing related attributes define in LLVM_MemAccessOpBase. + // Append the aliasing related attributes defined in LLVM_MemAccessOpBase. let arguments = !con(args, aliasAttrs); let results = (outs LLVM_LoadableType:$res); string llvmInstName = "Load"; @@ -402,7 +402,7 @@ def LLVM_StoreOp : LLVM_MemAccessOpBase<"store", DefaultValuedAttr< AtomicOrdering, "AtomicOrdering::not_atomic">:$ordering, OptionalAttr:$syncscope); - // Append the aliasing related attributes define in LLVM_MemAccessOpBase. + // Append the aliasing related attributes defined in LLVM_MemAccessOpBase. let arguments = !con(args, aliasAttrs); string llvmInstName = "Store"; let description = [{ @@ -568,10 +568,10 @@ def LLVM_LandingpadOp : LLVM_Op<"landingpad"> { // FIXME: Add a type attribute that carries the LLVM function type to support // indirect calls to variadic functions. The type attribute is necessary to // distinguish normal and variadic arguments. -def LLVM_CallOp : LLVM_Op<"call", - [DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods]> { +def LLVM_CallOp : LLVM_MemAccessOpBase<"call", + [DeclareOpInterfaceMethods, + DeclareOpInterfaceMethods, + DeclareOpInterfaceMethods]> { let summary = "Call to an LLVM function."; let description = [{ In LLVM IR, functions may return either 0 or 1 value. LLVM IR dialect @@ -601,13 +601,14 @@ def LLVM_CallOp : LLVM_Op<"call", ``` }]; - let arguments = (ins OptionalAttr:$callee, - Variadic, - DefaultValuedAttr:$fastmathFlags, - OptionalAttr:$branch_weights); + dag args = (ins OptionalAttr:$callee, + Variadic, + DefaultValuedAttr:$fastmathFlags, + OptionalAttr:$branch_weights); + // Append the aliasing related attributes defined in LLVM_MemAccessOpBase. + let arguments = !con(args, aliasAttrs); let results = (outs Optional:$result); - let builders = [ OpBuilder<(ins "LLVMFuncOp":$func, "ValueRange":$args)>, OpBuilder<(ins "TypeRange":$results, "StringAttr":$callee, @@ -617,7 +618,6 @@ def LLVM_CallOp : LLVM_Op<"call", OpBuilder<(ins "TypeRange":$results, "StringRef":$callee, CArg<"ValueRange", "{}">:$args)> ]; - let hasCustomAssemblyFormat = 1; } @@ -1778,7 +1778,7 @@ def LLVM_AtomicRMWOp : LLVM_MemAccessOpBase<"atomicrmw", [ OptionalAttr:$syncscope, OptionalAttr:$alignment, UnitAttr:$volatile_); - // Append the aliasing related attributes define in LLVM_MemAccessOpBase. + // Append the aliasing related attributes defined in LLVM_MemAccessOpBase. let arguments = !con(args, aliasAttrs); let results = (outs LLVM_AtomicRMWType:$res); let assemblyFormat = [{ @@ -1832,7 +1832,7 @@ def LLVM_AtomicCmpXchgOp : LLVM_MemAccessOpBase<"cmpxchg", [ OptionalAttr:$alignment, UnitAttr:$weak, UnitAttr:$volatile_); - // Append the aliasing related attributes define in LLVM_MemAccessOpBase. + // Append the aliasing related attributes defined in LLVM_MemAccessOpBase. let arguments = !con(args, aliasAttrs); let results = (outs LLVM_AnyStruct:$res); let assemblyFormat = [{ diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp index a31daaa..c44c60a 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -916,13 +916,15 @@ void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results, void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results, StringAttr callee, ValueRange args) { - build(builder, state, results, SymbolRefAttr::get(callee), args, nullptr, - nullptr); + build(builder, state, results, SymbolRefAttr::get(callee), args); } void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results, FlatSymbolRefAttr callee, ValueRange args) { - build(builder, state, results, callee, args, nullptr, nullptr); + build(builder, state, results, callee, args, /*fastmathFlags=*/nullptr, + /*branch_weights=*/nullptr, + /*access_groups=*/nullptr, /*alias_scopes=*/nullptr, + /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr); } void CallOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func, @@ -931,8 +933,11 @@ void CallOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func, Type resultType = func.getFunctionType().getReturnType(); if (!llvm::isa(resultType)) results.push_back(resultType); - build(builder, state, results, SymbolRefAttr::get(func), args, nullptr, - nullptr); + build(builder, state, results, SymbolRefAttr::get(func), args, + /*fastmathFlags=*/nullptr, + /*branch_weights=*/nullptr, + /*access_groups=*/nullptr, /*alias_scopes=*/nullptr, + /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr); } CallInterfaceCallable CallOp::getCallableForCallee() { diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp index c5a4800..a044930 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp @@ -186,6 +186,9 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder, convertBranchWeights(callOp.getBranchWeights(), moduleTranslation); if (branchWeights) call->setMetadata(llvm::LLVMContext::MD_prof, branchWeights); + moduleTranslation.setAccessGroupsMetadata(callOp, call); + moduleTranslation.setAliasScopeMetadata(callOp, call); + moduleTranslation.setTBAAMetadata(callOp, call); // If the called function has a result, remap the corresponding value. Note // that LLVM IR dialect CallOp has either 0 or 1 result. if (opInst.getNumResults() != 0) { diff --git a/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll b/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll index eb74b0a..19abc95 100644 --- a/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll +++ b/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll @@ -83,12 +83,17 @@ define void @supported_ops(ptr %arg1, float %arg2, i32 %arg3, i32 %arg4) { call void @llvm.memcpy.p0.p0.i32(ptr %arg1, ptr %arg1, i32 4, i1 false), !alias.scope !2 ; CHECK: "llvm.intr.memset"{{.*}}alias_scopes = [@__llvm_global_metadata::@[[$SCOPE]]] call void @llvm.memset.p0.i32(ptr %arg1, i8 42, i32 4, i1 false), !alias.scope !2 + ; CHECK: llvm.call{{.*}}alias_scopes = [@__llvm_global_metadata::@[[$SCOPE]]] + call void @foo(ptr %arg1), !alias.scope !2 + ; CHECK: llvm.call{{.*}}noalias_scopes = [@__llvm_global_metadata::@[[$SCOPE]]] + call void @foo(ptr %arg1), !noalias !2 ret void } declare void @llvm.experimental.noalias.scope.decl(metadata) declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg) declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg) +declare void @foo(ptr %arg1) !0 = distinct !{!0, !"The domain"} !1 = !{!1, !0} diff --git a/mlir/test/Target/LLVMIR/Import/metadata-loop.ll b/mlir/test/Target/LLVMIR/Import/metadata-loop.ll index dcd2004..9638ebd 100644 --- a/mlir/test/Target/LLVMIR/Import/metadata-loop.ll +++ b/mlir/test/Target/LLVMIR/Import/metadata-loop.ll @@ -41,11 +41,14 @@ define void @supported_ops(ptr %arg1, float %arg2, i32 %arg3, i32 %arg4) { call void @llvm.memcpy.p0.p0.i32(ptr %arg1, ptr %arg1, i32 4, i1 false), !llvm.access.group !0 ; CHECK: "llvm.intr.memset"{{.*}}access_groups = call void @llvm.memset.p0.i32(ptr %arg1, i8 42, i32 4, i1 false), !llvm.access.group !0 + ; CHECK: llvm.call{{.*}}access_groups = + call void @foo(ptr %arg1), !llvm.access.group !0 ret void } declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg) declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg) +declare void @foo(ptr %arg1) !0 = !{!1, !2} !1 = distinct !{} diff --git a/mlir/test/Target/LLVMIR/Import/metadata-tbaa.ll b/mlir/test/Target/LLVMIR/Import/metadata-tbaa.ll index 2aa1e94..9477063 100644 --- a/mlir/test/Target/LLVMIR/Import/metadata-tbaa.ll +++ b/mlir/test/Target/LLVMIR/Import/metadata-tbaa.ll @@ -85,11 +85,14 @@ define void @supported_ops(ptr %arg1, float %arg2, i32 %arg3, i32 %arg4) { call void @llvm.memcpy.p0.p0.i32(ptr %arg1, ptr %arg1, i32 4, i1 false), !tbaa !0 ; CHECK: "llvm.intr.memset"{{.*}}tbaa = call void @llvm.memset.p0.i32(ptr %arg1, i8 42, i32 4, i1 false), !tbaa !0 + ; CHECK: llvm.call{{.*}}tbaa = + call void @foo(ptr %arg1), !tbaa !0 ret void } declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg) declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg) +declare void @foo(ptr %arg1) !0 = !{!1, !1, i64 0} !1 = !{!"scalar type", !2, i64 0} diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir index 1c1581c..ed4237f 100644 --- a/mlir/test/Target/LLVMIR/llvmir.mlir +++ b/mlir/test/Target/LLVMIR/llvmir.mlir @@ -2019,6 +2019,8 @@ llvm.func @switch_weights(%arg0: i32) -> i32 { // ----- +llvm.func @foo(%arg0: !llvm.ptr) + // CHECK-LABEL: aliasScope llvm.func @aliasScope(%arg1 : !llvm.ptr) { %0 = llvm.mlir.constant(0 : i32) : i32 @@ -2038,6 +2040,10 @@ llvm.func @aliasScope(%arg1 : !llvm.ptr) { "llvm.intr.memcpy"(%arg1, %arg1, %0, %4) {alias_scopes = [@metadata::@scope3]} : (!llvm.ptr, !llvm.ptr, i32, i1) -> () // CHECK: llvm.memset{{.*}}, !noalias ![[SCOPES3]] "llvm.intr.memset"(%arg1, %5, %0, %4) {noalias_scopes = [@metadata::@scope3]} : (!llvm.ptr, i8, i32, i1) -> () + // CHECK: call void @foo({{.*}} !alias.scope ![[SCOPES3]] + llvm.call @foo(%arg1) {alias_scopes = [@metadata::@scope3]} : (!llvm.ptr) -> () + // CHECK: call void @foo({{.*}} !noalias ![[SCOPES3]] + llvm.call @foo(%arg1) {noalias_scopes = [@metadata::@scope3]} : (!llvm.ptr) -> () llvm.return } diff --git a/mlir/test/Target/LLVMIR/loop-metadata.mlir b/mlir/test/Target/LLVMIR/loop-metadata.mlir index f17cc00..de48072 100644 --- a/mlir/test/Target/LLVMIR/loop-metadata.mlir +++ b/mlir/test/Target/LLVMIR/loop-metadata.mlir @@ -233,6 +233,8 @@ llvm.func @unswitchOptions() { // ----- +llvm.func @foo(%arg0: i32) + // CHECK-LABEL: @loopOptions llvm.func @loopOptions(%arg1 : i32, %arg2 : i32) { %0 = llvm.mlir.constant(0 : i32) : i32 @@ -262,6 +264,8 @@ llvm.func @loopOptions(%arg1 : i32, %arg2 : i32) { "llvm.intr.memcpy"(%4, %4, %0, %8) {access_groups = [@metadata::@group1, @metadata::@group2]} : (!llvm.ptr, !llvm.ptr, i32, i1) -> () // CHECK: llvm.memset{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] "llvm.intr.memset"(%4, %9, %0, %8) {access_groups = [@metadata::@group1, @metadata::@group2]} : (!llvm.ptr, i8, i32, i1) -> () + // CHECK: call void @foo({{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] + llvm.call @foo(%arg1) {access_groups = [@metadata::@group1, @metadata::@group2]} : (i32) -> () // CHECK: br label {{.*}} !llvm.loop ![[LOOP_NODE]] llvm.br ^bb3(%3 : i32) {loop_annotation = #llvm.loop_annotation< licm = , diff --git a/mlir/test/Target/LLVMIR/tbaa.mlir b/mlir/test/Target/LLVMIR/tbaa.mlir index 1c9b2be..ade6c4a 100644 --- a/mlir/test/Target/LLVMIR/tbaa.mlir +++ b/mlir/test/Target/LLVMIR/tbaa.mlir @@ -55,6 +55,7 @@ module { llvm.tbaa_type_desc @tbaa_type_desc_6 {id = "agg1_t", members = {<@tbaa_type_desc_5, 0>, <@tbaa_type_desc_5, 4>}} llvm.tbaa_tag @tbaa_tag_7 {access_type = @tbaa_type_desc_5, base_type = @tbaa_type_desc_6, offset = 0 : i64} } + llvm.func @foo(%arg0: !llvm.ptr) llvm.func @tbaa2(%arg0: !llvm.ptr, %arg1: !llvm.ptr) { %0 = llvm.mlir.constant(0 : i32) : i32 %1 = llvm.mlir.constant(1 : i32) : i32 @@ -75,6 +76,8 @@ module { "llvm.intr.memcpy"(%arg1, %arg1, %0, %8) {tbaa = [@__tbaa::@tbaa_tag_7]} : (!llvm.ptr, !llvm.ptr, i32, i1) -> () // CHECK: llvm.memset{{.*}} !tbaa ![[STAG]] "llvm.intr.memset"(%arg1, %9, %0, %8) {tbaa = [@__tbaa::@tbaa_tag_7]} : (!llvm.ptr, i8, i32, i1) -> () + // CHECK: call void @foo({{.*}} !tbaa ![[STAG]] + llvm.call @foo(%arg1) {tbaa = [@__tbaa::@tbaa_tag_7]} : (!llvm.ptr) -> () llvm.return } }