#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;
addSuccessor(New);
}
-/// BranchesToLandingPad - The basic block is a landing pad or 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 (!CurMBB->isLandingPad()) {
- if (CurMBB->succ_size() != 1) break;
- if (!Visited.insert(CurMBB)) break;
- 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.
+/// 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).
bool MachineBasicBlock::CorrectExtraCFGEdges(MachineBasicBlock *DestA,
MachineBasicBlock *DestB,
bool isCond) {
+ // The values of DestA and DestB frequently come from a call to the
+ // 'TargetInstrInfo::AnalyzeBranch' method. We take our meaning of the initial
+ // values from there.
+ //
+ // 1. If both DestA and DestB are null, then the block ends with no branches
+ // (it falls through to its successor).
+ // 2. If DestA is set, DestB is null, and isCond is false, then the block ends
+ // with only an unconditional branch.
+ // 3. If DestA is set, DestB is null, and isCond is true, then the block ends
+ // with a conditional branch that falls through to a successor (DestB).
+ // 4. If DestA and DestB is set and isCond is true, then the block ends with a
+ // conditional branch followed by an unconditional branch. DestA is the
+ // 'true' destination and DestB is the 'false' destination.
+
bool MadeChange = false;
bool AddedFallThrough = false;
}
MachineBasicBlock::succ_iterator SI = succ_begin();
- const MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB;
+ MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB;
while (SI != succ_end()) {
const MachineBasicBlock *MBB = *SI;
if (MBB == DestA) {
} else if (MBB == DestB) {
DestB = 0;
++SI;
- } else if (MBB != OrigDestA && MBB != OrigDestB &&
- BranchesToLandingPad(MBB)) {
+ } else if (MBB->isLandingPad() &&
+ MBB != OrigDestA && MBB != OrigDestB) {
++SI;
} else {
// Otherwise, this is a superfluous edge, remove it.
}
}
- if (!AddedFallThrough) {
- assert(DestA == 0 && DestB == 0 &&
- "MachineCFG is missing edges!");
- } else if (isCond) {
+ if (!AddedFallThrough)
+ assert(DestA == 0 && DestB == 0 && "MachineCFG is missing edges!");
+ else if (isCond)
assert(DestA == 0 && "MachineCFG is missing edges!");
- }
return MadeChange;
}