aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/BranchFolding.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-10-14 00:21:48 +0000
committerChris Lattner <sabre@nondot.org>2006-10-14 00:21:48 +0000
commit7821a8afd3009c3c2760592e61de9e2c31c73e18 (patch)
tree51b20702a7a162023916066614f41dfabc794289 /lib/CodeGen/BranchFolding.cpp
parent78298871eb0c8382b909010a6e5e65e1a2632b8c (diff)
falling off the end of a function is ok with an unreachable instruction.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30950 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/BranchFolding.cpp')
-rw-r--r--lib/CodeGen/BranchFolding.cpp85
1 files changed, 57 insertions, 28 deletions
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index dad23eaaeb..7b5ee6cbae 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -26,32 +26,30 @@ using namespace llvm;
namespace {
struct BranchFolder : public MachineFunctionPass {
virtual bool runOnMachineFunction(MachineFunction &MF);
- virtual const char *getPassName() const { return "Branch Folder"; }
+ virtual const char *getPassName() const { return "Control Flow Optimizer"; }
+ const TargetInstrInfo *TII;
+ bool MadeChange;
private:
- bool OptimizeBlock(MachineFunction::iterator MBB,
- const TargetInstrInfo &TII);
-
- bool isUncondBranch(const MachineInstr *MI, const TargetInstrInfo &TII) {
- return TII.isBarrier(MI->getOpcode()) && TII.isBranch(MI->getOpcode());
- }
- bool isCondBranch(const MachineInstr *MI, const TargetInstrInfo &TII) {
- return TII.isBranch(MI->getOpcode()) && !TII.isBarrier(MI->getOpcode());
- }
+ void OptimizeBlock(MachineFunction::iterator MBB);
};
}
FunctionPass *llvm::createBranchFoldingPass() { return new BranchFolder(); }
bool BranchFolder::runOnMachineFunction(MachineFunction &MF) {
+ TII = MF.getTarget().getInstrInfo();
+ if (!TII) return false;
+
+ //MF.dump();
+
bool EverMadeChange = false;
- bool MadeChange = true;
- const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
+ MadeChange = true;
while (MadeChange) {
MadeChange = false;
for (MachineFunction::iterator MBB = ++MF.begin(), E = MF.end(); MBB != E;
++MBB)
- MadeChange |= OptimizeBlock(MBB, TII);
-
+ OptimizeBlock(MBB);
+
// If branches were folded away somehow, do a quick scan and delete any dead
// blocks.
if (MadeChange) {
@@ -78,13 +76,13 @@ bool BranchFolder::runOnMachineFunction(MachineFunction &MF) {
static void ReplaceUsesOfBlockWith(MachineBasicBlock *BB,
MachineBasicBlock *Old,
MachineBasicBlock *New,
- const TargetInstrInfo &TII) {
+ const TargetInstrInfo *TII) {
assert(Old != New && "Cannot replace self with self!");
MachineBasicBlock::iterator I = BB->end();
while (I != BB->begin()) {
--I;
- if (!TII.isTerminatorInstr(I->getOpcode())) break;
+ if (!TII->isTerminatorInstr(I->getOpcode())) break;
// Scan the operands of this machine instruction, replacing any uses of Old
// with New.
@@ -103,23 +101,55 @@ static void ReplaceUsesOfBlockWith(MachineBasicBlock *BB,
}
}
-
-bool BranchFolder::OptimizeBlock(MachineFunction::iterator MBB,
- const TargetInstrInfo &TII) {
+/// OptimizeBlock - Analyze and optimize control flow related to the specified
+/// block. This is never called on the entry block.
+void BranchFolder::OptimizeBlock(MachineFunction::iterator MBB) {
// If this block is empty, make everyone use its fall-through, not the block
// explicitly.
if (MBB->empty()) {
- if (MBB->pred_empty()) return false;
- MachineFunction::iterator FallThrough =next(MBB);
- assert(FallThrough != MBB->getParent()->end() &&
- "Fell off the end of the function!");
- while (!MBB->pred_empty()) {
- MachineBasicBlock *Pred = *(MBB->pred_end()-1);
- ReplaceUsesOfBlockWith(Pred, MBB, FallThrough, TII);
+ if (MBB->pred_empty()) return; // dead block? Leave for cleanup later.
+
+ MachineFunction::iterator FallThrough = next(MBB);
+
+ if (FallThrough != MBB->getParent()->end()) {
+ while (!MBB->pred_empty()) {
+ MachineBasicBlock *Pred = *(MBB->pred_end()-1);
+ ReplaceUsesOfBlockWith(Pred, MBB, FallThrough, TII);
+ }
+ MadeChange = true;
}
- return true;
+ // TODO: CHANGE STUFF TO NOT BRANCH HERE!
+ return;
}
+ // Check to see if we can simplify the terminator of the block before this
+ // one.
+#if 0
+ MachineBasicBlock *PriorTBB = 0, *PriorFBB = 0;
+ std::vector<MachineOperand> PriorCond;
+ if (!TII->AnalyzeBranch(*prior(MBB), PriorTBB, PriorFBB, PriorCond)) {
+ // If the previous branch is conditional and both conditions go to the same
+ // destination, remove the branch, replacing it with an unconditional one.
+ if (PriorTBB && PriorTBB == PriorFBB) {
+ TII->RemoveBranch(*prior(MBB));
+ PriorCond.clear();
+ if (PriorTBB != &*MBB)
+ TII->InsertBranch(*prior(MBB), PriorTBB, 0, PriorCond);
+ MadeChange = true;
+ return OptimizeBlock(MBB);
+ }
+
+ // If the previous branch *only* branches to *this* block (conditional or
+ // not) remove the branch.
+ if (PriorTBB == &*MBB && PriorFBB == 0) {
+ TII->RemoveBranch(*prior(MBB));
+ MadeChange = true;
+ return OptimizeBlock(MBB);
+ }
+ }
+#endif
+
+
#if 0
if (MBB->pred_size() == 1) {
@@ -235,5 +265,4 @@ bool BranchFolder::OptimizeBlock(MachineFunction::iterator MBB,
}
}
#endif
- return false;
}