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 @@ -64,7 +64,7 @@ namespace ICSharpCode.Decompiler.Ast
bodyGraph.Optimize(context, ilMethod);
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);
context.CancellationToken.ThrowIfCancellationRequested();

6
ICSharpCode.Decompiler/ILAst/GotoRemoval.cs

@ -32,7 +32,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -32,7 +32,7 @@ namespace ICSharpCode.Decompiler.ILAst
bool modified;
do {
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);
}
} while(modified);
@ -43,8 +43,8 @@ namespace ICSharpCode.Decompiler.ILAst @@ -43,8 +43,8 @@ namespace ICSharpCode.Decompiler.ILAst
public static void RemoveRedundantCode(ILBlock method)
{
// Remove dead lables and nops
HashSet<ILLabel> liveLabels = new HashSet<ILLabel>(method.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.GetBranchTargets()));
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) {
HashSet<ILLabel> liveLabels = new HashSet<ILLabel>(method.GetSelfAndChildrenRecursive<ILExpression>(e => e.IsBranch()).SelectMany(e => e.GetBranchTargets()));
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();
}

16
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -51,7 +51,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -51,7 +51,7 @@ namespace ICSharpCode.Decompiler.ILAst
RemoveRedundantCode(method);
if (abortBeforeStep == ILAstOptimizationStep.ReduceBranchInstructionSet) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) {
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
ReduceBranchInstructionSet(block);
}
// ReduceBranchInstructionSet runs before inlining because the non-aggressive inlining heuristic
@ -69,7 +69,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -69,7 +69,7 @@ namespace ICSharpCode.Decompiler.ILAst
YieldReturnDecompiler.Run(context, method);
if (abortBeforeStep == ILAstOptimizationStep.SplitToMovableBlocks) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) {
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
SplitToBasicBlocks(block);
}
@ -79,7 +79,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -79,7 +79,7 @@ namespace ICSharpCode.Decompiler.ILAst
if (abortBeforeStep == ILAstOptimizationStep.PeepholeOptimizations) return;
AnalyseLabels(method);
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) {
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
bool modified;
do {
modified = false;
@ -98,12 +98,12 @@ namespace ICSharpCode.Decompiler.ILAst @@ -98,12 +98,12 @@ namespace ICSharpCode.Decompiler.ILAst
}
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);
}
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);
}
@ -146,11 +146,11 @@ namespace ICSharpCode.Decompiler.ILAst @@ -146,11 +146,11 @@ namespace ICSharpCode.Decompiler.ILAst
void RemoveRedundantCode(ILBlock method)
{
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;
}
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) {
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
List<ILNode> body = block.Body;
List<ILNode> newBody = new List<ILNode>(body.Count);
for (int i = 0; i < body.Count; i++) {
@ -292,7 +292,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -292,7 +292,7 @@ namespace ICSharpCode.Decompiler.ILAst
void AnalyseLabels(ILBlock method)
{
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))
labelGlobalRefCount[target] = 0;
labelGlobalRefCount[target]++;

13
ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

@ -16,20 +16,21 @@ namespace ICSharpCode.Decompiler.ILAst @@ -16,20 +16,21 @@ namespace ICSharpCode.Decompiler.ILAst
{
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);
AccumulateSelfAndChildrenRecursive(result);
AccumulateSelfAndChildrenRecursive(result, predicate);
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)
list.Add((T)this);
T thisAsT = this as T;
if (thisAsT != null && (predicate == null || predicate(thisAsT)))
list.Add(thisAsT);
foreach (ILNode node in this.GetChildren()) {
if (node != null)
node.AccumulateSelfAndChildrenRecursive(list);
node.AccumulateSelfAndChildrenRecursive(list, predicate);
}
}

2
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

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

2
ILSpy/ILAstLanguage.cs

@ -60,7 +60,7 @@ namespace ICSharpCode.ILSpy @@ -60,7 +60,7 @@ namespace ICSharpCode.ILSpy
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) {
output.WriteDefinition(v.Name, v);
if (v.Type != null) {

Loading…
Cancel
Save