mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149708 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ee8901c08f
commit
59cb77fb11
@ -1799,7 +1799,7 @@ void MachineInstr::setPhysRegsDeadExcept(const SmallVectorImpl<unsigned> &UsedRe
|
||||
MachineOperand &MO = getOperand(i);
|
||||
if (!MO.isReg() || !MO.isDef()) continue;
|
||||
unsigned Reg = MO.getReg();
|
||||
if (Reg == 0) continue;
|
||||
if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
|
||||
bool Dead = true;
|
||||
for (SmallVectorImpl<unsigned>::const_iterator I = UsedRegs.begin(),
|
||||
E = UsedRegs.end(); I != E; ++I)
|
||||
|
@ -707,33 +707,6 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
|
||||
// Create the new machine instruction.
|
||||
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
|
||||
// instruction.
|
||||
if (NumResults)
|
||||
@ -758,30 +731,60 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
|
||||
// hook knows where in the block to insert the replacement code.
|
||||
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.
|
||||
if (HasPhysRegOuts) {
|
||||
for (unsigned i = II.getNumDefs(); i < NumResults; ++i) {
|
||||
unsigned Reg = II.getImplicitDefs()[i - II.getNumDefs()];
|
||||
if (Node->hasAnyUseOfValue(i))
|
||||
EmitCopyFromReg(Node, i, IsClone, IsCloned, Reg, VRBaseMap);
|
||||
// If there are no uses, mark the register as dead now, so that
|
||||
// MachineLICM/Sink can see that it's dead. Don't do this if the
|
||||
// node has a Glue value, for the benefit of targets still using
|
||||
// Glue for values in physregs.
|
||||
else if (Node->getValueType(Node->getNumValues()-1) != MVT::Glue)
|
||||
MI->addRegisterDead(Reg, TRI);
|
||||
if (!Node->hasAnyUseOfValue(i))
|
||||
continue;
|
||||
// This implicitly defined physreg has a use.
|
||||
UsedRegs.push_back(Reg);
|
||||
EmitCopyFromReg(Node, i, IsClone, IsCloned, Reg, VRBaseMap);
|
||||
}
|
||||
}
|
||||
|
||||
// If the instruction has implicit defs and the node doesn't, mark the
|
||||
// implicit def as dead. If the node has any glue outputs, we don't do this
|
||||
// because we don't know what implicit defs are being used by glued nodes.
|
||||
if (Node->getValueType(Node->getNumValues()-1) != MVT::Glue)
|
||||
if (const unsigned *IDList = II.getImplicitDefs()) {
|
||||
for (unsigned i = NumResults, e = II.getNumDefs()+II.getNumImplicitDefs();
|
||||
i != e; ++i)
|
||||
MI->addRegisterDead(IDList[i-II.getNumDefs()], TRI);
|
||||
// Scan the glue chain for any used physregs.
|
||||
if (Node->getValueType(Node->getNumValues()-1) == MVT::Glue) {
|
||||
for (SDNode *F = Node->getGluedUser(); F; F = F->getGluedUser()) {
|
||||
if (F->getOpcode() == ISD::CopyFromReg) {
|
||||
UsedRegs.push_back(cast<RegisterSDNode>(F->getOperand(1))->getReg());
|
||||
continue;
|
||||
}
|
||||
// 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.
|
||||
#ifdef NDEBUG
|
||||
|
Loading…
Reference in New Issue
Block a user