diff options
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()) |