From a08d7a7d167128568c42ff4c618ee61b49f47dbd Mon Sep 17 00:00:00 2001 From: xlauko Date: Sat, 2 Nov 2024 20:59:33 +0100 Subject: [PATCH] [mlir][linkage] Add linkage kind EnumAttr --- .../mlir/Dialect/Linkage/IR/CMakeLists.txt | 6 ++ .../include/mlir/Dialect/Linkage/IR/Linkage.h | 93 +++++++++++++++++++ .../mlir/Dialect/Linkage/IR/Linkage.td | 54 +++++++++++ mlir/lib/Dialect/Linkage/IR/CMakeLists.txt | 4 + mlir/lib/Dialect/Linkage/IR/Linkage.cpp | 7 ++ 5 files changed, 164 insertions(+) diff --git a/mlir/include/mlir/Dialect/Linkage/IR/CMakeLists.txt b/mlir/include/mlir/Dialect/Linkage/IR/CMakeLists.txt index 2e20f9cfa685fb2..9d81aa0f484a50d 100644 --- a/mlir/include/mlir/Dialect/Linkage/IR/CMakeLists.txt +++ b/mlir/include/mlir/Dialect/Linkage/IR/CMakeLists.txt @@ -1,2 +1,8 @@ add_mlir_dialect(Linkage linkage) add_mlir_doc(Linkage Linkage Dialects/ -gen-dialect-doc -dialect=linkage) + +# Generate extra headers for custom enum and attrs. +set(LLVM_TARGET_DEFINITIONS Linkage.td) +mlir_tablegen(LinkageEnums.h.inc -gen-enum-decls) +mlir_tablegen(LinkageEnums.cpp.inc -gen-enum-defs) +add_public_tablegen_target(MLIRLinkageEnumsGen) diff --git a/mlir/include/mlir/Dialect/Linkage/IR/Linkage.h b/mlir/include/mlir/Dialect/Linkage/IR/Linkage.h index eb0546d620e8cbd..71ab7de3f8d8ace 100644 --- a/mlir/include/mlir/Dialect/Linkage/IR/Linkage.h +++ b/mlir/include/mlir/Dialect/Linkage/IR/Linkage.h @@ -12,5 +12,98 @@ #include "mlir/IR/Dialect.h" #include "mlir/Dialect/Linkage/IR/Linkage.h.inc" +#include "mlir/Dialect/Linkage/IR/LinkageEnums.h.inc" + +namespace mlir::linkage { + +inline constexpr bool isExternalLinkage(LinkageKind linkage) { + return linkage == LinkageKind::ExternalLinkage; +} +inline constexpr bool isAvailableExternallyLinkage(LinkageKind linkage) { + return linkage == LinkageKind::AvailableExternallyLinkage; +} +inline constexpr bool isLinkOnceAnyLinkage(LinkageKind linkage) { + return linkage == LinkageKind::LinkOnceAnyLinkage; +} +inline constexpr bool isLinkOnceODRLinkage(LinkageKind linkage) { + return linkage == LinkageKind::LinkOnceODRLinkage; +} +inline constexpr bool isLinkOnceLinkage(LinkageKind linkage) { + return isLinkOnceAnyLinkage(linkage) || isLinkOnceODRLinkage(linkage); +} +inline constexpr bool isWeakAnyLinkage(LinkageKind linkage) { + return linkage == LinkageKind::WeakAnyLinkage; +} +inline constexpr bool isWeakODRLinkage(LinkageKind linkage) { + return linkage == LinkageKind::WeakODRLinkage; +} +inline constexpr bool isWeakLinkage(LinkageKind linkage) { + return isWeakAnyLinkage(linkage) || isWeakODRLinkage(linkage); +} +inline constexpr bool isInternalLinkage(LinkageKind linkage) { + return linkage == LinkageKind::InternalLinkage; +} +inline constexpr bool isPrivateLinkage(LinkageKind linkage) { + return linkage == LinkageKind::PrivateLinkage; +} +inline constexpr bool isLocalLinkage(LinkageKind linkage) { + return isInternalLinkage(linkage) || isPrivateLinkage(linkage); +} +inline constexpr bool isExternalWeakLinkage(LinkageKind linkage) { + return linkage == LinkageKind::ExternalWeakLinkage; +} +inline constexpr bool isCommonLinkage(LinkageKind linkage) { + return linkage == LinkageKind::CommonLinkage; +} +inline constexpr bool isValidDeclarationLinkage(LinkageKind linkage) { + return isExternalWeakLinkage(linkage) || isExternalLinkage(linkage); +} + +/// Whether the definition of this global may be replaced by something +/// non-equivalent at link time. For example, if a function has weak linkage +/// then the code defining it may be replaced by different code. +inline constexpr bool isInterposableLinkage(LinkageKind linkage) { + switch (linkage) { + case LinkageKind::WeakAnyLinkage: + case LinkageKind::LinkOnceAnyLinkage: + case LinkageKind::CommonLinkage: + case LinkageKind::ExternalWeakLinkage: + return true; + + case LinkageKind::AvailableExternallyLinkage: + case LinkageKind::LinkOnceODRLinkage: + case LinkageKind::WeakODRLinkage: + // The above three cannot be overridden but can be de-refined. + + case LinkageKind::ExternalLinkage: + case LinkageKind::AppendingLinkage: + case LinkageKind::InternalLinkage: + case LinkageKind::PrivateLinkage: + return false; + } + llvm_unreachable("Fully covered switch above!"); +} + +/// Whether the definition of this global may be discarded if it is not used +/// in its compilation unit. +inline constexpr bool isDiscardableIfUnused(LinkageKind linkage) { + return isLinkOnceLinkage(linkage) || isLocalLinkage(linkage) || + isAvailableExternallyLinkage(linkage); +} + +/// Whether the definition of this global may be replaced at link time. NB: +/// Using this method outside of the code generators is almost always a +/// mistake: when working at the IR level use isInterposable instead as it +/// knows about ODR semantics. +inline constexpr bool isWeakForLinker(LinkageKind linkage) { + return linkage == LinkageKind::WeakAnyLinkage || + linkage == LinkageKind::WeakODRLinkage || + linkage == LinkageKind::LinkOnceAnyLinkage || + linkage == LinkageKind::LinkOnceODRLinkage || + linkage == LinkageKind::CommonLinkage || + linkage == LinkageKind::ExternalWeakLinkage; +} + +} // namespace mlir::linkage #endif // MLIR_DIALECT_LINKAGE_IR_LINKAGE_H diff --git a/mlir/include/mlir/Dialect/Linkage/IR/Linkage.td b/mlir/include/mlir/Dialect/Linkage/IR/Linkage.td index 2af4425b09d4f5d..ac462c5b60b8fba 100644 --- a/mlir/include/mlir/Dialect/Linkage/IR/Linkage.td +++ b/mlir/include/mlir/Dialect/Linkage/IR/Linkage.td @@ -10,6 +10,7 @@ #define LINKAGE include "mlir/IR/OpBase.td" +include "mlir/IR/EnumAttr.td" //===----------------------------------------------------------------------===// // Linkage dialect definition. @@ -28,4 +29,57 @@ def Linkage_Dialect : Dialect { let useDefaultAttributePrinterParser = 1; } + +// Linkage types: mirrors linkage types from llvm/IR/GlobalValue.h. +// Used for forwarding linkage types during LLVM lowering and for MLIR linker. + +// Externally visible function +def Linkage_ExternalLinkage : + I32EnumAttrCase<"ExternalLinkage", 0, "external">; +// Available for inspection, not emission. +def Linkage_AvailableExternallyLinkage : + I32EnumAttrCase<"AvailableExternallyLinkage", 1, "available_externally">; +// Keep one copy of function when linking (inline) +def Linkage_LinkOnceAnyLinkage : + I32EnumAttrCase<"LinkOnceAnyLinkage", 2, "linkonce">; +// Same, but only replaced by something equivalent. +def Linkage_LinkOnceODRLinkage : + I32EnumAttrCase<"LinkOnceODRLinkage", 3, "linkonce_odr">; +// Keep one copy of named function when linking (weak) +def Linkage_WeakAnyLinkage : + I32EnumAttrCase<"WeakAnyLinkage", 4, "weak">; +// Same, but only replaced by something equivalent. +def Linkage_WeakODRLinkage : + I32EnumAttrCase<"WeakODRLinkage", 5, "weak_odr">; +// Special purpose, only applies to global arrays +def Linkage_AppendingLinkage : + I32EnumAttrCase<"AppendingLinkage", 6, "appending">; +// Rename collisions when linking (static functions). +def Linkage_InternalLinkage : + I32EnumAttrCase<"InternalLinkage", 7, "internal">; +// Like Internal, but omit from symbol table, prefix it with +// "linkage_" to prevent clash with MLIR's symbol "private". +def Linkage_PrivateLinkage : + I32EnumAttrCase<"PrivateLinkage", 8, "linkage_private">; +// ExternalWeak linkage description. +def Linkage_ExternalWeakLinkage : + I32EnumAttrCase<"ExternalWeakLinkage", 9, "extern_weak">; +// Tentative definitions. +def Linkage_CommonLinkage : + I32EnumAttrCase<"CommonLinkage", 10, "common">; + +/// An enumeration for the kinds of linkage for global values. +def Linkage_LinkageKind : I32EnumAttr< + "LinkageKind", + "Linkage type/kind", + [Linkage_ExternalLinkage, Linkage_AvailableExternallyLinkage, + Linkage_LinkOnceAnyLinkage, Linkage_LinkOnceODRLinkage, + Linkage_WeakAnyLinkage, Linkage_WeakODRLinkage, + Linkage_AppendingLinkage, + Linkage_InternalLinkage, Linkage_PrivateLinkage, + Linkage_ExternalWeakLinkage, Linkage_CommonLinkage + ]> { + let cppNamespace = "::mlir::linkage"; +} + #endif // LINKAGE diff --git a/mlir/lib/Dialect/Linkage/IR/CMakeLists.txt b/mlir/lib/Dialect/Linkage/IR/CMakeLists.txt index 1e1fe84d0f5f2c5..6885c654b4ab02e 100644 --- a/mlir/lib/Dialect/Linkage/IR/CMakeLists.txt +++ b/mlir/lib/Dialect/Linkage/IR/CMakeLists.txt @@ -1,6 +1,10 @@ add_mlir_dialect_library(MLIRLinkageDialect Linkage.cpp + DEPENDS + MLIRLinkageEnumsGen + MLIRLinkageIncGen + LINK_LIBS PUBLIC MLIRDialect MLIRIR diff --git a/mlir/lib/Dialect/Linkage/IR/Linkage.cpp b/mlir/lib/Dialect/Linkage/IR/Linkage.cpp index fd442e26e2d52b4..9658c4754bed709 100644 --- a/mlir/lib/Dialect/Linkage/IR/Linkage.cpp +++ b/mlir/lib/Dialect/Linkage/IR/Linkage.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "mlir/Dialect/Linkage/IR/Linkage.h" +#include "mlir/IR/BuiltinTypes.h" using namespace mlir; @@ -15,3 +16,9 @@ using namespace mlir; //===----------------------------------------------------------------------===// #include "mlir/Dialect/Linkage/IR/Linkage.cpp.inc" + +//===----------------------------------------------------------------------===// +// Linkage Enums +//===----------------------------------------------------------------------===// + +#include "mlir/Dialect/Linkage/IR/LinkageEnums.cpp.inc"