diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h index 010d7032c516a607d50082991a9f43586a952736..da3838f249768c2b009890d52752ca2d4bac1709 100644 --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -625,14 +625,23 @@ public: MachineInstr *CreateMachineInstr(const MCInstrDesc &MCID, const DebugLoc &DL, bool NoImp = false); - /// CloneMachineInstr - Create a new MachineInstr which is a copy of the - /// 'Orig' instruction, identical in all ways except the instruction - /// has no parent, prev, or next. + /// Create a new MachineInstr which is a copy of \p Orig, identical in all + /// ways except the instruction has no parent, prev, or next. Bundling flags + /// are reset. /// - /// See also TargetInstrInfo::duplicate() for target-specific fixes to cloned - /// instructions. + /// Note: Clones a single instruction, not whole instruction bundles. + /// Does not perform target specific adjustments; consider using + /// TargetInstrInfo::duplicate() instead. MachineInstr *CloneMachineInstr(const MachineInstr *Orig); + /// Clones instruction or the whole instruction bundle \p Orig and insert + /// into \p MBB before \p InsertBefore. + /// + /// Note: Does not perform target specific adjustments; consider using + /// TargetInstrInfo::duplicate() intead. + MachineInstr &CloneMachineInstrBundle(MachineBasicBlock &MBB, + MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig); + /// DeleteMachineInstr - Delete the given MachineInstr. void DeleteMachineInstr(MachineInstr *MI); diff --git a/llvm/include/llvm/Target/TargetInstrInfo.h b/llvm/include/llvm/Target/TargetInstrInfo.h index 612f0b601c831d1b83020b75e1fb1da39defa24a..6e0838ceec0aed362a0f75f0790bd75964533a09 100644 --- a/llvm/include/llvm/Target/TargetInstrInfo.h +++ b/llvm/include/llvm/Target/TargetInstrInfo.h @@ -324,13 +324,13 @@ public: unsigned SubIdx, const MachineInstr &Orig, const TargetRegisterInfo &TRI) const; - /// Create a duplicate of the Orig instruction in MF. This is like - /// MachineFunction::CloneMachineInstr(), but the target may update operands + /// \brief Clones instruction or the whole instruction bundle \p Orig and + /// insert into \p MBB before \p InsertBefore. The target may update operands /// that are required to be unique. /// - /// The instruction must be duplicable as indicated by isNotDuplicable(). - virtual MachineInstr *duplicate(MachineInstr &Orig, - MachineFunction &MF) const; + /// \p Orig must not return true for MachineInstr::isNotDuplicable(). + virtual MachineInstr &duplicate(MachineBasicBlock &MBB, + MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig) const; /// This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index 742b095d955e8226d8c2e350abb64b27bf042b25..c4c0dff7bdf527c084208723173e239f39b86ed4 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -270,6 +270,26 @@ MachineFunction::CloneMachineInstr(const MachineInstr *Orig) { MachineInstr(*this, *Orig); } +MachineInstr &MachineFunction::CloneMachineInstrBundle(MachineBasicBlock &MBB, + MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig) { + MachineInstr *FirstClone = nullptr; + MachineBasicBlock::const_instr_iterator I = Orig.getIterator(); + for (;;) { + MachineInstr *Cloned = CloneMachineInstr(&*I); + MBB.insert(InsertBefore, Cloned); + if (FirstClone == nullptr) { + FirstClone = Cloned; + } else { + Cloned->bundleWithPred(); + } + + if (!I->isBundledWithSucc()) + break; + ++I; + } + return *FirstClone; +} + /// Delete the given MachineInstr. /// /// This function also serves as the MachineInstr destructor - the real diff --git a/llvm/lib/CodeGen/TailDuplicator.cpp b/llvm/lib/CodeGen/TailDuplicator.cpp index dc7265dcf6c244403670dfa01e91449599dca50c..0f22040f3aec5e292828225642e32c26ef0a7b65 100644 --- a/llvm/lib/CodeGen/TailDuplicator.cpp +++ b/llvm/lib/CodeGen/TailDuplicator.cpp @@ -369,10 +369,10 @@ void TailDuplicator::duplicateInstruction( MachineInstr *MI, MachineBasicBlock *TailBB, MachineBasicBlock *PredBB, DenseMap &LocalVRMap, const DenseSet &UsedByPhi) { - MachineInstr *NewMI = TII->duplicate(*MI, *MF); + MachineInstr &NewMI = TII->duplicate(*PredBB, PredBB->end(), *MI); if (PreRegAlloc) { - for (unsigned i = 0, e = NewMI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = NewMI->getOperand(i); + for (unsigned i = 0, e = NewMI.getNumOperands(); i != e; ++i) { + MachineOperand &MO = NewMI.getOperand(i); if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); @@ -443,7 +443,6 @@ void TailDuplicator::duplicateInstruction( } } } - PredBB->insert(PredBB->instr_end(), NewMI); } /// After FromBB is tail duplicated into its predecessor blocks, the successors @@ -825,10 +824,8 @@ bool TailDuplicator::tailDuplicate(bool IsSimple, MachineBasicBlock *TailBB, // Clone the contents of TailBB into PredBB. DenseMap LocalVRMap; SmallVector, 4> CopyInfos; - // Use instr_iterator here to properly handle bundles, e.g. - // ARM Thumb2 IT block. - MachineBasicBlock::instr_iterator I = TailBB->instr_begin(); - while (I != TailBB->instr_end()) { + for (MachineBasicBlock::iterator I = TailBB->begin(), E = TailBB->end(); + I != E; /* empty */) { MachineInstr *MI = &*I; ++I; if (MI->isPHI()) { diff --git a/llvm/lib/CodeGen/TargetInstrInfo.cpp b/llvm/lib/CodeGen/TargetInstrInfo.cpp index 14c5adc0d898bd0f33e51f6d5d6ee5409ed8be7b..5e92cbf1ee0d80b668f96ac133e1765964b4f79d 100644 --- a/llvm/lib/CodeGen/TargetInstrInfo.cpp +++ b/llvm/lib/CodeGen/TargetInstrInfo.cpp @@ -388,10 +388,11 @@ bool TargetInstrInfo::produceSameValue(const MachineInstr &MI0, return MI0.isIdenticalTo(MI1, MachineInstr::IgnoreVRegDefs); } -MachineInstr *TargetInstrInfo::duplicate(MachineInstr &Orig, - MachineFunction &MF) const { +MachineInstr &TargetInstrInfo::duplicate(MachineBasicBlock &MBB, + MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig) const { assert(!Orig.isNotDuplicable() && "Instruction cannot be duplicated"); - return MF.CloneMachineInstr(&Orig); + MachineFunction &MF = *MBB.getParent(); + return MF.CloneMachineInstrBundle(MBB, InsertBefore, Orig); } // If the COPY instruction in MI can be folded to a stack operation, return diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index 3cf5950a1918d9583004fb6aa1cd36d91525ff18..3688db943d54161ca649be32a9890b31dcbd8975 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1550,20 +1550,29 @@ void ARMBaseInstrInfo::reMaterialize(MachineBasicBlock &MBB, } } -MachineInstr *ARMBaseInstrInfo::duplicate(MachineInstr &Orig, - MachineFunction &MF) const { - MachineInstr *MI = TargetInstrInfo::duplicate(Orig, MF); - switch (Orig.getOpcode()) { - case ARM::tLDRpci_pic: - case ARM::t2LDRpci_pic: { - unsigned CPI = Orig.getOperand(1).getIndex(); - unsigned PCLabelId = duplicateCPV(MF, CPI); - Orig.getOperand(1).setIndex(CPI); - Orig.getOperand(2).setImm(PCLabelId); - break; - } +MachineInstr & +ARMBaseInstrInfo::duplicate(MachineBasicBlock &MBB, + MachineBasicBlock::iterator InsertBefore, + const MachineInstr &Orig) const { + MachineInstr &Cloned = TargetInstrInfo::duplicate(MBB, InsertBefore, Orig); + MachineBasicBlock::instr_iterator I = Cloned.getIterator(); + for (;;) { + switch (I->getOpcode()) { + case ARM::tLDRpci_pic: + case ARM::t2LDRpci_pic: { + MachineFunction &MF = *MBB.getParent(); + unsigned CPI = I->getOperand(1).getIndex(); + unsigned PCLabelId = duplicateCPV(MF, CPI); + I->getOperand(1).setIndex(CPI); + I->getOperand(2).setImm(PCLabelId); + break; + } + } + if (!I->isBundledWithSucc()) + break; + ++I; } - return MI; + return Cloned; } bool ARMBaseInstrInfo::produceSameValue(const MachineInstr &MI0, diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h index c52e572786d4823d3e22e157f9ba1c5a5d3bd9ec..9f168acd56769d04efd56d7fc3ea700a14ba9a81 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -220,8 +220,9 @@ public: const MachineInstr &Orig, const TargetRegisterInfo &TRI) const override; - MachineInstr *duplicate(MachineInstr &Orig, - MachineFunction &MF) const override; + MachineInstr & + duplicate(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, + const MachineInstr &Orig) const override; const MachineInstrBuilder &AddDReg(MachineInstrBuilder &MIB, unsigned Reg, unsigned SubIdx, unsigned State,