ec42b9c0e4462e1e76a8a71a11ad8733c52e377e
[mesa.git] / src / gallium / drivers / radeon / AMDILMachineFunctionInfo.cpp
1 //===-- AMDILMachineFunctionInfo.cpp - TODO: Add brief description -------===//
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 #include "AMDILMachineFunctionInfo.h"
10 #include "AMDILCompilerErrors.h"
11 #include "AMDILSubtarget.h"
12 #include "AMDILTargetMachine.h"
13 #include "AMDILUtilityFunctions.h"
14 #include "llvm/ADT/StringExtras.h"
15 #include "llvm/CodeGen/MachineFrameInfo.h"
16 #include "llvm/CodeGen/MachineModuleInfo.h"
17 #include "llvm/Constants.h"
18 #include "llvm/DerivedTypes.h"
19 #include "llvm/Function.h"
20 #include "llvm/Instructions.h"
21 #include "llvm/Support/FormattedStream.h"
22
23 using namespace llvm;
24
25 static const AMDILConstPtr *getConstPtr(const AMDILKernel *krnl, const std::string &arg) {
26 llvm::SmallVector<AMDILConstPtr, DEFAULT_VEC_SLOTS>::const_iterator begin, end;
27 for (begin = krnl->constPtr.begin(), end = krnl->constPtr.end();
28 begin != end; ++begin) {
29 if (!strcmp(begin->name.data(),arg.c_str())) {
30 return &(*begin);
31 }
32 }
33 return NULL;
34 }
35
36 void PrintfInfo::addOperand(size_t idx, uint32_t size) {
37 mOperands.resize((unsigned)(idx + 1));
38 mOperands[(unsigned)idx] = size;
39 }
40
41 uint32_t PrintfInfo::getPrintfID() {
42 return mPrintfID;
43 }
44
45 void PrintfInfo::setPrintfID(uint32_t id) {
46 mPrintfID = id;
47 }
48
49 size_t PrintfInfo::getNumOperands() {
50 return mOperands.size();
51 }
52
53 uint32_t PrintfInfo::getOperandID(uint32_t idx) {
54 return mOperands[idx];
55 }
56
57 AMDILMachineFunctionInfo::AMDILMachineFunctionInfo()
58 : CalleeSavedFrameSize(0), BytesToPopOnReturn(0),
59 DecorationStyle(None), ReturnAddrIndex(0),
60 TailCallReturnAddrDelta(0),
61 SRetReturnReg(0), UsesLDS(false), LDSArg(false),
62 UsesGDS(false), GDSArg(false),
63 mReservedLits(9)
64 {
65 for (uint32_t x = 0; x < AMDILDevice::MAX_IDS; ++x) {
66 mUsedMem[x] = false;
67 }
68 mMF = NULL;
69 mKernel = NULL;
70 mScratchSize = -1;
71 mArgSize = -1;
72 mStackSize = -1;
73 }
74
75 AMDILMachineFunctionInfo::AMDILMachineFunctionInfo(MachineFunction& MF)
76 : CalleeSavedFrameSize(0), BytesToPopOnReturn(0),
77 DecorationStyle(None), ReturnAddrIndex(0),
78 TailCallReturnAddrDelta(0),
79 SRetReturnReg(0), UsesLDS(false), LDSArg(false),
80 UsesGDS(false), GDSArg(false),
81 mReservedLits(9)
82 {
83 for (uint32_t x = 0; x < AMDILDevice::MAX_IDS; ++x) {
84 mUsedMem[x] = false;
85 }
86 mMF = &MF;
87 const AMDILTargetMachine *TM =
88 reinterpret_cast<const AMDILTargetMachine*>(&MF.getTarget());
89 mSTM = TM->getSubtargetImpl();
90
91 mScratchSize = -1;
92 mArgSize = -1;
93 mStackSize = -1;
94 }
95
96 AMDILMachineFunctionInfo::~AMDILMachineFunctionInfo()
97 {
98 for (std::map<std::string, PrintfInfo*>::iterator pfb = printf_begin(),
99 pfe = printf_end(); pfb != pfe; ++pfb) {
100 delete pfb->second;
101 }
102 }
103 unsigned int
104 AMDILMachineFunctionInfo::getCalleeSavedFrameSize() const
105 {
106 return CalleeSavedFrameSize;
107 }
108 void
109 AMDILMachineFunctionInfo::setCalleeSavedFrameSize(unsigned int bytes)
110 {
111 CalleeSavedFrameSize = bytes;
112 }
113 unsigned int
114 AMDILMachineFunctionInfo::getBytesToPopOnReturn() const
115 {
116 return BytesToPopOnReturn;
117 }
118 void
119 AMDILMachineFunctionInfo::setBytesToPopOnReturn(unsigned int bytes)
120 {
121 BytesToPopOnReturn = bytes;
122 }
123 NameDecorationStyle
124 AMDILMachineFunctionInfo::getDecorationStyle() const
125 {
126 return DecorationStyle;
127 }
128 void
129 AMDILMachineFunctionInfo::setDecorationStyle(NameDecorationStyle style)
130 {
131 DecorationStyle = style;
132 }
133 int
134 AMDILMachineFunctionInfo::getRAIndex() const
135 {
136 return ReturnAddrIndex;
137 }
138 void
139 AMDILMachineFunctionInfo::setRAIndex(int index)
140 {
141 ReturnAddrIndex = index;
142 }
143 int
144 AMDILMachineFunctionInfo::getTCReturnAddrDelta() const
145 {
146 return TailCallReturnAddrDelta;
147 }
148 void
149 AMDILMachineFunctionInfo::setTCReturnAddrDelta(int delta)
150 {
151 TailCallReturnAddrDelta = delta;
152 }
153 unsigned int
154 AMDILMachineFunctionInfo::getSRetReturnReg() const
155 {
156 return SRetReturnReg;
157 }
158 void
159 AMDILMachineFunctionInfo::setSRetReturnReg(unsigned int reg)
160 {
161 SRetReturnReg = reg;
162 }
163
164 void
165 AMDILMachineFunctionInfo::setUsesLocal()
166 {
167 UsesLDS = true;
168 }
169
170 bool
171 AMDILMachineFunctionInfo::usesLocal() const
172 {
173 return UsesLDS;
174 }
175
176 void
177 AMDILMachineFunctionInfo::setHasLocalArg()
178 {
179 LDSArg = true;
180 }
181
182 bool
183 AMDILMachineFunctionInfo::hasLocalArg() const
184 {
185 return LDSArg;
186 }
187
188
189
190 void
191 AMDILMachineFunctionInfo::setUsesRegion()
192 {
193 UsesGDS = true;
194 }
195
196 bool
197 AMDILMachineFunctionInfo::usesRegion() const
198 {
199 return UsesGDS;
200 }
201
202 void
203 AMDILMachineFunctionInfo::setHasRegionArg()
204 {
205 GDSArg = true;
206 }
207
208 bool
209 AMDILMachineFunctionInfo::hasRegionArg() const
210 {
211 return GDSArg;
212 }
213
214
215 bool
216 AMDILMachineFunctionInfo::usesHWConstant(std::string name) const
217 {
218 const AMDILConstPtr *curConst = getConstPtr(mKernel, name);
219 if (curConst) {
220 return curConst->usesHardware;
221 } else {
222 return false;
223 }
224 }
225
226 uint32_t
227 AMDILMachineFunctionInfo::getLocal(uint32_t dim)
228 {
229 if (mKernel && mKernel->sgv) {
230 AMDILKernelAttr *sgv = mKernel->sgv;
231 switch (dim) {
232 default: break;
233 case 0:
234 case 1:
235 case 2:
236 return sgv->reqGroupSize[dim];
237 break;
238 case 3:
239 return sgv->reqGroupSize[0] * sgv->reqGroupSize[1] * sgv->reqGroupSize[2];
240 };
241 }
242 switch (dim) {
243 default:
244 return 1;
245 case 3:
246 return mSTM->getDefaultSize(0) *
247 mSTM->getDefaultSize(1) *
248 mSTM->getDefaultSize(2);
249 case 2:
250 case 1:
251 case 0:
252 return mSTM->getDefaultSize(dim);
253 break;
254 };
255 return 1;
256 }
257 bool
258 AMDILMachineFunctionInfo::isKernel() const
259 {
260 return mKernel != NULL && mKernel->mKernel;
261 }
262
263 AMDILKernel*
264 AMDILMachineFunctionInfo::getKernel()
265 {
266 return mKernel;
267 }
268
269 std::string
270 AMDILMachineFunctionInfo::getName()
271 {
272 if (mMF) {
273 return mMF->getFunction()->getName();
274 } else {
275 return "";
276 }
277 }
278
279 uint32_t
280 AMDILMachineFunctionInfo::getArgSize()
281 {
282 if (mArgSize == -1) {
283 Function::const_arg_iterator I = mMF->getFunction()->arg_begin();
284 Function::const_arg_iterator Ie = mMF->getFunction()->arg_end();
285 uint32_t Counter = 0;
286 while (I != Ie) {
287 Type* curType = I->getType();
288 if (curType->isIntegerTy() || curType->isFloatingPointTy()) {
289 ++Counter;
290 } else if (const VectorType *VT = dyn_cast<VectorType>(curType)) {
291 Type *ET = VT->getElementType();
292 int numEle = VT->getNumElements();
293 switch (ET->getPrimitiveSizeInBits()) {
294 default:
295 if (numEle == 3) {
296 Counter++;
297 } else {
298 Counter += ((numEle + 2) >> 2);
299 }
300 break;
301 case 64:
302 if (numEle == 3) {
303 Counter += 2;
304 } else {
305 Counter += (numEle >> 1);
306 }
307 break;
308 case 16:
309 case 8:
310 switch (numEle) {
311 default:
312 Counter += ((numEle + 2) >> 2);
313 case 2:
314 Counter++;
315 break;
316 }
317 break;
318 }
319 } else if (const PointerType *PT = dyn_cast<PointerType>(curType)) {
320 Type *CT = PT->getElementType();
321 const StructType *ST = dyn_cast<StructType>(CT);
322 if (ST && ST->isOpaque()) {
323 bool i1d = ST->getName() == "struct._image1d_t";
324 bool i1da = ST->getName() == "struct._image1d_array_t";
325 bool i1db = ST->getName() == "struct._image1d_buffer_t";
326 bool i2d = ST->getName() == "struct._image2d_t";
327 bool i2da = ST->getName() == "struct._image2d_array_t";
328 bool i3d = ST->getName() == "struct._image3d_t";
329 bool is_image = i1d || i1da || i1db || i2d || i2da || i3d;
330 if (is_image) {
331 if (mSTM->device()->isSupported(AMDILDeviceInfo::Images)) {
332 Counter += 2;
333 } else {
334 addErrorMsg(amd::CompilerErrorMessage[NO_IMAGE_SUPPORT]);
335 }
336 } else {
337 Counter++;
338 }
339 } else if (CT->isStructTy()
340 && PT->getAddressSpace() == AMDILAS::PRIVATE_ADDRESS) {
341 StructType *ST = dyn_cast<StructType>(CT);
342 Counter += ((getTypeSize(ST) + 15) & ~15) >> 4;
343 } else if (CT->isIntOrIntVectorTy()
344 || CT->isFPOrFPVectorTy()
345 || CT->isArrayTy()
346 || CT->isPointerTy()
347 || PT->getAddressSpace() != AMDILAS::PRIVATE_ADDRESS) {
348 ++Counter;
349 } else {
350 assert(0 && "Current type is not supported!");
351 addErrorMsg(amd::CompilerErrorMessage[INTERNAL_ERROR]);
352 }
353 } else {
354 assert(0 && "Current type is not supported!");
355 addErrorMsg(amd::CompilerErrorMessage[INTERNAL_ERROR]);
356 }
357 ++I;
358 }
359 // Convert from slots to bytes by multiplying by 16(shift by 4).
360 mArgSize = Counter << 4;
361 }
362 return (uint32_t)mArgSize;
363 }
364 uint32_t
365 AMDILMachineFunctionInfo::getScratchSize()
366 {
367 if (mScratchSize == -1) {
368 mScratchSize = 0;
369 Function::const_arg_iterator I = mMF->getFunction()->arg_begin();
370 Function::const_arg_iterator Ie = mMF->getFunction()->arg_end();
371 while (I != Ie) {
372 Type *curType = I->getType();
373 mScratchSize += ((getTypeSize(curType) + 15) & ~15);
374 ++I;
375 }
376 mScratchSize += ((mScratchSize + 15) & ~15);
377 }
378 return (uint32_t)mScratchSize;
379 }
380
381 uint32_t
382 AMDILMachineFunctionInfo::getStackSize()
383 {
384 if (mStackSize == -1) {
385 uint32_t privSize = 0;
386 const MachineFrameInfo *MFI = mMF->getFrameInfo();
387 privSize = MFI->getOffsetAdjustment() + MFI->getStackSize();
388 const AMDILTargetMachine *TM =
389 reinterpret_cast<const AMDILTargetMachine*>(&mMF->getTarget());
390 bool addStackSize = TM->getOptLevel() == CodeGenOpt::None;
391 Function::const_arg_iterator I = mMF->getFunction()->arg_begin();
392 Function::const_arg_iterator Ie = mMF->getFunction()->arg_end();
393 while (I != Ie) {
394 Type *curType = I->getType();
395 ++I;
396 if (dyn_cast<PointerType>(curType)) {
397 Type *CT = dyn_cast<PointerType>(curType)->getElementType();
398 if (CT->isStructTy()
399 && dyn_cast<PointerType>(curType)->getAddressSpace()
400 == AMDILAS::PRIVATE_ADDRESS) {
401 addStackSize = true;
402 }
403 }
404 }
405 if (addStackSize) {
406 privSize += getScratchSize();
407 }
408 mStackSize = privSize;
409 }
410 return (uint32_t)mStackSize;
411
412 }
413
414 uint32_t
415 AMDILMachineFunctionInfo::addi32Literal(uint32_t val, int Opcode) {
416 // Since we have emulated 16/8/1 bit register types with a 32bit real
417 // register, we need to sign extend the constants to 32bits in order for
418 // comparisons against the constants to work correctly, this fixes some issues
419 // we had in conformance failing for saturation.
420 if (Opcode == AMDIL::LOADCONST_i16) {
421 val = (((int32_t)val << 16) >> 16);
422 } else if (Opcode == AMDIL::LOADCONST_i8) {
423 val = (((int32_t)val << 24) >> 24);
424 }
425 if (mIntLits.find(val) == mIntLits.end()) {
426 mIntLits[val] = getNumLiterals();
427 }
428 return mIntLits[val];
429 }
430
431 uint32_t
432 AMDILMachineFunctionInfo::addi64Literal(uint64_t val) {
433 if (mLongLits.find(val) == mLongLits.end()) {
434 mLongLits[val] = getNumLiterals();
435 }
436 return mLongLits[val];
437 }
438
439 uint32_t
440 AMDILMachineFunctionInfo::addi128Literal(uint64_t val_lo, uint64_t val_hi) {
441 std::pair<uint64_t, uint64_t> a;
442 a.first = val_lo;
443 a.second = val_hi;
444 if (mVecLits.find(a) == mVecLits.end()) {
445 mVecLits[a] = getNumLiterals();
446 }
447 return mVecLits[a];
448 }
449
450 uint32_t
451 AMDILMachineFunctionInfo::addf32Literal(const ConstantFP *CFP) {
452 uint32_t val = (uint32_t)CFP->getValueAPF().bitcastToAPInt().getZExtValue();
453 if (mIntLits.find(val) == mIntLits.end()) {
454 mIntLits[val] = getNumLiterals();
455 }
456 return mIntLits[val];
457 }
458
459 uint32_t
460 AMDILMachineFunctionInfo::addf64Literal(const ConstantFP *CFP) {
461 union dtol_union {
462 double d;
463 uint64_t ul;
464 } dval;
465 const APFloat &APF = CFP->getValueAPF();
466 if (&APF.getSemantics() == (const llvm::fltSemantics *)&APFloat::IEEEsingle) {
467 float fval = APF.convertToFloat();
468 dval.d = (double)fval;
469 } else {
470 dval.d = APF.convertToDouble();
471 }
472 if (mLongLits.find(dval.ul) == mLongLits.end()) {
473 mLongLits[dval.ul] = getNumLiterals();
474 }
475 return mLongLits[dval.ul];
476 }
477
478 uint32_t
479 AMDILMachineFunctionInfo::getIntLits(uint32_t offset)
480 {
481 return mIntLits[offset];
482 }
483
484 uint32_t
485 AMDILMachineFunctionInfo::getLongLits(uint64_t offset)
486 {
487 return mLongLits[offset];
488 }
489
490 uint32_t
491 AMDILMachineFunctionInfo::getVecLits(uint64_t low64, uint64_t high64)
492 {
493 return mVecLits[std::pair<uint64_t, uint64_t>(low64, high64)];
494 }
495
496 size_t
497 AMDILMachineFunctionInfo::getNumLiterals() const {
498 return mLongLits.size() + mIntLits.size() + mVecLits.size() + mReservedLits;
499 }
500
501 void
502 AMDILMachineFunctionInfo::addReservedLiterals(uint32_t size)
503 {
504 mReservedLits += size;
505 }
506
507 uint32_t
508 AMDILMachineFunctionInfo::addSampler(std::string name, uint32_t val)
509 {
510 if (mSamplerMap.find(name) != mSamplerMap.end()) {
511 SamplerInfo newVal = mSamplerMap[name];
512 assert(newVal.val == val
513 && "Found a sampler with same name but different values!");
514 return mSamplerMap[name].idx;
515 } else {
516 SamplerInfo curVal;
517 curVal.name = name;
518 curVal.val = val;
519 curVal.idx = mSamplerMap.size();
520 mSamplerMap[name] = curVal;
521 return curVal.idx;
522 }
523 }
524
525 void
526 AMDILMachineFunctionInfo::setUsesMem(unsigned id) {
527 assert(id < AMDILDevice::MAX_IDS &&
528 "Must set the ID to be less than MAX_IDS!");
529 mUsedMem[id] = true;
530 }
531
532 bool
533 AMDILMachineFunctionInfo::usesMem(unsigned id) {
534 assert(id < AMDILDevice::MAX_IDS &&
535 "Must set the ID to be less than MAX_IDS!");
536 return mUsedMem[id];
537 }
538
539 void
540 AMDILMachineFunctionInfo::addErrorMsg(const char *msg, ErrorMsgEnum val)
541 {
542 if (val == DEBUG_ONLY) {
543 #if defined(DEBUG) || defined(_DEBUG)
544 mErrors.insert(msg);
545 #endif
546 } else if (val == RELEASE_ONLY) {
547 #if !defined(DEBUG) && !defined(_DEBUG)
548 mErrors.insert(msg);
549 #endif
550 } else if (val == ALWAYS) {
551 mErrors.insert(msg);
552 }
553 }
554
555 uint32_t
556 AMDILMachineFunctionInfo::addPrintfString(std::string &name, unsigned offset)
557 {
558 if (mPrintfMap.find(name) != mPrintfMap.end()) {
559 return mPrintfMap[name]->getPrintfID();
560 } else {
561 PrintfInfo *info = new PrintfInfo;
562 info->setPrintfID(mPrintfMap.size() + offset);
563 mPrintfMap[name] = info;
564 return info->getPrintfID();
565 }
566 }
567
568 void
569 AMDILMachineFunctionInfo::addPrintfOperand(std::string &name,
570 size_t idx,
571 uint32_t size)
572 {
573 mPrintfMap[name]->addOperand(idx, size);
574 }
575
576 void
577 AMDILMachineFunctionInfo::addMetadata(const char *md, bool kernelOnly)
578 {
579 addMetadata(std::string(md), kernelOnly);
580 }
581
582 void
583 AMDILMachineFunctionInfo::addMetadata(std::string md, bool kernelOnly)
584 {
585 if (kernelOnly) {
586 mMetadataKernel.push_back(md);
587 } else {
588 mMetadataFunc.insert(md);
589 }
590 }
591