From 7c2a4a30e0e16762c75adacebd05ec9fcbccf16b Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Tue, 6 Dec 2011 22:12:01 +0000 Subject: [PATCH] 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 --- include/llvm/CodeGen/MachineBasicBlock.h | 202 ++++++++++++++++-- include/llvm/CodeGen/MachineInstr.h | 60 +++++- include/llvm/MC/MCInstrDesc.h | 4 + include/llvm/Target/Target.td | 5 + include/llvm/Target/TargetOpcodes.h | 7 +- lib/CodeGen/LiveVariables.cpp | 2 +- lib/CodeGen/MachineBasicBlock.cpp | 95 +++++--- lib/CodeGen/MachineInstr.cpp | 35 +++ lib/CodeGen/MachineLICM.cpp | 5 +- lib/CodeGen/PHIElimination.cpp | 2 +- lib/CodeGen/RegisterCoalescer.cpp | 3 +- lib/CodeGen/ScheduleDAGInstrs.cpp | 2 +- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 3 +- lib/CodeGen/TailDuplication.cpp | 3 +- lib/Target/ARM/ARMBaseInstrInfo.cpp | 3 +- lib/Target/ARM/ARMCodeEmitter.cpp | 2 +- lib/Target/Mips/MipsCodeEmitter.cpp | 2 +- lib/Target/PTX/PTXInstrInfo.cpp | 2 +- utils/TableGen/CodeGenTarget.cpp | 1 + 19 files changed, 369 insertions(+), 69 deletions(-) diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 499f62d660f7..1ec89eefad99 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -129,10 +129,89 @@ class MachineBasicBlock : public ilist_node { 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_reverse_iterator; - typedef std::reverse_iterator reverse_iterator; + + /// bundle_iterator - MachineBasicBlock iterator that automatically skips over + /// MIs that are inside bundles (i.e. walk top level MIs only). + template + class bundle_iterator + : public std::iterator { + 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 reverse_insn_iterator; + typedef + std::reverse_iterator const_reverse_insn_iterator; + + typedef + bundle_iterator iterator; + typedef + bundle_iterator const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + unsigned size() const { return (unsigned)Insts.size(); } bool empty() const { return Insts.empty(); } @@ -142,15 +221,53 @@ class MachineBasicBlock : public ilist_node { 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::iterator pred_iterator; typedef std::vector::const_iterator const_pred_iterator; @@ -323,18 +440,16 @@ class MachineBasicBlock : public ilist_node { /// 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(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(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 @@ class MachineBasicBlock : public ilist_node { void pop_front() { Insts.pop_front(); } void pop_back() { Insts.pop_back(); } void push_back(MachineInstr *MI) { Insts.push_back(MI); } + template - 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 + 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 @@ class MachineBasicBlock : public ilist_node { /// 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 cae38f34709d..1558c4f9573f 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -53,9 +53,11 @@ class MachineInstr : public ilist_node { }; 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 @@ class MachineInstr : public ilist_node { 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 @@ class MachineInstr : public ilist_node { 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 @@ class MachineInstr : public ilist_node { 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 aafa800c1ac8..6c33bfa2ecd7 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -184,6 +184,10 @@ class MCInstrDesc { 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 8582015e7794..26e59e452f57 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 37f7b2fb8db5..f0b181e345b7 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 2ca90f9f05c0..03f8221e1f6e 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 75fdb7e212d7..46ed082ad2d1 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -73,7 +73,8 @@ void ilist_traits::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::removeNodeFromList(MachineInstr *N) { /// lists. void ilist_traits:: transferNodesFromList(ilist_traits &fromList, - MachineBasicBlock::iterator first, - MachineBasicBlock::iterator last) { + ilist_iterator first, + ilist_iterator last) { assert(Parent->getParent() == fromList.Parent->getParent() && "MachineInstr parent mismatch!"); @@ -140,9 +141,10 @@ void ilist_traits::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 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 b0ef9d401a2f..abe6645909b3 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 e5e8c5117ba6..f88b730c6d80 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 6994aa58fbd5..0e52496f00c9 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 8ba93a429c24..3866fc08691f 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 5408cdf1ad57..b382169a3613 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 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 b74142dc807f..ddbeaeb7cb7c 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 3a6211a0f3e6..adfce863d0d8 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 413c0a5197c3..e3785f563422 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1762,8 +1762,7 @@ OptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, int CmpMask, // Check that CPSR isn't set between the comparison instruction and the one we // want to change. - MachineBasicBlock::const_iterator I = CmpInstr, E = MI, - B = MI->getParent()->begin(); + MachineBasicBlock::iterator I = CmpInstr,E = MI, B = MI->getParent()->begin(); // Early exit if CmpInstr is at the beginning of the BB. if (I == B) return false; diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 4148d4ab10e9..ce5470044e0b 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -386,7 +386,7 @@ bool ARMCodeEmitter::runOnMachineFunction(MachineFunction &MF) { for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); MBB != E; ++MBB) { MCE.StartMachineBasicBlock(MBB); - for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end(); + for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E; ++I) emitInstruction(*I); } diff --git a/lib/Target/Mips/MipsCodeEmitter.cpp b/lib/Target/Mips/MipsCodeEmitter.cpp index a8f29ae7a615..17cc0c533e69 100644 --- a/lib/Target/Mips/MipsCodeEmitter.cpp +++ b/lib/Target/Mips/MipsCodeEmitter.cpp @@ -144,7 +144,7 @@ bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) { for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); MBB != E; ++MBB){ MCE.StartMachineBasicBlock(MBB); - for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end(); + for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E; ++I) emitInstruction(*I); } diff --git a/lib/Target/PTX/PTXInstrInfo.cpp b/lib/Target/PTX/PTXInstrInfo.cpp index 1b947a5400f4..0190a8572a40 100644 --- a/lib/Target/PTX/PTXInstrInfo.cpp +++ b/lib/Target/PTX/PTXInstrInfo.cpp @@ -184,7 +184,7 @@ AnalyzeBranch(MachineBasicBlock &MBB, if (MBB.empty()) return true; - MachineBasicBlock::const_iterator iter = MBB.end(); + MachineBasicBlock::iterator iter = MBB.end(); const MachineInstr& instLast1 = *--iter; const MCInstrDesc &desc1 = instLast1.getDesc(); // for special case that MBB has only 1 instruction diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 6e1872e27d95..c8d2b00a82e0 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -267,6 +267,7 @@ void CodeGenTarget::ComputeInstrsByEnum() const { "DBG_VALUE", "REG_SEQUENCE", "COPY", + "BUNDLE", 0 }; const DenseMap &Insts = getInstructions();