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 "AMDILModuleInfo.h"
12 #include "AMDILSubtarget.h"
13 #include "AMDILTargetMachine.h"
14 #include "AMDILUtilityFunctions.h"
15 #include "llvm/ADT/StringExtras.h"
16 #include "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/CodeGen/MachineModuleInfo.h"
18 #include "llvm/Constants.h"
19 #include "llvm/DerivedTypes.h"
20 #include "llvm/Function.h"
21 #include "llvm/Instructions.h"
22 #include "llvm/Support/FormattedStream.h"
26 static const AMDILConstPtr
*getConstPtr(const AMDILKernel
*krnl
, const std::string
&arg
) {
27 llvm::SmallVector
<AMDILConstPtr
, DEFAULT_VEC_SLOTS
>::const_iterator begin
, end
;
28 for (begin
= krnl
->constPtr
.begin(), end
= krnl
->constPtr
.end();
29 begin
!= end
; ++begin
) {
30 if (!strcmp(begin
->name
.data(),arg
.c_str())) {
37 void PrintfInfo::addOperand(size_t idx
, uint32_t size
) {
38 mOperands
.resize((unsigned)(idx
+ 1));
39 mOperands
[(unsigned)idx
] = size
;
42 uint32_t PrintfInfo::getPrintfID() {
46 void PrintfInfo::setPrintfID(uint32_t id
) {
50 size_t PrintfInfo::getNumOperands() {
51 return mOperands
.size();
54 uint32_t PrintfInfo::getOperandID(uint32_t idx
) {
55 return mOperands
[idx
];
58 AMDILMachineFunctionInfo::AMDILMachineFunctionInfo()
59 : CalleeSavedFrameSize(0), BytesToPopOnReturn(0),
60 DecorationStyle(None
), ReturnAddrIndex(0),
61 TailCallReturnAddrDelta(0),
62 SRetReturnReg(0), UsesLDS(false), LDSArg(false),
63 UsesGDS(false), GDSArg(false),
66 for (uint32_t x
= 0; x
< AMDILDevice::MAX_IDS
; ++x
) {
76 AMDILMachineFunctionInfo::AMDILMachineFunctionInfo(MachineFunction
& MF
)
77 : CalleeSavedFrameSize(0), BytesToPopOnReturn(0),
78 DecorationStyle(None
), ReturnAddrIndex(0),
79 TailCallReturnAddrDelta(0),
80 SRetReturnReg(0), UsesLDS(false), LDSArg(false),
81 UsesGDS(false), GDSArg(false),
84 for (uint32_t x
= 0; x
< AMDILDevice::MAX_IDS
; ++x
) {
87 const Function
*F
= MF
.getFunction();
89 MachineModuleInfo
&mmi
= MF
.getMMI();
90 const AMDILTargetMachine
*TM
=
91 reinterpret_cast<const AMDILTargetMachine
*>(&MF
.getTarget());
92 AMDILModuleInfo
*AMI
= &(mmi
.getObjFileInfo
<AMDILModuleInfo
>());
93 AMI
->processModule(mmi
.getModule(), TM
);
94 mSTM
= TM
->getSubtargetImpl();
95 mKernel
= AMI
->getKernel(F
->getName());
102 AMDILMachineFunctionInfo::~AMDILMachineFunctionInfo()
104 for (std::map
<std::string
, PrintfInfo
*>::iterator pfb
= printf_begin(),
105 pfe
= printf_end(); pfb
!= pfe
; ++pfb
) {
110 AMDILMachineFunctionInfo::getCalleeSavedFrameSize() const
112 return CalleeSavedFrameSize
;
115 AMDILMachineFunctionInfo::setCalleeSavedFrameSize(unsigned int bytes
)
117 CalleeSavedFrameSize
= bytes
;
120 AMDILMachineFunctionInfo::getBytesToPopOnReturn() const
122 return BytesToPopOnReturn
;
125 AMDILMachineFunctionInfo::setBytesToPopOnReturn(unsigned int bytes
)
127 BytesToPopOnReturn
= bytes
;
130 AMDILMachineFunctionInfo::getDecorationStyle() const
132 return DecorationStyle
;
135 AMDILMachineFunctionInfo::setDecorationStyle(NameDecorationStyle style
)
137 DecorationStyle
= style
;
140 AMDILMachineFunctionInfo::getRAIndex() const
142 return ReturnAddrIndex
;
145 AMDILMachineFunctionInfo::setRAIndex(int index
)
147 ReturnAddrIndex
= index
;
150 AMDILMachineFunctionInfo::getTCReturnAddrDelta() const
152 return TailCallReturnAddrDelta
;
155 AMDILMachineFunctionInfo::setTCReturnAddrDelta(int delta
)
157 TailCallReturnAddrDelta
= delta
;
160 AMDILMachineFunctionInfo::getSRetReturnReg() const
162 return SRetReturnReg
;
165 AMDILMachineFunctionInfo::setSRetReturnReg(unsigned int reg
)
171 AMDILMachineFunctionInfo::setUsesLocal()
177 AMDILMachineFunctionInfo::usesLocal() const
183 AMDILMachineFunctionInfo::setHasLocalArg()
189 AMDILMachineFunctionInfo::hasLocalArg() const
197 AMDILMachineFunctionInfo::setUsesRegion()
203 AMDILMachineFunctionInfo::usesRegion() const
209 AMDILMachineFunctionInfo::setHasRegionArg()
215 AMDILMachineFunctionInfo::hasRegionArg() const
222 AMDILMachineFunctionInfo::usesHWConstant(std::string name
) const
224 const AMDILConstPtr
*curConst
= getConstPtr(mKernel
, name
);
226 return curConst
->usesHardware
;
233 AMDILMachineFunctionInfo::getLocal(uint32_t dim
)
235 if (mKernel
&& mKernel
->sgv
) {
236 AMDILKernelAttr
*sgv
= mKernel
->sgv
;
242 return sgv
->reqGroupSize
[dim
];
245 return sgv
->reqGroupSize
[0] * sgv
->reqGroupSize
[1] * sgv
->reqGroupSize
[2];
252 return mSTM
->getDefaultSize(0) *
253 mSTM
->getDefaultSize(1) *
254 mSTM
->getDefaultSize(2);
258 return mSTM
->getDefaultSize(dim
);
264 AMDILMachineFunctionInfo::isKernel() const
266 return mKernel
!= NULL
&& mKernel
->mKernel
;
270 AMDILMachineFunctionInfo::getKernel()
276 AMDILMachineFunctionInfo::getName()
279 return mMF
->getFunction()->getName();
286 AMDILMachineFunctionInfo::getArgSize()
288 if (mArgSize
== -1) {
289 Function::const_arg_iterator I
= mMF
->getFunction()->arg_begin();
290 Function::const_arg_iterator Ie
= mMF
->getFunction()->arg_end();
291 uint32_t Counter
= 0;
293 Type
* curType
= I
->getType();
294 if (curType
->isIntegerTy() || curType
->isFloatingPointTy()) {
296 } else if (const VectorType
*VT
= dyn_cast
<VectorType
>(curType
)) {
297 Type
*ET
= VT
->getElementType();
298 int numEle
= VT
->getNumElements();
299 switch (ET
->getPrimitiveSizeInBits()) {
304 Counter
+= ((numEle
+ 2) >> 2);
311 Counter
+= (numEle
>> 1);
318 Counter
+= ((numEle
+ 2) >> 2);
325 } else if (const PointerType
*PT
= dyn_cast
<PointerType
>(curType
)) {
326 Type
*CT
= PT
->getElementType();
327 const StructType
*ST
= dyn_cast
<StructType
>(CT
);
328 if (ST
&& ST
->isOpaque()) {
329 bool i1d
= ST
->getName() == "struct._image1d_t";
330 bool i1da
= ST
->getName() == "struct._image1d_array_t";
331 bool i1db
= ST
->getName() == "struct._image1d_buffer_t";
332 bool i2d
= ST
->getName() == "struct._image2d_t";
333 bool i2da
= ST
->getName() == "struct._image2d_array_t";
334 bool i3d
= ST
->getName() == "struct._image3d_t";
335 bool is_image
= i1d
|| i1da
|| i1db
|| i2d
|| i2da
|| i3d
;
337 if (mSTM
->device()->isSupported(AMDILDeviceInfo::Images
)) {
340 addErrorMsg(amd::CompilerErrorMessage
[NO_IMAGE_SUPPORT
]);
345 } else if (CT
->isStructTy()
346 && PT
->getAddressSpace() == AMDILAS::PRIVATE_ADDRESS
) {
347 StructType
*ST
= dyn_cast
<StructType
>(CT
);
348 Counter
+= ((getTypeSize(ST
) + 15) & ~15) >> 4;
349 } else if (CT
->isIntOrIntVectorTy()
350 || CT
->isFPOrFPVectorTy()
353 || PT
->getAddressSpace() != AMDILAS::PRIVATE_ADDRESS
) {
356 assert(0 && "Current type is not supported!");
357 addErrorMsg(amd::CompilerErrorMessage
[INTERNAL_ERROR
]);
360 assert(0 && "Current type is not supported!");
361 addErrorMsg(amd::CompilerErrorMessage
[INTERNAL_ERROR
]);
365 // Convert from slots to bytes by multiplying by 16(shift by 4).
366 mArgSize
= Counter
<< 4;
368 return (uint32_t)mArgSize
;
371 AMDILMachineFunctionInfo::getScratchSize()
373 if (mScratchSize
== -1) {
375 Function::const_arg_iterator I
= mMF
->getFunction()->arg_begin();
376 Function::const_arg_iterator Ie
= mMF
->getFunction()->arg_end();
378 Type
*curType
= I
->getType();
379 mScratchSize
+= ((getTypeSize(curType
) + 15) & ~15);
382 mScratchSize
+= ((mScratchSize
+ 15) & ~15);
384 return (uint32_t)mScratchSize
;
388 AMDILMachineFunctionInfo::getStackSize()
390 if (mStackSize
== -1) {
391 uint32_t privSize
= 0;
392 const MachineFrameInfo
*MFI
= mMF
->getFrameInfo();
393 privSize
= MFI
->getOffsetAdjustment() + MFI
->getStackSize();
394 const AMDILTargetMachine
*TM
=
395 reinterpret_cast<const AMDILTargetMachine
*>(&mMF
->getTarget());
396 bool addStackSize
= TM
->getOptLevel() == CodeGenOpt::None
;
397 Function::const_arg_iterator I
= mMF
->getFunction()->arg_begin();
398 Function::const_arg_iterator Ie
= mMF
->getFunction()->arg_end();
400 Type
*curType
= I
->getType();
402 if (dyn_cast
<PointerType
>(curType
)) {
403 Type
*CT
= dyn_cast
<PointerType
>(curType
)->getElementType();
405 && dyn_cast
<PointerType
>(curType
)->getAddressSpace()
406 == AMDILAS::PRIVATE_ADDRESS
) {
412 privSize
+= getScratchSize();
414 mStackSize
= privSize
;
416 return (uint32_t)mStackSize
;
421 AMDILMachineFunctionInfo::addi32Literal(uint32_t val
, int Opcode
) {
422 // Since we have emulated 16/8/1 bit register types with a 32bit real
423 // register, we need to sign extend the constants to 32bits in order for
424 // comparisons against the constants to work correctly, this fixes some issues
425 // we had in conformance failing for saturation.
426 if (Opcode
== AMDIL::LOADCONST_i16
) {
427 val
= (((int32_t)val
<< 16) >> 16);
428 } else if (Opcode
== AMDIL::LOADCONST_i8
) {
429 val
= (((int32_t)val
<< 24) >> 24);
431 if (mIntLits
.find(val
) == mIntLits
.end()) {
432 mIntLits
[val
] = getNumLiterals();
434 return mIntLits
[val
];
438 AMDILMachineFunctionInfo::addi64Literal(uint64_t val
) {
439 if (mLongLits
.find(val
) == mLongLits
.end()) {
440 mLongLits
[val
] = getNumLiterals();
442 return mLongLits
[val
];
446 AMDILMachineFunctionInfo::addi128Literal(uint64_t val_lo
, uint64_t val_hi
) {
447 std::pair
<uint64_t, uint64_t> a
;
450 if (mVecLits
.find(a
) == mVecLits
.end()) {
451 mVecLits
[a
] = getNumLiterals();
457 AMDILMachineFunctionInfo::addf32Literal(const ConstantFP
*CFP
) {
458 uint32_t val
= (uint32_t)CFP
->getValueAPF().bitcastToAPInt().getZExtValue();
459 if (mIntLits
.find(val
) == mIntLits
.end()) {
460 mIntLits
[val
] = getNumLiterals();
462 return mIntLits
[val
];
466 AMDILMachineFunctionInfo::addf64Literal(const ConstantFP
*CFP
) {
471 const APFloat
&APF
= CFP
->getValueAPF();
472 if (&APF
.getSemantics() == (const llvm::fltSemantics
*)&APFloat::IEEEsingle
) {
473 float fval
= APF
.convertToFloat();
474 dval
.d
= (double)fval
;
476 dval
.d
= APF
.convertToDouble();
478 if (mLongLits
.find(dval
.ul
) == mLongLits
.end()) {
479 mLongLits
[dval
.ul
] = getNumLiterals();
481 return mLongLits
[dval
.ul
];
485 AMDILMachineFunctionInfo::getIntLits(uint32_t offset
)
487 return mIntLits
[offset
];
491 AMDILMachineFunctionInfo::getLongLits(uint64_t offset
)
493 return mLongLits
[offset
];
497 AMDILMachineFunctionInfo::getVecLits(uint64_t low64
, uint64_t high64
)
499 return mVecLits
[std::pair
<uint64_t, uint64_t>(low64
, high64
)];
503 AMDILMachineFunctionInfo::getNumLiterals() const {
504 return mLongLits
.size() + mIntLits
.size() + mVecLits
.size() + mReservedLits
;
508 AMDILMachineFunctionInfo::addReservedLiterals(uint32_t size
)
510 mReservedLits
+= size
;
514 AMDILMachineFunctionInfo::addSampler(std::string name
, uint32_t val
)
516 if (mSamplerMap
.find(name
) != mSamplerMap
.end()) {
517 SamplerInfo newVal
= mSamplerMap
[name
];
518 assert(newVal
.val
== val
519 && "Found a sampler with same name but different values!");
520 return mSamplerMap
[name
].idx
;
525 curVal
.idx
= mSamplerMap
.size();
526 mSamplerMap
[name
] = curVal
;
532 AMDILMachineFunctionInfo::setUsesMem(unsigned id
) {
533 assert(id
< AMDILDevice::MAX_IDS
&&
534 "Must set the ID to be less than MAX_IDS!");
539 AMDILMachineFunctionInfo::usesMem(unsigned id
) {
540 assert(id
< AMDILDevice::MAX_IDS
&&
541 "Must set the ID to be less than MAX_IDS!");
546 AMDILMachineFunctionInfo::addErrorMsg(const char *msg
, ErrorMsgEnum val
)
548 if (val
== DEBUG_ONLY
) {
549 #if defined(DEBUG) || defined(_DEBUG)
552 } else if (val
== RELEASE_ONLY
) {
553 #if !defined(DEBUG) && !defined(_DEBUG)
556 } else if (val
== ALWAYS
) {
562 AMDILMachineFunctionInfo::addPrintfString(std::string
&name
, unsigned offset
)
564 if (mPrintfMap
.find(name
) != mPrintfMap
.end()) {
565 return mPrintfMap
[name
]->getPrintfID();
567 PrintfInfo
*info
= new PrintfInfo
;
568 info
->setPrintfID(mPrintfMap
.size() + offset
);
569 mPrintfMap
[name
] = info
;
570 return info
->getPrintfID();
575 AMDILMachineFunctionInfo::addPrintfOperand(std::string
&name
,
579 mPrintfMap
[name
]->addOperand(idx
, size
);
583 AMDILMachineFunctionInfo::addMetadata(const char *md
, bool kernelOnly
)
585 addMetadata(std::string(md
), kernelOnly
);
589 AMDILMachineFunctionInfo::addMetadata(std::string md
, bool kernelOnly
)
592 mMetadataKernel
.push_back(md
);
594 mMetadataFunc
.insert(md
);