44 virtual ~AMDGPUDAGToDAGISel();
47 virtual const char *getPassName()
const;
48 virtual void PostprocessISelDAG();
51 inline SDValue getSmallIPtrImm(
unsigned Imm);
54 bool FoldOperands(
unsigned,
const R600InstrInfo *, std::vector<SDValue> &);
55 bool FoldDotOperands(
unsigned,
const R600InstrInfo *, std::vector<SDValue> &);
73 bool isConstantLoad(
const LoadSDNode *
N,
int cbID)
const;
81 bool SelectGlobalValueConstantOffset(
SDValue Addr,
SDValue& IntPtr);
82 bool SelectGlobalValueVariableOffset(
SDValue Addr,
88 #include "AMDGPUGenDAGISel.inc"
96 return new AMDGPUDAGToDAGISel(TM);
103 AMDGPUDAGToDAGISel::~AMDGPUDAGToDAGISel() {
111 unsigned OpNo)
const {
122 if (RegClass == -1) {
125 return TM.getRegisterInfo()->getRegClass(RegClass);
129 cast<ConstantSDNode>(N->
getOperand(0))->getZExtValue());
132 return TM.getRegisterInfo()->getSubClassWithSubReg(SuperRC, SubRegIdx);
137 SDValue AMDGPUDAGToDAGISel::getSmallIPtrImm(
unsigned int Imm) {
138 return CurDAG->getTargetConstant(Imm, MVT::i32);
141 bool AMDGPUDAGToDAGISel::SelectADDRParam(
146 R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
147 R2 = CurDAG->getTargetConstant(0, MVT::i32);
150 R2 = CurDAG->getTargetConstant(0, MVT::i32);
157 R2 = CurDAG->getTargetConstant(0, MVT::i32);
167 return SelectADDRParam(Addr, R1, R2);
179 R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64);
180 R2 = CurDAG->getTargetConstant(0, MVT::i64);
183 R2 = CurDAG->getTargetConstant(0, MVT::i64);
190 R2 = CurDAG->getTargetConstant(0, MVT::i64);
213 if (ST.
getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS) {
217 if (!U->isMachineOpcode()) {
228 switch(NumVectorElts) {
229 case 1: RegClassID = UseVReg ? AMDGPU::VReg_32RegClassID :
230 AMDGPU::SReg_32RegClassID;
232 case 2: RegClassID = UseVReg ? AMDGPU::VReg_64RegClassID :
233 AMDGPU::SReg_64RegClassID;
235 case 4: RegClassID = UseVReg ? AMDGPU::VReg_128RegClassID :
236 AMDGPU::SReg_128RegClassID;
238 case 8: RegClassID = UseVReg ? AMDGPU::VReg_256RegClassID :
239 AMDGPU::SReg_256RegClassID;
241 case 16: RegClassID = UseVReg ? AMDGPU::VReg_512RegClassID :
242 AMDGPU::SReg_512RegClassID;
251 switch(NumVectorElts) {
252 case 2: RegClassID = AMDGPU::R600_Reg64RegClassID;
break;
253 case 4: RegClassID = AMDGPU::R600_Reg128RegClassID;
break;
258 SDValue RegClass = CurDAG->getTargetConstant(RegClassID, MVT::i32);
260 if (NumVectorElts == 1) {
266 assert(NumVectorElts <= 16 &&
"Vectors with more than 16 elements not "
271 SDValue RegSeqArgs[16 * 2 + 1];
273 RegSeqArgs[0] = CurDAG->getTargetConstant(RegClassID, MVT::i32);
274 bool IsRegSeq =
true;
277 if (dyn_cast<RegisterSDNode>(N->
getOperand(i))) {
282 RegSeqArgs[1 + (2 * i) + 1] =
283 CurDAG->getTargetConstant(TRI->getSubRegFromChannel(i), MVT::i32);
293 if (ST.
getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) {
297 RC = CurDAG->getTargetConstant(AMDGPU::SReg_128RegClassID, MVT::i32);
298 SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0_sub1, MVT::i32);
299 SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub2_sub3, MVT::i32);
301 RC = CurDAG->getTargetConstant(AMDGPU::VSrc_64RegClassID, MVT::i32);
302 SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0, MVT::i32);
303 SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub1, MVT::i32);
318 SelectADDRIndirect(N->
getOperand(1), Addr, Offset);
322 CurDAG->getTargetConstant(0, MVT::i32),
325 return CurDAG->getMachineNode(AMDGPU::SI_RegisterLoad,
SDLoc(N),
326 CurDAG->getVTList(MVT::i32, MVT::i64, MVT::Other),
334 SelectADDRIndirect(N->
getOperand(2), Addr, Offset);
339 CurDAG->getTargetConstant(0, MVT::i32),
342 return CurDAG->getMachineNode(AMDGPU::SI_RegisterStorePseudo,
SDLoc(N),
343 CurDAG->getVTList(MVT::Other),
347 return SelectCode(N);
359 bool AMDGPUDAGToDAGISel::isGlobalStore(
const StoreSDNode *N) {
363 bool AMDGPUDAGToDAGISel::isPrivateStore(
const StoreSDNode *N) {
369 bool AMDGPUDAGToDAGISel::isLocalStore(
const StoreSDNode *N) {
373 bool AMDGPUDAGToDAGISel::isRegionStore(
const StoreSDNode *N) {
377 bool AMDGPUDAGToDAGISel::isConstantLoad(
const LoadSDNode *N,
int CbId)
const {
384 bool AMDGPUDAGToDAGISel::isGlobalLoad(
const LoadSDNode *N)
const {
387 if (ST.
getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS ||
399 bool AMDGPUDAGToDAGISel::isLocalLoad(
const LoadSDNode *N)
const {
403 bool AMDGPUDAGToDAGISel::isRegionLoad(
const LoadSDNode *N)
const {
407 bool AMDGPUDAGToDAGISel::isCPLoad(
const LoadSDNode *N)
const {
413 if (PSV && PSV == PseudoSourceValue::getConstantPool()) {
421 bool AMDGPUDAGToDAGISel::isPrivateLoad(
const LoadSDNode *N)
const {
425 if (isCPLoad(N) || isConstantLoad(N, -1)) {
440 const char *AMDGPUDAGToDAGISel::getPassName()
const {
441 return "AMDGPU DAG->DAG Pattern Instruction Selection";
453 bool AMDGPUDAGToDAGISel::SelectGlobalValueConstantOffset(
SDValue Addr,
456 IntPtr = CurDAG->getIntPtrConstant(Cst->getZExtValue() / 4,
true);
462 bool AMDGPUDAGToDAGISel::SelectGlobalValueVariableOffset(
SDValue Addr,
464 if (!dyn_cast<ConstantSDNode>(Addr)) {
466 Offset = CurDAG->getIntPtrConstant(0,
true);
472 bool AMDGPUDAGToDAGISel::SelectADDRVTX_READ(
SDValue Addr,
SDValue &Base,
478 &&
isInt<16>(IMMOffset->getZExtValue())) {
481 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32);
484 }
else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr))
485 &&
isInt<16>(IMMOffset->getZExtValue())) {
486 Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
487 SDLoc(CurDAG->getEntryNode()),
488 AMDGPU::ZERO, MVT::i32);
489 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32);
495 Offset = CurDAG->getTargetConstant(0, MVT::i32);
499 bool AMDGPUDAGToDAGISel::SelectADDRIndirect(
SDValue Addr,
SDValue &Base,
503 if ((C = dyn_cast<ConstantSDNode>(Addr))) {
504 Base = CurDAG->getRegister(AMDGPU::INDIRECT_BASE_ADDR, MVT::i32);
505 Offset = CurDAG->getTargetConstant(C->
getZExtValue(), MVT::i32);
507 (C = dyn_cast<ConstantSDNode>(Addr.
getOperand(1)))) {
509 Offset = CurDAG->getTargetConstant(C->
getZExtValue(), MVT::i32);
512 Offset = CurDAG->getTargetConstant(0, MVT::i32);
520 APInt KnownZero, KnownOne;
524 CurDAG->ReplaceAllUsesWith(Op, TLO.New);
525 CurDAG->RepositionNode(Op.
getNode(), TLO.New.getNode());
526 return SimplifyI24(TLO.New);
536 if (CurDAG->ComputeNumSignBits(Op) == 9) {
537 I24 = SimplifyI24(Op);
546 CurDAG->ComputeMaskedBits(Op, KnownZero, KnownOne);
552 if ((KnownZero &
APInt(KnownZero.
getBitWidth(), 0xFF000000)) == 0xFF000000 ||
555 U24 = SimplifyI24(Op);
561 void AMDGPUDAGToDAGISel::PostprocessISelDAG() {
564 bool IsModified =
false;
569 E = CurDAG->allnodes_end();
I != E; ++
I) {
578 if (ResNode != Node) {
579 ReplaceUses(Node, ResNode);
583 CurDAG->RemoveDeadNodes();
584 }
while (IsModified);
Interface definition for R600InstrInfo.
Address space for local memory.
SDVTList getVTList() const
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions. Register definitions always occur...
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
enum Generation getGeneration() const
unsigned getOpcode() const
unsigned getNumOperands() const
const SDValue & getOperand(unsigned Num) const
void setNodeId(int Id)
setNodeId - Set unique node id.
virtual SDNode * PostISelFolding(MachineSDNode *N, SelectionDAG &DAG) const
bool bitsLT(EVT VT) const
bitsLT - Return true if this has less bits than VT.
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask, APInt &KnownZero, APInt &KnownOne, TargetLoweringOpt &TLO, unsigned Depth=0) const
static Type * checkType(Type *Ty)
Address space for global memory (RAT0, VTX0).
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
EVT getValueType(unsigned ResNo) const
Address space for indirect addressible parameter memory (VTX1)
EVT getVectorElementType() const
TargetRegisterInfo interface that is implemented by all hw codegen targets.
Address space for direct addressible parameter memory (CONST0)
EVT getMemoryVT() const
getMemoryVT - Return the type of the in-memory value.
SDNode * getNode() const
get the SDNode which holds the desired result
bool isParamLoad(const MachineInstr *MI)
const SDValue & getOperand(unsigned i) const
FunctionPass * createAMDGPUISelDag(TargetMachine &tm)
This pass converts a legalized DAG into a AMDGPU-specific.
SI DAG Lowering interface definition.
Address space for region memory.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned getOpcode() const
use_iterator use_begin() const
bool bitsEq(EVT VT) const
bitsEq - Return true if this has the same number of bits as VT.
bool isEXTLoad(const SDNode *N)
static bool FoldOperand(SDNode *ParentNode, unsigned SrcIdx, SDValue &Src, SDValue &Neg, SDValue &Abs, SDValue &Sel, SDValue &Imm, SelectionDAG &DAG)
Interface definition of the TargetLowering class that is common to all AMD GPUs.
bool isSGPRClass(const TargetRegisterClass *RC) const
MachineMemOperand * getMemOperand() const
Class for arbitrary precision integers.
const Value * getValue() const
ANY_EXTEND - Used for integer types. The high bits are undefined.
Address space for private memory.
Contains the definition of a TargetInstrInfo class that is common to all AMD GPUs.
unsigned getAddressSpace() const
getAddressSpace - Return the address space for the associated pointer
const Value * getSrcValue() const
Returns the SrcValue and offset that describes the location of the access.
bool isInt< 16 >(int64_t x)
LLVM Value Representation.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction. Note that variadic (isVari...
const MCOperandInfo * OpInfo
Address space for constant memory.
bool isMachineOpcode() const
unsigned getMachineOpcode() const
uint64_t getZExtValue() const
unsigned getVectorNumElements() const