1 //===-- llvm/FMF.h - Fast math flags subclass -------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the fast math flags. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_IR_FMF_H 14 #define LLVM_IR_FMF_H 15 16 #include "llvm/Support/raw_ostream.h" 17 18 namespace llvm { 19 20 /// Convenience struct for specifying and reasoning about fast-math flags. 21 class FastMathFlags { 22 private: 23 friend class FPMathOperator; 24 25 unsigned Flags = 0; 26 FastMathFlags(unsigned F)27 FastMathFlags(unsigned F) { 28 // If all 7 bits are set, turn this into -1. If the number of bits grows, 29 // this must be updated. This is intended to provide some forward binary 30 // compatibility insurance for the meaning of 'fast' in case bits are added. 31 if (F == 0x7F) Flags = ~0U; 32 else Flags = F; 33 } 34 35 public: 36 // This is how the bits are used in Value::SubclassOptionalData so they 37 // should fit there too. 38 // WARNING: We're out of space. SubclassOptionalData only has 7 bits. New 39 // functionality will require a change in how this information is stored. 40 enum { 41 AllowReassoc = (1 << 0), 42 NoNaNs = (1 << 1), 43 NoInfs = (1 << 2), 44 NoSignedZeros = (1 << 3), 45 AllowReciprocal = (1 << 4), 46 AllowContract = (1 << 5), 47 ApproxFunc = (1 << 6) 48 }; 49 50 FastMathFlags() = default; 51 getFast()52 static FastMathFlags getFast() { 53 FastMathFlags FMF; 54 FMF.setFast(); 55 return FMF; 56 } 57 any()58 bool any() const { return Flags != 0; } none()59 bool none() const { return Flags == 0; } all()60 bool all() const { return Flags == ~0U; } 61 clear()62 void clear() { Flags = 0; } set()63 void set() { Flags = ~0U; } 64 65 /// Flag queries allowReassoc()66 bool allowReassoc() const { return 0 != (Flags & AllowReassoc); } noNaNs()67 bool noNaNs() const { return 0 != (Flags & NoNaNs); } noInfs()68 bool noInfs() const { return 0 != (Flags & NoInfs); } noSignedZeros()69 bool noSignedZeros() const { return 0 != (Flags & NoSignedZeros); } allowReciprocal()70 bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); } allowContract()71 bool allowContract() const { return 0 != (Flags & AllowContract); } approxFunc()72 bool approxFunc() const { return 0 != (Flags & ApproxFunc); } 73 /// 'Fast' means all bits are set. isFast()74 bool isFast() const { return all(); } 75 76 /// Flag setters 77 void setAllowReassoc(bool B = true) { 78 Flags = (Flags & ~AllowReassoc) | B * AllowReassoc; 79 } 80 void setNoNaNs(bool B = true) { 81 Flags = (Flags & ~NoNaNs) | B * NoNaNs; 82 } 83 void setNoInfs(bool B = true) { 84 Flags = (Flags & ~NoInfs) | B * NoInfs; 85 } 86 void setNoSignedZeros(bool B = true) { 87 Flags = (Flags & ~NoSignedZeros) | B * NoSignedZeros; 88 } 89 void setAllowReciprocal(bool B = true) { 90 Flags = (Flags & ~AllowReciprocal) | B * AllowReciprocal; 91 } 92 void setAllowContract(bool B = true) { 93 Flags = (Flags & ~AllowContract) | B * AllowContract; 94 } 95 void setApproxFunc(bool B = true) { 96 Flags = (Flags & ~ApproxFunc) | B * ApproxFunc; 97 } 98 void setFast(bool B = true) { B ? set() : clear(); } 99 100 void operator&=(const FastMathFlags &OtherFlags) { 101 Flags &= OtherFlags.Flags; 102 } 103 void operator|=(const FastMathFlags &OtherFlags) { 104 Flags |= OtherFlags.Flags; 105 } 106 bool operator!=(const FastMathFlags &OtherFlags) const { 107 return Flags != OtherFlags.Flags; 108 } 109 110 /// Print fast-math flags to \p O. 111 void print(raw_ostream &O) const; 112 }; 113 114 inline raw_ostream &operator<<(raw_ostream &O, FastMathFlags FMF) { 115 FMF.print(O); 116 return O; 117 } 118 119 } // end namespace llvm 120 121 #endif // LLVM_IR_FMF_H 122