summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2013-08-06 23:08:18 +0000
committerTom Stellard <thomas.stellard@amd.com>2013-08-06 23:08:18 +0000
commit4c0ffccbbf4ef58147bd8ae115cc9f6c3ef7d7a1 (patch)
tree265ad3981d47e7bc78aad84738aae70be15a3e3a /llvm/lib
parent8b24e1e4fb91f9bdb7f9a64e8d92e8dcd0bebf8b (diff)
downloadbcm5719-llvm-4c0ffccbbf4ef58147bd8ae115cc9f6c3ef7d7a1.tar.gz
bcm5719-llvm-4c0ffccbbf4ef58147bd8ae115cc9f6c3ef7d7a1.zip
R600/SI: Add more special cases for opcodes to ensureSRegLimit()
Also factor out the register class lookup to its own function. llvm-svn: 187830
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/R600/SIISelLowering.cpp88
-rw-r--r--llvm/lib/Target/R600/SIISelLowering.h2
-rw-r--r--llvm/lib/Target/R600/SIRegisterInfo.cpp21
-rw-r--r--llvm/lib/Target/R600/SIRegisterInfo.h4
4 files changed, 83 insertions, 32 deletions
diff --git a/llvm/lib/Target/R600/SIISelLowering.cpp b/llvm/lib/Target/R600/SIISelLowering.cpp
index 0be0d034371..a53e0b9ae37 100644
--- a/llvm/lib/Target/R600/SIISelLowering.cpp
+++ b/llvm/lib/Target/R600/SIISelLowering.cpp
@@ -673,43 +673,67 @@ bool SITargetLowering::foldImm(SDValue &Operand, int32_t &Immediate,
return false;
}
+const TargetRegisterClass *SITargetLowering::getRegClassForNode(
+ SelectionDAG &DAG, const SDValue &Op) const {
+ const SIInstrInfo *TII =
+ static_cast<const SIInstrInfo*>(getTargetMachine().getInstrInfo());
+ const SIRegisterInfo &TRI = TII->getRegisterInfo();
+
+ if (!Op->isMachineOpcode()) {
+ switch(Op->getOpcode()) {
+ case ISD::CopyFromReg: {
+ MachineRegisterInfo &MRI = DAG.getMachineFunction().getRegInfo();
+ unsigned Reg = cast<RegisterSDNode>(Op->getOperand(1))->getReg();
+ if (TargetRegisterInfo::isVirtualRegister(Reg)) {
+ return MRI.getRegClass(Reg);
+ }
+ return TRI.getPhysRegClass(Reg);
+ }
+ default: return NULL;
+ }
+ }
+ const MCInstrDesc &Desc = TII->get(Op->getMachineOpcode());
+ int OpClassID = Desc.OpInfo[Op.getResNo()].RegClass;
+ if (OpClassID != -1) {
+ return TRI.getRegClass(OpClassID);
+ }
+ switch(Op.getMachineOpcode()) {
+ case AMDGPU::COPY_TO_REGCLASS:
+ // Operand 1 is the register class id for COPY_TO_REGCLASS instructions.
+ OpClassID = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
+
+ // 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) {
+ return getRegClassForNode(DAG, Op.getOperand(0));
+ }
+ return TRI.getRegClass(OpClassID);
+ case AMDGPU::EXTRACT_SUBREG: {
+ int SubIdx = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
+ const TargetRegisterClass *SuperClass =
+ getRegClassForNode(DAG, Op.getOperand(0));
+ return TRI.getSubClassWithSubReg(SuperClass, SubIdx);
+ }
+ case AMDGPU::REG_SEQUENCE:
+ // Operand 0 is the register class id for REG_SEQUENCE instructions.
+ return TRI.getRegClass(
+ cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue());
+ default:
+ return getRegClassFor(Op.getSimpleValueType());
+ }
+}
+
/// \brief Does "Op" fit into register class "RegClass" ?
bool SITargetLowering::fitsRegClass(SelectionDAG &DAG, const SDValue &Op,
unsigned RegClass) const {
-
- MachineRegisterInfo &MRI = DAG.getMachineFunction().getRegInfo();
- SDNode *Node = Op.getNode();
-
- const TargetRegisterClass *OpClass;
const TargetRegisterInfo *TRI = getTargetMachine().getRegisterInfo();
- if (MachineSDNode *MN = dyn_cast<MachineSDNode>(Node)) {
- const SIInstrInfo *TII =
- static_cast<const SIInstrInfo*>(getTargetMachine().getInstrInfo());
- const MCInstrDesc &Desc = TII->get(MN->getMachineOpcode());
- int OpClassID = Desc.OpInfo[Op.getResNo()].RegClass;
- if (OpClassID == -1) {
- switch (MN->getMachineOpcode()) {
- case AMDGPU::REG_SEQUENCE:
- // Operand 0 is the register class id for REG_SEQUENCE instructions.
- OpClass = TRI->getRegClass(
- cast<ConstantSDNode>(MN->getOperand(0))->getZExtValue());
- break;
- default:
- OpClass = getRegClassFor(Op.getSimpleValueType());
- break;
- }
- } else {
- OpClass = TRI->getRegClass(OpClassID);
- }
-
- } else if (Node->getOpcode() == ISD::CopyFromReg) {
- RegisterSDNode *Reg = cast<RegisterSDNode>(Node->getOperand(1).getNode());
- OpClass = MRI.getRegClass(Reg->getReg());
-
- } else
+ const TargetRegisterClass *RC = getRegClassForNode(DAG, Op);
+ if (!RC) {
return false;
-
- return TRI->getRegClass(RegClass)->hasSubClassEq(OpClass);
+ }
+ return TRI->getRegClass(RegClass)->hasSubClassEq(RC);
}
/// \brief Make sure that we don't exeed the number of allowed scalars
diff --git a/llvm/lib/Target/R600/SIISelLowering.h b/llvm/lib/Target/R600/SIISelLowering.h
index 08c1d175a59..b4202c475d4 100644
--- a/llvm/lib/Target/R600/SIISelLowering.h
+++ b/llvm/lib/Target/R600/SIISelLowering.h
@@ -30,6 +30,8 @@ class SITargetLowering : public AMDGPUTargetLowering {
bool foldImm(SDValue &Operand, int32_t &Immediate,
bool &ScalarSlotUsed) const;
+ const TargetRegisterClass *getRegClassForNode(SelectionDAG &DAG,
+ const SDValue &Op) const;
bool fitsRegClass(SelectionDAG &DAG, const SDValue &Op,
unsigned RegClass) const;
void ensureSRegLimit(SelectionDAG &DAG, SDValue &Operand,
diff --git a/llvm/lib/Target/R600/SIRegisterInfo.cpp b/llvm/lib/Target/R600/SIRegisterInfo.cpp
index ddfc54e7b03..50fd4c7ed56 100644
--- a/llvm/lib/Target/R600/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/R600/SIRegisterInfo.cpp
@@ -49,3 +49,24 @@ const TargetRegisterClass * SIRegisterInfo::getCFGStructurizerRegClass(
case MVT::i32: return &AMDGPU::VReg_32RegClass;
}
}
+
+const TargetRegisterClass *SIRegisterInfo::getPhysRegClass(unsigned Reg) const {
+ assert(!TargetRegisterInfo::isVirtualRegister(Reg));
+
+ const TargetRegisterClass *BaseClasses[] = {
+ &AMDGPU::VReg_32RegClass,
+ &AMDGPU::SReg_32RegClass,
+ &AMDGPU::VReg_64RegClass,
+ &AMDGPU::SReg_64RegClass,
+ &AMDGPU::SReg_128RegClass,
+ &AMDGPU::SReg_256RegClass
+ };
+
+ for (unsigned i = 0, e = sizeof(BaseClasses) /
+ sizeof(const TargetRegisterClass*); i != e; ++i) {
+ if (BaseClasses[i]->contains(Reg)) {
+ return BaseClasses[i];
+ }
+ }
+ return NULL;
+}
diff --git a/llvm/lib/Target/R600/SIRegisterInfo.h b/llvm/lib/Target/R600/SIRegisterInfo.h
index c322f94914c..d0df4f9de60 100644
--- a/llvm/lib/Target/R600/SIRegisterInfo.h
+++ b/llvm/lib/Target/R600/SIRegisterInfo.h
@@ -41,6 +41,10 @@ struct SIRegisterInfo : public AMDGPURegisterInfo {
/// \brief get the register class of the specified type to use in the
/// CFGStructurizer
virtual const TargetRegisterClass * getCFGStructurizerRegClass(MVT VT) const;
+
+ /// \brief Return the 'base' register class for this register.
+ /// e.g. SGPR0 => SReg_32, VGPR => VReg_32 SGPR0_SGPR1 -> SReg_32, etc.
+ const TargetRegisterClass *getPhysRegClass(unsigned Reg) const;
};
} // End namespace llvm
OpenPOWER on IntegriCloud