private static void Search(IRBlock block, DominatorTree dominatorTree, Dictionary <Ident, int> count, Dictionary <Ident, Stack <int> > stack) { // Algorithm from Ron Cytron et al to rename variables into SSA form foreach (IRTuple irt in block.GetStatements()) { Console.Write("Type: " + irt.GetType() + " "); irt.Print(); Console.WriteLine(); if (irt.getOp() != IrOp.PHI) { foreach (Ident v in irt.GetUsedVars()) { Console.WriteLine("Renaming variable: " + v); int i = stack[v].Peek(); RenameTupleSourcesHelper(irt, v, i); // replace uses of v with vi in statement } } foreach (Ident a in irt.GetDefinedVars()) { count[a] = count[a] + 1; int i = count[a]; stack[a].Push(i); irt.setDest(RenameVar(a, i)); // replace definitions of a with ai in statement } } // rename Phi function arguments in the successors List <IRBlock> successors = block.GetSuccessors(); for (int i = 0; i < successors.Count; i++) { foreach (IRTuple stmt in block.GetStatements()) { if (stmt.getOp() == IrOp.PHI) { IRTupleManyOp phi = (IRTupleManyOp)stmt; Ident v = phi.GetSources()[i]; int numbering = stack[v].Peek(); phi.SetSource(i, RenameVar(v, numbering)); } } } // for each descendant do the Search(X) renaming process DominatorTreeNode node = dominatorTree.GetNode(block); foreach (DominatorTreeNode descendant in node.GetDescendants()) { Search(descendant.GetBlock(), dominatorTree, count, stack); } // pop stack phase foreach (IRTuple irt in block.GetStatements()) { foreach (Ident v in irt.GetDefinedVars()) { stack[v].Pop(); } } }
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()); } } }
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()); } } }