Skip to content

Commit

Permalink
[mlir][linkage] Add linkage kind EnumAttr
Browse files Browse the repository at this point in the history
  • Loading branch information
xlauko authored and frabert committed Jan 22, 2025
1 parent 06d5719 commit a08d7a7
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 0 deletions.
6 changes: 6 additions & 0 deletions mlir/include/mlir/Dialect/Linkage/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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)
93 changes: 93 additions & 0 deletions mlir/include/mlir/Dialect/Linkage/IR/Linkage.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
54 changes: 54 additions & 0 deletions mlir/include/mlir/Dialect/Linkage/IR/Linkage.td
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define LINKAGE

include "mlir/IR/OpBase.td"
include "mlir/IR/EnumAttr.td"

//===----------------------------------------------------------------------===//
// Linkage dialect definition.
Expand All @@ -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
4 changes: 4 additions & 0 deletions mlir/lib/Dialect/Linkage/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
add_mlir_dialect_library(MLIRLinkageDialect
Linkage.cpp

DEPENDS
MLIRLinkageEnumsGen
MLIRLinkageIncGen

LINK_LIBS PUBLIC
MLIRDialect
MLIRIR
Expand Down
7 changes: 7 additions & 0 deletions mlir/lib/Dialect/Linkage/IR/Linkage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/Linkage/IR/Linkage.h"
#include "mlir/IR/BuiltinTypes.h"

using namespace mlir;

Expand All @@ -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"

0 comments on commit a08d7a7

Please sign in to comment.