MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
eta_exp.h
Go to the documentation of this file.
1#pragma once
2
3#include "mim/pass/pass.h"
4
5namespace mim {
6
7class EtaRed;
8
9/// Performs η-expansion:
10/// `f -> λx.f x`, if `f` is a Lam with more than one user and does not appear in callee position.
11/// This rule is a generalization of critical edge elimination.
12/// It gives other Pass%es such as SSAConstr the opportunity to change `f`'s signature (e.g. adding or removingp Var%s).
13class EtaExp : public FPPass<EtaExp, Lam> {
14public:
16 : FPPass(man, "eta_exp")
17 , eta_red_(eta_red) {}
18
19 /// @name interface for other passes
20 ///@{
21 const Proxy* proxy(Lam* lam) { return FPPass<EtaExp, Lam>::proxy(lam->type(), {lam}, 0); }
22 void new2old(Lam* new_lam, Lam* old_lam) { new2old_[new_lam] = old_lam; }
23 Lam* new2old(Lam* new_lam);
24 ///@}
25
26 /// @name Lattice
27 /// EtaExp uses the following lattice:
28 /// ```
29 /// expand_ <-- η-expand non-callee as the Lam occurs more than once.
30 /// / \ Don't η-reduce the expansion again.
31 /// Callee Non_Callee_1 <-- Pos: Either multiple callees, **or** exactly one non-callee are okay.
32 /// \ /
33 /// Bot <-- Never seen.
34 /// ```
35 /// * EtaExp::expand_ trackes if a Lam is the top element.
36 /// * If it's not within EtaExp::expand_, it's either `Pos` or `Bot`.
37 /// But there is no need to differentiate this any further.
38 /// * EtaExp::Pos tracks the particular element at that level and is memorized statefully.
39 ///@{
40 enum Pos : bool { Callee, Non_Callee_1 };
41 static std::string_view pos2str(Pos pos) { return pos == Callee ? "Callee" : "Non_Callee_1"; }
42
43 using Data = std::tuple<Def2Def, LamMap<Pos>>;
44 auto& old2new() { return data<0>(); }
45 auto& pos() { return data<1>(); }
46 ///@}
47
48private:
49 /// @name PassMan hooks
50 ///@{
51 Ref rewrite(Ref) override;
52 undo_t analyze(const Proxy*) override;
53 undo_t analyze(Ref) override;
54 ///@}
55 Lam* eta_exp(Lam*); ///< Helper that peforms the actual η-expansion.
56
57 EtaRed* eta_red_;
58 LamSet expand_;
59 Lam2Lam exp2orig_;
60 Lam2Lam new2old_;
61 DefMap<DefVec> def2new_ops_;
62};
63
64} // namespace mim
Performs η-expansion: f -> λx.f x, if f is a Lam with more than one user and does not appear in calle...
Definition eta_exp.h:13
Ref rewrite(Ref) override
Definition eta_exp.cpp:20
void new2old(Lam *new_lam, Lam *old_lam)
Definition eta_exp.h:22
undo_t analyze(const Proxy *) override
Definition eta_exp.cpp:53
@ Non_Callee_1
Definition eta_exp.h:40
static std::string_view pos2str(Pos pos)
Definition eta_exp.h:41
auto & old2new()
Definition eta_exp.h:44
const Proxy * proxy(Lam *lam)
Definition eta_exp.h:21
EtaExp(PassMan &man, EtaRed *eta_red)
Definition eta_exp.h:15
std::tuple< Def2Def, LamMap< Pos > > Data
Definition eta_exp.h:43
auto & pos()
Definition eta_exp.h:45
Performs η-reduction.
Definition eta_red.h:9
Inherit from this class using CRTP, if you do need a Pass with a state and a fixed-point.
Definition pass.h:242
A function.
Definition lam.h:103
const Pi * type() const
Definition lam.h:115
An optimizer that combines several optimizations in an optimal way.
Definition pass.h:107
PassMan & man()
Definition pass.h:30
const Proxy * proxy(Ref type, Defs ops, u32 tag=0)
Definition pass.h:75
Helper class to retrieve Infer::arg if present.
Definition def.h:86
Definition cfg.h:11
GIDSet< Lam * > LamSet
Definition lam.h:200
GIDMap< const Def *, To > DefMap
Definition def.h:58
LamMap< Lam * > Lam2Lam
Definition lam.h:201
size_t undo_t
Definition pass.h:14