Reorganize FastMathFlags to be a wrapper around unsigned, and streamline some interfaces.
authorMichael Ilseman <milseman@apple.com>
Sun, 9 Dec 2012 21:12:04 +0000 (21:12 +0000)
committerMichael Ilseman <milseman@apple.com>
Sun, 9 Dec 2012 21:12:04 +0000 (21:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169712 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/InstructionSimplify.h
include/llvm/Instruction.h
include/llvm/Operator.h
lib/Analysis/InstructionSimplify.cpp
lib/AsmParser/LLParser.h
lib/Bitcode/Reader/BitcodeReader.cpp
lib/Bitcode/Writer/BitcodeWriter.cpp
unittests/VMCore/IRBuilderTest.cpp

index ce7818184e9a634306d94c27bc1dbbae7b49f39d..e9b72a2fa794ee3958aed9a99f0eb35d23eb4669 100644 (file)
@@ -25,7 +25,7 @@ namespace llvm {
   class DominatorTree;
   class Instruction;
   class DataLayout;
-  struct FastMathFlags;
+  class FastMathFlags;
   class TargetLibraryInfo;
   class Type;
   class Value;
index 39f657bf3a449ae02ca6d368f71e1b54241dd917..595ad179e08cb07783b22aa899a35be9a54ba679 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace llvm {
 
-struct FastMathFlags;
+class FastMathFlags;
 class LLVMContext;
 class MDNode;
 
index 289df4e8480a2f030f4f50ad3bd5176cf3f97344..d31e09e2b44fa32fa5885793ef35ddafef335695 100644 (file)
@@ -165,26 +165,48 @@ public:
 };
 
 /// Convenience struct for specifying and reasoning about fast-math flags.
-struct FastMathFlags {
-  bool UnsafeAlgebra   : 1;
-  bool NoNaNs          : 1;
-  bool NoInfs          : 1;
-  bool NoSignedZeros   : 1;
-  bool AllowReciprocal : 1;
-
-  FastMathFlags() : UnsafeAlgebra(false), NoNaNs(false), NoInfs(false),
-                    NoSignedZeros(false), AllowReciprocal(false)
+class FastMathFlags {
+private:
+  friend class FPMathOperator;
+  unsigned Flags;
+  FastMathFlags(unsigned F) : Flags(F) { }
+
+public:
+  enum {
+    UnsafeAlgebra   = (1 << 0),
+    NoNaNs          = (1 << 1),
+    NoInfs          = (1 << 2),
+    NoSignedZeros   = (1 << 3),
+    AllowReciprocal = (1 << 4)
+  };
+
+  FastMathFlags() : Flags(0)
   { }
 
   /// Whether any flag is set
-  bool any() {
-    return UnsafeAlgebra || NoNaNs || NoInfs || NoSignedZeros ||
-      AllowReciprocal;
-  }
+  bool any() { return Flags != 0; }
 
   /// Set all the flags to false
-  void clear() {
-    UnsafeAlgebra = NoNaNs = NoInfs = NoSignedZeros = AllowReciprocal = false;
+  void clear() { Flags = 0; }
+
+  /// Flag queries
+  bool noNaNs()          { return 0 != (Flags & NoNaNs); }
+  bool noInfs()          { return 0 != (Flags & NoInfs); }
+  bool noSignedZeros()   { return 0 != (Flags & NoSignedZeros); }
+  bool allowReciprocal() { return 0 != (Flags & AllowReciprocal); }
+  bool unsafeAlgebra()   { return 0 != (Flags & UnsafeAlgebra); }
+
+  /// Flag setters
+  void setNoNaNs()          { Flags |= NoNaNs; }
+  void setNoInfs()          { Flags |= NoInfs; }
+  void setNoSignedZeros()   { Flags |= NoSignedZeros; }
+  void setAllowReciprocal() { Flags |= AllowReciprocal; }
+  void setUnsafeAlgebra() {
+    Flags |= UnsafeAlgebra;
+    setNoNaNs();
+    setNoInfs();
+    setNoSignedZeros();
+    setAllowReciprocal();
   }
 };
 
@@ -192,21 +214,13 @@ struct FastMathFlags {
 /// FPMathOperator - Utility class for floating point operations which can have
 /// information about relaxed accuracy requirements attached to them.
 class FPMathOperator : public Operator {
-public:
-  enum {
-    UnsafeAlgebra   = (1 << 0),
-    NoNaNs          = (1 << 1),
-    NoInfs          = (1 << 2),
-    NoSignedZeros   = (1 << 3),
-    AllowReciprocal = (1 << 4)
-  };
-
 private:
   friend class Instruction;
 
   void setHasUnsafeAlgebra(bool B) {
     SubclassOptionalData =
-      (SubclassOptionalData & ~UnsafeAlgebra) | (B * UnsafeAlgebra);
+      (SubclassOptionalData & ~FastMathFlags::UnsafeAlgebra) |
+      (B * FastMathFlags::UnsafeAlgebra);
 
     // Unsafe algebra implies all the others
     if (B) {
@@ -218,79 +232,66 @@ private:
   }
   void setHasNoNaNs(bool B) {
     SubclassOptionalData =
-      (SubclassOptionalData & ~NoNaNs) | (B * NoNaNs);
+      (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
+      (B * FastMathFlags::NoNaNs);
   }
   void setHasNoInfs(bool B) {
     SubclassOptionalData =
-      (SubclassOptionalData & ~NoInfs) | (B * NoInfs);
+      (SubclassOptionalData & ~FastMathFlags::NoInfs) |
+      (B * FastMathFlags::NoInfs);
   }
   void setHasNoSignedZeros(bool B) {
     SubclassOptionalData =
-      (SubclassOptionalData & ~NoSignedZeros) | (B * NoSignedZeros);
+      (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) |
+      (B * FastMathFlags::NoSignedZeros);
   }
   void setHasAllowReciprocal(bool B) {
     SubclassOptionalData =
-      (SubclassOptionalData & ~AllowReciprocal) | (B * AllowReciprocal);
+      (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) |
+      (B * FastMathFlags::AllowReciprocal);
   }
 
   /// Convenience function for setting all the fast-math flags
   void setFastMathFlags(FastMathFlags FMF) {
-    if (FMF.UnsafeAlgebra) {
-      // Set all the bits to true
-      setHasUnsafeAlgebra(true);
-      return;
-    }
-
-    setHasUnsafeAlgebra(FMF.UnsafeAlgebra);
-    setHasNoNaNs(FMF.NoNaNs);
-    setHasNoInfs(FMF.NoInfs);
-    setHasNoSignedZeros(FMF.NoSignedZeros);
-    setHasAllowReciprocal(FMF.AllowReciprocal);
+    SubclassOptionalData |= FMF.Flags;
   }
 
 public:
   /// Test whether this operation is permitted to be
   /// algebraically transformed, aka the 'A' fast-math property.
   bool hasUnsafeAlgebra() const {
-    return (SubclassOptionalData & UnsafeAlgebra) != 0;
+    return (SubclassOptionalData & FastMathFlags::UnsafeAlgebra) != 0;
   }
 
   /// Test whether this operation's arguments and results are to be
   /// treated as non-NaN, aka the 'N' fast-math property.
   bool hasNoNaNs() const {
-    return (SubclassOptionalData & NoNaNs) != 0;
+    return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0;
   }
 
   /// Test whether this operation's arguments and results are to be
   /// treated as NoN-Inf, aka the 'I' fast-math property.
   bool hasNoInfs() const {
-    return (SubclassOptionalData & NoInfs) != 0;
+    return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
   }
 
   /// Test whether this operation can treat the sign of zero
   /// as insignificant, aka the 'S' fast-math property.
   bool hasNoSignedZeros() const {
-    return (SubclassOptionalData & NoSignedZeros) != 0;
+    return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
   }
 
   /// Test whether this operation is permitted to use
   /// reciprocal instead of division, aka the 'R' fast-math property.
   bool hasAllowReciprocal() const {
-    return (SubclassOptionalData & AllowReciprocal) != 0;
+    return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
   }
 
   /// Convenience function for getting all the fast-math flags
   FastMathFlags getFastMathFlags() const {
-    FastMathFlags FMF;
-    FMF.UnsafeAlgebra   = hasUnsafeAlgebra();
-    FMF.NoNaNs          = hasNoNaNs();
-    FMF.NoInfs          = hasNoInfs();
-    FMF.NoSignedZeros   = hasNoSignedZeros();
-    FMF.AllowReciprocal = hasAllowReciprocal();
-    return FMF;
+    return FastMathFlags(SubclassOptionalData);
   }
 
-
   /// \brief Get the maximum error permitted by this operation in ULPs.  An
   /// accuracy of 0.0 means that the operation should be performed with the
   /// default precision.
index dfac8fdc2590f90933ddf177690f32de4c05a408..00689475a41b4fdd7b7abd5b70cc21788ef70995 100644 (file)
@@ -900,8 +900,8 @@ static Value *SimplifyFMulInst(Value *Op0, Value *Op1,
  }
 
  // Check for some fast-math optimizations
- if (FMF.NoNaNs) {
-   if (FMF.NoSignedZeros) {
+ if (FMF.noNaNs()) {
+   if (FMF.noSignedZeros()) {
      // fmul N S 0, x ==> 0
      if (match(Op0, m_Zero()))
        return Op0;
index 0039164cc7c7f7d365cd0ee96566485d58246bb7..3a38159d80061f36c9395dbc8de1856cdf4691f7 100644 (file)
@@ -160,11 +160,11 @@ namespace llvm {
       FastMathFlags FMF;
       while (true)
         switch (Lex.getKind()) {
-        case lltok::kw_fast: FMF.UnsafeAlgebra   = true; Lex.Lex(); continue;
-        case lltok::kw_nnan: FMF.NoNaNs          = true; Lex.Lex(); continue;
-        case lltok::kw_ninf: FMF.NoInfs          = true; Lex.Lex(); continue;
-        case lltok::kw_nsz:  FMF.NoSignedZeros   = true; Lex.Lex(); continue;
-        case lltok::kw_arcp: FMF.AllowReciprocal = true; Lex.Lex(); continue;
+        case lltok::kw_fast: FMF.setUnsafeAlgebra();   Lex.Lex(); continue;
+        case lltok::kw_nnan: FMF.setNoNaNs();          Lex.Lex(); continue;
+        case lltok::kw_ninf: FMF.setNoInfs();          Lex.Lex(); continue;
+        case lltok::kw_nsz:  FMF.setNoSignedZeros();   Lex.Lex(); continue;
+        case lltok::kw_arcp: FMF.setAllowReciprocal(); Lex.Lex(); continue;
         default: return FMF;
         }
       return FMF;
index 131151f5354c6025d2f35708370e6e0d82b263e2..1fdea799d0298c0551b163f3023e2e8ce248e9e6 100644 (file)
@@ -2047,16 +2047,16 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
             cast<BinaryOperator>(I)->setIsExact(true);
         } else if (isa<FPMathOperator>(I)) {
           FastMathFlags FMF;
-          FMF.UnsafeAlgebra =
-            0 != (Record[OpNum] & FPMathOperator::UnsafeAlgebra);
-          FMF.NoNaNs =
-            0 != (Record[OpNum] & FPMathOperator::NoNaNs);
-          FMF.NoInfs =
-            0 != (Record[OpNum] & FPMathOperator::NoInfs);
-          FMF.NoSignedZeros =
-            0 != (Record[OpNum] & FPMathOperator::NoSignedZeros);
-          FMF.AllowReciprocal =
-            0 != (Record[OpNum] & FPMathOperator::AllowReciprocal);
+          if (0 != (Record[OpNum] & FastMathFlags::UnsafeAlgebra))
+            FMF.setUnsafeAlgebra();
+          if (0 != (Record[OpNum] & FastMathFlags::NoNaNs))
+            FMF.setNoNaNs();
+          if (0 != (Record[OpNum] & FastMathFlags::NoInfs))
+            FMF.setNoInfs();
+          if (0 != (Record[OpNum] & FastMathFlags::NoSignedZeros))
+            FMF.setNoSignedZeros();
+          if (0 != (Record[OpNum] & FastMathFlags::AllowReciprocal))
+            FMF.setAllowReciprocal();
           if (FMF.any())
             I->setFastMathFlags(FMF);
         }
index f2fe0aef68f564e51121938ecc973939c3db09fe..ffe95d8f273ef62701ac1a7d6d974985a3a5b761 100644 (file)
@@ -552,15 +552,15 @@ static uint64_t GetOptimizationFlags(const Value *V) {
   } else if (const FPMathOperator *FPMO =
              dyn_cast<const FPMathOperator>(V)) {
     if (FPMO->hasUnsafeAlgebra())
-      Flags |= FPMathOperator::UnsafeAlgebra;
+      Flags |= FastMathFlags::UnsafeAlgebra;
     if (FPMO->hasNoNaNs())
-      Flags |= FPMathOperator::NoNaNs;
+      Flags |= FastMathFlags::NoNaNs;
     if (FPMO->hasNoInfs())
-      Flags |= FPMathOperator::NoInfs;
+      Flags |= FastMathFlags::NoInfs;
     if (FPMO->hasNoSignedZeros())
-      Flags |= FPMathOperator::NoSignedZeros;
+      Flags |= FastMathFlags::NoSignedZeros;
     if (FPMO->hasAllowReciprocal())
-      Flags |= FPMathOperator::AllowReciprocal;
+      Flags |= FastMathFlags::AllowReciprocal;
   }
 
   return Flags;
index 86482fa05645c06c31b4a3a2662d439ee32edaaf..d1d59c71eb0016a3e2a4b053d51b538cf3b6f44f 100644 (file)
@@ -129,7 +129,7 @@ TEST_F(IRBuilderTest, FastMathFlags) {
   F = Builder.CreateFAdd(F, F);
   EXPECT_FALSE(Builder.getFastMathFlags().any());
 
-  FMF.UnsafeAlgebra = true;
+  FMF.setUnsafeAlgebra();
   Builder.SetFastMathFlags(FMF);
 
   F = Builder.CreateFAdd(F, F);
@@ -153,7 +153,7 @@ TEST_F(IRBuilderTest, FastMathFlags) {
   EXPECT_FALSE(FDiv->hasAllowReciprocal());
 
   FMF.clear();
-  FMF.AllowReciprocal = true;
+  FMF.setAllowReciprocal();
   Builder.SetFastMathFlags(FMF);
 
   F = Builder.CreateFDiv(F, F);