public void PropagatePrecondition(Func <string, Implementation> NameToImpl, Action <string, IWeight> SetPrecondition) { foreach (var node in Nodes) { node.weight = iw.Zero(impl); } entryNode.weight = precondition; var worklist = new SortedSet <Node>(entryNode); worklist.Add(entryNode); while (worklist.Any()) { var node = worklist.First(); worklist.Remove(node); foreach (var edge in node.Successors) { var c = edge.PropagatePrecondition(ProcSummary, NameToImpl, SetPrecondition); if (c) { worklist.Add(edge.tgt); } } } }
public IntraGraph(Implementation impl, IWeight iw, Func <string, IWeight> ProcSummary) { this.impl = impl; this.Id = impl.Name; this.ProcSummary = ProcSummary; priority = 0; idToNode = new Dictionary <string, Node>(); Nodes = new List <Node>(); Edges = new List <Edge>(); calleeToEdgeSrc = new Dictionary <string, HashSet <Node> >(); this.iw = iw; this.summary = iw.Zero(impl); this.precondition = iw.Zero(impl); returnNodes = new List <Node>(); summaryChanged = false; preconditionChanged = false; computedBefore = false; // Create nodes foreach (var block in impl.Blocks) { var n1 = new Node(block.Label + "::in", iw.Zero(impl)); var n2 = new Node(block.Label + "::out", iw.Zero(impl)); Nodes.Add(n1); Nodes.Add(n2); var edge = new Edge(n1, n2, block.Cmds.OfType <Cmd>()); n1.AddEdge(edge); n2.AddEdge(edge); Edges.Add(edge); // return nodes if (block.TransferCmd is ReturnCmd) { returnNodes.Add(n2); } // calls foreach (var callee in edge.Callees) { if (!calleeToEdgeSrc.ContainsKey(callee)) { calleeToEdgeSrc.Add(callee, new HashSet <Node>()); } calleeToEdgeSrc[callee].Add(n1); } } Nodes.Iter(n => idToNode.Add(n.Id, n)); entryNode = idToNode[impl.Blocks[0].Label + "::in"]; // connecting edges foreach (var block in impl.Blocks) { var gc = block.TransferCmd as GotoCmd; if (gc == null) { continue; } var src = idToNode[block.Label + "::out"]; var edges = gc.labelNames .OfType <string>() .Select(s => idToNode[s + "::in"]) .Select(tgt => new Edge(src, tgt, new Cmd[] { })); edges.Iter(e => { Edges.Add(e); e.src.AddEdge(e); e.tgt.AddEdge(e); }); } // Compute priorities var sccs = new StronglyConnectedComponents <Node>(Nodes, new Adjacency <Node>(n => n.Successors.Select(e => e.tgt)), new Adjacency <Node>(n => n.Predecessors.Select(e => e.src))); sccs.Compute(); int p = 0; foreach (var scc in sccs) { scc.Iter(n => n.priority = p); p++; } }