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);
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
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
MachineInstr *MI, MachineBasicBlock *TailBB, MachineBasicBlock *PredBB,
DenseMap<unsigned, RegSubRegPair> &LocalVRMap,
const DenseSet<unsigned> &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();
}
}
}
- PredBB->insert(PredBB->instr_end(), NewMI);
}
/// After FromBB is tail duplicated into its predecessor blocks, the successors
// Clone the contents of TailBB into PredBB.
DenseMap<unsigned, RegSubRegPair> LocalVRMap;
SmallVector<std::pair<unsigned, RegSubRegPair>, 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()) {
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
}
}
-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,
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,