[NFC][TableGen] Refactor getIntrinsicFnAttributeSet (#106587)
Fix intrinsic function attributes to not generate attribute sets that are empty in `getIntrinsicFnAttributeSet`. Refactor the code to use helper functions to get effective memory effects for an intrinsic and to check if it has non-default attributes. This eliminates 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.
This commit is contained in:
@@ -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,54 @@ 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";
|
||||
}
|
||||
llvm_unreachable("Unknown CodeGenIntrinsic::ArgAttrKind enum");
|
||||
}
|
||||
|
||||
/// EmitAttributes - This emits the Intrinsic::getAttributes method.
|
||||
void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints,
|
||||
raw_ostream &OS) {
|
||||
@@ -425,34 +473,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";
|
||||
}
|
||||
llvm_unreachable("Unknown CodeGenIntrinsic::ArgAttrKind enum");
|
||||
};
|
||||
|
||||
OS << formatv(R"(
|
||||
case {0}:
|
||||
@@ -460,7 +480,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",
|
||||
@@ -473,7 +493,8 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
|
||||
}
|
||||
OS << R"(
|
||||
}
|
||||
} // getIntrinsicArgAttributeSet)";
|
||||
} // getIntrinsicArgAttributeSet
|
||||
)";
|
||||
|
||||
// Compute unique function attribute sets.
|
||||
std::map<const CodeGenIntrinsic *, unsigned, FnAttributeComparator>
|
||||
@@ -482,9 +503,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}:
|
||||
@@ -494,44 +518,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) {
|
||||
@@ -586,11 +608,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",
|
||||
|
||||
Reference in New Issue
Block a user