-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[SDAG][NFC] Convert SDNodeFlags
into an enumeration
#114167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-llvm-selectiondag Author: Yingwei Zheng (dtcxzyw) ChangesThis patch converts It is split from #114061 for easier review. Full diff: https://github.com/llvm/llvm-project/pull/114167.diff 1 Files Affected:
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; }
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG
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.
This patch converts
SDNodeFlags
into an enumeration as we did forFastMathFlags
. It simplifies the implementation and improves compile-time. This patch is NFC since it doesn't break SDNodeFlags API.It is split from #114061 for easier review.