Browse Source

Enable aggressive inlining into switch expressions.

pull/2087/head
Daniel Grunwald 5 years ago
parent
commit
1a997fdb60
  1. 4
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/SwitchExpressions.cs
  2. 26
      ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

4
ICSharpCode.Decompiler.Tests/TestCases/Pretty/SwitchExpressions.cs

@ -75,9 +75,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
} }
} }
public static string SwitchOverNullableInt(int? i) public static string SwitchOverNullableInt(int? i, int? j)
{ {
return i switch { return (i + j) switch {
null => "null", null => "null",
0 => "zero", 0 => "zero",
5 => "five", 5 => "five",

26
ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

@ -418,6 +418,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
case OpCode.NumericCompoundAssign: case OpCode.NumericCompoundAssign:
case OpCode.UserDefinedCompoundAssign: case OpCode.UserDefinedCompoundAssign:
case OpCode.Await: case OpCode.Await:
case OpCode.SwitchInstruction:
return true; return true;
case OpCode.LdLoc: case OpCode.LdLoc:
if (v.StateMachineField == null && ((LdLoc)inlinedExpression).Variable.StateMachineField != null) { if (v.StateMachineField == null && ((LdLoc)inlinedExpression).Variable.StateMachineField != null) {
@ -479,32 +480,21 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return true; return true;
} }
break; break;
case OpCode.Leave:
case OpCode.YieldReturn:
return true;
case OpCode.SwitchInstruction:
//case OpCode.BinaryNumericInstruction when parent.SlotInfo == SwitchInstruction.ValueSlot:
case OpCode.StringToInt when parent.SlotInfo == SwitchInstruction.ValueSlot:
return true;
} }
// decide based on the top-level target instruction into which we are inlining: // decide based on the top-level target instruction into which we are inlining:
switch (next.OpCode) { switch (next.OpCode) {
case OpCode.Leave:
case OpCode.YieldReturn:
return parent == next;
case OpCode.IfInstruction: case OpCode.IfInstruction:
while (parent.MatchLogicNot(out _)) { while (parent.MatchLogicNot(out _)) {
parent = parent.Parent; parent = parent.Parent;
} }
return parent == next; return parent == next;
case OpCode.BlockContainer:
if (((BlockContainer)next).EntryPoint.Instructions[0] is SwitchInstruction switchInst) {
next = switchInst;
goto case OpCode.SwitchInstruction;
} else {
return false;
}
case OpCode.SwitchInstruction:
if (parent == next)
return true;
if (parent.MatchBinaryNumericInstruction(BinaryNumericOperator.Sub) && parent.Parent == next)
return true;
if (parent is StringToInt stringToInt && stringToInt.Parent == next)
return true;
return false;
default: default:
return false; return false;
} }

Loading…
Cancel
Save