Browse Source

DetectPinnedRegions: Inline the stack-slot involved in CustomRefPinPattern so that the following ProcessPinnedRegion call can reuse existing unmanaged pointer variables instead of being forced to create a new variable.

pull/2642/head
Siegfried Pammer 3 years ago
parent
commit
3c2e52854e
  1. 14
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs
  2. 28
      ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs

14
ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs

@ -422,13 +422,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -422,13 +422,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
#endif
#if CS73
//public unsafe void FixedCustomReferenceType(CustomPinnable mem)
//{
// fixed (int* ptr = mem)
// {
// UsePointer(ptr);
// }
//}
public unsafe void FixedCustomReferenceType(CustomPinnable mem)
{
fixed (int* ptr = mem)
{
UsePointer(ptr);
}
}
public unsafe void FixedCustomReferenceTypeNoPointerUse(CustomPinnable mem)
{

28
ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs

@ -174,7 +174,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -174,7 +174,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
((Branch)block.Instructions.Last()).TargetBlock = targetBlock;
modified = true;
}
else if (IsCustomRefPinPattern(block, out ILInstruction ldlocMem, out var callGPR, out v, out var stlocPtr, out targetBlock))
else if (IsCustomRefPinPattern(block, out ILInstruction ldlocMem, out var callGPR, out v, out var stlocPtr,
out targetBlock, out var nullBlock, out var notNullBlock))
{
context.Step("CustomRefPinPattern", block);
ILInstruction gpr;
@ -197,6 +198,20 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -197,6 +198,20 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
block.Instructions.Insert(block.Instructions.Count - 1, stlocPtr);
}
((Branch)block.Instructions.Last()).TargetBlock = targetBlock;
// clear out internal blocks that are now unreachable, so that
// targetBlock.IncomingEdgeCount is accurate at this point.
nullBlock?.Instructions.Clear();
notNullBlock.Instructions.Clear();
if (targetBlock.IncomingEdgeCount == 1 && targetBlock.Parent == block.Parent)
{
block.Instructions.RemoveLast();
block.Instructions.AddRange(targetBlock.Instructions);
targetBlock.Instructions.Clear();
if (stlocPtr != null)
{
ILInlining.InlineOneIfPossible(block, stlocPtr.ChildIndex, InliningOptions.None, context);
}
}
modified = true;
}
}
@ -226,13 +241,15 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -226,13 +241,15 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
// stloc ptr(conv ref->u (ldloc V_1))
// br targetBlock
private bool IsCustomRefPinPattern(Block block, out ILInstruction ldlocMem, out CallInstruction callGPR,
out ILVariable v, out StLoc ptrAssign, out Block targetBlock)
out ILVariable v, out StLoc ptrAssign, out Block targetBlock, out Block nullBlock, out Block notNullBlock)
{
ldlocMem = null;
callGPR = null;
v = null;
ptrAssign = null;
targetBlock = null;
nullBlock = null;
notNullBlock = null;
// if (comp.o(ldloc mem != ldnull)) br on_not_null
// br on_null
if (!block.MatchIfAtEndOfBlock(out var ifCondition, out var trueInst, out var falseInst))
@ -250,9 +267,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -250,9 +267,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
if (!SemanticHelper.IsPure(ldlocMem.Flags))
return false;
if (!trueInst.MatchBranch(out Block notNullBlock) || notNullBlock.Parent != block.Parent)
if (!trueInst.MatchBranch(out notNullBlock) || notNullBlock.Parent != block.Parent)
return false;
if (!falseInst.MatchBranch(out Block nullBlock) || nullBlock.Parent != block.Parent)
if (!falseInst.MatchBranch(out nullBlock) || nullBlock.Parent != block.Parent)
return false;
// Block notNullBlock (incoming: 1) {
@ -309,6 +326,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -309,6 +326,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (targetBlock != nullBlock)
return false;
// nullBlock must be set to null, so that
// we do not clear out targetBlock in the caller.
nullBlock = null;
}
return true;
}

Loading…
Cancel
Save