/// Select - Select instructions not customized! Used for
/// expanded, promoted and normal instructions.
-SDNode *NVPTXDAGToDAGISel::SelectImpl(SDNode *N) {
+void NVPTXDAGToDAGISel::Select(SDNode *N) {
if (N->isMachineOpcode()) {
N->setNodeId(-1);
- return nullptr; // Already selected.
+ return; // Already selected.
}
- SDNode *ResNode = nullptr;
switch (N->getOpcode()) {
case ISD::LOAD:
- ResNode = SelectLoad(N);
+ if (tryLoad(N))
+ return;
break;
case ISD::STORE:
- ResNode = SelectStore(N);
+ if (tryStore(N))
+ return;
break;
case NVPTXISD::LoadV2:
case NVPTXISD::LoadV4:
- ResNode = SelectLoadVector(N);
+ if (tryLoadVector(N))
+ return;
break;
case NVPTXISD::LDGV2:
case NVPTXISD::LDGV4:
case NVPTXISD::LDUV2:
case NVPTXISD::LDUV4:
- ResNode = SelectLDGLDU(N);
+ if (tryLDGLDU(N))
+ return;
break;
case NVPTXISD::StoreV2:
case NVPTXISD::StoreV4:
- ResNode = SelectStoreVector(N);
+ if (tryStoreVector(N))
+ return;
break;
case NVPTXISD::LoadParam:
case NVPTXISD::LoadParamV2:
case NVPTXISD::LoadParamV4:
- ResNode = SelectLoadParam(N);
+ if (tryLoadParam(N))
+ return;
break;
case NVPTXISD::StoreRetval:
case NVPTXISD::StoreRetvalV2:
case NVPTXISD::StoreRetvalV4:
- ResNode = SelectStoreRetval(N);
+ if (tryStoreRetval(N))
+ return;
break;
case NVPTXISD::StoreParam:
case NVPTXISD::StoreParamV2:
case NVPTXISD::StoreParamV4:
case NVPTXISD::StoreParamS32:
case NVPTXISD::StoreParamU32:
- ResNode = SelectStoreParam(N);
+ if (tryStoreParam(N))
+ return;
break;
case ISD::INTRINSIC_WO_CHAIN:
- ResNode = SelectIntrinsicNoChain(N);
+ if (tryIntrinsicNoChain(N))
+ return;
break;
case ISD::INTRINSIC_W_CHAIN:
- ResNode = SelectIntrinsicChain(N);
+ if (tryIntrinsicChain(N))
+ return;
break;
case NVPTXISD::Tex1DFloatS32:
case NVPTXISD::Tex1DFloatFloat:
case NVPTXISD::Tld4UnifiedG2DU64Float:
case NVPTXISD::Tld4UnifiedB2DU64Float:
case NVPTXISD::Tld4UnifiedA2DU64Float:
- ResNode = SelectTextureIntrinsic(N);
+ if (tryTextureIntrinsic(N))
+ return;
break;
case NVPTXISD::Suld1DI8Clamp:
case NVPTXISD::Suld1DI16Clamp:
case NVPTXISD::Suld3DV4I8Zero:
case NVPTXISD::Suld3DV4I16Zero:
case NVPTXISD::Suld3DV4I32Zero:
- ResNode = SelectSurfaceIntrinsic(N);
+ if (trySurfaceIntrinsic(N))
+ return;
break;
case ISD::AND:
case ISD::SRA:
case ISD::SRL:
// Try to select BFE
- ResNode = SelectBFE(N);
+ if (tryBFE(N))
+ return;
break;
case ISD::ADDRSPACECAST:
- ResNode = SelectAddrSpaceCast(N);
- break;
+ SelectAddrSpaceCast(N);
+ return;
default:
break;
}
- if (ResNode)
- return ResNode;
- return SelectCode(N);
+ SelectCode(N);
}
-SDNode *NVPTXDAGToDAGISel::SelectIntrinsicChain(SDNode *N) {
+bool NVPTXDAGToDAGISel::tryIntrinsicChain(SDNode *N) {
unsigned IID = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
switch (IID) {
default:
- return NULL;
+ return false;
case Intrinsic::nvvm_ldg_global_f:
case Intrinsic::nvvm_ldg_global_i:
case Intrinsic::nvvm_ldg_global_p:
case Intrinsic::nvvm_ldu_global_f:
case Intrinsic::nvvm_ldu_global_i:
case Intrinsic::nvvm_ldu_global_p:
- return SelectLDGLDU(N);
+ return tryLDGLDU(N);
}
}
return true;
}
-SDNode *NVPTXDAGToDAGISel::SelectIntrinsicNoChain(SDNode *N) {
+bool NVPTXDAGToDAGISel::tryIntrinsicNoChain(SDNode *N) {
unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
switch (IID) {
default:
- return nullptr;
+ return false;
case Intrinsic::nvvm_texsurf_handle_internal:
- return SelectTexSurfHandle(N);
+ SelectTexSurfHandle(N);
+ return true;
}
}
-SDNode *NVPTXDAGToDAGISel::SelectTexSurfHandle(SDNode *N) {
+void NVPTXDAGToDAGISel::SelectTexSurfHandle(SDNode *N) {
// Op 0 is the intrinsic ID
SDValue Wrapper = N->getOperand(1);
SDValue GlobalVal = Wrapper.getOperand(0);
- return CurDAG->getMachineNode(NVPTX::texsurf_handles, SDLoc(N), MVT::i64,
- GlobalVal);
+ ReplaceNode(N, CurDAG->getMachineNode(NVPTX::texsurf_handles, SDLoc(N),
+ MVT::i64, GlobalVal));
}
-SDNode *NVPTXDAGToDAGISel::SelectAddrSpaceCast(SDNode *N) {
+void NVPTXDAGToDAGISel::SelectAddrSpaceCast(SDNode *N) {
SDValue Src = N->getOperand(0);
AddrSpaceCastSDNode *CastN = cast<AddrSpaceCastSDNode>(N);
unsigned SrcAddrSpace = CastN->getSrcAddressSpace();
Opc = TM.is64Bit() ? NVPTX::cvta_local_yes_64 : NVPTX::cvta_local_yes;
break;
}
- return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src);
+ ReplaceNode(N, CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0),
+ Src));
+ return;
} else {
// Generic to specific
if (SrcAddrSpace != 0)
: NVPTX::nvvm_ptr_gen_to_param;
break;
}
- return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src);
+ ReplaceNode(N, CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0),
+ Src));
+ return;
}
}
-SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
+bool NVPTXDAGToDAGISel::tryLoad(SDNode *N) {
SDLoc dl(N);
LoadSDNode *LD = cast<LoadSDNode>(N);
EVT LoadedVT = LD->getMemoryVT();
// do not support pre/post inc/dec
if (LD->isIndexed())
- return nullptr;
+ return false;
if (!LoadedVT.isSimple())
- return nullptr;
+ return false;
// Address Space Setting
unsigned int codeAddrSpace = getCodeAddrSpace(LD);
if (canLowerToLDG(LD, *Subtarget, codeAddrSpace, MF)) {
- return SelectLDGLDU(N);
+ return tryLDGLDU(N);
}
// Volatile Setting
else if (num == 4)
vecType = NVPTX::PTXLdStInstCode::V4;
else
- return nullptr;
+ return false;
}
// Type Setting: fromType + fromTypeWidth
Opcode = NVPTX::LD_f64_avar;
break;
default:
- return nullptr;
+ return false;
}
SDValue Ops[] = { getI32Imm(isVolatile, dl), getI32Imm(codeAddrSpace, dl),
getI32Imm(vecType, dl), getI32Imm(fromType, dl),
Opcode = NVPTX::LD_f64_asi;
break;
default:
- return nullptr;
+ return false;
}
SDValue Ops[] = { getI32Imm(isVolatile, dl), getI32Imm(codeAddrSpace, dl),
getI32Imm(vecType, dl), getI32Imm(fromType, dl),
Opcode = NVPTX::LD_f64_ari_64;
break;
default:
- return nullptr;
+ return false;
}
} else {
switch (TargetVT) {
Opcode = NVPTX::LD_f64_ari;
break;
default:
- return nullptr;
+ return false;
}
}
SDValue Ops[] = { getI32Imm(isVolatile, dl), getI32Imm(codeAddrSpace, dl),
Opcode = NVPTX::LD_f64_areg_64;
break;
default:
- return nullptr;
+ return false;
}
} else {
switch (TargetVT) {
Opcode = NVPTX::LD_f64_areg;
break;
default:
- return nullptr;
+ return false;
}
}
SDValue Ops[] = { getI32Imm(isVolatile, dl), getI32Imm(codeAddrSpace, dl),
NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
}
- if (NVPTXLD) {
- MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
- MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
- cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
- }
+ if (!NVPTXLD)
+ return false;
+
+ MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
+ MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
+ cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
- return NVPTXLD;
+ ReplaceNode(N, NVPTXLD);
+ return true;
}
-SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
+bool NVPTXDAGToDAGISel::tryLoadVector(SDNode *N) {
SDValue Chain = N->getOperand(0);
SDValue Op1 = N->getOperand(1);
EVT LoadedVT = MemSD->getMemoryVT();
if (!LoadedVT.isSimple())
- return nullptr;
+ return false;
// Address Space Setting
unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD);
if (canLowerToLDG(MemSD, *Subtarget, CodeAddrSpace, MF)) {
- return SelectLDGLDU(N);
+ return tryLDGLDU(N);
}
// Volatile Setting
VecType = NVPTX::PTXLdStInstCode::V4;
break;
default:
- return nullptr;
+ return false;
}
EVT EltVT = N->getValueType(0);
if (SelectDirectAddr(Op1, Addr)) {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::LoadV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::LDV_i8_v2_avar;
break;
case NVPTXISD::LoadV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::LDV_i8_v4_avar;
break;
: SelectADDRsi(Op1.getNode(), Op1, Base, Offset)) {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::LoadV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::LDV_i8_v2_asi;
break;
case NVPTXISD::LoadV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::LDV_i8_v4_asi;
break;
if (TM.is64Bit()) {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::LoadV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::LDV_i8_v2_ari_64;
break;
case NVPTXISD::LoadV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::LDV_i8_v4_ari_64;
break;
} else {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::LoadV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::LDV_i8_v2_ari;
break;
case NVPTXISD::LoadV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::LDV_i8_v4_ari;
break;
if (TM.is64Bit()) {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::LoadV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::LDV_i8_v2_areg_64;
break;
case NVPTXISD::LoadV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::LDV_i8_v4_areg_64;
break;
} else {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::LoadV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::LDV_i8_v2_areg;
break;
case NVPTXISD::LoadV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::LDV_i8_v4_areg;
break;
MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
- return LD;
+ ReplaceNode(N, LD);
+ return true;
}
-SDNode *NVPTXDAGToDAGISel::SelectLDGLDU(SDNode *N) {
+bool NVPTXDAGToDAGISel::tryLDGLDU(SDNode *N) {
SDValue Chain = N->getOperand(0);
SDValue Op1;
unsigned IID = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
switch (IID) {
default:
- return NULL;
+ return false;
case Intrinsic::nvvm_ldg_global_f:
case Intrinsic::nvvm_ldg_global_i:
case Intrinsic::nvvm_ldg_global_p:
if (SelectDirectAddr(Op1, Addr)) {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case ISD::INTRINSIC_W_CHAIN:
if (IsLDG) {
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_GLOBAL_i8avar;
break;
} else {
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_GLOBAL_i8avar;
break;
case NVPTXISD::LDGV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_avar;
break;
case NVPTXISD::LDUV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_avar;
break;
case NVPTXISD::LDGV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_avar;
break;
case NVPTXISD::LDUV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_avar;
break;
if (TM.is64Bit()) {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case ISD::LOAD:
case ISD::INTRINSIC_W_CHAIN:
if (IsLDG) {
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_GLOBAL_i8ari64;
break;
} else {
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_GLOBAL_i8ari64;
break;
case NVPTXISD::LDGV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari64;
break;
case NVPTXISD::LDUV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari64;
break;
case NVPTXISD::LDGV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari64;
break;
case NVPTXISD::LDUV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari64;
break;
} else {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case ISD::LOAD:
case ISD::INTRINSIC_W_CHAIN:
if (IsLDG) {
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_GLOBAL_i8ari;
break;
} else {
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_GLOBAL_i8ari;
break;
case NVPTXISD::LDGV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari32;
break;
case NVPTXISD::LDUV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari32;
break;
case NVPTXISD::LDGV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari32;
break;
case NVPTXISD::LDUV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari32;
break;
if (TM.is64Bit()) {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case ISD::LOAD:
case ISD::INTRINSIC_W_CHAIN:
if (IsLDG) {
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_GLOBAL_i8areg64;
break;
} else {
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_GLOBAL_i8areg64;
break;
case NVPTXISD::LDGV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg64;
break;
case NVPTXISD::LDUV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg64;
break;
case NVPTXISD::LDGV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg64;
break;
case NVPTXISD::LDUV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg64;
break;
} else {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case ISD::LOAD:
case ISD::INTRINSIC_W_CHAIN:
if (IsLDG) {
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_GLOBAL_i8areg;
break;
} else {
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_GLOBAL_i8areg;
break;
case NVPTXISD::LDGV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg32;
break;
case NVPTXISD::LDUV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg32;
break;
case NVPTXISD::LDGV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg32;
break;
case NVPTXISD::LDUV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg32;
break;
}
}
- return LD;
+ ReplaceNode(N, LD);
+ return true;
}
-SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
+bool NVPTXDAGToDAGISel::tryStore(SDNode *N) {
SDLoc dl(N);
StoreSDNode *ST = cast<StoreSDNode>(N);
EVT StoreVT = ST->getMemoryVT();
// do not support pre/post inc/dec
if (ST->isIndexed())
- return nullptr;
+ return false;
if (!StoreVT.isSimple())
- return nullptr;
+ return false;
// Address Space Setting
unsigned int codeAddrSpace = getCodeAddrSpace(ST);
else if (num == 4)
vecType = NVPTX::PTXLdStInstCode::V4;
else
- return nullptr;
+ return false;
}
// Type Setting: toType + toTypeWidth
Opcode = NVPTX::ST_f64_avar;
break;
default:
- return nullptr;
+ return false;
}
SDValue Ops[] = { N1, getI32Imm(isVolatile, dl),
getI32Imm(codeAddrSpace, dl), getI32Imm(vecType, dl),
Opcode = NVPTX::ST_f64_asi;
break;
default:
- return nullptr;
+ return false;
}
SDValue Ops[] = { N1, getI32Imm(isVolatile, dl),
getI32Imm(codeAddrSpace, dl), getI32Imm(vecType, dl),
Opcode = NVPTX::ST_f64_ari_64;
break;
default:
- return nullptr;
+ return false;
}
} else {
switch (SourceVT) {
Opcode = NVPTX::ST_f64_ari;
break;
default:
- return nullptr;
+ return false;
}
}
SDValue Ops[] = { N1, getI32Imm(isVolatile, dl),
Opcode = NVPTX::ST_f64_areg_64;
break;
default:
- return nullptr;
+ return false;
}
} else {
switch (SourceVT) {
Opcode = NVPTX::ST_f64_areg;
break;
default:
- return nullptr;
+ return false;
}
}
SDValue Ops[] = { N1, getI32Imm(isVolatile, dl),
NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
}
- if (NVPTXST) {
- MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
- MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
- cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
- }
+ if (!NVPTXST)
+ return false;
- return NVPTXST;
+ MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
+ MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
+ cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
+ ReplaceNode(N, NVPTXST);
+ return true;
}
-SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
+bool NVPTXDAGToDAGISel::tryStoreVector(SDNode *N) {
SDValue Chain = N->getOperand(0);
SDValue Op1 = N->getOperand(1);
SDValue Addr, Offset, Base;
N2 = N->getOperand(5);
break;
default:
- return nullptr;
+ return false;
}
StOps.push_back(getI32Imm(IsVolatile, DL));
if (SelectDirectAddr(N2, Addr)) {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::StoreV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::STV_i8_v2_avar;
break;
case NVPTXISD::StoreV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::STV_i8_v4_avar;
break;
: SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::StoreV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::STV_i8_v2_asi;
break;
case NVPTXISD::StoreV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::STV_i8_v4_asi;
break;
if (TM.is64Bit()) {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::StoreV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::STV_i8_v2_ari_64;
break;
case NVPTXISD::StoreV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::STV_i8_v4_ari_64;
break;
} else {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::StoreV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::STV_i8_v2_ari;
break;
case NVPTXISD::StoreV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::STV_i8_v4_ari;
break;
if (TM.is64Bit()) {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::StoreV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::STV_i8_v2_areg_64;
break;
case NVPTXISD::StoreV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::STV_i8_v4_areg_64;
break;
} else {
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::StoreV2:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::STV_i8_v2_areg;
break;
case NVPTXISD::StoreV4:
switch (EltVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i8:
Opcode = NVPTX::STV_i8_v4_areg;
break;
MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
- return ST;
+ ReplaceNode(N, ST);
+ return true;
}
-SDNode *NVPTXDAGToDAGISel::SelectLoadParam(SDNode *Node) {
+bool NVPTXDAGToDAGISel::tryLoadParam(SDNode *Node) {
SDValue Chain = Node->getOperand(0);
SDValue Offset = Node->getOperand(2);
SDValue Flag = Node->getOperand(3);
unsigned VecSize;
switch (Node->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::LoadParam:
VecSize = 1;
break;
switch (VecSize) {
default:
- return nullptr;
+ return false;
case 1:
switch (MemVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i1:
Opc = NVPTX::LoadParamMemI8;
break;
case 2:
switch (MemVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i1:
Opc = NVPTX::LoadParamMemV2I8;
break;
case 4:
switch (MemVT.getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i1:
Opc = NVPTX::LoadParamMemV4I8;
break;
Ops.push_back(Chain);
Ops.push_back(Flag);
- return CurDAG->getMachineNode(Opc, DL, VTs, Ops);
+ ReplaceNode(Node, CurDAG->getMachineNode(Opc, DL, VTs, Ops));
+ return true;
}
-SDNode *NVPTXDAGToDAGISel::SelectStoreRetval(SDNode *N) {
+bool NVPTXDAGToDAGISel::tryStoreRetval(SDNode *N) {
SDLoc DL(N);
SDValue Chain = N->getOperand(0);
SDValue Offset = N->getOperand(1);
unsigned NumElts = 1;
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::StoreRetval:
NumElts = 1;
break;
unsigned Opcode = 0;
switch (NumElts) {
default:
- return nullptr;
+ return false;
case 1:
switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i1:
Opcode = NVPTX::StoreRetvalI8;
break;
case 2:
switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i1:
Opcode = NVPTX::StoreRetvalV2I8;
break;
case 4:
switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i1:
Opcode = NVPTX::StoreRetvalV4I8;
break;
MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
- return Ret;
+ ReplaceNode(N, Ret);
+ return true;
}
-SDNode *NVPTXDAGToDAGISel::SelectStoreParam(SDNode *N) {
+bool NVPTXDAGToDAGISel::tryStoreParam(SDNode *N) {
SDLoc DL(N);
SDValue Chain = N->getOperand(0);
SDValue Param = N->getOperand(1);
unsigned NumElts = 1;
switch (N->getOpcode()) {
default:
- return nullptr;
+ return false;
case NVPTXISD::StoreParamU32:
case NVPTXISD::StoreParamS32:
case NVPTXISD::StoreParam:
default:
switch (NumElts) {
default:
- return nullptr;
+ return false;
case 1:
switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i1:
Opcode = NVPTX::StoreParamI8;
break;
case 2:
switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i1:
Opcode = NVPTX::StoreParamV2I8;
break;
case 4:
switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
default:
- return nullptr;
+ return false;
case MVT::i1:
Opcode = NVPTX::StoreParamV4I8;
break;
MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
- return Ret;
+ ReplaceNode(N, Ret);
+ return true;
}
-SDNode *NVPTXDAGToDAGISel::SelectTextureIntrinsic(SDNode *N) {
+bool NVPTXDAGToDAGISel::tryTextureIntrinsic(SDNode *N) {
SDValue Chain = N->getOperand(0);
- SDNode *Ret = nullptr;
unsigned Opc = 0;
SmallVector<SDValue, 8> Ops;
switch (N->getOpcode()) {
- default: return nullptr;
+ default: return false;
case NVPTXISD::Tex1DFloatS32:
Opc = NVPTX::TEX_1D_F32_S32;
break;
}
Ops.push_back(Chain);
- Ret = CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
- return Ret;
+ ReplaceNode(N, CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops));
+ return true;
}
-SDNode *NVPTXDAGToDAGISel::SelectSurfaceIntrinsic(SDNode *N) {
+bool NVPTXDAGToDAGISel::trySurfaceIntrinsic(SDNode *N) {
SDValue Chain = N->getOperand(0);
SDValue TexHandle = N->getOperand(1);
- SDNode *Ret = nullptr;
unsigned Opc = 0;
SmallVector<SDValue, 8> Ops;
switch (N->getOpcode()) {
- default: return nullptr;
+ default: return false;
case NVPTXISD::Suld1DI8Clamp:
Opc = NVPTX::SULD_1D_I8_CLAMP;
Ops.push_back(TexHandle);
Ops.push_back(Chain);
break;
}
- Ret = CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
- return Ret;
+ ReplaceNode(N, CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops));
+ return true;
}
/// SelectBFE - Look for instruction sequences that can be made more efficient
/// by using the 'bfe' (bit-field extract) PTX instruction
-SDNode *NVPTXDAGToDAGISel::SelectBFE(SDNode *N) {
+bool NVPTXDAGToDAGISel::tryBFE(SDNode *N) {
SDLoc DL(N);
SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(RHS);
if (!Mask) {
// We need a constant mask on the RHS of the AND
- return NULL;
+ return false;
}
// Extract the mask bits
// We *could* handle shifted masks here, but doing so would require an
// 'and' operation to fix up the low-order bits so we would trade
// shr+and for bfe+and, which has the same throughput
- return NULL;
+ return false;
}
// How many bits are in our mask?
// Do not handle the case where bits have been shifted in. In theory
// we could handle this, but the cost is likely higher than just
// emitting the srl/and pair.
- return NULL;
+ return false;
}
Start = CurDAG->getTargetConstant(StartVal, DL, MVT::i32);
} else {
// was found) is not constant. We could handle this case, but it would
// require run-time logic that would be more expensive than just
// emitting the srl/and pair.
- return NULL;
+ return false;
}
} else {
// Do not handle the case where the LHS of the and is not a shift. While
// it would be trivial to handle this case, it would just transform
// 'and' -> 'bfe', but 'and' has higher-throughput.
- return NULL;
+ return false;
}
} else if (N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA) {
if (LHS->getOpcode() == ISD::AND) {
ConstantSDNode *ShiftCnst = dyn_cast<ConstantSDNode>(RHS);
if (!ShiftCnst) {
// Shift amount must be constant
- return NULL;
+ return false;
}
uint64_t ShiftAmt = ShiftCnst->getZExtValue();
ConstantSDNode *MaskCnst = dyn_cast<ConstantSDNode>(AndRHS);
if (!MaskCnst) {
// Mask must be constant
- return NULL;
+ return false;
}
uint64_t MaskVal = MaskCnst->getZExtValue();
NumBits = NumZeros + NumOnes - ShiftAmt;
} else {
// This is not a mask we can handle
- return NULL;
+ return false;
}
if (ShiftAmt < NumZeros) {
// Handling this case would require extra logic that would make this
// transformation non-profitable
- return NULL;
+ return false;
}
Val = AndLHS;
ConstantSDNode *ShlCnst = dyn_cast<ConstantSDNode>(ShlRHS);
if (!ShlCnst) {
// Shift amount must be constant
- return NULL;
+ return false;
}
uint64_t InnerShiftAmt = ShlCnst->getZExtValue();
ConstantSDNode *ShrCnst = dyn_cast<ConstantSDNode>(ShrRHS);
if (!ShrCnst) {
// Shift amount must be constant
- return NULL;
+ return false;
}
uint64_t OuterShiftAmt = ShrCnst->getZExtValue();
// To avoid extra codegen and be profitable, we need Outer >= Inner
if (OuterShiftAmt < InnerShiftAmt) {
- return NULL;
+ return false;
}
// If the outer shift is more than the type size, we have no bitfield to
// extract (since we also check that the inner shift is <= the outer shift
// then this also implies that the inner shift is < the type size)
if (OuterShiftAmt >= Val.getValueType().getSizeInBits()) {
- return NULL;
+ return false;
}
Start =
}
} else {
// No can do...
- return NULL;
+ return false;
}
} else {
// No can do...
- return NULL;
+ return false;
}
}
} else {
// We cannot handle this type
- return NULL;
+ return false;
}
SDValue Ops[] = {
Val, Start, Len
};
- return CurDAG->getMachineNode(Opc, DL, N->getVTList(), Ops);
+ ReplaceNode(N, CurDAG->getMachineNode(Opc, DL, N->getVTList(), Ops));
+ return true;
}
// SelectDirectAddr - Match a direct address for DAG.