@@ -378,36 +378,48 @@ template<> struct simplify_type<SDUse> {
378
378
// / the backend.
379
379
struct SDNodeFlags {
380
380
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
+ }
402
388
403
389
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
+
404
421
// / 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 ) {}
411
423
412
424
// / Propagate the fast-math-flags from an IR FPMathOperator.
413
425
void copyFMF (const FPMathOperator &FPMO) {
@@ -421,71 +433,49 @@ struct SDNodeFlags {
421
433
}
422
434
423
435
// 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) ; }
438
450
439
451
// 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; }
454
466
455
467
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 ;
467
469
}
468
470
469
471
// / Clear any flags in this flag set that aren't also set in Flags. All
470
472
// / 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 ; }
487
474
};
488
475
476
+ LLVM_DECLARE_ENUM_AS_BITMASK (decltype (SDNodeFlags::None),
477
+ SDNodeFlags::Unpredictable);
478
+
489
479
// / Represents one node in the SelectionDAG.
490
480
// /
491
481
class SDNode : public FoldingSetNode , public ilist_node <SDNode> {
@@ -1029,10 +1019,7 @@ END_TWO_BYTE_PACK()
1029
1019
void intersectFlagsWith (const SDNodeFlags Flags);
1030
1020
1031
1021
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;
1036
1023
}
1037
1024
1038
1025
void setCFIType (uint32_t Type) { CFIType = Type; }
0 commit comments