/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.compilers.opt.controlflow; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import org.jikesrvm.compilers.opt.OperationNotImplementedException; import org.jikesrvm.compilers.opt.dfsolver.DF_LatticeCell; import org.jikesrvm.compilers.opt.dfsolver.DF_Solution; import org.jikesrvm.compilers.opt.ir.BasicBlock; import org.jikesrvm.compilers.opt.ir.IR; /** * Calculate dominators for basic blocks. * <p> Uses the algorithm contained in Dragon book, pg. 670-1. * <pre> * D(n0) := { n0 } * for n in N - { n0 } do D(n) := N; * while changes to any D(n) occur do * for n in N - {n0} do * D(n) := {n} U (intersect of D(p) over all predecessors p of n) * </pre> * <p> TODO: we do not support IRs with exception handlers!! */ public class Dominators { /** * Control for debug output */ static final boolean DEBUG = false; /** * Should we compute post-dominators instead of dominators? This is * false by default. */ static boolean COMPUTE_POST_DOMINATORS = false; private Map<BasicBlock, DominatorInfo> dominatorInfo; /** * Calculate the dominators for an IR. * * @param ir the IR in question */ public void perform(IR ir) { if (ir.hasReachableExceptionHandlers()) { throw new OperationNotImplementedException("IR with exception handlers"); } DominatorSystem system = new DominatorSystem(ir); if (DEBUG) { System.out.print("Solving..."); } if (DEBUG) { System.out.println(system); } system.solve(); if (DEBUG) { System.out.println("done"); } DF_Solution solution = system.getSolution(); if (DEBUG) { System.out.println("Dominator Solution :" + solution); } if (DEBUG) { System.out.print("Updating blocks ..."); } updateBlocks(solution); if (DEBUG) { System.out.println("done."); } if (ir.options.PRINT_DOMINATORS) { printDominators(ir); } } /** * Calculate the "approximate" dominators for an IR i.e., the * dominators in the factored CFG rather than the normal CFG. * <p> (No exception is thrown if the input IR has handler blocks.) * * @param ir the IR in question */ public void computeApproxDominators(IR ir) { DominatorSystem system = new DominatorSystem(ir); if (DEBUG) { System.out.print("Solving..."); } if (DEBUG) { System.out.println(system); } system.solve(); if (DEBUG) { System.out.println("done"); } DF_Solution solution = system.getSolution(); if (DEBUG) { System.out.println("Dominator Solution :" + solution); } if (DEBUG) { System.out.print("Updating blocks ..."); } updateBlocks(solution); if (DEBUG) { System.out.println("done."); } if (ir.options.PRINT_DOMINATORS) { printDominators(ir); } } /** * Calculate the postdominators for an IR. * * @param ir the IR in question */ public void computeApproxPostdominators(IR ir) { Dominators.COMPUTE_POST_DOMINATORS = true; DominatorSystem system = new DominatorSystem(ir); if (DEBUG) { System.out.print("Solving..."); } if (DEBUG) { System.out.println(system); } system.solve(); if (DEBUG) { System.out.println("done"); } DF_Solution solution = system.getSolution(); if (DEBUG) { System.out.println("Postdominator Solution :" + solution); } if (DEBUG) { System.out.print("Updating blocks ..."); } updateBlocks(solution); if (DEBUG) { System.out.println("done."); } if (ir.options.PRINT_DOMINATORS) { printDominators(ir); } Dominators.COMPUTE_POST_DOMINATORS = false; } /** * Creates a {@code DominatorInfo} for each basic block * in the data flow system solution. * * @param solution the solution to the Dominators equations */ public void updateBlocks(DF_Solution solution) { int capacityToPreventRehash = (int) (solution.size() * 1.4f); dominatorInfo = new HashMap<BasicBlock, DominatorInfo>(capacityToPreventRehash); for (final DF_LatticeCell latticeCell : solution.values()) { DominatorCell cell = (DominatorCell) latticeCell; BasicBlock b = cell.block; dominatorInfo.put(b, new DominatorInfo(cell.dominators)); if (DEBUG) { System.out.println("Dominators of " + b + ":" + cell.dominators); } } } /** * Print the (already calculated) dominators. * @param ir the IR */ public void printDominators(IR ir) { for (Enumeration<BasicBlock> e = ir.getBasicBlocks(); e.hasMoreElements();) { BasicBlock b = e.nextElement(); DominatorInfo i = dominatorInfo.get(b); System.out.println("Dominators of " + b + ":" + i.dominators); } } public DominatorInfo getDominatorInfo(BasicBlock b) { return dominatorInfo.get(b); } }