Browse Source

Remove useless stack variables.

pull/734/merge
Daniel Grunwald 8 years ago
parent
commit
56a0ca2f13
  1. 4
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 7
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  3. 40
      ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs
  4. 11
      ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs
  5. 1
      ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

4
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1068,8 +1068,8 @@ namespace ICSharpCode.Decompiler.CSharp
if (!parameter.Type.ContainsAnonymousType()) if (!parameter.Type.ContainsAnonymousType())
arguments[i] = arguments[i].ConvertTo(parameter.Type, this); arguments[i] = arguments[i].ConvertTo(parameter.Type, this);
if (parameter.IsOut && arguments[i].Expression is DirectionExpression) { if (parameter.IsOut && arguments[i].Expression is DirectionExpression dirExpr) {
((DirectionExpression)arguments[i].Expression).FieldDirection = FieldDirection.Out; dirExpr.FieldDirection = FieldDirection.Out;
} }
} }

7
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -25,6 +25,7 @@ using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
using ICSharpCode.Decompiler.IL.Patterns; using ICSharpCode.Decompiler.IL.Patterns;
using System;
namespace ICSharpCode.Decompiler.CSharp namespace ICSharpCode.Decompiler.CSharp
{ {
@ -60,7 +61,11 @@ namespace ICSharpCode.Decompiler.CSharp
protected internal override Statement VisitNop(Nop inst) protected internal override Statement VisitNop(Nop inst)
{ {
return new EmptyStatement(); var stmt = new EmptyStatement();
if (inst.Comment != null) {
stmt.AddChild(new Comment(inst.Comment), Roles.Comment);
}
return stmt;
} }
protected internal override Statement VisitIfInstruction(IfInstruction inst) protected internal override Statement VisitIfInstruction(IfInstruction inst)

40
ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs

@ -108,6 +108,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{ {
try { try {
this.context = context; this.context = context;
EnsureExpressionStatementsAreValid(rootNode);
FindInsertionPoints(rootNode, 0); FindInsertionPoints(rootNode, 0);
ResolveCollisions(); ResolveCollisions();
InsertVariableDeclarations(); InsertVariableDeclarations();
@ -117,6 +118,45 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
} }
} }
#region EnsureExpressionStatementsAreValid
void EnsureExpressionStatementsAreValid(AstNode rootNode)
{
foreach (var stmt in rootNode.DescendantsAndSelf.OfType<ExpressionStatement>()) {
if (!IsValidInStatementExpression(stmt.Expression)) {
// assign result to dummy variable
var v = new ILVariable(VariableKind.StackSlot, stmt.Expression.GetResolveResult().Type, 0);
v.Name = "_";
stmt.Expression = new AssignmentExpression(
new IdentifierExpression(v.Name).WithRR(new ILVariableResolveResult(v, v.Type)),
stmt.Expression.Detach());
}
}
}
private static bool IsValidInStatementExpression(Expression expr)
{
switch (expr) {
case InvocationExpression ie:
case ObjectCreateExpression oce:
case AssignmentExpression ae:
return true;
case UnaryOperatorExpression uoe:
switch (uoe.Operator) {
case UnaryOperatorType.PostIncrement:
case UnaryOperatorType.PostDecrement:
case UnaryOperatorType.Increment:
case UnaryOperatorType.Decrement:
case UnaryOperatorType.Await:
return true;
default:
return false;
}
default:
return false;
}
}
#endregion
#region FindInsertionPoints #region FindInsertionPoints
List<(InsertionPoint InsertionPoint, BlockContainer Loop)> loopTracking = new List<(InsertionPoint, BlockContainer)>(); List<(InsertionPoint InsertionPoint, BlockContainer Loop)> loopTracking = new List<(InsertionPoint, BlockContainer)>();

11
ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs

@ -47,7 +47,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms
ILVariable v; ILVariable v;
ILInstruction copiedExpr; ILInstruction copiedExpr;
if (block.Instructions[i].MatchStLoc(out v, out copiedExpr)) { if (block.Instructions[i].MatchStLoc(out v, out copiedExpr)) {
if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr)) { if (v.IsSingleDefinition && v.LoadCount == 0 && v.Kind == VariableKind.StackSlot) {
// dead store to stack
if (copiedExpr.Flags == InstructionFlags.None) {
// no-op -> delete
block.Instructions.RemoveAt(i--);
} else {
// evaluate the value for its side-effects
block.Instructions[i] = copiedExpr;
}
} else if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr)) {
DoPropagate(v, copiedExpr, block, ref i, context); DoPropagate(v, copiedExpr, block, ref i, context);
} }
} }

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

@ -336,7 +336,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms
static bool IsSafeForInlineOver(ILInstruction expr, ILInstruction expressionBeingMoved) static bool IsSafeForInlineOver(ILInstruction expr, ILInstruction expressionBeingMoved)
{ {
return SemanticHelper.MayReorder(expressionBeingMoved, expr); return SemanticHelper.MayReorder(expressionBeingMoved, expr);
} }
} }
} }

Loading…
Cancel
Save