/**
  * This recursive method performs the path compression
  *
  * @param block the block of interest
  */
 private void compress(BasicBlock block) {
   if (getAncestor(getAncestor(block)) != null) {
     compress(getAncestor(block));
     LTDominatorInfo blockInfo = LTDominatorInfo.getInfo(block);
     if (getSemi(getLabel(getAncestor(block))) < getSemi(getLabel(block))) {
       blockInfo.setLabel(getLabel(getAncestor(block)));
     }
     blockInfo.setAncestor(getAncestor(getAncestor(block)));
   }
 }
  /** This is the heart of the algorithm. See sources for details. */
  private void step2() {
    if (DEBUG) {
      System.out.println(" ******* Beginning STEP 2 *******\n");
    }

    // Visit each node in reverse DFS order, except for the root, which
    // has number 1
    // for i=n downto 2
    for (int i = DFSCounter; i > 1; i--) {
      // block = vertex[i]
      BasicBlock block = vertex[i];
      LTDominatorInfo blockInfo = LTDominatorInfo.getInfo(block);

      if (DEBUG) {
        System.out.println(" Processing: " + block + "\n");
      }

      // visit each predecessor
      BasicBlockEnumeration e = getPrevNodes(block);
      while (e.hasMoreElements()) {
        BasicBlock prev = e.next();
        if (DEBUG) {
          System.out.println("    Inspecting prev: " + prev);
        }
        BasicBlock u = EVAL(prev);
        // if semi(u) < semi(block) then semi(block) = semi(u)
        // u may be part of infinite loop and thus, is unreachable from the exit node.
        // In this case, it will have a semi value of 0.  Thus, we screen for it here
        if (getSemi(u) != 0 && getSemi(u) < getSemi(block)) {
          blockInfo.setSemiDominator(getSemi(u));
        }
      } // while prev

      // add "block" to bucket(vertex(semi(block)));
      LTDominatorInfo.getInfo(vertex[blockInfo.getSemiDominator()]).addToBucket(block);

      // LINK(parent(block), block)
      LINK(blockInfo.getParent(), block);

      // foreach block2 in bucket(parent(block)) do
      java.util.Iterator<BasicBlock> bucketEnum =
          LTDominatorInfo.getInfo(getParent(block)).getBucketIterator();
      while (bucketEnum.hasNext()) {
        BasicBlock block2 = bucketEnum.next();

        // u = EVAL(block2)
        BasicBlock u = EVAL(block2);

        // if semi(u) < semi(block2) then
        //    dom(block2) = u
        // else
        //    dom(block2) = parent(block)
        if (getSemi(u) < getSemi(block2)) {
          LTDominatorInfo.getInfo(block2).setDominator(u);
        } else {
          LTDominatorInfo.getInfo(block2).setDominator(getParent(block));
        }
      } // while bucket has more elements
    } // for DFSCounter .. 1
  } // method
 /**
  * Adds edge (block1, block2) to the forest maintained as an auxiliary data structure. This
  * implementation uses path compression and results in a O(e * alpha(e,n)) complexity, where e is
  * the number of edges in the CFG and n is the number of nodes.
  *
  * @param block1 a basic block corresponding to the source of the new edge
  * @param block2 a basic block corresponding to the source of the new edge
  */
 private void LINK(BasicBlock block1, BasicBlock block2) {
   if (DEBUG) {
     System.out.println("  Linking " + block1 + " with " + block2);
   }
   BasicBlock s = block2;
   while (getSemi(getLabel(block2)) < getSemi(getLabel(getChild(s)))) {
     if (getSize(s) + getSize(getChild(getChild(s))) >= 2 * getSize(getChild(s))) {
       LTDominatorInfo.getInfo(getChild(s)).setAncestor(s);
       LTDominatorInfo.getInfo(s).setChild(getChild(getChild(s)));
     } else {
       LTDominatorInfo.getInfo(getChild(s)).setSize(getSize(s));
       LTDominatorInfo.getInfo(s).setAncestor(getChild(s));
       s = getChild(s);
     }
   }
   LTDominatorInfo.getInfo(s).setLabel(getLabel(block2));
   LTDominatorInfo.getInfo(block1).setSize(getSize(block1) + getSize(block2));
   if (getSize(block1) < 2 * getSize(block2)) {
     BasicBlock tmp = s;
     s = getChild(block1);
     LTDominatorInfo.getInfo(block1).setChild(tmp);
   }
   while (s != null) {
     LTDominatorInfo.getInfo(s).setAncestor(block1);
     s = getChild(s);
   }
   if (DEBUG) {
     System.out.println("  .... done");
   }
 }
  /**
   * Print the nodes that dominate each basic block
   *
   * @param ir the IR
   */
  private void printResults(IR ir) {
    if (forward) {
      System.out.println(
          "Results of dominators computation for method " + ir.method.getName() + "\n");
      System.out.println("   Here's the CFG:");
      System.out.println(ir.cfg);
      System.out.println("\n\n  Here's the Dominator Info:");
    } else {
      System.out.println(
          "Results of Post-Dominators computation for method " + ir.method.getName() + "\n");
      System.out.println("   Here's the CFG:");
      System.out.println(ir.cfg);
      System.out.println("\n\n  Here's the Post-Dominator Info:");
    }

    for (Enumeration<BasicBlock> bbEnum = cfg.basicBlocks(); bbEnum.hasMoreElements(); ) {
      BasicBlock block = bbEnum.nextElement();
      // We don't compute a result for the exit node for forward direction
      if (!forward || !block.isExit()) {
        System.out.println(
            "Dominators of " + block + ":" + LTDominatorInfo.getInfo(block).dominators(block, ir));
      }
    }
    System.out.println("\n");
  }
 /** This final step sets the final dominator information. */
 private void step3() {
   // Visit each node in DFS order, except for the root, which has number 1
   for (int i = 2; i <= DFSCounter; i++) {
     BasicBlock block = vertex[i];
     // if dom(block) != vertex[semi(block)]
     if (getDom(block) != vertex[getSemi(block)]) {
       // dom(block) = dom(dom(block))
       LTDominatorInfo.getInfo(block).setDominator(getDom(getDom(block)));
     }
   }
 }
 /**
  * Get the child node for this block
  *
  * @param block
  * @return the child node
  */
 private BasicBlock getChild(BasicBlock block) {
   return LTDominatorInfo.getInfo(block).getChild();
 }
 /**
  * returns the size associated with the block
  *
  * @param block
  * @return the size of the block or 0 if the block is null
  */
 private int getSize(BasicBlock block) {
   if (block == null) {
     return 0;
   }
   return LTDominatorInfo.getInfo(block).getSize();
 }
 /**
  * returns the label for the passed block or null if the block is null
  *
  * @param block
  * @return the label for the passed block or null if the block is null
  */
 private BasicBlock getLabel(BasicBlock block) {
   if (block == null) {
     return null;
   }
   return LTDominatorInfo.getInfo(block).getLabel();
 }
 /**
  * Returns the ancestor for the passed block
  *
  * @param block
  * @return the ancestor for the passed block
  */
 private BasicBlock getAncestor(BasicBlock block) {
   return LTDominatorInfo.getInfo(block).getAncestor();
 }
