public List <Interval> BuildIntervals(DirectedGraph <StructureNode> graph, StructureNode entry) { if (graph == null) { throw new ArgumentNullException("graph"); } if (entry == null) { throw new ArgumentNullException("entry"); } var intervalsInGraph = new List <Interval>(); // The sequence of intervals in this graph var headers = new WorkList <StructureNode>(); // The sequence of interval header nodes var beenInH = new HashSet <StructureNode>(); // The set of nodes that have been in the above sequence at some stage headers.Add(entry); beenInH.Add(entry); StructureNode header; while (headers.GetWorkItem(out header)) { Interval newInt = new Interval(intervalID++, header); // Process each succesive node in the interval until no more nodes can be added to the interval. for (int i = 0; i < newInt.Nodes.Count; i++) { StructureNode curNode = newInt.Nodes[i]; foreach (StructureNode succ in graph.Successors(curNode)) { // Only further consider the current child if it isn't already in the interval if (!newInt.Nodes.Contains(succ)) { // If the current child has all its parents // inside the interval, then add it to the interval. Remove it from the header // sequence if it is on it. if (IsSubSetOf(graph.Predecessors(succ), newInt)) { newInt.AddNode(succ); headers.Remove(succ); } // Otherwise, add it to the header sequence if it hasn't already been in it. else if (!beenInH.Contains(succ)) { headers.Add(succ); beenInH.Add(succ); } } } } // Add the new interval to the sequence of intervals intervalsInGraph.Add(newInt); } return(intervalsInGraph); }
public void BuildIntervals(DerivedGraph derGraph) { if (derGraph == null) throw new ArgumentNullException("derGraph"); if (derGraph.Entry == null) throw new ArgumentException("cfg graph must be non-null.", "derGraph"); var intSeq = derGraph.Intervals; // The sequence of intervals in this graph var headerSeq = new WorkList<StructureNode>(); // The sequence of interval header nodes var beenInH = new List<StructureNode>(); // The set of nodes that have been in the above sequence at some stage headerSeq.Add(derGraph.Entry); beenInH.Add(derGraph.Entry); StructureNode header; while (headerSeq.GetWorkItem(out header)) { var newInt = new Interval(intervalID++, header); // Process each succesive node in the interval until no more nodes can be added to the interval. for (int i = 0; i < newInt.Nodes.Count; i++) { var curNode = newInt.Nodes[i]; // Process each child of the current node for (int j = 0; j < curNode.OutEdges.Count; j++) { var succ = curNode.OutEdges[j]; // Only further consider the current child if it isn't already in the interval if (!newInt.Nodes.Contains(succ)) { // If the current child has all its parents // inside the interval, then add it to the interval. Remove it from the header // sequence if it is on it. if (IsSubSetOf(succ.InEdges, newInt)) { newInt.AddNode(succ); headerSeq.Remove(succ); } // Otherwise, add it to the header sequence if it hasn't already been in it. else if (!beenInH.Contains(succ)) { headerSeq.Add(succ); beenInH.Add(succ); } } } } // Add the new interval to the sequence of intervals intSeq.Add(newInt); } }
public void WlAdd() { WorkList<int> w = new WorkList<int>(); w.Add(3); Assert.IsFalse(w.IsEmpty); int x; Assert.IsTrue(w.GetWorkItem(out x)); Assert.AreEqual(3, x); Assert.IsTrue(w.IsEmpty); }
public void WlAdd() { WorkList <int> w = new WorkList <int>(); w.Add(3); Assert.IsFalse(w.IsEmpty); int x; Assert.IsTrue(w.GetWorkItem(out x)); Assert.AreEqual(3, x); Assert.IsTrue(w.IsEmpty); }
public void WlRemove() { WorkList<int> w = new WorkList<int>(); w.Add(3); w.Add(2); Assert.IsFalse(w.IsEmpty); w.Remove(3); Assert.IsFalse(w.IsEmpty); w.Remove(2); Assert.IsTrue(w.IsEmpty); int x; Assert.IsFalse(w.GetWorkItem(out x)); }
private HashSet <Statement> PlacePhiFunctions() { HashSet <Statement> phiStatements = new HashSet <Statement>(); var defVars = LocateAllDefinedVariables(AOrig); MarkTemporariesDeadIn(AOrig); // For each defined variable in block n, collect the places where it is defined foreach (var a in defVars) { // Create a worklist W of all the blocks that define a. var W = new WorkList <Block>(); foreach (Block b in SsaState.DomGraph.ReversePostOrder.Keys) { byte bits; AOrig[SsaState.RpoNumber(b)].TryGetValue(a, out bits); if ((bits & BitDefined) != 0) { W.Add(b); } } Block n; while (W.GetWorkItem(out n)) { foreach (Block y in SsaState.DomGraph.DominatorFrontier(n)) { // Only add phi functions if there is no // phi already and variable is not deadIn. var dict = AOrig[SsaState.RpoNumber(y)]; byte bits; dict.TryGetValue(a, out bits); if ((bits & (BitHasPhi | BitDeadIn)) == 0) { bits |= BitHasPhi; dict[a] = bits; var stm = InsertPhiStatement(y, a); phiStatements.Add(stm); if ((bits & BitDefined) == 0) { W.Add(y); } } } } } return(phiStatements); }
public void WlRemove() { WorkList <int> w = new WorkList <int>(); w.Add(3); w.Add(2); Assert.IsFalse(w.IsEmpty); w.Remove(3); Assert.IsFalse(w.IsEmpty); w.Remove(2); Assert.IsTrue(w.IsEmpty); int x; Assert.IsFalse(w.GetWorkItem(out x)); }
public DataType BuildOverlappedStructure(List<StructureField> fields) { List<StructureType> types = new List<StructureType>(); int commonOffset = CommonOffset(fields); StructureField field; WorkList<StructureField> worklist = new WorkList<StructureField>(fields); while (worklist.GetWorkItem(out field)) { StructureType s = FindStructureToFitIn(field, commonOffset, types); if (s == null) { s = new StructureType(); types.Add(s); } s.Fields.Add(new StructureField(field.Offset - commonOffset, field.DataType)); } return Normalize(types); }
public void ReplaceDefinitionsWithOutParameter(Identifier id, Identifier idOut) { this.idOut = idOut; wl = new WorkList <Identifier>(); wl.Add(id); var visited = new HashSet <Statement>(); while (wl.GetWorkItem(out id)) { ssa = ssaIds[id]; stmDef = ssa.DefStatement; if (stmDef != null && !visited.Contains(stmDef)) { visited.Add(stmDef); iStmDef = stmDef.Block.Statements.IndexOf(stmDef); stmDef.Instruction = stmDef.Instruction.Accept(this); } } }
public void ReplaceDefinitionsWithOutParameter(Identifier id, Identifier idOut) { this.idOut = idOut; wl = new WorkList<Identifier>(); wl.Add(id); var visited = new HashSet<Statement>(); while (wl.GetWorkItem(out id)) { ssa = ssaIds[id]; stmDef = ssa.DefStatement; if (stmDef != null && !visited.Contains(stmDef)) { visited.Add(stmDef); iStmDef = stmDef.Block.Statements.IndexOf(stmDef); stmDef.Instruction = stmDef.Instruction.Accept(this); } } }
public DataType BuildOverlappedStructure(List <StructureField> fields) { List <StructureType> types = new List <StructureType>(); int commonOffset = CommonOffset(fields); StructureField field; WorkList <StructureField> worklist = new WorkList <StructureField>(fields); while (worklist.GetWorkItem(out field)) { StructureType s = FindStructureToFitIn(field, commonOffset, types); if (s == null) { s = new StructureType(); types.Add(s); } s.Fields.Add(new StructureField(field.Offset - commonOffset, field.DataType)); } return(Normalize(types)); }
/// <summary> /// As far as possible, try fusing consecutive linear blocks in the /// cluster. /// </summary> /// <param name="cluster"></param> public void FuseLinearBlocks(Cluster cluster) { var wl = new WorkList <RtlBlock>(cluster.Blocks); RtlBlock block; while (wl.GetWorkItem(out block)) { if (sr.ICFG.Successors(block).Count != 1) { continue; } var succ = sr.ICFG.Successors(block).First(); if (sr.ICFG.Predecessors(succ).Count != 1) { continue; } Debug.Assert(sr.ICFG.Predecessors(succ).First() == block, "Inconsistent graph"); if (!(block.Instructions.Last().Instructions.Last() is RtlAssignment)) { continue; } // Move all instructions into predecessor. block.Instructions.AddRange(succ.Instructions); sr.ICFG.RemoveEdge(block, succ); var succSuccs = sr.ICFG.Successors(succ).ToList(); foreach (var ss in succSuccs) { sr.ICFG.RemoveEdge(succ, ss); sr.ICFG.AddEdge(block, ss); } cluster.Blocks.Remove(succ); // May be more blocks. wl.Add(block); } }
private State [] BuildDfaTable(Node n) { List <State> dStates = new List <State>(); // Create the default, error state. State err = new State(new BitArray(n.FirstPos.Length), charClasses); AddState(dStates, err); // Create the initial state. State s0 = new State(n.FirstPos, charClasses); AddState(dStates, s0); // Start the worklist. WorkList <State> worklist = new WorkList <State>(); worklist.Add(s0); State t; while (worklist.GetWorkItem(out t)) { Debug.WriteLine(t.ToString()); for (int a = 0; a != charClasses; ++a) { // Create U, a state consisting of the positions in // FollowPos(p) where p is any position in t that has // an 'a'. State u = new State(new BitArray(positions.Count), charClasses); for (int p = 0; p != t.Positions.Length; ++p) { if (!t.Positions[p]) { continue; } ByteNode pp = (ByteNode)positions[p]; if (pp.Any || alphabet[pp.startByte] == a) { u.Positions.Or(pp.FollowPos); } t.Accepts |= pp.Accepts; } if (IsEmptySet(u.Positions)) { u = null; } else { State uu = FindState(dStates, u.Positions); if (uu == null) { AddState(dStates, u); worklist.Add(u); } else { u = uu; } } t.NextState[a] = u; } Debug.WriteLine("t complete: " + t); } return(dStates.ToArray()); }
private void PlacePhiFunctions() { var defVars = LocateAllDefinedVariables(AOrig); MarkTemporariesDeadIn(AOrig); // For each defined variable in block n, collect the places where it is defined foreach (var a in defVars) { // Create a worklist W of all the blocks that define a. var W = new WorkList<Block>(); foreach (Block b in SsaState.DomGraph.ReversePostOrder.Keys) { byte bits; AOrig[SsaState.RpoNumber(b)].TryGetValue(a, out bits); if ((bits & BitDefined) != 0) W.Add(b); } Block n; while (W.GetWorkItem(out n)) { foreach (Block y in SsaState.DomGraph.DominatorFrontier(n)) { // Only add phi functions if there is no // phi already and variable is not deadIn. var dict = AOrig[SsaState.RpoNumber(y)]; byte bits; dict.TryGetValue(a, out bits); if ((bits & (BitHasPhi | BitDeadIn)) == 0) { bits |= BitHasPhi; dict[a] = bits; InsertPhiStatement(y, a); if ((bits & BitDefined) == 0) { W.Add(y); } } } } } }
private void Eliminate() { liveIds = new WorkList <SsaIdentifier>(); HashSet <Statement> marks = new HashSet <Statement>(); // Initially, just mark those statements that contain critical statements. // These are calls to other functions, functions (which have side effects) and use statements. // Critical instructions must never be considered dead. foreach (var stm in proc.Statements) { if (critical.IsCritical(stm.Instruction)) { if (trace.TraceInfo) { Debug.WriteLineIf(trace.TraceInfo, string.Format("Critical: {0}", stm.Instruction)); } marks.Add(stm); stm.Instruction.Accept(this); // mark all used identifiers as live. } } // Each identifier is live, so its defining statement is also live. SsaIdentifier sid; while (liveIds.GetWorkItem(out sid)) { Statement def = sid.DefStatement; if (def != null) { if (!marks.Contains(def)) { if (trace.TraceInfo) { Debug.WriteLine(string.Format("Marked: {0}", def.Instruction)); } marks.Add(def); sid.DefStatement.Instruction.Accept(this); } } } // We have now marked all the useful instructions in the code. Any non-marked // instruction is now useless and should be deleted. foreach (Block b in proc.ControlGraph.Blocks) { for (int iStm = 0; iStm < b.Statements.Count; ++iStm) { Statement stm = b.Statements[iStm]; if (!marks.Contains(stm)) { if (trace.TraceInfo) { Debug.WriteLineIf(trace.TraceInfo, string.Format("Deleting: {0}", stm.Instruction)); } ssa.DeleteStatement(stm); --iStm; } } } AdjustApplicationsWithDeadReturnValues(); }
public List<Interval> BuildIntervals(DirectedGraph<StructureNode> graph, StructureNode entry) { if (graph == null) throw new ArgumentNullException("graph"); if (entry == null) throw new ArgumentNullException("entry"); var intervalsInGraph = new List<Interval>(); // The sequence of intervals in this graph var headers = new WorkList<StructureNode>(); // The sequence of interval header nodes var beenInH = new HashSet<StructureNode>(); // The set of nodes that have been in the above sequence at some stage headers.Add(entry); beenInH.Add(entry); StructureNode header; while (headers.GetWorkItem(out header)) { Interval newInt = new Interval(intervalID++, header); // Process each succesive node in the interval until no more nodes can be added to the interval. for (int i = 0; i < newInt.Nodes.Count; i++) { StructureNode curNode = newInt.Nodes[i]; foreach (StructureNode succ in graph.Successors(curNode)) { // Only further consider the current child if it isn't already in the interval if (!newInt.Nodes.Contains(succ)) { // If the current child has all its parents // inside the interval, then add it to the interval. Remove it from the header // sequence if it is on it. if (IsSubSetOf(graph.Predecessors(succ), newInt)) { newInt.AddNode(succ); headers.Remove(succ); } // Otherwise, add it to the header sequence if it hasn't already been in it. else if (!beenInH.Contains(succ)) { headers.Add(succ); beenInH.Add(succ); } } } } // Add the new interval to the sequence of intervals intervalsInGraph.Add(newInt); } return intervalsInGraph; }
private State [] BuildDfaTable(Node n) { List<State> dStates = new List<State>(); // Create the default, error state. State err = new State(new BitArray(n.FirstPos.Length), charClasses); AddState(dStates, err); // Create the initial state. State s0 = new State(n.FirstPos, charClasses); AddState(dStates, s0); // Start the worklist. WorkList<State> worklist = new WorkList<State>(); worklist.Add(s0); State t; while (worklist.GetWorkItem(out t)) { Debug.WriteLine(t.ToString()); for (int a = 0; a != charClasses; ++a) { // Create U, a state consisting of the positions in // FollowPos(p) where p is any position in t that has // an 'a'. State u = new State(new BitArray(positions.Count), charClasses); for (int p = 0; p != t.Positions.Length; ++p) { if (!t.Positions[p]) continue; ByteNode pp = (ByteNode) positions[p]; if (pp.Any || alphabet[pp.startByte] == a) { u.Positions.Or(pp.FollowPos); } t.Accepts |= pp.Accepts; } if (IsEmptySet(u.Positions)) { u = null; } else { State uu = FindState(dStates, u.Positions); if (uu == null) { AddState(dStates, u); worklist.Add(u); } else { u = uu; } } t.NextState[a] = u; } Debug.WriteLine("t complete: " + t); } return dStates.ToArray(); }
private void Eliminate() { liveIds = new WorkList<SsaIdentifier>(); HashSet<Statement> marks = new HashSet<Statement>(); // Initially, just mark those statements that contain critical statements. // These are calls to other functions, functions (which have side effects) and use statements. // Critical instructions must never be considered dead. foreach (var stm in proc.Statements) { if (critical.IsCritical(stm.Instruction)) { if (trace.TraceInfo) Debug.WriteLineIf(trace.TraceInfo, string.Format("Critical: {0}", stm.Instruction)); marks.Add(stm); stm.Instruction.Accept(this); // mark all used identifiers as live. } } // Each identifier is live, so its defining statement is also live. SsaIdentifier sid; while (liveIds.GetWorkItem(out sid)) { Statement def = sid.DefStatement; if (def != null) { if (!marks.Contains(def)) { if (trace.TraceInfo) Debug.WriteLine(string.Format("Marked: {0}", def.Instruction)); marks.Add(def); sid.DefStatement.Instruction.Accept(this); } } } // We have now marked all the useful instructions in the code. Any non-marked // instruction is now useless and should be deleted. foreach (Block b in proc.ControlGraph.Blocks) { for (int iStm = 0; iStm < b.Statements.Count; ++iStm) { Statement stm = b.Statements[iStm]; if (!marks.Contains(stm)) { if (trace.TraceInfo) Debug.WriteLineIf(trace.TraceInfo, string.Format("Deleting: {0}", stm.Instruction)); ssa.DeleteStatement(stm); --iStm; } } } AdjustApplicationsWithDeadReturnValues(); }
public void BuildIntervals(DerivedGraph derGraph) { if (derGraph == null) { throw new ArgumentNullException("derGraph"); } if (derGraph.Entry == null) { throw new ArgumentException("cfg graph must be non-null.", "derGraph"); } var intSeq = derGraph.Intervals; // The sequence of intervals in this graph var headerSeq = new WorkList <StructureNode>(); // The sequence of interval header nodes var beenInH = new List <StructureNode>(); // The set of nodes that have been in the above sequence at some stage headerSeq.Add(derGraph.Entry); beenInH.Add(derGraph.Entry); StructureNode header; while (headerSeq.GetWorkItem(out header)) { var newInt = new Interval(intervalID++, header); // Process each succesive node in the interval until no more nodes can be added to the interval. for (int i = 0; i < newInt.Nodes.Count; i++) { var curNode = newInt.Nodes[i]; // Process each child of the current node for (int j = 0; j < curNode.OutEdges.Count; j++) { var succ = curNode.OutEdges[j]; // Only further consider the current child if it isn't already in the interval if (!newInt.Nodes.Contains(succ)) { // If the current child has all its parents // inside the interval, then add it to the interval. Remove it from the header // sequence if it is on it. if (IsSubSetOf(succ.InEdges, newInt)) { newInt.AddNode(succ); headerSeq.Remove(succ); } // Otherwise, add it to the header sequence if it hasn't already been in it. else if (!beenInH.Contains(succ)) { headerSeq.Add(succ); beenInH.Add(succ); } } } } // Add the new interval to the sequence of intervals intSeq.Add(newInt); } }