diff --git a/src/DotWeb.Decompiler/Core/BackEnd.cs b/src/DotWeb.Decompiler/Core/BackEnd.cs
deleted file mode 100644
index c8db49e..0000000
--- a/src/DotWeb.Decompiler/Core/BackEnd.cs
+++ /dev/null
@@ -1,360 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see .
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using DotWeb.Decompiler.CodeModel;
-using Mono.Cecil.Cil;
-using System.Diagnostics;
-
-namespace DotWeb.Decompiler.Core
-{
- class BackEnd
- {
- public ControlFlowGraph Cfg { get; private set; }
- public CodeMethodMember Method { get; private set; }
-
- class Context
- {
- private ControlFlowGraph cfg;
- public Node LatchNode { get; private set; }
- public Node IfFollow { get; private set; }
- public Node LoopFollow { get; private set; }
- public Node LoopHeader { get; private set; }
-
- public Context(ControlFlowGraph cfg) {
- this.cfg = cfg;
- this.LatchNode = null;
- this.IfFollow = null;
- this.LoopHeader = null;
- this.LoopFollow = null;
- }
-
- public Context Clone() {
- return new Context(this.cfg) {
- LatchNode = this.LatchNode,
- IfFollow = this.IfFollow,
- LoopFollow = this.LoopFollow,
- LoopHeader = this.LoopHeader
- };
- }
-
- public Context NewIfFollow(int ifFollow) {
- var node = this.cfg.DepthFirstPostOrder[ifFollow];
- var ctx = this.Clone();
- ctx.IfFollow = node;
- return ctx;
- }
-
- public Context NewLatch(Node latchNode) {
- var ctx = this.Clone();
- ctx.LatchNode = latchNode;
- return ctx;
- }
-
- public Context NewLoop(int loopHeader, int loopFollow) {
- var ctx = this.Clone();
- ctx.LoopHeader = this.cfg.DepthFirstPostOrder[loopHeader];
- ctx.LoopFollow = this.cfg.DepthFirstPostOrder[loopFollow];
- return ctx;
- }
- }
-
- public BackEnd(ControlFlowGraph cfg) {
- this.Cfg = cfg;
-
- this.Method = new CodeMethodMember(cfg.Method) {
- ExternalMethods = cfg.ExternalMethods
- };
-
- //foreach (LocalVariableInfo local in cfg.Method.GetMethodBody().LocalVariables) {
- // this.Method.Statements.Add(new CodeVariableDeclarationStatement(
- // local.LocalType,
- // CodeDomGenerator.LocalVariable(local.LocalIndex)
- // ));
- //}
- }
-
- public void WriteCode() {
- this.WriteCode(this.Cfg.Root, new Context(this.Cfg), this.Method.Statements);
- }
-
- private void WriteIf(BasicBlock bb, Context context, List stmts) {
- int i = 0;
- for (i = 0; i < bb.Statements.Count - 1; i++) {
- stmts.Add(bb.Statements[i]);
- }
-
- CodeStatement last = bb.Statements[i];
- CodeExpressionStatement ces = last as CodeExpressionStatement;
- CodeExpression test = ces.Expression;
- CodeIfStatement condition = new CodeIfStatement();
- stmts.Add(condition);
-
- bool emptyThen = false;
- // is there a follow?
- if (bb.IfFollow != Node.NoNode) {
- // process the THEN part
- Node succ = bb.ThenEdge;
- if (succ.DfsTraversed != DfsTraversal.Alpha) {
- // not visited
- context = context.NewIfFollow(bb.IfFollow);
- if (succ.DfsPostOrder != bb.IfFollow) {
- // THEN part
- test = test.Invert();
- WriteCode((BasicBlock)succ, context, condition.TrueStatements);
- }
- else {
- // empty THEN part => negate ELSE part
- WriteCode((BasicBlock)bb.ElseEdge, context, condition.TrueStatements);
- emptyThen = true;
- }
- }
-
- // process the ELSE part
- succ = bb.ElseEdge;
- if (succ.DfsTraversed != DfsTraversal.Alpha) {
- if (succ.DfsPostOrder != bb.IfFollow) {
- // ELSE part
- WriteCode((BasicBlock)succ, context.NewIfFollow(bb.IfFollow), condition.FalseStatements);
- }
- }
- else if (!emptyThen) {
- // already visited => emit label
- throw new InvalidOperationException();
- }
-
- // Continue with the follow
- succ = this.Cfg.DepthFirstPostOrder[bb.IfFollow];
- if (succ.DfsTraversed != DfsTraversal.Alpha) {
- WriteCode((BasicBlock)succ, context, stmts);
- }
- }
- else {
- // no follow => if..then..else
- test = test.Invert();
- WriteCode((BasicBlock)bb.ThenEdge, context, condition.TrueStatements);
- WriteCode((BasicBlock)bb.ElseEdge, context, condition.FalseStatements);
- }
-
- condition.Condition = test;
- }
-
- private void WriteLoopInner(BasicBlock bb, Context context, List stmts) {
- Node succ;
- if (bb.LoopType == LoopType.While) {
- succ = bb.ThenEdge;
- if (succ.DfsPostOrder == bb.LoopFollow) {
- succ = bb.ElseEdge;
- }
- }
- else {
- succ = bb.Successors.First();
- }
-
- if (succ.DfsTraversed != DfsTraversal.Alpha) {
- WriteCode((BasicBlock)succ, context.NewLatch(bb.LatchNode), stmts);
- }
- }
-
- private void WriteLoopFollow(BasicBlock bb, Context context, List stmts) {
- Node succ = this.Cfg.DepthFirstPostOrder[bb.LoopFollow];
- if (succ.DfsTraversed != DfsTraversal.Alpha) {
- WriteCode((BasicBlock)succ, context, stmts);
- }
- }
-
- private void WriteWhileLoop(BasicBlock bb, Context context, List stmts) {
- context = context.NewLoop(bb.LoopHead, bb.LoopFollow);
-
- CodeWhileStatement loop;
- if (bb.Statements.Count > 1) {
- // emit a while(true) { $bb.stmts; if($condition) { $then_stmts; break; } ... }
- loop = new CodeWhileStatement {
- TestExpression = new CodePrimitiveExpression(true)
- };
-
- WriteIf(bb, context, loop.Statements);
- }
- else {
- CodeStatement last = bb.Statements.Last();
- CodeExpressionStatement ces = last as CodeExpressionStatement;
- CodeExpression test = ces.Expression;
-
- if (bb.ElseEdge.DfsPostOrder == bb.LoopFollow) {
- test = test.Invert();
- }
-
- // emit a pre-tested loop
- loop = new CodeWhileStatement {
- TestExpression = test
- };
- }
-
- stmts.Add(loop);
-
- if (bb != bb.LatchNode) {
- WriteLoopInner(bb, context, loop.Statements);
- }
-
- if (bb.LoopFollow != Node.NoNode) {
- WriteLoopFollow(bb, context, stmts);
- }
- }
-
- private void WriteRepeatLoop(BasicBlock bb, Context context, List stmts) {
- List temp = new List();
- int i = 0;
- for (i = 0; i < bb.Statements.Count - 1; i++) {
- temp.Add(bb.Statements[i]);
- }
- CodeStatement last = bb.Statements[i];
- CodeExpressionStatement ces = last as CodeExpressionStatement;
- CodeExpression test = ces.Expression;
- CodeRepeatStatement loop = new CodeRepeatStatement {
- TestExpression = test
- };
-
- stmts.Add(loop);
-
- if (bb != bb.LatchNode) {
- WriteLoopInner(bb, context, loop.Statements);
- }
-
- loop.Statements.AddRange(temp);
-
- if (bb.LoopFollow != Node.NoNode) {
- WriteLoopFollow(bb, context, stmts);
- }
- }
-
- private void WriteLoop(BasicBlock bb, Context context, List stmts) {
- switch (bb.LoopType) {
- case LoopType.While:
- WriteWhileLoop(bb, context, stmts);
- break;
- case LoopType.Repeat:
- WriteRepeatLoop(bb, context, stmts);
- break;
- case LoopType.Endless:
- Debug.Assert(false);
- //loop = new CodeWhileStatement {
- // TestExpression = new CodePrimitiveExpression(true)
- //};
- break;
- default:
- throw new InvalidOperationException();
- }
- }
-
- private void WriteCode(BasicBlock bb, Context context, List stmts) {
- if ((context.IfFollow != null) && (bb == context.IfFollow)) {
- return;
- }
- if (bb.DfsTraversed == DfsTraversal.Alpha) {
- return;
- }
- bb.DfsTraversed = DfsTraversal.Alpha;
-
- if (bb.LoopType != LoopType.None) {
- WriteLoop(bb, context, stmts);
- }
- else if (bb.IsTwoWay) {
- WriteIf(bb, context, stmts);
- }
- else if (bb.FlowControl == FlowControl.Return ||
- bb.FlowControl == FlowControl.Throw ||
- bb == context.LatchNode) {
- WriteBasicBlock(bb, context, stmts);
- return;
- }
- else if (bb.IsMultiWay) {
- WriteCases(bb, context, stmts);
- }
- else {
- WriteBasicBlock(bb, context, stmts);
- Node succ = bb.Successors.First();
- if (succ.DfsTraversed != DfsTraversal.Alpha) {
- WriteCode((BasicBlock)succ, context, stmts);
- }
- }
- }
-
- private void WriteCases(BasicBlock bb, Context context, List stmts) {
- int i = 0;
- for (i = 0; i < bb.Statements.Count - 1; i++) {
- stmts.Add(bb.Statements[i]);
- }
-
- CodeStatement last = bb.Statements[i];
- CodeSwitchStatement sw = last as CodeSwitchStatement;
- stmts.Add(sw);
-
- var cases = (Instruction[])bb.LastInstruction.Operand;
- Dictionary ccDict = new Dictionary();
- foreach (BasicBlock succ in bb.Successors) {
- CodeCase cc = new CodeCase();
- if (succ.DfsTraversed != DfsTraversal.Alpha) {
- WriteCode(succ, context.NewIfFollow(bb.CaseTail), cc.Statements);
- }
- ccDict.Add(succ.BeginOffset, cc);
- }
-
- for (int j = 0; j < cases.Length; j++) {
- int offset = cases[j].Offset;
- CodeCase cc = ccDict[offset];
- cc.Expressions.Add(new CodePrimitiveExpression(j));
- }
-
- sw.Cases.AddRange(ccDict.Values);
-
- if (bb.CaseTail != Node.NoNode) {
- /* Continue with the follow */
- Node next = this.Cfg.DepthFirstPostOrder[bb.CaseTail];
- if (next.DfsTraversed != DfsTraversal.Alpha) {
- WriteCode((BasicBlock)next, context, stmts);
- }
- }
- }
-
- private void WriteBasicBlock(BasicBlock bb, Context context, List stmts) {
- foreach (CodeStatement stmt in bb.Statements) {
- var gotoStmt = stmt as CodeGotoStatement;
- if (gotoStmt != null) {
- if (context.LoopFollow != null) {
- var bbFollow = (BasicBlock)context.LoopFollow;
- if (bbFollow.FirstInstruction == gotoStmt.Target) {
- stmts.Add(new CodeBreakStatement());
- continue;
- }
- }
- if (context.LoopHeader != null) {
- var bbHeader = (BasicBlock)context.LoopHeader;
- if (bbHeader.FirstInstruction == gotoStmt.Target) {
- stmts.Add(new CodeContinueStatement());
- continue;
- }
- }
- }
- else {
- stmts.Add(stmt);
- }
- }
- }
- }
-}
diff --git a/src/DotWeb.Decompiler/Core/ControlFlowAnalyzer.cs b/src/DotWeb.Decompiler/Core/ControlFlowAnalyzer.cs
deleted file mode 100644
index 61bd4a4..0000000
--- a/src/DotWeb.Decompiler/Core/ControlFlowAnalyzer.cs
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see .
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using DotWeb.Decompiler.CodeModel;
-using Mono.Cecil.Cil;
-using DotWeb.Utility;
-
-namespace DotWeb.Decompiler.Core
-{
- class ControlFlowAnalyzer
- {
- public ControlFlowGraph Cfg { get; private set; }
-
- public ControlFlowAnalyzer(ControlFlowGraph cfg) {
- this.Cfg = cfg;
- }
-
- public void Structure() {
- //CompoundConditions();
-
- FindImmediateDominator();
- if (Cfg.HasCases) {
- StructureCases();
- }
- StructureLoops();
- StructureIfs();
-
- //DisplayDfs(this.Cfg.Root);
- }
-
- private void DisplayDfs(BasicBlock bb) {
- bb.DfsTraversed = DfsTraversal.Display;
-
- Console.WriteLine("{0}: NodeType: {1}, in: {2}, out: {3}",
- bb.RefName, bb.FlowControl, bb.Predecessors.Count, bb.Successors.Count);
- Console.WriteLine("dfsFirst: {0}, dfsLast: {1}, immedDom: {2}",
- bb.DfsPreOrder, bb.DfsPreOrder, bb.ImmediateDominator);
-
- string latch = "(null)";
- if (bb.LatchNode != null)
- latch = bb.LatchNode.RefName;
- Console.WriteLine("LoopType: {0}, LoopHead: {1}, LatchNode: {2}, Follow: {3}",
- bb.LoopType, bb.LoopHead, latch, bb.LoopFollow);
- Console.WriteLine("IfFollow: {0}",
- bb.IfFollow);
- Console.WriteLine("----");
-
- foreach (Node node in bb.Successors) {
- if (node.IsInvalid)
- continue;
-
- if (node.DfsTraversed != DfsTraversal.Display)
- DisplayDfs((BasicBlock)node);
- }
- }
-
- ///
- /// Finds the immediate dominator of each node in the graph pProc->cfg.
- /// Adapted version of the dominators algorithm by Hecht and Ullman; finds
- /// immediate dominators only.
- /// Note: graph should be reducible
- ///
- private void FindImmediateDominator() {
- Node[] dfsList = this.Cfg.DepthFirstPostOrder;
- for (int curIndex = 0; curIndex < dfsList.Length; curIndex++) {
- Node node = dfsList[curIndex];
- if (node.IsInvalid)
- continue;
-
- foreach (Node pred in node.Predecessors) {
- int predIndex = pred.DfsPostOrder;
- if (predIndex < curIndex) {
- node.ImmediateDominator = CommonDominator(node.ImmediateDominator, predIndex);
- }
- }
- }
- }
-
- ///
- /// Finds the common dominator of the current immediate dominator
- /// currImmDom and its predecessor's immediate dominator predImmDom
- ///
- private int CommonDominator(int curImmDom, int predImmDom) {
- if (curImmDom == Node.NoDominator)
- return predImmDom;
- if (predImmDom == Node.NoDominator)
- return curImmDom;
- while ((curImmDom != Node.NoDominator) && (predImmDom != Node.NoDominator) &&
- (curImmDom != predImmDom)) {
- if (curImmDom < predImmDom)
- predImmDom = this.Cfg.DepthFirstPostOrder[predImmDom].ImmediateDominator;
- else
- curImmDom = this.Cfg.DepthFirstPostOrder[curImmDom].ImmediateDominator;
- }
- return curImmDom;
- }
-
- private bool IsSuccessor(int successor, int header)
- {
- return Cfg.DepthFirstPostOrder[header].Successors.Any(x => x.DfsPostOrder == successor);
- }
-
- private void StructureCases() {
- int exitNode = Node.NoNode;
- List caseNodes = new List();
-
- /* Linear scan of the nodes in reverse dfsLast order, searching for
- * case nodes */
- for (int i = Cfg.DepthFirstPostOrder.Length - 1; i >= 0; i--) {
- BasicBlock caseHeader = (BasicBlock)Cfg.DepthFirstPostOrder[i];
- if (caseHeader.IsInvalid)
- continue;
-
- if (caseHeader.LastInstruction.OpCode != OpCodes.Switch)
- continue;
-
- /* Find descendant node which has as immediate predecessor
- * the current header node, and is not a successor. */
- for (int j = i + 2; j < Cfg.DepthFirstPostOrder.Length; j++) {
- var node = Cfg.DepthFirstPostOrder[j];
- if (node.IsInvalid)
- continue;
-
- if (!IsSuccessor(j, i) && node.ImmediateDominator == i) {
- if (exitNode == Node.NoNode) {
- exitNode = j;
- }
- else if (Cfg.DepthFirstPostOrder[exitNode].Predecessors.Count < node.Predecessors.Count) {
- exitNode = j;
- }
- }
- }
- caseHeader.CaseTail = exitNode;
-
- /* Tag nodes that belong to the case by recording the
- * header field with caseHeader. */
-
- caseNodes.Add(i);
- caseHeader.CaseHead = i;
- foreach (BasicBlock node in caseHeader.Successors) {
- TagNodesInCase(node, caseNodes, i, exitNode);
- }
- if (exitNode != Node.NoNode) {
- Cfg.DepthFirstPostOrder[exitNode].CaseHead = i;
- }
- }
- }
-
- ///
- /// Recursive procedure to tag nodes that belong to the case described by
- /// the list l, head and tail (dfsLast index to first and exit node of the case).
- ///
- ///
- ///
- ///
- ///
- private void TagNodesInCase(BasicBlock node, ICollection list, int head, int tail) {
- node.DfsTraversed = DfsTraversal.Case;
- int current = node.DfsPostOrder;
- if ((current != tail) &&
- (node.LastInstruction.OpCode != OpCodes.Switch) &&
- list.Contains(node.ImmediateDominator)) {
- list.Add(current);
- node.CaseHead = head;
- foreach (BasicBlock bb in node.Successors) {
- if (bb.DfsTraversed != DfsTraversal.Case) {
- TagNodesInCase(bb, list, head, tail);
- }
- }
- }
- }
-
- ///
- /// Checks if the edge (p,s) is a back edge. If node s was visited first
- /// during the dfs traversal (ie. s has a smaller dfsFirst number) or s == p,
- /// then it is a backedge.
- /// Also incrementes the number of backedges entries to the header node.
- ///
- ///
- ///
- ///
- private bool IsBackEdge(Node pred, Node succ) {
- if (pred.DfsPreOrder >= succ.DfsPreOrder) {
- succ.BackEdgeCount++;
- return true;
- }
- return false;
- }
-
- private void StructureLoops() {
- foreach (var graph in this.Cfg.Sequences) {
- foreach (Interval interval in graph.Nodes) {
- StructureLoopForInterval(interval);
- }
- }
- }
-
- private void StructureLoopForInterval(Interval interval) {
- // Find nodes that belong to the interval (nodes from G1)
- List nodes = new List();
- interval.CollectNodes(nodes);
- BasicBlock head = (BasicBlock)nodes.First();
-
- BasicBlock latchNode = null;
- // Find greatest enclosing back edge (if any)
- foreach (BasicBlock pred in head.Predecessors) {
- if (nodes.Contains(pred) && IsBackEdge(pred, head)) {
- if (latchNode == null) {
- latchNode = pred;
- }
- else {
- if (pred.DfsPostOrder > latchNode.DfsPostOrder)
- latchNode = pred;
- }
- }
- }
-
- /* Find nodes in the loop and the type of loop */
- if (latchNode != null) {
- // Check latching node is at the same nesting level of case
- // statements (if any) and that the node doesn't belong to
- // another loop.
- if ((latchNode.CaseHead == head.CaseHead) &&
- (latchNode.LoopHead == Node.NoNode)) {
- head.LatchNode = latchNode;
- FindNodesInLoop(latchNode, head, nodes);
- latchNode.IsLatchNode = true;
- }
- }
- }
-
- ///
- /// Flags nodes that belong to the loop determined by (latchNode, head) and
- /// determines the type of loop.
- ///
- ///
- ///
- ///
- private void FindNodesInLoop(BasicBlock latchNode, BasicBlock headerNode, List nodes) {
- headerNode.LoopHead = headerNode.DfsPostOrder;
-
- List loopNodes = new List();
- loopNodes.Add(headerNode.LoopHead);
-
- for (int i = headerNode.LoopHead + 1; i < latchNode.DfsPostOrder; i++) {
- Node node = this.Cfg.DepthFirstPostOrder[i];
- if (node.IsInvalid)
- continue;
-
- int immedDom = node.ImmediateDominator;
- if (loopNodes.Contains(immedDom) && nodes.Contains(node)) {
- loopNodes.Add(i);
- if (node.LoopHead == Node.NoNode) {
- node.LoopHead = headerNode.LoopHead;
- }
- }
- }
-
- latchNode.LoopHead = headerNode.LoopHead;
- if (latchNode != headerNode) {
- loopNodes.Add(latchNode.DfsPostOrder);
- }
-
- ClassifyLoop(headerNode, latchNode, loopNodes);
- }
-
- private void ClassifyLoop(BasicBlock headerNode, BasicBlock latchNode, List loopNodes) {
- int thenDfs = headerNode.ThenEdge.DfsPostOrder;
- int elseDfs = Node.NoNode;
- if (headerNode.Successors.Count > 1)
- elseDfs = headerNode.ElseEdge.DfsPostOrder;
-
- if (latchNode.IsTwoWay) {
- if ((headerNode.IsTwoWay) || (latchNode == headerNode)) {
- if ((latchNode == headerNode) ||
- loopNodes.Contains(thenDfs) &&
- loopNodes.Contains(elseDfs)) {
- headerNode.LoopType = LoopType.Repeat;
- if (latchNode.ThenEdge == headerNode)
- headerNode.LoopFollow = latchNode.ElseEdge.DfsPostOrder;
- else
- headerNode.LoopFollow = latchNode.ThenEdge.DfsPostOrder;
- latchNode.IsLoopNode = true;
- }
- else {
- headerNode.LoopType = LoopType.While;
- if (loopNodes.Contains(thenDfs))
- headerNode.LoopFollow = elseDfs;
- else
- headerNode.LoopFollow = thenDfs;
- headerNode.IsLoopNode = true;
- }
- }
- else {
- // head = anything besides 2-way, latch = 2-way
- headerNode.LoopType = LoopType.Repeat;
- if (latchNode.ThenEdge == headerNode)
- headerNode.LoopFollow = latchNode.ElseEdge.DfsPostOrder;
- else
- headerNode.LoopFollow = latchNode.ThenEdge.DfsPostOrder;
- latchNode.IsLoopNode = true;
- }
- }
- else {
- // latch = 1-way
- if (headerNode.IsTwoWay) {
- headerNode.LoopType = LoopType.While;
- Node node = latchNode;
- while (true) {
- if (node.DfsPostOrder == thenDfs) {
- headerNode.LoopFollow = elseDfs;
- break;
- }
- else if (node.DfsPostOrder == elseDfs) {
- headerNode.LoopFollow = thenDfs;
- break;
- }
- // Check if couldn't find it, then it is a strangely formed
- // loop, so it is safer to consider it an endless loop
- if (node.DfsPostOrder <= headerNode.DfsPostOrder) {
- headerNode.LoopType = LoopType.Endless;
- FindEndlessFollow(loopNodes, headerNode);
- break;
- }
-
- node = this.Cfg.DepthFirstPostOrder[node.ImmediateDominator];
- }
-
- if (node.DfsPostOrder > headerNode.DfsPostOrder) {
- this.Cfg.DepthFirstPostOrder[headerNode.LoopFollow].LoopHead = Node.NoNode;
- }
- headerNode.IsLoopNode = true;
- }
- else {
- headerNode.LoopType = LoopType.Endless;
- FindEndlessFollow(loopNodes, headerNode);
- }
- }
- }
-
- private void FindEndlessFollow(List loopNodes, BasicBlock head) {
- head.LoopFollow = int.MaxValue;
-
- foreach (var i in loopNodes) {
- var node = this.Cfg.DepthFirstPostOrder[i];
- if (node.IsInvalid)
- continue;
-
- foreach (var succ in node.Successors) {
- if (!loopNodes.Contains(succ.DfsPostOrder) &&
- (succ.DfsPostOrder < head.LoopFollow)) {
- head.LoopFollow = succ.DfsPostOrder;
- }
- }
- }
- }
-
- private void StructureIfs() {
- var bbCount = this.Cfg.DepthFirstPostOrder.Length;
- var unresolved = new List();
-
- // Linear scan of nodes in reverse dfsLast order
- for (int cur = bbCount - 1; cur >= 0; cur--) {
- BasicBlock curNode = (BasicBlock)this.Cfg.DepthFirstPostOrder[cur];
- if (curNode.IsInvalid)
- continue;
-
- if (curNode.IsTwoWay && !curNode.IsLoopNode) {
- int followInEdges = 0;
- int follow = 0;
-
- // Find all nodes that have this node as immediate dominator
- for (int desc = cur + 1; desc < bbCount; desc++) {
- Node node = this.Cfg.DepthFirstPostOrder[desc];
- if (node.IsInvalid)
- continue;
-
- if (node.ImmediateDominator == cur) {
- int delta = node.Predecessors.Count - node.BackEdgeCount;
- if (delta >= followInEdges) {
- follow = desc;
- followInEdges = delta;
- }
- }
- }
-
- // Determine follow according to number of descendants
- // immediately dominated by this node
- if ((follow != 0) && (followInEdges > 1)) {
- curNode.IfFollow = follow;
- if (unresolved.Any()) {
- FlagNodes(unresolved, follow);
- }
- }
- else {
- unresolved.Add(curNode);
- }
- }
- }
- }
-
- private void FlagNodes(List list, int follow) {
- while (list.Any()) {
- var node = list.Dequeue();
- node.IfFollow = follow;
- }
- }
- }
-}