r->score += 1 << (loop_depth * 3);
until variables in 11 deep loops go undefined?
Not undefined, but spilled. First *oops*, but second of course this all not final. I did change scoring several times from the code base AFAIK Angel Faus did implement. And we don't currently have any code that goes near that omplexity of such a deep nested loop.
There are probably a *lot* of such gotchas in the whole CFG code in imcc. I'm currently on some failing perl6 tests, when using optimization, all in regexen tests, which do a lot of branching.
I'm not sure how to patch this specific instance - just trap loop depths over
10? Should score be unsigned?
A linear counting of loop_depth will do it, e.g.
r->score += 100 * loop_depth ;
Or score deeper nested loops vars always higher then outside, or ...
More importantly, how do we trap these sort of things in the general case?
With a lot of tests
I wonder how hard it would be to make a --fsummon-nasal-demons flag for gcc that added trap code for all classes of undefined behaviour, and caused code to abort (or something more colourfully "undefined") if anything undefined gets executed. I realise that code would run very slowly, but it would be a very very useful debugging tool.
I'm currently adding asserts to e.g. loop detection code. Last one (to be checked in) is:
/* we could also take the depth of the first contained * block, but below is a check, that an inner loop is fully * contained in an outer loop */
This is a check, that all blocks of a deeper nested loop are contained totally in the outer loop, so that there can't be basic blocks outside. But in regex code, this seems not to be true - or a prior stage of optimization messes things up.
This issues are as hard to debug as deeply buried in ~400 basic blocks with ~1000 edges connecting those.
perl6 $ ../imcc/imcc -O1 -d70 t/rx/basic_2.imc 2>&1 | less
Nicholas Clark
leo