#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/ilist"
-#include <iosfwd>
+#include "llvm/Support/Streams.h"
namespace llvm {
class MachineFunction;
class BasicBlock;
class MachineBasicBlock {
-public:
typedef ilist<MachineInstr> Instructions;
Instructions Insts;
MachineBasicBlock *Prev, *Next;
const BasicBlock *BB;
- std::vector<MachineBasicBlock *> Predecessors;
- std::vector<MachineBasicBlock *> Successors;
int Number;
MachineFunction *Parent;
+ /// Predecessors/Successors - Keep track of the predecessor / successor
+ /// basicblocks.
+ std::vector<MachineBasicBlock *> Predecessors;
+ std::vector<MachineBasicBlock *> Successors;
+
+ /// LiveIns - Keep track of the physical registers that are livein of
+ /// the basicblock.
+ std::vector<unsigned> LiveIns;
+
+ /// IsLandingPad - Indicate that this basic block is entered via an
+ /// exception handler.
+ bool IsLandingPad;
+
public:
- MachineBasicBlock(const BasicBlock *bb = 0) : Prev(0), Next(0), BB(bb),
- Number(-1), Parent(0) {
+ explicit MachineBasicBlock(const BasicBlock *bb = 0) : Prev(0), Next(0),
+ BB(bb), Number(-1),
+ Parent(0),
+ IsLandingPad(false) {
Insts.parent = this;
}
typedef std::vector<MachineBasicBlock *>::const_iterator const_pred_iterator;
typedef std::vector<MachineBasicBlock *>::iterator succ_iterator;
typedef std::vector<MachineBasicBlock *>::const_iterator const_succ_iterator;
-
- pred_iterator pred_begin() { return Predecessors.begin (); }
- const_pred_iterator pred_begin() const { return Predecessors.begin (); }
- pred_iterator pred_end() { return Predecessors.end (); }
- const_pred_iterator pred_end() const { return Predecessors.end (); }
- unsigned pred_size() const { return Predecessors.size (); }
- bool pred_empty() const { return Predecessors.empty(); }
- succ_iterator succ_begin() { return Successors.begin (); }
- const_succ_iterator succ_begin() const { return Successors.begin (); }
- succ_iterator succ_end() { return Successors.end (); }
- const_succ_iterator succ_end() const { return Successors.end (); }
- unsigned succ_size() const { return Successors.size (); }
- bool succ_empty() const { return Successors.empty(); }
-
+ typedef std::vector<MachineBasicBlock *>::reverse_iterator
+ pred_reverse_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_reverse_iterator
+ const_pred_reverse_iterator;
+ typedef std::vector<MachineBasicBlock *>::reverse_iterator
+ succ_reverse_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_reverse_iterator
+ const_succ_reverse_iterator;
+
+ pred_iterator pred_begin() { return Predecessors.begin(); }
+ const_pred_iterator pred_begin() const { return Predecessors.begin(); }
+ pred_iterator pred_end() { return Predecessors.end(); }
+ const_pred_iterator pred_end() const { return Predecessors.end(); }
+ pred_reverse_iterator pred_rbegin()
+ { return Predecessors.rbegin();}
+ const_pred_reverse_iterator pred_rbegin() const
+ { return Predecessors.rbegin();}
+ pred_reverse_iterator pred_rend()
+ { return Predecessors.rend(); }
+ const_pred_reverse_iterator pred_rend() const
+ { return Predecessors.rend(); }
+ unsigned pred_size() const { return Predecessors.size(); }
+ bool pred_empty() const { return Predecessors.empty(); }
+ succ_iterator succ_begin() { return Successors.begin(); }
+ const_succ_iterator succ_begin() const { return Successors.begin(); }
+ succ_iterator succ_end() { return Successors.end(); }
+ const_succ_iterator succ_end() const { return Successors.end(); }
+ succ_reverse_iterator succ_rbegin()
+ { return Successors.rbegin(); }
+ const_succ_reverse_iterator succ_rbegin() const
+ { return Successors.rbegin(); }
+ succ_reverse_iterator succ_rend()
+ { return Successors.rend(); }
+ const_succ_reverse_iterator succ_rend() const
+ { return Successors.rend(); }
+ unsigned succ_size() const { return Successors.size(); }
+ bool succ_empty() const { return Successors.empty(); }
+
+ // LiveIn management methods.
+
+ /// addLiveIn - Add the specified register as a live in. Note that it
+ /// is an error to add the same register to the same set more than once.
+ void addLiveIn(unsigned Reg) { LiveIns.push_back(Reg); }
+
+ /// removeLiveIn - Remove the specified register from the live in set.
+ ///
+ void removeLiveIn(unsigned Reg);
+
+ // Iteration support for live in sets. These sets are kept in sorted
+ // order by their register number.
+ typedef std::vector<unsigned>::iterator livein_iterator;
+ typedef std::vector<unsigned>::const_iterator const_livein_iterator;
+ livein_iterator livein_begin() { return LiveIns.begin(); }
+ const_livein_iterator livein_begin() const { return LiveIns.begin(); }
+ livein_iterator livein_end() { return LiveIns.end(); }
+ const_livein_iterator livein_end() const { return LiveIns.end(); }
+ bool livein_empty() const { return LiveIns.empty(); }
+
+ /// isLandingPad - Returns true if the block is a landing pad. That is
+ /// this basic block is entered via an exception handler.
+ bool isLandingPad() const { return IsLandingPad; }
+
+ /// setIsLandingPad - Indicates the block is a landing pad. That is
+ /// this basic block is entered via an exception handler.
+ void setIsLandingPad() { IsLandingPad = true; }
+
+ // Code Layout methods.
+
+ /// moveBefore/moveAfter - move 'this' block before or after the specified
+ /// block. This only moves the block, it does not modify the CFG or adjust
+ /// potential fall-throughs at the end of the block.
+ void moveBefore(MachineBasicBlock *NewAfter);
+ void moveAfter(MachineBasicBlock *NewBefore);
+
// Machine-CFG mutators
-
+
/// addSuccessor - Add succ as a successor of this MachineBasicBlock.
/// The Predecessors list of succ is automatically updated.
///
/// removeSuccessor - Remove specified successor from the successors list of
/// this MachineBasicBlock. The Predecessors list of succ is automatically
- /// updated.
+ /// updated. Return the iterator to the element after the one removed.
///
- void removeSuccessor(succ_iterator I);
+ succ_iterator removeSuccessor(succ_iterator I);
+
+ /// isSuccessor - Return true if the specified MBB is a successor of this
+ /// block.
+ bool isSuccessor(MachineBasicBlock *MBB) const;
/// getFirstTerminator - returns an iterator to the first terminator
/// instruction of this basic block. If a terminator does not exist,
Insts.splice(where, Other->Insts, From, To);
}
+ /// ReplaceUsesOfBlockWith - Given a machine basic block that branched to
+ /// 'Old', change the code and CFG so that it branches to 'New' instead.
+ void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New);
+
+ /// 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.
+ bool CorrectExtraCFGEdges(MachineBasicBlock *DestA,
+ MachineBasicBlock *DestB,
+ bool isCond);
+
// Debugging methods.
void dump() const;
void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
/// getNumber - MachineBasicBlocks are uniquely numbered at the function
/// level, unless they're not in a MachineFunction yet, in which case this
/// will return -1.
///
int getNumber() const { return Number; }
+ void setNumber(int N) { Number = N; }
private: // Methods used to maintain doubly linked list of blocks...
friend struct ilist_traits<MachineBasicBlock>;
void removePredecessor(MachineBasicBlock *pred);
};
-
+std::ostream& operator<<(std::ostream &OS, const MachineBasicBlock &MBB);
//===--------------------------------------------------------------------===//
// GraphTraits specializations for machine basic block graphs (machine-CFGs)