diff options
Diffstat (limited to 'contrib/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp | 183 |
1 files changed, 102 insertions, 81 deletions
diff --git a/contrib/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp b/contrib/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp index b75cf40..7663696 100644 --- a/contrib/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp +++ b/contrib/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp @@ -124,6 +124,10 @@ NVPTXTargetLowering::NVPTXTargetLowering(const NVPTXTargetMachine &TM, // condition branches. setJumpIsExpensive(true); + // Wide divides are _very_ slow. Try to reduce the width of the divide if + // possible. + addBypassSlowDiv(64, 32); + // By default, use the Source scheduling if (sched4reg) setSchedulingPreference(Sched::RegPressure); @@ -275,6 +279,7 @@ NVPTXTargetLowering::NVPTXTargetLowering(const NVPTXTargetMachine &TM, setTargetDAGCombine(ISD::FADD); setTargetDAGCombine(ISD::MUL); setTargetDAGCombine(ISD::SHL); + setTargetDAGCombine(ISD::SELECT); // Now deduce the information based on the above mentioned // actions @@ -910,7 +915,7 @@ std::string NVPTXTargetLowering::getPrototype( O << "("; if (retTy->isFloatingPointTy() || retTy->isIntegerTy()) { unsigned size = 0; - if (const IntegerType *ITy = dyn_cast<IntegerType>(retTy)) { + if (auto *ITy = dyn_cast<IntegerType>(retTy)) { size = ITy->getBitWidth(); if (size < 32) size = 32; @@ -981,7 +986,7 @@ std::string NVPTXTargetLowering::getPrototype( O << "_"; continue; } - const PointerType *PTy = dyn_cast<PointerType>(Ty); + auto *PTy = dyn_cast<PointerType>(Ty); assert(PTy && "Param with byval attribute should be a pointer type"); Type *ETy = PTy->getElementType(); @@ -1318,7 +1323,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // struct or vector SmallVector<EVT, 16> vtparts; SmallVector<uint64_t, 16> Offsets; - const PointerType *PTy = dyn_cast<PointerType>(Args[i].Ty); + auto *PTy = dyn_cast<PointerType>(Args[i].Ty); assert(PTy && "Type of a byval parameter should be pointer"); ComputePTXValueVTs(*this, DAG.getDataLayout(), PTy->getElementType(), vtparts, &Offsets, 0); @@ -2007,15 +2012,6 @@ SDValue NVPTXTargetLowering::LowerSTOREi1(SDValue Op, SelectionDAG &DAG) const { return Result; } -SDValue NVPTXTargetLowering::getExtSymb(SelectionDAG &DAG, const char *inname, - int idx, EVT v) const { - std::string *name = nvTM->getManagedStrPool()->getManagedString(inname); - std::stringstream suffix; - suffix << idx; - *name += suffix.str(); - return DAG.getTargetExternalSymbol(name->c_str(), v); -} - SDValue NVPTXTargetLowering::getParamSymbol(SelectionDAG &DAG, int idx, EVT v) const { std::string ParamSym; @@ -2029,10 +2025,6 @@ NVPTXTargetLowering::getParamSymbol(SelectionDAG &DAG, int idx, EVT v) const { return DAG.getTargetExternalSymbol(SavedStr->c_str(), v); } -SDValue NVPTXTargetLowering::getParamHelpSymbol(SelectionDAG &DAG, int idx) { - return getExtSymb(DAG, ".HLPPARAM", idx); -} - // Check to see if the kernel argument is image*_t or sampler_t bool llvm::isImageOrSamplerVal(const Value *arg, const Module *context) { @@ -2040,8 +2032,8 @@ bool llvm::isImageOrSamplerVal(const Value *arg, const Module *context) { "struct._image3d_t", "struct._sampler_t" }; - const Type *Ty = arg->getType(); - const PointerType *PTy = dyn_cast<PointerType>(Ty); + Type *Ty = arg->getType(); + auto *PTy = dyn_cast<PointerType>(Ty); if (!PTy) return false; @@ -2049,14 +2041,11 @@ bool llvm::isImageOrSamplerVal(const Value *arg, const Module *context) { if (!context) return false; - const StructType *STy = dyn_cast<StructType>(PTy->getElementType()); + auto *STy = dyn_cast<StructType>(PTy->getElementType()); const std::string TypeName = STy && !STy->isLiteral() ? STy->getName() : ""; - for (int i = 0, e = array_lengthof(specialTypes); i != e; ++i) - if (TypeName == specialTypes[i]) - return true; - - return false; + return std::find(std::begin(specialTypes), std::end(specialTypes), + TypeName) != std::end(specialTypes); } SDValue NVPTXTargetLowering::LowerFormalArguments( @@ -2082,10 +2071,9 @@ SDValue NVPTXTargetLowering::LowerFormalArguments( std::vector<Type *> argTypes; std::vector<const Argument *> theArgs; - for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); - I != E; ++I) { - theArgs.push_back(I); - argTypes.push_back(I->getType()); + for (const Argument &I : F->args()) { + theArgs.push_back(&I); + argTypes.push_back(I.getType()); } // argTypes.size() (or theArgs.size()) and Ins.size() need not match. // Ins.size() will be larger @@ -2545,20 +2533,6 @@ void NVPTXTargetLowering::LowerAsmOperandForConstraint( TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); } -// NVPTX suuport vector of legal types of any length in Intrinsics because the -// NVPTX specific type legalizer -// will legalize them to the PTX supported length. -bool NVPTXTargetLowering::isTypeSupportedInIntrinsic(MVT VT) const { - if (isTypeLegal(VT)) - return true; - if (VT.isVector()) { - MVT eVT = VT.getVectorElementType(); - if (isTypeLegal(eVT)) - return true; - } - return false; -} - static unsigned getOpcForTextureInstr(unsigned Intrinsic) { switch (Intrinsic) { default: @@ -3747,9 +3721,7 @@ bool NVPTXTargetLowering::isLegalAddressingMode(const DataLayout &DL, // - [immAddr] if (AM.BaseGV) { - if (AM.BaseOffs || AM.HasBaseReg || AM.Scale) - return false; - return true; + return !AM.BaseOffs && !AM.HasBaseReg && !AM.Scale; } switch (AM.Scale) { @@ -3820,11 +3792,6 @@ NVPTXTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); } -/// getFunctionAlignment - Return the Log2 alignment of this function. -unsigned NVPTXTargetLowering::getFunctionAlignment(const Function *) const { - return 4; -} - //===----------------------------------------------------------------------===// // NVPTX DAG Combining //===----------------------------------------------------------------------===// @@ -4057,6 +4024,67 @@ static SDValue PerformANDCombine(SDNode *N, return SDValue(); } +static SDValue PerformSELECTCombine(SDNode *N, + TargetLowering::DAGCombinerInfo &DCI) { + // Currently this detects patterns for integer min and max and + // lowers them to PTX-specific intrinsics that enable hardware + // support. + + const SDValue Cond = N->getOperand(0); + if (Cond.getOpcode() != ISD::SETCC) return SDValue(); + + const SDValue LHS = Cond.getOperand(0); + const SDValue RHS = Cond.getOperand(1); + const SDValue True = N->getOperand(1); + const SDValue False = N->getOperand(2); + if (!(LHS == True && RHS == False) && !(LHS == False && RHS == True)) + return SDValue(); + + const EVT VT = N->getValueType(0); + if (VT != MVT::i32 && VT != MVT::i64) return SDValue(); + + const ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get(); + SDValue Larger; // The larger of LHS and RHS when condition is true. + switch (CC) { + case ISD::SETULT: + case ISD::SETULE: + case ISD::SETLT: + case ISD::SETLE: + Larger = RHS; + break; + + case ISD::SETGT: + case ISD::SETGE: + case ISD::SETUGT: + case ISD::SETUGE: + Larger = LHS; + break; + + default: + return SDValue(); + } + const bool IsMax = (Larger == True); + const bool IsSigned = ISD::isSignedIntSetCC(CC); + + unsigned IntrinsicId; + if (VT == MVT::i32) { + if (IsSigned) + IntrinsicId = IsMax ? Intrinsic::nvvm_max_i : Intrinsic::nvvm_min_i; + else + IntrinsicId = IsMax ? Intrinsic::nvvm_max_ui : Intrinsic::nvvm_min_ui; + } else { + assert(VT == MVT::i64); + if (IsSigned) + IntrinsicId = IsMax ? Intrinsic::nvvm_max_ll : Intrinsic::nvvm_min_ll; + else + IntrinsicId = IsMax ? Intrinsic::nvvm_max_ull : Intrinsic::nvvm_min_ull; + } + + SDLoc DL(N); + return DCI.DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, VT, + DCI.DAG.getConstant(IntrinsicId, DL, VT), LHS, RHS); +} + enum OperandSignedness { Signed = 0, Unsigned, @@ -4113,25 +4141,16 @@ static bool AreMulWideOperandsDemotable(SDValue LHS, SDValue RHS, if (ConstantSDNode *CI = dyn_cast<ConstantSDNode>(RHS)) { APInt Val = CI->getAPIntValue(); if (LHSSign == Unsigned) { - if (Val.isIntN(OptSize)) { - return true; - } - return false; + return Val.isIntN(OptSize); } else { - if (Val.isSignedIntN(OptSize)) { - return true; - } - return false; + return Val.isSignedIntN(OptSize); } } else { OperandSignedness RHSSign; if (!IsMulWideOperandDemotable(RHS, OptSize, RHSSign)) return false; - if (LHSSign != RHSSign) - return false; - - return true; + return LHSSign == RHSSign; } } @@ -4247,6 +4266,8 @@ SDValue NVPTXTargetLowering::PerformDAGCombine(SDNode *N, return PerformSHLCombine(N, DCI, OptLevel); case ISD::AND: return PerformANDCombine(N, DCI); + case ISD::SELECT: + return PerformSELECTCombine(N, DCI); } return SDValue(); } @@ -4509,25 +4530,25 @@ void NVPTXTargetLowering::ReplaceNodeResults( void NVPTXSection::anchor() {} NVPTXTargetObjectFile::~NVPTXTargetObjectFile() { - delete TextSection; - delete DataSection; - delete BSSSection; - delete ReadOnlySection; - - delete StaticCtorSection; - delete StaticDtorSection; - delete LSDASection; - delete EHFrameSection; - delete DwarfAbbrevSection; - delete DwarfInfoSection; - delete DwarfLineSection; - delete DwarfFrameSection; - delete DwarfPubTypesSection; - delete DwarfDebugInlineSection; - delete DwarfStrSection; - delete DwarfLocSection; - delete DwarfARangesSection; - delete DwarfRangesSection; + delete static_cast<NVPTXSection *>(TextSection); + delete static_cast<NVPTXSection *>(DataSection); + delete static_cast<NVPTXSection *>(BSSSection); + delete static_cast<NVPTXSection *>(ReadOnlySection); + + delete static_cast<NVPTXSection *>(StaticCtorSection); + delete static_cast<NVPTXSection *>(StaticDtorSection); + delete static_cast<NVPTXSection *>(LSDASection); + delete static_cast<NVPTXSection *>(EHFrameSection); + delete static_cast<NVPTXSection *>(DwarfAbbrevSection); + delete static_cast<NVPTXSection *>(DwarfInfoSection); + delete static_cast<NVPTXSection *>(DwarfLineSection); + delete static_cast<NVPTXSection *>(DwarfFrameSection); + delete static_cast<NVPTXSection *>(DwarfPubTypesSection); + delete static_cast<const NVPTXSection *>(DwarfDebugInlineSection); + delete static_cast<NVPTXSection *>(DwarfStrSection); + delete static_cast<NVPTXSection *>(DwarfLocSection); + delete static_cast<NVPTXSection *>(DwarfARangesSection); + delete static_cast<NVPTXSection *>(DwarfRangesSection); } MCSection * |