forked from OSchip/llvm-project
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
This commit is contained in:
parent
16a9a205c8
commit
df94dc3917
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -1582,6 +1582,16 @@ def : Pat <
|
|||
/********** Immediate Patterns **********/
|
||||
/********** ================== **********/
|
||||
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue