From 1638b839090a35adcd5a4b4cc0a649352276e703 Mon Sep 17 00:00:00 2001 From: Michael Ilseman Date: Sun, 9 Dec 2012 21:12:04 +0000 Subject: [PATCH] Reorganize FastMathFlags to be a wrapper around unsigned, and streamline some interfaces. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169712 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/InstructionSimplify.h | 2 +- include/llvm/Instruction.h | 2 +- include/llvm/Operator.h | 111 ++++++++++---------- lib/Analysis/InstructionSimplify.cpp | 4 +- lib/AsmParser/LLParser.h | 10 +- lib/Bitcode/Reader/BitcodeReader.cpp | 20 ++-- lib/Bitcode/Writer/BitcodeWriter.cpp | 10 +- unittests/VMCore/IRBuilderTest.cpp | 4 +- 8 files changed, 82 insertions(+), 81 deletions(-) diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index ce7818184e9..e9b72a2fa79 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -25,7 +25,7 @@ namespace llvm { class DominatorTree; class Instruction; class DataLayout; - struct FastMathFlags; + class FastMathFlags; class TargetLibraryInfo; class Type; class Value; diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index 39f657bf3a4..595ad179e08 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -21,7 +21,7 @@ namespace llvm { -struct FastMathFlags; +class FastMathFlags; class LLVMContext; class MDNode; diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h index 289df4e8480..d31e09e2b44 100644 --- a/include/llvm/Operator.h +++ b/include/llvm/Operator.h @@ -165,33 +165,12 @@ 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; +class FastMathFlags { +private: + friend class FPMathOperator; + unsigned Flags; + FastMathFlags(unsigned F) : Flags(F) { } - FastMathFlags() : UnsafeAlgebra(false), NoNaNs(false), NoInfs(false), - NoSignedZeros(false), AllowReciprocal(false) - { } - - /// Whether any flag is set - bool any() { - return UnsafeAlgebra || NoNaNs || NoInfs || NoSignedZeros || - AllowReciprocal; - } - - /// Set all the flags to false - void clear() { - UnsafeAlgebra = NoNaNs = NoInfs = NoSignedZeros = AllowReciprocal = false; - } -}; - - -/// 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), @@ -201,12 +180,47 @@ public: AllowReciprocal = (1 << 4) }; + FastMathFlags() : Flags(0) + { } + + /// Whether any flag is set + bool any() { return Flags != 0; } + + /// Set all the flags to 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(); + } +}; + + +/// FPMathOperator - Utility class for floating point operations which can have +/// information about relaxed accuracy requirements attached to them. +class FPMathOperator : public Operator { 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. diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index dfac8fdc259..00689475a41 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -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; diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index 0039164cc7c..3a38159d800 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -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; diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 131151f5354..1fdea799d02 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2047,16 +2047,16 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { cast(I)->setIsExact(true); } else if (isa(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); } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index f2fe0aef68f..ffe95d8f273 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -552,15 +552,15 @@ static uint64_t GetOptimizationFlags(const Value *V) { } else if (const FPMathOperator *FPMO = dyn_cast(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; diff --git a/unittests/VMCore/IRBuilderTest.cpp b/unittests/VMCore/IRBuilderTest.cpp index 86482fa0564..d1d59c71eb0 100644 --- a/unittests/VMCore/IRBuilderTest.cpp +++ b/unittests/VMCore/IRBuilderTest.cpp @@ -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);