-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Direct2CPS Scheduling/Calling Problem #141
Comments
Current branch: https://github.com/NeuralCoder3/thorin2/tree/direct_fix |
The issue was that nested lambda rewrites overwrote the current lambda screwing up the call trace. The solution is to explicitly handle lambdas and to manage a meta call stack. Note: There is still a case where either
This issue might be related to scheduling. |
I had similar probls when implementing SSAConstr, CopyProp, etc. To me the problem seems to be that you just shouldn't rewrite the body. What you should do instead is a reduction of the nominal in question and replace everything with the desired Defs up front. if (auto app = def->isa<App>()) {
if (auto callee = app->callee()->isa_nominal<Lam>()) {
map[some_old_value] = some_new_value;
// and do sth later on with map
}
} You should do it like this: if (auto app = def->isa<App>()) {
if (auto callee = app->callee()->isa_nominal<Lam>()) {
auto new_ops = callee->reduce(/*my_new_args*/);
// ...
}
} |
The current issue does not happen in the original pass. Instead, partial evaluation inlines functions and causes an issue to surface. Simplified .con .extern main __690558::[mem_690876: %mem.M, argc_691342: .Idx 4294967296, %mem.Ptr (%mem.Ptr (.Idx 256, 0), 0), return_690562: .Cn [%mem.M, .Idx 4294967296]] @(0:(.Idx 2)) = {
.let A: [.Idx 4294967296, .Cn [.Idx 4294967296, .Cn «2; .Idx 4294967296»]] = %direct.cps2ds_dep («2; .Idx 4294967296», Uf_691251) eta_inner_mul_deriv_cps_691294 (42:(.Idx 4294967296), argc_691342);
// ^
.con comp_tup_pb__691250 _691347::[_691349: .Idx 4294967296, _691358: .Cn [%mem.M, .Idx 4294967296]] @(1:(.Idx 2)) = {
A:(.Idx 2) (_691349, comp_tup_pb__cont_691356)
};
.let B: %mem.M = f(A);
.let C: [%mem.M, .Idx 4294967296] = f(B);
.let D: [%mem.M, .Cn [.Idx 4294967296, .Cn [%mem.M, .Idx 4294967296]]] = f(C);
.con comp_tup_pb__690636 _691889::[_691891: .Idx 4294967296, _691894: .Cn [%mem.M, .Idx 4294967296]] @(1:(.Idx 2)) = {
.con comp_tup_pb__cont_691892 _691940::[_691941: .Idx 4294967296, _692020: .Idx 4294967296] @(1:(.Idx 2)) = {
.let _691942: [%mem.M, .Idx 4294967296] = %direct.cps2ds_dep (.Idx 4294967296, Uf_691899) zero_pb_691934 _691941;
.let _692021: [%mem.M, .Idx 4294967296] = %direct.cps2ds_dep (.Idx 4294967296, Uf_691949) D _692020;
.let _692028: .Idx 4294967296 = %core.wrap.add 4294967296 0 (_691942#1:(.Idx 2), _692021#1:(.Idx 2));
_691894 (⊤:%mem.M, _692028)
};
.let E: [.Idx 4294967296, .Cn [.Idx 4294967296, .Cn «2; .Idx 4294967296»]] = %direct.cps2ds_dep («2; .Idx 4294967296», Uf_690659) eta_inner_mul_deriv_cps_690710 (100:(.Idx 4294967296), C:(.Idx 2));
E:(.Idx 2) (_691891, comp_tup_pb__cont_691892)
};
.let _692035: [%mem.M, .Idx 4294967296] = %direct.cps2ds_dep (.Idx 4294967296, Uf_690595) comp_tup_pb__690636 1:(.Idx 4294967296);
.let _692095: [%mem.M, .Idx 4294967296] = %direct.cps2ds_dep (%mem.M, Uf_692052) zero_pb_692087 D:(.Idx 2);
.let _692102: .Idx 4294967296 = %core.wrap.add 4294967296 0 (_692035#1:(.Idx 2), _692095#1:(.Idx 2));
return_690562 (⊤:%mem.M, _692102)
}; The underlying problem seems to be that a function (A) is cps2ds called in main before others but the iteration first inlines other calls (bottom) because the first call is not directly used as an argument. The functions are not correctly inlined/rewritten as cps in such complex circumstances. |
Current work in branch direct_scheduling. To recap: The general idea of the translation is to generate a cps call and use the argument res = cps2ds fun args
... becomes fun(args, fun_cps_cont)
.cn fun_cps_cont [res] = {
...
} However, this procedure becomes problematic in more complex situations (e.g. lit/direct/ad_mem2) One kind of problem: {
a = cps2ds f1 x
}
b = cps2ds f2 y If We possibly need to first call a function found later on in an outer scope. One Idea: Previous Translation:
h:
b = f a
C[b] => h:
f'(a,h_cont)
h_cont(b):
C[b]
f : A -> B
f': .Cn [A, ret: .Cn[B]] Idea: Problem: Attempt:
Possibly, a good enough place for the calls might be enough: We want the place the call so low (depth large) Linked to the depth is the call nesting. The open question is how to find this place. Can the scope do this for us? If so, how (for which def) do I compute this place? |
I think we should discuss this online in our next meeting. I've difficulties following you here. |
The direct2cps dialect has a bug as demonstrated in
https://github.com/NeuralCoder3/thorin2/blob/test/direct_old_var/lit/direct/ad_mem.thorin.disabled
The bug manifests in the test case only in complex circumstances.
Two
cps2ds
calls are used with functions that containcps2ds
where a function is created that is called.Removing some of the complexity resolves the bug.
The dialect rewrites the function but only introduces new lambdas for the continuations.
To do so, the body of the old functions is replaced.
Therefore, the origin of the bug is unclear.
The text was updated successfully, but these errors were encountered: