From 5adc88672a91b0ccc5af2d192fc79446ce868de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Srbeck=C3=BD?= Date: Fri, 28 Mar 2008 22:11:13 +0000 Subject: [PATCH] Use the new representation to handle 'dup' instruction better. The outputted code is now just 'count++;'. This access to field previously involved a temporary variable. --- bin/Debug/output.cs | 14 +++++++------- src/ByteCodeExpression.cs | 25 +++++++++++++++++++++++++ src/ByteCodeExpressionCollection.cs | 24 +++++++++++++++++++++--- 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/bin/Debug/output.cs b/bin/Debug/output.cs index 9241f0da0..8e335cf7a 100644 --- a/bin/Debug/output.cs +++ b/bin/Debug/output.cs @@ -162,27 +162,27 @@ namespace Reversi } } if (squares[i, j] == Black) { - expr122.blackCount = blackCount + 1; + blackCount++; if (flag2) { - expr134.blackFrontierCount = blackFrontierCount + 1; + blackFrontierCount++; } if (safeDiscs[i, j]) { - expr151.blackSafeCount = blackSafeCount + 1; + blackSafeCount++; } } else { if (squares[i, j] == White) { - expr175.whiteCount = whiteCount + 1; + whiteCount++; if (flag2) { - expr187.whiteFrontierCount = whiteFrontierCount + 1; + whiteFrontierCount++; } if (safeDiscs[i, j]) { - expr1A4.whiteSafeCount = whiteSafeCount + 1; + whiteSafeCount++; goto BasicBlock_327; } else { goto BasicBlock_327; } } - expr1B4.emptyCount = emptyCount + 1; + emptyCount++; } BasicBlock_327: } diff --git a/src/ByteCodeExpression.cs b/src/ByteCodeExpression.cs index 8a926e0f5..7c2bee6d5 100644 --- a/src/ByteCodeExpression.cs +++ b/src/ByteCodeExpression.cs @@ -108,5 +108,30 @@ namespace Decompiler { return string.Format("[ByteCodeExpression OpCode={0}]", this.opCode); } + + public ByteCodeExpression Clone() + { + ByteCodeExpression clone = (ByteCodeExpression)this.MemberwiseClone(); + clone.branchTarget = null; + clone.branchesHere = new List(); + return clone; + } + + public bool IsConstant() + { + if (!IsOpCodeConstant()) return false; + foreach(ByteCodeExpression arg in this.Arguments) { + if (!arg.IsConstant()) return false; + } + return true; + } + + bool IsOpCodeConstant() + { + switch(this.OpCode.Code) { + case Code.Ldarg: return true; + default: return false; + } + } } } diff --git a/src/ByteCodeExpressionCollection.cs b/src/ByteCodeExpressionCollection.cs index 904369db9..7d3b0eb5a 100644 --- a/src/ByteCodeExpressionCollection.cs +++ b/src/ByteCodeExpressionCollection.cs @@ -21,7 +21,7 @@ namespace Decompiler string name = string.Format("expr{0:X2}", byteCode.Offset); ByteCodeExpression stExpr = ByteCodeExpression.Stloc(name); stExpr.Arguments.Add(newExpr); - stExpr.IsSSASR = true; + stExpr.IsSSASR = byteCode.PushCount == 1; newExpr = stExpr; } @@ -38,16 +38,34 @@ namespace Decompiler } } + Dictionary alreadyDuplicated = new Dictionary(); + public void Optimize() { - // Try to in-line stloc into following expression - for(int i = 0; i < this.Count - 1; i++) { if (i < 0) continue; ByteCodeExpression expr = this[i]; ByteCodeExpression nextExpr = this[i + 1]; + // Duplicate 'dup' expressions + + if (expr.OpCode.Code == Code.Stloc && + expr.Arguments[0].OpCode.Code == Code.Dup && + expr.Arguments[0].Arguments[0].IsConstant() && + !alreadyDuplicated.ContainsKey(expr)) + { + Options.NotifyCollapsingExpression(); + this.Insert(i + 1, expr.Clone()); + this[i].IsSSASR = true; + this[i + 1].IsSSASR = true; + alreadyDuplicated.Add(this[i], null); + alreadyDuplicated.Add(this[i + 1], null); + continue; + } + + // Try to in-line stloc into following expression + if (expr.OpCode.Code == Code.Stloc && expr.IsSSASR && !nextExpr.IsBranchTarget) {