R600/SI: Clean up checks for legality of immediate operands

There are new register classes VCSrc_* which represent operands that
can take an SGPR, VGPR or inline constant.  The VSrc_* class is now used
to represent operands that can take an SGPR, VGPR, or a 32-bit
immediate.

This allows us to have more accurate checks for legality of
immediates, since before we had no way to distinguish between operands
that supported any 32-bit immediate and operands which could only
support inline constants.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218334 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tom Stellard
2014-09-23 21:26:25 +00:00
parent 30e7514d01
commit 33aca6d4a0
8 changed files with 149 additions and 67 deletions

View File

@@ -1498,8 +1498,14 @@ SDValue SITargetLowering::PerformDAGCombine(SDNode *N,
/// \brief Test if RegClass is one of the VSrc classes
static bool isVSrc(unsigned RegClass) {
return AMDGPU::VSrc_32RegClassID == RegClass ||
AMDGPU::VSrc_64RegClassID == RegClass;
switch(RegClass) {
default: return false;
case AMDGPU::VSrc_32RegClassID:
case AMDGPU::VCSrc_32RegClassID:
case AMDGPU::VSrc_64RegClassID:
case AMDGPU::VCSrc_64RegClassID:
return true;
}
}
/// \brief Test if RegClass is one of the SSrc classes
@@ -1611,10 +1617,9 @@ const TargetRegisterClass *SITargetLowering::getRegClassForNode(
// If the COPY_TO_REGCLASS instruction is copying to a VSrc register
// class, then the register class for the value could be either a
// VReg or and SReg. In order to get a more accurate
if (OpClassID == AMDGPU::VSrc_32RegClassID ||
OpClassID == AMDGPU::VSrc_64RegClassID) {
if (isVSrc(OpClassID))
return getRegClassForNode(DAG, Op.getOperand(0));
}
return TRI.getRegClass(OpClassID);
case AMDGPU::EXTRACT_SUBREG: {
int SubIdx = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
@@ -1648,14 +1653,23 @@ void SITargetLowering::ensureSRegLimit(SelectionDAG &DAG, SDValue &Operand,
unsigned RegClass,
bool &ScalarSlotUsed) const {
// First map the operands register class to a destination class
if (RegClass == AMDGPU::VSrc_32RegClassID)
RegClass = AMDGPU::VReg_32RegClassID;
else if (RegClass == AMDGPU::VSrc_64RegClassID)
RegClass = AMDGPU::VReg_64RegClassID;
else
if (!isVSrc(RegClass))
return;
// First map the operands register class to a destination class
switch (RegClass) {
case AMDGPU::VSrc_32RegClassID:
case AMDGPU::VCSrc_32RegClassID:
RegClass = AMDGPU::VReg_32RegClassID;
break;
case AMDGPU::VSrc_64RegClassID:
case AMDGPU::VCSrc_64RegClassID:
RegClass = AMDGPU::VReg_64RegClassID;
break;
default:
llvm_unreachable("Unknown vsrc reg class");
}
// Nothing to do if they fit naturally
if (fitsRegClass(DAG, Operand, RegClass))
return;
@@ -1745,6 +1759,15 @@ SDNode *SITargetLowering::legalizeOperands(MachineSDNode *Node,
// No scalar allowed when we have both VSrc and SSrc
bool ScalarSlotUsed = HaveVSrc && HaveSSrc;
// If this instruction has an implicit use of VCC, then it can't use the
// constant bus.
for (unsigned i = 0, e = Desc->getNumImplicitUses(); i != e; ++i) {
if (Desc->ImplicitUses[i] == AMDGPU::VCC) {
ScalarSlotUsed = true;
break;
}
}
// Second go over the operands and try to fold them
std::vector<SDValue> Ops;
for (unsigned i = 0, e = Node->getNumOperands(), Op = NumDefs;