1*9880d681SAndroid Build Coastguard Worker //===-- AMDGPUInstrInfo.cpp - Base class for AMD GPU InstrInfo ------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker /// \file
11*9880d681SAndroid Build Coastguard Worker /// \brief Implementation of the TargetInstrInfo class that is common to all
12*9880d681SAndroid Build Coastguard Worker /// AMD GPUs.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker #include "AMDGPUInstrInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "AMDGPURegisterInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "AMDGPUTargetMachine.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker using namespace llvm;
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker #define GET_INSTRINFO_CTOR_DTOR
26*9880d681SAndroid Build Coastguard Worker #define GET_INSTRINFO_NAMED_OPS
27*9880d681SAndroid Build Coastguard Worker #define GET_INSTRMAP_INFO
28*9880d681SAndroid Build Coastguard Worker #include "AMDGPUGenInstrInfo.inc"
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker // Pin the vtable to this file.
anchor()31*9880d681SAndroid Build Coastguard Worker void AMDGPUInstrInfo::anchor() {}
32*9880d681SAndroid Build Coastguard Worker
AMDGPUInstrInfo(const AMDGPUSubtarget & ST)33*9880d681SAndroid Build Coastguard Worker AMDGPUInstrInfo::AMDGPUInstrInfo(const AMDGPUSubtarget &ST)
34*9880d681SAndroid Build Coastguard Worker : AMDGPUGenInstrInfo(-1, -1), ST(ST) {}
35*9880d681SAndroid Build Coastguard Worker
enableClusterLoads() const36*9880d681SAndroid Build Coastguard Worker bool AMDGPUInstrInfo::enableClusterLoads() const {
37*9880d681SAndroid Build Coastguard Worker return true;
38*9880d681SAndroid Build Coastguard Worker }
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker // FIXME: This behaves strangely. If, for example, you have 32 load + stores,
41*9880d681SAndroid Build Coastguard Worker // the first 16 loads will be interleaved with the stores, and the next 16 will
42*9880d681SAndroid Build Coastguard Worker // be clustered as expected. It should really split into 2 16 store batches.
43*9880d681SAndroid Build Coastguard Worker //
44*9880d681SAndroid Build Coastguard Worker // Loads are clustered until this returns false, rather than trying to schedule
45*9880d681SAndroid Build Coastguard Worker // groups of stores. This also means we have to deal with saying different
46*9880d681SAndroid Build Coastguard Worker // address space loads should be clustered, and ones which might cause bank
47*9880d681SAndroid Build Coastguard Worker // conflicts.
48*9880d681SAndroid Build Coastguard Worker //
49*9880d681SAndroid Build Coastguard Worker // This might be deprecated so it might not be worth that much effort to fix.
shouldScheduleLoadsNear(SDNode * Load0,SDNode * Load1,int64_t Offset0,int64_t Offset1,unsigned NumLoads) const50*9880d681SAndroid Build Coastguard Worker bool AMDGPUInstrInfo::shouldScheduleLoadsNear(SDNode *Load0, SDNode *Load1,
51*9880d681SAndroid Build Coastguard Worker int64_t Offset0, int64_t Offset1,
52*9880d681SAndroid Build Coastguard Worker unsigned NumLoads) const {
53*9880d681SAndroid Build Coastguard Worker assert(Offset1 > Offset0 &&
54*9880d681SAndroid Build Coastguard Worker "Second offset should be larger than first offset!");
55*9880d681SAndroid Build Coastguard Worker // If we have less than 16 loads in a row, and the offsets are within 64
56*9880d681SAndroid Build Coastguard Worker // bytes, then schedule together.
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker // A cacheline is 64 bytes (for global memory).
59*9880d681SAndroid Build Coastguard Worker return (NumLoads <= 16 && (Offset1 - Offset0) < 64);
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker
getMaskedMIMGOp(uint16_t Opcode,unsigned Channels) const62*9880d681SAndroid Build Coastguard Worker int AMDGPUInstrInfo::getMaskedMIMGOp(uint16_t Opcode, unsigned Channels) const {
63*9880d681SAndroid Build Coastguard Worker switch (Channels) {
64*9880d681SAndroid Build Coastguard Worker default: return Opcode;
65*9880d681SAndroid Build Coastguard Worker case 1: return AMDGPU::getMaskedMIMGOp(Opcode, AMDGPU::Channels_1);
66*9880d681SAndroid Build Coastguard Worker case 2: return AMDGPU::getMaskedMIMGOp(Opcode, AMDGPU::Channels_2);
67*9880d681SAndroid Build Coastguard Worker case 3: return AMDGPU::getMaskedMIMGOp(Opcode, AMDGPU::Channels_3);
68*9880d681SAndroid Build Coastguard Worker }
69*9880d681SAndroid Build Coastguard Worker }
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker // This must be kept in sync with the SIEncodingFamily class in SIInstrInfo.td
72*9880d681SAndroid Build Coastguard Worker enum SIEncodingFamily {
73*9880d681SAndroid Build Coastguard Worker SI = 0,
74*9880d681SAndroid Build Coastguard Worker VI = 1
75*9880d681SAndroid Build Coastguard Worker };
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker // Wrapper for Tablegen'd function. enum Subtarget is not defined in any
78*9880d681SAndroid Build Coastguard Worker // header files, so we need to wrap it in a function that takes unsigned
79*9880d681SAndroid Build Coastguard Worker // instead.
80*9880d681SAndroid Build Coastguard Worker namespace llvm {
81*9880d681SAndroid Build Coastguard Worker namespace AMDGPU {
getMCOpcode(uint16_t Opcode,unsigned Gen)82*9880d681SAndroid Build Coastguard Worker static int getMCOpcode(uint16_t Opcode, unsigned Gen) {
83*9880d681SAndroid Build Coastguard Worker return getMCOpcodeGen(Opcode, static_cast<Subtarget>(Gen));
84*9880d681SAndroid Build Coastguard Worker }
85*9880d681SAndroid Build Coastguard Worker }
86*9880d681SAndroid Build Coastguard Worker }
87*9880d681SAndroid Build Coastguard Worker
subtargetEncodingFamily(const AMDGPUSubtarget & ST)88*9880d681SAndroid Build Coastguard Worker static SIEncodingFamily subtargetEncodingFamily(const AMDGPUSubtarget &ST) {
89*9880d681SAndroid Build Coastguard Worker switch (ST.getGeneration()) {
90*9880d681SAndroid Build Coastguard Worker case AMDGPUSubtarget::SOUTHERN_ISLANDS:
91*9880d681SAndroid Build Coastguard Worker case AMDGPUSubtarget::SEA_ISLANDS:
92*9880d681SAndroid Build Coastguard Worker return SIEncodingFamily::SI;
93*9880d681SAndroid Build Coastguard Worker case AMDGPUSubtarget::VOLCANIC_ISLANDS:
94*9880d681SAndroid Build Coastguard Worker return SIEncodingFamily::VI;
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Worker // FIXME: This should never be called for r600 GPUs.
97*9880d681SAndroid Build Coastguard Worker case AMDGPUSubtarget::R600:
98*9880d681SAndroid Build Coastguard Worker case AMDGPUSubtarget::R700:
99*9880d681SAndroid Build Coastguard Worker case AMDGPUSubtarget::EVERGREEN:
100*9880d681SAndroid Build Coastguard Worker case AMDGPUSubtarget::NORTHERN_ISLANDS:
101*9880d681SAndroid Build Coastguard Worker return SIEncodingFamily::SI;
102*9880d681SAndroid Build Coastguard Worker }
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unknown subtarget generation!");
105*9880d681SAndroid Build Coastguard Worker }
106*9880d681SAndroid Build Coastguard Worker
pseudoToMCOpcode(int Opcode) const107*9880d681SAndroid Build Coastguard Worker int AMDGPUInstrInfo::pseudoToMCOpcode(int Opcode) const {
108*9880d681SAndroid Build Coastguard Worker int MCOp = AMDGPU::getMCOpcode(Opcode, subtargetEncodingFamily(ST));
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Worker // -1 means that Opcode is already a native instruction.
111*9880d681SAndroid Build Coastguard Worker if (MCOp == -1)
112*9880d681SAndroid Build Coastguard Worker return Opcode;
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker // (uint16_t)-1 means that Opcode is a pseudo instruction that has
115*9880d681SAndroid Build Coastguard Worker // no encoding in the given subtarget generation.
116*9880d681SAndroid Build Coastguard Worker if (MCOp == (uint16_t)-1)
117*9880d681SAndroid Build Coastguard Worker return -1;
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker return MCOp;
120*9880d681SAndroid Build Coastguard Worker }
121