MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
math.h
Go to the documentation of this file.
1#pragma once
2
3#include <mim/axm.h>
4#include <mim/world.h>
5
7
8namespace mim::plug::math {
9
10/// @name Mode
11///@{
12// clang-format off
13/// Allowed optimizations for a specific operation.
14enum class Mode : nat_t {
15 top = 0,
16 none = top, ///< Alias for Mode::none.
17 nnan = 1 << 0, ///< No NaNs.
18 ///< Allow optimizations to assume the arguments and result are not NaN.
19 ///< Such optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined.
20 ninf = 1 << 1, ///< No Infs.
21 ///< Allow optimizations to assume the arguments and result are not +/-Inf.
22 ///< Such optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined.
23 nsz = 1 << 2, ///< No Signed Zeros.
24 ///< Allow optimizations to treat the sign of a zero argument or result as insignificant.
25 arcp = 1 << 3, ///< Allow Reciprocal.
26 ///< Allow optimizations to use the reciprocal of an argument rather than perform division.
27 contract = 1 << 4, ///< Allow floating-point contraction
28 ///< (e.g. fusing a multiply followed by an addition into a fused multiply-and-add).
29 afn = 1 << 5, ///< Approximate functions.
30 ///< Allow substitution of approximate calculations for functions (sin, log, sqrt, etc).
31 reassoc = 1 << 6, ///< Allow reassociation transformations for floating-point operations.
32 ///< This may dramatically change results in floating point.
33 finite = nnan | ninf, ///< Mode::nnan `|` Mode::ninf.
34 unsafe = nsz | arcp | reassoc, ///< Mode::nsz `|` Mode::arcp `|` Mode::reassoc
36 | arcp | contract | afn
37 | reassoc, ///< All flags.
38 bot = fast, ///< Alias for Mode::fast.
39};
40// clang-format on
41
42/// Give Mode as mim::plug::math::Mode, mim::nat_t or const Def*.
43using VMode = std::variant<Mode, nat_t, const Def*>;
44
45/// mim::plug::math::VMode -> const Def*.
46inline const Def* mode(World& w, VMode m) {
47 if (auto def = std::get_if<const Def*>(&m)) return *def;
48 if (auto nat = std::get_if<nat_t>(&m)) return w.lit_nat(*nat);
49 return w.lit_nat(std::to_underlying(std::get<Mode>(m)));
50}
51///@}
52
53/// @name math.F
54///@{
55inline std::optional<nat_t> isa_f(const Def* def) {
56 if (auto f_ty = Axm::isa<F>(def)) {
57 if (auto [p, e] = f_ty->arg()->projs<2>([](auto op) { return Lit::isa(op); }); p && e) {
58 if (*p == 10 && e == 5) return 16;
59 if (*p == 23 && e == 8) return 32;
60 if (*p == 52 && e == 11) return 64;
61 }
62 }
63 return {};
64}
65
66// clang-format off
67const Lit* lit_f(World& w, std::floating_point auto val) {
68 if constexpr (sizeof(val) == 2) return w.lit(w.annex<F16>(), std::bit_cast<u16>(val));
69 else if constexpr (sizeof(val) == 4) return w.lit(w.annex<F32>(), std::bit_cast<u32>(val));
70 else if constexpr (sizeof(val) == 8) return w.lit(w.annex<F64>(), std::bit_cast<u64>(val));
71 else std::unreachable();
72}
73
74inline const Lit* lit_f(World& w, nat_t width, mim::f64 val) {
75 switch (width) {
76#if defined(__STDCPP_FLOAT16_T__)
77 case 16: assert(mim::f64(mim::f16(val)) == val && "loosing precision"); return lit_f(w, mim::f16(val));
78#endif
79 case 32: assert(mim::f64(mim::f32(val)) == val && "loosing precision"); return lit_f(w, mim::f32(val));
80 case 64: assert(mim::f64(mim::f64(val)) == val && "loosing precision"); return lit_f(w, mim::f64(val));
81 default: return nullptr;
82 }
83}
84// clang-format on
85///@}
86
87} // namespace mim::plug::math
88
89namespace mim {
90
91/// @name is_commutative/is_associative
92///@{
93// clang-format off
94constexpr bool is_commutative(plug::math::extrema ) { return true; }
96constexpr bool is_commutative(plug::math::cmp id) { return id == plug::math::cmp ::e || id == plug::math::cmp ::ne ; }
97constexpr bool is_associative(plug::math::arith id) { return is_commutative(id); }
98// clang-format on
99///@}
100
101} // namespace mim
102
103#ifndef DOXYGEN
104template<>
105struct fe::is_bit_enum<mim::plug::math::Mode> : std::true_type {};
106#endif
static auto isa(const Def *def)
Definition axm.h:112
Base class for all Defs.
Definition def.h:289
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:43
The math Plugin
Definition math.h:8
Mode
Allowed optimizations for a specific operation.
Definition math.h:14
@ arcp
Allow Reciprocal.
Definition math.h:25
@ fast
All flags.
Definition math.h:35
@ afn
Approximate functions.
Definition math.h:29
@ ninf
No Infs.
Definition math.h:20
@ unsafe
Mode::nsz | Mode::arcp | Mode::reassoc.
Definition math.h:34
@ contract
Allow floating-point contraction (e.g.
Definition math.h:27
@ nsz
No Signed Zeros.
Definition math.h:23
@ nnan
No NaNs.
Definition math.h:17
@ finite
Mode::nnan | Mode::ninf.
Definition math.h:33
@ bot
Alias for Mode::fast.
Definition math.h:38
const Lit * lit_f(World &w, std::floating_point auto val)
Definition math.h:67
std::variant< Mode, nat_t, const Def * > VMode
Give Mode as mim::plug::math::Mode, mim::nat_t or const Def*.
Definition math.h:43
std::optional< nat_t > isa_f(const Def *def)
Definition math.h:55
Definition ast.h:16
u64 nat_t
Definition types.h:37
double f64
Definition types.h:35
constexpr bool is_commutative(Id)
Definition axm.h:171
float f32
Definition types.h:34
constexpr bool is_associative(Id id)
Definition axm.h:177