21 return w.mut_con({w.annex<
M>(), dom});
26 if (match<mem::M>(def->
type()))
return def;
27 if (def->
type()->isa<
Arr>())
return {};
30 for (
auto proj : def->
projs())
44 auto& w =
mem->world();
45 return w.tuple(
DefVec(arg->
num_projs(), [&](
auto i) { return replace_mem(mem, arg->proj(i)); }));
48 if (match<mem::M>(arg->
type()))
return mem;
55 auto& world = def->
world();
57 if (
auto sigma = def->isa<
Sigma>()) {
59 for (
auto op : sigma->ops())
60 if (
auto new_op =
strip_mem_ty(op); new_op != world.sigma()) new_ops.push_back(new_op);
62 return world.sigma(new_ops);
63 }
else if (match<mem::M>(def)) {
73 auto& world = def->
world();
75 if (
auto tuple = def->isa<
Tuple>()) {
77 for (
auto op : tuple->ops())
78 if (
auto new_op =
strip_mem(op); new_op != world.tuple()) new_ops.push_back(new_op);
80 return world.tuple(new_ops);
81 }
else if (match<mem::M>(def->
type())) {
83 }
else if (
auto extract = def->isa<
Extract>()) {
85 if (extract->num_projs() == 1)
return extract;
88 for (
auto op : extract->projs())
89 if (
auto new_op =
strip_mem(op); new_op != world.tuple()) new_ops.push_back(new_op);
91 return world.tuple(new_ops);
113 auto [pointee, addr_space] = force<Ptr>(ptr->
type())->args<2>();
115 return w.app(w.app(w.annex<
lea>(), {pointee->arity(), Ts, addr_space}), {ptr, index});
130 return w.app(w.annex<
remem>(),
mem);
138 return w.app(w.app(w.annex<
alloc>(), {type, w.lit_nat_0()}),
mem);
146 return w.app(w.app(w.annex<
slot>(), {type, w.lit_nat_0()}), {mem, w.lit_nat(w.curr_gid())});
155 return w.app(w.app(w.annex<
malloc>(), {type, w.lit_nat_0()}), {mem, size});
164 return w.app(w.app(w.annex<
mslot>(), {type, w.lit_nat_0()}), {mem, size, id});
A (possibly paramterized) Array.
auto projs(F f) const
Splits this Def via Def::projections into an Array (if A == -1_n) or std::array (otherwise).
Ref var(nat_t a, nat_t i)
const Def * type() const
Yields the raw type of this Def, i.e. maybe nullptr.
nat_t num_projs() const
Yields Def::as_lit_arity(), if it is in fact a Lit, or 1 otherwise.
Helper class to retrieve Infer::arg if present.
Data constructor for a Sigma.
The World represents the whole program and manages creation of Thorin nodes (Defs).
Ref mem_def(Ref def)
Returns the (first) element of type mem::M from the given tuple.
Ref op_lea_unsafe(Ref ptr, Ref i)
Ref op_alloc(Ref type, Ref mem)
Ref mem_var(Lam *lam)
Returns the memory argument of a function if it has one.
Ref op_lea(Ref ptr, Ref index)
Ref op_slot(Ref type, Ref mem)
Ref strip_mem(Ref def)
Recursively removes all occurrences of mem from a tuple.
Ref op_malloc(Ref type, Ref mem)
Ref op_mslot(Ref type, Ref mem, Ref id)
Ref strip_mem_ty(Ref def)
Removes recusively all occurences of mem from a type (sigma).
Lam * mut_con(World &w)
Yields .con[mem.M].
Ref replace_mem(Ref mem, Ref arg)
Swaps the memory occurrences in the given def with the given memory.
Ref tuple_of_types(Ref t)
Vector< const Def * > DefVec