diff options
| author | Chris Lattner <sabre@nondot.org> | 2006-11-18 21:56:39 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2006-11-18 21:56:39 +0000 |
| commit | 56ec81ff731c4f515eb59faf8139b93179216c13 (patch) | |
| tree | 881c5c8b04cdd5a78a2e5e684e5aed9423c3ffda /llvm/lib/CodeGen/BranchFolding.cpp | |
| parent | e008326b86d2a500e0b046937430f6842c5b4d5d (diff) | |
| download | bcm5719-llvm-56ec81ff731c4f515eb59faf8139b93179216c13.tar.gz bcm5719-llvm-56ec81ff731c4f515eb59faf8139b93179216c13.zip | |
Fix another case we *don't* want to do this xform.
llvm-svn: 31861
Diffstat (limited to 'llvm/lib/CodeGen/BranchFolding.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/BranchFolding.cpp | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/BranchFolding.cpp b/llvm/lib/CodeGen/BranchFolding.cpp index d43b6879f3f..c69930da81e 100644 --- a/llvm/lib/CodeGen/BranchFolding.cpp +++ b/llvm/lib/CodeGen/BranchFolding.cpp @@ -16,6 +16,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "branchfolding" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/MachineDebugInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -23,6 +24,7 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" #include <algorithm> @@ -705,17 +707,39 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { if (!PriorCond.empty() && PriorFBB == 0 && MachineFunction::iterator(PriorTBB) == FallThrough && !CanFallThrough(MBB)) { + bool DoTransform = true; + // We have to be careful that the succs of PredBB aren't both no-successor // blocks. If neither have successors and if PredBB is the second from // last block in the function, we'd just keep swapping the two blocks for // last. Only do the swap if one is clearly better to fall through than // the other. - if (FallThrough != --MBB->getParent()->end() || - IsBetterFallthrough(PriorTBB, MBB, *TII)) { + if (FallThrough == --MBB->getParent()->end() && + !IsBetterFallthrough(PriorTBB, MBB, *TII)) + DoTransform = false; + + // We don't want to do this transformation if we have control flow like: + // br cond BB2 + // BB1: + // .. + // jmp BBX + // BB2: + // .. + // ret + // + // In this case, we could actually be moving the return block *into* a + // loop! + if (DoTransform && !MBB->succ_empty() && !CanFallThrough(PriorTBB)) + DoTransform = false; + + if (DoTransform) { // Reverse the branch so we will fall through on the previous true cond. std::vector<MachineOperand> NewPriorCond(PriorCond); if (!TII->ReverseBranchCondition(NewPriorCond)) { + DOUT << "\nMoving MBB: " << *MBB; + DOUT << "To make fallthrough to: " << *PriorTBB << "\n"; + TII->RemoveBranch(PrevBB); TII->InsertBranch(PrevBB, MBB, 0, NewPriorCond); |

