BreakCriticalMachineEdge.h

Hi LLVMers,

     what is the status of breaking critical edges in machine functions? I just compiled the top of the LLVM tree, and I found llvm/CodeGen/BreakCriticalMachineEdge.h. But this file seems not to be up-to-date with the other classes in the top of the tree. For instance, it calls isTerminatorInstr on llvm::TargetInstrInfo, but this method is no longer there.
     If I want to break critical edges of machine basic blocks, does LLVM 2.2 give me something to work with?

best,

Fernando

Fernando,

The code there should be more or less functional, though it's not currently used by anything. Eventually it should probably be moved to a method on MachineBasicBlock.

The API breakage you're seeing is because some methods moved around. Feel free to fix it. :slight_smile:

--Owen

Hi, Owen,

     I just fixed the mismatches, and the code now works. I tried it in all the SPEC2000, and it works as before.
     In any case, I am sending the code below the replays. It is working fine, if you guys want to patch it.

best,

Fernando

Fernando,

The code there should be more or less functional, though it's not currently used by anything. Eventually it should probably be moved to a method on MachineBasicBlock.

The API breakage you're seeing is because some methods moved around. Feel free to fix it. :slight_smile:

--Owen

Hi LLVMers,

   what is the status of breaking critical edges in machine functions? I
just compiled the top of the LLVM tree, and I found
llvm/CodeGen/BreakCriticalMachineEdge.h. But this file seems not to be
up-to-date with the other classes in the top of the tree. For instance, it
calls isTerminatorInstr on llvm::TargetInstrInfo, but this method is no
longer there.

MachineBasicBlock* SplitCriticalMachineEdge(MachineBasicBlock* src,
                                             MachineBasicBlock* dst) {
   const BasicBlock* srcBB = src->getBasicBlock();

   MachineBasicBlock* crit_mbb = new MachineBasicBlock(srcBB);

   // modify the llvm control flow graph
   src->removeSuccessor(dst);
   src->addSuccessor(crit_mbb);
   crit_mbb->addSuccessor(dst);

   // insert the new block into the machine function.
   src->getParent()->getBasicBlockList().insert(src->getParent()->end(),
                                                crit_mbb);

   // insert a unconditional branch linking the new block to dst
   const TargetMachine& TM = src->getParent()->getTarget();
   const TargetInstrInfo* TII = TM.getInstrInfo();
   std::vector<MachineOperand> emptyConditions;
   TII->InsertBranch(*crit_mbb, dst, (MachineBasicBlock*)0, emptyConditions);

   // modify every branch in src that points to dst to point to the new
   // machine basic block instead:
   MachineBasicBlock::iterator mii = src->end();
   bool found_branch = false;
   while (mii != src->begin()) {
     mii--;
     // if there are no more branches, finish the loop
     if (!mii->getDesc().isTerminator()) {
       break;
     }

     // Scan the operands of this branch, replacing any uses of dst with
     // crit_mbb.
     for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
       MachineOperand & mo = mii->getOperand(i);
       if (mo.isMachineBasicBlock() &&
           mo.getMBB() == dst) {
         found_branch = true;
         mo.setMBB(crit_mbb);
       }
     }
   }

   // TODO: This is tentative. It may be necessary to fix this code. Maybe
   // I am inserting too many gotos, but I am trusting that the asm printer
   // will optimize the unnecessary gotos.
   if(!found_branch) {
     TII->InsertBranch(*src, crit_mbb, (MachineBasicBlock*)0, emptyConditions);
   }

   /// Change all the phi functions in dst, so that the incoming block be
   /// crit_mbb, instead of src
   for(mii = dst->begin(); mii != dst->end(); mii++) {
     /// the first instructions are always phi functions.
     if(mii->getOpcode() != TargetInstrInfo::PHI)
       break;

     // Find the operands corresponding to the source block
     std::vector<unsigned> toRemove;
     unsigned reg = 0;
     for (unsigned u = 0; u != mii->getNumOperands(); ++u)
       if (mii->getOperand(u).isMachineBasicBlock() &&
           mii->getOperand(u).getMBB() == src) {
         reg = mii->getOperand(u-1).getReg();
         toRemove.push_back(u-1);
       }
     // Remove all uses of this MBB
     for (std::vector<unsigned>::reverse_iterator I = toRemove.rbegin(),
          E = toRemove.rend(); I != E; ++I) {
       mii->RemoveOperand(*I+1);
       mii->RemoveOperand(*I);
     }

     // Add a single use corresponding to the new MBB
     mii->addOperand(MachineOperand::CreateReg(reg, false));
     mii->addOperand(MachineOperand::CreateMBB(crit_mbb));
   }

   return crit_mbb;
}