Browse Source

Remove temporary local variables generated by the C# compiler for instance method calls on immutable value type values

pull/139/head
pentp 15 years ago
parent
commit
71149caffd
  1. 33
      ICSharpCode.Decompiler/ILAst/ILInlining.cs

33
ICSharpCode.Decompiler/ILAst/ILInlining.cs

@ -169,7 +169,10 @@ namespace ICSharpCode.Decompiler.ILAst @@ -169,7 +169,10 @@ namespace ICSharpCode.Decompiler.ILAst
bool InlineIfPossible(ILVariable v, ILExpression inlinedExpression, ILNode next, bool aggressive)
{
// ensure the variable is accessed only a single time
if (!(numStloc.GetOrDefault(v) == 1 && numLdloc.GetOrDefault(v) == 1 && numLdloca.GetOrDefault(v) == 0))
if (numStloc.GetOrDefault(v) != 1)
return false;
int ldloc = numLdloc.GetOrDefault(v);
if (ldloc > 1 || ldloc + numLdloca.GetOrDefault(v) != 1)
return false;
if (next is ILCondition)
@ -180,7 +183,12 @@ namespace ICSharpCode.Decompiler.ILAst @@ -180,7 +183,12 @@ namespace ICSharpCode.Decompiler.ILAst
ILExpression parent;
int pos;
if (FindLoadInNext(next as ILExpression, v, inlinedExpression, out parent, out pos) == true) {
if (!aggressive && !v.IsGenerated && !NonAggressiveInlineInto((ILExpression)next, parent, inlinedExpression))
if (ldloc == 0)
{
if (!IsGeneratedValueTypeTemporary((ILExpression)next, parent, pos, v))
return false;
}
else if (!aggressive && !v.IsGenerated && !NonAggressiveInlineInto((ILExpression)next, parent, inlinedExpression))
return false;
// Assign the ranges of the ldloc instruction:
@ -192,6 +200,15 @@ namespace ICSharpCode.Decompiler.ILAst @@ -192,6 +200,15 @@ namespace ICSharpCode.Decompiler.ILAst
}
return false;
}
/// <summary>
/// Is this a temporary variable generated by the C# compiler for instance method calls on immutable value type values
/// </summary>
bool IsGeneratedValueTypeTemporary(ILExpression next, ILExpression parent, int pos, ILVariable v)
{
return pos == 0 && v.Type != null && v.Type.IsValueType && next.Code == ILCode.Stloc
&& (parent.Code == ILCode.Call || parent.Code == ILCode.Callvirt) && ((MethodReference)parent.Operand).HasThis;
}
bool NonAggressiveInlineInto(ILExpression next, ILExpression parent, ILExpression inlinedExpression)
{
@ -214,16 +231,6 @@ namespace ICSharpCode.Decompiler.ILAst @@ -214,16 +231,6 @@ namespace ICSharpCode.Decompiler.ILAst
}
}
/// <summary>
/// Gets whether 'expressionBeingMoved' can be inlined into 'expr'.
/// </summary>
public bool CanInlineInto(ILExpression expr, ILVariable v, ILExpression expressionBeingMoved)
{
ILExpression parent;
int pos;
return FindLoadInNext(expr, v, expressionBeingMoved, out parent, out pos) == true;
}
/// <summary>
/// Finds the position to inline to.
/// </summary>
@ -242,7 +249,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -242,7 +249,7 @@ namespace ICSharpCode.Decompiler.ILAst
ILExpression arg = expr.Arguments[i];
if (arg.Code == ILCode.Ldloc && arg.Operand == v) {
if ((arg.Code == ILCode.Ldloc || arg.Code == ILCode.Ldloca) && arg.Operand == v) {
parent = expr;
pos = i;
return true;

Loading…
Cancel
Save