Browse Source

GetSelfAndChildrenRecursive can be predicated

pull/100/head
David Srbecký 15 years ago
parent
commit
7318663cd5
  1. 2
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 6
      ICSharpCode.Decompiler/ILAst/GotoRemoval.cs
  3. 16
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  4. 13
      ICSharpCode.Decompiler/ILAst/ILAstTypes.cs
  5. 2
      ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs
  6. 2
      ILSpy/ILAstLanguage.cs

2
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -64,7 +64,7 @@ namespace ICSharpCode.Decompiler.Ast
bodyGraph.Optimize(context, ilMethod); bodyGraph.Optimize(context, ilMethod);
context.CancellationToken.ThrowIfCancellationRequested(); context.CancellationToken.ThrowIfCancellationRequested();
var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable).Where(v => v != null && !v.IsGenerated).Distinct(); var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>(e => e.Operand is ILVariable).Select(e => (ILVariable)e.Operand).Where(v => !v.IsGenerated).Distinct();
NameVariables.AssignNamesToVariables(methodDef.Parameters.Select(p => p.Name), allVariables, ilMethod); NameVariables.AssignNamesToVariables(methodDef.Parameters.Select(p => p.Name), allVariables, ilMethod);
context.CancellationToken.ThrowIfCancellationRequested(); context.CancellationToken.ThrowIfCancellationRequested();

6
ICSharpCode.Decompiler/ILAst/GotoRemoval.cs

@ -32,7 +32,7 @@ namespace ICSharpCode.Decompiler.ILAst
bool modified; bool modified;
do { do {
modified = false; modified = false;
foreach (ILExpression gotoExpr in method.GetSelfAndChildrenRecursive<ILExpression>().Where(e => e.Code == ILCode.Br || e.Code == ILCode.Leave)) { foreach (ILExpression gotoExpr in method.GetSelfAndChildrenRecursive<ILExpression>(e => e.Code == ILCode.Br || e.Code == ILCode.Leave)) {
modified |= TrySimplifyGoto(gotoExpr); modified |= TrySimplifyGoto(gotoExpr);
} }
} while(modified); } while(modified);
@ -43,8 +43,8 @@ namespace ICSharpCode.Decompiler.ILAst
public static void RemoveRedundantCode(ILBlock method) public static void RemoveRedundantCode(ILBlock method)
{ {
// Remove dead lables and nops // Remove dead lables and nops
HashSet<ILLabel> liveLabels = new HashSet<ILLabel>(method.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.GetBranchTargets())); HashSet<ILLabel> liveLabels = new HashSet<ILLabel>(method.GetSelfAndChildrenRecursive<ILExpression>(e => e.IsBranch()).SelectMany(e => e.GetBranchTargets()));
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
block.Body = block.Body.Where(n => !n.Match(ILCode.Nop) && !(n is ILLabel && !liveLabels.Contains((ILLabel)n))).ToList(); block.Body = block.Body.Where(n => !n.Match(ILCode.Nop) && !(n is ILLabel && !liveLabels.Contains((ILLabel)n))).ToList();
} }

