blob: 9b9ec06386487f86ce7e3b3f89468847f336c0c6 [file] [log] [blame]
Tom Stellard75aadc22012-12-11 21:25:42 +00001//===-- AMDGPUInstrInfo.cpp - Base class for AMD GPU InstrInfo ------------===//
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/// \brief Implementation of the TargetInstrInfo class that is common to all
12/// AMD GPUs.
13//
14//===----------------------------------------------------------------------===//
15
16#include "AMDGPUInstrInfo.h"
17#include "AMDGPURegisterInfo.h"
18#include "AMDGPUTargetMachine.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000019#include "llvm/CodeGen/MachineFrameInfo.h"
20#include "llvm/CodeGen/MachineInstrBuilder.h"
21#include "llvm/CodeGen/MachineRegisterInfo.h"
22
Chandler Carruthd174b722014-04-22 02:03:14 +000023using namespace llvm;
24
Juergen Ributzkad12ccbd2013-11-19 00:57:56 +000025#define GET_INSTRINFO_CTOR_DTOR
Tom Stellard75aadc22012-12-11 21:25:42 +000026#include "AMDGPUGenInstrInfo.inc"
27
Juergen Ributzkad12ccbd2013-11-19 00:57:56 +000028// Pin the vtable to this file.
29void AMDGPUInstrInfo::anchor() {}
30
Matt Arsenault43e92fe2016-06-24 06:30:11 +000031AMDGPUInstrInfo::AMDGPUInstrInfo(const AMDGPUSubtarget &ST)
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000032 : AMDGPUGenInstrInfo(AMDGPU::ADJCALLSTACKUP, AMDGPU::ADJCALLSTACKDOWN),
33 ST(ST),
34 AMDGPUASI(ST.getAMDGPUAS()) {}
Tom Stellard75aadc22012-12-11 21:25:42 +000035
Matt Arsenaultd5f4de22014-08-06 00:29:49 +000036// FIXME: This behaves strangely. If, for example, you have 32 load + stores,
37// the first 16 loads will be interleaved with the stores, and the next 16 will
38// be clustered as expected. It should really split into 2 16 store batches.
39//
40// Loads are clustered until this returns false, rather than trying to schedule
41// groups of stores. This also means we have to deal with saying different
42// address space loads should be clustered, and ones which might cause bank
43// conflicts.
44//
45// This might be deprecated so it might not be worth that much effort to fix.
46bool AMDGPUInstrInfo::shouldScheduleLoadsNear(SDNode *Load0, SDNode *Load1,
47 int64_t Offset0, int64_t Offset1,
48 unsigned NumLoads) const {
49 assert(Offset1 > Offset0 &&
50 "Second offset should be larger than first offset!");
51 // If we have less than 16 loads in a row, and the offsets are within 64
52 // bytes, then schedule together.
53
54 // A cacheline is 64 bytes (for global memory).
55 return (NumLoads <= 16 && (Offset1 - Offset0) < 64);
Tom Stellard75aadc22012-12-11 21:25:42 +000056}
57
Matt Arsenault43e92fe2016-06-24 06:30:11 +000058// This must be kept in sync with the SIEncodingFamily class in SIInstrInfo.td
59enum SIEncodingFamily {
60 SI = 0,
Sam Kolton549c89d2017-06-21 08:53:38 +000061 VI = 1,
62 SDWA = 2,
Dmitry Preobrazhensky1e325502017-08-09 17:10:47 +000063 SDWA9 = 3,
Changpeng Fang44dfa1d2018-01-12 21:12:19 +000064 GFX80 = 4,
65 GFX9 = 5
Matt Arsenault43e92fe2016-06-24 06:30:11 +000066};
67
Matt Arsenault43e92fe2016-06-24 06:30:11 +000068static SIEncodingFamily subtargetEncodingFamily(const AMDGPUSubtarget &ST) {
69 switch (ST.getGeneration()) {
70 case AMDGPUSubtarget::SOUTHERN_ISLANDS:
71 case AMDGPUSubtarget::SEA_ISLANDS:
72 return SIEncodingFamily::SI;
Marek Olsaka93603d2015-01-15 18:42:51 +000073 case AMDGPUSubtarget::VOLCANIC_ISLANDS:
Matt Arsenaulte823d922017-02-18 18:29:53 +000074 case AMDGPUSubtarget::GFX9:
Matt Arsenault43e92fe2016-06-24 06:30:11 +000075 return SIEncodingFamily::VI;
76
77 // FIXME: This should never be called for r600 GPUs.
78 case AMDGPUSubtarget::R600:
79 case AMDGPUSubtarget::R700:
80 case AMDGPUSubtarget::EVERGREEN:
81 case AMDGPUSubtarget::NORTHERN_ISLANDS:
82 return SIEncodingFamily::SI;
Marek Olsaka93603d2015-01-15 18:42:51 +000083 }
Simon Pilgrim634dde32016-06-27 12:58:10 +000084
85 llvm_unreachable("Unknown subtarget generation!");
Marek Olsaka93603d2015-01-15 18:42:51 +000086}
87
88int AMDGPUInstrInfo::pseudoToMCOpcode(int Opcode) const {
Sam Kolton549c89d2017-06-21 08:53:38 +000089 SIEncodingFamily Gen = subtargetEncodingFamily(ST);
Dmitry Preobrazhenskya0342dc2017-11-20 18:24:21 +000090
91 if ((get(Opcode).TSFlags & SIInstrFlags::renamedInGFX9) != 0 &&
92 ST.getGeneration() >= AMDGPUSubtarget::GFX9)
93 Gen = SIEncodingFamily::GFX9;
94
Sam Kolton549c89d2017-06-21 08:53:38 +000095 if (get(Opcode).TSFlags & SIInstrFlags::SDWA)
96 Gen = ST.getGeneration() == AMDGPUSubtarget::GFX9 ? SIEncodingFamily::SDWA9
97 : SIEncodingFamily::SDWA;
98
99 int MCOp = AMDGPU::getMCOpcode(Opcode, Gen);
Marek Olsaka93603d2015-01-15 18:42:51 +0000100
101 // -1 means that Opcode is already a native instruction.
102 if (MCOp == -1)
103 return Opcode;
104
105 // (uint16_t)-1 means that Opcode is a pseudo instruction that has
106 // no encoding in the given subtarget generation.
107 if (MCOp == (uint16_t)-1)
108 return -1;
109
110 return MCOp;
111}