1 //===- R600TargetTransformInfo.cpp - AMDGPU specific TTI pass -----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // \file
10 // This file implements a TargetTransformInfo analysis pass specific to the
11 // R600 target machine. It uses the target's detailed information to provide
12 // more precise answers to certain TTI queries, while letting the target
13 // independent and default TTI implementations handle the rest.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #include "R600TargetTransformInfo.h"
18 #include "AMDGPU.h"
19 #include "AMDGPUTargetMachine.h"
20 #include "R600Subtarget.h"
21 
22 using namespace llvm;
23 
24 #define DEBUG_TYPE "R600tti"
25 
26 R600TTIImpl::R600TTIImpl(const AMDGPUTargetMachine *TM, const Function &F)
27     : BaseT(TM, F.getParent()->getDataLayout()),
28       ST(static_cast<const R600Subtarget *>(TM->getSubtargetImpl(F))),
29       TLI(ST->getTargetLowering()), CommonTTI(TM, F) {}
30 
31 unsigned R600TTIImpl::getHardwareNumberOfRegisters(bool Vec) const {
32   return 4 * 128; // XXX - 4 channels. Should these count as vector instead?
33 }
34 
35 unsigned R600TTIImpl::getNumberOfRegisters(bool Vec) const {
36   return getHardwareNumberOfRegisters(Vec);
37 }
38 
39 TypeSize
40 R600TTIImpl::getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const {
41   return TypeSize::getFixed(32);
42 }
43 
44 unsigned R600TTIImpl::getMinVectorRegisterBitWidth() const { return 32; }
45 
46 unsigned R600TTIImpl::getLoadStoreVecRegBitWidth(unsigned AddrSpace) const {
47   if (AddrSpace == AMDGPUAS::GLOBAL_ADDRESS ||
48       AddrSpace == AMDGPUAS::CONSTANT_ADDRESS)
49     return 128;
50   if (AddrSpace == AMDGPUAS::LOCAL_ADDRESS ||
51       AddrSpace == AMDGPUAS::REGION_ADDRESS)
52     return 64;
53   if (AddrSpace == AMDGPUAS::PRIVATE_ADDRESS)
54     return 32;
55 
56   if ((AddrSpace == AMDGPUAS::PARAM_D_ADDRESS ||
57        AddrSpace == AMDGPUAS::PARAM_I_ADDRESS ||
58        (AddrSpace >= AMDGPUAS::CONSTANT_BUFFER_0 &&
59         AddrSpace <= AMDGPUAS::CONSTANT_BUFFER_15)))
60     return 128;
61   llvm_unreachable("unhandled address space");
62 }
63 
64 bool R600TTIImpl::isLegalToVectorizeMemChain(unsigned ChainSizeInBytes,
65                                              Align Alignment,
66                                              unsigned AddrSpace) const {
67   // We allow vectorization of flat stores, even though we may need to decompose
68   // them later if they may access private memory. We don't have enough context
69   // here, and legalization can handle it.
70   return (AddrSpace != AMDGPUAS::PRIVATE_ADDRESS);
71 }
72 
73 bool R600TTIImpl::isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes,
74                                               Align Alignment,
75                                               unsigned AddrSpace) const {
76   return isLegalToVectorizeMemChain(ChainSizeInBytes, Alignment, AddrSpace);
77 }
78 
79 bool R600TTIImpl::isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes,
80                                                Align Alignment,
81                                                unsigned AddrSpace) const {
82   return isLegalToVectorizeMemChain(ChainSizeInBytes, Alignment, AddrSpace);
83 }
84 
85 unsigned R600TTIImpl::getMaxInterleaveFactor(ElementCount VF) {
86   // Disable unrolling if the loop is not vectorized.
87   // TODO: Enable this again.
88   if (VF.isScalar())
89     return 1;
90 
91   return 8;
92 }
93 
94 InstructionCost R600TTIImpl::getCFInstrCost(unsigned Opcode,
95                                             TTI::TargetCostKind CostKind,
96                                             const Instruction *I) {
97   if (CostKind == TTI::TCK_CodeSize || CostKind == TTI::TCK_SizeAndLatency)
98     return Opcode == Instruction::PHI ? 0 : 1;
99 
100   // XXX - For some reason this isn't called for switch.
101   switch (Opcode) {
102   case Instruction::Br:
103   case Instruction::Ret:
104     return 10;
105   default:
106     return BaseT::getCFInstrCost(Opcode, CostKind, I);
107   }
108 }
109 
110 InstructionCost R600TTIImpl::getVectorInstrCost(unsigned Opcode, Type *ValTy,
111                                                 TTI::TargetCostKind CostKind,
112                                                 unsigned Index, Value *Op0,
113                                                 Value *Op1) {
114   switch (Opcode) {
115   case Instruction::ExtractElement:
116   case Instruction::InsertElement: {
117     unsigned EltSize =
118         DL.getTypeSizeInBits(cast<VectorType>(ValTy)->getElementType());
119     if (EltSize < 32) {
120       return BaseT::getVectorInstrCost(Opcode, ValTy, CostKind, Index, Op0,
121                                        Op1);
122     }
123 
124     // Extracts are just reads of a subregister, so are free. Inserts are
125     // considered free because we don't want to have any cost for scalarizing
126     // operations, and we don't have to copy into a different register class.
127 
128     // Dynamic indexing isn't free and is best avoided.
129     return Index == ~0u ? 2 : 0;
130   }
131   default:
132     return BaseT::getVectorInstrCost(Opcode, ValTy, CostKind, Index, Op0, Op1);
133   }
134 }
135 
136 void R600TTIImpl::getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
137                                           TTI::UnrollingPreferences &UP,
138                                           OptimizationRemarkEmitter *ORE) {
139   CommonTTI.getUnrollingPreferences(L, SE, UP, ORE);
140 }
141 
142 void R600TTIImpl::getPeelingPreferences(Loop *L, ScalarEvolution &SE,
143                                         TTI::PeelingPreferences &PP) {
144   CommonTTI.getPeelingPreferences(L, SE, PP);
145 }
146