Program: 150068
Project: 150068
Buggy source:
/** 
 * Reorder code using Algo2 (Bottom-Up Positioning) from Pettis and Hansen PLDI'90.
 * @param ir the OPT_IR to reorder.
 */
private void doPettisHansenAlgo2(OPT_IR ir){
  int numBlocks=0;
  SortedSet edges=new TreeSet();
  Set chainHeads=new HashSet();
  OPT_BasicBlock entry=ir.cfg.entry();
  if (VM.VerifyAssertions)   VM._assert(ir.cfg.entry() == ir.cfg.firstInCodeOrder());
  for (OPT_BasicBlock bb=entry; bb != null; bb=bb.nextBasicBlockInCodeOrder()) {
    numBlocks++;
    chainHeads.add(bb);
    bb.scratchObject=bb;
    OPT_BasicBlock ft=bb.getFallThroughBlock();
    if (ft != null) {
      bb.appendInstruction(Goto.create(GOTO,ft.makeJumpTarget()));
    }
    float bw=bb.getExecutionFrequency();
    for (OPT_WeightedBranchTargets wbt=new OPT_WeightedBranchTargets(bb); wbt.hasMoreElements(); wbt.advance()) {
      edges.add(new Edge(bb,wbt.curBlock(),wbt.curWeight() * bw));
    }
  }
  if (DEBUG)   VM.sysWriteln("String_Node_Str" + edges);
  ir.cfg.clearCodeOrder();
  for (Iterator edgesI=edges.iterator(); edgesI.hasNext(); ) {
    Edge e=(Edge)edgesI.next();
    if (DEBUG)     VM.sysWriteln("String_Node_Str" + e);
    if (e.target == entry) {
      if (DEBUG)       VM.sysWriteln("String_Node_Str");
      continue;
    }
    if (e.source.nextBasicBlockInCodeOrder() != null) {
      if (DEBUG)       VM.sysWriteln("String_Node_Str");
      continue;
    }
    if (e.target.prevBasicBlockInCodeOrder() != null) {
      if (DEBUG)       VM.sysWriteln("String_Node_Str");
      continue;
    }
    if (e.source.scratchObject == e.target.scratchObject) {
      if (DEBUG)       VM.sysWriteln("String_Node_Str");
      continue;
    }
    if (DEBUG)     VM.sysWriteln("String_Node_Str");
    chainHeads.remove(e.target);
    ir.cfg.linkInCodeOrder(e.source,e.target);
    OPT_BasicBlock newChain=(OPT_BasicBlock)e.source.scratchObject;
    for (OPT_BasicBlock ptr=e.target; ptr != null; ptr=ptr.nextBasicBlockInCodeOrder()) {
      ptr.scratchObject=newChain;
    }
  }
  if (DEBUG)   VM.sysWriteln("String_Node_Str");
  Map chainInfo=new HashMap();
  for (Iterator chainI=chainHeads.iterator(); chainI.hasNext(); ) {
    OPT_BasicBlock head=(OPT_BasicBlock)chainI.next();
    if (DEBUG)     dumpChain(head);
    chainInfo.put(head,new ChainInfo(head));
  }
  for (Iterator edgesI=edges.iterator(); edgesI.hasNext(); ) {
    Edge e=(Edge)edgesI.next();
    if (e.source.scratchObject != e.target.scratchObject) {
      Object sourceChain=e.source.scratchObject;
      Object targetChain=e.target.scratchObject;
      ChainInfo sourceInfo=(ChainInfo)chainInfo.get(sourceChain);
      ChainInfo targetInfo=(ChainInfo)chainInfo.get(targetChain);
      if (DEBUG)       VM.sysWriteln("String_Node_Str" + sourceChain + "String_Node_Str"+ targetChain+ "String_Node_Str"+ e.weight+ "String_Node_Str");
      Object value=sourceInfo.outWeights.get(targetInfo);
      float weight=e.weight;
      if (value != null) {
        weight+=((Float)value).floatValue();
      }
      sourceInfo.outWeights.put(targetInfo,new Float(weight));
      targetInfo.inWeight+=e.weight;
      if (DEBUG)       VM.sysWriteln("String_Node_Str" + targetInfo + "String_Node_Str"+ sourceInfo.outWeights.get(targetInfo));
    }
  }
  if (DEBUG)   VM.sysWriteln("String_Node_Str" + chainInfo);
  OPT_BasicBlock lastNode=null;
  ChainInfo nextChoice=(ChainInfo)chainInfo.get(entry);
  int numPlaced=0;
  ir.cfg._firstNode=entry;
  while (true) {
    if (DEBUG)     VM.sysWriteln("String_Node_Str" + nextChoice);
    if (lastNode != null)     ir.cfg.linkInCodeOrder(lastNode,nextChoice.head);
    for (OPT_BasicBlock ptr=nextChoice.head; ptr != null; ptr=ptr.nextBasicBlockInCodeOrder()) {
      numPlaced++;
      lastNode=ptr;
    }
    chainInfo.remove(nextChoice.head);
    if (chainInfo.isEmpty())     break;
    for (Iterator i=nextChoice.outWeights.keySet().iterator(); i.hasNext(); ) {
      ChainInfo target=(ChainInfo)i.next();
      if (DEBUG)       VM.sysWrite("String_Node_Str" + target);
      float weight=((Float)nextChoice.outWeights.get(target)).floatValue();
      if (DEBUG)       VM.sysWriteln("String_Node_Str" + weight);
      target.placedWeight+=weight;
      target.inWeight-=weight;
    }
    if (DEBUG)     VM.sysWriteln("String_Node_Str" + chainInfo);
    nextChoice=null;
    float placedWeight=0f;
    for (Iterator i=chainInfo.values().iterator(); i.hasNext(); ) {
      ChainInfo cand=(ChainInfo)i.next();
      if (cand.placedWeight > 0f) {
        if (nextChoice == null) {
          if (DEBUG)           VM.sysWriteln("String_Node_Str" + cand);
          nextChoice=cand;
        }
 else         if (cand.inWeight < nextChoice.inWeight || (cand.inWeight == nextChoice.inWeight && cand.placedWeight > nextChoice.placedWeight)) {
          if (DEBUG)           VM.sysWriteln(cand + "String_Node_Str" + nextChoice);
          nextChoice=cand;
        }
      }
    }
    if (nextChoice != null)     continue;
    for (Iterator i=chainInfo.values().iterator(); i.hasNext(); ) {
      ChainInfo cand=(ChainInfo)i.next();
      if (nextChoice == null) {
        if (DEBUG)         VM.sysWriteln("String_Node_Str" + cand);
        nextChoice=cand;
      }
 else       if (cand.inWeight < nextChoice.inWeight) {
        if (DEBUG)         VM.sysWriteln(cand + "String_Node_Str" + nextChoice);
        nextChoice=cand;
      }
    }
  }
  if (VM.VerifyAssertions)   VM._assert(numPlaced == numBlocks);
  ir.cfg._lastNode=lastNode;
}

