Browse Source

Also use GraphTraversal.DepthFirstSearch for dominance calculation.

pull/3111/head
Daniel Grunwald 2 years ago
parent
commit
c12187277c
  1. 32
      ICSharpCode.Decompiler/FlowAnalysis/ControlFlowNode.cs
  2. 2
      ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs
  3. 7
      ICSharpCode.Decompiler/Util/GraphTraversal.cs

32
ICSharpCode.Decompiler/FlowAnalysis/ControlFlowNode.cs

@ -88,24 +88,32 @@ namespace ICSharpCode.Decompiler.FlowAnalysis @@ -88,24 +88,32 @@ namespace ICSharpCode.Decompiler.FlowAnalysis
public void TraversePreOrder(Func<ControlFlowNode, IEnumerable<ControlFlowNode>> children, Action<ControlFlowNode> visitAction)
{
if (Visited)
return;
Visited = true;
visitAction(this);
foreach (ControlFlowNode t in children(this))
t.TraversePreOrder(children, visitAction);
GraphTraversal.DepthFirstSearch(new[] { this }, Visit, children);
bool Visit(ControlFlowNode node)
{
if (node.Visited)
return false;
node.Visited = true;
visitAction(node);
return true;
}
}
public void TraversePostOrder(Func<ControlFlowNode, IEnumerable<ControlFlowNode>> children, Action<ControlFlowNode> visitAction)
{
if (Visited)
return;
Visited = true;
foreach (ControlFlowNode t in children(this))
t.TraversePostOrder(children, visitAction);
visitAction(this);
GraphTraversal.DepthFirstSearch(new[] { this }, Visit, children, postorderAction: visitAction);
bool Visit(ControlFlowNode node)
{
if (node.Visited)
return false;
node.Visited = true;
return true;
}
}
/// <summary>
/// Gets whether <c>this</c> dominates <paramref name="node"/>.
/// </summary>

2
ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs

@ -279,7 +279,7 @@ namespace ICSharpCode.Decompiler.IL @@ -279,7 +279,7 @@ namespace ICSharpCode.Decompiler.IL
// Visit blocks in post-order
BitSet visited = new BitSet(Blocks.Count);
List<Block> postOrder = new List<Block>();
GraphTraversal.DepthFirstSearch(new[] { EntryPoint }, Successors, postOrder.Add, MarkAsVisited, reverseSuccessors: true);
GraphTraversal.DepthFirstSearch(new[] { EntryPoint }, MarkAsVisited, Successors, postOrder.Add, reverseSuccessors: true);
postOrder.Reverse();
if (!deleteUnreachableBlocks)
{

7
ICSharpCode.Decompiler/Util/GraphTraversal.cs

@ -31,7 +31,8 @@ static class GraphTraversal @@ -31,7 +31,8 @@ static class GraphTraversal
/// </summary>
/// <param name="startNodes">The start nodes.</param>
/// <param name="visitedFunc">Called multiple times per node. The first call should return true, subsequent calls must return false.
/// If this function is not provided, normal Equals/GetHashCode will be used to compare nodes.</param>
/// The first calls to this function occur in pre-order.
/// If null, normal Equals/GetHashCode will be used to compare nodes.</param>
/// <param name="successorFunc">The function that gets the successors of an element. Called in pre-order.</param>
/// <param name="postorderAction">Called in post-order.</param>
/// <param name="reverseSuccessors">
@ -40,7 +41,7 @@ static class GraphTraversal @@ -40,7 +41,7 @@ static class GraphTraversal
/// so that blocks which could be output in either order (e.g. then-block and else-block of an if)
/// will maintain the order of the edges (then-block before else-block).
/// </param>
public static void DepthFirstSearch<T>(IEnumerable<T> startNodes, Func<T, IEnumerable<T>?> successorFunc, Action<T> postorderAction, Func<T, bool>? visitedFunc = null, bool reverseSuccessors = false)
public static void DepthFirstSearch<T>(IEnumerable<T> startNodes, Func<T, bool>? visitedFunc, Func<T, IEnumerable<T>?> successorFunc, Action<T>? postorderAction = null, bool reverseSuccessors = false)
{
/*
Pseudocode:
@ -80,7 +81,7 @@ static class GraphTraversal @@ -80,7 +81,7 @@ static class GraphTraversal
if (isPostOrderContinuation)
{
// Execute postorder_action
postorderAction(node);
postorderAction?.Invoke(node);
worklist.RemoveAt(worklist.Count - 1);
continue;
}

Loading…
Cancel
Save