1 //===-- NVPTXTargetTransformInfo.cpp - NVPTX specific TTI pass ---------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // \file 11 // This file implements a TargetTransformInfo analysis pass specific to the 12 // NVPTX target machine. It uses the target's detailed information to provide 13 // more precise answers to certain TTI queries, while letting the target 14 // independent and default TTI implementations handle the rest. 15 // 16 //===----------------------------------------------------------------------===// 17 18 #include "NVPTXTargetMachine.h" 19 #include "llvm/Analysis/LoopInfo.h" 20 #include "llvm/Analysis/TargetTransformInfo.h" 21 #include "llvm/Analysis/ValueTracking.h" 22 #include "llvm/Support/Debug.h" 23 #include "llvm/Target/CostTable.h" 24 #include "llvm/Target/TargetLowering.h" 25 using namespace llvm; 26 27 #define DEBUG_TYPE "NVPTXtti" 28 29 // Declare the pass initialization routine locally as target-specific passes 30 // don't have a target-wide initialization entry point, and so we rely on the 31 // pass constructor initialization. 32 namespace llvm { 33 void initializeNVPTXTTIPass(PassRegistry &); 34 } 35 36 namespace { 37 38 class NVPTXTTI final : public ImmutablePass, public TargetTransformInfo { 39 const NVPTXTargetLowering *TLI; 40 public: 41 NVPTXTTI() : ImmutablePass(ID), TLI(nullptr) { 42 llvm_unreachable("This pass cannot be directly constructed"); 43 } 44 45 NVPTXTTI(const NVPTXTargetMachine *TM) 46 : ImmutablePass(ID), TLI(TM->getSubtargetImpl()->getTargetLowering()) { 47 initializeNVPTXTTIPass(*PassRegistry::getPassRegistry()); 48 } 49 50 void initializePass() override { pushTTIStack(this); } 51 52 void getAnalysisUsage(AnalysisUsage &AU) const override { 53 TargetTransformInfo::getAnalysisUsage(AU); 54 } 55 56 /// Pass identification. 57 static char ID; 58 59 /// Provide necessary pointer adjustments for the two base classes. 60 void *getAdjustedAnalysisPointer(const void *ID) override { 61 if (ID == &TargetTransformInfo::ID) 62 return (TargetTransformInfo *)this; 63 return this; 64 } 65 66 bool hasBranchDivergence() const override; 67 68 unsigned getArithmeticInstrCost( 69 unsigned Opcode, Type *Ty, OperandValueKind Opd1Info = OK_AnyValue, 70 OperandValueKind Opd2Info = OK_AnyValue, 71 OperandValueProperties Opd1PropInfo = OP_None, 72 OperandValueProperties Opd2PropInfo = OP_None) const override; 73 }; 74 75 } // end anonymous namespace 76 77 INITIALIZE_AG_PASS(NVPTXTTI, TargetTransformInfo, "NVPTXtti", 78 "NVPTX Target Transform Info", true, true, false) 79 char NVPTXTTI::ID = 0; 80 81 ImmutablePass * 82 llvm::createNVPTXTargetTransformInfoPass(const NVPTXTargetMachine *TM) { 83 return new NVPTXTTI(TM); 84 } 85 86 bool NVPTXTTI::hasBranchDivergence() const { return true; } 87 88 unsigned NVPTXTTI::getArithmeticInstrCost( 89 unsigned Opcode, Type *Ty, OperandValueKind Opd1Info, 90 OperandValueKind Opd2Info, OperandValueProperties Opd1PropInfo, 91 OperandValueProperties Opd2PropInfo) const { 92 // Legalize the type. 93 std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Ty); 94 95 int ISD = TLI->InstructionOpcodeToISD(Opcode); 96 97 switch (ISD) { 98 default: 99 return TargetTransformInfo::getArithmeticInstrCost( 100 Opcode, Ty, Opd1Info, Opd2Info, Opd1PropInfo, Opd2PropInfo); 101 case ISD::ADD: 102 case ISD::MUL: 103 case ISD::XOR: 104 case ISD::OR: 105 case ISD::AND: 106 // The machine code (SASS) simulates an i64 with two i32. Therefore, we 107 // estimate that arithmetic operations on i64 are twice as expensive as 108 // those on types that can fit into one machine register. 109 if (LT.second.SimpleTy == MVT::i64) 110 return 2 * LT.first; 111 // Delegate other cases to the basic TTI. 112 return TargetTransformInfo::getArithmeticInstrCost( 113 Opcode, Ty, Opd1Info, Opd2Info, Opd1PropInfo, Opd2PropInfo); 114 } 115 } 116