Skip to content
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

Generalize optimization of "one-armed" cases #1528

Merged

Conversation

bjorng
Copy link
Contributor

@bjorng bjorng commented Aug 9, 2017

In general, a 'case' expression will force a stack frame.

However, for an one-armed 'case':

  case Expr of
     Pat1 ->
       DoSomething;
     Pat2 ->
       erlang:error(bad)
  end.

at the end of a function there is no need to allocate a
stack frame

In sys_core_fold there is an optimization that takes advantage
of this by rewriting code such as:

  case Expr of
     Pat1 ->
       DoSomething;
     Pat2 ->
       erlang:error(bad)
  end,
  MoreCode.

to:

  case Expr of
     Pat1 ->
       DoSomething,
       MoreCode;
     Pat2 ->
       erlang:error(bad)
  end.

However, that optimization would not be applied if there
were more than one failing clause such as in this code:

  case Expr of
     Pat1 ->
       DoSomething,
       MoreCode;
     Pat2 ->
       erlang:error(bad);
     _ ->
       erlang:error(case_clause)
  end.

Generalize the optimization to handle any number of failing
clauses at the end of the case.

Reported-by: bugs.erlang.org/browse/ERL-452

@bjorng bjorng added enhancement team:VM Assigned to OTP team VM labels Aug 9, 2017
@bjorng bjorng self-assigned this Aug 9, 2017
A 'case' expression will force a stack frame (essentially in the same
way as a function call), unless it is at the end of a function.

In sys_core_fold there is an optimization that can optimize one-armed
cases such as:

  case Expr of
     Pat1 ->
       DoSomething;
     Pat2 ->
       erlang:error(bad)
  end,
  MoreCode.

Because only one arm of the 'case' can succeed, the code after the
case can be move into the successful arm:

  case Expr of
     Pat1 ->
       DoSomething,
       MoreCode;
     Pat2 ->
       erlang:error(bad)
  end.

Thus, the 'case' is at the end of the function and it will no longer
need a stack frame.

However, the optimization in sys_core_fold would not be applied if
there were more than one failing clause such as in this code:

  case Expr of
     Pat1 ->
       DoSomething,
       MoreCode;
     Pat2 ->
       erlang:error(bad);
     _ ->
       erlang:error(case_clause)
  end.

Generalize the optimization to handle any number of failing
clauses at the end of the case.

Reported-by: bugs.erlang.org/browse/ERL-452
@bjorng bjorng force-pushed the bjorn/compiler/improve-case-opt/ERL-452/OTP-14525 branch from 702b870 to 3e1d141 Compare August 10, 2017 10:15
@bjorng bjorng added the testing currently being tested, tag is used by OTP internal CI label Aug 14, 2017
@bjorng bjorng merged commit a84ddf3 into erlang:master Aug 16, 2017
@bjorng bjorng deleted the bjorn/compiler/improve-case-opt/ERL-452/OTP-14525 branch August 16, 2017 08:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement team:VM Assigned to OTP team VM testing currently being tested, tag is used by OTP internal CI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant