diff options
author | Owen Anderson <resistor@mac.com> | 2007-11-12 01:05:09 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2007-11-12 01:05:09 +0000 |
commit | fe0c882e5a6ddf4e3c9f771485fdaa4672759539 (patch) | |
tree | 5c630791aaec2bc691c48fd3f602ada521d3c9f8 /include/llvm/CodeGen/BreakCriticalMachineEdge.h | |
parent | e7e113361ea550afbb8bebcdc1e736c5d4833f8c (diff) |
As Chris and Evan pointed out, BreakCriticalMachineEdges doesn't really need
to be a pass of its own. Instead, move it out into a helper method.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44002 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/CodeGen/BreakCriticalMachineEdge.h')
-rw-r--r-- | include/llvm/CodeGen/BreakCriticalMachineEdge.h | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/include/llvm/CodeGen/BreakCriticalMachineEdge.h b/include/llvm/CodeGen/BreakCriticalMachineEdge.h new file mode 100644 index 0000000000..c02eaa784a --- /dev/null +++ b/include/llvm/CodeGen/BreakCriticalMachineEdge.h @@ -0,0 +1,94 @@ +//===--------- BreakCriticalMachineEdges.h - Break critical edges ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Fernando Pereira and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +// +// Helper function to break a critical machine edge. +// +//===---------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_ASMPRINTER_H +#define LLVM_CODEGEN_ASMPRINTER_H + +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Support/Compiler.h" + +namespace llvm { + +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 (!TII->isTerminatorInstr(mii->getOpcode())) { + 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.getMachineBasicBlock() == dst) { + found_branch = true; + mo.setMachineBasicBlock(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; + + for (unsigned u = 0; u != mii->getNumOperands(); ++u) + if (mii->getOperand(u).isMachineBasicBlock() && + mii->getOperand(u).getMachineBasicBlock() == src) + mii->getOperand(u).setMachineBasicBlock(crit_mbb); + } + + return crit_mbb; +} + +} + +#endif |