21 return w.mut_con({w.call<
M>(0), dom});
34 if (pi->num_doms() == 0)
return false;
35 auto dom0 = pi->
dom(0uz);
44 if (def->
type()->isa<
Arr>())
return {};
47 for (
auto proj : def->
projs())
59 auto& world = def->
world();
61 if (
auto sigma = def->isa<
Sigma>()) {
63 for (
auto op : sigma->ops())
64 if (
auto new_op =
strip_mem_ty(op); new_op != world.sigma()) new_ops.push_back(new_op);
66 return world.sigma(new_ops);
77 auto& world = def->
world();
81 for (
auto op :
tuple->ops())
82 if (
auto new_op =
strip_mem(op); new_op != world.tuple()) new_ops.push_back(new_op);
84 return world.tuple(new_ops);
87 }
else if (
auto extract = def->isa<
Extract>()) {
89 if (extract->num_projs() == 1)
return extract;
92 for (
auto op : extract->projs())
93 if (
auto new_op =
strip_mem(op); new_op != world.tuple()) new_ops.push_back(new_op);
95 return world.tuple(new_ops);
116 return w.app(w.app(w.annex<
lea>(), {pointee->arity(), Ts, addr_space}), {ptr, index});
130 World& w = type->world();
131 return w.app(w.app(w.annex<
alloc>(), {type, as}),
mem);
141 World& w = type->world();
142 return w.app(w.app(w.annex<
slot>(), {type, as}), {mem, ret});
145 return op_slot(type, type->world().lit_nat_0(),
mem, ret);
151 auto [
mem, ret] =
slot->args<2>();
152 auto ret_lam = ret->isa_mut<
Lam>();
153 return {
mem, ret_lam, ret_lam->var(2, 0), ret_lam->var(2, 1)};
161 World& w = type->world();
163 return w.app(w.app(w.annex<
malloc>(), {type, as}), {mem, size});
173 World& w = type->world();
175 return w.app(w.app(w.annex<
mslot>(), {type, as}), {w.tuple({mem, size}), ret});
178 return op_mslot(type, type->world().lit_nat_0(),
mem, ret);
A (possibly paramterized) Array.
static auto isa(const Def *def)
static auto as(const Def *def)
World & world() const noexcept
const Def * var(nat_t a, nat_t i) noexcept
auto projs(F f) const
Splits this Def via Def::projections into an Array (if A == std::dynamic_extent) or std::array (other...
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
nat_t num_projs() const
Yields Def::arity(), if it is a Lit, or 1 otherwise.
constexpr size_t num_ops() const noexcept
A dependent function type.
Data constructor for a Sigma.
The World represents the whole program and manages creation of MimIR nodes (Defs).
bool has_leading_mem(const Pi *pi)
Does pi already thread memory - a leading mem.M, either directly or grouped as the first component of...
const Def * mem_var(Lam *lam)
Returns the memory argument of a function if it has one.
const Def * mem_def(const Def *def)
Returns the (first) element of type mem.M a from the given tuple.
const Def * strip_mem_ty(const Def *def)
Removes recusively all occurences of mem from a type (sigma).
const Def * op_lea(const Def *ptr, const Def *index)
const Def * op_mslot(const Def *type, const Def *as, const Def *mem, const Def *ret)
const Def * op_lea_unsafe(const Def *ptr, const Def *i)
Lam * mut_con(World &w, nat_t a=0)
Yields con[mem.M 0].
const Def * strip_mem(const Def *def)
Recursively removes all occurrences of mem from a tuple.
const Def * op_alloc(const Def *type, const Def *as, const Def *mem)
const App * isa_mem(const Def *def)
If def is a mem.M-typed value, yields its memory type mem.M a; otherwise nullptr.
std::tuple< const Def *, Lam *, const Def *, const Def * > split_slot(const App *slot)
Decomposes the continuation-based slot into (mem, ret_lam, ret_mem, ptr), where ret_mem is the contin...
const Def * pointee(const Def *ptr)
const Def * op_slot(const Def *type, const Def *as, const Def *mem, const Def *ret)
const Def * op_malloc(const Def *type, const Def *as, const Def *mem)
Vector< const Def * > DefVec
const Def * tuple_of_types(const Def *t)