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}