@@ -378,36 +378,48 @@ template<> struct simplify_type<SDUse> {
378378// / the backend.
379379struct SDNodeFlags {
380380private:
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
403389public:
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// /
491481class 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