public static void RemoveGuards(NodeGraph graph) { for (int i = graph.numBlocks - 1; i >= 0; i--) { NodeBlock block = graph[i]; for (NodeList.reverse_iterator iter = block.nodes.rbegin(); iter.more(); ) { if (iter.node.guard) { //Debug.Assert(iter.node.idempotent); iter.node.removeFromUseChains(); block.nodes.remove(iter); continue; } iter.next(); } } }
public SourceStructureBuilder(NodeGraph graph) { graph_ = graph; }
public NodeRewriter(NodeGraph graph) { graph_ = graph; }
public NodeRenamer(NodeGraph graph) { graph_ = graph; }
public BackwardTypePropagation(NodeGraph graph) { graph_ = graph; }
private static NodeBlock InLoop(NodeGraph graph, NodeBlock block) { while (true) { if (block.lir.backedge != null) return block; NodeBlock next = graph[block.lir.idom.id]; if (block == next) return null; block = next; } }
static void DumpMethod(SourcePawnFile file, SourceBuilder source, uint addr) { MethodParser mp = new MethodParser(file, addr); LGraph graph = mp.parse(); NodeBuilder nb = new NodeBuilder(file, graph); NodeBlock[] nblocks = nb.buildNodes(); NodeGraph ngraph = new NodeGraph(file, nblocks); // Remove dead phis first. NodeAnalysis.RemoveDeadCode(ngraph); NodeRewriter rewriter = new NodeRewriter(ngraph); rewriter.rewrite(); NodeAnalysis.CollapseArrayReferences(ngraph); // Propagate type information. ForwardTypePropagation ftypes = new ForwardTypePropagation(ngraph); ftypes.propagate(); BackwardTypePropagation btypes = new BackwardTypePropagation(ngraph); btypes.propagate(); // We're not fixpoint, so just iterate again. ftypes.propagate(); btypes.propagate(); // Try this again now that we have type information. NodeAnalysis.CollapseArrayReferences(ngraph); ftypes.propagate(); btypes.propagate(); // Coalesce x[y] = x[y] + 5 into x[y] += 5 NodeAnalysis.CoalesceLoadStores(ngraph); // After this, it is not legal to run type analysis again, because // arguments expecting references may have been rewritten to take // constants, for pretty-printing. NodeAnalysis.AnalyzeHeapUsage(ngraph); // Do another DCE pass, this time, without guards. NodeAnalysis.RemoveGuards(ngraph); NodeAnalysis.RemoveDeadCode(ngraph); NodeRenamer renamer = new NodeRenamer(ngraph); renamer.rename(); // Do a pass to coalesce declaration+stores. NodeAnalysis.CoalesceLoadsAndDeclarations(ngraph); // Simplify conditional expressions. // BlockAnalysis.NormalizeConditionals(ngraph); var sb = new SourceStructureBuilder(ngraph); var structure = sb.build(); source.write(structure); //System.Console.In.Read(); //System.Console.In.Read(); }
// We rely on accurate use counts to rename nodes in a readable way, // so we provide a phase for updating use info. public static void RemoveDeadCode(NodeGraph graph) { for (int i = graph.numBlocks - 1; i >= 0; i--) RemoveDeadCodeInBlock(graph[i]); }
public static void AnalyzeHeapUsage(NodeGraph graph) { for (int i = 0; i < graph.numBlocks; i++) AnalyzeHeapUsage(graph[i]); }
public static void CoalesceLoadStores(NodeGraph graph) { for (int i = 0; i < graph.numBlocks; i++) CoalesceLoadStores(graph[i]); }
public static void CoalesceLoadsAndDeclarations(NodeGraph graph) { for (int i = 0; i < graph.numBlocks; i++) { NodeBlock block = graph[i]; for (NodeList.iterator iter = block.nodes.begin(); iter.more(); ) { DNode node = iter.node; if (node.type == NodeType.DeclareLocal) { // Peephole next = store(this, expr) DDeclareLocal local = (DDeclareLocal)node; if (node.next.type == NodeType.Store) { DStore store = (DStore)node.next; if (store.getOperand(0) == local) { local.replaceOperand(0, store.getOperand(1)); store.removeFromUseChains(); iter.next(); block.nodes.remove(iter); continue; } } } iter.next(); } } }
// Find adds that should really be array references. public static void CollapseArrayReferences(NodeGraph graph) { bool changed; do { changed = false; for (int i = graph.numBlocks - 1; i >= 0; i--) changed |= CollapseArrayReferences(graph[i]); } while (changed); }
private static NodeBlock FindJoinBlock(NodeGraph graph, NodeBlock block) { if (block.nodes.last.type == NodeType.JumpCondition && block.lir.idominated.Length == 3) return graph[block.lir.idominated[2].id]; if (block.lir.idom == null) return null; if (block.lir.idom == block.lir) return null; return FindJoinBlock(graph, graph[block.lir.idom.id]); }
public ForwardTypePropagation(NodeGraph graph) { graph_ = graph; }