Browse Source

Move some special cases from ILInlining.FindLoadInNext to the individual ILInstructions.

pull/2069/head
Daniel Grunwald 5 years ago
parent
commit
c63e14e805
  1. 14
      ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs
  2. 9
      ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs
  3. 10
      ICSharpCode.Decompiler/IL/Instructions/NullableInstructions.cs
  4. 15
      ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

14
ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs

@ -20,6 +20,7 @@ using System; @@ -20,6 +20,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL
@ -239,6 +240,19 @@ namespace ICSharpCode.Decompiler.IL @@ -239,6 +240,19 @@ namespace ICSharpCode.Decompiler.IL
}
}
internal override bool CanInlineIntoSlot(int childIndex, ILInstruction expressionBeingMoved)
{
// Inlining into the entry-point is allowed as long as we're not moving code into a loop.
// This is used to inline into the switch expression.
return childIndex == 0 && this.EntryPoint.IncomingEdgeCount == 1;
}
internal override bool PrepareExtract(int childIndex, ExtractionContext ctx)
{
// Un-inlining from the entry-point is allowed as long as we're not moving code out of a loop
return childIndex == 0 && this.EntryPoint.IncomingEdgeCount == 1;
}
/// <summary>
/// Topologically sort the blocks.
/// The new order is returned without modifying the BlockContainer.

9
ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs

@ -802,6 +802,15 @@ namespace ICSharpCode.Decompiler.IL @@ -802,6 +802,15 @@ namespace ICSharpCode.Decompiler.IL
}
return true;
}
/// <summary>
/// Gets whether the specified instruction may be inlined into the specified slot.
/// Note: this does not check whether reordering with the previous slots is valid; only wheter the target slot supports inlining at all!
/// </summary>
internal virtual bool CanInlineIntoSlot(int childIndex, ILInstruction expressionBeingMoved)
{
return GetChildSlot(childIndex).CanInlineInto;
}
}
public interface IInstructionWithTypeOperand

10
ICSharpCode.Decompiler/IL/Instructions/NullableInstructions.cs

@ -63,7 +63,7 @@ namespace ICSharpCode.Decompiler.IL @@ -63,7 +63,7 @@ namespace ICSharpCode.Decompiler.IL
/// </summary>
public bool RefOutput { get => ResultType == StackType.Ref; }
public NullableUnwrap(StackType unwrappedType, ILInstruction argument, bool refInput=false)
public NullableUnwrap(StackType unwrappedType, ILInstruction argument, bool refInput = false)
: base(OpCode.NullableUnwrap, argument)
{
this.ResultType = unwrappedType;
@ -132,5 +132,13 @@ namespace ICSharpCode.Decompiler.IL @@ -132,5 +132,13 @@ namespace ICSharpCode.Decompiler.IL
return base.PrepareExtract(childIndex, ctx)
&& (ctx.FlagsBeingMoved & InstructionFlags.MayUnwrapNull) == 0;
}
internal override bool CanInlineIntoSlot(int childIndex, ILInstruction expressionBeingMoved)
{
// Inlining into nullable.rewrap is OK unless the expression being inlined
// contains a nullable.wrap that isn't being re-wrapped within the expression being inlined.
return base.CanInlineIntoSlot(childIndex, expressionBeingMoved)
&& !expressionBeingMoved.HasFlag(InstructionFlags.MayUnwrapNull);
}
}
}

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

@ -589,6 +589,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -589,6 +589,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} else if (expr is Block block) {
// Inlining into inline-blocks?
switch (block.Kind) {
case BlockKind.ControlFlow when block.Parent is BlockContainer:
case BlockKind.ArrayInitializer:
case BlockKind.CollectionInitializer:
case BlockKind.ObjectInitializer:
@ -604,19 +605,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -604,19 +605,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
default:
return FindResult.Stop;
}
} else if (expr is BlockContainer container && container.EntryPoint.IncomingEdgeCount == 1) {
// Possibly a switch-container, allow inlining into the switch instruction:
return NoContinue(FindLoadInNext(container.EntryPoint.Instructions[0], v, expressionBeingMoved, options));
// If FindLoadInNext() returns null, we still can't continue searching
// because we can't inline over the remainder of the blockcontainer.
} else if (expr is NullableRewrap) {
// Inlining into nullable.rewrap is OK unless the expression being inlined
// contains a nullable.wrap that isn't being re-wrapped within the expression being inlined.
if (expressionBeingMoved.HasFlag(InstructionFlags.MayUnwrapNull))
return FindResult.Stop;
}
foreach (var child in expr.Children) {
if (!child.SlotInfo.CanInlineInto)
if (!expr.CanInlineIntoSlot(child.ChildIndex, expressionBeingMoved))
return FindResult.Stop;
// Recursively try to find the load instruction
@ -672,7 +663,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -672,7 +663,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
Debug.Assert(targetLoad.IsDescendantOf(stmt));
for (ILInstruction inst = targetLoad; inst != stmt; inst = inst.Parent) {
if (!inst.SlotInfo.CanInlineInto)
if (!inst.Parent.CanInlineIntoSlot(inst.ChildIndex, expressionBeingMoved))
return false;
// Check whether re-ordering with predecessors is valid:
int childIndex = inst.ChildIndex;

Loading…
Cancel
Save