Possible over-optimization with 'continue return'

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Possible over-optimization with 'continue return'

Chris Angelico
Playing around with generators, and have come across a strange oddity.
This code works fine:

continue int gen(int x)
{
  if (x == 1) continue return 1;
  if (x == 1) continue return 2;
  if (x == 1) continue return 3;
  return 4;
}

int main()
{
  function foo = gen(1);
  while (1) {
    int i = foo();
    if (undefinedp(i)) break;
    write("%d\n", i);
  }
}

But remove any of the 'if' guards, and the function terminates prematurely.

continue int gen(int x)
{
  if (x == 1) continue return 1;
  continue return 2;
  if (x == 1) continue return 3;
  return 4;
}

This will print out 1, 2, 0, and then halt. It appears that perhaps an
unconditional 'continue return' causes subsequent code to be
eliminated as if following a hard 'return' statement?

ChrisA
Reply | Threaded
Open this post in threaded view
|

Possible over-optimization with 'continue return'

Martin Nilsson (Coppermist) @ Pike (-) developers forum
> Playing around with generators, and have come across a strange oddity.
> This code works fine:
[...]

> But remove any of the 'if' guards, and the function terminates prematurely.
>
> continue int gen(int x)
> {
>   if (x == 1) continue return 1;
>   continue return 2;
>   if (x == 1) continue return 3;
>   return 4;
> }
>
> This will print out 1, 2, 0, and then halt. It appears that perhaps an
> unconditional 'continue return' causes subsequent code to be
> eliminated as if following a hard 'return' statement?

Indeed. Looks like it is probably a bug in treeopt, where there's
likely some rule that doesn't know about continue return.

        /grubba
Reply | Threaded
Open this post in threaded view
|

Re: Possible over-optimization with 'continue return'

Chris Angelico
In reply to this post by Chris Angelico
On Sat, Mar 6, 2021 at 7:59 AM Henrik Grubbström (Lysator) @ Pike (-)
developers forum <[hidden email]> wrote:

>
> > Playing around with generators, and have come across a strange oddity.
> > This code works fine:
> [...]
> > But remove any of the 'if' guards, and the function terminates prematurely.
> >
> > continue int gen(int x)
> > {
> >   if (x == 1) continue return 1;
> >   continue return 2;
> >   if (x == 1) continue return 3;
> >   return 4;
> > }
> >
> > This will print out 1, 2, 0, and then halt. It appears that perhaps an
> > unconditional 'continue return' causes subsequent code to be
> > eliminated as if following a hard 'return' statement?
>
> Indeed. Looks like it is probably a bug in treeopt, where there's
> likely some rule that doesn't know about continue return.

Thanks for the pointer! Found it, I think. I've pushed it to the
branch rosuav/deoptimize-continue-return - would appreciate a second
opinion on this!

-F_COMMA_EXPR(0 = F_COMMA_EXPR(*, F_RETURN), +[!($$->tree_info & OPT_CASE)]):
+// Code after a return statement can be eliminated, as long as
+// it's not a 'continue return' statement.
+F_COMMA_EXPR(0 = F_COMMA_EXPR(*, F_RETURN(*,
F_CONSTANT[!($$->u.sval.u.integer)])),
+             +[!($$->tree_info & OPT_CASE)]):
   $0;

ChrisA