1 //===-- AMDILMachineFunctionInfo.cpp - TODO: Add brief description -------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
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"
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())) {
36 void PrintfInfo::addOperand(size_t idx
, uint32_t size
) {
37 mOperands
.resize((unsigned)(idx
+ 1));
38 mOperands
[(unsigned)idx
] = size
;
41 uint32_t PrintfInfo::getPrintfID() {
45 void PrintfInfo::setPrintfID(uint32_t id
) {
49 size_t PrintfInfo::getNumOperands() {
50 return mOperands
.size();
53 uint32_t PrintfInfo::getOperandID(uint32_t idx
) {
54 return mOperands
[idx
];
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),
65 for (uint32_t x
= 0; x
< AMDILDevice::MAX_IDS
; ++x
) {
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),
83 for (uint32_t x
= 0; x
< AMDILDevice::MAX_IDS
; ++x
) {
87 const AMDILTargetMachine
*TM
=
88 reinterpret_cast<const AMDILTargetMachine
*>(&MF
.getTarget());
89 mSTM
= TM
->getSubtargetImpl();
96 AMDILMachineFunctionInfo::~AMDILMachineFunctionInfo()
98 for (std::map
<std::string
, PrintfInfo
*>::iterator pfb
= printf_begin(),
99 pfe
= printf_end(); pfb
!= pfe
; ++pfb
) {
104 AMDILMachineFunctionInfo::getCalleeSavedFrameSize() const
106 return CalleeSavedFrameSize
;
109 AMDILMachineFunctionInfo::setCalleeSavedFrameSize(unsigned int bytes
)
111 CalleeSavedFrameSize
= bytes
;
114 AMDILMachineFunctionInfo::getBytesToPopOnReturn() const
116 return BytesToPopOnReturn
;
119 AMDILMachineFunctionInfo::setBytesToPopOnReturn(unsigned int bytes
)
121 BytesToPopOnReturn
= bytes
;
124 AMDILMachineFunctionInfo::getDecorationStyle() const
126 return DecorationStyle
;
129 AMDILMachineFunctionInfo::setDecorationStyle(NameDecorationStyle style
)
131 DecorationStyle
= style
;
134 AMDILMachineFunctionInfo::getRAIndex() const
136 return ReturnAddrIndex
;
139 AMDILMachineFunctionInfo::setRAIndex(int index
)
141 ReturnAddrIndex
= index
;
144 AMDILMachineFunctionInfo::getTCReturnAddrDelta() const
146 return TailCallReturnAddrDelta
;
149 AMDILMachineFunctionInfo::setTCReturnAddrDelta(int delta
)
151 TailCallReturnAddrDelta
= delta
;
154 AMDILMachineFunctionInfo::getSRetReturnReg() const
156 return SRetReturnReg
;
159 AMDILMachineFunctionInfo::setSRetReturnReg(unsigned int reg
)
165 AMDILMachineFunctionInfo::setUsesLocal()
171 AMDILMachineFunctionInfo::usesLocal() const
177 AMDILMachineFunctionInfo::setHasLocalArg()
183 AMDILMachineFunctionInfo::hasLocalArg() const
191 AMDILMachineFunctionInfo::setUsesRegion()
197 AMDILMachineFunctionInfo::usesRegion() const
203 AMDILMachineFunctionInfo::setHasRegionArg()
209 AMDILMachineFunctionInfo::hasRegionArg() const
216 AMDILMachineFunctionInfo::usesHWConstant(std::string name
) const
218 const AMDILConstPtr
*curConst
= getConstPtr(mKernel
, name
);
220 return curConst
->usesHardware
;
227 AMDILMachineFunctionInfo::getLocal(uint32_t dim
)
229 if (mKernel
&& mKernel
->sgv
) {
230 AMDILKernelAttr
*sgv
= mKernel
->sgv
;
236 return sgv
->reqGroupSize
[dim
];
239 return sgv
->reqGroupSize
[0] * sgv
->reqGroupSize
[1] * sgv
->reqGroupSize
[2];
246 return mSTM
->getDefaultSize(0) *
247 mSTM
->getDefaultSize(1) *
248 mSTM
->getDefaultSize(2);
252 return mSTM
->getDefaultSize(dim
);
258 AMDILMachineFunctionInfo::isKernel() const
260 return mKernel
!= NULL
&& mKernel
->mKernel
;
264 AMDILMachineFunctionInfo::getKernel()
270 AMDILMachineFunctionInfo::getName()
273 return mMF
->getFunction()->getName();
280 AMDILMachineFunctionInfo::getArgSize()
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;
287 Type
* curType
= I
->getType();
288 if (curType
->isIntegerTy() || curType
->isFloatingPointTy()) {
290 } else if (const VectorType
*VT
= dyn_cast
<VectorType
>(curType
)) {
291 Type
*ET
= VT
->getElementType();
292 int numEle
= VT
->getNumElements();
293 switch (ET
->getPrimitiveSizeInBits()) {
298 Counter
+= ((numEle
+ 2) >> 2);
305 Counter
+= (numEle
>> 1);
312 Counter
+= ((numEle
+ 2) >> 2);
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
;
331 if (mSTM
->device()->isSupported(AMDILDeviceInfo::Images
)) {
334 addErrorMsg(amd::CompilerErrorMessage
[NO_IMAGE_SUPPORT
]);
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()
347 || PT
->getAddressSpace() != AMDILAS::PRIVATE_ADDRESS
) {
350 assert(0 && "Current type is not supported!");
351 addErrorMsg(amd::CompilerErrorMessage
[INTERNAL_ERROR
]);
354 assert(0 && "Current type is not supported!");
355 addErrorMsg(amd::CompilerErrorMessage
[INTERNAL_ERROR
]);
359 // Convert from slots to bytes by multiplying by 16(shift by 4).
360 mArgSize
= Counter
<< 4;
362 return (uint32_t)mArgSize
;
365 AMDILMachineFunctionInfo::getScratchSize()
367 if (mScratchSize
== -1) {
369 Function::const_arg_iterator I
= mMF
->getFunction()->arg_begin();
370 Function::const_arg_iterator Ie
= mMF
->getFunction()->arg_end();
372 Type
*curType
= I
->getType();
373 mScratchSize
+= ((getTypeSize(curType
) + 15) & ~15);
376 mScratchSize
+= ((mScratchSize
+ 15) & ~15);
378 return (uint32_t)mScratchSize
;
382 AMDILMachineFunctionInfo::getStackSize()
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();
394 Type
*curType
= I
->getType();
396 if (dyn_cast
<PointerType
>(curType
)) {
397 Type
*CT
= dyn_cast
<PointerType
>(curType
)->getElementType();
399 && dyn_cast
<PointerType
>(curType
)->getAddressSpace()
400 == AMDILAS::PRIVATE_ADDRESS
) {
406 privSize
+= getScratchSize();
408 mStackSize
= privSize
;
410 return (uint32_t)mStackSize
;
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);
425 if (mIntLits
.find(val
) == mIntLits
.end()) {
426 mIntLits
[val
] = getNumLiterals();
428 return mIntLits
[val
];
432 AMDILMachineFunctionInfo::addi64Literal(uint64_t val
) {
433 if (mLongLits
.find(val
) == mLongLits
.end()) {
434 mLongLits
[val
] = getNumLiterals();
436 return mLongLits
[val
];
440 AMDILMachineFunctionInfo::addi128Literal(uint64_t val_lo
, uint64_t val_hi
) {
441 std::pair
<uint64_t, uint64_t> a
;
444 if (mVecLits
.find(a
) == mVecLits
.end()) {
445 mVecLits
[a
] = getNumLiterals();
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();
456 return mIntLits
[val
];
460 AMDILMachineFunctionInfo::addf64Literal(const ConstantFP
*CFP
) {
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
;
470 dval
.d
= APF
.convertToDouble();
472 if (mLongLits
.find(dval
.ul
) == mLongLits
.end()) {
473 mLongLits
[dval
.ul
] = getNumLiterals();
475 return mLongLits
[dval
.ul
];
479 AMDILMachineFunctionInfo::getIntLits(uint32_t offset
)
481 return mIntLits
[offset
];
485 AMDILMachineFunctionInfo::getLongLits(uint64_t offset
)
487 return mLongLits
[offset
];
491 AMDILMachineFunctionInfo::getVecLits(uint64_t low64
, uint64_t high64
)
493 return mVecLits
[std::pair
<uint64_t, uint64_t>(low64
, high64
)];
497 AMDILMachineFunctionInfo::getNumLiterals() const {
498 return mLongLits
.size() + mIntLits
.size() + mVecLits
.size() + mReservedLits
;
502 AMDILMachineFunctionInfo::addReservedLiterals(uint32_t size
)
504 mReservedLits
+= size
;
508 AMDILMachineFunctionInfo::addSampler(std::string name
, uint32_t val
)
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
;
519 curVal
.idx
= mSamplerMap
.size();
520 mSamplerMap
[name
] = curVal
;
526 AMDILMachineFunctionInfo::setUsesMem(unsigned id
) {
527 assert(id
< AMDILDevice::MAX_IDS
&&
528 "Must set the ID to be less than MAX_IDS!");
533 AMDILMachineFunctionInfo::usesMem(unsigned id
) {
534 assert(id
< AMDILDevice::MAX_IDS
&&
535 "Must set the ID to be less than MAX_IDS!");
540 AMDILMachineFunctionInfo::addErrorMsg(const char *msg
, ErrorMsgEnum val
)
542 if (val
== DEBUG_ONLY
) {
543 #if defined(DEBUG) || defined(_DEBUG)
546 } else if (val
== RELEASE_ONLY
) {
547 #if !defined(DEBUG) && !defined(_DEBUG)
550 } else if (val
== ALWAYS
) {
556 AMDILMachineFunctionInfo::addPrintfString(std::string
&name
, unsigned offset
)
558 if (mPrintfMap
.find(name
) != mPrintfMap
.end()) {
559 return mPrintfMap
[name
]->getPrintfID();
561 PrintfInfo
*info
= new PrintfInfo
;
562 info
->setPrintfID(mPrintfMap
.size() + offset
);
563 mPrintfMap
[name
] = info
;
564 return info
->getPrintfID();
569 AMDILMachineFunctionInfo::addPrintfOperand(std::string
&name
,
573 mPrintfMap
[name
]->addOperand(idx
, size
);
577 AMDILMachineFunctionInfo::addMetadata(const char *md
, bool kernelOnly
)
579 addMetadata(std::string(md
), kernelOnly
);
583 AMDILMachineFunctionInfo::addMetadata(std::string md
, bool kernelOnly
)
586 mMetadataKernel
.push_back(md
);
588 mMetadataFunc
.insert(md
);