Simplify EXTRACT_SUBREG emission.

EXTRACT_SUBREG is emitted as %dst = COPY %src:sub, so there is no need to
constrain the %dst register class.  RegisterCoalescer will apply the
necessary constraints if it decides to eliminate the COPY.

The %src register class does need to be constrained to something with
the right sub-registers, though.  This is currently done manually with
COPY_TO_REGCLASS nodes.  They can possibly be removed after this patch.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141207 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2011-10-05 20:26:40 +00:00
parent 9bb272c900
commit d2ed2d71c9
2 changed files with 51 additions and 26 deletions

View File

@ -30,6 +30,12 @@
#include "llvm/Support/MathExtras.h"
using namespace llvm;
/// MinRCSize - Smallest register class we allow when constraining virtual
/// registers. If satisfying all register class constraints would require
/// using a smaller register class, emit a COPY to a new virtual register
/// instead.
const unsigned MinRCSize = 4;
/// CountResults - The results of target nodes have register or immediate
/// operands first, then an optional chain, and optional glue operands (which do
/// not go into the resulting MachineInstr).
@ -284,7 +290,6 @@ InstrEmitter::AddRegisterOperand(MachineInstr *MI, SDValue Op,
// a new virtual register and copy the value into it, but first attempt to
// shrink VReg's register class within reason. For example, if VReg == GR32
// and II requires a GR32_NOSP, just constrain VReg to GR32_NOSP.
const unsigned MinRCSize = 4;
if (II) {
const TargetRegisterClass *DstRC = 0;
if (IIOpNum < II->getNumOperands())
@ -392,6 +397,30 @@ void InstrEmitter::AddOperand(MachineInstr *MI, SDValue Op,
}
}
unsigned InstrEmitter::ConstrainForSubReg(unsigned VReg, unsigned SubIdx,
EVT VT, DebugLoc DL) {
const TargetRegisterClass *VRC = MRI->getRegClass(VReg);
const TargetRegisterClass *RC = TRI->getSubClassWithSubReg(VRC, SubIdx);
// RC is a sub-class of VRC that supports SubIdx. Try to constrain VReg
// within reason.
if (RC && RC != VRC)
RC = MRI->constrainRegClass(VReg, RC, MinRCSize);
// VReg has been adjusted. It can be used with SubIdx operands now.
if (RC)
return VReg;
// VReg couldn't be reasonably constrained. Emit a COPY to a new virtual
// register instead.
RC = TRI->getSubClassWithSubReg(TLI->getRegClassFor(VT), SubIdx);
assert(RC && "No legal register class for VT supports that SubIdx");
unsigned NewReg = MRI->createVirtualRegister(RC);
BuildMI(*MBB, InsertPos, DL, TII->get(TargetOpcode::COPY), NewReg)
.addReg(VReg);
return NewReg;
}
/// EmitSubregNode - Generate machine code for subreg nodes.
///
void InstrEmitter::EmitSubregNode(SDNode *Node,
@ -416,10 +445,12 @@ void InstrEmitter::EmitSubregNode(SDNode *Node,
}
if (Opc == TargetOpcode::EXTRACT_SUBREG) {
// EXTRACT_SUBREG is lowered as %dst = COPY %src:sub
// EXTRACT_SUBREG is lowered as %dst = COPY %src:sub. There are no
// constraints on the %dst register, COPY can target all legal register
// classes.
unsigned SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
const TargetRegisterClass *TRC = TLI->getRegClassFor(Node->getValueType(0));
// Figure out the register class to create for the destreg.
unsigned VReg = getVR(Node->getOperand(0), VRBaseMap);
MachineInstr *DefMI = MRI->getVRegDef(VReg);
unsigned SrcReg, DstReg, DefSubIdx;
@ -431,36 +462,24 @@ void InstrEmitter::EmitSubregNode(SDNode *Node,
// r1026 = extract_subreg r1025, 4
// to a copy
// r1026 = copy r1024
const TargetRegisterClass *TRC = MRI->getRegClass(SrcReg);
VRBase = MRI->createVirtualRegister(TRC);
BuildMI(*MBB, InsertPos, Node->getDebugLoc(),
TII->get(TargetOpcode::COPY), VRBase).addReg(SrcReg);
} else {
const TargetRegisterClass *TRC = MRI->getRegClass(VReg);
const TargetRegisterClass *SRC = TRC->getSubRegisterRegClass(SubIdx);
assert(SRC && "Invalid subregister index in EXTRACT_SUBREG");
// VReg may not support a SubIdx sub-register, and we may need to
// constrain its register class or issue a COPY to a compatible register
// class.
VReg = ConstrainForSubReg(VReg, SubIdx,
Node->getOperand(0).getValueType(),
Node->getDebugLoc());
// Figure out the register class to create for the destreg.
// Note that if we're going to directly use an existing register,
// it must be precisely the required class, and not a subclass
// thereof.
if (VRBase == 0 || SRC != MRI->getRegClass(VRBase)) {
// Create the reg
assert(SRC && "Couldn't find source register class");
VRBase = MRI->createVirtualRegister(SRC);
}
// Create the destreg if it is missing.
if (VRBase == 0)
VRBase = MRI->createVirtualRegister(TRC);
// Create the extract_subreg machine instruction.
MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(),
TII->get(TargetOpcode::COPY), VRBase);
// Add source, and subreg index
AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap, /*IsDebug=*/false,
IsClone, IsCloned);
assert(TargetRegisterInfo::isVirtualRegister(MI->getOperand(1).getReg())&&
"Cannot yet extract from physregs");
MI->getOperand(1).setSubReg(SubIdx);
MBB->insert(InsertPos, MI);
BuildMI(*MBB, InsertPos, Node->getDebugLoc(),
TII->get(TargetOpcode::COPY), VRBase).addReg(VReg, 0, SubIdx);
}
} else if (Opc == TargetOpcode::INSERT_SUBREG ||
Opc == TargetOpcode::SUBREG_TO_REG) {

View File

@ -77,6 +77,12 @@ class InstrEmitter {
DenseMap<SDValue, unsigned> &VRBaseMap,
bool IsDebug, bool IsClone, bool IsCloned);
/// ConstrainForSubReg - Try to constrain VReg to a register class that
/// supports SubIdx sub-registers. Emit a copy if that isn't possible.
/// Return the virtual register to use.
unsigned ConstrainForSubReg(unsigned VReg, unsigned SubIdx,
EVT VT, DebugLoc DL);
/// EmitSubregNode - Generate machine code for subreg nodes.
///
void EmitSubregNode(SDNode *Node, DenseMap<SDValue, unsigned> &VRBaseMap,