/// <summary> /// Создать узлы графа потока управления программы /// </summary> private void CreateCFGNodes() { // оборачиваем ББ в CFG foreach (var block in Code.CreateBasicBlockList()) { _cfgNodes.Add(block); CFGAuxiliary.AddVertex(block); } foreach (var cfgNode in _cfgNodes) { // блок содержит GoTo в последней строке if (cfgNode.CodeList.Last() is Goto gt) { // ищем на какую строку идет переход var targetFirst = Code.LabeledCode[gt.TargetLabel]; // забираем информацию о том, какому блоку принадлежит эта строка var targetNode = _cfgNodes.First(n => n.Equals(targetFirst.Block)); // устанавливаем связи cfgNode <-> targetNode cfgNode.AddChild(targetNode); targetNode.AddParent(cfgNode); CFGAuxiliary.AddEdge(new Edge<BasicBlock>(cfgNode, targetNode)); } } // каждый блок является родителем последующего var nodeList = CFGNodes.ToList(); for (int i = 0; i < nodeList.Count - 1; ++i) { var cur = nodeList[i]; var next = nodeList[i + 1]; // если последняя строчка -- чистый goto (не if), то дуги быть не может if (cur.CodeList.Last().GetType() == typeof(Goto)) continue; cur.AddChild(next); next.AddParent(cur); CFGAuxiliary.AddEdge(new Edge<BasicBlock>(cur, next)); } EdgeTypes = new EdgeTypes(); //ClassificateEdges(); }
public BasicBlock GetRoot() { return (NumberOfVertices() > 0) ? CFGNodes.ElementAt(0) : null; }