diff options
| author | Tom Stellard <thomas.stellard@amd.com> | 2013-08-14 23:24:24 +0000 |
|---|---|---|
| committer | Tom Stellard <thomas.stellard@amd.com> | 2013-08-14 23:24:24 +0000 |
| commit | df94dc391724b0f9d94d8d2045757a320ec4d414 (patch) | |
| tree | 1c09ca94c14a55304064530cfca7bdc013f0ff9d /llvm | |
| parent | 16a9a205c8fecb4ed0c37b0f6dfc4ca5f0c4233f (diff) | |
| download | bcm5719-llvm-df94dc391724b0f9d94d8d2045757a320ec4d414.tar.gz bcm5719-llvm-df94dc391724b0f9d94d8d2045757a320ec4d414.zip | |
R600/SI: Choose the correct MOV instruction for copying immediates
The instruction selector will now try to infer the destination register
so it can decided whether to use V_MOV_B32 or S_MOV_B32 when copying
immediates.
llvm-svn: 188426
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp | 29 | ||||
| -rw-r--r-- | llvm/lib/Target/R600/SIInstrInfo.td | 16 | ||||
| -rw-r--r-- | llvm/lib/Target/R600/SIInstructions.td | 10 | ||||
| -rw-r--r-- | llvm/lib/Target/R600/SIRegisterInfo.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/Target/R600/SIRegisterInfo.h | 3 |
5 files changed, 69 insertions, 0 deletions
diff --git a/llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp index f222901b8fc..d339b09b9e1 100644 --- a/llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp @@ -77,6 +77,7 @@ private: bool isLocalLoad(const LoadSDNode *N) const; bool isRegionLoad(const LoadSDNode *N) const; + const TargetRegisterClass *getOperandRegClass(SDNode *N, unsigned OpNo) const; bool SelectGlobalValueConstantOffset(SDValue Addr, SDValue& IntPtr); bool SelectGlobalValueVariableOffset(SDValue Addr, SDValue &BaseReg, SDValue& Offset); @@ -102,6 +103,34 @@ AMDGPUDAGToDAGISel::AMDGPUDAGToDAGISel(TargetMachine &TM) AMDGPUDAGToDAGISel::~AMDGPUDAGToDAGISel() { } +/// \brief Determine the register class for \p OpNo +/// \returns The register class of the virtual register that will be used for +/// the given operand number \OpNo or NULL if the register class cannot be +/// determined. +const TargetRegisterClass *AMDGPUDAGToDAGISel::getOperandRegClass(SDNode *N, + unsigned OpNo) const { + if (!N->isMachineOpcode()) { + return NULL; + } + switch (N->getMachineOpcode()) { + default: { + const MCInstrDesc &Desc = TM.getInstrInfo()->get(N->getMachineOpcode()); + int RegClass = Desc.OpInfo[Desc.getNumDefs() + OpNo].RegClass; + if (RegClass == -1) { + return NULL; + } + return TM.getRegisterInfo()->getRegClass(RegClass); + } + case AMDGPU::REG_SEQUENCE: { + const TargetRegisterClass *SuperRC = TM.getRegisterInfo()->getRegClass( + cast<ConstantSDNode>(N->getOperand(0))->getZExtValue()); + unsigned SubRegIdx = + dyn_cast<ConstantSDNode>(N->getOperand(OpNo + 1))->getZExtValue(); + return TM.getRegisterInfo()->getSubClassWithSubReg(SuperRC, SubRegIdx); + } + } +} + SDValue AMDGPUDAGToDAGISel::getSmallIPtrImm(unsigned int Imm) { return CurDAG->getTargetConstant(Imm, MVT::i32); } diff --git a/llvm/lib/Target/R600/SIInstrInfo.td b/llvm/lib/Target/R600/SIInstrInfo.td index 71d20eaa0fb..df6d99410d9 100644 --- a/llvm/lib/Target/R600/SIInstrInfo.td +++ b/llvm/lib/Target/R600/SIInstrInfo.td @@ -58,6 +58,22 @@ class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{ (*(const SITargetLowering *)getTargetLowering()).analyzeImmediate(N) == 0; }]>; +class SGPRImm <dag frag> : PatLeaf<frag, [{ + if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() < + AMDGPUSubtarget::SOUTHERN_ISLANDS) { + return false; + } + const SIRegisterInfo *SIRI = + static_cast<const SIRegisterInfo*>(TM.getRegisterInfo()); + for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end(); + U != E; ++U) { + if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) { + return true; + } + } + return false; +}]>; + //===----------------------------------------------------------------------===// // SI assembler operands //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/R600/SIInstructions.td b/llvm/lib/Target/R600/SIInstructions.td index 5fbd68f3e7c..b20d7c0533a 100644 --- a/llvm/lib/Target/R600/SIInstructions.td +++ b/llvm/lib/Target/R600/SIInstructions.td @@ -1583,6 +1583,16 @@ def : Pat < /********** ================== **********/ def : Pat < + (SGPRImm<(i32 imm)>:$imm), + (S_MOV_B32 imm:$imm) +>; + +def : Pat < + (SGPRImm<(f32 fpimm)>:$imm), + (S_MOV_B32 fpimm:$imm) +>; + +def : Pat < (i32 imm:$imm), (V_MOV_B32_e32 imm:$imm) >; diff --git a/llvm/lib/Target/R600/SIRegisterInfo.cpp b/llvm/lib/Target/R600/SIRegisterInfo.cpp index 50fd4c7ed56..5d12564fe8b 100644 --- a/llvm/lib/Target/R600/SIRegisterInfo.cpp +++ b/llvm/lib/Target/R600/SIRegisterInfo.cpp @@ -70,3 +70,14 @@ const TargetRegisterClass *SIRegisterInfo::getPhysRegClass(unsigned Reg) const { } return NULL; } + +bool SIRegisterInfo::isSGPRClass(const TargetRegisterClass *RC) const { + if (!RC) { + return false; + } + return RC == &AMDGPU::SReg_32RegClass || + RC == &AMDGPU::SReg_64RegClass || + RC == &AMDGPU::SReg_128RegClass || + RC == &AMDGPU::SReg_256RegClass || + RC == &AMDGPU::SReg_512RegClass; +} diff --git a/llvm/lib/Target/R600/SIRegisterInfo.h b/llvm/lib/Target/R600/SIRegisterInfo.h index d0df4f9de60..ffc57973e05 100644 --- a/llvm/lib/Target/R600/SIRegisterInfo.h +++ b/llvm/lib/Target/R600/SIRegisterInfo.h @@ -45,6 +45,9 @@ struct SIRegisterInfo : public AMDGPURegisterInfo { /// \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; + + /// \returns true if this class contains only SGPR registers + bool isSGPRClass(const TargetRegisterClass *RC) const; }; } // End namespace llvm |

