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

Do not flatten matches for C# #5509

Closed

Conversation

keyboardDrummer
Copy link
Member

@keyboardDrummer keyboardDrummer commented May 30, 2024

Description

Do not flatten matches for C#. Such flattening can cause the generated code size to be the square of the input code size. Removing the flattening leads to a huge decrease in the size of the generated C# code inside the Dafny codebase. It goes from ~14K lines to ~7K.

The compilation of nested matches is done as follows:

datatype TX = X(x1arg: TY, x2arg: TY)
datatype TY = Y(yarg: int)
datatype TZ = Z(zarg: TW)
datatype TW = W(warg: int)

method M(a: TX) {
  match a
    case X(Y(b),Z(W(c)) => <body1>
    case r => <body2>
}

Is roughly compiled into

// Same datatypes

method M(a: TX) {
  var unmatched := true;
  if (unmatched && a is X) {
    var x1arg1 = ((X)a).1;
    if (x1 is Y) {
      var b = ((Y)x1arg1).1;
      var x2arg2 := ((X)a).2; 
      if (x2 is Z) {
        var zarg1 := ((Z)x2arg2).1;
        if (x4 is W) {
          var c := ((W)zarg1).1;
          unmatched := false;
          <body1>
        }
      } 
    }
  }
  if (unmatched) {
    var r := a;
    <body2>
  }
}

Caveats

Maintainability

The approach taken to compile unflattened matches is one that could be applied generally, across all compilers, but it was slightly simpler to only apply it to C#, so I've done that for now.

Ideally the transformation would be a Dafny-to-Dafny source transformation, instead of a customization of SinglePassCompiler. However, Dafny does not allow using statements in expression contexts, and this is needed for the transformation. I think it would be good to have an intermediate Dafny that does allow this, similar to what @cpitclaudel 's Dafny-in-Dafny compiler allowed, and then to define the rewrite that this PR introduces using a Dafny source translation.

Improvement

For C# we could generate much nicer code, since C# allows declaring new variables inside expressions using x is T xAsType expressions. We could get rid of the nested if statements and the unmatched variable. However, I'll leave this for future work.

How has this been tested?

  • Performance change. No additional tests added.

By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.

@keyboardDrummer keyboardDrummer marked this pull request as draft May 30, 2024 13:43
@keyboardDrummer keyboardDrummer added the run-integration-tests Forces running the CI for integration tests even if the deep tests fail label Jun 3, 2024
keyboardDrummer added a commit that referenced this pull request Jun 4, 2024
### Description
- Split off parts of single pass compiler, which is the refactoring part
of #5509

### How has this been tested?
- No additional testing needed

<small>By submitting this pull request, I confirm that my contribution
is made under the terms of the [MIT
license](https://github.com/dafny-lang/dafny/blob/master/LICENSE.txt).</small>
@keyboardDrummer keyboardDrummer marked this pull request as ready for review June 5, 2024 08:20
@keyboardDrummer keyboardDrummer enabled auto-merge (squash) June 5, 2024 10:40
@keyboardDrummer
Copy link
Member Author

Closing in favor of #5528

auto-merge was automatically disabled June 5, 2024 15:04

Pull request was closed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
run-integration-tests Forces running the CI for integration tests even if the deep tests fail
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant