[llvm] [NFC][TableGen] Refactor `getIntrinsicFnAttributeSet` (PR #106587)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 29 12:51:58 PDT 2024
https://github.com/jurahul updated https://github.com/llvm/llvm-project/pull/106587
>From b75527a74368237acd728ff77c636b1deee97079 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Thu, 29 Aug 2024 10:13:13 -0700
Subject: [PATCH] [NFC][TableGen] Refactor `getIntrinsicFnAttributeSet`
Fix intrinsic function attributes to not generate attribute sets that are
empty in `getIntrinsicFnAttributeSet`. Refactor the code to use helper
lambdas to get effective memory effects for an intrinsic and to check if
it has non-default attributes.
This emiminates one case statement in `getIntrinsicFnAttributeSet` that
we generate today for the case when intrinsic attributes are default ones.
Also rename `Intrinsic` to `Int` to follow the naming convention used in
this file, and adjust emission code to not emit unnecessary empty line
between cases generated.
---
llvm/utils/TableGen/IntrinsicEmitter.cpp | 134 +++++++++++++----------
1 file changed, 76 insertions(+), 58 deletions(-)
diff --git a/llvm/utils/TableGen/IntrinsicEmitter.cpp b/llvm/utils/TableGen/IntrinsicEmitter.cpp
index 06b430ae011405..a0cbc0d3f6cfc7 100644
--- a/llvm/utils/TableGen/IntrinsicEmitter.cpp
+++ b/llvm/utils/TableGen/IntrinsicEmitter.cpp
@@ -379,10 +379,10 @@ static bool compareFnAttributes(const CodeGenIntrinsic *L,
return TieL < TieR;
// Try to order by readonly/readnone attribute.
- uint32_t LK = L->ME.toIntValue();
- uint32_t RK = R->ME.toIntValue();
- if (LK != RK)
- return LK > RK;
+ uint32_t LME = L->ME.toIntValue();
+ uint32_t RME = R->ME.toIntValue();
+ if (LME != RME)
+ return LME > RME;
return Default;
}
@@ -404,6 +404,53 @@ struct AttributeComparator {
};
} // End anonymous namespace
+/// Returns the effective MemoryEffects for intrinsic \p Int.
+static MemoryEffects getEffectiveME(const CodeGenIntrinsic &Int) {
+ MemoryEffects ME = Int.ME;
+ // TODO: IntrHasSideEffects should affect not only readnone intrinsics.
+ if (ME.doesNotAccessMemory() && Int.hasSideEffects)
+ ME = MemoryEffects::unknown();
+ return ME;
+}
+
+/// Returns true if \p Int has a non-empty set of function attributes. Note that
+/// NoUnwind = !canThrow, so we need to negate it's sense to test if the
+// intrinsic has NoUnwind attribute.
+static bool hasFnAttributes(const CodeGenIntrinsic &Int) {
+ return !Int.canThrow || Int.isNoReturn || Int.isNoCallback || Int.isNoSync ||
+ Int.isNoFree || Int.isWillReturn || Int.isCold || Int.isNoDuplicate ||
+ Int.isNoMerge || Int.isConvergent || Int.isSpeculatable ||
+ Int.isStrictFP || getEffectiveME(Int) != MemoryEffects::unknown();
+}
+
+/// Returns the name of the IR enum for argument attribute kind \p Kind.
+static StringRef getArgAttrEnumName(CodeGenIntrinsic::ArgAttrKind Kind) {
+ switch (Kind) {
+ case CodeGenIntrinsic::NoCapture:
+ return "NoCapture";
+ case CodeGenIntrinsic::NoAlias:
+ return "NoAlias";
+ case CodeGenIntrinsic::NoUndef:
+ return "NoUndef";
+ case CodeGenIntrinsic::NonNull:
+ return "NonNull";
+ case CodeGenIntrinsic::Returned:
+ return "Returned";
+ case CodeGenIntrinsic::ReadOnly:
+ return "ReadOnly";
+ case CodeGenIntrinsic::WriteOnly:
+ return "WriteOnly";
+ case CodeGenIntrinsic::ReadNone:
+ return "ReadNone";
+ case CodeGenIntrinsic::ImmArg:
+ return "ImmArg";
+ case CodeGenIntrinsic::Alignment:
+ return "Alignment";
+ case CodeGenIntrinsic::Dereferenceable:
+ return "Dereferenceable";
+ }
+}
+
/// EmitAttributes - This emits the Intrinsic::getAttributes method.
void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints,
raw_ostream &OS) {
@@ -425,33 +472,6 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
continue;
assert(is_sorted(Attrs) && "Argument attributes are not sorted");
- auto getAttrEnumName =
- [](CodeGenIntrinsic::ArgAttrKind Kind) -> StringRef {
- switch (Kind) {
- case CodeGenIntrinsic::NoCapture:
- return "NoCapture";
- case CodeGenIntrinsic::NoAlias:
- return "NoAlias";
- case CodeGenIntrinsic::NoUndef:
- return "NoUndef";
- case CodeGenIntrinsic::NonNull:
- return "NonNull";
- case CodeGenIntrinsic::Returned:
- return "Returned";
- case CodeGenIntrinsic::ReadOnly:
- return "ReadOnly";
- case CodeGenIntrinsic::WriteOnly:
- return "WriteOnly";
- case CodeGenIntrinsic::ReadNone:
- return "ReadNone";
- case CodeGenIntrinsic::ImmArg:
- return "ImmArg";
- case CodeGenIntrinsic::Alignment:
- return "Alignment";
- case CodeGenIntrinsic::Dereferenceable:
- return "Dereferenceable";
- }
- };
OS << formatv(R"(
case {0}:
@@ -459,7 +479,7 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
)",
ID);
for (const CodeGenIntrinsic::ArgAttribute &Attr : Attrs) {
- StringRef AttrName = getAttrEnumName(Attr.Kind);
+ StringRef AttrName = getArgAttrEnumName(Attr.Kind);
if (Attr.Kind == CodeGenIntrinsic::Alignment ||
Attr.Kind == CodeGenIntrinsic::Dereferenceable)
OS << formatv(" Attribute::get(C, Attribute::{0}, {1}),\n",
@@ -472,7 +492,8 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
}
OS << R"(
}
-} // getIntrinsicArgAttributeSet)";
+} // getIntrinsicArgAttributeSet
+)";
// Compute unique function attribute sets.
std::map<const CodeGenIntrinsic *, unsigned, FnAttributeComparator>
@@ -481,9 +502,12 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
switch (ID) {
default: llvm_unreachable("Invalid attribute set number");)";
- for (const CodeGenIntrinsic &Intrinsic : Ints) {
+
+ for (const CodeGenIntrinsic &Int : Ints) {
+ if (!hasFnAttributes(Int))
+ continue;
unsigned ID = UniqFnAttributes.size();
- if (!UniqFnAttributes.try_emplace(&Intrinsic, ID).second)
+ if (!UniqFnAttributes.try_emplace(&Int, ID).second)
continue;
OS << formatv(R"(
case {0}:
@@ -493,44 +517,42 @@ static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
auto addAttribute = [&OS](StringRef Attr) {
OS << formatv(" Attribute::get(C, Attribute::{0}),\n", Attr);
};
- if (!Intrinsic.canThrow)
+ if (!Int.canThrow)
addAttribute("NoUnwind");
- if (Intrinsic.isNoReturn)
+ if (Int.isNoReturn)
addAttribute("NoReturn");
- if (Intrinsic.isNoCallback)
+ if (Int.isNoCallback)
addAttribute("NoCallback");
- if (Intrinsic.isNoSync)
+ if (Int.isNoSync)
addAttribute("NoSync");
- if (Intrinsic.isNoFree)
+ if (Int.isNoFree)
addAttribute("NoFree");
- if (Intrinsic.isWillReturn)
+ if (Int.isWillReturn)
addAttribute("WillReturn");
- if (Intrinsic.isCold)
+ if (Int.isCold)
addAttribute("Cold");
- if (Intrinsic.isNoDuplicate)
+ if (Int.isNoDuplicate)
addAttribute("NoDuplicate");
- if (Intrinsic.isNoMerge)
+ if (Int.isNoMerge)
addAttribute("NoMerge");
- if (Intrinsic.isConvergent)
+ if (Int.isConvergent)
addAttribute("Convergent");
- if (Intrinsic.isSpeculatable)
+ if (Int.isSpeculatable)
addAttribute("Speculatable");
- if (Intrinsic.isStrictFP)
+ if (Int.isStrictFP)
addAttribute("StrictFP");
- MemoryEffects ME = Intrinsic.ME;
- // TODO: IntrHasSideEffects should affect not only readnone intrinsics.
- if (ME.doesNotAccessMemory() && Intrinsic.hasSideEffects)
- ME = MemoryEffects::unknown();
+ const MemoryEffects ME = getEffectiveME(Int);
if (ME != MemoryEffects::unknown()) {
OS << formatv(" // {0}\n", ME);
OS << formatv(" Attribute::getWithMemoryEffects(C, "
"MemoryEffects::createFromIntValue({0})),\n",
ME.toIntValue());
}
- OS << " });\n";
+ OS << " });";
+ }
+ OS << R"(
}
- OS << R"( }
} // getIntrinsicFnAttributeSet
AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
@@ -585,11 +607,7 @@ AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
NumAttrs++, AttrIdx, ArgAttrID);
}
- if (!Int.canThrow ||
- (Int.ME != MemoryEffects::unknown() && !Int.hasSideEffects) ||
- Int.isNoReturn || Int.isNoCallback || Int.isNoSync || Int.isNoFree ||
- Int.isWillReturn || Int.isCold || Int.isNoDuplicate || Int.isNoMerge ||
- Int.isConvergent || Int.isSpeculatable || Int.isStrictFP) {
+ if (hasFnAttributes(Int)) {
unsigned FnAttrID = UniqFnAttributes.find(&Int)->second;
OS << formatv(" AS[{0}] = {{AttributeList::FunctionIndex, "
"getIntrinsicFnAttributeSet(C, {1})};\n",
More information about the llvm-commits
mailing list