[LLVMdev] BreakCriticalMachineEdge.h

Fernando Magno Quintao Pereira fernando at CS.UCLA.EDU
Sun Jan 27 11:19:15 PST 2008


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. :-)
>
> --Owen
>
> On Jan 26, 2008, at 6:31 PM, Fernando Magno Quintao Pereira wrote:
>> 
>> 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;
}



More information about the llvm-dev mailing list