15void CPS2DS::rewrite_lam(
Lam* lam) {
16 if (
auto [_, ins] = rewritten_lams.emplace(lam); !ins)
return;
19 world().DLOG(
"skipped {}", lam);
23 world().DLOG(
"Rewrite lam: {}", lam->
sym());
25 lam_stack.push_back(curr_lam_);
28 auto new_f = rewrite_body(curr_lam_->
filter());
29 auto new_b = rewrite_body(curr_lam_->
body());
31 world().DLOG(
"Result of rewrite {} in {}", lam, curr_lam_);
33 curr_lam_->
unset()->
set({new_f, new_b});
34 curr_lam_ = lam_stack.back();
38const Def* CPS2DS::rewrite_body(
const Def* def) {
39 if (!def)
return nullptr;
40 if (
auto i = rewritten_.find(def); i != rewritten_.end())
return i->second;
41 auto new_def = rewrite_body_(def);
42 rewritten_[def] = new_def;
43 return rewritten_[def];
46const Def* CPS2DS::rewrite_body_(
const Def* def) {
47 if (
auto app = def->isa<App>()) {
48 auto callee = app->callee();
49 auto arg = app->arg();
50 auto new_callee = rewrite_body(callee);
51 auto new_arg = rewrite_body(arg);
54 world().DLOG(
"rewrite callee {} : {}", callee, callee->type());
55 world().DLOG(
"rewrite arg {} : {}", arg, arg->type());
57 auto cps_fun =
cps2ds->arg();
58 cps_fun = rewrite_body(cps_fun);
59 world().DLOG(
"function: {} : {}", cps_fun, cps_fun->type());
82 auto ty = callee->
type();
83 auto ret_ty = ty->as<
Pi>()->codom();
84 world().DLOG(
"callee {} : {}", callee, ty);
85 world().DLOG(
"new arguments {} : {}", new_arg, new_arg->type());
86 world().DLOG(
"ret_ty {}", ret_ty);
88 auto inst_ret_ty = ret_ty;
89 if (
auto pi = ty->isa_mut<Pi>()) inst_ret_ty = pi->reduce(new_arg).back();
94 rewritten_lams.insert(fun_cont);
97 auto cps_call =
world().
app(cps_fun, {new_arg, fun_cont})->set(
"cps_call");
98 world().DLOG(
" curr_lam {}", curr_lam_->
sym());
100 auto filter = curr_lam_->
filter();
101 curr_lam_->
reset({filter, cps_call});
103 curr_lam_->
set(
world().lit_ff(), cps_call);
115 curr_lam_ = fun_cont;
117 auto res = fun_cont->
var();
119 world().DLOG(
" result {} : {} instead of {} : {}", res, res->type(), def, def->type());
123 return world().
app(new_callee, new_arg);
126 if (
auto lam = def->isa_mut<Lam>()) {
131 if (def->isa<
Var>())
return def;
132 if (def->isa<Global>())
return def;
134 if (
auto tuple = def->isa<Tuple>()) {
135 auto elements =
DefVec(tuple->ops(), [&](
const Def* op) { return rewrite_body(op); });
136 return world().
tuple(def->type(), elements)->
set(tuple->dbg());
142 if (
auto old_mut = def->isa_mut()) {
143 auto new_type = rewrite_body(old_mut->type());
144 auto new_mut = old_mut->stub(new_type);
145 rewritten_[old_mut] = new_mut;
146 if (
auto var = old_mut->has_var()) rewritten_[var] = new_mut->var();
147 auto new_ops =
DefVec(def->ops(), [&](
const Def* op) { return rewrite_body(op); });
148 new_mut->set(new_ops);
150 if (
auto imm = new_mut->immutabilize())
return rewritten_[old_mut] = imm;
154 auto new_ops =
DefVec(def->ops(), [&](
const Def* op) { return rewrite_body(op); });
155 world().DLOG(
"def {} : {} [{}]", def, def->type(), def->node_name());
157 if (def->isa<
Infer>()) {
158 world().WLOG(
"infer node {} : {} [{}]", def, def->type(), def->node_name());
162 return def->rebuild(def->type(), new_ops);
bool is_set() const
Yields true if empty or the last op is set.
Def * set(size_t i, const Def *def)
Successively set from left to right.
Ref var(nat_t a, nat_t i)
const T * isa_imm() const
Def * reset(size_t i, const Def *def)
Successively reset from left to right.
Lam * set(Filter filter, const Def *body)
Ref app(Ref callee, Ref arg)
Sym append_suffix(Sym name, std::string suffix)
Appends a suffix or an increasing number if the suffix already exists.
const Type * type(Ref level)
void enter() override
Invoked just before Pass::rewriteing PassMan::curr_mut's body.
Vector< const Def * > DefVec