1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
|
//===----------- AMDILIOExpansion.h - IO Expansion Pass -------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//==-----------------------------------------------------------------------===//
// The AMDIL IO Expansion class expands pseudo IO instructions into a sequence
// of instructions that produces the correct results. These instructions are
// not expanded earlier in the backend because any pass before this can assume to
// be able to generate a load/store instruction. So this pass can only have
// passes that execute after it if no load/store instructions can be generated
// in those passes.
//===----------------------------------------------------------------------===//
#ifndef _AMDILIOEXPANSION_H_
#define _AMDILIOEXPANSION_H_
#undef DEBUG_TYPE
#undef DEBUGME
#define DEBUG_TYPE "IOExpansion"
#if !defined(NDEBUG)
#define DEBUGME (DebugFlag && isCurrentDebugType(DEBUG_TYPE))
#else
#define DEBUGME (false)
#endif
#include "AMDIL.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
class MachineFunction;
class AMDILKernelManager;
class AMDILMachineFunctionInfo;
class AMDILSubtarget;
class MachineInstr;
class Constant;
class TargetInstrInfo;
class Type;
typedef enum {
NO_PACKING = 0,
PACK_V2I8,
PACK_V4I8,
PACK_V2I16,
PACK_V4I16,
UNPACK_V2I8,
UNPACK_V4I8,
UNPACK_V2I16,
UNPACK_V4I16,
UNPACK_LAST
} REG_PACKED_TYPE;
class AMDILIOExpansion : public MachineFunctionPass
{
public:
virtual ~AMDILIOExpansion();
virtual const char* getPassName() const;
bool runOnMachineFunction(MachineFunction &MF);
static char ID;
protected:
AMDILIOExpansion(TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
TargetMachine &TM;
//
// @param MI Machine instruction to check.
// @brief checks to see if the machine instruction
// is an I/O instruction or not.
//
// @return true if I/O, false otherwise.
//
virtual bool
isIOInstruction(MachineInstr *MI);
// Wrapper function that calls the appropriate I/O
// expansion function based on the instruction type.
virtual void
expandIOInstruction(MachineInstr *MI);
virtual void
expandGlobalStore(MachineInstr *MI) = 0;
virtual void
expandLocalStore(MachineInstr *MI) = 0;
virtual void
expandRegionStore(MachineInstr *MI) = 0;
virtual void
expandPrivateStore(MachineInstr *MI) = 0;
virtual void
expandGlobalLoad(MachineInstr *MI) = 0;
virtual void
expandRegionLoad(MachineInstr *MI) = 0;
virtual void
expandLocalLoad(MachineInstr *MI) = 0;
virtual void
expandPrivateLoad(MachineInstr *MI) = 0;
virtual void
expandConstantLoad(MachineInstr *MI) = 0;
virtual void
expandConstantPoolLoad(MachineInstr *MI) = 0;
bool
isAddrCalcInstr(MachineInstr *MI);
bool
isExtendLoad(MachineInstr *MI);
bool
isHardwareRegion(MachineInstr *MI);
bool
isHardwareLocal(MachineInstr *MI);
bool
isPackedData(MachineInstr *MI);
bool
isStaticCPLoad(MachineInstr *MI);
bool
isNbitType(Type *MI, uint32_t nBits, bool isScalar = true);
bool
isHardwareInst(MachineInstr *MI);
uint32_t
getMemorySize(MachineInstr *MI);
REG_PACKED_TYPE
getPackedID(MachineInstr *MI);
uint32_t
getShiftSize(MachineInstr *MI);
uint32_t
getPointerID(MachineInstr *MI);
void
expandTruncData(MachineInstr *MI);
void
expandLoadStartCode(MachineInstr *MI);
virtual void
expandStoreSetupCode(MachineInstr *MI) = 0;
void
expandAddressCalc(MachineInstr *MI);
void
expandLongExtend(MachineInstr *MI,
uint32_t numComponents, uint32_t size, bool signedShift);
void
expandLongExtendSub32(MachineInstr *MI,
unsigned SHLop, unsigned SHRop, unsigned USHRop,
unsigned SHLimm, uint64_t SHRimm, unsigned USHRimm,
unsigned LCRop, bool signedShift);
void
expandIntegerExtend(MachineInstr *MI, unsigned, unsigned, unsigned);
void
expandExtendLoad(MachineInstr *MI);
virtual void
expandPackedData(MachineInstr *MI) = 0;
void
emitCPInst(MachineInstr* MI, const Constant* C,
AMDILKernelManager* KM, int swizzle, bool ExtFPLoad);
bool mDebug;
const AMDILSubtarget *mSTM;
AMDILKernelManager *mKM;
MachineBasicBlock *mBB;
AMDILMachineFunctionInfo *mMFI;
const TargetInstrInfo *mTII;
bool saveInst;
private:
void
emitStaticCPLoad(MachineInstr* MI, int swizzle, int id,
bool ExtFPLoad);
}; // class AMDILIOExpansion
// Intermediate class that holds I/O code expansion that is common to the
// 7XX, Evergreen and Northern Island family of chips.
class AMDIL789IOExpansion : public AMDILIOExpansion {
public:
virtual ~AMDIL789IOExpansion();
virtual const char* getPassName() const;
protected:
AMDIL789IOExpansion(TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
virtual void
expandGlobalStore(MachineInstr *MI) = 0;
virtual void
expandLocalStore(MachineInstr *MI) = 0;
virtual void
expandRegionStore(MachineInstr *MI) = 0;
virtual void
expandGlobalLoad(MachineInstr *MI) = 0;
virtual void
expandRegionLoad(MachineInstr *MI) = 0;
virtual void
expandLocalLoad(MachineInstr *MI) = 0;
virtual void
expandPrivateStore(MachineInstr *MI);
virtual void
expandConstantLoad(MachineInstr *MI);
virtual void
expandPrivateLoad(MachineInstr *MI) ;
virtual void
expandConstantPoolLoad(MachineInstr *MI);
void
expandStoreSetupCode(MachineInstr *MI);
virtual void
expandPackedData(MachineInstr *MI);
private:
void emitVectorAddressCalc(MachineInstr *MI, bool is32bit,
bool needsSelect);
void emitVectorSwitchWrite(MachineInstr *MI, bool is32bit);
void emitComponentExtract(MachineInstr *MI, unsigned flag, unsigned src,
unsigned dst, bool beforeInst);
void emitDataLoadSelect(MachineInstr *MI);
}; // class AMDIL789IOExpansion
// Class that handles I/O emission for the 7XX family of devices.
class AMDIL7XXIOExpansion : public AMDIL789IOExpansion {
public:
AMDIL7XXIOExpansion(TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
~AMDIL7XXIOExpansion();
const char* getPassName() const;
protected:
void
expandGlobalStore(MachineInstr *MI);
void
expandLocalStore(MachineInstr *MI);
void
expandRegionStore(MachineInstr *MI);
void
expandGlobalLoad(MachineInstr *MI);
void
expandRegionLoad(MachineInstr *MI);
void
expandLocalLoad(MachineInstr *MI);
}; // class AMDIL7XXIOExpansion
// Class that handles image functions to expand them into the
// correct set of I/O instructions.
class AMDILImageExpansion : public AMDIL789IOExpansion {
public:
AMDILImageExpansion(TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
virtual ~AMDILImageExpansion();
protected:
//
// @param MI Instruction iterator that has the sample instruction
// that needs to be taken care of.
// @brief transforms the __amdil_sample_data function call into a
// sample instruction in IL.
//
// @warning This function only works correctly if all functions get
// inlined
//
virtual void
expandImageLoad(MachineBasicBlock *BB, MachineInstr *MI);
//
// @param MI Instruction iterator that has the write instruction that
// needs to be taken care of.
// @brief transforms the __amdil_write_data function call into a
// simple UAV write instruction in IL.
//
// @warning This function only works correctly if all functions get
// inlined
//
virtual void
expandImageStore(MachineBasicBlock *BB, MachineInstr *MI);
//
// @param MI Instruction interator that has the image parameter
// instruction
// @brief transforms the __amdil_get_image_params function call into
// a copy of data from a specific constant buffer to the register
//
// @warning This function only works correctly if all functions get
// inlined
//
virtual void
expandImageParam(MachineBasicBlock *BB, MachineInstr *MI);
//
// @param MI Insturction that points to the image
// @brief transforms __amdil_sample_data into a sequence of
// if/else that selects the correct sample instruction.
//
// @warning This function is inefficient and works with no
// inlining.
//
virtual void
expandInefficientImageLoad(MachineBasicBlock *BB, MachineInstr *MI);
private:
AMDILImageExpansion(); // Do not implement.
}; // class AMDILImageExpansion
// Class that expands IO instructions for Evergreen and Northern
// Island family of devices.
class AMDILEGIOExpansion : public AMDILImageExpansion {
public:
AMDILEGIOExpansion(TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
virtual ~AMDILEGIOExpansion();
const char* getPassName() const;
protected:
virtual bool
isIOInstruction(MachineInstr *MI);
virtual void
expandIOInstruction(MachineInstr *MI);
bool
isImageIO(MachineInstr *MI);
virtual void
expandGlobalStore(MachineInstr *MI);
void
expandLocalStore(MachineInstr *MI);
void
expandRegionStore(MachineInstr *MI);
virtual void
expandGlobalLoad(MachineInstr *MI);
void
expandRegionLoad(MachineInstr *MI);
void
expandLocalLoad(MachineInstr *MI);
virtual bool
isCacheableOp(MachineInstr *MI);
void
expandStoreSetupCode(MachineInstr *MI);
void
expandPackedData(MachineInstr *MI);
private:
bool
isArenaOp(MachineInstr *MI);
void
expandArenaSetup(MachineInstr *MI);
}; // class AMDILEGIOExpansion
} // namespace llvm
#endif // _AMDILIOEXPANSION_H_
|