Browse Source

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.
pull/1/head^2
David Srbecký 18 years ago
parent
commit
5adc88672a
  1. 14
      bin/Debug/output.cs
  2. 25
      src/ByteCodeExpression.cs
  3. 24
      src/ByteCodeExpressionCollection.cs

14
bin/Debug/output.cs

@ -162,27 +162,27 @@ namespace Reversi
} }
} }
if (squares[i, j] == Black) { if (squares[i, j] == Black) {
expr122.blackCount = blackCount + 1; blackCount++;
if (flag2) { if (flag2) {
expr134.blackFrontierCount = blackFrontierCount + 1; blackFrontierCount++;
} }
if (safeDiscs[i, j]) { if (safeDiscs[i, j]) {
expr151.blackSafeCount = blackSafeCount + 1; blackSafeCount++;
} }
} else { } else {
if (squares[i, j] == White) { if (squares[i, j] == White) {
expr175.whiteCount = whiteCount + 1; whiteCount++;
if (flag2) { if (flag2) {
expr187.whiteFrontierCount = whiteFrontierCount + 1; whiteFrontierCount++;
} }
if (safeDiscs[i, j]) { if (safeDiscs[i, j]) {
expr1A4.whiteSafeCount = whiteSafeCount + 1; whiteSafeCount++;
goto BasicBlock_327; goto BasicBlock_327;
} else { } else {
goto BasicBlock_327; goto BasicBlock_327;
} }
} }
expr1B4.emptyCount = emptyCount + 1; emptyCount++;
} }
BasicBlock_327: BasicBlock_327:
} }

25
src/ByteCodeExpression.cs

@ -108,5 +108,30 @@ namespace Decompiler
{ {
return string.Format("[ByteCodeExpression OpCode={0}]", this.opCode); return string.Format("[ByteCodeExpression OpCode={0}]", this.opCode);
} }
public ByteCodeExpression Clone()
{
ByteCodeExpression clone = (ByteCodeExpression)this.MemberwiseClone();
clone.branchTarget = null;
clone.branchesHere = new List<ByteCodeExpression>();
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;
}
}
} }
} }

24
src/ByteCodeExpressionCollection.cs

@ -21,7 +21,7 @@ namespace Decompiler
string name = string.Format("expr{0:X2}", byteCode.Offset); string name = string.Format("expr{0:X2}", byteCode.Offset);
ByteCodeExpression stExpr = ByteCodeExpression.Stloc(name); ByteCodeExpression stExpr = ByteCodeExpression.Stloc(name);
stExpr.Arguments.Add(newExpr); stExpr.Arguments.Add(newExpr);
stExpr.IsSSASR = true; stExpr.IsSSASR = byteCode.PushCount == 1;
newExpr = stExpr; newExpr = stExpr;
} }
@ -38,16 +38,34 @@ namespace Decompiler
} }
} }
Dictionary<ByteCodeExpression, object> alreadyDuplicated = new Dictionary<ByteCodeExpression, object>();
public void Optimize() public void Optimize()
{ {
// Try to in-line stloc into following expression
for(int i = 0; i < this.Count - 1; i++) { for(int i = 0; i < this.Count - 1; i++) {
if (i < 0) continue; if (i < 0) continue;
ByteCodeExpression expr = this[i]; ByteCodeExpression expr = this[i];
ByteCodeExpression nextExpr = this[i + 1]; 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 && if (expr.OpCode.Code == Code.Stloc &&
expr.IsSSASR && expr.IsSSASR &&
!nextExpr.IsBranchTarget) { !nextExpr.IsBranchTarget) {

Loading…
Cancel
Save