aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-11-18 21:56:39 +0000
committerChris Lattner <sabre@nondot.org>2006-11-18 21:56:39 +0000
commitf10a56a86f8ae32d0493c7de770493d55519b073 (patch)
treed72f79f2495197d714f75356b97f48016d05e604
parent36d68e418d8d044964cf763daf49543d9052d55b (diff)
downloadexternal_llvm-f10a56a86f8ae32d0493c7de770493d55519b073.zip
external_llvm-f10a56a86f8ae32d0493c7de770493d55519b073.tar.gz
external_llvm-f10a56a86f8ae32d0493c7de770493d55519b073.tar.bz2
Fix another case we *don't* want to do this xform.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31861 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/BranchFolding.cpp28
1 files changed, 26 insertions, 2 deletions
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index d43b687..c69930d 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/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);