122 lines
3.7 KiB
C
122 lines
3.7 KiB
C
|
|
//===-- 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
|