Revert "Reland "[mlir][llvm] Add intrinsic arg and result attribute support (…" (#151316)
Reverts llvm/llvm-project#151125 Broke the gcc-7 build: include/mlir/Target/LLVMIR/ModuleTranslation.h:318:34: error: no type named 'CallBase' in namespace 'llvm' llvm::CallBase *call, ~~~~~~^
This commit is contained in:
parent
5c87374f2a
commit
97fa9a1f53
@ -71,7 +71,6 @@ class ArmSME_IntrOp<string mnemonic,
|
||||
/*bit requiresAccessGroup=*/0,
|
||||
/*bit requiresAliasAnalysis=*/0,
|
||||
/*bit requiresFastmath=*/0,
|
||||
/*bit requiresArgAndResultAttrs=*/0,
|
||||
/*bit requiresOpBundles=*/0,
|
||||
/*list<int> immArgPositions=*/immArgPositions,
|
||||
/*list<string> immArgAttrNames=*/immArgAttrNames>;
|
||||
|
@ -92,7 +92,6 @@ class ArmSVE_IntrOp<string mnemonic,
|
||||
/*bit requiresAccessGroup=*/0,
|
||||
/*bit requiresAliasAnalysis=*/0,
|
||||
/*bit requiresFastmath=*/0,
|
||||
/*bit requiresArgAndResultAttrs=*/0,
|
||||
/*bit requiresOpBundles=*/0,
|
||||
/*list<int> immArgPositions=*/immArgPositions,
|
||||
/*list<string> immArgAttrNames=*/immArgAttrNames>;
|
||||
|
@ -140,8 +140,8 @@ def LLVM_Log2Op : LLVM_UnaryIntrOpF<"log2">;
|
||||
def LLVM_LogOp : LLVM_UnaryIntrOpF<"log">;
|
||||
def LLVM_Prefetch : LLVM_ZeroResultIntrOp<"prefetch", [0],
|
||||
/*traits=*/[], /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
|
||||
/*requiresArgAndResultAttrs=*/0, /*requiresOpBundles=*/0,
|
||||
/*immArgPositions=*/[1, 2, 3], /*immArgAttrNames=*/["rw", "hint", "cache"]
|
||||
/*requiresOpBundles=*/0, /*immArgPositions=*/[1, 2, 3],
|
||||
/*immArgAttrNames=*/["rw", "hint", "cache"]
|
||||
> {
|
||||
let arguments = (ins LLVM_AnyPointer:$addr, I32Attr:$rw, I32Attr:$hint, I32Attr:$cache);
|
||||
}
|
||||
@ -200,13 +200,13 @@ class LLVM_MemcpyIntrOpBase<string name> :
|
||||
DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>,
|
||||
DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>],
|
||||
/*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1,
|
||||
/*requiresArgAndResultAttrs=*/1, /*requiresOpBundles=*/0,
|
||||
/*immArgPositions=*/[3], /*immArgAttrNames=*/["isVolatile"]> {
|
||||
/*requiresOpBundles=*/0, /*immArgPositions=*/[3],
|
||||
/*immArgAttrNames=*/["isVolatile"]> {
|
||||
dag args = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst,
|
||||
Arg<LLVM_AnyPointer,"",[MemRead]>:$src,
|
||||
AnySignlessInteger:$len, I1Attr:$isVolatile);
|
||||
// Append the arguments defined by LLVM_IntrOpBase.
|
||||
let arguments = !con(args, baseArgs);
|
||||
// Append the alias attributes defined by LLVM_IntrOpBase.
|
||||
let arguments = !con(args, aliasAttrs);
|
||||
let builders = [
|
||||
OpBuilder<(ins "Value":$dst, "Value":$src, "Value":$len,
|
||||
"bool":$isVolatile), [{
|
||||
@ -217,8 +217,7 @@ class LLVM_MemcpyIntrOpBase<string name> :
|
||||
"IntegerAttr":$isVolatile), [{
|
||||
build($_builder, $_state, dst, src, len, isVolatile,
|
||||
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
|
||||
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr,
|
||||
/*arg_attrs=*/nullptr, /*res_attrs=*/nullptr);
|
||||
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
|
||||
}]>
|
||||
];
|
||||
}
|
||||
@ -232,13 +231,13 @@ def LLVM_MemcpyInlineOp :
|
||||
DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>,
|
||||
DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>],
|
||||
/*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1,
|
||||
/*requiresArgAndResultAttrs=*/1, /*requiresOpBundles=*/0,
|
||||
/*immArgPositions=*/[2, 3], /*immArgAttrNames=*/["len", "isVolatile"]> {
|
||||
/*requiresOpBundles=*/0, /*immArgPositions=*/[2, 3],
|
||||
/*immArgAttrNames=*/["len", "isVolatile"]> {
|
||||
dag args = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst,
|
||||
Arg<LLVM_AnyPointer,"",[MemRead]>:$src,
|
||||
APIntAttr:$len, I1Attr:$isVolatile);
|
||||
// Append the arguments defined by LLVM_IntrOpBase.
|
||||
let arguments = !con(args, baseArgs);
|
||||
// Append the alias attributes defined by LLVM_IntrOpBase.
|
||||
let arguments = !con(args, aliasAttrs);
|
||||
let builders = [
|
||||
OpBuilder<(ins "Value":$dst, "Value":$src, "IntegerAttr":$len,
|
||||
"bool":$isVolatile), [{
|
||||
@ -249,8 +248,7 @@ def LLVM_MemcpyInlineOp :
|
||||
"IntegerAttr":$isVolatile), [{
|
||||
build($_builder, $_state, dst, src, len, isVolatile,
|
||||
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
|
||||
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr,
|
||||
/*arg_attrs=*/nullptr, /*res_attrs=*/nullptr);
|
||||
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
|
||||
}]>
|
||||
];
|
||||
}
|
||||
@ -260,12 +258,12 @@ def LLVM_MemsetOp : LLVM_ZeroResultIntrOp<"memset", [0, 2],
|
||||
DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>,
|
||||
DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>],
|
||||
/*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1,
|
||||
/*requiresArgAndResultAttrs=*/1, /*requiresOpBundles=*/0,
|
||||
/*immArgPositions=*/[3], /*immArgAttrNames=*/["isVolatile"]> {
|
||||
/*requiresOpBundles=*/0, /*immArgPositions=*/[3],
|
||||
/*immArgAttrNames=*/["isVolatile"]> {
|
||||
dag args = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst,
|
||||
I8:$val, AnySignlessInteger:$len, I1Attr:$isVolatile);
|
||||
// Append the arguments defined by LLVM_IntrOpBase.
|
||||
let arguments = !con(args, baseArgs);
|
||||
// Append the alias attributes defined by LLVM_IntrOpBase.
|
||||
let arguments = !con(args, aliasAttrs);
|
||||
let builders = [
|
||||
OpBuilder<(ins "Value":$dst, "Value":$val, "Value":$len,
|
||||
"bool":$isVolatile), [{
|
||||
@ -276,8 +274,7 @@ def LLVM_MemsetOp : LLVM_ZeroResultIntrOp<"memset", [0, 2],
|
||||
"IntegerAttr":$isVolatile), [{
|
||||
build($_builder, $_state, dst, val, len, isVolatile,
|
||||
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
|
||||
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr,
|
||||
/*arg_attrs=*/nullptr, /*res_attrs=*/nullptr);
|
||||
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
|
||||
}]>
|
||||
];
|
||||
}
|
||||
@ -287,12 +284,12 @@ def LLVM_MemsetInlineOp : LLVM_ZeroResultIntrOp<"memset.inline", [0, 2],
|
||||
DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>,
|
||||
DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>],
|
||||
/*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1,
|
||||
/*requiresArgAndResultAttrs=*/1, /*requiresOpBundles=*/0,
|
||||
/*immArgPositions=*/[2, 3], /*immArgAttrNames=*/["len", "isVolatile"]> {
|
||||
/*requiresOpBundles=*/0, /*immArgPositions=*/[2, 3],
|
||||
/*immArgAttrNames=*/["len", "isVolatile"]> {
|
||||
dag args = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst,
|
||||
I8:$val, APIntAttr:$len, I1Attr:$isVolatile);
|
||||
// Append the arguments defined by LLVM_IntrOpBase.
|
||||
let arguments = !con(args, baseArgs);
|
||||
// Append the alias attributes defined by LLVM_IntrOpBase.
|
||||
let arguments = !con(args, aliasAttrs);
|
||||
let builders = [
|
||||
OpBuilder<(ins "Value":$dst, "Value":$val, "IntegerAttr":$len,
|
||||
"bool":$isVolatile), [{
|
||||
@ -303,8 +300,7 @@ def LLVM_MemsetInlineOp : LLVM_ZeroResultIntrOp<"memset.inline", [0, 2],
|
||||
"IntegerAttr":$isVolatile), [{
|
||||
build($_builder, $_state, dst, val, len, isVolatile,
|
||||
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
|
||||
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr,
|
||||
/*arg_attrs=*/nullptr, /*res_attrs=*/nullptr);
|
||||
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
|
||||
}]>
|
||||
];
|
||||
}
|
||||
@ -353,8 +349,8 @@ def LLVM_PtrMaskOp
|
||||
class LLVM_LifetimeBaseOp<string opName> : LLVM_ZeroResultIntrOp<opName, [1],
|
||||
[DeclareOpInterfaceMethods<PromotableOpInterface>],
|
||||
/*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
|
||||
/*requiresArgAndResultAttrs=*/0, /*requiresOpBundles=*/0,
|
||||
/*immArgPositions=*/[0], /*immArgAttrNames=*/["size"]> {
|
||||
/*requiresOpBundles=*/0, /*immArgPositions=*/[0],
|
||||
/*immArgAttrNames=*/["size"]> {
|
||||
let arguments = (ins I64Attr:$size, LLVM_AnyPointer:$ptr);
|
||||
let assemblyFormat = "$size `,` $ptr attr-dict `:` qualified(type($ptr))";
|
||||
}
|
||||
@ -374,8 +370,8 @@ def LLVM_InvariantStartOp : LLVM_OneResultIntrOp<"invariant.start", [], [1],
|
||||
def LLVM_InvariantEndOp : LLVM_ZeroResultIntrOp<"invariant.end", [2],
|
||||
[DeclareOpInterfaceMethods<PromotableOpInterface>],
|
||||
/*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
|
||||
/*requiresArgAndResultAttrs=*/0, /*requiresOpBundles=*/0,
|
||||
/*immArgPositions=*/[1], /*immArgAttrNames=*/["size"]> {
|
||||
/*requiresOpBundles=*/0, /*immArgPositions=*/[1],
|
||||
/*immArgAttrNames=*/["size"]> {
|
||||
let arguments = (ins LLVM_DefaultPointer:$start,
|
||||
I64Attr:$size,
|
||||
LLVM_AnyPointer:$ptr);
|
||||
@ -546,10 +542,9 @@ def LLVM_AssumeOp
|
||||
: LLVM_ZeroResultIntrOp<"assume", /*overloadedOperands=*/[], /*traits=*/[],
|
||||
/*requiresAccessGroup=*/0,
|
||||
/*requiresAliasAnalysis=*/0,
|
||||
/*requiresArgAndResultAttrs=*/0,
|
||||
/*requiresOpBundles=*/1> {
|
||||
dag args = (ins I1:$cond);
|
||||
let arguments = !con(args, baseArgs);
|
||||
let arguments = !con(args, opBundleArgs);
|
||||
|
||||
let assemblyFormat = [{
|
||||
$cond
|
||||
@ -1131,8 +1126,8 @@ def LLVM_DebugTrap : LLVM_ZeroResultIntrOp<"debugtrap">;
|
||||
def LLVM_UBSanTrap : LLVM_ZeroResultIntrOp<"ubsantrap",
|
||||
/*overloadedOperands=*/[], /*traits=*/[],
|
||||
/*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
|
||||
/*requiresArgAndResultAttrs=*/0, /*requiresOpBundles=*/0,
|
||||
/*immArgPositions=*/[0], /*immArgAttrNames=*/["failureKind"]> {
|
||||
/*requiresOpBundles=*/0, /*immArgPositions=*/[0],
|
||||
/*immArgAttrNames=*/["failureKind"]> {
|
||||
let arguments = (ins I8Attr:$failureKind);
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@ include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td"
|
||||
include "mlir/Dialect/LLVMIR/LLVMInterfaces.td"
|
||||
include "mlir/IR/OpBase.td"
|
||||
include "mlir/Interfaces/SideEffectInterfaces.td"
|
||||
include "mlir/Interfaces/CallInterfaces.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LLVM dialect type constraints.
|
||||
@ -287,26 +286,22 @@ class LLVM_MemAccessOpBase<string mnemonic, list<Trait> traits = []> :
|
||||
// intrinsic and "enumName" contains the name of the intrinsic as appears in
|
||||
// `llvm::Intrinsic` enum; one usually wants these to be related. Additionally,
|
||||
// the base class also defines the "mlirBuilder" field to support the inverse
|
||||
// translation starting from an LLVM IR intrinsic.
|
||||
//
|
||||
// The flags "requiresAccessGroup", "requiresAliasAnalysis",
|
||||
// "requiresFastmath", and "requiresArgAndResultAttrs" indicate which
|
||||
// interfaces the intrinsic implements. When a flag is set, the "baseArgs"
|
||||
// list includes the arguments required by the corresponding interface.
|
||||
// Derived intrinsics must append "baseArgs" to their argument list if they
|
||||
// enable any of these flags.
|
||||
//
|
||||
// LLVM `immargs` can be represented as MLIR attributes by providing both
|
||||
// the `immArgPositions` and `immArgAttrNames` lists. These two lists should
|
||||
// have equal length, with `immArgPositions` containing the argument
|
||||
// positions on the LLVM IR attribute that are `immargs`, and
|
||||
// `immArgAttrNames` mapping these to corresponding MLIR attributes.
|
||||
// translation starting from an LLVM IR intrinsic. The "requiresAccessGroup",
|
||||
// "requiresAliasAnalysis", and "requiresFastmath" flags specify which
|
||||
// interfaces the intrinsic implements. If the corresponding flags are set, the
|
||||
// "aliasAttrs" list contains the arguments required by the access group and
|
||||
// alias analysis interfaces. Derived intrinsics should append the "aliasAttrs"
|
||||
// to their argument list if they set one of the flags. LLVM `immargs` can be
|
||||
// represented as MLIR attributes by providing both the `immArgPositions` and
|
||||
// `immArgAttrNames` lists. These two lists should have equal length, with
|
||||
// `immArgPositions` containing the argument positions on the LLVM IR attribute
|
||||
// that are `immargs`, and `immArgAttrNames` mapping these to corresponding
|
||||
// MLIR attributes.
|
||||
class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
|
||||
list<int> overloadedResults, list<int> overloadedOperands,
|
||||
list<Trait> traits, int numResults,
|
||||
bit requiresAccessGroup = 0, bit requiresAliasAnalysis = 0,
|
||||
bit requiresFastmath = 0, bit requiresArgAndResultAttrs = 0,
|
||||
bit requiresOpBundles = 0,
|
||||
bit requiresFastmath = 0, bit requiresOpBundles = 0,
|
||||
list<int> immArgPositions = [],
|
||||
list<string> immArgAttrNames = []>
|
||||
: LLVM_OpBase<dialect, opName, !listconcat(
|
||||
@ -316,12 +311,10 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
|
||||
[DeclareOpInterfaceMethods<AliasAnalysisOpInterface>], []),
|
||||
!if(!gt(requiresFastmath, 0),
|
||||
[DeclareOpInterfaceMethods<FastmathFlagsInterface>], []),
|
||||
!if(!gt(requiresArgAndResultAttrs, 0),
|
||||
[DeclareOpInterfaceMethods<ArgAndResultAttrsOpInterface>], []),
|
||||
traits)>,
|
||||
LLVM_MemOpPatterns,
|
||||
Results<!if(!gt(numResults, 0), (outs LLVM_Type:$res), (outs))> {
|
||||
dag baseArgs = !con(
|
||||
dag aliasAttrs = !con(
|
||||
!if(!gt(requiresAccessGroup, 0),
|
||||
(ins OptionalAttr<LLVM_AccessGroupArrayAttr>:$access_groups),
|
||||
(ins )),
|
||||
@ -329,17 +322,13 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
|
||||
(ins OptionalAttr<LLVM_AliasScopeArrayAttr>:$alias_scopes,
|
||||
OptionalAttr<LLVM_AliasScopeArrayAttr>:$noalias_scopes,
|
||||
OptionalAttr<LLVM_TBAATagArrayAttr>:$tbaa),
|
||||
(ins )),
|
||||
!if(!gt(requiresArgAndResultAttrs, 0),
|
||||
(ins OptionalAttr<DictArrayAttr>:$arg_attrs,
|
||||
OptionalAttr<DictArrayAttr>:$res_attrs),
|
||||
(ins )),
|
||||
!if(!gt(requiresOpBundles, 0),
|
||||
(ins VariadicOfVariadic<LLVM_Type,
|
||||
"op_bundle_sizes">:$op_bundle_operands,
|
||||
DenseI32ArrayAttr:$op_bundle_sizes,
|
||||
OptionalAttr<ArrayAttr>:$op_bundle_tags),
|
||||
(ins )));
|
||||
dag opBundleArgs = !if(!gt(requiresOpBundles, 0),
|
||||
(ins VariadicOfVariadic<LLVM_Type,
|
||||
"op_bundle_sizes">:$op_bundle_operands,
|
||||
DenseI32ArrayAttr:$op_bundle_sizes,
|
||||
OptionalAttr<ArrayAttr>:$op_bundle_tags),
|
||||
(ins ));
|
||||
string llvmEnumName = enumName;
|
||||
string overloadedResultsCpp = "{" # !interleave(overloadedResults, ", ") # "}";
|
||||
string overloadedOperandsCpp = "{" # !interleave(overloadedOperands, ", ") # "}";
|
||||
@ -353,35 +342,23 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
|
||||
immArgPositionsCpp, immArgAttrNamesCpp], ",") # [{);
|
||||
(void) inst;
|
||||
}];
|
||||
string baseLlvmBuilderArgAndResultAttrs = [{
|
||||
if (failed(moduleTranslation.convertArgAndResultAttrs(
|
||||
op,
|
||||
inst,
|
||||
}] # immArgPositionsCpp # [{))) {
|
||||
return failure();
|
||||
}
|
||||
}];
|
||||
string baseLlvmBuilderCoda = !if(!gt(numResults, 0), "$res = inst;", "");
|
||||
let llvmBuilder = baseLlvmBuilder
|
||||
# !if(!gt(requiresAccessGroup, 0),
|
||||
setAccessGroupsMetadataCode, "")
|
||||
# !if(!gt(requiresAliasAnalysis, 0),
|
||||
setAliasAnalysisMetadataCode, "")
|
||||
# !if(!gt(requiresArgAndResultAttrs, 0),
|
||||
baseLlvmBuilderArgAndResultAttrs, "")
|
||||
# baseLlvmBuilderCoda;
|
||||
let llvmBuilder = baseLlvmBuilder # !if(!gt(requiresAccessGroup, 0), setAccessGroupsMetadataCode, "")
|
||||
# !if(!gt(requiresAliasAnalysis, 0), setAliasAnalysisMetadataCode, "")
|
||||
# baseLlvmBuilderCoda;
|
||||
|
||||
string baseMlirBuilder = [{
|
||||
SmallVector<Value> mlirOperands;
|
||||
SmallVector<NamedAttribute> mlirAttrs;
|
||||
if (failed(moduleImport.convertIntrinsicArguments(
|
||||
llvmOperands,
|
||||
llvmOpBundles,
|
||||
}] # !if(!gt(requiresOpBundles, 0), "true", "false") # [{,
|
||||
}] # immArgPositionsCpp # [{,
|
||||
}] # immArgAttrNamesCpp # [{,
|
||||
mlirOperands,
|
||||
mlirAttrs))) {
|
||||
llvmOperands,
|
||||
llvmOpBundles,
|
||||
}] # !if(!gt(requiresOpBundles, 0), "true", "false") # [{,
|
||||
}] # immArgPositionsCpp # [{,
|
||||
}] # immArgAttrNamesCpp # [{,
|
||||
mlirOperands,
|
||||
mlirAttrs))
|
||||
) {
|
||||
return failure();
|
||||
}
|
||||
SmallVector<Type> resultTypes =
|
||||
@ -389,16 +366,9 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
|
||||
auto op = $_qualCppClassName::create($_builder,
|
||||
$_location, resultTypes, mlirOperands, mlirAttrs);
|
||||
}];
|
||||
string baseMlirBuilderArgAndResultAttrs = [{
|
||||
moduleImport.convertArgAndResultAttrs(
|
||||
inst, op, }] # immArgPositionsCpp # [{);
|
||||
}];
|
||||
string baseMlirBuilderCoda = !if(!gt(numResults, 0), "$res = op;", "$_op = op;");
|
||||
let mlirBuilder = baseMlirBuilder
|
||||
# !if(!gt(requiresFastmath, 0),
|
||||
let mlirBuilder = baseMlirBuilder # !if(!gt(requiresFastmath, 0),
|
||||
"moduleImport.setFastmathFlagsAttr(inst, op);", "")
|
||||
# !if(!gt(requiresArgAndResultAttrs, 0),
|
||||
baseMlirBuilderArgAndResultAttrs, "")
|
||||
# baseMlirBuilderCoda;
|
||||
|
||||
// Code for handling a `range` attribute that holds the constant range of the
|
||||
@ -429,14 +399,14 @@ class LLVM_IntrOp<string mnem, list<int> overloadedResults,
|
||||
list<int> overloadedOperands, list<Trait> traits,
|
||||
int numResults, bit requiresAccessGroup = 0,
|
||||
bit requiresAliasAnalysis = 0, bit requiresFastmath = 0,
|
||||
bit requiresArgAndResultAttrs = 0, bit requiresOpBundles = 0,
|
||||
bit requiresOpBundles = 0,
|
||||
list<int> immArgPositions = [],
|
||||
list<string> immArgAttrNames = []>
|
||||
: LLVM_IntrOpBase<LLVM_Dialect, "intr." # mnem, !subst(".", "_", mnem),
|
||||
overloadedResults, overloadedOperands, traits,
|
||||
numResults, requiresAccessGroup, requiresAliasAnalysis,
|
||||
requiresFastmath, requiresArgAndResultAttrs,
|
||||
requiresOpBundles, immArgPositions, immArgAttrNames>;
|
||||
requiresFastmath, requiresOpBundles, immArgPositions,
|
||||
immArgAttrNames>;
|
||||
|
||||
// Base class for LLVM intrinsic operations returning no results. Places the
|
||||
// intrinsic into the LLVM dialect and prefixes its name with "intr.".
|
||||
@ -456,14 +426,13 @@ class LLVM_ZeroResultIntrOp<string mnem, list<int> overloadedOperands = [],
|
||||
list<Trait> traits = [],
|
||||
bit requiresAccessGroup = 0,
|
||||
bit requiresAliasAnalysis = 0,
|
||||
bit requiresArgAndResultAttrs = 0,
|
||||
bit requiresOpBundles = 0,
|
||||
list<int> immArgPositions = [],
|
||||
list<string> immArgAttrNames = []>
|
||||
: LLVM_IntrOp<mnem, [], overloadedOperands, traits, /*numResults=*/0,
|
||||
requiresAccessGroup, requiresAliasAnalysis,
|
||||
/*requiresFastMath=*/0, requiresArgAndResultAttrs,
|
||||
requiresOpBundles, immArgPositions, immArgAttrNames>;
|
||||
/*requiresFastMath=*/0, requiresOpBundles, immArgPositions,
|
||||
immArgAttrNames>;
|
||||
|
||||
// Base class for LLVM intrinsic operations returning one result. Places the
|
||||
// intrinsic into the LLVM dialect and prefixes its name with "intr.". This is
|
||||
@ -479,8 +448,7 @@ class LLVM_OneResultIntrOp<string mnem, list<int> overloadedResults = [],
|
||||
list<string> immArgAttrNames = []>
|
||||
: LLVM_IntrOp<mnem, overloadedResults, overloadedOperands, traits, 1,
|
||||
/*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
|
||||
requiresFastmath, /*requiresArgAndResultAttrs=*/0,
|
||||
/*requiresOpBundles=*/0, immArgPositions,
|
||||
requiresFastmath, /*requiresOpBundles=*/0, immArgPositions,
|
||||
immArgAttrNames>;
|
||||
|
||||
// Base class for LLVM intrinsic operations returning two results. Places the
|
||||
@ -497,8 +465,7 @@ class LLVM_TwoResultIntrOp<string mnem, list<int> overloadedResults = [],
|
||||
list<string> immArgAttrNames = []>
|
||||
: LLVM_IntrOp<mnem, overloadedResults, overloadedOperands, traits, 2,
|
||||
/*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
|
||||
requiresFastmath, /*requiresArgAndResultAttrs=*/0,
|
||||
/*requiresOpBundles=*/0, immArgPositions,
|
||||
requiresFastmath, /*requiresOpBundles=*/0, immArgPositions,
|
||||
immArgAttrNames>;
|
||||
|
||||
def LLVM_OneResultOpBuilder :
|
||||
|
@ -2405,8 +2405,7 @@ def LLVM_InlineAsmOp : LLVM_Op<"inline_asm", [DeclareOpInterfaceMethods<MemoryEf
|
||||
|
||||
def LLVM_CallIntrinsicOp
|
||||
: LLVM_Op<"call_intrinsic",
|
||||
[ArgAndResultAttrsOpInterface,
|
||||
AttrSizedOperandSegments,
|
||||
[AttrSizedOperandSegments,
|
||||
DeclareOpInterfaceMethods<FastmathFlagsInterface>]> {
|
||||
let summary = "Call to an LLVM intrinsic function.";
|
||||
let description = [{
|
||||
|
@ -98,7 +98,7 @@ class ROCDL_IntrOp<string mnemonic, list<int> overloadedResults,
|
||||
LLVM_IntrOpBase<ROCDL_Dialect, mnemonic,
|
||||
"amdgcn_" # !subst(".", "_", mnemonic), overloadedResults,
|
||||
overloadedOperands, traits, numResults, requiresAccessGroup,
|
||||
requiresAliasAnalysis, 0, 0, 0, immArgPositions, immArgAttrNames>;
|
||||
requiresAliasAnalysis, 0, 0, immArgPositions, immArgAttrNames>;
|
||||
|
||||
// Subclass to save typing and ease readibility when there aren't overloaded
|
||||
// operands or memory accesses.
|
||||
@ -482,7 +482,7 @@ def ROCDLBufferLDS : LLVM_PointerInAddressSpace<3>;
|
||||
class ROCDL_LDS_Read_Tr_IntrOp<string mnemonic> :
|
||||
ROCDL_IntrOp<mnemonic, [1], [], [], 1, 0, 1> {
|
||||
dag args = (ins Arg<ROCDLBufferLDS, "", [MemRead]>:$ptr);
|
||||
let arguments = !con(args, baseArgs);
|
||||
let arguments = !con(args, aliasAttrs);
|
||||
let assemblyFormat = "$ptr attr-dict `:` type($ptr) `->` type($res)";
|
||||
let extraClassDefinition = [{
|
||||
::llvm::SmallVector<::mlir::Value> $cppClass::getAccessedOperands() {
|
||||
@ -507,7 +507,7 @@ def ROCDL_LoadToLDSOp :
|
||||
I32Attr:$size,
|
||||
I32Attr:$offset,
|
||||
I32Attr:$aux);
|
||||
let arguments = !con(args, baseArgs);
|
||||
let arguments = !con(args, aliasAttrs);
|
||||
let assemblyFormat = [{
|
||||
$globalPtr `,` $ldsPtr `,` $size `,` $offset `,` $aux
|
||||
attr-dict `:` type($globalPtr)
|
||||
@ -526,7 +526,7 @@ def ROCDL_GlobalLoadLDSOp :
|
||||
I32Attr:$size,
|
||||
I32Attr:$offset,
|
||||
I32Attr:$aux);
|
||||
let arguments = !con(args, baseArgs);
|
||||
let arguments = !con(args, aliasAttrs);
|
||||
let assemblyFormat = [{
|
||||
$globalPtr `,` $ldsPtr `,` $size `,` $offset `,` $aux
|
||||
attr-dict
|
||||
@ -561,7 +561,7 @@ def ROCDL_RawPtrBufferLoadOp :
|
||||
I32:$offset,
|
||||
I32:$soffset,
|
||||
I32:$aux);
|
||||
let arguments = !con(args, baseArgs);
|
||||
let arguments = !con(args, aliasAttrs);
|
||||
let assemblyFormat = "operands attr-dict `:` type($res)";
|
||||
let extraClassDefinition = [{
|
||||
::llvm::SmallVector<::mlir::Value> $cppClass::getAccessedOperands() {
|
||||
@ -579,7 +579,7 @@ def ROCDL_RawPtrBufferLoadLdsOp :
|
||||
I32:$soffset,
|
||||
I32:$offset,
|
||||
I32:$aux);
|
||||
let arguments = !con(args, baseArgs);
|
||||
let arguments = !con(args, aliasAttrs);
|
||||
let assemblyFormat = "operands attr-dict";
|
||||
let extraClassDefinition = [{
|
||||
::llvm::SmallVector<::mlir::Value> $cppClass::getAccessedOperands() {
|
||||
@ -595,7 +595,7 @@ def ROCDL_RawPtrBufferStoreOp :
|
||||
I32:$offset,
|
||||
I32:$soffset,
|
||||
I32:$aux);
|
||||
let arguments = !con(args, baseArgs);
|
||||
let arguments = !con(args, aliasAttrs);
|
||||
let assemblyFormat = "operands attr-dict `:` type($vdata)";
|
||||
let extraClassDefinition = [{
|
||||
::llvm::SmallVector<::mlir::Value> $cppClass::getAccessedOperands() {
|
||||
@ -614,7 +614,7 @@ def ROCDL_RawPtrBufferAtomicCmpSwap :
|
||||
I32:$offset,
|
||||
I32:$soffset,
|
||||
I32:$aux);
|
||||
let arguments = !con(args, baseArgs);
|
||||
let arguments = !con(args, aliasAttrs);
|
||||
let assemblyFormat = "operands attr-dict `:` type($res)";
|
||||
let extraClassDefinition = [{
|
||||
::llvm::SmallVector<::mlir::Value> $cppClass::getAccessedOperands() {
|
||||
@ -630,7 +630,7 @@ class ROCDL_RawPtrBufferAtomicNoRet<string op> :
|
||||
I32:$offset,
|
||||
I32:$soffset,
|
||||
I32:$aux);
|
||||
let arguments = !con(args, baseArgs);
|
||||
let arguments = !con(args, aliasAttrs);
|
||||
let assemblyFormat = "operands attr-dict `:` type($vdata)";
|
||||
let extraClassDefinition = [{
|
||||
::llvm::SmallVector<::mlir::Value> $cppClass::getAccessedOperands() {
|
||||
|
@ -18,16 +18,10 @@
|
||||
include "mlir/IR/OpBase.td"
|
||||
|
||||
|
||||
/// Interface for operations with result and argument attributes.
|
||||
def ArgAndResultAttrsOpInterface : OpInterface<"ArgAndResultAttrsOpInterface"> {
|
||||
let description = [{
|
||||
An operation that has argument and result attributes. This interface
|
||||
provides functions to access and modify the argument and result
|
||||
attributes of the operation.
|
||||
}];
|
||||
let cppNamespace = "::mlir";
|
||||
|
||||
let methods = [
|
||||
/// Interface for operations with arguments attributes (both call-like
|
||||
/// and callable operations).
|
||||
def ArgumentAttributesMethods {
|
||||
list<InterfaceMethod> methods = [
|
||||
InterfaceMethod<[{
|
||||
Get the array of argument attribute dictionaries. The method should
|
||||
return an array attribute containing only dictionary attributes equal in
|
||||
@ -70,8 +64,7 @@ def ArgAndResultAttrsOpInterface : OpInterface<"ArgAndResultAttrsOpInterface"> {
|
||||
// a call-like operation. This represents the destination of the call.
|
||||
|
||||
/// Interface for call-like operations.
|
||||
def CallOpInterface : OpInterface<"CallOpInterface",
|
||||
[ArgAndResultAttrsOpInterface]> {
|
||||
def CallOpInterface : OpInterface<"CallOpInterface"> {
|
||||
let description = [{
|
||||
A call-like operation is one that transfers control from one sub-routine to
|
||||
another. These operations may be traditional direct calls `call @foo`, or
|
||||
@ -130,12 +123,11 @@ def CallOpInterface : OpInterface<"CallOpInterface",
|
||||
return ::mlir::call_interface_impl::resolveCallable($_op);
|
||||
}]
|
||||
>
|
||||
];
|
||||
] # ArgumentAttributesMethods.methods;
|
||||
}
|
||||
|
||||
/// Interface for callable operations.
|
||||
def CallableOpInterface : OpInterface<"CallableOpInterface",
|
||||
[ArgAndResultAttrsOpInterface]> {
|
||||
def CallableOpInterface : OpInterface<"CallableOpInterface"> {
|
||||
let description = [{
|
||||
A callable operation is one who represents a potential sub-routine, and may
|
||||
be a target for a call-like operation (those providing the CallOpInterface
|
||||
@ -148,11 +140,11 @@ def CallableOpInterface : OpInterface<"CallableOpInterface",
|
||||
|
||||
let methods = [
|
||||
InterfaceMethod<[{
|
||||
Returns the region on the current operation that is callable. This may
|
||||
return null in the case of an external callable object, e.g. an external
|
||||
function.
|
||||
}],
|
||||
"::mlir::Region *", "getCallableRegion">,
|
||||
Returns the region on the current operation that is callable. This may
|
||||
return null in the case of an external callable object, e.g. an external
|
||||
function.
|
||||
}],
|
||||
"::mlir::Region *", "getCallableRegion">,
|
||||
InterfaceMethod<[{
|
||||
Returns the callable's argument types based exclusively on the type (to
|
||||
allow for this method may be called on function declarations).
|
||||
@ -163,7 +155,7 @@ def CallableOpInterface : OpInterface<"CallableOpInterface",
|
||||
allow for this method may be called on function declarations).
|
||||
}],
|
||||
"::llvm::ArrayRef<::mlir::Type>", "getResultTypes">,
|
||||
];
|
||||
] # ArgumentAttributesMethods.methods;
|
||||
}
|
||||
|
||||
#endif // MLIR_INTERFACES_CALLINTERFACES
|
||||
|
@ -291,12 +291,10 @@ public:
|
||||
SmallVectorImpl<Value> &valuesOut,
|
||||
SmallVectorImpl<NamedAttribute> &attrsOut);
|
||||
|
||||
/// Converts the argument and result attributes attached to `call` and adds
|
||||
/// them to `attrsOp`. For intrinsic calls, filters out attributes
|
||||
/// corresponding to immediate arguments specified by `immArgPositions`.
|
||||
void convertArgAndResultAttrs(llvm::CallBase *call,
|
||||
ArgAndResultAttrsOpInterface attrsOp,
|
||||
ArrayRef<unsigned> immArgPositions = {});
|
||||
/// Converts the parameter and result attributes in `argsAttr` and `resAttr`
|
||||
/// and add them to the `callOp`.
|
||||
void convertParameterAttributes(llvm::CallBase *call, ArrayAttr &argsAttr,
|
||||
ArrayAttr &resAttr, OpBuilder &builder);
|
||||
|
||||
/// Whether the importer should try to convert all intrinsics to
|
||||
/// llvm.call_intrinsic instead of dialect supported operations.
|
||||
@ -380,12 +378,19 @@ private:
|
||||
bool &isIncompatibleCall);
|
||||
/// Returns the callee name, or an empty symbol if the call is not direct.
|
||||
FlatSymbolRefAttr convertCalleeName(llvm::CallBase *callInst);
|
||||
/// Converts the argument and result attributes attached to `func` and adds
|
||||
/// Converts the parameter and result attributes attached to `func` and adds
|
||||
/// them to the `funcOp`.
|
||||
void convertArgAndResultAttrs(llvm::Function *func, LLVMFuncOp funcOp);
|
||||
/// Converts the argument or result attributes in `llvmAttrSet` to a
|
||||
/// corresponding MLIR LLVM dialect attribute dictionary.
|
||||
DictionaryAttr convertArgOrResultAttrSet(llvm::AttributeSet llvmAttrSet);
|
||||
void convertParameterAttributes(llvm::Function *func, LLVMFuncOp funcOp,
|
||||
OpBuilder &builder);
|
||||
/// Converts the AttributeSet of one parameter in LLVM IR to a corresponding
|
||||
/// DictionaryAttr for the LLVM dialect.
|
||||
DictionaryAttr convertParameterAttribute(llvm::AttributeSet llvmParamAttrs,
|
||||
OpBuilder &builder);
|
||||
/// Converts the parameter and result attributes attached to `call` and adds
|
||||
/// them to the `callOp`. Implemented in terms of the the public definition of
|
||||
/// convertParameterAttributes.
|
||||
void convertParameterAttributes(llvm::CallBase *call, CallOpInterface callOp,
|
||||
OpBuilder &builder);
|
||||
/// Converts the attributes attached to `inst` and adds them to the `op`.
|
||||
LogicalResult convertCallAttributes(llvm::CallInst *inst, CallOp op);
|
||||
/// Converts the attributes attached to `inst` and adds them to the `op`.
|
||||
|
@ -307,16 +307,10 @@ public:
|
||||
/*recordInsertions=*/false);
|
||||
}
|
||||
|
||||
/// Converts argument and result attributes from `attrsOp` to LLVM IR
|
||||
/// attributes on the `call` instruction. Returns failure if conversion fails.
|
||||
/// The `immArgPositions` parameter is only relevant for intrinsics. It
|
||||
/// specifies the positions of immediate arguments, which do not have
|
||||
/// associated argument attributes in MLIR and should be skipped during
|
||||
/// attribute mapping.
|
||||
LogicalResult
|
||||
convertArgAndResultAttrs(ArgAndResultAttrsOpInterface attrsOp,
|
||||
llvm::CallBase *call,
|
||||
ArrayRef<unsigned> immArgPositions = {});
|
||||
/// Translates parameter attributes of a call and adds them to the returned
|
||||
/// AttrBuilder. Returns failure if any of the translations failed.
|
||||
FailureOr<llvm::AttrBuilder> convertParameterAttrs(mlir::Location loc,
|
||||
DictionaryAttr paramAttrs);
|
||||
|
||||
/// Gets the named metadata in the LLVM IR module being constructed, creating
|
||||
/// it if it does not exist.
|
||||
@ -396,11 +390,6 @@ private:
|
||||
convertDialectAttributes(Operation *op,
|
||||
ArrayRef<llvm::Instruction *> instructions);
|
||||
|
||||
/// Translates parameter attributes of a call and adds them to the returned
|
||||
/// AttrBuilder. Returns failure if any of the translations failed.
|
||||
FailureOr<llvm::AttrBuilder> convertParameterAttrs(mlir::Location loc,
|
||||
DictionaryAttr paramAttrs);
|
||||
|
||||
/// Translates parameter attributes of a function and adds them to the
|
||||
/// returned AttrBuilder. Returns failure if any of the translations failed.
|
||||
FailureOr<llvm::AttrBuilder>
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
|
||||
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
|
||||
#include "mlir/IR/Operation.h"
|
||||
#include "mlir/Interfaces/CallInterfaces.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "mlir/Target/LLVMIR/ModuleTranslation.h"
|
||||
|
||||
@ -137,6 +136,46 @@ convertOperandBundles(OperandRangeRange bundleOperands,
|
||||
return convertOperandBundles(bundleOperands, *bundleTags, moduleTranslation);
|
||||
}
|
||||
|
||||
static LogicalResult
|
||||
convertParameterAndResultAttrs(mlir::Location loc, ArrayAttr argAttrsArray,
|
||||
ArrayAttr resAttrsArray, llvm::CallBase *call,
|
||||
LLVM::ModuleTranslation &moduleTranslation) {
|
||||
if (argAttrsArray) {
|
||||
for (auto [argIdx, argAttrsAttr] : llvm::enumerate(argAttrsArray)) {
|
||||
if (auto argAttrs = cast<DictionaryAttr>(argAttrsAttr);
|
||||
!argAttrs.empty()) {
|
||||
FailureOr<llvm::AttrBuilder> attrBuilder =
|
||||
moduleTranslation.convertParameterAttrs(loc, argAttrs);
|
||||
if (failed(attrBuilder))
|
||||
return failure();
|
||||
call->addParamAttrs(argIdx, *attrBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (resAttrsArray && resAttrsArray.size() > 0) {
|
||||
if (resAttrsArray.size() != 1)
|
||||
return mlir::emitError(loc, "llvm.func cannot have multiple results");
|
||||
if (auto resAttrs = cast<DictionaryAttr>(resAttrsArray[0]);
|
||||
!resAttrs.empty()) {
|
||||
FailureOr<llvm::AttrBuilder> attrBuilder =
|
||||
moduleTranslation.convertParameterAttrs(loc, resAttrs);
|
||||
if (failed(attrBuilder))
|
||||
return failure();
|
||||
call->addRetAttrs(*attrBuilder);
|
||||
}
|
||||
}
|
||||
return success();
|
||||
}
|
||||
|
||||
static LogicalResult
|
||||
convertParameterAndResultAttrs(CallOpInterface callOp, llvm::CallBase *call,
|
||||
LLVM::ModuleTranslation &moduleTranslation) {
|
||||
return convertParameterAndResultAttrs(
|
||||
callOp.getLoc(), callOp.getArgAttrsAttr(), callOp.getResAttrsAttr(), call,
|
||||
moduleTranslation);
|
||||
}
|
||||
|
||||
/// Builder for LLVM_CallIntrinsicOp
|
||||
static LogicalResult
|
||||
convertCallLLVMIntrinsicOp(CallIntrinsicOp op, llvm::IRBuilderBase &builder,
|
||||
@ -204,7 +243,9 @@ convertCallLLVMIntrinsicOp(CallIntrinsicOp op, llvm::IRBuilderBase &builder,
|
||||
convertOperandBundles(op.getOpBundleOperands(), op.getOpBundleTags(),
|
||||
moduleTranslation));
|
||||
|
||||
if (failed(moduleTranslation.convertArgAndResultAttrs(op, inst)))
|
||||
if (failed(convertParameterAndResultAttrs(op.getLoc(), op.getArgAttrsAttr(),
|
||||
op.getResAttrsAttr(), inst,
|
||||
moduleTranslation)))
|
||||
return failure();
|
||||
|
||||
if (op.getNumResults() == 1)
|
||||
@ -414,7 +455,7 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
|
||||
if (callOp.getInlineHintAttr())
|
||||
call->addFnAttr(llvm::Attribute::InlineHint);
|
||||
|
||||
if (failed(moduleTranslation.convertArgAndResultAttrs(callOp, call)))
|
||||
if (failed(convertParameterAndResultAttrs(callOp, call, moduleTranslation)))
|
||||
return failure();
|
||||
|
||||
if (MemoryEffectsAttr memAttr = callOp.getMemoryEffectsAttr()) {
|
||||
@ -528,7 +569,8 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
|
||||
operandsRef.drop_front(), opBundles);
|
||||
}
|
||||
result->setCallingConv(convertCConvToLLVM(invOp.getCConv()));
|
||||
if (failed(moduleTranslation.convertArgAndResultAttrs(invOp, result)))
|
||||
if (failed(
|
||||
convertParameterAndResultAttrs(invOp, result, moduleTranslation)))
|
||||
return failure();
|
||||
moduleTranslation.mapBranch(invOp, result);
|
||||
// InvokeOp can only have 0 or 1 result
|
||||
|
@ -33,9 +33,7 @@ LogicalResult mlir::LLVMImportInterface::convertUnregisteredIntrinsic(
|
||||
SmallVector<Value> mlirOperands;
|
||||
SmallVector<NamedAttribute> mlirAttrs;
|
||||
if (failed(moduleImport.convertIntrinsicArguments(
|
||||
llvmOperands, llvmOpBundles, /*requiresOpBundles=*/false,
|
||||
/*immArgPositions=*/{}, /*immArgAttrNames=*/{}, mlirOperands,
|
||||
mlirAttrs)))
|
||||
llvmOperands, llvmOpBundles, false, {}, {}, mlirOperands, mlirAttrs)))
|
||||
return failure();
|
||||
|
||||
Type resultType = moduleImport.convertType(inst->getType());
|
||||
@ -46,7 +44,11 @@ LogicalResult mlir::LLVMImportInterface::convertUnregisteredIntrinsic(
|
||||
ValueRange{mlirOperands}, FastmathFlagsAttr{});
|
||||
|
||||
moduleImport.setFastmathFlagsAttr(inst, op);
|
||||
moduleImport.convertArgAndResultAttrs(inst, op);
|
||||
|
||||
ArrayAttr argsAttr, resAttr;
|
||||
moduleImport.convertParameterAttributes(inst, argsAttr, resAttr, builder);
|
||||
op.setArgAttrsAttr(argsAttr);
|
||||
op.setResAttrsAttr(resAttr);
|
||||
|
||||
// Update importer tracking of results.
|
||||
unsigned numRes = op.getNumResults();
|
||||
|
@ -2267,7 +2267,7 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
|
||||
// Handle parameter and result attributes unless it's an incompatible
|
||||
// call.
|
||||
if (!isIncompatibleCall)
|
||||
convertArgAndResultAttrs(callInst, callOp);
|
||||
convertParameterAttributes(callInst, callOp, builder);
|
||||
return callOp.getOperation();
|
||||
}();
|
||||
|
||||
@ -2364,7 +2364,7 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
|
||||
// Handle parameter and result attributes unless it's an incompatible
|
||||
// invoke.
|
||||
if (!isIncompatibleInvoke)
|
||||
convertArgAndResultAttrs(invokeInst, invokeOp);
|
||||
convertParameterAttributes(invokeInst, invokeOp, builder);
|
||||
|
||||
if (!invokeInst->getType()->isVoidTy())
|
||||
mapValue(inst, invokeOp.getResults().front());
|
||||
@ -2730,10 +2730,11 @@ void ModuleImport::processFunctionAttributes(llvm::Function *func,
|
||||
}
|
||||
|
||||
DictionaryAttr
|
||||
ModuleImport::convertArgOrResultAttrSet(llvm::AttributeSet llvmAttrSet) {
|
||||
ModuleImport::convertParameterAttribute(llvm::AttributeSet llvmParamAttrs,
|
||||
OpBuilder &builder) {
|
||||
SmallVector<NamedAttribute> paramAttrs;
|
||||
for (auto [llvmKind, mlirName] : getAttrKindToNameMapping()) {
|
||||
auto llvmAttr = llvmAttrSet.getAttribute(llvmKind);
|
||||
auto llvmAttr = llvmParamAttrs.getAttribute(llvmKind);
|
||||
// Skip attributes that are not attached.
|
||||
if (!llvmAttr.isValid())
|
||||
continue;
|
||||
@ -2768,12 +2769,13 @@ ModuleImport::convertArgOrResultAttrSet(llvm::AttributeSet llvmAttrSet) {
|
||||
return builder.getDictionaryAttr(paramAttrs);
|
||||
}
|
||||
|
||||
void ModuleImport::convertArgAndResultAttrs(llvm::Function *func,
|
||||
LLVMFuncOp funcOp) {
|
||||
void ModuleImport::convertParameterAttributes(llvm::Function *func,
|
||||
LLVMFuncOp funcOp,
|
||||
OpBuilder &builder) {
|
||||
auto llvmAttrs = func->getAttributes();
|
||||
for (size_t i = 0, e = funcOp.getNumArguments(); i < e; ++i) {
|
||||
llvm::AttributeSet llvmArgAttrs = llvmAttrs.getParamAttrs(i);
|
||||
funcOp.setArgAttrs(i, convertArgOrResultAttrSet(llvmArgAttrs));
|
||||
funcOp.setArgAttrs(i, convertParameterAttribute(llvmArgAttrs, builder));
|
||||
}
|
||||
// Convert the result attributes and attach them wrapped in an ArrayAttribute
|
||||
// to the funcOp.
|
||||
@ -2781,23 +2783,17 @@ void ModuleImport::convertArgAndResultAttrs(llvm::Function *func,
|
||||
if (!llvmResAttr.hasAttributes())
|
||||
return;
|
||||
funcOp.setResAttrsAttr(
|
||||
builder.getArrayAttr({convertArgOrResultAttrSet(llvmResAttr)}));
|
||||
builder.getArrayAttr(convertParameterAttribute(llvmResAttr, builder)));
|
||||
}
|
||||
|
||||
void ModuleImport::convertArgAndResultAttrs(
|
||||
llvm::CallBase *call, ArgAndResultAttrsOpInterface attrsOp,
|
||||
ArrayRef<unsigned> immArgPositions) {
|
||||
// Compute the set of immediate argument positions.
|
||||
llvm::SmallDenseSet<unsigned> immArgPositionsSet(immArgPositions.begin(),
|
||||
immArgPositions.end());
|
||||
// Convert the argument attributes and filter out immediate arguments.
|
||||
void ModuleImport::convertParameterAttributes(llvm::CallBase *call,
|
||||
ArrayAttr &argsAttr,
|
||||
ArrayAttr &resAttr,
|
||||
OpBuilder &builder) {
|
||||
llvm::AttributeList llvmAttrs = call->getAttributes();
|
||||
SmallVector<llvm::AttributeSet> llvmArgAttrsSet;
|
||||
bool anyArgAttrs = false;
|
||||
for (size_t i = 0, e = call->arg_size(); i < e; ++i) {
|
||||
// Skip immediate arguments.
|
||||
if (immArgPositionsSet.contains(i))
|
||||
continue;
|
||||
llvmArgAttrsSet.emplace_back(llvmAttrs.getParamAttrs(i));
|
||||
if (llvmArgAttrsSet.back().hasAttributes())
|
||||
anyArgAttrs = true;
|
||||
@ -2811,16 +2807,24 @@ void ModuleImport::convertArgAndResultAttrs(
|
||||
if (anyArgAttrs) {
|
||||
SmallVector<DictionaryAttr> argAttrs;
|
||||
for (auto &llvmArgAttrs : llvmArgAttrsSet)
|
||||
argAttrs.emplace_back(convertArgOrResultAttrSet(llvmArgAttrs));
|
||||
attrsOp.setArgAttrsAttr(getArrayAttr(argAttrs));
|
||||
argAttrs.emplace_back(convertParameterAttribute(llvmArgAttrs, builder));
|
||||
argsAttr = getArrayAttr(argAttrs);
|
||||
}
|
||||
|
||||
// Convert the result attributes.
|
||||
llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
|
||||
if (!llvmResAttr.hasAttributes())
|
||||
return;
|
||||
DictionaryAttr resAttrs = convertArgOrResultAttrSet(llvmResAttr);
|
||||
attrsOp.setResAttrsAttr(getArrayAttr({resAttrs}));
|
||||
DictionaryAttr resAttrs = convertParameterAttribute(llvmResAttr, builder);
|
||||
resAttr = getArrayAttr({resAttrs});
|
||||
}
|
||||
|
||||
void ModuleImport::convertParameterAttributes(llvm::CallBase *call,
|
||||
CallOpInterface callOp,
|
||||
OpBuilder &builder) {
|
||||
ArrayAttr argsAttr, resAttr;
|
||||
convertParameterAttributes(call, argsAttr, resAttr, builder);
|
||||
callOp.setArgAttrsAttr(argsAttr);
|
||||
callOp.setResAttrsAttr(resAttr);
|
||||
}
|
||||
|
||||
template <typename Op>
|
||||
@ -2888,7 +2892,7 @@ LogicalResult ModuleImport::processFunction(llvm::Function *func) {
|
||||
builder, loc, func->getName(), functionType,
|
||||
convertLinkageFromLLVM(func->getLinkage()), dsoLocal, cconv);
|
||||
|
||||
convertArgAndResultAttrs(func, funcOp);
|
||||
convertParameterAttributes(func, funcOp, builder);
|
||||
|
||||
if (FlatSymbolRefAttr personality = getPersonalityAsAttr(func))
|
||||
funcOp.setPersonalityAttr(personality);
|
||||
|
@ -1758,48 +1758,6 @@ ModuleTranslation::convertParameterAttrs(LLVMFuncOp func, int argIdx,
|
||||
return attrBuilder;
|
||||
}
|
||||
|
||||
LogicalResult ModuleTranslation::convertArgAndResultAttrs(
|
||||
ArgAndResultAttrsOpInterface attrsOp, llvm::CallBase *call,
|
||||
ArrayRef<unsigned> immArgPositions) {
|
||||
// Convert the argument attributes.
|
||||
if (ArrayAttr argAttrsArray = attrsOp.getArgAttrsAttr()) {
|
||||
unsigned argAttrIdx = 0;
|
||||
llvm::SmallDenseSet<unsigned> immArgPositionsSet(immArgPositions.begin(),
|
||||
immArgPositions.end());
|
||||
for (unsigned argIdx : llvm::seq<unsigned>(call->arg_size())) {
|
||||
if (argAttrIdx >= argAttrsArray.size())
|
||||
break;
|
||||
// Skip immediate arguments (they have no entries in argAttrsArray).
|
||||
if (immArgPositionsSet.contains(argIdx))
|
||||
continue;
|
||||
// Skip empty argument attributes.
|
||||
auto argAttrs = cast<DictionaryAttr>(argAttrsArray[argAttrIdx++]);
|
||||
if (argAttrs.empty())
|
||||
continue;
|
||||
// Convert and add attributes to the call instruction.
|
||||
FailureOr<llvm::AttrBuilder> attrBuilder =
|
||||
convertParameterAttrs(attrsOp->getLoc(), argAttrs);
|
||||
if (failed(attrBuilder))
|
||||
return failure();
|
||||
call->addParamAttrs(argIdx, *attrBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the result attributes.
|
||||
if (ArrayAttr resAttrsArray = attrsOp.getResAttrsAttr()) {
|
||||
if (!resAttrsArray.empty()) {
|
||||
auto resAttrs = cast<DictionaryAttr>(resAttrsArray[0]);
|
||||
FailureOr<llvm::AttrBuilder> attrBuilder =
|
||||
convertParameterAttrs(attrsOp->getLoc(), resAttrs);
|
||||
if (failed(attrBuilder))
|
||||
return failure();
|
||||
call->addRetAttrs(*attrBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
return success();
|
||||
}
|
||||
|
||||
FailureOr<llvm::AttrBuilder>
|
||||
ModuleTranslation::convertParameterAttrs(Location loc,
|
||||
DictionaryAttr paramAttrs) {
|
||||
|
@ -570,10 +570,10 @@ define void @trap_intrinsics() {
|
||||
|
||||
; CHECK-LABEL: llvm.func @memcpy_test
|
||||
define void @memcpy_test(i32 %0, ptr %1, ptr %2) {
|
||||
; CHECK: "llvm.intr.memcpy"(%{{.*}}, %{{.*}}, %{{.*}}) <{arg_attrs = [{llvm.align = 4 : i64}, {llvm.align = 8 : i64}, {}], isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %1, ptr align 8 %2, i32 %0, i1 false)
|
||||
; CHECK: "llvm.intr.memcpy.inline"(%{{.*}}, %{{.*}}) <{arg_attrs = [{}, {llvm.align = 4 : i64}], isVolatile = false, len = 10 : i64}> : (!llvm.ptr, !llvm.ptr) -> ()
|
||||
call void @llvm.memcpy.inline.p0.p0.i64(ptr %1, ptr align 4 %2, i64 10, i1 false)
|
||||
; CHECK: "llvm.intr.memcpy"(%{{.*}}, %{{.*}}, %{{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr %1, ptr %2, i32 %0, i1 false)
|
||||
; CHECK: "llvm.intr.memcpy.inline"(%{{.*}}, %{{.*}}) <{isVolatile = false, len = 10 : i64}> : (!llvm.ptr, !llvm.ptr) -> ()
|
||||
call void @llvm.memcpy.inline.p0.p0.i64(ptr %1, ptr %2, i64 10, i1 false)
|
||||
; CHECK: "llvm.intr.memcpy.inline"(%{{.*}}, %{{.*}}) <{isVolatile = false, len = 10 : i32}> : (!llvm.ptr, !llvm.ptr) -> ()
|
||||
call void @llvm.memcpy.inline.p0.p0.i32(ptr %1, ptr %2, i32 10, i1 false)
|
||||
ret void
|
||||
@ -581,17 +581,17 @@ define void @memcpy_test(i32 %0, ptr %1, ptr %2) {
|
||||
|
||||
; CHECK-LABEL: llvm.func @memmove_test
|
||||
define void @memmove_test(i32 %0, ptr %1, ptr %2) {
|
||||
; CHECK: "llvm.intr.memmove"(%{{.*}}, %{{.*}}, %{{.*}}) <{arg_attrs = [{llvm.align = 16 : i64}, {}, {}], isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
|
||||
call void @llvm.memmove.p0.p0.i32(ptr align 16 %1, ptr %2, i32 %0, i1 false)
|
||||
; CHECK: "llvm.intr.memmove"(%{{.*}}, %{{.*}}, %{{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
|
||||
call void @llvm.memmove.p0.p0.i32(ptr %1, ptr %2, i32 %0, i1 false)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: llvm.func @memset_test
|
||||
define void @memset_test(i32 %0, ptr %1, i8 %2) {
|
||||
; CHECK: "llvm.intr.memset"(%{{.*}}, %{{.*}}, %{{.*}}) <{arg_attrs = [{llvm.align = 2 : i64}, {}, {}], isVolatile = false}> : (!llvm.ptr, i8, i32) -> ()
|
||||
call void @llvm.memset.p0.i32(ptr align 2 %1, i8 %2, i32 %0, i1 false)
|
||||
; CHECK: "llvm.intr.memset.inline"(%{{.*}}, %{{.*}}) <{arg_attrs = [{llvm.align = 4 : i64}, {}], isVolatile = false, len = 10 : i64}> : (!llvm.ptr, i8) -> ()
|
||||
call void @llvm.memset.inline.p0.i64(ptr align 4 %1, i8 %2, i64 10, i1 false)
|
||||
; CHECK: "llvm.intr.memset"(%{{.*}}, %{{.*}}, %{{.*}}) <{isVolatile = false}> : (!llvm.ptr, i8, i32) -> ()
|
||||
call void @llvm.memset.p0.i32(ptr %1, i8 %2, i32 %0, i1 false)
|
||||
; CHECK: "llvm.intr.memset.inline"(%{{.*}}, %{{.*}}) <{isVolatile = false, len = 10 : i64}> : (!llvm.ptr, i8) -> ()
|
||||
call void @llvm.memset.inline.p0.i64(ptr %1, i8 %2, i64 10, i1 false)
|
||||
; CHECK: "llvm.intr.memset.inline"(%{{.*}}, %{{.*}}) <{isVolatile = false, len = 10 : i32}> : (!llvm.ptr, i8) -> ()
|
||||
call void @llvm.memset.inline.p0.i32(ptr %1, i8 %2, i32 10, i1 false)
|
||||
ret void
|
||||
|
@ -601,33 +601,29 @@ llvm.func @trap_intrinsics() {
|
||||
|
||||
// CHECK-LABEL: @memcpy_test
|
||||
llvm.func @memcpy_test(%arg0: i32, %arg2: !llvm.ptr, %arg3: !llvm.ptr) {
|
||||
// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %{{.*}}, ptr align 8 %{{.*}}, i32 %{{.*}}, i1 false
|
||||
"llvm.intr.memcpy"(%arg2, %arg3, %arg0) <{arg_attrs = [{llvm.align = 4 : i64}, {llvm.align = 8 : i64}, {}], isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
|
||||
// CHECK: call void @llvm.memcpy.inline.p0.p0.i32(ptr align 4 %{{.*}}, ptr %{{.*}}, i32 10, i1 true
|
||||
"llvm.intr.memcpy.inline"(%arg2, %arg3) <{arg_attrs = [{llvm.align = 4 : i64}, {}], isVolatile = true, len = 10 : i32}> : (!llvm.ptr, !llvm.ptr) -> ()
|
||||
// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr %{{.*}}, ptr %{{.*}}, i32 %{{.*}}, i1 false
|
||||
"llvm.intr.memcpy"(%arg2, %arg3, %arg0) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
|
||||
// CHECK: call void @llvm.memcpy.inline.p0.p0.i32(ptr %{{.*}}, ptr %{{.*}}, i32 10, i1 true
|
||||
"llvm.intr.memcpy.inline"(%arg2, %arg3) <{isVolatile = true, len = 10 : i32}> : (!llvm.ptr, !llvm.ptr) -> ()
|
||||
// CHECK: call void @llvm.memcpy.inline.p0.p0.i64(ptr %{{.*}}, ptr %{{.*}}, i64 10, i1 true
|
||||
"llvm.intr.memcpy.inline"(%arg2, %arg3) <{isVolatile = true, len = 10 : i64}> : (!llvm.ptr, !llvm.ptr) -> ()
|
||||
|
||||
// Verify that trailing empty argument attribute dictionaries can be omitted.
|
||||
// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %{{.*}}, ptr align 8 %{{.*}}, i32 %{{.*}}, i1 false
|
||||
"llvm.intr.memcpy"(%arg2, %arg3, %arg0) <{arg_attrs = [{llvm.align = 4 : i64}, {llvm.align = 8 : i64}], isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
|
||||
llvm.return
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @memmove_test
|
||||
llvm.func @memmove_test(%arg0: i32, %arg2: !llvm.ptr, %arg3: !llvm.ptr) {
|
||||
// CHECK: call void @llvm.memmove.p0.p0.i32(ptr align 4 %{{.*}}, ptr align 8 %{{.*}}, i32 %{{.*}}, i1 false
|
||||
"llvm.intr.memmove"(%arg2, %arg3, %arg0) <{arg_attrs = [{llvm.align = 4 : i64}, {llvm.align = 8 : i64}, {}], isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
|
||||
// CHECK: call void @llvm.memmove.p0.p0.i32(ptr %{{.*}}, ptr %{{.*}}, i32 %{{.*}}, i1 false
|
||||
"llvm.intr.memmove"(%arg2, %arg3, %arg0) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
|
||||
llvm.return
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @memset_test
|
||||
llvm.func @memset_test(%arg0: i32, %arg2: !llvm.ptr, %arg3: i8) {
|
||||
%i1 = llvm.mlir.constant(false) : i1
|
||||
// CHECK: call void @llvm.memset.p0.i32(ptr align 8 %{{.*}}, i8 %{{.*}}, i32 %{{.*}}, i1 false
|
||||
"llvm.intr.memset"(%arg2, %arg3, %arg0) <{arg_attrs = [{llvm.align = 8 : i64}, {}, {}], isVolatile = false}> : (!llvm.ptr, i8, i32) -> ()
|
||||
// CHECK: call void @llvm.memset.inline.p0.i32(ptr align 8 %{{.*}}, i8 %{{.*}}, i32 10, i1 true
|
||||
"llvm.intr.memset.inline"(%arg2, %arg3) <{arg_attrs = [{llvm.align = 8 : i64}, {}], isVolatile = true, len = 10 : i32}> : (!llvm.ptr, i8) -> ()
|
||||
// CHECK: call void @llvm.memset.p0.i32(ptr %{{.*}}, i8 %{{.*}}, i32 %{{.*}}, i1 false
|
||||
"llvm.intr.memset"(%arg2, %arg3, %arg0) <{isVolatile = false}> : (!llvm.ptr, i8, i32) -> ()
|
||||
// CHECK: call void @llvm.memset.inline.p0.i32(ptr %{{.*}}, i8 %{{.*}}, i32 10, i1 true
|
||||
"llvm.intr.memset.inline"(%arg2, %arg3) <{isVolatile = true, len = 10 : i32}> : (!llvm.ptr, i8) -> ()
|
||||
// CHECK: call void @llvm.memset.inline.p0.i64(ptr %{{.*}}, i8 %{{.*}}, i64 10, i1 true
|
||||
"llvm.intr.memset.inline"(%arg2, %arg3) <{isVolatile = true, len = 10 : i64}> : (!llvm.ptr, i8) -> ()
|
||||
llvm.return
|
||||
|
@ -32,7 +32,6 @@ package(default_visibility = ["//visibility:public"])
|
||||
"//mlir:include/mlir/IR/BuiltinDialectBytecode.td",
|
||||
"//mlir:include/mlir/IR/BytecodeBase.td",
|
||||
"//mlir:include/mlir/IR/OpBase.td",
|
||||
"//mlir:include/mlir/Interfaces/CallInterfaces.td",
|
||||
"//mlir:include/mlir/Interfaces/InferTypeOpInterface.td",
|
||||
"//mlir:include/mlir/Interfaces/SideEffectInterfaces.td",
|
||||
"//mlir:include/mlir/Pass/PassBase.td",
|
||||
|
Loading…
x
Reference in New Issue
Block a user