/* * Translate into SSA form */ private static void ConvertIntoSSAForm(IRGraph graph) { DominatorTree dominatorTree = new DominatorTree(graph); InsertPhiFunctions(graph, dominatorTree); RenameVariables(graph, dominatorTree); }
private static void DeadCodeElimination(IRGraph graph) { Dictionary <Ident, IRIdent> identAnalysis = SimpleVariableAnalysis(graph); Queue <Ident> worklist = new Queue <Ident>(identAnalysis.Keys); while (worklist.Count > 0) { Ident ident = worklist.Dequeue(); IRIdent identObj = identAnalysis[ident]; if (identObj.CountUsesites() == 0) { IRTuple defStatement = identObj.GetDefsite(); if (!defStatement.HasSideEffects()) { Console.WriteLine("SSA: Deleting tuple: " + defStatement.toString() + " as it is dead code"); HashSet <Ident> usedVars = defStatement.GetUsedVars(); foreach (Ident used in usedVars) { IRIdent usedObj = identAnalysis[used]; usedObj.DeleteUsesite(defStatement); worklist.Enqueue(used); } graph.RemoveStatement(defStatement); } } } }
public static List <IRTuple> DoSSAOptimizations(List <IRTuple> tuples) { Console.WriteLine("** SSA: Building Control Flow Graph ..."); IRGraph graph = new IRGraph(tuples); // Live variable analysis List <string> livein; List <List <string> > liveouts; graph.ComputeLiveness(out livein, out liveouts); // convert into SSA form Console.WriteLine("** SSA: Starting conversion into SSA form ..."); ConvertIntoSSAForm(graph); Console.WriteLine("** SSA: Conversion into SSA form complete"); // do optimizations (constant propagation, dead code elimination) Console.WriteLine("** SSA: Starting dead code elimination ..."); DeadCodeElimination(graph); Console.WriteLine("** SSA: Starting constant propagation ..."); ConstantPropagation(graph); // use Briggs method to translate out of SSA form Console.WriteLine("** SSA: Starting conversion out of SSA form ..."); TranslateOutOfSSAForm(graph); Console.WriteLine("** SSA: Generating new IRTuple Stream"); return(graph.GenerateTupleStream()); }
public static List<IRTuple> DoSSAOptimizations(List<IRTuple> tuples) { Console.WriteLine("** SSA: Building Control Flow Graph ..."); IRGraph graph = new IRGraph(tuples); // Live variable analysis List<string> livein; List<List<string>> liveouts; graph.ComputeLiveness(out livein, out liveouts); // convert into SSA form Console.WriteLine("** SSA: Starting conversion into SSA form ..."); ConvertIntoSSAForm(graph); Console.WriteLine("** SSA: Conversion into SSA form complete"); // do optimizations (constant propagation, dead code elimination) Console.WriteLine("** SSA: Starting dead code elimination ..."); DeadCodeElimination(graph); Console.WriteLine("** SSA: Starting constant propagation ..."); ConstantPropagation(graph); // use Briggs method to translate out of SSA form Console.WriteLine("** SSA: Starting conversion out of SSA form ..."); TranslateOutOfSSAForm(graph); Console.WriteLine("** SSA: Generating new IRTuple Stream"); return graph.GenerateTupleStream(); }
private static void DeadCodeElimination(IRGraph graph) { Dictionary<Ident, IRIdent> identAnalysis = SimpleVariableAnalysis(graph); Queue<Ident> worklist = new Queue<Ident>(identAnalysis.Keys); while (worklist.Count > 0) { Ident ident = worklist.Dequeue(); IRIdent identObj = identAnalysis[ident]; if (identObj.CountUsesites() == 0) { IRTuple defStatement = identObj.GetDefsite(); if (!defStatement.HasSideEffects()) { Console.WriteLine("SSA: Deleting tuple: " + defStatement.toString() + " as it is dead code"); HashSet<Ident> usedVars = defStatement.GetUsedVars(); foreach (Ident used in usedVars) { IRIdent usedObj = identAnalysis[used]; usedObj.DeleteUsesite(defStatement); worklist.Enqueue(used); } graph.RemoveStatement(defStatement); } } } }
/* * Test find reachable blocks methods */ private static void TestFindReachableBlocks(int index, SortedSet <int> expected) { IRGraph cfg = BuildSampleCFG(); SortedSet <IRBlock> result = DominatorTree.FindReachableBlocks(cfg, index); SortedSet <int> intResult = ConvertToIndexSet(result); if (!intResult.SetEquals(expected)) { throw new Exception("Reachable blocks for block " + index + " is " + ConvertSetToString(intResult) + " should be " + ConvertSetToString(expected)); } }
public DominatorTree(IRGraph cfg) { this.cfg = cfg; this.imediateDominator = new Dictionary<IRBlock, IRBlock>(); this.blockToNodeMappings = new Dictionary<IRBlock, DominatorTreeNode>(); this.dominanceFrontiers = new Dictionary<IRBlock, SortedSet<IRBlock>>(); // Build the tree and construct the dominance froniters this.BuildDominatorTree(); this.ConstructDominanceFrontierMapping(); }
public static SortedSet<IRBlock> CalculateDominatesSet(IRGraph cfg, SortedSet<IRBlock> V, SortedSet<IRBlock> VSansR, IRBlock v) { SortedSet<IRBlock> VSansv = new SortedSet<IRBlock>(); VSansv.UnionWith(V); VSansv.Remove(v); // V - {v} SortedSet<IRBlock> S = FindReachableBlocks(cfg, v.GetIndex()); VSansv.ExceptWith(S); return VSansv; // V - {v} - S }
public DominatorTree(IRGraph cfg) { this.cfg = cfg; this.imediateDominator = new Dictionary <IRBlock, IRBlock>(); this.blockToNodeMappings = new Dictionary <IRBlock, DominatorTreeNode>(); this.dominanceFrontiers = new Dictionary <IRBlock, SortedSet <IRBlock> >(); // Build the tree and construct the dominance froniters this.BuildDominatorTree(); this.ConstructDominanceFrontierMapping(); }
public static SortedSet<IRBlock> FindReachableBlocks(IRGraph cfg, int ignoreBlockIndex) { IRBlock head = cfg.GetGraphHead(); SortedSet<IRBlock> reachable = new SortedSet<IRBlock>(); reachable.Add(head); // if you can't use head you should ge no where if (head.GetIndex() == ignoreBlockIndex) return reachable; return FindReachableBlocks(reachable, head, ignoreBlockIndex); }
public static SortedSet <IRBlock> CalculateDominatesSet(IRGraph cfg, SortedSet <IRBlock> V, SortedSet <IRBlock> VSansR, IRBlock v) { SortedSet <IRBlock> VSansv = new SortedSet <IRBlock>(); VSansv.UnionWith(V); VSansv.Remove(v); // V - {v} SortedSet <IRBlock> S = FindReachableBlocks(cfg, v.GetIndex()); VSansv.ExceptWith(S); return(VSansv); // V - {v} - S }
public static void Main(string [] args) { List <IRTuple> irstream = new List <IRTuple>(); irstream.Add(new IRTuple(IrOp.LABEL, "F$1")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "T", "R2")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "A", "R0")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "B", "R1")); irstream.Add(new IRTupleOneOpImm <int>(IrOp.STORE, "C", 0)); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "D", "A")); irstream.Add(new IRTuple(IrOp.LABEL, "L$1")); irstream.Add(new IRTupleTwoOp(IrOp.ADD, "C", "C", "B")); irstream.Add(new IRTupleOneOpImm <int>(IrOp.STORE, "T$1", 1)); irstream.Add(new IRTupleTwoOp(IrOp.SUB, "D", "D", "T$1")); irstream.Add(new IRTupleOneOpImm <int>(IrOp.STORE, "T$2", 0)); irstream.Add(new IRTupleTwoOp(IrOp.LTE, "T$3", "D", "T$2")); irstream.Add(new IRTupleOneOpIdent(IrOp.JMPF, "L$1", "T$3")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "R0", "C")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "R2", "T")); IRGraph graph = new IRGraph(irstream); List <string> livein; List <List <string> > liveouts; graph.ComputeLiveness(out livein, out liveouts); Dictionary <string, string> registerAllocation = Allocate.run(liveouts, livein); List <IRTuple> irstream_out = new List <IRTuple>(); foreach (IRTuple irt in irstream) { IRTuple translated = irt.TranslateNames(registerAllocation); irstream_out.Add(translated); } Console.WriteLine(); foreach (var kvp in registerAllocation) { Console.WriteLine("{0} : {1}", kvp.Key, kvp.Value); } Console.WriteLine(); foreach (IRTuple irt in irstream_out) { irt.Print(); Console.WriteLine(); } }
/* * Test Building Full Dominator Tree */ private static void TestCalculatingDominanceFrontier(int index, SortedSet <int> expected) { // Build Dominator Tree IRGraph cfg = BuildSampleCFG(); DominatorTree dominatorTree = new DominatorTree(cfg); SortedSet <IRBlock> result = dominatorTree.GetDominanceFrontier(cfg.GetBlock(index)); SortedSet <int> intResult = ConvertToIndexSet(result); if (!intResult.SetEquals(expected)) { throw new Exception("Dominance frontier for block " + index + " is " + ConvertSetToString(intResult) + " should be " + ConvertSetToString(expected)); } }
public static SortedSet <IRBlock> FindReachableBlocks(IRGraph cfg, int ignoreBlockIndex) { IRBlock head = cfg.GetGraphHead(); SortedSet <IRBlock> reachable = new SortedSet <IRBlock>(); reachable.Add(head); // if you can't use head you should ge no where if (head.GetIndex() == ignoreBlockIndex) { return(reachable); } return(FindReachableBlocks(reachable, head, ignoreBlockIndex)); }
public static void Main(string [] args) { List <IRTuple> irstream = new List <IRTuple>(); irstream.Add(new IRTuple(IrOp.LABEL, "F$1")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "T", "R$2")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "A", "R$0")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "B", "R$1")); irstream.Add(new IRTupleOneOpImm <int>(IrOp.STORE, "C", 0)); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "D", "A")); irstream.Add(new IRTuple(IrOp.LABEL, "L$1")); irstream.Add(new IRTupleTwoOp(IrOp.ADD, "C", "C", "B")); irstream.Add(new IRTupleOneOpImm <int>(IrOp.STORE, "T$1", 1)); irstream.Add(new IRTupleTwoOp(IrOp.SUB, "D", "D", "T$1")); irstream.Add(new IRTupleOneOpImm <int>(IrOp.STORE, "T$2", 0)); irstream.Add(new IRTupleTwoOp(IrOp.LTE, "T$3", "D", "T$2")); irstream.Add(new IRTupleOneOpIdent(IrOp.JMPF, "L$1", "T$3")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "R$0", "C")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "R$2", "T")); IRGraph graph = new IRGraph(irstream); List <string> livein; List <List <string> > liveouts; graph.ComputeLiveness(out livein, out liveouts); graph.Print(); Console.WriteLine("-------"); Console.WriteLine("LiveIn:"); foreach (string li in livein) { Console.Write("\t" + li); } Console.WriteLine(); Console.WriteLine("LiveOuts:"); foreach (List <string> los in liveouts) { foreach (string lo in los) { Console.Write(lo + "\t"); } Console.WriteLine(); } }
private static void RenameVariables(IRGraph graph, DominatorTree dominatorTree) { // setup data structures Dictionary <Ident, int> count = new Dictionary <Ident, int>(); Dictionary <Ident, Stack <int> > stack = new Dictionary <Ident, Stack <int> >(); foreach (Ident ident in graph.GetDefinedVars()) { count[ident] = 0; stack[ident] = new Stack <int>(); stack[ident].Push(0); } // recursively walk the dominator tree in-order starting with the root node Search(graph.GetGraphHead(), dominatorTree, count, stack); }
public static void Main(string [] args) { List<IRTuple> irstream = new List<IRTuple>(); irstream.Add(new IRTuple(IrOp.LABEL, "F$1")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "T", "R2")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "A", "R0")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "B", "R1")); irstream.Add(new IRTupleOneOpImm<int>(IrOp.STORE, "C", 0)); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "D", "A")); irstream.Add(new IRTuple(IrOp.LABEL, "L$1")); irstream.Add(new IRTupleTwoOp(IrOp.ADD, "C", "C", "B")); irstream.Add(new IRTupleOneOpImm<int>(IrOp.STORE, "T$1", 1)); irstream.Add(new IRTupleTwoOp(IrOp.SUB, "D", "D", "T$1")); irstream.Add(new IRTupleOneOpImm<int>(IrOp.STORE, "T$2", 0)); irstream.Add(new IRTupleTwoOp(IrOp.LTE, "T$3", "D", "T$2")); irstream.Add(new IRTupleOneOpIdent(IrOp.JMPF, "L$1", "T$3")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "R0", "C")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "R2", "T")); IRGraph graph = new IRGraph(irstream); List<string> livein; List<List<string>> liveouts; graph.ComputeLiveness(out livein, out liveouts); Dictionary<string,string> registerAllocation = Allocate.run(liveouts, livein); List<IRTuple> irstream_out = new List<IRTuple>(); foreach (IRTuple irt in irstream) { IRTuple translated = irt.TranslateNames(registerAllocation); irstream_out.Add(translated); } Console.WriteLine(); foreach(var kvp in registerAllocation) { Console.WriteLine("{0} : {1}", kvp.Key, kvp.Value); } Console.WriteLine(); foreach (IRTuple irt in irstream_out) { irt.Print(); Console.WriteLine(); } }
/* * Test the dominance set */ private static void TestDomaintes(int index, SortedSet <int> expected) { IRGraph cfg = BuildSampleCFG(); SortedSet <IRBlock> V = cfg.GetSetOfAllBlocks(); SortedSet <IRBlock> VSansR = new SortedSet <IRBlock>(); VSansR.UnionWith(V); VSansR.Remove(cfg.GetGraphHead()); SortedSet <IRBlock> result = DominatorTree.CalculateDominatesSet(cfg, V, VSansR, cfg.GetBlock(index)); SortedSet <int> intResult = ConvertToIndexSet(result); if (!intResult.SetEquals(expected)) { throw new Exception("Dominates blocks for block " + index + " is " + ConvertSetToString(intResult) + " should be " + ConvertSetToString(expected)); } }
public static void Main(string [] args) { List<IRTuple> irstream = new List<IRTuple>(); irstream.Add(new IRTuple(IrOp.LABEL, "F$1")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "T", "R$2")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "A", "R$0")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "B", "R$1")); irstream.Add(new IRTupleOneOpImm<int>(IrOp.STORE, "C", 0)); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "D", "A")); irstream.Add(new IRTuple(IrOp.LABEL, "L$1")); irstream.Add(new IRTupleTwoOp(IrOp.ADD, "C", "C", "B")); irstream.Add(new IRTupleOneOpImm<int>(IrOp.STORE, "T$1", 1)); irstream.Add(new IRTupleTwoOp(IrOp.SUB, "D", "D", "T$1")); irstream.Add(new IRTupleOneOpImm<int>(IrOp.STORE, "T$2", 0)); irstream.Add(new IRTupleTwoOp(IrOp.LTE, "T$3", "D", "T$2")); irstream.Add(new IRTupleOneOpIdent(IrOp.JMPF, "L$1", "T$3")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "R$0", "C")); irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "R$2", "T")); IRGraph graph = new IRGraph(irstream); List<string> livein; List<List<string>> liveouts; graph.ComputeLiveness(out livein, out liveouts); graph.Print(); Console.WriteLine("-------"); Console.WriteLine("LiveIn:"); foreach(string li in livein) Console.Write("\t" + li); Console.WriteLine(); Console.WriteLine("LiveOuts:"); foreach(List<string> los in liveouts) { foreach(string lo in los) Console.Write(lo + "\t"); Console.WriteLine(); } }
/* * Test Building Full Dominator Tree */ public static void TestBuildFullTree() { // Build Dominator Tree IRGraph cfg = BuildSampleCFG(); DominatorTree dominatorTree = new DominatorTree(cfg); // Expected DominatorTreeNode expected = BuildExpectedDominatorTree(); // Compare Result to Expected if (!dominatorTree.GetRoot().Equals(expected)) { Console.WriteLine("\n\n *** RESULT ***"); printTree(dominatorTree.GetRoot()); Console.WriteLine("\n\n *** EXPECTED ***"); printTree(expected); throw new Exception("Dominator Tree built doesn't match expected dominator tree"); } }
/* * Helper Methods */ private static IRGraph BuildSampleCFG() { IRBlock block1 = new IRBlock(1); IRBlock block2 = new IRBlock(2); IRBlock block3 = new IRBlock(3); IRBlock block4 = new IRBlock(4); IRBlock block5 = new IRBlock(5); IRBlock block6 = new IRBlock(6); IRBlock block7 = new IRBlock(7); IRBlock block8 = new IRBlock(8); IRBlock block9 = new IRBlock(9); block1.AddSuccessor(block2); block2.AddSuccessor(block3); block3.AddSuccessor(block4); block3.AddSuccessor(block5); block4.AddSuccessor(block6); block4.AddSuccessor(block7); block5.AddSuccessor(block8); block6.AddSuccessor(block9); block7.AddSuccessor(block9); block9.AddSuccessor(block3); List <IRBlock> blocks = new List <IRBlock>(); blocks.Add(block1); blocks.Add(block2); blocks.Add(block3); blocks.Add(block4); blocks.Add(block5); blocks.Add(block6); blocks.Add(block7); blocks.Add(block8); blocks.Add(block9); IRGraph cfg = new IRGraph(blocks); return(cfg); }
private static Dictionary <Ident, IRIdent> SimpleVariableAnalysis(IRGraph graph) { Dictionary <Ident, IRIdent> identAnalysis = new Dictionary <Ident, IRIdent>(); foreach (IRBlock block in graph.GetSetOfAllBlocks()) { foreach (IRTuple stmt in block.GetStatements()) { HashSet <Ident> usedVars = stmt.GetUsedVars(); foreach (Ident ident in usedVars) { IRIdent identObj; if (identAnalysis.ContainsKey(ident)) { identObj = identAnalysis[ident]; } else { identObj = new IRIdent(ident, stmt); identAnalysis[ident] = identObj; } identObj.AddUsesite(stmt); } HashSet <Ident> definedVars = stmt.GetDefinedVars(); foreach (Ident ident in definedVars) { if (!identAnalysis.ContainsKey(ident)) { IRIdent identObj = new IRIdent(ident, stmt); identAnalysis[ident] = identObj; } } } } return(identAnalysis); }
/* * Helper Methods */ private static IRGraph BuildSampleCFG() { IRBlock block1 = new IRBlock(1); IRBlock block2 = new IRBlock(2); IRBlock block3 = new IRBlock(3); IRBlock block4 = new IRBlock(4); IRBlock block5 = new IRBlock(5); IRBlock block6 = new IRBlock(6); IRBlock block7 = new IRBlock(7); IRBlock block8 = new IRBlock(8); IRBlock block9 = new IRBlock(9); block1.AddSuccessor(block2); block2.AddSuccessor(block3); block3.AddSuccessor(block4); block3.AddSuccessor(block5); block4.AddSuccessor(block6); block4.AddSuccessor(block7); block5.AddSuccessor(block8); block6.AddSuccessor(block9); block7.AddSuccessor(block9); block9.AddSuccessor(block3); List<IRBlock> blocks = new List<IRBlock>(); blocks.Add(block1); blocks.Add(block2); blocks.Add(block3); blocks.Add(block4); blocks.Add(block5); blocks.Add(block6); blocks.Add(block7); blocks.Add(block8); blocks.Add(block9); IRGraph cfg = new IRGraph(blocks); return cfg; }
private static void RenameVariables(IRGraph graph, DominatorTree dominatorTree) { // setup data structures Dictionary<Ident, int> count = new Dictionary<Ident, int>(); Dictionary<Ident, Stack<int>> stack = new Dictionary<Ident, Stack<int>>(); foreach (Ident ident in graph.GetDefinedVars()) { count[ident] = 0; stack[ident] = new Stack<int>(); stack[ident].Push(0); } // recursively walk the dominator tree in-order starting with the root node Search(graph.GetGraphHead(), dominatorTree, count, stack); }
private static Dictionary<Ident, IRIdent> SimpleVariableAnalysis(IRGraph graph) { Dictionary<Ident, IRIdent> identAnalysis = new Dictionary<Ident, IRIdent>(); foreach (IRBlock block in graph.GetSetOfAllBlocks()) { foreach (IRTuple stmt in block.GetStatements()) { HashSet<Ident> usedVars = stmt.GetUsedVars(); foreach (Ident ident in usedVars) { IRIdent identObj; if (identAnalysis.ContainsKey(ident)) { identObj = identAnalysis[ident]; } else { identObj = new IRIdent(ident, stmt); identAnalysis[ident] = identObj; } identObj.AddUsesite(stmt); } HashSet<Ident> definedVars = stmt.GetDefinedVars(); foreach (Ident ident in definedVars) { if (!identAnalysis.ContainsKey(ident)) { IRIdent identObj = new IRIdent(ident, stmt); identAnalysis[ident] = identObj; } } } } return identAnalysis; }
/* * Translate out of SAA form */ private static void TranslateOutOfSSAForm(IRGraph graph) { }
private static void InsertPhiFunctions(IRGraph graph, DominatorTree dominatorTree) { foreach (IRBlock block in graph.GetSetOfAllBlocks()) { Console.WriteLine(); Console.WriteLine("***"); Console.WriteLine("Block: " + block.GetIndex()); block.PrintStatements(); Console.Write("Predecessors: "); foreach (IRBlock pred in graph.GetPredecessors(block)) { Console.Write(pred.GetIndex() + ", "); } Console.WriteLine(); Console.Write("Live in : "); foreach (Ident ident in block.GetLiveIn()) { Console.Write(ident + ", "); } Console.WriteLine(); Console.Write("Defined vars: "); foreach (Ident ident in block.GetDefinedVars()) { Console.Write(ident + ", "); } Console.WriteLine(); } foreach (Ident v in graph.GetDefinedVars()) { // A(v) = blocks containing an assignment to v HashSet <IRBlock> Av = new HashSet <IRBlock>(); foreach (IRBlock block in graph.GetSetOfAllBlocks()) { if (block.GetDefinedVars().Contains(v) && block.GetLiveIn().Contains(v)) { Av.Add(block); } } // place Phi tuple for each v in the iterated dominance frontier of A(v) HashSet <IRBlock> needsPhiFunction = new HashSet <IRBlock>(); foreach (IRBlock Avblock in Av) { // create set of blocks that need phi functions foreach (IRBlock block in dominatorTree.GetDominanceFrontier(Avblock)) { needsPhiFunction.Add(block); } } // only want one phi function per block for each variable where appropiate foreach (IRBlock block in needsPhiFunction) { // Phi function should have as many arguments as it does predecessors List <Ident> sources = new List <Ident>(); foreach (IRBlock b in graph.GetPredecessors(block)) { sources.Add(v); } IRTupleManyOp phi = new IRTupleManyOp(IrOp.PHI, v, sources); block.InsertStatement(phi, 0); Console.WriteLine("** SSA: Inserting phi function: " + phi.toString() + " into block " + block.GetIndex()); } } }
/* * Optimization Methods */ private static void ConstantPropagation(IRGraph graph) { }
private static void InsertPhiFunctions(IRGraph graph, DominatorTree dominatorTree) { foreach (IRBlock block in graph.GetSetOfAllBlocks()) { Console.WriteLine(); Console.WriteLine("***"); Console.WriteLine("Block: " + block.GetIndex()); block.PrintStatements(); Console.Write("Predecessors: "); foreach (IRBlock pred in graph.GetPredecessors(block)) Console.Write(pred.GetIndex() + ", "); Console.WriteLine(); Console.Write("Live in : "); foreach (Ident ident in block.GetLiveIn()) Console.Write(ident + ", "); Console.WriteLine(); Console.Write("Defined vars: "); foreach (Ident ident in block.GetDefinedVars()) Console.Write(ident + ", "); Console.WriteLine(); } foreach (Ident v in graph.GetDefinedVars()) { // A(v) = blocks containing an assignment to v HashSet<IRBlock> Av = new HashSet<IRBlock>(); foreach (IRBlock block in graph.GetSetOfAllBlocks()) { if (block.GetDefinedVars().Contains(v) && block.GetLiveIn().Contains(v)) Av.Add(block); } // place Phi tuple for each v in the iterated dominance frontier of A(v) HashSet<IRBlock> needsPhiFunction = new HashSet<IRBlock>(); foreach (IRBlock Avblock in Av) { // create set of blocks that need phi functions foreach (IRBlock block in dominatorTree.GetDominanceFrontier(Avblock)) { needsPhiFunction.Add(block); } } // only want one phi function per block for each variable where appropiate foreach (IRBlock block in needsPhiFunction) { // Phi function should have as many arguments as it does predecessors List<Ident> sources = new List<Ident>(); foreach (IRBlock b in graph.GetPredecessors(block)) sources.Add(v); IRTupleManyOp phi = new IRTupleManyOp(IrOp.PHI, v, sources); block.InsertStatement(phi, 0); Console.WriteLine("** SSA: Inserting phi function: " + phi.toString() + " into block " + block.GetIndex()); } } }
public static List <IRTuple> run(List <IRTuple> irstream) { List <string> live; List <List <string> > interfereList; List <IRTuple> temp; List <string> spill = new List <string>(); List <List <string> > results = null; Dictionary <string, string> dict; while (results == null) { int i = 0; temp = new List <IRTuple>(); Console.WriteLine("Spill count: " + spill.Count); foreach (IRTuple irt in irstream) { dict = new Dictionary <string, string>(); HashSet <string> defined = irt.GetDefinedVars(); HashSet <string> used = irt.GetUsedVars(); for (int j = 0; j < spill.Count; j++) { dict.Add(spill[j], "#t" + i); i++; if (used.Contains(spill[j])) { temp.Add(new IRTupleOneOpIdent(IrOp.STORE, dict[spill[j]], "MEM[" + spill[j] + "]")); } } temp.Add(irt.TranslateNames(dict)); for (int j = 0; j < spill.Count; j++) { if (defined.Contains(spill[j])) { temp.Add(new IRTupleOneOpIdent(IrOp.STORE, "MEM[" + spill[j] + "]", dict[spill[j]])); } } } irstream = temp; //magic live variable analysis provided by Orla IRGraph irgraph = new IRGraph(irstream); irgraph.ComputeLiveness(out live, out interfereList); takeInput(interfereList, live); build(); spill = new List <string>(); results = simplify(graph, spill); } dict = new Dictionary <string, string>(); for (int i = 0; i < results.Count; i++) { dict.Add(results[i][0], results[i][1]); } Console.WriteLine(); foreach (var kvp in dict) { Console.WriteLine("{0} : {1}", kvp.Key, kvp.Value); } Console.WriteLine(); List <IRTuple> irstream_out = new List <IRTuple>(); foreach (IRTuple irt in irstream) { IRTuple translated = irt.TranslateNames(dict); irstream_out.Add(translated); } return(irstream_out); }
public static List<IRTuple> run(List<IRTuple> irstream) { List<string> live; List<List<string>> interfereList; List<IRTuple> temp; List<string> spill = new List<string>(); List<List<string>> results = null; Dictionary<string,string> dict; while(results == null){ int i = 0; temp = new List<IRTuple>(); Console.WriteLine("Spill count: " + spill.Count); foreach (IRTuple irt in irstream){ dict = new Dictionary<string,string>(); HashSet<string> defined = irt.GetDefinedVars(); HashSet<string> used = irt.GetUsedVars(); for(int j = 0; j < spill.Count; j++){ dict.Add(spill[j],"#t"+i); i++; if(used.Contains(spill[j])){ temp.Add(new IRTupleOneOpIdent(IrOp.STORE, dict[spill[j]], "MEM["+spill[j]+"]")); } } temp.Add(irt.TranslateNames(dict)); for(int j = 0; j < spill.Count; j++){ if(defined.Contains(spill[j])){ temp.Add(new IRTupleOneOpIdent(IrOp.STORE, "MEM["+spill[j]+"]", dict[spill[j]])); } } } irstream = temp; //magic live variable analysis provided by Orla IRGraph irgraph = new IRGraph(irstream); irgraph.ComputeLiveness(out live, out interfereList); takeInput(interfereList, live); build(); spill = new List<string>(); results = simplify(graph, spill); } dict = new Dictionary<string,string>(); for(int i = 0; i < results.Count; i++){ dict.Add(results[i][0], results[i][1]); } Console.WriteLine(); foreach(var kvp in dict) { Console.WriteLine("{0} : {1}", kvp.Key, kvp.Value); } Console.WriteLine(); List<IRTuple> irstream_out = new List<IRTuple>(); foreach (IRTuple irt in irstream){ IRTuple translated = irt.TranslateNames(dict); irstream_out.Add(translated); } return irstream_out; }