dotnet/roslyn

Optimize pattern matching over large tuple literals

开放

#48,052 创建于 2020年9月25日

 (2 条评论) (0 个反应) (0 位负责人)C# (4,257 个派生)batch import
Area-CompilersCode Gen QualityFeature - Pattern Matchinghelp wanted

仓库指标

星标
 (20,414 个星标)
PR 合并指标
 (平均合并 6天 17小时) (30 天内合并 256 个 PR)

描述

Follow-up to #47878

Version Used: f33a0fd1d5e9e1387e2bc3879b0ee1b14bd0a5a7

Steps to Reproduce:

Compile the following program:

using System;
public class C
{
    public static void Main()
    {
        int x = (1, 2, 3, 4, 5, 6, 7, 8) switch
        {
            (1, 2, 3, 4, 5, 6, 7, 8) => 1,
            _ => -1,
        };
        Console.WriteLine(x);
    }
}

Expected Behavior: Emitted code does not use ValueTuple, except to throw SwitchExpressionException(object), if applicable. This is what is done for smaller tuple literals. The optimization in RewriteTupleInput instead creates locals for the fields of the tuple literal.

Actual Behavior: Emitted code uses ValueTuple:

{
  // Code size      110 (0x6e)
  .maxstack  9
  .locals init (int V_0,
                System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>> V_1)
  IL_0000:  ldloca.s   V_1
  IL_0002:  ldc.i4.1
  IL_0003:  ldc.i4.2
  IL_0004:  ldc.i4.3
  IL_0005:  ldc.i4.4
  IL_0006:  ldc.i4.5
  IL_0007:  ldc.i4.6
  IL_0008:  ldc.i4.7
  IL_0009:  ldc.i4.8
  IL_000a:  newobj     ""System.ValueTuple<int>..ctor(int)""
  IL_000f:  call       ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>..ctor(int, int, int, int, int, int, int, System.ValueTuple<int>)""
  IL_0014:  ldloc.1
  IL_0015:  ldfld      ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item1""
  IL_001a:  ldc.i4.1
  IL_001b:  bne.un.s   IL_0065
  IL_001d:  ldloc.1
  IL_001e:  ldfld      ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item2""
  IL_0023:  ldc.i4.2
  IL_0024:  bne.un.s   IL_0065
  IL_0026:  ldloc.1
  IL_0027:  ldfld      ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item3""
  IL_002c:  ldc.i4.3
  IL_002d:  bne.un.s   IL_0065
  IL_002f:  ldloc.1
  IL_0030:  ldfld      ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item4""
  IL_0035:  ldc.i4.4
  IL_0036:  bne.un.s   IL_0065
  IL_0038:  ldloc.1
  IL_0039:  ldfld      ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item5""
  IL_003e:  ldc.i4.5
  IL_003f:  bne.un.s   IL_0065
  IL_0041:  ldloc.1
  IL_0042:  ldfld      ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item6""
  IL_0047:  ldc.i4.6
  IL_0048:  bne.un.s   IL_0065
  IL_004a:  ldloc.1
  IL_004b:  ldfld      ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item7""
  IL_0050:  ldc.i4.7
  IL_0051:  bne.un.s   IL_0065
  IL_0053:  ldloc.1
  IL_0054:  ldfld      ""System.ValueTuple<int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Rest""
  IL_0059:  ldfld      ""int System.ValueTuple<int>.Item1""
  IL_005e:  ldc.i4.8
  IL_005f:  bne.un.s   IL_0065
  IL_0061:  ldc.i4.1
  IL_0062:  stloc.0
  IL_0063:  br.s       IL_0067
  IL_0065:  ldc.i4.m1
  IL_0066:  stloc.0
  IL_0067:  ldloc.0
  IL_0068:  call       ""void System.Console.WriteLine(int)""
  IL_006d:  ret
}

贡献者指南