Fixed version (ground truth):
/** 
 * Reorder code using Algo2 (Bottom-Up Positioning) from Pettis and Hansen PLDI'90.
 * @param ir the OPT_IR to reorder.
 */
private void doPettisHansenAlgo2(OPT_IR ir){
  int numBlocks=0;
  SortedSet edges=new TreeSet();
  Set chainHeads=new HashSet();
  OPT_BasicBlock entry=ir.cfg.entry();
  if (VM.VerifyAssertions)   VM._assert(ir.cfg.entry() == ir.cfg.firstInCodeOrder());
  for (OPT_BasicBlock bb=entry; bb != null; bb=bb.nextBasicBlockInCodeOrder()) {
    numBlocks++;
    chainHeads.add(bb);
    bb.scratchObject=bb;
    OPT_BasicBlock ft=bb.getFallThroughBlock();
    if (ft != null) {
      bb.appendInstruction(Goto.create(GOTO,ft.makeJumpTarget()));
    }
    float bw=bb.getExecutionFrequency();
    for (OPT_WeightedBranchTargets wbt=new OPT_WeightedBranchTargets(bb); wbt.hasMoreElements(); wbt.advance()) {
      edges.add(new Edge(bb,wbt.curBlock(),wbt.curWeight() * bw));
    }
  }
  if (DEBUG)   VM.sysWriteln("String_Node_Str" + edges);
  ir.cfg.clearCodeOrder();
  for (Iterator edgesI=edges.iterator(); edgesI.hasNext(); ) {
    Edge e=(Edge)edgesI.next();
    if (DEBUG)     VM.sysWriteln("String_Node_Str" + e);
    if (e.target == entry) {
      if (DEBUG)       VM.sysWriteln("String_Node_Str");
      continue;
    }
    if (e.source.nextBasicBlockInCodeOrder() != null) {
      if (DEBUG)       VM.sysWriteln("String_Node_Str");
      continue;
    }
    if (e.target.prevBasicBlockInCodeOrder() != null) {
      if (DEBUG)       VM.sysWriteln("String_Node_Str");
      continue;
    }
    if (e.source.scratchObject == e.target.scratchObject) {
      if (DEBUG)       VM.sysWriteln("String_Node_Str");
      continue;
    }
    if (DEBUG)     VM.sysWriteln("String_Node_Str");
    chainHeads.remove(e.target);
    ir.cfg.linkInCodeOrder(e.source,e.target);
    OPT_BasicBlock newChain=(OPT_BasicBlock)e.source.scratchObject;
    for (OPT_BasicBlock ptr=e.target; ptr != null; ptr=ptr.nextBasicBlockInCodeOrder()) {
      ptr.scratchObject=newChain;
    }
  }
  if (DEBUG)   VM.sysWriteln("String_Node_Str");
  Map chainInfo=new HashMap();
  for (Iterator chainI=chainHeads.iterator(); chainI.hasNext(); ) {
    OPT_BasicBlock head=(OPT_BasicBlock)chainI.next();
    if (DEBUG)     dumpChain(head);
    chainInfo.put(head,new ChainInfo(head));
  }
  for (Iterator edgesI=edges.iterator(); edgesI.hasNext(); ) {
    Edge e=(Edge)edgesI.next();
    if (e.source.scratchObject != e.target.scratchObject) {
      Object sourceChain=e.source.scratchObject;
      Object targetChain=e.target.scratchObject;
      ChainInfo sourceInfo=(ChainInfo)chainInfo.get(sourceChain);
      ChainInfo targetInfo=(ChainInfo)chainInfo.get(targetChain);
      if (DEBUG)       VM.sysWriteln("String_Node_Str" + sourceChain + "String_Node_Str"+ targetChain+ "String_Node_Str"+ e.weight+ "String_Node_Str");
      Object value=sourceInfo.outWeights.get(targetInfo);
      float weight=e.weight;
      if (value != null) {
        weight+=((Float)value).floatValue();
      }
      sourceInfo.outWeights.put(targetInfo,new Float(weight));
      targetInfo.inWeight+=e.weight;
      if (DEBUG)       VM.sysWriteln("String_Node_Str" + targetInfo + "String_Node_Str"+ sourceInfo.outWeights.get(targetInfo));
    }
  }
  if (DEBUG)   VM.sysWriteln("String_Node_Str" + chainInfo);
  OPT_BasicBlock lastNode=null;
  ChainInfo nextChoice=(ChainInfo)chainInfo.get(entry);
  int numPlaced=0;
  ir.cfg._firstNode=entry;
  while (true) {
    if (DEBUG)     VM.sysWriteln("String_Node_Str" + nextChoice);
    if (lastNode != null)     ir.cfg.linkInCodeOrder(lastNode,nextChoice.head);
    for (OPT_BasicBlock ptr=nextChoice.head; ptr != null; ptr=ptr.nextBasicBlockInCodeOrder()) {
      numPlaced++;
      lastNode=ptr;
    }
    chainInfo.remove(nextChoice.head);
    if (chainInfo.isEmpty())     break;
    for (Iterator i=nextChoice.outWeights.keySet().iterator(); i.hasNext(); ) {
      ChainInfo target=(ChainInfo)i.next();
      if (DEBUG)       VM.sysWrite("String_Node_Str" + target);
      float weight=((Float)nextChoice.outWeights.get(target)).floatValue();
      if (DEBUG)       VM.sysWriteln("String_Node_Str" + weight);
      target.placedWeight+=weight;
      target.inWeight-=weight;
    }
    if (DEBUG)     VM.sysWriteln("String_Node_Str" + chainInfo);
    nextChoice=null;
    float placedWeight=0f;
    for (Iterator i=chainInfo.values().iterator(); i.hasNext(); ) {
      ChainInfo cand=(ChainInfo)i.next();
      if (cand.placedWeight > 0f) {
        if (nextChoice == null) {
          if (DEBUG)           VM.sysWriteln("String_Node_Str" + cand);
          nextChoice=cand;
        }
 else         if (cand.inWeight > nextChoice.inWeight || (cand.inWeight == nextChoice.inWeight && cand.placedWeight > nextChoice.placedWeight)) {
          if (DEBUG)           VM.sysWriteln(cand + "String_Node_Str" + nextChoice);
          nextChoice=cand;
        }
      }
    }
    if (nextChoice != null)     continue;
    for (Iterator i=chainInfo.values().iterator(); i.hasNext(); ) {
      ChainInfo cand=(ChainInfo)i.next();
      if (nextChoice == null) {
        if (DEBUG)         VM.sysWriteln("String_Node_Str" + cand);
        nextChoice=cand;
      }
 else       if (cand.inWeight < nextChoice.inWeight) {
        if (DEBUG)         VM.sysWriteln(cand + "String_Node_Str" + nextChoice);
        nextChoice=cand;
      }
    }
  }
  if (VM.VerifyAssertions)   VM._assert(numPlaced == numBlocks);
  ir.cfg._lastNode=lastNode;
}