Skip to content

Commit f1467b3

Browse files
authored
[SDAG][NFC] Convert SDNodeFlags into an enumeration (#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.
1 parent e7262c1 commit f1467b3

File tree

1 file changed

+73
-86
lines changed

1 file changed

+73
-86
lines changed

llvm/include/llvm/CodeGen/SelectionDAGNodes.h

Lines changed: 73 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -378,36 +378,48 @@ template<> struct simplify_type<SDUse> {
378378
/// the backend.
379379
struct SDNodeFlags {
380380
private:
381-
bool NoUnsignedWrap : 1;
382-
bool NoSignedWrap : 1;
383-
bool Exact : 1;
384-
bool Disjoint : 1;
385-
bool NonNeg : 1;
386-
bool NoNaNs : 1;
387-
bool NoInfs : 1;
388-
bool NoSignedZeros : 1;
389-
bool AllowReciprocal : 1;
390-
bool AllowContract : 1;
391-
bool ApproximateFuncs : 1;
392-
bool AllowReassociation : 1;
393-
394-
// We assume instructions do not raise floating-point exceptions by default,
395-
// and only those marked explicitly may do so. We could choose to represent
396-
// this via a positive "FPExcept" flags like on the MI level, but having a
397-
// negative "NoFPExcept" flag here makes the flag intersection logic more
398-
// straightforward.
399-
bool NoFPExcept : 1;
400-
// Instructions with attached 'unpredictable' metadata on IR level.
401-
bool Unpredictable : 1;
381+
friend class SDNode;
382+
383+
unsigned Flags = 0;
384+
385+
template <unsigned Flag> void setFlag(bool B) {
386+
Flags = (Flags & ~Flag) | (B ? Flag : 0);
387+
}
402388

403389
public:
390+
enum : unsigned {
391+
None = 0,
392+
NoUnsignedWrap = 1 << 0,
393+
NoSignedWrap = 1 << 1,
394+
Exact = 1 << 2,
395+
Disjoint = 1 << 3,
396+
NonNeg = 1 << 4,
397+
NoNaNs = 1 << 5,
398+
NoInfs = 1 << 6,
399+
NoSignedZeros = 1 << 7,
400+
AllowReciprocal = 1 << 8,
401+
AllowContract = 1 << 9,
402+
ApproximateFuncs = 1 << 10,
403+
AllowReassociation = 1 << 11,
404+
405+
// We assume instructions do not raise floating-point exceptions by default,
406+
// and only those marked explicitly may do so. We could choose to represent
407+
// this via a positive "FPExcept" flags like on the MI level, but having a
408+
// negative "NoFPExcept" flag here makes the flag intersection logic more
409+
// straightforward.
410+
NoFPExcept = 1 << 12,
411+
// Instructions with attached 'unpredictable' metadata on IR level.
412+
Unpredictable = 1 << 13,
413+
414+
// NOTE: Please update LargestValue in LLVM_DECLARE_ENUM_AS_BITMASK below
415+
// the class definition when adding new flags.
416+
417+
PoisonGeneratingFlags = NoUnsignedWrap | NoSignedWrap | Exact | Disjoint |
418+
NonNeg | NoNaNs | NoInfs,
419+
};
420+
404421
/// Default constructor turns off all optimization flags.
405-
SDNodeFlags()
406-
: NoUnsignedWrap(false), NoSignedWrap(false), Exact(false),
407-
Disjoint(false), NonNeg(false), NoNaNs(false), NoInfs(false),
408-
NoSignedZeros(false), AllowReciprocal(false), AllowContract(false),
409-
ApproximateFuncs(false), AllowReassociation(false), NoFPExcept(false),
410-
Unpredictable(false) {}
422+
SDNodeFlags() : Flags(0) {}
411423

412424
/// Propagate the fast-math-flags from an IR FPMathOperator.
413425
void copyFMF(const FPMathOperator &FPMO) {
@@ -421,71 +433,49 @@ struct SDNodeFlags {
421433
}
422434

423435
// These are mutators for each flag.
424-
void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; }
425-
void setNoSignedWrap(bool b) { NoSignedWrap = b; }
426-
void setExact(bool b) { Exact = b; }
427-
void setDisjoint(bool b) { Disjoint = b; }
428-
void setNonNeg(bool b) { NonNeg = b; }
429-
void setNoNaNs(bool b) { NoNaNs = b; }
430-
void setNoInfs(bool b) { NoInfs = b; }
431-
void setNoSignedZeros(bool b) { NoSignedZeros = b; }
432-
void setAllowReciprocal(bool b) { AllowReciprocal = b; }
433-
void setAllowContract(bool b) { AllowContract = b; }
434-
void setApproximateFuncs(bool b) { ApproximateFuncs = b; }
435-
void setAllowReassociation(bool b) { AllowReassociation = b; }
436-
void setNoFPExcept(bool b) { NoFPExcept = b; }
437-
void setUnpredictable(bool b) { Unpredictable = b; }
436+
void setNoUnsignedWrap(bool b) { setFlag<NoUnsignedWrap>(b); }
437+
void setNoSignedWrap(bool b) { setFlag<NoSignedWrap>(b); }
438+
void setExact(bool b) { setFlag<Exact>(b); }
439+
void setDisjoint(bool b) { setFlag<Disjoint>(b); }
440+
void setNonNeg(bool b) { setFlag<NonNeg>(b); }
441+
void setNoNaNs(bool b) { setFlag<NoNaNs>(b); }
442+
void setNoInfs(bool b) { setFlag<NoInfs>(b); }
443+
void setNoSignedZeros(bool b) { setFlag<NoSignedZeros>(b); }
444+
void setAllowReciprocal(bool b) { setFlag<AllowReciprocal>(b); }
445+
void setAllowContract(bool b) { setFlag<AllowContract>(b); }
446+
void setApproximateFuncs(bool b) { setFlag<ApproximateFuncs>(b); }
447+
void setAllowReassociation(bool b) { setFlag<AllowReassociation>(b); }
448+
void setNoFPExcept(bool b) { setFlag<NoFPExcept>(b); }
449+
void setUnpredictable(bool b) { setFlag<Unpredictable>(b); }
438450

439451
// These are accessors for each flag.
440-
bool hasNoUnsignedWrap() const { return NoUnsignedWrap; }
441-
bool hasNoSignedWrap() const { return NoSignedWrap; }
442-
bool hasExact() const { return Exact; }
443-
bool hasDisjoint() const { return Disjoint; }
444-
bool hasNonNeg() const { return NonNeg; }
445-
bool hasNoNaNs() const { return NoNaNs; }
446-
bool hasNoInfs() const { return NoInfs; }
447-
bool hasNoSignedZeros() const { return NoSignedZeros; }
448-
bool hasAllowReciprocal() const { return AllowReciprocal; }
449-
bool hasAllowContract() const { return AllowContract; }
450-
bool hasApproximateFuncs() const { return ApproximateFuncs; }
451-
bool hasAllowReassociation() const { return AllowReassociation; }
452-
bool hasNoFPExcept() const { return NoFPExcept; }
453-
bool hasUnpredictable() const { return Unpredictable; }
452+
bool hasNoUnsignedWrap() const { return Flags & NoUnsignedWrap; }
453+
bool hasNoSignedWrap() const { return Flags & NoSignedWrap; }
454+
bool hasExact() const { return Flags & Exact; }
455+
bool hasDisjoint() const { return Flags & Disjoint; }
456+
bool hasNonNeg() const { return Flags & NonNeg; }
457+
bool hasNoNaNs() const { return Flags & NoNaNs; }
458+
bool hasNoInfs() const { return Flags & NoInfs; }
459+
bool hasNoSignedZeros() const { return Flags & NoSignedZeros; }
460+
bool hasAllowReciprocal() const { return Flags & AllowReciprocal; }
461+
bool hasAllowContract() const { return Flags & AllowContract; }
462+
bool hasApproximateFuncs() const { return Flags & ApproximateFuncs; }
463+
bool hasAllowReassociation() const { return Flags & AllowReassociation; }
464+
bool hasNoFPExcept() const { return Flags & NoFPExcept; }
465+
bool hasUnpredictable() const { return Flags & Unpredictable; }
454466

455467
bool operator==(const SDNodeFlags &Other) const {
456-
return NoUnsignedWrap == Other.NoUnsignedWrap &&
457-
NoSignedWrap == Other.NoSignedWrap && Exact == Other.Exact &&
458-
Disjoint == Other.Disjoint && NonNeg == Other.NonNeg &&
459-
NoNaNs == Other.NoNaNs && NoInfs == Other.NoInfs &&
460-
NoSignedZeros == Other.NoSignedZeros &&
461-
AllowReciprocal == Other.AllowReciprocal &&
462-
AllowContract == Other.AllowContract &&
463-
ApproximateFuncs == Other.ApproximateFuncs &&
464-
AllowReassociation == Other.AllowReassociation &&
465-
NoFPExcept == Other.NoFPExcept &&
466-
Unpredictable == Other.Unpredictable;
468+
return Flags == Other.Flags;
467469
}
468470

469471
/// Clear any flags in this flag set that aren't also set in Flags. All
470472
/// flags will be cleared if Flags are undefined.
471-
void intersectWith(const SDNodeFlags Flags) {
472-
NoUnsignedWrap &= Flags.NoUnsignedWrap;
473-
NoSignedWrap &= Flags.NoSignedWrap;
474-
Exact &= Flags.Exact;
475-
Disjoint &= Flags.Disjoint;
476-
NonNeg &= Flags.NonNeg;
477-
NoNaNs &= Flags.NoNaNs;
478-
NoInfs &= Flags.NoInfs;
479-
NoSignedZeros &= Flags.NoSignedZeros;
480-
AllowReciprocal &= Flags.AllowReciprocal;
481-
AllowContract &= Flags.AllowContract;
482-
ApproximateFuncs &= Flags.ApproximateFuncs;
483-
AllowReassociation &= Flags.AllowReassociation;
484-
NoFPExcept &= Flags.NoFPExcept;
485-
Unpredictable &= Flags.Unpredictable;
486-
}
473+
void intersectWith(const SDNodeFlags Flags) { this->Flags &= Flags.Flags; }
487474
};
488475

476+
LLVM_DECLARE_ENUM_AS_BITMASK(decltype(SDNodeFlags::None),
477+
SDNodeFlags::Unpredictable);
478+
489479
/// Represents one node in the SelectionDAG.
490480
///
491481
class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
@@ -1029,10 +1019,7 @@ END_TWO_BYTE_PACK()
10291019
void intersectFlagsWith(const SDNodeFlags Flags);
10301020

10311021
bool hasPoisonGeneratingFlags() const {
1032-
SDNodeFlags Flags = getFlags();
1033-
return Flags.hasNoUnsignedWrap() || Flags.hasNoSignedWrap() ||
1034-
Flags.hasExact() || Flags.hasDisjoint() || Flags.hasNonNeg() ||
1035-
Flags.hasNoNaNs() || Flags.hasNoInfs();
1022+
return Flags.Flags & SDNodeFlags::PoisonGeneratingFlags;
10361023
}
10371024

10381025
void setCFIType(uint32_t Type) { CFIType = Type; }

0 commit comments

Comments
 (0)