28 auto [m, v] = w.call(
op,
Defs{mem_, w.tuple({x, c})})->projs<2>();
55 fe::throwf(
"`affine.op.mul` should have been rewritten to `affine.semiop.mul` and then to `core.mul`");
65 fe::throwf(
"`affine.semiop.mul` called with non-constant second argument");
86 auto strides = [&](
const Def* s,
size_t n) {
88 if (n) str[n - 1] = w.lit_nat(1);
89 for (
size_t k = n - 1; k-- != 0;)
91 for (
size_t k = 0; k != n; ++k)
99 auto xs = idxs->projs();
100 auto str = strides(s, xs.size());
101 const Def* lin = w.lit(w.type_i64(), 0);
102 for (
size_t k = 0; k != xs.size(); ++k) {
112 auto m = s->num_projs();
113 auto str = strides(s, m);
114 return w.tuple(
DefVec(m, [&](
size_t d) {
125 auto [mn, sinout, f, idxs, _] = app->
callee()->as<
App>()->uncurry_args<5>();
126 auto [sin, sout] = sinout->projs<2>();
128 auto __ = fe::Restore(mem_);
131 auto lifted = w.tuple(
DefVec(ins.size(), [&](
size_t i) { return w.call(core::conv::u, w.lit_i64(), ins[i]); }));
132 auto f_lam = f->isa_mut<
Lam>();
134 Lam* idx_map_lam =
nullptr;
135 Lam* rw_idx_lam =
nullptr;
136 if (
auto idx_lam =
lookup(f_lam)) {
137 if (
auto idx_lam_mut = idx_lam->isa_mut<
Lam>();
138 idx_lam_mut && idx_lam_mut->
num_vars() == 2 && idx_lam_mut->var(0)->type() ==
mem->type())
140 idx_map_lam = idx_lam->as_mut<
Lam>();
146 auto lam_pi =
rewrite(f_lam->type())->as<
Pi>();
148 idx_map_lam = w.mut_lam(w.pi({mem->type(), lam_pi->dom()}, {mem->type(), lam_pi->codom()}));
149 map(f_lam, idx_map_lam);
152 map(f_lam->var(), idx_map_lam->
var(1));
153 for (
size_t i = 0; i != f_lam->num_vars(); ++i)
154 map(f_lam->var(i), idx_map_lam->
var(1)->
proj(f_lam->num_vars(), i));
155 mem_ = idx_map_lam->
var(0);
157 auto get_body = [&]() ->
const Def* {
158 if (rw_idx_lam)
return rw_idx_lam->
reduce_body(idx_map_lam->
var(1));
161 idx_map_lam->
set(
true, w.tuple({mem_, get_body()}))->
set(f_lam->dbg_key());
165 auto outs = w.app(idx_map_lam, {
mem, lifted});
168 auto narrowed = w.tuple(
DefVec(sout_n->num_projs(), [&](
size_t j) {
169 return w.call(core::conv::u, sout_n->proj(j), outs->proj(2, 1)->proj(j));
172 return w.tuple({outs->proj(0), narrowed});
175 return RWPhase::rewrite_imm_App(app);
const Def * proj(nat_t a, nat_t i) const
Similar to World::extract while assuming an arity of a, but also works on Sigmas and Arrays.