16
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -51,7 +51,7 @@ namespace ICSharpCode.Decompiler.ILAst
RemoveRedundantCode(method); RemoveRedundantCode(method);
if (abortBeforeStep == ILAstOptimizationStep.ReduceBranchInstructionSet) return; if (abortBeforeStep == ILAstOptimizationStep.ReduceBranchInstructionSet) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
ReduceBranchInstructionSet(block); ReduceBranchInstructionSet(block);
} }
// ReduceBranchInstructionSet runs before inlining because the non-aggressive inlining heuristic // ReduceBranchInstructionSet runs before inlining because the non-aggressive inlining heuristic
@ -69,7 +69,7 @@ namespace ICSharpCode.Decompiler.ILAst
YieldReturnDecompiler.Run(context, method); YieldReturnDecompiler.Run(context, method);
if (abortBeforeStep == ILAstOptimizationStep.SplitToMovableBlocks) return; if (abortBeforeStep == ILAstOptimizationStep.SplitToMovableBlocks) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
SplitToBasicBlocks(block); SplitToBasicBlocks(block);
} }
@ -79,7 +79,7 @@ namespace ICSharpCode.Decompiler.ILAst
if (abortBeforeStep == ILAstOptimizationStep.PeepholeOptimizations) return; if (abortBeforeStep == ILAstOptimizationStep.PeepholeOptimizations) return;
AnalyseLabels(method); AnalyseLabels(method);
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
bool modified; bool modified;
do { do {
modified = false; modified = false;
@ -98,12 +98,12 @@ namespace ICSharpCode.Decompiler.ILAst
} }
if (abortBeforeStep == ILAstOptimizationStep.FindLoops) return; if (abortBeforeStep == ILAstOptimizationStep.FindLoops) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
new LoopsAndConditions(context).FindLoops(block); new LoopsAndConditions(context).FindLoops(block);
} }
if (abortBeforeStep == ILAstOptimizationStep.FindConditions) return; if (abortBeforeStep == ILAstOptimizationStep.FindConditions) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
new LoopsAndConditions(context).FindConditions(block); new LoopsAndConditions(context).FindConditions(block);
} }
@ -146,11 +146,11 @@ namespace ICSharpCode.Decompiler.ILAst
void RemoveRedundantCode(ILBlock method) void RemoveRedundantCode(ILBlock method)
{ {
Dictionary<ILLabel, int> labelRefCount = new Dictionary<ILLabel, int>(); Dictionary<ILLabel, int> labelRefCount = new Dictionary<ILLabel, int>();
foreach (ILLabel target in method.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.GetBranchTargets())) { foreach (ILLabel target in method.GetSelfAndChildrenRecursive<ILExpression>(e => e.IsBranch()).SelectMany(e => e.GetBranchTargets())) {
labelRefCount[target] = labelRefCount.GetOrDefault(target) + 1; labelRefCount[target] = labelRefCount.GetOrDefault(target) + 1;
} }
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
List<ILNode> body = block.Body; List<ILNode> body = block.Body;
List<ILNode> newBody = new List<ILNode>(body.Count); List<ILNode> newBody = new List<ILNode>(body.Count);
for (int i = 0; i < body.Count; i++) { for (int i = 0; i < body.Count; i++) {
@ -292,7 +292,7 @@ namespace ICSharpCode.Decompiler.ILAst
void AnalyseLabels(ILBlock method) void AnalyseLabels(ILBlock method)
{ {
labelGlobalRefCount = new Dictionary<ILLabel, int>(); labelGlobalRefCount = new Dictionary<ILLabel, int>();
foreach(ILLabel target in method.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.GetBranchTargets())) { foreach(ILLabel target in method.GetSelfAndChildrenRecursive<ILExpression>(e => e.IsBranch()).SelectMany(e => e.GetBranchTargets())) {
if (!labelGlobalRefCount.ContainsKey(target)) if (!labelGlobalRefCount.ContainsKey(target))
labelGlobalRefCount[target] = 0; labelGlobalRefCount[target] = 0;
labelGlobalRefCount[target]++; labelGlobalRefCount[target]++;

13
ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

@ -16,20 +16,21 @@ namespace ICSharpCode.Decompiler.ILAst
{ {
public abstract class ILNode public abstract class ILNode
{ {
public IEnumerable<T> GetSelfAndChildrenRecursive<T>() where T: ILNode public IEnumerable<T> GetSelfAndChildrenRecursive<T>(Func<T, bool> predicate = null) where T: ILNode
{ {
List<T> result = new List<T>(16); List<T> result = new List<T>(16);
AccumulateSelfAndChildrenRecursive(result); AccumulateSelfAndChildrenRecursive(result, predicate);
return result; return result;
} }
void AccumulateSelfAndChildrenRecursive<T>(List<T> list) where T:ILNode void AccumulateSelfAndChildrenRecursive<T>(List<T> list, Func<T, bool> predicate) where T:ILNode
{ {
if (this is T) T thisAsT = this as T;
list.Add((T)this); if (thisAsT != null && (predicate == null || predicate(thisAsT)))
list.Add(thisAsT);
foreach (ILNode node in this.GetChildren()) { foreach (ILNode node in this.GetChildren()) {
if (node != null) if (node != null)
node.AccumulateSelfAndChildrenRecursive(list); node.AccumulateSelfAndChildrenRecursive(list, predicate);
} }
} }

2
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -374,6 +374,8 @@ namespace ICSharpCode.Decompiler.ILAst
case ILCode.Ldelem_I2: case ILCode.Ldelem_I2:
case ILCode.Ldelem_I4: case ILCode.Ldelem_I4:
case ILCode.Ldelem_I8: case ILCode.Ldelem_I8:
case ILCode.Ldelem_R4:
case ILCode.Ldelem_R8:
case ILCode.Ldelem_I: case ILCode.Ldelem_I:
case ILCode.Ldelem_Ref: case ILCode.Ldelem_Ref:
{ {

2
ILSpy/ILAstLanguage.cs

@ -60,7 +60,7 @@ namespace ICSharpCode.ILSpy
new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value); new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
} }
var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable).Where(v => v != null).Distinct(); var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>(e => e.Operand is ILVariable).Select(e => (ILVariable)e.Operand).Distinct();
foreach (ILVariable v in allVariables) { foreach (ILVariable v in allVariables) {
output.WriteDefinition(v.Name, v); output.WriteDefinition(v.Name, v);
if (v.Type != null) { if (v.Type != null) {

Loading…
Cancel
Save