21 return w.mut_con({w.call<
M>(0), dom});
30 if (pi->
num_doms() == 0)
return false;
40 if (def->isa<
Arr>() || def->
type()->isa<
Arr>())
return {};
43 for (
auto proj : def->
projs())
56 if (
auto sigma = type->isa<
Sigma>())
57 return std::ranges::any_of(sigma->ops(), [](
const Def* op) { return Axm::isa<mem::M>(op); });
63 auto& world = def->
world();
65 if (
auto sigma = def->isa<
Sigma>()) {
67 for (
auto op : sigma->ops())
68 if (
auto new_op =
strip_mem_ty(op); new_op != world.sigma()) new_ops.push_back(new_op);
70 return world.sigma(new_ops);
93 return w.app(w.app(w.annex<
lea>(), {pointee->arity(), Ts, addr_space}), {ptr, index});
98 auto n =
tuple->num_projs();
100 for (
size_t i = 0; i != n; ++i)
109 World& w = type->world();
110 return w.app(w.app(w.annex<
alloc>(), {type, as}),
mem);
120 World& w = type->world();
121 return w.app(w.app(w.annex<
slot>(), {type, as}), {mem, ret});
128 auto [
mem, ret] =
slot->args<2>();
129 if (
auto ret_lam = ret->isa_mut<
Lam>())
return {
mem, ret_lam, ret_lam->var(2, 0), ret_lam->var(2, 1)};
130 return {
mem,
nullptr,
nullptr,
nullptr};
138 World& w = type->world();
140 return w.app(w.app(w.annex<
malloc>(), {type, as}), {mem, size});
149 World& w = type->world();
151 return w.app(w.app(w.annex<
mslot>(), {type, as}), {w.tuple({mem, size}), 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(Projector auto 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.
nat_t num_doms() const noexcept
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)
Lam * mut_con(World &w, nat_t a=0)
Yields con[mem.M 0].
bool has_mem_ty(const Def *type)
Is type mem.M or a Sigma with a mem.M component?
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_lea_tuple(const Def *ptr, const Def *tuple)
Successively offsets ptr by each component of the index tuple, peeling one array dimension per mem....
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)
const Def * tuple_of_types(const Def *t)
fe::Vector< const Def * > DefVec