10template<
class Value,
class Type,
class BB,
class Child>
class Emitter :
public NestPhase<Lam> {
12 constexpr const Child& child()
const {
return *
static_cast<const Child*
>(
this); }
13 constexpr Child& child() {
return *
static_cast<Child*
>(
this); }
16 Value emit_(
const Def* def) {
19 return child().emit_bb(bb, def);
37 assert(child().is_valid(res));
44 if (
auto i =
locals_.find(def); i !=
locals_.end())
return i->second;
46 auto val = emit_(def);
51 if (!
root()->is_set()) {
52 child().emit_imported(
root());
60 if (
auto lam = mut->isa<
Lam>())
lam2bb_.emplace(lam, BB());
63 assert(
root()->ret_var());
65 auto fct = child().prepare();
70 for (
auto mut : muts) {
71 if (
auto lam = mut->isa<
Lam>()) {
74 child().emit_epilogue(lam);
80 assert_unused(
lam2bb_.size() == old_size &&
"really make sure we didn't triger a rehash");
Value emit(const Def *def)
Recursively emits code.
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)
void visit(const Nest &nest) override
static const Lam * isa_basicblock(Ref d)
Like ClosedMutPhase but computes a Nest for each NestPhase::visit.
const Nest & nest() const
Builds a nesting tree of all immutables‍/binders.
std::string_view name() const
const Nest::Node * smart(Def *curr, const Def *)
static Schedule schedule(const Nest &)
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