diff --git a/include/llvm/CodeGen/LivePhysRegs.h b/include/llvm/CodeGen/LivePhysRegs.h index f44d627d717..6ffd3eeea35 100644 --- a/include/llvm/CodeGen/LivePhysRegs.h +++ b/include/llvm/CodeGen/LivePhysRegs.h @@ -93,7 +93,8 @@ public: } /// \brief Removes physical registers clobbered by the regmask operand @p MO. - void removeRegsInMask(const MachineOperand &MO); + void removeRegsInMask(const MachineOperand &MO, + SmallVectorImpl> *Clobbers); /// \brief Returns true if register @p Reg is contained in the set. This also /// works if only the super register of @p Reg has been defined, because we @@ -109,7 +110,11 @@ public: /// instruction(bundle): Remove killed-uses, add defs. This is the not /// recommended way, because it depends on accurate kill flags. If possible /// use stepBackwards() instead of this function. - void stepForward(const MachineInstr &MI); + /// The clobbers set will be the list of registers either defined or clobbered + /// by a regmask. The operand will identify whether this is a regmask or + /// register operand. + void stepForward(const MachineInstr &MI, + SmallVectorImpl> &Clobbers); /// \brief Adds all live-in registers of basic block @p MBB. void addLiveIns(const MachineBasicBlock *MBB) { diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp index b8799a563fc..6359d765da4 100644 --- a/lib/CodeGen/IfConversion.cpp +++ b/lib/CodeGen/IfConversion.cpp @@ -975,26 +975,18 @@ void IfConverter::RemoveExtraEdges(BBInfo &BBI) { /// Behaves like LiveRegUnits::StepForward() but also adds implicit uses to all /// values defined in MI which are not live/used by MI. static void UpdatePredRedefs(MachineInstr *MI, LivePhysRegs &Redefs) { - for (ConstMIBundleOperands Ops(MI); Ops.isValid(); ++Ops) { - if (!Ops->isReg() || !Ops->isKill()) - continue; - unsigned Reg = Ops->getReg(); - if (Reg == 0) - continue; - Redefs.removeReg(Reg); - } - for (MIBundleOperands Ops(MI); Ops.isValid(); ++Ops) { - if (!Ops->isReg() || !Ops->isDef()) - continue; - unsigned Reg = Ops->getReg(); - if (Reg == 0 || Redefs.contains(Reg)) - continue; - Redefs.addReg(Reg); + SmallVector, 4> Clobbers; + Redefs.stepForward(*MI, Clobbers); - MachineOperand &Op = *Ops; - MachineInstr *MI = Op.getParent(); - MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI); - MIB.addReg(Reg, RegState::Implicit | RegState::Undef); + // Now add the implicit uses for each of the clobbered values. + for (auto Reg : Clobbers) { + const MachineOperand &Op = *Reg.second; + // FIXME: Const cast here is nasty, but better than making StepForward + // take a mutable instruction instead of const. + MachineInstr *OpMI = const_cast(Op.getParent()); + MachineInstrBuilder MIB(*OpMI->getParent()->getParent(), OpMI); + if (Op.isReg()) + MIB.addReg(Reg.first, RegState::Implicit | RegState::Undef); } } @@ -1374,7 +1366,8 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind, for (MachineBasicBlock::const_iterator I = BBI1->BB->begin(), E = DI1; I != E; ++I) { - Redefs.stepForward(*I); + SmallVector, 4> IgnoredClobbers; + Redefs.stepForward(*I, IgnoredClobbers); } BBI.BB->splice(BBI.BB->end(), BBI1->BB, BBI1->BB->begin(), DI1); BBI2->BB->erase(BBI2->BB->begin(), DI2); diff --git a/lib/CodeGen/LivePhysRegs.cpp b/lib/CodeGen/LivePhysRegs.cpp index 89567eff517..b6369275051 100644 --- a/lib/CodeGen/LivePhysRegs.cpp +++ b/lib/CodeGen/LivePhysRegs.cpp @@ -22,12 +22,17 @@ using namespace llvm; /// \brief Remove all registers from the set that get clobbered by the register /// mask. -void LivePhysRegs::removeRegsInMask(const MachineOperand &MO) { +/// The clobbers set will be the list of live registers clobbered +/// by the regmask. +void LivePhysRegs::removeRegsInMask(const MachineOperand &MO, + SmallVectorImpl> *Clobbers) { SparseSet::iterator LRI = LiveRegs.begin(); while (LRI != LiveRegs.end()) { - if (MO.clobbersPhysReg(*LRI)) + if (MO.clobbersPhysReg(*LRI)) { + if (Clobbers) + Clobbers->push_back(std::make_pair(*LRI, &MO)); LRI = LiveRegs.erase(LRI); - else + } else ++LRI; } } @@ -45,7 +50,7 @@ void LivePhysRegs::stepBackward(const MachineInstr &MI) { continue; removeReg(Reg); } else if (O->isRegMask()) - removeRegsInMask(*O); + removeRegsInMask(*O, nullptr); } // Add uses to the set. @@ -63,8 +68,8 @@ void LivePhysRegs::stepBackward(const MachineInstr &MI) { /// killed-uses, add defs. This is the not recommended way, because it depends /// on accurate kill flags. If possible use stepBackwards() instead of this /// function. -void LivePhysRegs::stepForward(const MachineInstr &MI) { - SmallVector Defs; +void LivePhysRegs::stepForward(const MachineInstr &MI, + SmallVectorImpl> &Clobbers) { // Remove killed registers from the set. for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) { if (O->isReg()) { @@ -73,7 +78,7 @@ void LivePhysRegs::stepForward(const MachineInstr &MI) { continue; if (O->isDef()) { if (!O->isDead()) - Defs.push_back(Reg); + Clobbers.push_back(std::make_pair(Reg, &*O)); } else { if (!O->isKill()) continue; @@ -81,12 +86,12 @@ void LivePhysRegs::stepForward(const MachineInstr &MI) { removeReg(Reg); } } else if (O->isRegMask()) - removeRegsInMask(*O); + removeRegsInMask(*O, &Clobbers); } // Add defs to the set. - for (unsigned i = 0, e = Defs.size(); i != e; ++i) - addReg(Defs[i]); + for (auto Reg : Clobbers) + addReg(Reg.first); } /// Prin the currently live registers to OS.