summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2009-12-11 01:49:14 +0000
committerBill Wendling <isanbard@gmail.com>2009-12-11 01:49:14 +0000
commit4bde1ab82d4a520dca59db1fd212d77ac667b3a8 (patch)
tree8a324c08758ee0b1ef5b55a3aa75e02b30c27e11 /lib
parent5278eb802fae2ee1a7b2a428596bc364d8bcd9db (diff)
downloadexternal_llvm-4bde1ab82d4a520dca59db1fd212d77ac667b3a8.zip
external_llvm-4bde1ab82d4a520dca59db1fd212d77ac667b3a8.tar.gz
external_llvm-4bde1ab82d4a520dca59db1fd212d77ac667b3a8.tar.bz2
A machine basic block may end in an unconditional branch, however it may have
more than one successor. Normally, these extra successors are dead. However, some of them may branch to exception handling landing pads. If we remove those successors, then the landing pads could go away if all predecessors to it are removed. Before, it was checking if the direct successor was the landing pad. But it could be the result of jumping through multiple basic blocks to get to it. If we were to only check for the existence of an EH_LABEL in the basic block and not remove successors if it's in there, then it could stop actually dead basic blocks from being removed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91092 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp43
1 files changed, 36 insertions, 7 deletions
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index de358fa..684af34 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -13,15 +13,16 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/BasicBlock.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetInstrDesc.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/LeakDetector.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Assembly/Writer.h"
#include <algorithm>
using namespace llvm;
@@ -448,10 +449,35 @@ void MachineBasicBlock::ReplaceUsesOfBlockWith(MachineBasicBlock *Old,
addSuccessor(New);
}
+/// BranchesToLandingPad - The basic block branches only to a landing pad or to
+/// another basic block which branches only to a landing pad. No other
+/// instructions are present other than the unconditional branch.
+bool
+MachineBasicBlock::BranchesToLandingPad(const MachineBasicBlock *MBB) const {
+ SmallSet<const MachineBasicBlock*, 32> Visited;
+ const MachineBasicBlock *CurMBB = MBB;
+
+ while (!Visited.count(CurMBB) && !CurMBB->isLandingPad()) {
+ if (CurMBB->size() != 1 || CurMBB->succ_empty() || CurMBB->succ_size() != 1)
+ break;
+
+ const TargetInstrInfo *TII =
+ CurMBB->getParent()->getTarget().getInstrInfo();
+ if (!TII->isUnpredicatedTerminator(CurMBB->begin()))
+ break;
+
+ Visited.insert(CurMBB);
+ CurMBB = *CurMBB->succ_begin();
+ }
+
+ return CurMBB->isLandingPad();
+}
+
/// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in the
/// CFG to be inserted. If we have proven that MBB can only branch to DestA and
/// DestB, remove any other MBB successors from the CFG. DestA and DestB can
/// be null.
+///
/// Besides DestA and DestB, retain other edges leading to LandingPads
/// (currently there can be only one; we don't check or require that here).
/// Note it is possible that DestA and/or DestB are LandingPads.
@@ -481,16 +507,17 @@ bool MachineBasicBlock::CorrectExtraCFGEdges(MachineBasicBlock *DestA,
}
MachineBasicBlock::succ_iterator SI = succ_begin();
- MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB;
+ const MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB;
while (SI != succ_end()) {
- if (*SI == DestA) {
+ const MachineBasicBlock *MBB = *SI;
+ if (MBB == DestA) {
DestA = 0;
++SI;
- } else if (*SI == DestB) {
+ } else if (MBB == DestB) {
DestB = 0;
++SI;
- } else if ((*SI)->isLandingPad() &&
- *SI!=OrigDestA && *SI!=OrigDestB) {
+ } else if (BranchesToLandingPad(MBB) &&
+ MBB != OrigDestA && MBB != OrigDestB) {
++SI;
} else {
// Otherwise, this is a superfluous edge, remove it.
@@ -498,12 +525,14 @@ bool MachineBasicBlock::CorrectExtraCFGEdges(MachineBasicBlock *DestA,
MadeChange = true;
}
}
+
if (!AddedFallThrough) {
assert(DestA == 0 && DestB == 0 &&
"MachineCFG is missing edges!");
} else if (isCond) {
assert(DestA == 0 && "MachineCFG is missing edges!");
}
+
return MadeChange;
}