From c12187277cace22f6d919ea879360ccd981e9fea Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 21 Oct 2023 17:33:30 +0200 Subject: [PATCH] Also use GraphTraversal.DepthFirstSearch for dominance calculation. --- .../FlowAnalysis/ControlFlowNode.cs | 32 ++++++++++++------- .../IL/Instructions/BlockContainer.cs | 2 +- ICSharpCode.Decompiler/Util/GraphTraversal.cs | 7 ++-- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/ICSharpCode.Decompiler/FlowAnalysis/ControlFlowNode.cs b/ICSharpCode.Decompiler/FlowAnalysis/ControlFlowNode.cs index 91c7f364d..bb1365de0 100644 --- a/ICSharpCode.Decompiler/FlowAnalysis/ControlFlowNode.cs +++ b/ICSharpCode.Decompiler/FlowAnalysis/ControlFlowNode.cs @@ -88,24 +88,32 @@ namespace ICSharpCode.Decompiler.FlowAnalysis public void TraversePreOrder(Func> children, Action 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> children, Action 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; + } } + /// /// Gets whether this dominates . /// diff --git a/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs b/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs index 7db8f7f61..e4b8ecbef 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs @@ -279,7 +279,7 @@ namespace ICSharpCode.Decompiler.IL // Visit blocks in post-order BitSet visited = new BitSet(Blocks.Count); List postOrder = new List(); - GraphTraversal.DepthFirstSearch(new[] { EntryPoint }, Successors, postOrder.Add, MarkAsVisited, reverseSuccessors: true); + GraphTraversal.DepthFirstSearch(new[] { EntryPoint }, MarkAsVisited, Successors, postOrder.Add, reverseSuccessors: true); postOrder.Reverse(); if (!deleteUnreachableBlocks) { diff --git a/ICSharpCode.Decompiler/Util/GraphTraversal.cs b/ICSharpCode.Decompiler/Util/GraphTraversal.cs index f11310bf7..a2dc4c7b2 100644 --- a/ICSharpCode.Decompiler/Util/GraphTraversal.cs +++ b/ICSharpCode.Decompiler/Util/GraphTraversal.cs @@ -31,7 +31,8 @@ static class GraphTraversal /// /// The start nodes. /// 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. + /// The first calls to this function occur in pre-order. + /// If null, normal Equals/GetHashCode will be used to compare nodes. /// The function that gets the successors of an element. Called in pre-order. /// Called in post-order. /// @@ -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). /// - public static void DepthFirstSearch(IEnumerable startNodes, Func?> successorFunc, Action postorderAction, Func? visitedFunc = null, bool reverseSuccessors = false) + public static void DepthFirstSearch(IEnumerable startNodes, Func? visitedFunc, Func?> successorFunc, Action? postorderAction = null, bool reverseSuccessors = false) { /* Pseudocode: @@ -80,7 +81,7 @@ static class GraphTraversal if (isPostOrderContinuation) { // Execute postorder_action - postorderAction(node); + postorderAction?.Invoke(node); worklist.RemoveAt(worklist.Count - 1); continue; }