aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/MachineBasicBlock.cpp
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2009-11-26 00:32:21 +0000
committerBob Wilson <bob.wilson@apple.com>2009-11-26 00:32:21 +0000
commit810ced7daebe78a8d84b94fac07e320a02cecb71 (patch)
tree379bad402a664a687cd94163cc84caa3f2438f41 /lib/CodeGen/MachineBasicBlock.cpp
parent97658f0fa49d6a3d8fd5f14010589e53474d2ba4 (diff)
downloadexternal_llvm-810ced7daebe78a8d84b94fac07e320a02cecb71.zip
external_llvm-810ced7daebe78a8d84b94fac07e320a02cecb71.tar.gz
external_llvm-810ced7daebe78a8d84b94fac07e320a02cecb71.tar.bz2
Split tail duplication into a separate pass. This is needed to avoid
running tail duplication when doing branch folding for if-conversion, and we also want to be able to run tail duplication earlier to fix some reg alloc problems. Move the CanFallThrough function from BranchFolding to MachineBasicBlock so that it can be shared by TailDuplication. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89904 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineBasicBlock.cpp')
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index e6a1878..e55e369 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -362,6 +362,51 @@ bool MachineBasicBlock::isLayoutSuccessor(const MachineBasicBlock *MBB) const {
return next(I) == MachineFunction::const_iterator(MBB);
}
+bool MachineBasicBlock::canFallThrough() {
+ MachineBasicBlock *TBB = 0, *FBB = 0;
+ SmallVector<MachineOperand, 4> Cond;
+ const TargetInstrInfo *TII = getParent()->getTarget().getInstrInfo();
+ bool BranchUnAnalyzable = TII->AnalyzeBranch(*this, TBB, FBB, Cond, true);
+
+ MachineFunction::iterator Fallthrough = this;
+ ++Fallthrough;
+ // If FallthroughBlock is off the end of the function, it can't fall through.
+ if (Fallthrough == getParent()->end())
+ return false;
+
+ // If FallthroughBlock isn't a successor, no fallthrough is possible.
+ if (!isSuccessor(Fallthrough))
+ return false;
+
+ // If we couldn't analyze the branch, examine the last instruction.
+ // If the block doesn't end in a known control barrier, assume fallthrough
+ // is possible. The isPredicable check is needed because this code can be
+ // called during IfConversion, where an instruction which is normally a
+ // Barrier is predicated and thus no longer an actual control barrier. This
+ // is over-conservative though, because if an instruction isn't actually
+ // predicated we could still treat it like a barrier.
+ if (BranchUnAnalyzable)
+ return empty() || !back().getDesc().isBarrier() ||
+ back().getDesc().isPredicable();
+
+ // If there is no branch, control always falls through.
+ if (TBB == 0) return true;
+
+ // If there is some explicit branch to the fallthrough block, it can obviously
+ // reach, even though the branch should get folded to fall through implicitly.
+ if (MachineFunction::iterator(TBB) == Fallthrough ||
+ MachineFunction::iterator(FBB) == Fallthrough)
+ return true;
+
+ // If it's an unconditional branch to some block not the fall through, it
+ // doesn't fall through.
+ if (Cond.empty()) return false;
+
+ // Otherwise, if it is conditional and has no explicit false block, it falls
+ // through.
+ return FBB == 0;
+}
+
/// removeFromParent - This method unlinks 'this' from the containing function,
/// and returns it, but does not delete it.
MachineBasicBlock *MachineBasicBlock::removeFromParent() {