Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:00

0001 //===-- llvm/FMF.h - Fast math flags subclass -------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the fast math flags.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_IR_FMF_H
0014 #define LLVM_IR_FMF_H
0015 
0016 namespace llvm {
0017 class raw_ostream;
0018 
0019 /// Convenience struct for specifying and reasoning about fast-math flags.
0020 class FastMathFlags {
0021 private:
0022   friend class FPMathOperator;
0023 
0024   unsigned Flags = 0;
0025 
0026   FastMathFlags(unsigned F) {
0027     // If all 7 bits are set, turn this into -1. If the number of bits grows,
0028     // this must be updated. This is intended to provide some forward binary
0029     // compatibility insurance for the meaning of 'fast' in case bits are added.
0030     if (F == 0x7F) Flags = ~0U;
0031     else Flags = F;
0032   }
0033 
0034 public:
0035   // This is how the bits are used in Value::SubclassOptionalData so they
0036   // should fit there too.
0037   // WARNING: We're out of space. SubclassOptionalData only has 7 bits. New
0038   // functionality will require a change in how this information is stored.
0039   enum {
0040     AllowReassoc    = (1 << 0),
0041     NoNaNs          = (1 << 1),
0042     NoInfs          = (1 << 2),
0043     NoSignedZeros   = (1 << 3),
0044     AllowReciprocal = (1 << 4),
0045     AllowContract   = (1 << 5),
0046     ApproxFunc      = (1 << 6)
0047   };
0048 
0049   FastMathFlags() = default;
0050 
0051   static FastMathFlags getFast() {
0052     FastMathFlags FMF;
0053     FMF.setFast();
0054     return FMF;
0055   }
0056 
0057   bool any() const { return Flags != 0; }
0058   bool none() const { return Flags == 0; }
0059   bool all() const { return Flags == ~0U; }
0060 
0061   void clear() { Flags = 0; }
0062   void set()   { Flags = ~0U; }
0063 
0064   /// Flag queries
0065   bool allowReassoc() const    { return 0 != (Flags & AllowReassoc); }
0066   bool noNaNs() const          { return 0 != (Flags & NoNaNs); }
0067   bool noInfs() const          { return 0 != (Flags & NoInfs); }
0068   bool noSignedZeros() const   { return 0 != (Flags & NoSignedZeros); }
0069   bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); }
0070   bool allowContract() const   { return 0 != (Flags & AllowContract); }
0071   bool approxFunc() const      { return 0 != (Flags & ApproxFunc); }
0072   /// 'Fast' means all bits are set.
0073   bool isFast() const          { return all(); }
0074 
0075   /// Flag setters
0076   void setAllowReassoc(bool B = true) {
0077     Flags = (Flags & ~AllowReassoc) | B * AllowReassoc;
0078   }
0079   void setNoNaNs(bool B = true) {
0080     Flags = (Flags & ~NoNaNs) | B * NoNaNs;
0081   }
0082   void setNoInfs(bool B = true) {
0083     Flags = (Flags & ~NoInfs) | B * NoInfs;
0084   }
0085   void setNoSignedZeros(bool B = true) {
0086     Flags = (Flags & ~NoSignedZeros) | B * NoSignedZeros;
0087   }
0088   void setAllowReciprocal(bool B = true) {
0089     Flags = (Flags & ~AllowReciprocal) | B * AllowReciprocal;
0090   }
0091   void setAllowContract(bool B = true) {
0092     Flags = (Flags & ~AllowContract) | B * AllowContract;
0093   }
0094   void setApproxFunc(bool B = true) {
0095     Flags = (Flags & ~ApproxFunc) | B * ApproxFunc;
0096   }
0097   void setFast(bool B = true) { B ? set() : clear(); }
0098 
0099   void operator&=(const FastMathFlags &OtherFlags) {
0100     Flags &= OtherFlags.Flags;
0101   }
0102   void operator|=(const FastMathFlags &OtherFlags) {
0103     Flags |= OtherFlags.Flags;
0104   }
0105   bool operator!=(const FastMathFlags &OtherFlags) const {
0106     return Flags != OtherFlags.Flags;
0107   }
0108 
0109   /// Print fast-math flags to \p O.
0110   void print(raw_ostream &O) const;
0111 
0112   /// Intersect rewrite-based flags
0113   static inline FastMathFlags intersectRewrite(FastMathFlags LHS,
0114                                                FastMathFlags RHS) {
0115     const unsigned RewriteMask =
0116         AllowReassoc | AllowReciprocal | AllowContract | ApproxFunc;
0117     return FastMathFlags(RewriteMask & LHS.Flags & RHS.Flags);
0118   }
0119 
0120   /// Union value flags
0121   static inline FastMathFlags unionValue(FastMathFlags LHS, FastMathFlags RHS) {
0122     const unsigned ValueMask = NoNaNs | NoInfs | NoSignedZeros;
0123     return FastMathFlags(ValueMask & (LHS.Flags | RHS.Flags));
0124   }
0125 };
0126 
0127 inline FastMathFlags operator|(FastMathFlags LHS, FastMathFlags RHS) {
0128   LHS |= RHS;
0129   return LHS;
0130 }
0131 
0132 inline FastMathFlags operator&(FastMathFlags LHS, FastMathFlags RHS) {
0133   LHS &= RHS;
0134   return LHS;
0135 }
0136 
0137 inline raw_ostream &operator<<(raw_ostream &O, FastMathFlags FMF) {
0138   FMF.print(O);
0139   return O;
0140 }
0141 
0142 } // end namespace llvm
0143 
0144 #endif // LLVM_IR_FMF_H