View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||
---|---|---|---|---|---|---|---|---|---|
0000539 | mercury | Bug | public | 2021-10-11 12:56 | 2021-10-14 13:17 | ||||
Reporter | wangp | ||||||||
Assigned To | zs | ||||||||
Priority | normal | Severity | minor | Reproducibility | always | ||||
Status | resolved | Resolution | fixed | ||||||
Product Version | |||||||||
Target Version | Fixed in Version | ||||||||
Summary | 0000539: placing nondummy var which has no state (LCMC) | ||||||||
Description | The compiler aborts during code generation in low-level C grades when LCMC is enabled. (There are other similar bug reports involving debugging or parallel conjunction which may or may not be related.) % mmc -s asm_fast.gc --optimise-constructor-last-call -C soupy Uncaught Mercury exception: Software Error: predicate `ll_backend.var_locn.actually_place_var'/6: Unexpected: placing nondummy var 6 which has no state Stack dump follows: 0 pred exception.throw/1-0 (erroneous) (exception.m:313) 1 pred require.error/1-0 (erroneous) (require.m:172) 2 pred require.unexpected/2-0 (erroneous) (require.m:203) 3 pred ll_backend.var_locn.actually_place_var/6-0 (det) (var_locn.m:1807) 4 pred ll_backend.var_locn.var_locn_place_var/5-0 (det) (var_locn.m:1706) 5 pred ll_backend.var_locn.actually_place_vars/4-0 (det) (var_locn.m:1730) 6 pred ll_backend.var_locn.var_locn_place_vars/4-0 (det) (var_locn.m:1722) 7 pred ll_backend.code_loc_dep.setup_call/7-0 (det) (code_loc_dep.m:3325) | ||||||||
Tags | No tags attached. | ||||||||
Attached Files |
|
Notes | |
zs (developer) 2021-10-12 02:14 |
I have diagnosed the source of the problem, and outlined two possible approaches to a fix, in the version of this test case I added to the test suite as tests/valid/bug539.m. The bug is solely in lco.m, which sets a buried mine; the code generator, which is where the abort occurs, merely steps on it. |
wangp (developer) 2021-10-12 11:46 |
Thanks for looking into it. Of the two proposed solutions, I favour the second. I don't see a reason why lco.m should be replacing the non-self-recursive call to type_check/2 with the lco-optimised version in the first place. |
zs (developer) 2021-10-12 18:53 |
The reason why lco.m replaces the call to type_check in fun_type is that these two predicates are mutually recursive, i.e. they are in the same SCC. If we restricted lco.m to optimize only self-recursive tail calls, lco couldn't generate code for mutually recursive predicates that could handle unlimited input sizes in constant stack space. lco.m should avoid transforming that call to type_check in fun_type NOT because the call is not SELF-recursive, but because it is not TAIL recursive (in the lco sense, i.e. modulo constructors). A call that is a tail call in this sense *cannot* be followed by consumers of the original output variable, which is the cause of the compiler abort. |
zs (developer) 2021-10-14 13:17 |
Fix committed 2021 oct 13. |
Issue History | |||
Date Modified | Username | Field | Change |
---|---|---|---|
2021-10-11 12:56 | wangp | New Issue | |
2021-10-11 12:56 | wangp | File Added: soupy.m | |
2021-10-12 02:14 | zs | Note Added: 0001152 | |
2021-10-12 11:46 | wangp | Note Added: 0001153 | |
2021-10-12 18:53 | zs | Note Added: 0001154 | |
2021-10-14 13:17 | zs | Assigned To | => zs |
2021-10-14 13:17 | zs | Status | new => resolved |
2021-10-14 13:17 | zs | Resolution | open => fixed |
2021-10-14 13:17 | zs | Note Added: 0001155 |