Example #10
0
 /**
  * Returns the parent for the passed block
  *
  * @param block
  * @return the parent for the passed block
  */
 private BasicBlock getParent(BasicBlock block) {
   return LTDominatorInfo.getInfo(block).getParent();
 }
Example #11
0
  /**
   * The non-recursive depth-first numbering code called from Step 1. The recursive version was too
   * costly on the toba benchmark on Linux/IA32.
   *
   * @param block the basic block to process
   */
  protected void DFS(BasicBlock block) {

    // push node on to the emulated activation stack
    push(block);

    recurse:
    while (!empty()) {

      block = peek();
      if (DEBUG) {
        System.out.println(" Processing (peek)" + block);
      }

      if (block == null) {
        if (DEBUG) {
          System.out.println(" Popping");
        }
        pop(); // return
        continue;
      }

      // The current Dominance Frontier and SSA code assumes the exit
      // node will not be part of the (regular) dominator solution.
      // To avoid this from happening we screen it out here for forward CFG
      //
      // However, it really shouldn't be in the CFG, if it isn't a node!
      if (forward && block == cfg.exit()) {
        if (DEBUG) {
          System.out.println(" Popping");
        }
        pop(); // return
        continue;
      }

      BasicBlockEnumeration e;
      e = LTDominatorInfo.getInfo(block).getEnum();

      if (e == null) {
        if (DEBUG) {
          System.out.println(" Initial processing of " + block);
        }

        DFSCounter++;
        LTDominatorInfo.getInfo(block).setSemiDominator(DFSCounter);
        vertex[DFSCounter] = block;
        e = getNextNodes(block);
      } else {
        if (DEBUG) {
          System.out.println(" Resuming processing of " + block);
        }
      }

      while (e.hasMoreElements()) {
        BasicBlock next = e.next();

        if (DEBUG) {
          System.out.println("    Inspecting next node: " + next);
        }

        // We treat the exit node as not being in the CFG for forward direction
        if (forward && next.isExit()) {
          continue; // inner loop
        }
        if (getSemi(next) == 0) {
          LTDominatorInfo.getInfo(next).setParent(block);

          // simulate a recursive call
          // save the enumeration state for resumption later
          LTDominatorInfo.getInfo(block).setEnum(e);

          if (DEBUG) {
            System.out.println(" Pushing" + next);
          }
          push(next);
          continue recurse;
        }
      } // while more nexts
      // "Pop" from the emulated activiation stack
      if (DEBUG) {
        System.out.println(" Popping");
      }
      pop();
    } // while stack not empty loop
  }