[LLVMdev] Inserting MachineBasicBlock(s) before a MachineBasicBlock

Fernando Magno Quintao Pereira fernando at CS.UCLA.EDU
Tue Sep 30 10:56:08 PDT 2008

> I want to be able to do two things with LLVM (both just before code
> emission):
> 1. Insert a MachineBasicBlock just before a MachineBasicBlock.
> There is a function called AddPredecessor(). However, the comment says that
> it does not update the actual CFG. I want to redirect all CFG edges that are
> incoming to this MachineBasicBlock to the new one I create, and add just one
> outgoing edge (no branch) to the newly formed MachineBasicBlock to jump to
> the original MachineBasicBlock. How can I do this?


    I had an old pass to break critical edges, and I am sending you the 
code below. I Last tested it with LLVM 2.1. It inserts a basic block 
between src and dst.



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

   MachineBasicBlock* crit_mbb = new MachineBasicBlock(srcBB);

   // modify the llvm control flow graph

   // insert the new block into the machine function.

   // 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, 

   // 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()) {
     // if there are no more branches, finish the loop
     if (!TII->isTerminatorInstr(mii->getOpcode())) {

     // 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.getMachineBasicBlock() == dst) {
         found_branch = true;

   // 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, 

   /// 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)

     for (unsigned u = 0; u != mii->getNumOperands(); ++u)
       if (mii->getOperand(u).isMachineBasicBlock() &&
           mii->getOperand(u).getMachineBasicBlock() == src)

   return crit_mbb;

More information about the llvm-dev mailing list