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