aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2011-12-06 22:12:01 +0000
committerEvan Cheng <evan.cheng@apple.com>2011-12-06 22:12:01 +0000
commit7c2a4a30e0e16762c75adacebd05ec9fcbccf16b (patch)
treeccd531b26932f56aae8b213493bc6fbbf365cd12
parent3d5d8f6b768619ed65f79606d5c981c1e056c7e8 (diff)
First chunk of MachineInstr bundle support.
1. Added opcode BUNDLE 2. Taught MachineInstr class to deal with bundled MIs 3. Changed MachineBasicBlock iterator to skip over bundled MIs; added an iterator to walk all the MIs 4. Taught MachineBasicBlock methods about bundled MIs git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145975 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h202
-rw-r--r--include/llvm/CodeGen/MachineInstr.h60
-rw-r--r--include/llvm/MC/MCInstrDesc.h4
-rw-r--r--include/llvm/Target/Target.td5
-rw-r--r--include/llvm/Target/TargetOpcodes.h7
-rw-r--r--lib/CodeGen/LiveVariables.cpp2
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp95
-rw-r--r--lib/CodeGen/MachineInstr.cpp35
-rw-r--r--lib/CodeGen/MachineLICM.cpp5
-rw-r--r--lib/CodeGen/PHIElimination.cpp2
-rw-r--r--lib/CodeGen/RegisterCoalescer.cpp3
-rw-r--r--lib/CodeGen/ScheduleDAGInstrs.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp3
-rw-r--r--lib/CodeGen/TailDuplication.cpp3
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp3
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp2
-rw-r--r--lib/Target/Mips/MipsCodeEmitter.cpp2
-rw-r--r--lib/Target/PTX/PTXInstrInfo.cpp2
-rw-r--r--utils/TableGen/CodeGenTarget.cpp1
19 files changed, 369 insertions, 69 deletions
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index 499f62d660..1ec89eefad 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -129,10 +129,89 @@ public:
const MachineFunction *getParent() const { return xParent; }
MachineFunction *getParent() { return xParent; }
- typedef Instructions::iterator iterator;
- typedef Instructions::const_iterator const_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ /// bundle_iterator - MachineBasicBlock iterator that automatically skips over
+ /// MIs that are inside bundles (i.e. walk top level MIs only).
+ template<typename Ty, typename IterTy>
+ class bundle_iterator
+ : public std::iterator<std::bidirectional_iterator_tag, Ty, ptrdiff_t> {
+ IterTy MII;
+
+ public:
+ bundle_iterator(IterTy mii) : MII(mii) {
+ assert(!MII->isInsideBundle() &&
+ "It's not legal to initialize bundle_iterator with a bundled MI");
+ }
+
+ bundle_iterator(Ty &mi) : MII(mi) {
+ assert(!mi.isInsideBundle() &&
+ "It's not legal to initialize bundle_iterator with a bundled MI");
+ }
+ bundle_iterator(Ty *mi) : MII(mi) {
+ assert((!mi || !mi->isInsideBundle()) &&
+ "It's not legal to initialize bundle_iterator with a bundled MI");
+ }
+ bundle_iterator(const bundle_iterator &I) : MII(I.MII) {}
+ bundle_iterator() : MII(0) {}
+
+ Ty &operator*() const { return *MII; }
+ Ty *operator->() const { return &operator*(); }
+
+ operator Ty*() const { return MII; }
+
+ bool operator==(const bundle_iterator &x) const {
+ return MII == x.MII;
+ }
+ bool operator!=(const bundle_iterator &x) const {
+ return !operator==(x);
+ }
+
+ // Increment and decrement operators...
+ bundle_iterator &operator--() { // predecrement - Back up
+ do {
+ --MII;
+ } while (MII->isInsideBundle());
+ return *this;
+ }
+ bundle_iterator &operator++() { // preincrement - Advance
+ do {
+ ++MII;
+ } while (MII->isInsideBundle());
+ return *this;
+ }
+ bundle_iterator operator--(int) { // postdecrement operators...
+ bundle_iterator tmp = *this;
+ do {
+ --MII;
+ } while (MII->isInsideBundle());
+ return tmp;
+ }
+ bundle_iterator operator++(int) { // postincrement operators...
+ bundle_iterator tmp = *this;
+ do {
+ ++MII;
+ } while (MII->isInsideBundle());
+ return tmp;
+ }
+
+ IterTy getInsnIterator() const {
+ return MII;
+ }
+ };
+
+ typedef Instructions::iterator insn_iterator;
+ typedef Instructions::const_iterator const_insn_iterator;
+ typedef std::reverse_iterator<insn_iterator> reverse_insn_iterator;
+ typedef
+ std::reverse_iterator<const_insn_iterator> const_reverse_insn_iterator;
+
+ typedef
+ bundle_iterator<MachineInstr,insn_iterator> iterator;
+ typedef
+ bundle_iterator<const MachineInstr,const_insn_iterator> const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
unsigned size() const { return (unsigned)Insts.size(); }
bool empty() const { return Insts.empty(); }
@@ -142,15 +221,53 @@ public:
const MachineInstr& front() const { return Insts.front(); }
const MachineInstr& back() const { return Insts.back(); }
+ insn_iterator insn_begin() { return Insts.begin(); }
+ const_insn_iterator insn_begin() const { return Insts.begin(); }
+ insn_iterator insn_end() { return Insts.end(); }
+ const_insn_iterator insn_end() const { return Insts.end(); }
+ reverse_insn_iterator insn_rbegin() { return Insts.rbegin(); }
+ const_reverse_insn_iterator insn_rbegin() const { return Insts.rbegin(); }
+ reverse_insn_iterator insn_rend () { return Insts.rend(); }
+ const_reverse_insn_iterator insn_rend () const { return Insts.rend(); }
+
iterator begin() { return Insts.begin(); }
const_iterator begin() const { return Insts.begin(); }
- iterator end() { return Insts.end(); }
- const_iterator end() const { return Insts.end(); }
- reverse_iterator rbegin() { return Insts.rbegin(); }
- const_reverse_iterator rbegin() const { return Insts.rbegin(); }
+ iterator end() {
+ insn_iterator II = insn_end();
+ if (II != insn_begin()) {
+ while (II->isInsideBundle())
+ --II;
+ }
+ return II;
+ }
+ const_iterator end() const {
+ const_insn_iterator II = insn_end();
+ if (II != insn_begin()) {
+ while (II->isInsideBundle())
+ --II;
+ }
+ return II;
+ }
+ reverse_iterator rbegin() {
+ reverse_insn_iterator II = insn_rbegin();
+ if (II != insn_rend()) {
+ while (II->isInsideBundle())
+ ++II;
+ }
+ return II;
+ }
+ const_reverse_iterator rbegin() const {
+ const_reverse_insn_iterator II = insn_rbegin();
+ if (II != insn_rend()) {
+ while (II->isInsideBundle())
+ ++II;
+ }
+ return II;
+ }
reverse_iterator rend () { return Insts.rend(); }
const_reverse_iterator rend () const { return Insts.rend(); }
+
// Machine-CFG iterators
typedef std::vector<MachineBasicBlock *>::iterator pred_iterator;
typedef std::vector<MachineBasicBlock *>::const_iterator const_pred_iterator;
@@ -323,18 +440,16 @@ public:
/// instruction of this basic block. If a terminator does not exist,
/// it returns end()
iterator getFirstTerminator();
+ const_iterator getFirstTerminator() const;
- const_iterator getFirstTerminator() const {
- return const_cast<MachineBasicBlock*>(this)->getFirstTerminator();
- }
+ /// getFirstInsnTerminator - Same getFirstTerminator but it ignores bundles
+ /// and return an insn_iterator instead.
+ insn_iterator getFirstInsnTerminator();
/// getLastNonDebugInstr - returns an iterator to the last non-debug
/// instruction in the basic block, or end()
iterator getLastNonDebugInstr();
-
- const_iterator getLastNonDebugInstr() const {
- return const_cast<MachineBasicBlock*>(this)->getLastNonDebugInstr();
- }
+ const_iterator getLastNonDebugInstr() const;
/// SplitCriticalEdge - Split the critical edge from this block to the
/// given successor block, and return the newly created block, or null
@@ -347,32 +462,70 @@ public:
void pop_front() { Insts.pop_front(); }
void pop_back() { Insts.pop_back(); }
void push_back(MachineInstr *MI) { Insts.push_back(MI); }
+
template<typename IT>
- void insert(iterator I, IT S, IT E) { Insts.insert(I, S, E); }
- iterator insert(iterator I, MachineInstr *M) { return Insts.insert(I, M); }
- iterator insertAfter(iterator I, MachineInstr *M) {
+ void insert(insn_iterator I, IT S, IT E) {
+ Insts.insert(I, S, E);
+ }
+ insn_iterator insert(insn_iterator I, MachineInstr *M) {
+ return Insts.insert(I, M);
+ }
+ insn_iterator insertAfter(insn_iterator I, MachineInstr *M) {
return Insts.insertAfter(I, M);
}
+ template<typename IT>
+ void insert(iterator I, IT S, IT E) {
+ Insts.insert(I.getInsnIterator(), S, E);
+ }
+ iterator insert(iterator I, MachineInstr *M) {
+ return Insts.insert(I.getInsnIterator(), M);
+ }
+ iterator insertAfter(iterator I, MachineInstr *M) {
+ return Insts.insertAfter(I.getInsnIterator(), M);
+ }
+
// erase - Remove the specified element or range from the instruction list.
// These functions delete any instructions removed.
//
- iterator erase(iterator I) { return Insts.erase(I); }
- iterator erase(iterator I, iterator E) { return Insts.erase(I, E); }
+ insn_iterator erase(insn_iterator I) {
+ return Insts.erase(I);
+ }
+ insn_iterator erase(insn_iterator I, insn_iterator E) {
+ return Insts.erase(I, E);
+ }
+
+ iterator erase(iterator I) {
+ return Insts.erase(I.getInsnIterator());
+ }
+ iterator erase(iterator I, iterator E) {
+ return Insts.erase(I.getInsnIterator(), E.getInsnIterator());
+ }
+
+ iterator erase(MachineInstr *I) { iterator MII(I); return erase(MII); }
MachineInstr *remove(MachineInstr *I) { return Insts.remove(I); }
void clear() { Insts.clear(); }
/// splice - Take an instruction from MBB 'Other' at the position From,
/// and insert it into this MBB right before 'where'.
- void splice(iterator where, MachineBasicBlock *Other, iterator From) {
+ void splice(insn_iterator where, MachineBasicBlock *Other,
+ insn_iterator From) {
Insts.splice(where, Other->Insts, From);
}
+ void splice(iterator where, MachineBasicBlock *Other, iterator From) {
+ Insts.splice(where.getInsnIterator(), Other->Insts, From.getInsnIterator());
+ }
/// splice - Take a block of instructions from MBB 'Other' in the range [From,
/// To), and insert them into this MBB right before 'where'.
+ void splice(insn_iterator where, MachineBasicBlock *Other, insn_iterator From,
+ insn_iterator To) {
+ Insts.splice(where, Other->Insts, From, To);
+ }
void splice(iterator where, MachineBasicBlock *Other, iterator From,
iterator To) {
- Insts.splice(where, Other->Insts, From, To);
+ Insts.splice(where.getInsnIterator(), Other->Insts,
+ From.getInsnIterator(), To.getInsnIterator());
}
/// removeFromParent - This method unlinks 'this' from the containing
@@ -399,7 +552,10 @@ public:
/// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping
/// any DBG_VALUE instructions. Return UnknownLoc if there is none.
- DebugLoc findDebugLoc(MachineBasicBlock::iterator &MBBI);
+ DebugLoc findDebugLoc(insn_iterator MBBI);
+ DebugLoc findDebugLoc(iterator MBBI) {
+ return findDebugLoc(MBBI.getInsnIterator());
+ }
// Debugging methods.
void dump() const;
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index cae38f3470..1558c4f957 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -53,9 +53,11 @@ public:
};
enum MIFlag {
- NoFlags = 0,
- FrameSetup = 1 << 0 // Instruction is used as a part of
+ NoFlags = 0,
+ FrameSetup = 1 << 0, // Instruction is used as a part of
// function frame setup code.
+ InsideBundle = 1 << 1 // Instruction is inside a bundle (not
+ // the first MI in a bundle)
};
private:
const MCInstrDesc *MCID; // Instruction descriptor.
@@ -148,6 +150,12 @@ public:
AsmPrinterFlags |= (uint8_t)Flag;
}
+ /// clearAsmPrinterFlag - clear specific AsmPrinter flags
+ ///
+ void clearAsmPrinterFlag(CommentFlag Flag) {
+ AsmPrinterFlags &= ~Flag;
+ }
+
/// getFlags - Return the MI flags bitvector.
uint8_t getFlags() const {
return Flags;
@@ -167,10 +175,44 @@ public:
Flags = flags;
}
- /// clearAsmPrinterFlag - clear specific AsmPrinter flags
+ /// isInsideBundle - Return true if MI is in a bundle (but not the first MI
+ /// in a bundle).
///
- void clearAsmPrinterFlag(CommentFlag Flag) {
- AsmPrinterFlags &= ~Flag;
+ /// A bundle looks like this before it's finalized:
+ /// ----------------
+ /// | MI |
+ /// ----------------
+ /// |
+ /// ----------------
+ /// | MI * |
+ /// ----------------
+ /// |
+ /// ----------------
+ /// | MI * |
+ /// ----------------
+ /// In this case, the first MI starts a bundle but is not inside a bundle, the
+ /// next 2 MIs are considered "inside" the bundle.
+ ///
+ /// After a bundle is finalized, it looks like this:
+ /// ----------------
+ /// | Bundle |
+ /// ----------------
+ /// |
+ /// ----------------
+ /// | MI * |
+ /// ----------------
+ /// |
+ /// ----------------
+ /// | MI * |
+ /// ----------------
+ /// |
+ /// ----------------
+ /// | MI * |
+ /// ----------------
+ /// The first instruction has the special opcode "BUNDLE". It's not "inside"
+ /// a bundle, but the next three MIs are.
+ bool isInsideBundle() const {
+ return getFlag(InsideBundle);
}
/// getDebugLoc - Returns the debug location id of this MachineInstr.
@@ -232,6 +274,14 @@ public:
return MemRefsEnd - MemRefs == 1;
}
+ /// API for querying MachineInstr properties. These are bundle aware.
+ ///
+ bool hasProperty(unsigned short Flag) const;
+
+ bool isTerminator() const {
+ return hasProperty(MCID::Terminator);
+ }
+
enum MICheckType {
CheckDefs, // Check all operands for equality
CheckKillDead, // Check all operands including kill / dead markers
diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h
index aafa800c1a..6c33bfa2ec 100644
--- a/include/llvm/MC/MCInstrDesc.h
+++ b/include/llvm/MC/MCInstrDesc.h
@@ -184,6 +184,10 @@ public:
return NumDefs;
}
+ /// getFlags - Return flags of this instruction.
+ ///
+ unsigned short getFlags() const { return Flags; }
+
/// isVariadic - Return true if this instruction can have a variable number of
/// operands. In this case, the variable operands will be after the normal
/// operands but before the implicit definitions and uses (if any are
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 8582015e77..26e59e452f 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -688,6 +688,11 @@ def COPY : Instruction {
let neverHasSideEffects = 1;
let isAsCheapAsAMove = 1;
}
+def BUNDLE : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins variable_ops);
+ let AsmString = "BUNDLE";
+}
}
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h
index 37f7b2fb8d..f0b181e345 100644
--- a/include/llvm/Target/TargetOpcodes.h
+++ b/include/llvm/Target/TargetOpcodes.h
@@ -82,7 +82,12 @@ namespace TargetOpcode {
/// COPY - Target-independent register copy. This instruction can also be
/// used to copy between subregisters of virtual registers.
- COPY = 13
+ COPY = 13,
+
+ /// BUNDLE - This instruction represents an instruction bundle. Instructions
+ /// which immediately follow a BUNDLE instruction which are marked with
+ /// 'InsideBundle' flag are inside the bundle.
+ BUNDLE
};
} // end namespace TargetOpcode
} // end namespace llvm
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp
index 2ca90f9f05..03f8221e1f 100644
--- a/lib/CodeGen/LiveVariables.cpp
+++ b/lib/CodeGen/LiveVariables.cpp
@@ -754,7 +754,7 @@ void LiveVariables::addNewBlock(MachineBasicBlock *BB,
const unsigned NumNew = BB->getNumber();
// All registers used by PHI nodes in SuccBB must be live through BB.
- for (MachineBasicBlock::const_iterator BBI = SuccBB->begin(),
+ for (MachineBasicBlock::iterator BBI = SuccBB->begin(),
BBE = SuccBB->end(); BBI != BBE && BBI->isPHI(); ++BBI)
for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2)
if (BBI->getOperand(i+1).getMBB() == BB)
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index 75fdb7e212..46ed082ad2 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -73,7 +73,8 @@ void ilist_traits<MachineBasicBlock>::addNodeToList(MachineBasicBlock *N) {
// Make sure the instructions have their operands in the reginfo lists.
MachineRegisterInfo &RegInfo = MF.getRegInfo();
- for (MachineBasicBlock::iterator I = N->begin(), E = N->end(); I != E; ++I)
+ for (MachineBasicBlock::insn_iterator I = N->insn_begin(), E = N->insn_end();
+ I != E; ++I)
I->AddRegOperandsToUseLists(RegInfo);
LeakDetector::removeGarbageObject(N);
@@ -120,8 +121,8 @@ void ilist_traits<MachineInstr>::removeNodeFromList(MachineInstr *N) {
/// lists.
void ilist_traits<MachineInstr>::
transferNodesFromList(ilist_traits<MachineInstr> &fromList,
- MachineBasicBlock::iterator first,
- MachineBasicBlock::iterator last) {
+ ilist_iterator<MachineInstr> first,
+ ilist_iterator<MachineInstr> last) {
assert(Parent->getParent() == fromList.Parent->getParent() &&
"MachineInstr parent mismatch!");
@@ -140,9 +141,10 @@ void ilist_traits<MachineInstr>::deleteNode(MachineInstr* MI) {
}
MachineBasicBlock::iterator MachineBasicBlock::getFirstNonPHI() {
- iterator I = begin();
+ insn_iterator I = insn_begin();
while (I != end() && I->isPHI())
++I;
+ assert(!I->isInsideBundle() && "First non-phi MI cannot be inside a bundle!");
return I;
}
@@ -150,23 +152,63 @@ MachineBasicBlock::iterator
MachineBasicBlock::SkipPHIsAndLabels(MachineBasicBlock::iterator I) {
while (I != end() && (I->isPHI() || I->isLabel() || I->isDebugValue()))
++I;
+ // FIXME: This needs to change if we wish to bundle labels / dbg_values
+ // inside the bundle.
+ assert(!I->isInsideBundle() &&
+ "First non-phi / non-label instruction is inside a bundle!");
return I;
}
MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() {
iterator I = end();
- while (I != begin() && ((--I)->getDesc().isTerminator() || I->isDebugValue()))
+ while (I != begin() && ((--I)->isTerminator() || I->isDebugValue()))
; /*noop */
- while (I != end() && !I->getDesc().isTerminator())
+ while (I != end() && !I->isTerminator())
+ ++I;
+ return I;
+}
+
+MachineBasicBlock::const_iterator
+MachineBasicBlock::getFirstTerminator() const {
+ const_iterator I = end();
+ while (I != begin() && ((--I)->isTerminator() || I->isDebugValue()))
+ ; /*noop */
+ while (I != end() && !I->isTerminator())
+ ++I;
+ return I;
+}
+
+MachineBasicBlock::insn_iterator MachineBasicBlock::getFirstInsnTerminator() {
+ insn_iterator I = insn_end();
+ while (I != insn_begin() && ((--I)->isTerminator() || I->isDebugValue()))
+ ; /*noop */
+ while (I != insn_end() && !I->isTerminator())
++I;
return I;
}
MachineBasicBlock::iterator MachineBasicBlock::getLastNonDebugInstr() {
- iterator B = begin(), I = end();
+ // Skip over end-of-block dbg_value instructions.
+ insn_iterator B = insn_begin(), I = insn_end();
while (I != B) {
--I;
- if (I->isDebugValue())
+ // Return instruction that starts a bundle.
+ if (I->isDebugValue() || I->isInsideBundle())
+ continue;
+ return I;
+ }
+ // The block is all debug values.
+ return end();
+}
+
+MachineBasicBlock::const_iterator
+MachineBasicBlock::getLastNonDebugInstr() const {
+ // Skip over end-of-block dbg_value instructions.
+ const_insn_iterator B = insn_begin(), I = insn_end();
+ while (I != B) {
+ --I;
+ // Return instruction that starts a bundle.
+ if (I->isDebugValue() || I->isInsideBundle())
continue;
return I;
}
@@ -453,8 +495,8 @@ MachineBasicBlock::transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB) {
fromMBB->removeSuccessor(Succ);
// Fix up any PHI nodes in the successor.
- for (MachineBasicBlock::iterator MI = Succ->begin(), ME = Succ->end();
- MI != ME && MI->isPHI(); ++MI)
+ for (MachineBasicBlock::insn_iterator MI = Succ->insn_begin(),
+ ME = Succ->insn_end(); MI != ME && MI->isPHI(); ++MI)
for (unsigned i = 2, e = MI->getNumOperands()+1; i != e; i += 2) {
MachineOperand &MO = MI->getOperand(i);
if (MO.getMBB() == fromMBB)
@@ -556,7 +598,8 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
// Collect a list of virtual registers killed by the terminators.
SmallVector<unsigned, 4> KilledRegs;
if (LV)
- for (iterator I = getFirstTerminator(), E = end(); I != E; ++I) {
+ for (insn_iterator I = getFirstInsnTerminator(), E = insn_end();
+ I != E; ++I) {
MachineInstr *MI = I;
for (MachineInstr::mop_iterator OI = MI->operands_begin(),
OE = MI->operands_end(); OI != OE; ++OI) {
@@ -583,8 +626,8 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
}
// Fix PHI nodes in Succ so they refer to NMBB instead of this
- for (MachineBasicBlock::iterator i = Succ->begin(), e = Succ->end();
- i != e && i->isPHI(); ++i)
+ for (MachineBasicBlock::insn_iterator
+ i = Succ->insn_begin(),e = Succ->insn_end(); i != e && i->isPHI(); ++i)
for (unsigned ni = 1, ne = i->getNumOperands(); ni != ne; ni += 2)
if (i->getOperand(ni+1).getMBB() == this)
i->getOperand(ni+1).setMBB(NMBB);
@@ -599,7 +642,7 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
// Restore kills of virtual registers that were killed by the terminators.
while (!KilledRegs.empty()) {
unsigned Reg = KilledRegs.pop_back_val();
- for (iterator I = end(), E = begin(); I != E;) {
+ for (insn_iterator I = insn_end(), E = insn_begin(); I != E;) {
if (!(--I)->addRegisterKilled(Reg, NULL, /* addIfNotFound= */ false))
continue;
LV->getVarInfo(Reg).Kills.push_back(I);
@@ -691,8 +734,8 @@ void MachineBasicBlock::ReplaceUsesOfBlockWith(MachineBasicBlock *Old,
MachineBasicBlock *New) {
assert(Old != New && "Cannot replace self with self!");
- MachineBasicBlock::iterator I = end();
- while (I != begin()) {
+ MachineBasicBlock::insn_iterator I = insn_end();
+ while (I != insn_begin()) {
--I;
if (!I->getDesc().isTerminator()) break;
@@ -773,17 +816,17 @@ bool MachineBasicBlock::CorrectExtraCFGEdges(MachineBasicBlock *DestA,
/// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping
/// any DBG_VALUE instructions. Return UnknownLoc if there is none.
DebugLoc
-MachineBasicBlock::findDebugLoc(MachineBasicBlock::iterator &MBBI) {
+MachineBasicBlock::findDebugLoc(insn_iterator MBBI) {
DebugLoc DL;
- MachineBasicBlock::iterator E = end();
- if (MBBI != E) {
- // Skip debug declarations, we don't want a DebugLoc from them.
- MachineBasicBlock::iterator MBBI2 = MBBI;
- while (MBBI2 != E && MBBI2->isDebugValue())
- MBBI2++;
- if (MBBI2 != E)
- DL = MBBI2->getDebugLoc();
- }
+ insn_iterator E = insn_end();
+ if (MBBI == E)
+ return DL;
+
+ // Skip debug declarations, we don't want a DebugLoc from them.
+ while (MBBI != E && MBBI->isDebugValue())
+ MBBI++;
+ if (MBBI != E)
+ DL = MBBI->getDebugLoc();
return DL;
}
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index b0ef9d401a..abe6645909 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -735,6 +735,20 @@ void MachineInstr::addMemOperand(MachineFunction &MF,
MemRefsEnd = NewMemRefsEnd;
}
+bool MachineInstr::hasProperty(unsigned short MCFlag) const {
+ if (getOpcode() != TargetOpcode::BUNDLE)
+ return getDesc().getFlags() & (1 << MCFlag);
+
+ const MachineBasicBlock *MBB = getParent();
+ MachineBasicBlock::const_insn_iterator MII = *this; ++MII;
+ while (MII != MBB->end() && MII->isInsideBundle()) {
+ if (MII->getDesc().getFlags() & (1 << MCFlag))
+ return true;
+ ++MII;
+ }
+ return false;
+}
+
bool MachineInstr::isIdenticalTo(const MachineInstr *Other,
MICheckType Check) const {
// If opcodes or number of operands are not the same then the two
@@ -789,6 +803,17 @@ bool MachineInstr::isIdenticalTo(const MachineInstr *Other,
/// block, and returns it, but does not delete it.
MachineInstr *MachineInstr::removeFromParent() {
assert(getParent() && "Not embedded in a basic block!");
+
+ // If it's a bundle then remove the MIs inside the bundle as well.
+ if (getOpcode() == TargetOpcode::BUNDLE) {
+ MachineBasicBlock *MBB = getParent();
+ MachineBasicBlock::insn_iterator MII = *this; ++MII;
+ while (MII != MBB->end() && MII->isInsideBundle()) {
+ MachineInstr *MI = &*MII;
+ ++MII;
+ MBB->remove(MI);
+ }
+ }
getParent()->remove(this);
return this;
}
@@ -798,6 +823,16 @@ MachineInstr *MachineInstr::removeFromParent() {
/// block, and deletes it.
void MachineInstr::eraseFromParent() {
assert(getParent() && "Not embedded in a basic block!");
+ // If it's a bundle then remove the MIs inside the bundle as well.
+ if (getOpcode() == TargetOpcode::BUNDLE) {
+ MachineBasicBlock *MBB = getParent();
+ MachineBasicBlock::insn_iterator MII = *this; ++MII;
+ while (MII != MBB->end() && MII->isInsideBundle()) {
+ MachineInstr *MI = &*MII;
+ ++MII;
+ MBB->erase(MI);
+ }
+ }
getParent()->erase(this);
}
diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp
index e5e8c5117b..f88b730c6d 100644
--- a/lib/CodeGen/MachineLICM.cpp
+++ b/lib/CodeGen/MachineLICM.cpp
@@ -1141,8 +1141,9 @@ MachineInstr *MachineLICM::ExtractHoistableLoad(MachineInstr *MI) {
assert(NewMIs.size() == 2 &&
"Unfolded a load into multiple instructions!");
MachineBasicBlock *MBB = MI->getParent();
- MBB->insert(MI, NewMIs[0]);
- MBB->insert(MI, NewMIs[1]);
+ MachineBasicBlock::iterator Pos = MI;
+ MBB->insert(Pos, NewMIs[0]);
+ MBB->insert(Pos, NewMIs[1]);
// If unfolding produced a load that wasn't loop-invariant or profitable to
// hoist, discard the new instructions and bail.
if (!IsLoopInvariantInst(*NewMIs[0]) || !IsProfitableToHoist(*NewMIs[0])) {
diff --git a/lib/CodeGen/PHIElimination.cpp b/lib/CodeGen/PHIElimination.cpp
index 6994aa58fb..0e52496f00 100644
--- a/lib/CodeGen/PHIElimination.cpp
+++ b/lib/CodeGen/PHIElimination.cpp
@@ -410,7 +410,7 @@ bool PHIElimination::SplitPHIEdges(MachineFunction &MF,
return false; // Quick exit for basic blocks without PHIs.
bool Changed = false;
- for (MachineBasicBlock::const_iterator BBI = MBB.begin(), BBE = MBB.end();
+ for (MachineBasicBlock::iterator BBI = MBB.begin(), BBE = MBB.end();
BBI != BBE && BBI->isPHI(); ++BBI) {
for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) {
unsigned Reg = BBI->getOperand(i).getReg();
diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp
index 8ba93a429c..3866fc0869 100644
--- a/lib/CodeGen/RegisterCoalescer.cpp
+++ b/lib/CodeGen/RegisterCoalescer.cpp
@@ -710,7 +710,8 @@ bool RegisterCoalescer::RemoveCopyByCommutingDef(const CoalescerPair &CP,
return false;
if (NewMI != DefMI) {
LIS->ReplaceMachineInstrInMaps(DefMI, NewMI);
- MBB->insert(DefMI, NewMI);
+ MachineBasicBlock::iterator Pos = DefMI;
+ MBB->insert(Pos, NewMI);
MBB->erase(DefMI);
}
unsigned OpIdx = NewMI->findRegisterUseOperandIdx(IntA.reg, false);
diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp
index 5408cdf1ad..b382169a36 100644
--- a/lib/CodeGen/ScheduleDAGInstrs.cpp
+++ b/lib/CodeGen/ScheduleDAGInstrs.cpp
@@ -689,7 +689,7 @@ MachineBasicBlock *ScheduleDAGInstrs::EmitSchedule() {
DI = DbgValues.end(), DE = DbgValues.begin(); DI != DE; --DI) {
std::pair<MachineInstr *, MachineInstr *> P = *prior(DI);
MachineInstr *DbgValue = P.first;
- MachineInstr *OrigPrivMI = P.second;
+ MachineBasicBlock::iterator OrigPrivMI = P.second;
BB->insertAfter(OrigPrivMI, DbgValue);
}
DbgValues.clear();
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index b74142dc80..ddbeaeb7cb 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -346,7 +346,8 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
TII.get(TargetOpcode::DBG_VALUE))
.addReg(CopyUseMI->getOperand(0).getReg(), RegState::Debug)
.addImm(Offset).addMetadata(Variable);
- EntryMBB->insertAfter(CopyUseMI, NewMI);
+ MachineBasicBlock::iterator Pos = CopyUseMI;
+ EntryMBB->insertAfter(Pos, NewMI);
}
}
}
diff --git a/lib/CodeGen/TailDuplication.cpp b/lib/CodeGen/TailDuplication.cpp
index 3a6211a0f3..adfce863d0 100644
--- a/lib/CodeGen/TailDuplication.cpp
+++ b/lib/CodeGen/TailDuplication.cpp
@@ -561,8 +561,7 @@ TailDuplicatePass::shouldTailDuplicate(const MachineFunction &MF,
// Check the instructions in the block to determine whether tail-duplication
// is invalid or unlikely to be profitable.
unsigned InstrCount = 0;
- for (MachineBasicBlock::const_iterator I = TailBB.begin(); I != TailBB.end();
- ++I) {
+ for (MachineBasicBlock::iterator I = TailBB.begin(); I != TailBB.end(); ++I) {
// Non-duplicable things shouldn't be tail-duplicated.
if (I->getDesc().isNotDuplicable())
return false;
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 413c0a5197..e3785f5634 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/