123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===-- llvm/FMF.h - Fast math flags subclass -------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines the fast math flags.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_IR_FMF_H
- #define LLVM_IR_FMF_H
- #include "llvm/Support/raw_ostream.h"
- namespace llvm {
- /// Convenience struct for specifying and reasoning about fast-math flags.
- class FastMathFlags {
- private:
- friend class FPMathOperator;
- unsigned Flags = 0;
- FastMathFlags(unsigned F) {
- // If all 7 bits are set, turn this into -1. If the number of bits grows,
- // this must be updated. This is intended to provide some forward binary
- // compatibility insurance for the meaning of 'fast' in case bits are added.
- if (F == 0x7F) Flags = ~0U;
- else Flags = F;
- }
- public:
- // This is how the bits are used in Value::SubclassOptionalData so they
- // should fit there too.
- // WARNING: We're out of space. SubclassOptionalData only has 7 bits. New
- // functionality will require a change in how this information is stored.
- enum {
- AllowReassoc = (1 << 0),
- NoNaNs = (1 << 1),
- NoInfs = (1 << 2),
- NoSignedZeros = (1 << 3),
- AllowReciprocal = (1 << 4),
- AllowContract = (1 << 5),
- ApproxFunc = (1 << 6)
- };
- FastMathFlags() = default;
- static FastMathFlags getFast() {
- FastMathFlags FMF;
- FMF.setFast();
- return FMF;
- }
- bool any() const { return Flags != 0; }
- bool none() const { return Flags == 0; }
- bool all() const { return Flags == ~0U; }
- void clear() { Flags = 0; }
- void set() { Flags = ~0U; }
- /// Flag queries
- bool allowReassoc() const { return 0 != (Flags & AllowReassoc); }
- bool noNaNs() const { return 0 != (Flags & NoNaNs); }
- bool noInfs() const { return 0 != (Flags & NoInfs); }
- bool noSignedZeros() const { return 0 != (Flags & NoSignedZeros); }
- bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); }
- bool allowContract() const { return 0 != (Flags & AllowContract); }
- bool approxFunc() const { return 0 != (Flags & ApproxFunc); }
- /// 'Fast' means all bits are set.
- bool isFast() const { return all(); }
- /// Flag setters
- void setAllowReassoc(bool B = true) {
- Flags = (Flags & ~AllowReassoc) | B * AllowReassoc;
- }
- void setNoNaNs(bool B = true) {
- Flags = (Flags & ~NoNaNs) | B * NoNaNs;
- }
- void setNoInfs(bool B = true) {
- Flags = (Flags & ~NoInfs) | B * NoInfs;
- }
- void setNoSignedZeros(bool B = true) {
- Flags = (Flags & ~NoSignedZeros) | B * NoSignedZeros;
- }
- void setAllowReciprocal(bool B = true) {
- Flags = (Flags & ~AllowReciprocal) | B * AllowReciprocal;
- }
- void setAllowContract(bool B = true) {
- Flags = (Flags & ~AllowContract) | B * AllowContract;
- }
- void setApproxFunc(bool B = true) {
- Flags = (Flags & ~ApproxFunc) | B * ApproxFunc;
- }
- void setFast(bool B = true) { B ? set() : clear(); }
- void operator&=(const FastMathFlags &OtherFlags) {
- Flags &= OtherFlags.Flags;
- }
- void operator|=(const FastMathFlags &OtherFlags) {
- Flags |= OtherFlags.Flags;
- }
- bool operator!=(const FastMathFlags &OtherFlags) const {
- return Flags != OtherFlags.Flags;
- }
- /// Print fast-math flags to \p O.
- void print(raw_ostream &O) const;
- };
- inline raw_ostream &operator<<(raw_ostream &O, FastMathFlags FMF) {
- FMF.print(O);
- return O;
- }
- } // end namespace llvm
- #endif // LLVM_IR_FMF_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|