On Thu Jun 29 18:26:09 2023 +0000, Giovanni Mascellani wrote:
Generally I prefer the new approach (store the iteration instruction list and then copy it directly before each `continue`) rather than the old one (first generate code without the iteration instructions and then patch it). One of the reasons is that, as you said, it's good that the IR has a well-defined meaning independently of the processing stage. I can't exclude that some details could be refined a little bit, but the current proposal is fine for me.
I don't know if I can describe why in any exact terms, but it doesn't feel as easy to understand to me.
Generally I prefer the new approach (store the iteration instruction list and then copy it directly before each `continue`) rather than the old one (first generate code without the iteration instructions and then patch it). One of the reasons is that, as you said, it's good that the IR has a well-defined meaning independently of the processing stage.
I guess.
It might help if we were to arrange the rules more like
loop_statement: loop_header statement
loop_header: attribute_list_optional KW_FOR '(' scope_start expr_statement expr_statement expr_optional ')'
and then loop_header can essentially call create_loop() as now but without filling the body yet, then loop_statement would take care of moving the "statement" body into the loop instruction. That would also remove the need for "loop_scope_start".
Hmm, but this breaks with do-while...
---
Okay, so a minute later I realize that there's a problem which I think prevents this approach from working in the first place. 'continue' doesn't just need to apply the iterator, it needs to apply the conditional in the case of do-while loops, and we can't know what the conditional is until we've parsed the whole loop. [This is only a concern for do-while; for other loop types the conditional is executed at the head of the loop.] Example shader, sorry it's a bit complex:
``` uint m;
float4 main() : sv_target { float4 f = 0; uint x = 0;
do { if (x % 2 == 0) continue; f += 5; } while (x++ < m);
return f; } ```
compiled with sm4 you can see it increments x on every iteration.
So we either can fix up loops in create_loop(), or we can fix them up in a separate pass. In either case, for the sake of having a consistent meaning, it probably does make sense to have two separate "continue" jump types, though I'm not sure how to name them.