void CreateEdge(ControlFlowNode fromNode, ControlFlowNode toNode, JumpType type) { ControlFlowEdge edge = new ControlFlowEdge(fromNode, toNode, type); fromNode.Outgoing.Add(edge); toNode.Incoming.Add(edge); }
ControlFlowGraph BuildGraph(List<ILNode> nodes, ILLabel entryLabel) { int index = 0; List<ControlFlowNode> cfNodes = new List<ControlFlowNode>(); ControlFlowNode entryPoint = new ControlFlowNode(index++, 0, ControlFlowNodeType.EntryPoint); cfNodes.Add(entryPoint); ControlFlowNode regularExit = new ControlFlowNode(index++, -1, ControlFlowNodeType.RegularExit); cfNodes.Add(regularExit); ControlFlowNode exceptionalExit = new ControlFlowNode(index++, -1, ControlFlowNodeType.ExceptionalExit); cfNodes.Add(exceptionalExit); // Create graph nodes labelToCfNode = new Dictionary<ILLabel, ControlFlowNode>(); Dictionary<ILNode, ControlFlowNode> astNodeToCfNode = new Dictionary<ILNode, ControlFlowNode>(); foreach(ILBasicBlock node in nodes) { ControlFlowNode cfNode = new ControlFlowNode(index++, -1, ControlFlowNodeType.Normal); cfNodes.Add(cfNode); astNodeToCfNode[node] = cfNode; cfNode.UserData = node; // Find all contained labels foreach(ILLabel label in node.GetSelfAndChildrenRecursive<ILLabel>()) { labelToCfNode[label] = cfNode; } } // Entry endge ControlFlowNode entryNode = labelToCfNode[entryLabel]; ControlFlowEdge entryEdge = new ControlFlowEdge(entryPoint, entryNode, JumpType.Normal); entryPoint.Outgoing.Add(entryEdge); entryNode.Incoming.Add(entryEdge); // Create edges foreach(ILBasicBlock node in nodes) { ControlFlowNode source = astNodeToCfNode[node]; // Find all branches foreach(ILLabel target in node.GetSelfAndChildrenRecursive<ILExpression>(e => e.IsBranch()).SelectMany(e => e.GetBranchTargets())) { ControlFlowNode destination; // Labels which are out of out scope will not be in the collection // Insert self edge only if we are sure we are a loop if (labelToCfNode.TryGetValue(target, out destination) && (destination != source || target == node.Body.FirstOrDefault())) { ControlFlowEdge edge = new ControlFlowEdge(source, destination, JumpType.Normal); source.Outgoing.Add(edge); destination.Incoming.Add(edge); } } } return new ControlFlowGraph(cfNodes.ToArray()); }