001/* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013package org.jikesrvm.compilers.opt.controlflow; 014 015import java.util.Enumeration; 016import java.util.HashSet; 017import java.util.Iterator; 018import org.jikesrvm.compilers.opt.ir.BasicBlock; 019import org.jikesrvm.compilers.opt.ir.IR; 020import org.jikesrvm.util.BitVector; 021 022/** 023 * This class holds data associated with a basic block as computed by the 024 * Lengauer-Tarjan dominator calculation. 025 * @see LTDominators 026 */ 027class LTDominatorInfo { 028 static final boolean DEBUG = false; 029 030 private int semiDominator; 031 /** the immediate dominator */ 032 private BasicBlock dominator; 033 private BasicBlock parent; 034 private final HashSet<BasicBlock> bucket; 035 private BasicBlock label; 036 private BasicBlock ancestor; 037 // Used to keep the trees balanced, during path compression 038 private int size; 039 private BasicBlock child; 040 041 // used to capture activation record state to avoid the use of recursion 042 // in Step 1 of the LT algorithm 043 // A null value will signal that we have not started to process this 044 // block, otherwise, we'll skip the (redundant) 045 // initialization step for the block 046 // See LTDominators.DFS() for details 047 private Enumeration<BasicBlock> bbEnum; 048 049 /** 050 * @param block the basic block this info is associated with 051 */ 052 LTDominatorInfo(BasicBlock block) { 053 semiDominator = 0; 054 dominator = null; 055 parent = null; 056 bucket = new HashSet<BasicBlock>(); 057 ancestor = null; 058 label = block; 059 size = 1; 060 child = null; 061 bbEnum = null; 062 } 063 064 /** 065 * This method returns the set of blocks that dominates the passed 066 * block, i.e., it answers the question "Who dominates me?" 067 * 068 * @param block the block of interest 069 * @param ir the governing ir 070 * @return a BitVector containing those blocks that dominate the passed one 071 */ 072 public BitVector dominators(BasicBlock block, IR ir) { 073 // Currently this set is computed on demand. We may want to cache 074 // the result for reuse. The cost of computing is the height of the 075 // the dominator tree. 076 BitVector dominators = new BitVector(ir.getMaxBasicBlockNumber() + 1); 077 dominators.set(block.getNumber()); 078 while ((block = getIdom(block, ir)) != null) { 079 dominators.set(block.getNumber()); 080 } 081 return dominators; 082 } 083 084 /** 085 * This method determines if the 1st parameter (block) is dominated by 086 * the 2nd parameter (master), i.e., must control pass through "master" 087 * before reaching "block" 088 * 089 * @param block the block we care about 090 * @param master the potential dominating block 091 * @param ir the IR that contains the blocks 092 * @return whether master dominates block 093 */ 094 public static boolean isDominatedBy(BasicBlock block, BasicBlock master, IR ir) { 095 if (block == master) { 096 return true; 097 } 098 // walk up the dominator tree looking for the passed block 099 block = getIdom(block, ir); 100 while (block != null && block != master) { 101 block = getIdom(block, ir); 102 } 103 // If we found the master, the condition is true 104 return block == master; 105 } 106 107 /** 108 * Sets the semidominator for this node 109 * @param value the new value 110 */ 111 public void setSemiDominator(int value) { 112 semiDominator = value; 113 } 114 115 /** 116 * Returns the semidomintor for this node 117 * @return the semidomintor for this node 118 */ 119 public int getSemiDominator() { 120 return semiDominator; 121 } 122 123 /** 124 * Sets the immediate dominator for this node 125 * @param value the value to set 126 */ 127 public void setDominator(BasicBlock value) { 128 dominator = value; 129 } 130 131 /** 132 * Returns the immediate dominator for this node 133 * @return the immediate dominator for this node 134 */ 135 public BasicBlock getDominator() { 136 return dominator; 137 } 138 139 /** 140 * Sets the parent of this block 141 * @param value the value 142 */ 143 public void setParent(BasicBlock value) { 144 parent = value; 145 } 146 147 /** 148 * Returns the parent of this block 149 * @return the parent of this block 150 */ 151 public BasicBlock getParent() { 152 return parent; 153 } 154 155 /** 156 * Returns an iterator over this block's bucket 157 * @return an iterator over this block's bucket 158 */ 159 public Iterator<BasicBlock> getBucketIterator() { 160 return bucket.iterator(); 161 } 162 163 /** 164 * Removes the passed block from the bucket for this node 165 * @param block the block to remove from the bucket 166 */ 167 public void removeFromBucket(BasicBlock block) { 168 bucket.remove(block); 169 } 170 171 /** 172 * Adds the passed block from the bucket for this node 173 * @param block the block to add to our bucket 174 */ 175 public void addToBucket(BasicBlock block) { 176 bucket.add(block); 177 } 178 179 /** 180 * Sets the ancestor for the value passed 181 * @param value the ancestor value 182 */ 183 public void setAncestor(BasicBlock value) { 184 ancestor = value; 185 } 186 187 /** 188 * Returns the ancestor for this block 189 * @return the ancestor for this block 190 */ 191 public BasicBlock getAncestor() { 192 return ancestor; 193 } 194 195 /** 196 * sets the label 197 * @param value the label 198 */ 199 public void setLabel(BasicBlock value) { 200 label = value; 201 } 202 203 /** 204 * returns the label 205 * @return the label 206 */ 207 public BasicBlock getLabel() { 208 return label; 209 } 210 211 /** 212 * sets the size 213 * @param value the size 214 */ 215 public void setSize(int value) { 216 size = value; 217 } 218 219 /** 220 * returns the size 221 * @return the size 222 */ 223 public int getSize() { 224 return size; 225 } 226 227 /** 228 * sets the child field 229 * @param value the child value 230 */ 231 public void setChild(BasicBlock value) { 232 child = value; 233 } 234 235 /** 236 * returns the child 237 * @return the child 238 */ 239 public BasicBlock getChild() { 240 return child; 241 } 242 243 /** 244 * Helper method to return the Info field associated with a block 245 * @return the basic block enumeration, could be null 246 */ 247 public Enumeration<BasicBlock> getEnum() { 248 return bbEnum; 249 } 250 251 /** 252 * set the basic block enum field 253 * @param bbEnum basic block enum 254 */ 255 public void setEnum(Enumeration<BasicBlock> bbEnum) { 256 this.bbEnum = bbEnum; 257 } 258 259 /** 260 * Helper method to return the Info field associated with a block 261 * @param block the block of interest 262 * @param ir the IR that contains the information about the dominators 263 * @return the LTInfo info 264 */ 265 public static LTDominatorInfo getInfo(BasicBlock block, IR ir) { 266 return ir.getLtDominators().getInfo(block); 267 } 268 269 /** 270 * return the immediate dominator of a basic block. 271 * Note: the dominator info must be pre-calculated 272 * @param bb the basic block in question 273 * @param ir the IR that contains the information about the dominators 274 * @return bb's immediate dominator 275 */ 276 public static BasicBlock getIdom(BasicBlock bb, IR ir) { 277 return getInfo(bb, ir).dominator; 278 } 279 280 /** 281 * Prints a string version of objection 282 */ 283 @Override 284 public String toString() { 285 return super.toString() + " [Parent: " + parent + " SDom: " + semiDominator + " Dom: " + dominator + "]"; 286 } 287}