diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -9,9 +9,8 @@ #ifndef LLVMIR_ATTRDEFS #define LLVMIR_ATTRDEFS +include "mlir/Dialect/LLVMIR/LLVMDialect.td" include "mlir/IR/AttrTypeBase.td" -include "mlir/Dialect/LLVMIR/LLVMEnums.td" -include "mlir/Dialect/LLVMIR/LLVMOpBase.td" // All of the attributes will extend this class. class LLVM_Attr { - let assemblyFormat = "`<` $value `>`"; -} - //===----------------------------------------------------------------------===// // LinkageAttr //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td new file mode 100644 --- /dev/null +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td @@ -0,0 +1,100 @@ +//===-- LLVMDialect.td - LLVM IR dialect definition --------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVMIR_DIALECT +#define LLVMIR_DIALECT + +include "mlir/IR/DialectBase.td" + +def LLVM_Dialect : Dialect { + let name = "llvm"; + let cppNamespace = "::mlir::LLVM"; + + let useDefaultAttributePrinterParser = 1; + let hasRegionArgAttrVerify = 1; + let hasRegionResultAttrVerify = 1; + let hasOperationAttrVerify = 1; + + let extraClassDeclaration = [{ + /// Name of the data layout attributes. + static StringRef getDataLayoutAttrName() { return "llvm.data_layout"; } + static StringRef getNoAliasScopesAttrName() { return "noalias_scopes"; } + static StringRef getAliasScopesAttrName() { return "alias_scopes"; } + static StringRef getAccessGroupsAttrName() { return "access_groups"; } + + /// Names of llvm parameter attributes. + static StringRef getAlignAttrName() { return "llvm.align"; } + static StringRef getAllocAlignAttrName() { return "llvm.allocalign"; } + static StringRef getAllocatedPointerAttrName() { return "llvm.allocptr"; } + static StringRef getByValAttrName() { return "llvm.byval"; } + static StringRef getByRefAttrName() { return "llvm.byref"; } + static StringRef getNoUndefAttrName() { return "llvm.noundef"; } + static StringRef getDereferenceableAttrName() { return "llvm.dereferenceable"; } + static StringRef getDereferenceableOrNullAttrName() { return "llvm.dereferenceable_or_null"; } + static StringRef getInAllocaAttrName() { return "llvm.inalloca"; } + static StringRef getInRegAttrName() { return "llvm.inreg"; } + static StringRef getNestAttrName() { return "llvm.nest"; } + static StringRef getNoAliasAttrName() { return "llvm.noalias"; } + static StringRef getNoCaptureAttrName() { return "llvm.nocapture"; } + static StringRef getNoFreeAttrName() { return "llvm.nofree"; } + static StringRef getNonNullAttrName() { return "llvm.nonnull"; } + static StringRef getPreallocatedAttrName() { return "llvm.preallocated"; } + static StringRef getReadonlyAttrName() { return "llvm.readonly"; } + static StringRef getReturnedAttrName() { return "llvm.returned"; } + static StringRef getSExtAttrName() { return "llvm.signext"; } + static StringRef getStackAlignmentAttrName() { return "llvm.alignstack"; } + static StringRef getStructRetAttrName() { return "llvm.sret"; } + static StringRef getWriteOnlyAttrName() { return "llvm.writeonly"; } + static StringRef getZExtAttrName() { return "llvm.zeroext"; } + // TODO Restrict the usage of this to parameter attributes once there is an + // alternative way of modeling memory effects on FunctionOpInterface. + /// Name of the attribute that will cause the creation of a readnone memory + /// effect when lowering to the LLVMDialect. + static StringRef getReadnoneAttrName() { return "llvm.readnone"; } + + /// Verifies if the given string is a well-formed data layout descriptor. + /// Uses `reportError` to report errors. + static LogicalResult verifyDataLayoutString( + StringRef descr, llvm::function_ref reportError); + + /// Name of the target triple attribute. + static StringRef getTargetTripleAttrName() { return "llvm.target_triple"; } + + /// Name of the C wrapper emission attribute. + static StringRef getEmitCWrapperAttrName() { + return "llvm.emit_c_interface"; + } + + /// Returns `true` if the given type is compatible with the LLVM dialect. + static bool isCompatibleType(Type); + + + Type parseType(DialectAsmParser &p) const override; + void printType(Type, DialectAsmPrinter &p) const override; + + private: + /// Verifies a parameter attribute attached to a parameter of type + /// paramType. + LogicalResult verifyParameterAttribute(Operation *op, + Type paramType, + NamedAttribute paramAttr); + + /// Register all types. + void registerTypes(); + + /// A cache storing compatible LLVM types that have been verified. This + /// can save us lots of verification time if there are many occurrences + /// of some deeply-nested aggregate types in the program. + ThreadLocalCache> compatibleTypes; + + /// Register the attributes of this dialect. + void registerAttributes(); + }]; +} + +#endif // LLVMIR_DIALECT diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td @@ -6,10 +6,64 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVMIR_ENUMS_TD -#define LLVMIR_ENUMS_TD +#ifndef LLVMIR_ENUMS +#define LLVMIR_ENUMS -include "mlir/Dialect/LLVMIR/LLVMOpBase.td" +include "mlir/Dialect/LLVMIR/LLVMDialect.td" +include "mlir/IR/EnumAttr.td" + +//===----------------------------------------------------------------------===// +// Base classes for LLVM enum attributes. +//===----------------------------------------------------------------------===// + +// Case of the LLVM enum attribute backed by I64Attr with customized string +// representation that corresponds to what is visible in the textual IR form. +// The parameters are as follows: +// - `cppSym`: name of the C++ enumerant for this case in MLIR API; +// - `irSym`: keyword used in the custom form of MLIR operation; +// - `llvmSym`: name of the C++ enumerant for this case in LLVM API. +// For example, `LLVM_EnumAttrCase<"Weak", "weak", "WeakAnyLinkage">` is usable +// as `::Weak` in MLIR API, `WeakAnyLinkage` in LLVM API and +// is printed/parsed as `weak` in MLIR custom textual format. +class LLVM_EnumAttrCase : + I64EnumAttrCase { + // The name of the equivalent enumerant in LLVM. + string llvmEnumerant = llvmSym; +} + +// LLVM enum attribute backed by I64Attr with string representation +// corresponding to what is visible in the textual IR form. +// The parameters are as follows: +// - `name`: name of the C++ enum class in MLIR API; +// - `llvmName`: name of the C++ enum in LLVM API; +// - `description`: textual description for documentation purposes; +// - `cases`: list of enum cases; +// - `unsupportedCases`: optional list of unsupported enum cases. +// For example, `LLVM_EnumAttr cases, + list unsupportedCases = []> : + I64EnumAttr { + // List of unsupported cases that have no conversion to an MLIR value. + list unsupported = unsupportedCases; + + // The equivalent enum class name in LLVM. + string llvmClassName = llvmName; +} + +// LLVM_CEnumAttr is functionally identical to LLVM_EnumAttr, but to be used for +// non-class enums. +class LLVM_CEnumAttr cases> : + I64EnumAttr { + string llvmClassName = llvmNS; +} //===----------------------------------------------------------------------===// // AsmDialect @@ -402,6 +456,11 @@ let printBitEnumPrimaryGroups = 1; } +def LLVM_FastmathFlagsAttr : + EnumAttr { + let assemblyFormat = "`<` $value `>`"; +} + //===----------------------------------------------------------------------===// // FCmp and ICmp Predicates //===----------------------------------------------------------------------===// @@ -582,4 +641,4 @@ let cppNamespace = "::mlir::LLVM"; } -#endif // LLVMIR_ENUMS_TD +#endif // LLVMIR_ENUMS diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td @@ -3,6 +3,7 @@ include "mlir/IR/OpBase.td" include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td" +include "mlir/Dialect/LLVMIR/LLVMEnums.td" include "mlir/Dialect/LLVMIR/LLVMOpBase.td" include "mlir/Interfaces/InferTypeOpInterface.td" diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td @@ -14,101 +14,11 @@ #ifndef LLVMIR_OP_BASE #define LLVMIR_OP_BASE +include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td" include "mlir/Dialect/LLVMIR/LLVMInterfaces.td" -include "mlir/IR/EnumAttr.td" include "mlir/IR/OpBase.td" include "mlir/Interfaces/SideEffectInterfaces.td" -//===----------------------------------------------------------------------===// -// LLVM Dialect. -//===----------------------------------------------------------------------===// - -def LLVM_Dialect : Dialect { - let name = "llvm"; - let cppNamespace = "::mlir::LLVM"; - - let useDefaultAttributePrinterParser = 1; - let hasRegionArgAttrVerify = 1; - let hasRegionResultAttrVerify = 1; - let hasOperationAttrVerify = 1; - - let extraClassDeclaration = [{ - /// Name of the data layout attributes. - static StringRef getDataLayoutAttrName() { return "llvm.data_layout"; } - static StringRef getNoAliasScopesAttrName() { return "noalias_scopes"; } - static StringRef getAliasScopesAttrName() { return "alias_scopes"; } - static StringRef getAccessGroupsAttrName() { return "access_groups"; } - - /// Names of llvm parameter attributes. - static StringRef getAlignAttrName() { return "llvm.align"; } - static StringRef getAllocAlignAttrName() { return "llvm.allocalign"; } - static StringRef getAllocatedPointerAttrName() { return "llvm.allocptr"; } - static StringRef getByValAttrName() { return "llvm.byval"; } - static StringRef getByRefAttrName() { return "llvm.byref"; } - static StringRef getNoUndefAttrName() { return "llvm.noundef"; } - static StringRef getDereferenceableAttrName() { return "llvm.dereferenceable"; } - static StringRef getDereferenceableOrNullAttrName() { return "llvm.dereferenceable_or_null"; } - static StringRef getInAllocaAttrName() { return "llvm.inalloca"; } - static StringRef getInRegAttrName() { return "llvm.inreg"; } - static StringRef getNestAttrName() { return "llvm.nest"; } - static StringRef getNoAliasAttrName() { return "llvm.noalias"; } - static StringRef getNoCaptureAttrName() { return "llvm.nocapture"; } - static StringRef getNoFreeAttrName() { return "llvm.nofree"; } - static StringRef getNonNullAttrName() { return "llvm.nonnull"; } - static StringRef getPreallocatedAttrName() { return "llvm.preallocated"; } - static StringRef getReadonlyAttrName() { return "llvm.readonly"; } - static StringRef getReturnedAttrName() { return "llvm.returned"; } - static StringRef getSExtAttrName() { return "llvm.signext"; } - static StringRef getStackAlignmentAttrName() { return "llvm.alignstack"; } - static StringRef getStructRetAttrName() { return "llvm.sret"; } - static StringRef getWriteOnlyAttrName() { return "llvm.writeonly"; } - static StringRef getZExtAttrName() { return "llvm.zeroext"; } - // TODO Restrict the usage of this to parameter attributes once there is an - // alternative way of modeling memory effects on FunctionOpInterface. - /// Name of the attribute that will cause the creation of a readnone memory - /// effect when lowering to the LLVMDialect. - static StringRef getReadnoneAttrName() { return "llvm.readnone"; } - - /// Verifies if the given string is a well-formed data layout descriptor. - /// Uses `reportError` to report errors. - static LogicalResult verifyDataLayoutString( - StringRef descr, llvm::function_ref reportError); - - /// Name of the target triple attribute. - static StringRef getTargetTripleAttrName() { return "llvm.target_triple"; } - - /// Name of the C wrapper emission attribute. - static StringRef getEmitCWrapperAttrName() { - return "llvm.emit_c_interface"; - } - - /// Returns `true` if the given type is compatible with the LLVM dialect. - static bool isCompatibleType(Type); - - - Type parseType(DialectAsmParser &p) const override; - void printType(Type, DialectAsmPrinter &p) const override; - - private: - /// Verifies a parameter attribute attached to a parameter of type - /// paramType. - LogicalResult verifyParameterAttribute(Operation *op, - Type paramType, - NamedAttribute paramAttr); - - /// Register all types. - void registerTypes(); - - /// A cache storing compatible LLVM types that have been verified. This - /// can save us lots of verification time if there are many occurrences - /// of some deeply-nested aggregate types in the program. - ThreadLocalCache> compatibleTypes; - - /// Register the attributes of this dialect. - void registerAttributes(); - }]; -} - //===----------------------------------------------------------------------===// // LLVM dialect type constraints. //===----------------------------------------------------------------------===// @@ -268,59 +178,6 @@ list llvmArgIndices = []; } -//===----------------------------------------------------------------------===// -// Base classes for LLVM enum attributes. -//===----------------------------------------------------------------------===// - -// Case of the LLVM enum attribute backed by I64Attr with customized string -// representation that corresponds to what is visible in the textual IR form. -// The parameters are as follows: -// - `cppSym`: name of the C++ enumerant for this case in MLIR API; -// - `irSym`: keyword used in the custom form of MLIR operation; -// - `llvmSym`: name of the C++ enumerant for this case in LLVM API. -// For example, `LLVM_EnumAttrCase<"Weak", "weak", "WeakAnyLinkage">` is usable -// as `::Weak` in MLIR API, `WeakAnyLinkage` in LLVM API and -// is printed/parsed as `weak` in MLIR custom textual format. -class LLVM_EnumAttrCase : - I64EnumAttrCase { - // The name of the equivalent enumerant in LLVM. - string llvmEnumerant = llvmSym; -} - -// LLVM enum attribute backed by I64Attr with string representation -// corresponding to what is visible in the textual IR form. -// The parameters are as follows: -// - `name`: name of the C++ enum class in MLIR API; -// - `llvmName`: name of the C++ enum in LLVM API; -// - `description`: textual description for documentation purposes; -// - `cases`: list of enum cases; -// - `unsupportedCases`: optional list of unsupported enum cases. -// For example, `LLVM_EnumAttr cases, - list unsupportedCases = []> : - I64EnumAttr { - // List of unsupported cases that have no conversion to an MLIR value. - list unsupported = unsupportedCases; - - // The equivalent enum class name in LLVM. - string llvmClassName = llvmName; -} - -// LLVM_CEnumAttr is functionally identical to LLVM_EnumAttr, but to be used for -// non-class enums. -class LLVM_CEnumAttr cases> : - I64EnumAttr { - string llvmClassName = llvmNS; -} - //===----------------------------------------------------------------------===// // Patterns for LLVM dialect operations. //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -14,6 +14,7 @@ #define LLVMIR_OPS include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td" +include "mlir/Dialect/LLVMIR/LLVMEnums.td" include "mlir/Dialect/LLVMIR/LLVMOpBase.td" include "mlir/IR/EnumAttr.td" include "mlir/IR/FunctionInterfaces.td"