aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h122
-rw-r--r--include/llvm/CodeGen/MachineInstr.h20
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h46
-rw-r--r--include/llvm/CodeGen/MachineInstrBundle.h34
-rw-r--r--include/llvm/CodeGen/Passes.h4
-rw-r--r--include/llvm/InitializePasses.h1
-rw-r--r--lib/CodeGen/BranchFolding.cpp5
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp78
-rw-r--r--lib/CodeGen/MachineInstr.cpp51
-rw-r--r--lib/CodeGen/MachineInstrBundle.cpp180
-rw-r--r--lib/CodeGen/MachineVerifier.cpp8
-rw-r--r--lib/CodeGen/PostRASchedulerList.cpp5
-rw-r--r--lib/CodeGen/ScheduleDAGInstrs.cpp17
-rw-r--r--lib/CodeGen/TargetInstrInfoImpl.cpp4
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp137
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.h7
-rw-r--r--lib/Target/ARM/ARMFastISel.cpp4
-rw-r--r--lib/Target/ARM/ARMHazardRecognizer.cpp22
-rw-r--r--lib/Target/ARM/ARMHazardRecognizer.h4
-rw-r--r--lib/Target/ARM/ARMTargetMachine.cpp10
-rw-r--r--lib/Target/ARM/MLxExpansionPass.cpp4
-rw-r--r--lib/Target/ARM/Thumb2ITBlockPass.cpp4
-rw-r--r--lib/Target/ARM/Thumb2SizeReduction.cpp41
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp4
-rw-r--r--test/CodeGen/ARM/debug-info-d16-reg.ll2
-rw-r--r--test/CodeGen/ARM/long_shift.ll4
-rw-r--r--test/CodeGen/Thumb2/machine-licm.ll2
-rw-r--r--test/CodeGen/Thumb2/thumb2-select_xform.ll2
28 files changed, 653 insertions, 169 deletions
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index 1ec89eefad..10a32d31c1 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -194,21 +194,21 @@ public:
return tmp;
}
- IterTy getInsnIterator() const {
+ IterTy getInstrIterator() 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 Instructions::iterator instr_iterator;
+ typedef Instructions::const_iterator const_instr_iterator;
+ typedef std::reverse_iterator<instr_iterator> reverse_instr_iterator;
typedef
- std::reverse_iterator<const_insn_iterator> const_reverse_insn_iterator;
+ std::reverse_iterator<const_instr_iterator> const_reverse_instr_iterator;
typedef
- bundle_iterator<MachineInstr,insn_iterator> iterator;
+ bundle_iterator<MachineInstr,instr_iterator> iterator;
typedef
- bundle_iterator<const MachineInstr,const_insn_iterator> const_iterator;
+ bundle_iterator<const MachineInstr,const_instr_iterator> const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
@@ -221,44 +221,44 @@ 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(); }
+ instr_iterator instr_begin() { return Insts.begin(); }
+ const_instr_iterator instr_begin() const { return Insts.begin(); }
+ instr_iterator instr_end() { return Insts.end(); }
+ const_instr_iterator instr_end() const { return Insts.end(); }
+ reverse_instr_iterator instr_rbegin() { return Insts.rbegin(); }
+ const_reverse_instr_iterator instr_rbegin() const { return Insts.rbegin(); }
+ reverse_instr_iterator instr_rend () { return Insts.rend(); }
+ const_reverse_instr_iterator instr_rend () const { return Insts.rend(); }
iterator begin() { return Insts.begin(); }
const_iterator begin() const { return Insts.begin(); }
iterator end() {
- insn_iterator II = insn_end();
- if (II != insn_begin()) {
+ instr_iterator II = instr_end();
+ if (II != instr_begin()) {
while (II->isInsideBundle())
--II;
}
return II;
}
const_iterator end() const {
- const_insn_iterator II = insn_end();
- if (II != insn_begin()) {
+ const_instr_iterator II = instr_end();
+ if (II != instr_begin()) {
while (II->isInsideBundle())
--II;
}
return II;
}
reverse_iterator rbegin() {
- reverse_insn_iterator II = insn_rbegin();
- if (II != insn_rend()) {
+ reverse_instr_iterator II = instr_rbegin();
+ if (II != instr_rend()) {
while (II->isInsideBundle())
++II;
}
return II;
}
const_reverse_iterator rbegin() const {
- const_reverse_insn_iterator II = insn_rbegin();
- if (II != insn_rend()) {
+ const_reverse_instr_iterator II = instr_rbegin();
+ if (II != instr_rend()) {
while (II->isInsideBundle())
++II;
}
@@ -442,9 +442,9 @@ public:
iterator getFirstTerminator();
const_iterator getFirstTerminator() const;
- /// getFirstInsnTerminator - Same getFirstTerminator but it ignores bundles
- /// and return an insn_iterator instead.
- insn_iterator getFirstInsnTerminator();
+ /// getFirstInstrTerminator - Same getFirstTerminator but it ignores bundles
+ /// and return an instr_iterator instead.
+ instr_iterator getFirstInstrTerminator();
/// getLastNonDebugInstr - returns an iterator to the last non-debug
/// instruction in the basic block, or end()
@@ -464,68 +464,80 @@ public:
void push_back(MachineInstr *MI) { Insts.push_back(MI); }
template<typename IT>
- void insert(insn_iterator I, IT S, IT E) {
+ void insert(instr_iterator I, IT S, IT E) {
Insts.insert(I, S, E);
}
- insn_iterator insert(insn_iterator I, MachineInstr *M) {
+ instr_iterator insert(instr_iterator I, MachineInstr *M) {
return Insts.insert(I, M);
}
- insn_iterator insertAfter(insn_iterator I, MachineInstr *M) {
+ instr_iterator insertAfter(instr_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);
+ Insts.insert(I.getInstrIterator(), S, E);
}
iterator insert(iterator I, MachineInstr *M) {
- return Insts.insert(I.getInsnIterator(), M);
+ return Insts.insert(I.getInstrIterator(), M);
}
iterator insertAfter(iterator I, MachineInstr *M) {
- return Insts.insertAfter(I.getInsnIterator(), M);
+ return Insts.insertAfter(I.getInstrIterator(), M);
}
- // erase - Remove the specified element or range from the instruction list.
- // These functions delete any instructions removed.
- //
- insn_iterator erase(insn_iterator I) {
+ /// erase - Remove the specified element or range from the instruction list.
+ /// These functions delete any instructions removed.
+ ///
+ instr_iterator erase(instr_iterator I) {
return Insts.erase(I);
}
- insn_iterator erase(insn_iterator I, insn_iterator E) {
+ instr_iterator erase(instr_iterator I, instr_iterator E) {
return Insts.erase(I, E);
}
-
- iterator erase(iterator I) {
- return Insts.erase(I.getInsnIterator());
+ instr_iterator erase_instr(MachineInstr *I) {
+ instr_iterator MII(I);
+ return erase(MII);
}
+
+ iterator erase(iterator I);
iterator erase(iterator I, iterator E) {
- return Insts.erase(I.getInsnIterator(), E.getInsnIterator());
+ return Insts.erase(I.getInstrIterator(), E.getInstrIterator());
+ }
+ iterator erase(MachineInstr *I) {
+ iterator MII(I);
+ return erase(MII);
}
- iterator erase(MachineInstr *I) { iterator MII(I); return erase(MII); }
- MachineInstr *remove(MachineInstr *I) { return Insts.remove(I); }
- void clear() { Insts.clear(); }
+ /// remove - Remove the instruction from the instruction list. This function
+ /// does not delete the instruction. WARNING: Note, if the specified
+ /// instruction is a bundle this function will remove all the bundled
+ /// instructions as well. It is up to the caller to keep a list of the
+ /// bundled instructions and re-insert them if desired. This function is
+ /// *not recommended* for manipulating instructions with bundled. Use
+ /// splice instead.
+ MachineInstr *remove(MachineInstr *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(insn_iterator where, MachineBasicBlock *Other,
- insn_iterator From) {
+ void splice(instr_iterator where, MachineBasicBlock *Other,
+ instr_iterator From) {
Insts.splice(where, Other->Insts, From);
}
- void splice(iterator where, MachineBasicBlock *Other, iterator From) {
- Insts.splice(where.getInsnIterator(), Other->Insts, From.getInsnIterator());
- }
+ void splice(iterator where, MachineBasicBlock *Other, iterator From);
/// 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) {
+ void splice(instr_iterator where, MachineBasicBlock *Other, instr_iterator From,
+ instr_iterator To) {
Insts.splice(where, Other->Insts, From, To);
}
void splice(iterator where, MachineBasicBlock *Other, iterator From,
iterator To) {
- Insts.splice(where.getInsnIterator(), Other->Insts,
- From.getInsnIterator(), To.getInsnIterator());
+ Insts.splice(where.getInstrIterator(), Other->Insts,
+ From.getInstrIterator(), To.getInstrIterator());
}
/// removeFromParent - This method unlinks 'this' from the containing
@@ -552,9 +564,9 @@ public:
/// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping
/// any DBG_VALUE instructions. Return UnknownLoc if there is none.
- DebugLoc findDebugLoc(insn_iterator MBBI);
+ DebugLoc findDebugLoc(instr_iterator MBBI);
DebugLoc findDebugLoc(iterator MBBI) {
- return findDebugLoc(MBBI.getInsnIterator());
+ return findDebugLoc(MBBI.getInstrIterator());
}
// Debugging methods.
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index 9b04c1dd0c..904f1a6aee 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -175,6 +175,11 @@ public:
Flags = flags;
}
+ /// clearFlag - Clear a MI flag.
+ void clearFlag(MIFlag Flag) {
+ Flags &= ~((uint8_t)Flag);
+ }
+
/// isInsideBundle - Return true if MI is in a bundle (but not the first MI
/// in a bundle).
///
@@ -215,6 +220,15 @@ public:
return getFlag(InsideBundle);
}
+ /// setIsInsideBundle - Set InsideBundle bit.
+ ///
+ void setIsInsideBundle(bool Val = true) {
+ if (Val)
+ setFlag(InsideBundle);
+ else
+ clearFlag(InsideBundle);
+ }
+
/// getDebugLoc - Returns the debug location id of this MachineInstr.
///
DebugLoc getDebugLoc() const { return debugLoc; }
@@ -589,6 +603,9 @@ public:
bool isRegSequence() const {
return getOpcode() == TargetOpcode::REG_SEQUENCE;
}
+ bool isBundle() const {
+ return getOpcode() == TargetOpcode::BUNDLE;
+ }
bool isCopy() const {
return getOpcode() == TargetOpcode::COPY;
}
@@ -608,6 +625,9 @@ public:
getOperand(0).getSubReg() == getOperand(1).getSubReg();
}
+ /// getBundleSize - Return the number of instructions inside the MI bundle.
+ unsigned getBundleSize() const;
+
/// readsRegister - Return true if the MachineInstr reads the specified
/// register. If TargetRegisterInfo is passed, then it also checks if there
/// is a read of a super-register.
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index b989027246..80256428b2 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -209,6 +209,30 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
}
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::instr_iterator I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID,
+ unsigned DestReg) {
+ MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
+}
+
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineInstr *I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID,
+ unsigned DestReg) {
+ if (I->isInsideBundle()) {
+ MachineBasicBlock::instr_iterator MII = I;
+ return BuildMI(BB, MII, DL, MCID, DestReg);
+ }
+
+ MachineBasicBlock::iterator MII = I;
+ return BuildMI(BB, MII, DL, MCID, DestReg);
+}
+
/// BuildMI - This version of the builder inserts the newly-built
/// instruction before the given position in the given MachineBasicBlock, and
/// does NOT take a destination register.
@@ -222,6 +246,28 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
return MachineInstrBuilder(MI);
}
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::instr_iterator I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID) {
+ MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI);
+}
+
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineInstr *I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID) {
+ if (I->isInsideBundle()) {
+ MachineBasicBlock::instr_iterator MII = I;
+ return BuildMI(BB, MII, DL, MCID);
+ }
+
+ MachineBasicBlock::iterator MII = I;
+ return BuildMI(BB, MII, DL, MCID);
+}
+
/// BuildMI - This version of the builder inserts the newly-built
/// instruction at the end of the given MachineBasicBlock, and does NOT take a
/// destination register.
diff --git a/include/llvm/CodeGen/MachineInstrBundle.h b/include/llvm/CodeGen/MachineInstrBundle.h
new file mode 100644
index 0000000000..8c150e6d56
--- /dev/null
+++ b/include/llvm/CodeGen/MachineInstrBundle.h
@@ -0,0 +1,34 @@
+//===-- CodeGen/MachineInstBundle.h - MI bundle utilities -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provide utility functions to manipulate machine instruction
+// bundles.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEINSTRBUNDLE_H
+#define LLVM_CODEGEN_MACHINEINSTRBUNDLE_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+
+namespace llvm {
+
+/// FinalizeBundle - Finalize a machine instruction bundle which includes
+/// a sequence of instructions starting from FirstMI to LastMI (inclusive).
+/// This routine adds a BUNDLE instruction to represent the bundle, it adds
+/// IsInternalRead markers to MachineOperands which are defined inside the
+/// bundle, and it copies externally visible defs and uses to the BUNDLE
+/// instruction.
+void FinalizeBundle(MachineBasicBlock &MBB,
+ MachineBasicBlock::instr_iterator FirstMI,
+ MachineBasicBlock::instr_iterator LastMI);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 45b3353ac6..b4f6cac858 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -238,6 +238,10 @@ namespace llvm {
///
FunctionPass *createExecutionDependencyFixPass(const TargetRegisterClass *RC);
+ /// createUnpackMachineBundles - This pass unpack machine instruction bundles.
+ ///
+ FunctionPass *createUnpackMachineBundlesPass();
+
} // End llvm namespace
#endif
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index 565b64b438..ce87f16c2e 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -231,6 +231,7 @@ void initializeUnreachableMachineBlockElimPass(PassRegistry&);
void initializeVerifierPass(PassRegistry&);
void initializeVirtRegMapPass(PassRegistry&);
void initializeInstSimplifierPass(PassRegistry&);
+void initializeUnpackMachineBundlesPass(PassRegistry&);
}
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index 0d88e6c211..89894c37ee 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -926,8 +926,9 @@ bool BranchFolder::TailMergeBlocks(MachineFunction &MF) {
if (MergePotentials.size() >= 2)
MadeChange |= TryTailMergeBlocks(IBB, PredBB);
// Reinsert an unconditional branch if needed.
- // The 1 below can occur as a result of removing blocks in TryTailMergeBlocks.
- PredBB = prior(I); // this may have been changed in TryTailMergeBlocks
+ // The 1 below can occur as a result of removing blocks in
+ // TryTailMergeBlocks.
+ PredBB = prior(I); // this may have been changed in TryTailMergeBlocks
if (MergePotentials.size() == 1 &&
MergePotentials.begin()->getBlock() != PredBB)
FixTail(MergePotentials.begin()->getBlock(), IBB, TII);
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index 4dc8173bd7..673491608d 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -73,8 +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::insn_iterator I = N->insn_begin(), E = N->insn_end();
- I != E; ++I)
+ for (MachineBasicBlock::instr_iterator
+ I = N->instr_begin(), E = N->instr_end(); I != E; ++I)
I->AddRegOperandsToUseLists(RegInfo);
LeakDetector::removeGarbageObject(N);
@@ -141,7 +141,7 @@ void ilist_traits<MachineInstr>::deleteNode(MachineInstr* MI) {
}
MachineBasicBlock::iterator MachineBasicBlock::getFirstNonPHI() {
- insn_iterator I = insn_begin();
+ instr_iterator I = instr_begin();
while (I != end() && I->isPHI())
++I;
assert(!I->isInsideBundle() && "First non-phi MI cannot be inside a bundle!");
@@ -178,18 +178,18 @@ MachineBasicBlock::getFirstTerminator() const {
return I;
}
-MachineBasicBlock::insn_iterator MachineBasicBlock::getFirstInsnTerminator() {
- insn_iterator I = insn_end();
- while (I != insn_begin() && ((--I)->isTerminator() || I->isDebugValue()))
+MachineBasicBlock::instr_iterator MachineBasicBlock::getFirstInstrTerminator() {
+ instr_iterator I = instr_end();
+ while (I != instr_begin() && ((--I)->isTerminator() || I->isDebugValue()))
; /*noop */
- while (I != insn_end() && !I->isTerminator())
+ while (I != instr_end() && !I->isTerminator())
++I;
return I;
}
MachineBasicBlock::iterator MachineBasicBlock::getLastNonDebugInstr() {
// Skip over end-of-block dbg_value instructions.
- insn_iterator B = insn_begin(), I = insn_end();
+ instr_iterator B = instr_begin(), I = instr_end();
while (I != B) {
--I;
// Return instruction that starts a bundle.
@@ -204,7 +204,7 @@ MachineBasicBlock::iterator MachineBasicBlock::getLastNonDebugInstr() {
MachineBasicBlock::const_iterator
MachineBasicBlock::getLastNonDebugInstr() const {
// Skip over end-of-block dbg_value instructions.
- const_insn_iterator B = insn_begin(), I = insn_end();
+ const_instr_iterator B = instr_begin(), I = instr_end();
while (I != B) {
--I;
// Return instruction that starts a bundle.
@@ -283,13 +283,15 @@ void MachineBasicBlock::print(raw_ostream &OS, SlotIndexes *Indexes) const {
OS << '\n';
}
- for (const_iterator I = begin(); I != end(); ++I) {
+ for (const_instr_iterator I = instr_begin(); I != instr_end(); ++I) {
if (Indexes) {
if (Indexes->hasIndex(I))
OS << Indexes->getInstructionIndex(I);
OS << '\t';
}
OS << '\t';
+ if (I->isInsideBundle())
+ OS << " * ";
I->print(OS, &getParent()->getTarget());
}
@@ -495,8 +497,8 @@ MachineBasicBlock::transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB) {
fromMBB->removeSuccessor(Succ);
// Fix up any PHI nodes in the successor.
- for (MachineBasicBlock::insn_iterator MI = Succ->insn_begin(),
- ME = Succ->insn_end(); MI != ME && MI->isPHI(); ++MI)
+ for (MachineBasicBlock::instr_iterator MI = Succ->instr_begin(),
+ ME = Succ->instr_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)
@@ -598,7 +600,7 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
// Collect a list of virtual registers killed by the terminators.
SmallVector<unsigned, 4> KilledRegs;
if (LV)
- for (insn_iterator I = getFirstInsnTerminator(), E = insn_end();
+ for (instr_iterator I = getFirstInstrTerminator(), E = instr_end();
I != E; ++I) {
MachineInstr *MI = I;
for (MachineInstr::mop_iterator OI = MI->operands_begin(),
@@ -626,8 +628,9 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
}
// Fix PHI nodes in Succ so they refer to NMBB instead of this
- for (MachineBasicBlock::insn_iterator
- i = Succ->insn_begin(),e = Succ->insn_end(); i != e && i->isPHI(); ++i)
+ for (MachineBasicBlock::instr_iterator
+ i = Succ->instr_begin(),e = Succ->instr_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);
@@ -642,7 +645,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 (insn_iterator I = insn_end(), E = insn_begin(); I != E;) {
+ for (instr_iterator I = instr_end(), E = instr_begin(); I != E;) {
if (!(--I)->addRegisterKilled(Reg, NULL, /* addIfNotFound= */ false))
continue;
LV->getVarInfo(Reg).Kills.push_back(I);
@@ -711,6 +714,41 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
return NMBB;
}
+MachineBasicBlock::iterator
+MachineBasicBlock::erase(MachineBasicBlock::iterator I) {
+ if (I->isBundle()) {
+ MachineBasicBlock::iterator E = llvm::next(I);
+ return Insts.erase(I.getInstrIterator(), E.getInstrIterator());
+ }
+
+ return Insts.erase(I.getInstrIterator());
+}
+
+MachineInstr *MachineBasicBlock::remove(MachineInstr *I) {
+ if (I->isBundle()) {
+ MachineBasicBlock::instr_iterator MII = I; ++MII;
+ while (MII != end() && MII->isInsideBundle()) {
+ MachineInstr *MI = &*MII++;
+ Insts.remove(MI);
+ }
+ }
+
+ return Insts.remove(I);
+}
+
+void MachineBasicBlock::splice(MachineBasicBlock::iterator where,
+ MachineBasicBlock *Other,
+ MachineBasicBlock::iterator From) {
+ if (From->isBundle()) {
+ MachineBasicBlock::iterator To = llvm::next(From);
+ Insts.splice(where.getInstrIterator(), Other->Insts,
+ From.getInstrIterator(), To.getInstrIterator());
+ return;
+ }
+
+ Insts.splice(where.getInstrIterator(), Other->Insts, From.getInstrIterator());
+}
+
/// removeFromParent - This method unlinks 'this' from the containing function,
/// and returns it, but does not delete it.
MachineBasicBlock *MachineBasicBlock::removeFromParent() {
@@ -734,8 +772,8 @@ void MachineBasicBlock::ReplaceUsesOfBlockWith(MachineBasicBlock *Old,
MachineBasicBlock *New) {
assert(Old != New && "Cannot replace self with self!");
- MachineBasicBlock::insn_iterator I = insn_end();
- while (I != insn_begin()) {
+ MachineBasicBlock::instr_iterator I = instr_end();
+ while (I != instr_begin()) {
--I;
if (!I->isTerminator()) break;
@@ -816,9 +854,9 @@ 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(insn_iterator MBBI) {
+MachineBasicBlock::findDebugLoc(instr_iterator MBBI) {
DebugLoc DL;
- insn_iterator E = insn_end();
+ instr_iterator E = instr_end();
if (MBBI == E)
return DL;
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index d16e5d44c7..ec5a1cd099 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -750,11 +750,11 @@ void MachineInstr::addMemOperand(MachineFunction &MF,
bool
MachineInstr::hasProperty(unsigned MCFlag, QueryType Type) const {
- if (Type == IgnoreBundle || getOpcode() != TargetOpcode::BUNDLE)
+ if (Type == IgnoreBundle || !isBundle())
return getDesc().getFlags() & (1 << MCFlag);
const MachineBasicBlock *MBB = getParent();
- MachineBasicBlock::const_insn_iterator MII = *this; ++MII;
+ MachineBasicBlock::const_instr_iterator MII = *this; ++MII;
while (MII != MBB->end() && MII->isInsideBundle()) {
if (MII->getDesc().getFlags() & (1 << MCFlag)) {
if (Type == AnyInBundle)
@@ -777,6 +777,19 @@ bool MachineInstr::isIdenticalTo(const MachineInstr *Other,
Other->getNumOperands() != getNumOperands())
return false;
+ if (isBundle()) {
+ // Both instructions are bundles, compare MIs inside the bundle.
+ MachineBasicBlock::const_instr_iterator I1 = *this;
+ MachineBasicBlock::const_instr_iterator E1 = getParent()->instr_end();
+ MachineBasicBlock::const_instr_iterator I2 = *Other;
+ MachineBasicBlock::const_instr_iterator E2= Other->getParent()->instr_end();
+ while (++I1 != E1 && I1->isInsideBundle()) {
+ ++I2;
+ if (I2 == E2 || !I2->isInsideBundle() || !I1->isIdenticalTo(I2, Check))
+ return false;
+ }
+ }
+
// Check operands to make sure they match.
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
const MachineOperand &MO = getOperand(i);
@@ -825,10 +838,11 @@ 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) {
+ if (isBundle()) {
MachineBasicBlock *MBB = getParent();
- MachineBasicBlock::insn_iterator MII = *this; ++MII;
- while (MII != MBB->end() && MII->isInsideBundle()) {
+ MachineBasicBlock::instr_iterator MII = *this; ++MII;
+ MachineBasicBlock::instr_iterator E = MBB->instr_end();
+ while (MII != E && MII->isInsideBundle()) {
MachineInstr *MI = &*MII;
++MII;
MBB->remove(MI);
@@ -844,10 +858,11 @@ MachineInstr *MachineInstr::removeFromParent() {
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) {
+ if (isBundle()) {
MachineBasicBlock *MBB = getParent();
- MachineBasicBlock::insn_iterator MII = *this; ++MII;
- while (MII != MBB->end() && MII->isInsideBundle()) {
+ MachineBasicBlock::instr_iterator MII = *this; ++MII;
+ MachineBasicBlock::instr_iterator E = MBB->instr_end();
+ while (MII != E && MII->isInsideBundle()) {
MachineInstr *MI = &*MII;
++MII;
MBB->erase(MI);
@@ -942,6 +957,20 @@ MachineInstr::getRegClassConstraint(unsigned OpIdx,
return NULL;
}
+/// getBundleSize - Return the number of instructions inside the MI bundle.
+unsigned MachineInstr::getBundleSize() const {
+ assert(isBundle() && "Expecting a bundle");
+
+ MachineBasicBlock::const_instr_iterator I = *this;
+ unsigned Size = 0;
+ while ((++I)->isInsideBundle()) {
+ ++Size;
+ }
+ assert(Size > 1 && "Malformed bundle");
+
+ return Size;
+}
+
/// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of
/// the specific register or -1 if it is not found. It further tightens
/// the search criteria to a use that kills the register if isKill is true.
@@ -1024,9 +1053,6 @@ MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead, bool Overlap,
/// operand list that is used to represent the predicate. It returns -1 if
/// none is found.
int MachineInstr::findFirstPredOperandIdx() const {
- assert(getOpcode() != TargetOpcode::BUNDLE &&
- "MachineInstr::findFirstPredOperandIdx() can't handle bundles");
-
// Don't call MCID.findFirstPredOperandIdx() because this variant
// is sometimes called on an instruction that's not yet complete, and
// so the number of operands is less than the MCID indicates. In
@@ -1176,8 +1202,7 @@ void MachineInstr::copyKillDeadInfo(const MachineInstr *MI) {
/// copyPredicates - Copies predicate operand(s) from MI.
void MachineInstr::copyPredicates(const MachineInstr *MI) {
- assert(getOpcode() != TargetOpcode::BUNDLE &&
- "MachineInstr::copyPredicates() can't handle bundles");
+ assert(!isBundle() && "MachineInstr::copyPredicates() can't handle bundles");
const MCInstrDesc &MCID = MI->getDesc();
if (!MCID.isPredicable())