Browse Source

Generate only one variable for 'dup' if possible

pull/100/head
David Srbecký 15 years ago
parent
commit
171b11b87f
  1. 25
      ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

25
ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

@ -409,6 +409,31 @@ namespace ICSharpCode.Decompiler.ILAst @@ -409,6 +409,31 @@ namespace ICSharpCode.Decompiler.ILAst
}
}
// Try to use single temporary variable insted of several if possilbe (especially useful for dup)
foreach(ByteCode byteCode in body) {
if (byteCode.StoreTo != null && byteCode.StoreTo.Count > 1) {
var locVars = byteCode.StoreTo;
// For each of the variables, find the location where it is loaded - there should be preciesly one
var loadedBy = locVars.Select(argVar => body.SelectMany(bc => bc.StackBefore).Where(s => s.LoadFrom == argVar).Single()).ToList();
// We now know that all the variables have a single load,
// Let's make sure that they have also a single store - us
if (loadedBy.All(slot => slot.PushedBy.Length == 1 && slot.PushedBy[0] == byteCode)) {
// Great - we can reduce everything into single variable
ILVariable tmpVar = new ILVariable() { Name = string.Format("expr_{0:X2}", byteCode.Offset), IsGenerated = true };
byteCode.StoreTo = new List<ILVariable>() { tmpVar };
foreach(ByteCode bc in body) {
for (int i = 0; i < bc.StackBefore.Count; i++) {
// Is it one of the variable to be merged?
if (locVars.Contains(bc.StackBefore[i].LoadFrom)) {
// Replace with the new temp variable
bc.StackBefore[i] = new StackSlot(bc.StackBefore[i].PushedBy, tmpVar);
}
}
}
}
}
}
// Split and convert the normal local variables
ConvertLocalVariables(body);

Loading…
Cancel
Save