LLVM API Documentation
00001 //===--------- BreakCriticalMachineEdge.h - Break critical edges ---------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===---------------------------------------------------------------------===// 00009 // 00010 // Helper function to break a critical machine edge. 00011 // 00012 //===---------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CODEGEN_BREAKCRITICALMACHINEEDGE_H 00015 #define LLVM_CODEGEN_BREAKCRITICALMACHINEEDGE_H 00016 00017 #include "llvm/CodeGen/MachineJumpTableInfo.h" 00018 #include "llvm/Target/TargetInstrInfo.h" 00019 #include "llvm/Target/TargetMachine.h" 00020 00021 namespace llvm { 00022 00023 MachineBasicBlock* SplitCriticalMachineEdge(MachineBasicBlock* src, 00024 MachineBasicBlock* dst) { 00025 MachineFunction &MF = *src->getParent(); 00026 const BasicBlock* srcBB = src->getBasicBlock(); 00027 00028 MachineBasicBlock* crit_mbb = MF.CreateMachineBasicBlock(srcBB); 00029 00030 // modify the llvm control flow graph 00031 src->removeSuccessor(dst); 00032 src->addSuccessor(crit_mbb); 00033 crit_mbb->addSuccessor(dst); 00034 00035 // insert the new block into the machine function. 00036 MF.push_back(crit_mbb); 00037 00038 // insert a unconditional branch linking the new block to dst 00039 const TargetMachine& TM = MF.getTarget(); 00040 const TargetInstrInfo* TII = TM.getInstrInfo(); 00041 std::vector<MachineOperand> emptyConditions; 00042 TII->InsertBranch(*crit_mbb, dst, (MachineBasicBlock*)0, 00043 emptyConditions); 00044 00045 // modify every branch in src that points to dst to point to the new 00046 // machine basic block instead: 00047 MachineBasicBlock::iterator mii = src->end(); 00048 bool found_branch = false; 00049 while (mii != src->begin()) { 00050 mii--; 00051 // if there are no more branches, finish the loop 00052 if (!mii->getDesc().isTerminator()) { 00053 break; 00054 } 00055 00056 // Scan the operands of this branch, replacing any uses of dst with 00057 // crit_mbb. 00058 for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) { 00059 MachineOperand & mo = mii->getOperand(i); 00060 if (mo.isMBB() && mo.getMBB() == dst) { 00061 found_branch = true; 00062 mo.setMBB(crit_mbb); 00063 } 00064 } 00065 } 00066 00067 // TODO: This is tentative. It may be necessary to fix this code. Maybe 00068 // I am inserting too many gotos, but I am trusting that the asm printer 00069 // will optimize the unnecessary gotos. 00070 if(!found_branch) { 00071 TII->InsertBranch(*src, crit_mbb, (MachineBasicBlock*)0, 00072 emptyConditions); 00073 } 00074 00075 /// Change all the phi functions in dst, so that the incoming block be 00076 /// crit_mbb, instead of src 00077 for(mii = dst->begin(); mii != dst->end(); mii++) { 00078 /// the first instructions are always phi functions. 00079 if(mii->getOpcode() != TargetInstrInfo::PHI) 00080 break; 00081 00082 // Find the operands corresponding to the source block 00083 std::vector<unsigned> toRemove; 00084 unsigned reg = 0; 00085 for (unsigned u = 0; u != mii->getNumOperands(); ++u) 00086 if (mii->getOperand(u).isMBB() && 00087 mii->getOperand(u).getMBB() == src) { 00088 reg = mii->getOperand(u-1).getReg(); 00089 toRemove.push_back(u-1); 00090 } 00091 // Remove all uses of this MBB 00092 for (std::vector<unsigned>::reverse_iterator I = toRemove.rbegin(), 00093 E = toRemove.rend(); I != E; ++I) { 00094 mii->RemoveOperand(*I+1); 00095 mii->RemoveOperand(*I); 00096 } 00097 00098 // Add a single use corresponding to the new MBB 00099 mii->addOperand(MachineOperand::CreateReg(reg, false)); 00100 mii->addOperand(MachineOperand::CreateMBB(crit_mbb)); 00101 } 00102 00103 return crit_mbb; 00104 } 00105 00106 } 00107 00108 #endif