[llvm] [SDAG][NFC] Convert `SDNodeFlags` into an enumeration (PR #114167)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 29 19:28:51 PDT 2024
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/114167
This patch converts `SDNodeFlags` into an enumeration as we did for `FastMathFlags`. It simplifies the implementation and improves compile-time. This patch is NFC since it doesn't break SDNodeFlags API.
It is split from https://github.com/llvm/llvm-project/pull/114061 for easier review.
>From 687117b846838af0310871406b0921f882ac82d7 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 29 Oct 2024 19:49:49 +0800
Subject: [PATCH] [SDAG] Convert `SDNodeFlags` into enums
---
llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 159 ++++++++----------
1 file changed, 73 insertions(+), 86 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index bda0120a2df4aa..26488413fe5826 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -378,36 +378,48 @@ template<> struct simplify_type<SDUse> {
/// the backend.
struct SDNodeFlags {
private:
- bool NoUnsignedWrap : 1;
- bool NoSignedWrap : 1;
- bool Exact : 1;
- bool Disjoint : 1;
- bool NonNeg : 1;
- bool NoNaNs : 1;
- bool NoInfs : 1;
- bool NoSignedZeros : 1;
- bool AllowReciprocal : 1;
- bool AllowContract : 1;
- bool ApproximateFuncs : 1;
- bool AllowReassociation : 1;
-
- // We assume instructions do not raise floating-point exceptions by default,
- // and only those marked explicitly may do so. We could choose to represent
- // this via a positive "FPExcept" flags like on the MI level, but having a
- // negative "NoFPExcept" flag here makes the flag intersection logic more
- // straightforward.
- bool NoFPExcept : 1;
- // Instructions with attached 'unpredictable' metadata on IR level.
- bool Unpredictable : 1;
+ friend class SDNode;
+
+ unsigned Flags = 0;
+
+ template <unsigned Flag> void setFlag(bool B) {
+ Flags = (Flags & ~Flag) | (B ? Flag : 0);
+ }
public:
+ enum : unsigned {
+ None = 0,
+ NoUnsignedWrap = 1 << 0,
+ NoSignedWrap = 1 << 1,
+ Exact = 1 << 2,
+ Disjoint = 1 << 3,
+ NonNeg = 1 << 4,
+ NoNaNs = 1 << 5,
+ NoInfs = 1 << 6,
+ NoSignedZeros = 1 << 7,
+ AllowReciprocal = 1 << 8,
+ AllowContract = 1 << 9,
+ ApproximateFuncs = 1 << 10,
+ AllowReassociation = 1 << 11,
+
+ // We assume instructions do not raise floating-point exceptions by default,
+ // and only those marked explicitly may do so. We could choose to represent
+ // this via a positive "FPExcept" flags like on the MI level, but having a
+ // negative "NoFPExcept" flag here makes the flag intersection logic more
+ // straightforward.
+ NoFPExcept = 1 << 12,
+ // Instructions with attached 'unpredictable' metadata on IR level.
+ Unpredictable = 1 << 13,
+
+ // NOTE: Please update LargestValue in LLVM_DECLARE_ENUM_AS_BITMASK below
+ // the class definition when adding new flags.
+
+ PoisonGeneratingFlags = NoUnsignedWrap | NoSignedWrap | Exact | Disjoint |
+ NonNeg | NoNaNs | NoInfs,
+ };
+
/// Default constructor turns off all optimization flags.
- SDNodeFlags()
- : NoUnsignedWrap(false), NoSignedWrap(false), Exact(false),
- Disjoint(false), NonNeg(false), NoNaNs(false), NoInfs(false),
- NoSignedZeros(false), AllowReciprocal(false), AllowContract(false),
- ApproximateFuncs(false), AllowReassociation(false), NoFPExcept(false),
- Unpredictable(false) {}
+ SDNodeFlags() : Flags(0) {}
/// Propagate the fast-math-flags from an IR FPMathOperator.
void copyFMF(const FPMathOperator &FPMO) {
@@ -421,71 +433,49 @@ struct SDNodeFlags {
}
// These are mutators for each flag.
- void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; }
- void setNoSignedWrap(bool b) { NoSignedWrap = b; }
- void setExact(bool b) { Exact = b; }
- void setDisjoint(bool b) { Disjoint = b; }
- void setNonNeg(bool b) { NonNeg = b; }
- void setNoNaNs(bool b) { NoNaNs = b; }
- void setNoInfs(bool b) { NoInfs = b; }
- void setNoSignedZeros(bool b) { NoSignedZeros = b; }
- void setAllowReciprocal(bool b) { AllowReciprocal = b; }
- void setAllowContract(bool b) { AllowContract = b; }
- void setApproximateFuncs(bool b) { ApproximateFuncs = b; }
- void setAllowReassociation(bool b) { AllowReassociation = b; }
- void setNoFPExcept(bool b) { NoFPExcept = b; }
- void setUnpredictable(bool b) { Unpredictable = b; }
+ void setNoUnsignedWrap(bool b) { setFlag<NoUnsignedWrap>(b); }
+ void setNoSignedWrap(bool b) { setFlag<NoSignedWrap>(b); }
+ void setExact(bool b) { setFlag<Exact>(b); }
+ void setDisjoint(bool b) { setFlag<Disjoint>(b); }
+ void setNonNeg(bool b) { setFlag<NonNeg>(b); }
+ void setNoNaNs(bool b) { setFlag<NoNaNs>(b); }
+ void setNoInfs(bool b) { setFlag<NoInfs>(b); }
+ void setNoSignedZeros(bool b) { setFlag<NoSignedZeros>(b); }
+ void setAllowReciprocal(bool b) { setFlag<AllowReciprocal>(b); }
+ void setAllowContract(bool b) { setFlag<AllowContract>(b); }
+ void setApproximateFuncs(bool b) { setFlag<ApproximateFuncs>(b); }
+ void setAllowReassociation(bool b) { setFlag<AllowReassociation>(b); }
+ void setNoFPExcept(bool b) { setFlag<NoFPExcept>(b); }
+ void setUnpredictable(bool b) { setFlag<Unpredictable>(b); }
// These are accessors for each flag.
- bool hasNoUnsignedWrap() const { return NoUnsignedWrap; }
- bool hasNoSignedWrap() const { return NoSignedWrap; }
- bool hasExact() const { return Exact; }
- bool hasDisjoint() const { return Disjoint; }
- bool hasNonNeg() const { return NonNeg; }
- bool hasNoNaNs() const { return NoNaNs; }
- bool hasNoInfs() const { return NoInfs; }
- bool hasNoSignedZeros() const { return NoSignedZeros; }
- bool hasAllowReciprocal() const { return AllowReciprocal; }
- bool hasAllowContract() const { return AllowContract; }
- bool hasApproximateFuncs() const { return ApproximateFuncs; }
- bool hasAllowReassociation() const { return AllowReassociation; }
- bool hasNoFPExcept() const { return NoFPExcept; }
- bool hasUnpredictable() const { return Unpredictable; }
+ bool hasNoUnsignedWrap() const { return Flags & NoUnsignedWrap; }
+ bool hasNoSignedWrap() const { return Flags & NoSignedWrap; }
+ bool hasExact() const { return Flags & Exact; }
+ bool hasDisjoint() const { return Flags & Disjoint; }
+ bool hasNonNeg() const { return Flags & NonNeg; }
+ bool hasNoNaNs() const { return Flags & NoNaNs; }
+ bool hasNoInfs() const { return Flags & NoInfs; }
+ bool hasNoSignedZeros() const { return Flags & NoSignedZeros; }
+ bool hasAllowReciprocal() const { return Flags & AllowReciprocal; }
+ bool hasAllowContract() const { return Flags & AllowContract; }
+ bool hasApproximateFuncs() const { return Flags & ApproximateFuncs; }
+ bool hasAllowReassociation() const { return Flags & AllowReassociation; }
+ bool hasNoFPExcept() const { return Flags & NoFPExcept; }
+ bool hasUnpredictable() const { return Flags & Unpredictable; }
bool operator==(const SDNodeFlags &Other) const {
- return NoUnsignedWrap == Other.NoUnsignedWrap &&
- NoSignedWrap == Other.NoSignedWrap && Exact == Other.Exact &&
- Disjoint == Other.Disjoint && NonNeg == Other.NonNeg &&
- NoNaNs == Other.NoNaNs && NoInfs == Other.NoInfs &&
- NoSignedZeros == Other.NoSignedZeros &&
- AllowReciprocal == Other.AllowReciprocal &&
- AllowContract == Other.AllowContract &&
- ApproximateFuncs == Other.ApproximateFuncs &&
- AllowReassociation == Other.AllowReassociation &&
- NoFPExcept == Other.NoFPExcept &&
- Unpredictable == Other.Unpredictable;
+ return Flags == Other.Flags;
}
/// Clear any flags in this flag set that aren't also set in Flags. All
/// flags will be cleared if Flags are undefined.
- void intersectWith(const SDNodeFlags Flags) {
- NoUnsignedWrap &= Flags.NoUnsignedWrap;
- NoSignedWrap &= Flags.NoSignedWrap;
- Exact &= Flags.Exact;
- Disjoint &= Flags.Disjoint;
- NonNeg &= Flags.NonNeg;
- NoNaNs &= Flags.NoNaNs;
- NoInfs &= Flags.NoInfs;
- NoSignedZeros &= Flags.NoSignedZeros;
- AllowReciprocal &= Flags.AllowReciprocal;
- AllowContract &= Flags.AllowContract;
- ApproximateFuncs &= Flags.ApproximateFuncs;
- AllowReassociation &= Flags.AllowReassociation;
- NoFPExcept &= Flags.NoFPExcept;
- Unpredictable &= Flags.Unpredictable;
- }
+ void intersectWith(const SDNodeFlags Flags) { this->Flags &= Flags.Flags; }
};
+LLVM_DECLARE_ENUM_AS_BITMASK(decltype(SDNodeFlags::None),
+ SDNodeFlags::Unpredictable);
+
/// Represents one node in the SelectionDAG.
///
class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
@@ -1029,10 +1019,7 @@ END_TWO_BYTE_PACK()
void intersectFlagsWith(const SDNodeFlags Flags);
bool hasPoisonGeneratingFlags() const {
- SDNodeFlags Flags = getFlags();
- return Flags.hasNoUnsignedWrap() || Flags.hasNoSignedWrap() ||
- Flags.hasExact() || Flags.hasDisjoint() || Flags.hasNonNeg() ||
- Flags.hasNoNaNs() || Flags.hasNoInfs();
+ return Flags.Flags & SDNodeFlags::PoisonGeneratingFlags;
}
void setCFIType(uint32_t Type) { CFIType = Type; }
More information about the llvm-commits
mailing list