9template<
class Value,
class Type,
class BB,
class Child>
class Emitter :
public ScopePhase {
11 constexpr const Child& child()
const {
return *
static_cast<const Child*
>(
this); }
12 constexpr Child& child() {
return *
static_cast<Child*
>(
this); }
15 Value emit_(
const Def* def) {
18 return child().emit_bb(bb, def);
36 assert(child().is_valid(res));
43 if (
auto i =
locals_.find(def); i !=
locals_.end())
return i->second;
45 auto val = emit_(def);
53 child().emit_imported(
entry_);
61 if (
auto lam = mut->isa<
Lam>())
lam2bb_.emplace(lam, BB());
67 auto fct = child().prepare(
scope);
72 for (
auto mut : muts) {
73 if (
auto lam = mut->isa<
Lam>(); lam && lam !=
scope.
exit()) {
75 child().emit_epilogue(lam);
79 child().finalize(
scope);
81 assert_unused(
lam2bb_.size() == old_size &&
"really make sure we didn't triger a rehash");
bool is_set() const
Yields true if empty or the last op is set.
T * as_mut() const
Asserts that this is a mutable, casts constness away and performs a static_cast to T.
T * isa_mut() const
If this is *mut*able, it will cast constness away and perform a dynamic_cast to T.
Value emit(const Def *def)
Recursively emits code.
void visit(const Scope &scope) override
std::ostream & ostream() const
Value emit_unsafe(const Def *def)
As above but returning !child().is_valid(value) is permitted.
Emitter(World &world, std::string_view name, std::ostream &ostream)
static const Lam * isa_basicblock(Ref d)
Ref ret_var()
Yields the Lam::var of the Lam::ret_pi.
std::string_view name() const
static Schedule schedule(const Scope &)
Transitively visits all reachable Scopes in World that do not have free variables.
const Scope & scope() const
A Scope represents a region of Defs that are live from the view of an entry's Var.
Keeps track of indentation level.
The World represents the whole program and manages creation of MimIR nodes (Defs).
GIDMap< const Def *, To > DefMap
GIDMap< Lam *, To > LamMap