16const Def* merge(
bool term,
const Def* elem,
const Def* prod,
const Def* mem) {
17 auto&
w = elem->world();
18 if (mem)
return w.prod(term,
Def::cat(elem, prod->projs()));
19 return w.prod(term, {elem, prod});
26 log().d(
"lower for: {}", for_ax);
27 auto [old_body, old_exit,
args] = for_ax->uncurry_args<3>();
28 auto [new_begin, new_end, new_step, new_init] =
args->projs<4>([
this](
const Def* def) {
return rewrite(def); });
30 const Def* vec_axm =
nullptr;
32 old_body = ll_vec->arg();
35 old_body = ll_novec->arg();
45 auto new_head_dom = merge(
false, new_begin->type(), new_init->type(), new_mem);
47 auto new_phis = new_head_lam->
vars();
48 auto new_iter = new_phis.front();
61 new_head_lam->branch(
false, new_cmp, new_body, new_exit, new_mem);
62 new_yield->app(
false, new_head_lam, merge(
true, new_inc, new_yield->var(), new_mem));
66 auto acc_for = [&](
Lam* bb) ->
const Def* {
67 if (!new_mem)
return new_acc;
70 for (
auto phi : new_phis.view().subspan(1))
76 map(old_body_lam->var(), {new_iter, acc_for(new_body), new_yield});
77 auto new_body_filter =
rewrite(old_body_lam->filter());
78 auto new_body_value =
rewrite(old_body_lam->body());
79 new_body->set({new_body_filter, new_body_value});
83 map(old_exit_lam->
var(), acc_for(new_exit));
85 auto new_exit_value =
rewrite(old_exit_lam->
body());
86 new_exit->set({new_exit_filter, new_exit_value});
89 return new_world().
app(new_head_lam, merge(
true, new_begin, new_init, new_mem));
static auto isa(const Def *def)
T * isa_mut() const
If this is mutable, it will cast constness away and perform a dynamic_cast to T.
static DefVec cat(Defs a, Defs b)
const Def * var(nat_t a, nat_t i) noexcept
auto vars(Projector auto f) noexcept
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
const Var * has_var()
Only returns not nullptr, if Var of this mutable has ever been created.
const Def * filter() const
Lam * set(Filter filter, const Def *body)
static Lam * eta_expand(Filter, const Def *f)
const fe::Log & log() const
const fe::Vector< std::string > & args()
Command-line arguments passed to this Phase's plugin via -X <plugin>:<arg>.
World & new_world()
Create new Defs into this.
World & old_world()
Get old Defs from here.
const Def * rewrite_imm_App(const App *) override
const Def * map(const Def *old_def, const Def *new_def)
virtual const Def * rewrite(const Def *)
void push(Vars old_vars={}, Vars new_vars={})
const Def * call(const Def *callee, auto &&arg, Args &&... args)
const Def * sigma(Defs ops)
const Def * app(const Def *callee, const Def *arg)
const Def * tuple(Defs ops)
Lam * mut_con(const Def *dom)
const Def * rewrite_imm_App(const App *) final
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.
fe::View< const Def * > Defs
fe::Vector< const Def * > DefVec
fe::Patricia< const Var, DefKey >::Set Vars