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
16namespace llvm {
17class raw_ostream;
18
19/// Convenience struct for specifying and reasoning about fast-math flags.
20class FastMathFlags {
21private:
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
34public:
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 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
113inline FastMathFlags operator|(FastMathFlags LHS, FastMathFlags RHS) {
114 LHS |= RHS;
115 return LHS;
116}
117
118inline FastMathFlags operator&(FastMathFlags LHS, FastMathFlags RHS) {
119 LHS &= RHS;
120 return LHS;
121}
122
123inline 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
131

source code of llvm/include/llvm/IR/FMF.h