public virtual void Run() { foreach (var b in graph.GetVertices()) { Out[b] = Top; } var nodes = new HashSet <CFGNode>(graph.GetVertices()); //nodes.Remove(graph.GetRoot()); var cont = true; while (cont) { cont = false; foreach (var node in nodes) { In[node] = MeetOp(node.ParentsNodes); var prevOut = Out[node]; var newOut = Out[node] = TransferFunc(node); if (ContCond(prevOut, newOut)) { cont = true; } } } }
public void analyze() { var firstBlock = cfg.GetVertices().First(); var vertces = cfg.GetVertices(); // Инициализируем для кажлого ББЛ кроме прервого список выходных выражений равный U (множество всех выражений) foreach (var vertce in vertces) { if (firstBlock != vertce.Value) { OutBlocks[vertce.Value] = new List <Expression>(genKills.AllExpressions); } } bool hasChanges = true; while (hasChanges) { hasChanges = false; foreach (var vertce in vertces) { if (firstBlock != vertce.Value) { // Добавляем во входные выражения все выражения, которые выходят из родительских блоков foreach (var parent in vertce.ParentsNodes) { InBlocks[vertce.Value] = UnionNodes(InBlocks[vertce.Value], OutBlocks[parent.Value]); } //Копируем старый список выходных выражений для сравнения в будущем var oldOut = new List <Expression>(OutBlocks[vertce.Value]); // IN[B] - e_kill_B - убиваем в списке входных выражений те, которые будут убиты в текущем базовом блоке var resNodes = ResidualNodes(InBlocks[vertce.Value], genKills.Remove[vertce.Value]); // объединяем оставшиеся IN[B] с e_gen_B, т.е. все что осталось после кровавой резни между IN и e_kill объединяем с тем, что родилось в данном ББЛ // Cохраняем это все как выходные выражения для текущего базового блока OutBlocks[vertce.Value] = UnionNodes(genKills.Gen[vertce.Value], resNodes); // Если мы поменяли список выходных вырожений, то мы обязаны снова пройти по всем блокам и пересчитать вход/выход, ибо наш вход опирается на выходы других блоков, которые могли быть изменены if (!EqualNodes(OutBlocks[vertce.Value], oldOut)) { hasChanges = true; } } } } }
public RegionSequence(CFGraph cfg) { regions = new List <Region>(); // Get all nodes of cfg List <CFGNode> allNodes = cfg.GetVertices().ToList(); // All edges in cfg List <Edge <CFGNode> > edges = cfg.EdgeTypes.Select(e => e.Key).ToList(); // Each node in cfg is leaf region foreach (var node in cfg.GetVertices()) { var edgesFromNode = edges.FindAll(e => e.Target == node); regions.Add(new LeafRegion(node, edges, NextName())); } var nc = cfg.getNaturalCyclesForBackwardEdges(); // Nodes which are headers of natural cycles HashSet <CFGNode> cyclesHeaders = new HashSet <CFGNode>(nc.Select(c => c[0])); // Headers of cycles. These cycles are added to list of regions HashSet <CFGNode> addedCyclesHeaders = new HashSet <CFGNode>(); while (nc.Count > 0) { // List of cycles we can add into regions (there are no nonadded cycles inside) List <List <CFGNode> > cyclesToAdd = nc.FindAll(c => c.Skip(1).All(node => { // If node is header of cycle then it should be added in list of regions return(cyclesHeaders.Contains(node) ? addedCyclesHeaders.Contains(node) : true); })); foreach (var cycle in cyclesToAdd) { var nodes = new HashSet <CFGNode>(cycle); AddCycle(cycle, edges, nodes); addedCyclesHeaders.Add(cycle[0]); } nc.RemoveAll(c => addedCyclesHeaders.Contains(c[0])); } // cfg is natural cycle if there is cycle header equals first node of cfg bool cfgIsNaturalCycle = cyclesHeaders.Contains(allNodes[0]); // If cfg isn't natural cycle then add region contains all nodes and edges if (!cfgIsNaturalCycle) { regions.Add(new BodyRegion(allNodes[0], allNodes, edges, NextName())); } }
public AvailableExprAnalyzer(CFGraph _cfg) { cfg = _cfg; // Генерируем e_gen и e_kills genKills = new GenKillExprs(cfg); // Инициализируем для всех ББЛ пустые списки с входными выражениями foreach (var vertice in cfg.GetVertices()) { InBlocks.Add(vertice.Value, new List <Expression>()); } }