Handle all live physreg defs in the same place.
SelectionDAG has 4 different ways of passing physreg defs to users. Collect all of the uses at the same time, and pass all of them to MI->setPhysRegsDeadExcept() to mark the remaining defs dead. The setPhysRegsDeadExcept() function will soon add the required implicit-defs to instructions with register mask operands. llvm-svn: 149708
This commit is contained in:
parent
15f247ad8c
commit
f650732cab
|
@ -1799,7 +1799,7 @@ void MachineInstr::setPhysRegsDeadExcept(const SmallVectorImpl<unsigned> &UsedRe
|
||||||
MachineOperand &MO = getOperand(i);
|
MachineOperand &MO = getOperand(i);
|
||||||
if (!MO.isReg() || !MO.isDef()) continue;
|
if (!MO.isReg() || !MO.isDef()) continue;
|
||||||
unsigned Reg = MO.getReg();
|
unsigned Reg = MO.getReg();
|
||||||
if (Reg == 0) continue;
|
if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
|
||||||
bool Dead = true;
|
bool Dead = true;
|
||||||
for (SmallVectorImpl<unsigned>::const_iterator I = UsedRegs.begin(),
|
for (SmallVectorImpl<unsigned>::const_iterator I = UsedRegs.begin(),
|
||||||
E = UsedRegs.end(); I != E; ++I)
|
E = UsedRegs.end(); I != E; ++I)
|
||||||
|
|
|
@ -707,33 +707,6 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
|
||||||
// Create the new machine instruction.
|
// Create the new machine instruction.
|
||||||
MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(), II);
|
MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(), II);
|
||||||
|
|
||||||
// The MachineInstr constructor adds implicit-def operands. Scan through
|
|
||||||
// these to determine which are dead.
|
|
||||||
if (MI->getNumOperands() != 0 &&
|
|
||||||
Node->getValueType(Node->getNumValues()-1) == MVT::Glue) {
|
|
||||||
// First, collect all used registers.
|
|
||||||
SmallVector<unsigned, 8> UsedRegs;
|
|
||||||
for (SDNode *F = Node->getGluedUser(); F; F = F->getGluedUser())
|
|
||||||
if (F->getOpcode() == ISD::CopyFromReg)
|
|
||||||
UsedRegs.push_back(cast<RegisterSDNode>(F->getOperand(1))->getReg());
|
|
||||||
else {
|
|
||||||
// Collect declared implicit uses.
|
|
||||||
const MCInstrDesc &MCID = TII->get(F->getMachineOpcode());
|
|
||||||
UsedRegs.append(MCID.getImplicitUses(),
|
|
||||||
MCID.getImplicitUses() + MCID.getNumImplicitUses());
|
|
||||||
// In addition to declared implicit uses, we must also check for
|
|
||||||
// direct RegisterSDNode operands.
|
|
||||||
for (unsigned i = 0, e = F->getNumOperands(); i != e; ++i)
|
|
||||||
if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(F->getOperand(i))) {
|
|
||||||
unsigned Reg = R->getReg();
|
|
||||||
if (TargetRegisterInfo::isPhysicalRegister(Reg))
|
|
||||||
UsedRegs.push_back(Reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Then mark unused registers as dead.
|
|
||||||
MI->setPhysRegsDeadExcept(UsedRegs, *TRI);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add result register values for things that are defined by this
|
// Add result register values for things that are defined by this
|
||||||
// instruction.
|
// instruction.
|
||||||
if (NumResults)
|
if (NumResults)
|
||||||
|
@ -758,30 +731,60 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
|
||||||
// hook knows where in the block to insert the replacement code.
|
// hook knows where in the block to insert the replacement code.
|
||||||
MBB->insert(InsertPos, MI);
|
MBB->insert(InsertPos, MI);
|
||||||
|
|
||||||
|
// The MachineInstr may also define physregs instead of virtregs. These
|
||||||
|
// physreg values can reach other instructions in different ways:
|
||||||
|
//
|
||||||
|
// 1. When there is a use of a Node value beyond the explicitly defined
|
||||||
|
// virtual registers, we emit a CopyFromReg for one of the implicitly
|
||||||
|
// defined physregs. This only happens when HasPhysRegOuts is true.
|
||||||
|
//
|
||||||
|
// 2. A CopyFromReg reading a physreg may be glued to this instruction.
|
||||||
|
//
|
||||||
|
// 3. A glued instruction may implicitly use a physreg.
|
||||||
|
//
|
||||||
|
// 4. A glued instruction may use a RegisterSDNode operand.
|
||||||
|
//
|
||||||
|
// Collect all the used physreg defs, and make sure that any unused physreg
|
||||||
|
// defs are marked as dead.
|
||||||
|
SmallVector<unsigned, 8> UsedRegs;
|
||||||
|
|
||||||
// Additional results must be physical register defs.
|
// Additional results must be physical register defs.
|
||||||
if (HasPhysRegOuts) {
|
if (HasPhysRegOuts) {
|
||||||
for (unsigned i = II.getNumDefs(); i < NumResults; ++i) {
|
for (unsigned i = II.getNumDefs(); i < NumResults; ++i) {
|
||||||
unsigned Reg = II.getImplicitDefs()[i - II.getNumDefs()];
|
unsigned Reg = II.getImplicitDefs()[i - II.getNumDefs()];
|
||||||
if (Node->hasAnyUseOfValue(i))
|
if (!Node->hasAnyUseOfValue(i))
|
||||||
EmitCopyFromReg(Node, i, IsClone, IsCloned, Reg, VRBaseMap);
|
continue;
|
||||||
// If there are no uses, mark the register as dead now, so that
|
// This implicitly defined physreg has a use.
|
||||||
// MachineLICM/Sink can see that it's dead. Don't do this if the
|
UsedRegs.push_back(Reg);
|
||||||
// node has a Glue value, for the benefit of targets still using
|
EmitCopyFromReg(Node, i, IsClone, IsCloned, Reg, VRBaseMap);
|
||||||
// Glue for values in physregs.
|
|
||||||
else if (Node->getValueType(Node->getNumValues()-1) != MVT::Glue)
|
|
||||||
MI->addRegisterDead(Reg, TRI);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the instruction has implicit defs and the node doesn't, mark the
|
// Scan the glue chain for any used physregs.
|
||||||
// implicit def as dead. If the node has any glue outputs, we don't do this
|
if (Node->getValueType(Node->getNumValues()-1) == MVT::Glue) {
|
||||||
// because we don't know what implicit defs are being used by glued nodes.
|
for (SDNode *F = Node->getGluedUser(); F; F = F->getGluedUser()) {
|
||||||
if (Node->getValueType(Node->getNumValues()-1) != MVT::Glue)
|
if (F->getOpcode() == ISD::CopyFromReg) {
|
||||||
if (const unsigned *IDList = II.getImplicitDefs()) {
|
UsedRegs.push_back(cast<RegisterSDNode>(F->getOperand(1))->getReg());
|
||||||
for (unsigned i = NumResults, e = II.getNumDefs()+II.getNumImplicitDefs();
|
continue;
|
||||||
i != e; ++i)
|
}
|
||||||
MI->addRegisterDead(IDList[i-II.getNumDefs()], TRI);
|
// Collect declared implicit uses.
|
||||||
|
const MCInstrDesc &MCID = TII->get(F->getMachineOpcode());
|
||||||
|
UsedRegs.append(MCID.getImplicitUses(),
|
||||||
|
MCID.getImplicitUses() + MCID.getNumImplicitUses());
|
||||||
|
// In addition to declared implicit uses, we must also check for
|
||||||
|
// direct RegisterSDNode operands.
|
||||||
|
for (unsigned i = 0, e = F->getNumOperands(); i != e; ++i)
|
||||||
|
if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(F->getOperand(i))) {
|
||||||
|
unsigned Reg = R->getReg();
|
||||||
|
if (TargetRegisterInfo::isPhysicalRegister(Reg))
|
||||||
|
UsedRegs.push_back(Reg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally mark unused registers as dead.
|
||||||
|
if (!UsedRegs.empty() || II.getImplicitDefs())
|
||||||
|
MI->setPhysRegsDeadExcept(UsedRegs, *TRI);
|
||||||
|
|
||||||
// Run post-isel target hook to adjust this instruction if needed.
|
// Run post-isel target hook to adjust this instruction if needed.
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
|
|
Loading…
Reference in New Issue