|
|
|
@ -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); |
|
|
|
|
|
|
|
|
|