OSDN Git Service

radeonsi: initial WIP SI code
[android-x86/external-mesa.git] / src / gallium / drivers / radeon / AMDILModuleInfo.cpp
1 //===-- AMDILModuleInfo.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 "AMDILModuleInfo.h"
10 #include "AMDILDevices.h"
11 #include "AMDILKernel.h"
12 #include "AMDILSubtarget.h"
13
14 #include "AMDILAlgorithms.tpp"
15 #include "AMDILModuleInfo.h"
16 #include "AMDILDevices.h"
17 #include "AMDILKernel.h"
18 #include "AMDILSubtarget.h"
19 #include "AMDILUtilityFunctions.h"
20 #include "llvm/CodeGen/MachineConstantPool.h"
21 #include "llvm/Constants.h"
22 #include "llvm/DerivedTypes.h"
23 #include "llvm/Instructions.h"
24 #include "llvm/Support/FormattedStream.h"
25
26 #include <cstdio>
27
28 #define CB_BASE_OFFSET 2
29 using namespace llvm;
30
31 AMDILModuleInfo::AMDILModuleInfo(const MachineModuleInfo &MMI)
32 {
33   mMMI = &MMI;
34   mOffset = 0;
35   mReservedBuffs = 0;
36   symTab = NULL;
37   mCurrentCPOffset = 0;
38   mPrintfOffset = 0;
39 }
40
41 AMDILModuleInfo::~AMDILModuleInfo() {
42   for (StringMap<AMDILKernel*>::iterator kb = mKernels.begin(), ke = mKernels.end();
43       kb != ke; ++kb) {
44     StringMapEntry<AMDILKernel*> cur = *kb;
45     AMDILKernel *ptr = cur.getValue();
46     delete ptr;
47   }
48 }
49
50 static const AMDILConstPtr *getConstPtr(const AMDILKernel *krnl, const std::string &arg) {
51   llvm::SmallVector<AMDILConstPtr, DEFAULT_VEC_SLOTS>::const_iterator begin, end;
52   for (begin = krnl->constPtr.begin(), end = krnl->constPtr.end();
53        begin != end; ++begin) {
54     if (!strcmp(begin->name.data(),arg.c_str())) {
55       return &(*begin);
56     }
57   }
58   return NULL;
59 }
60 #if 0
61 static bool structContainsSub32bitType(const StructType *ST) {
62   StructType::element_iterator eib, eie;
63   for (eib = ST->element_begin(), eie = ST->element_end(); eib != eie; ++eib) {
64     Type *ptr = *eib;
65     uint32_t size = (uint32_t)GET_SCALAR_SIZE(ptr);
66     if (!size) {
67       if (const StructType *ST = dyn_cast<StructType>(ptr)) {
68         if (structContainsSub32bitType(ST)) {
69           return true;
70         }
71       }
72     } else if (size < 32) {
73       return true;
74     }
75   }
76   return false;
77 }
78 #endif
79
80 void AMDILModuleInfo::processModule(const Module *M,
81                                        const AMDILTargetMachine *mTM)
82 {
83   Module::const_global_iterator GI;
84   Module::const_global_iterator GE;
85   mSTM = mTM->getSubtargetImpl();
86   for (GI = M->global_begin(), GE = M->global_end(); GI != GE; ++GI) {
87     const GlobalValue *GV = GI;
88     llvm::StringRef GVName = GV->getName();
89     const char *name = GVName.data();
90     if (!strncmp(name, "sgv", 3)) {
91       mKernelArgs[GVName] = parseSGV(GV);
92     } else if (!strncmp(name, "fgv", 3)) {
93       // we can ignore this since we don't care about the filename
94       // string
95     } else if (!strncmp(name, "lvgv", 4)) {
96       mLocalArgs[GVName] = parseLVGV(GV);
97     } else if (!strncmp(name, "llvm.image.annotations", 22)) {
98       parseImageAnnotate(GV);
99     } else if (!strncmp(name, "llvm.global.annotations", 23)) {
100       parseGlobalAnnotate(GV);
101     } else if (!strncmp(name, "llvm.constpointer.annotations", 29)) {
102       parseConstantPtrAnnotate(GV);
103     } else if (!strncmp(name, "llvm.readonlypointer.annotations", 32)) {
104       // These are skipped as we handle them later in AMDILPointerManager.cpp
105     } else if (GV->getType()->getAddressSpace() == 3) { // *** Match cl_kernel.h local AS #
106       parseAutoArray(GV, false);
107     } else if (strstr(name, "clregion")) {
108       parseAutoArray(GV, true);
109     } else if (!GV->use_empty()
110                && mIgnoreStr.find(GVName) == mIgnoreStr.end()) {
111       parseConstantPtr(GV);
112     }
113   }
114   allocateGlobalCB();
115
116   safeForEach(M->begin(), M->end(),
117       std::bind1st(
118         std::mem_fun(&AMDILModuleInfo::checkConstPtrsUseHW),
119         this));
120 }
121
122 void AMDILModuleInfo::allocateGlobalCB(void) {
123   uint32_t maxCBSize = mSTM->device()->getMaxCBSize();
124   uint32_t offset = 0;
125   uint32_t curCB = 0;
126   uint32_t swoffset = 0;
127   for (StringMap<AMDILConstPtr>::iterator cpb = mConstMems.begin(),
128        cpe = mConstMems.end(); cpb != cpe; ++cpb) {
129     bool constHW = mSTM->device()->usesHardware(AMDILDeviceInfo::ConstantMem);
130     cpb->second.usesHardware = false;
131     if (constHW) {
132       // If we have a limit on the max CB Size, then we need to make sure that
133       // the constant sizes fall within the limits.
134       if (cpb->second.size <= maxCBSize) {
135         if (offset + cpb->second.size > maxCBSize) {
136           offset = 0;
137           curCB++;
138         }
139         if (curCB < mSTM->device()->getMaxNumCBs()) {
140           cpb->second.cbNum = curCB + CB_BASE_OFFSET;
141           cpb->second.offset = offset;
142           offset += (cpb->second.size + 15) & (~15);
143           cpb->second.usesHardware = true;
144           continue;
145         }
146       }
147     }
148     cpb->second.cbNum = 0;
149     cpb->second.offset = swoffset;
150     swoffset += (cpb->second.size + 15) & (~15);
151   }
152   if (!mConstMems.empty()) {
153     mReservedBuffs = curCB + 1;
154   }
155 }
156
157 bool AMDILModuleInfo::checkConstPtrsUseHW(llvm::Module::const_iterator *FCI)
158 {
159   Function::const_arg_iterator AI, AE;
160   const Function *func = *FCI;
161   std::string name = func->getName();
162   if (!strstr(name.c_str(), "__OpenCL")
163       || !strstr(name.c_str(), "_AMDILKernel")) {
164     return false;
165   }
166   AMDILKernel *krnl = mKernels[name];
167   if (mSTM->device()->usesHardware(AMDILDeviceInfo::ConstantMem)) {
168     for (AI = func->arg_begin(), AE = func->arg_end();
169          AI != AE; ++AI) {
170       const Argument *Arg = &(*AI);
171       const PointerType *P = dyn_cast<PointerType>(Arg->getType());
172       if (!P) {
173         continue;
174       }
175       if (P->getAddressSpace() != AMDILAS::CONSTANT_ADDRESS) {
176         continue;
177       }
178       const AMDILConstPtr *ptr = getConstPtr(krnl, Arg->getName());
179       if (ptr) {
180         continue;
181       }
182       AMDILConstPtr constAttr;
183       constAttr.name = Arg->getName();
184       constAttr.size = this->mSTM->device()->getMaxCBSize();
185       constAttr.base = Arg;
186       constAttr.isArgument = true;
187       constAttr.isArray = false;
188       constAttr.offset = 0;
189       constAttr.usesHardware =
190         mSTM->device()->usesHardware(AMDILDeviceInfo::ConstantMem);
191       if (constAttr.usesHardware) {
192         constAttr.cbNum = krnl->constPtr.size() + 2;
193       } else {
194         constAttr.cbNum = 0;
195       }
196       krnl->constPtr.push_back(constAttr);
197     }
198   }
199   // Now lets make sure that only the N largest buffers
200   // get allocated in hardware if we have too many buffers
201   uint32_t numPtrs = krnl->constPtr.size();
202   if (numPtrs > (this->mSTM->device()->getMaxNumCBs() - mReservedBuffs)) {
203     // TODO: Change this routine so it sorts
204     // AMDILConstPtr instead of pulling the sizes out
205     // and then grab the N largest and disable the rest
206     llvm::SmallVector<uint32_t, 16> sizes;
207     for (uint32_t x = 0; x < numPtrs; ++x) {
208       sizes.push_back(krnl->constPtr[x].size);
209     }
210     std::sort(sizes.begin(), sizes.end());
211     uint32_t numToDisable = numPtrs - (mSTM->device()->getMaxNumCBs() -
212                                        mReservedBuffs);
213     uint32_t safeSize = sizes[numToDisable-1];
214     for (uint32_t x = 0; x < numPtrs && numToDisable; ++x) {
215       if (krnl->constPtr[x].size <= safeSize) {
216         krnl->constPtr[x].usesHardware = false;
217         --numToDisable;
218       }
219     }
220   }
221   // Renumber all of the valid CB's so that
222   // they are linear increase
223   uint32_t CBid = 2 + mReservedBuffs;
224   for (uint32_t x = 0; x < numPtrs; ++x) {
225     if (krnl->constPtr[x].usesHardware) {
226       krnl->constPtr[x].cbNum = CBid++;
227     }
228   }
229   for (StringMap<AMDILConstPtr>::iterator cpb = mConstMems.begin(),
230        cpe = mConstMems.end(); cpb != cpe; ++cpb) {
231     if (cpb->second.usesHardware) {
232       krnl->constPtr.push_back(cpb->second);
233     }
234   }
235   for (uint32_t x = 0; x < krnl->constPtr.size(); ++x) {
236     AMDILConstPtr &c = krnl->constPtr[x];
237     uint32_t cbNum = c.cbNum - CB_BASE_OFFSET;
238     if (cbNum < HW_MAX_NUM_CB && c.cbNum >= CB_BASE_OFFSET) {
239       if ((c.size + c.offset) > krnl->constSizes[cbNum]) {
240         krnl->constSizes[cbNum] =
241           ((c.size + c.offset) + 15) & ~15;
242       }
243     } else {
244       krnl->constPtr[x].usesHardware = false;
245     }
246   }
247   return false;
248 }
249
250 int32_t AMDILModuleInfo::getArrayOffset(const llvm::StringRef &a) const {
251   StringMap<AMDILArrayMem>::const_iterator iter = mArrayMems.find(a);
252   if (iter != mArrayMems.end()) {
253     return iter->second.offset;
254   } else {
255     return -1;
256   }
257 }
258
259 int32_t AMDILModuleInfo::getConstOffset(const llvm::StringRef &a) const {
260   StringMap<AMDILConstPtr>::const_iterator iter = mConstMems.find(a);
261   if (iter != mConstMems.end()) {
262     return iter->second.offset;
263   } else {
264     return -1;
265   }
266 }
267
268 bool AMDILModuleInfo::getConstHWBit(const llvm::StringRef &name) const {
269   StringMap<AMDILConstPtr>::const_iterator iter = mConstMems.find(name);
270   if (iter != mConstMems.end()) {
271     return iter->second.usesHardware;
272   } else {
273     return false;
274   }
275 }
276
277 // As of right now we only care about the required group size
278 // so we can skip the variable encoding
279 AMDILKernelAttr AMDILModuleInfo::parseSGV(const GlobalValue *G) {
280   AMDILKernelAttr nArg;
281   const GlobalVariable *GV = dyn_cast<GlobalVariable>(G);
282   memset(&nArg, 0, sizeof(nArg));
283   for (int x = 0; x < 3; ++x) {
284     nArg.reqGroupSize[x] = mSTM->getDefaultSize(x);
285     nArg.reqRegionSize[x] = mSTM->getDefaultSize(x);
286   }
287   if (!GV || !GV->hasInitializer()) {
288     return nArg;
289   }
290   const Constant *CV = GV->getInitializer();
291   const ConstantDataArray *CA = dyn_cast_or_null<ConstantDataArray>(CV);
292   if (!CA || !CA->isString()) {
293     return nArg;
294   }
295   std::string init = CA->getAsString();
296   size_t pos = init.find("RWG");
297   if (pos != llvm::StringRef::npos) {
298     pos += 3;
299     std::string LWS = init.substr(pos, init.length() - pos);
300     const char *lws = LWS.c_str();
301     sscanf(lws, "%u,%u,%u", &(nArg.reqGroupSize[0]),
302            &(nArg.reqGroupSize[1]),
303            &(nArg.reqGroupSize[2]));
304     nArg.mHasRWG = true;
305   }
306   pos = init.find("RWR");
307   if (pos != llvm::StringRef::npos) {
308     pos += 3;
309     std::string LWS = init.substr(pos, init.length() - pos);
310     const char *lws = LWS.c_str();
311     sscanf(lws, "%u,%u,%u", &(nArg.reqRegionSize[0]),
312            &(nArg.reqRegionSize[1]),
313            &(nArg.reqRegionSize[2]));
314     nArg.mHasRWR = true;
315   }
316   return nArg;
317 }
318
319 AMDILLocalArg AMDILModuleInfo::parseLVGV(const GlobalValue *G) {
320   AMDILLocalArg nArg;
321   const GlobalVariable *GV = dyn_cast<GlobalVariable>(G);
322   nArg.name = "";
323   if (!GV || !GV->hasInitializer()) {
324     return nArg;
325   }
326   const ConstantArray *CA =
327     dyn_cast_or_null<ConstantArray>(GV->getInitializer());
328   if (!CA) {
329     return nArg;
330   }
331   for (size_t x = 0, y = CA->getNumOperands(); x < y; ++x) {
332     const Value *local = CA->getOperand(x);
333     const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(local);
334     if (!CE || !CE->getNumOperands()) {
335       continue;
336     }
337     nArg.name = (*(CE->op_begin()))->getName();
338     if (mArrayMems.find(nArg.name) != mArrayMems.end()) {
339       nArg.local.push_back(&(mArrayMems[nArg.name]));
340     }
341   }
342   return nArg;
343 }
344
345 void AMDILModuleInfo::parseConstantPtrAnnotate(const GlobalValue *G) {
346   const GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(G);
347   const ConstantArray *CA =
348     dyn_cast_or_null<ConstantArray>(GV->getInitializer());
349   if (!CA) {
350     return;
351   }
352   uint32_t numOps = CA->getNumOperands();
353   for (uint32_t x = 0; x < numOps; ++x) {
354     const Value *V = CA->getOperand(x);
355     const ConstantStruct *CS = dyn_cast_or_null<ConstantStruct>(V);
356     if (!CS) {
357       continue;
358     }
359     assert(CS->getNumOperands() == 2 && "There can only be 2"
360            " fields, a name and size");
361     const ConstantExpr *nameField = dyn_cast<ConstantExpr>(CS->getOperand(0));
362     const ConstantInt *sizeField = dyn_cast<ConstantInt>(CS->getOperand(1));
363     assert(nameField && "There must be a constant name field");
364     assert(sizeField && "There must be a constant size field");
365     const GlobalVariable *nameGV =
366       dyn_cast<GlobalVariable>(nameField->getOperand(0));
367     const ConstantDataArray *nameArray =
368       dyn_cast<ConstantDataArray>(nameGV->getInitializer());
369     // Lets add this string to the set of strings we should ignore processing
370     mIgnoreStr.insert(nameGV->getName());
371     if (mConstMems.find(nameGV->getName())
372         != mConstMems.end()) {
373       // If we already processesd this string as a constant, lets remove it from
374       // the list of known constants.  This way we don't process unneeded data
375       // and don't generate code/metadata for strings that are never used.
376       mConstMems.erase(mConstMems.find(nameGV->getName()));
377     } else {
378       mIgnoreStr.insert(CS->getOperand(0)->getName());
379     }
380     AMDILConstPtr constAttr;
381     constAttr.name = nameArray->getAsString();
382     constAttr.size = (sizeField->getZExtValue() + 15) & ~15;
383     constAttr.base = CS;
384     constAttr.isArgument = true;
385     constAttr.isArray = false;
386     constAttr.cbNum = 0;
387     constAttr.offset = 0;
388     constAttr.usesHardware = (constAttr.size <= mSTM->device()->getMaxCBSize());
389     // Now that we have all our constant information,
390     // lets update the AMDILKernel
391     llvm::StringRef  AMDILKernelName = G->getName().data() + 30;
392     AMDILKernel *k;
393     if (mKernels.find(AMDILKernelName) != mKernels.end()) {
394       k = mKernels[AMDILKernelName];
395     } else {
396       k = new AMDILKernel;
397       k->curSize = 0;
398       k->curRSize = 0;
399       k->curHWSize = 0;
400       k->curHWRSize = 0;
401       k->constSize = 0;
402       k->lvgv = NULL;
403       k->sgv = NULL;
404       memset(k->constSizes, 0, sizeof(uint32_t) * HW_MAX_NUM_CB);
405     }
406     constAttr.cbNum = k->constPtr.size() + 2;
407     k->constPtr.push_back(constAttr);
408     mKernels[AMDILKernelName] = k;
409   }
410 }
411
412 void AMDILModuleInfo::parseImageAnnotate(const GlobalValue *G) {
413   const GlobalVariable *GV = dyn_cast<GlobalVariable>(G);
414   const ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer());
415   if (!CA) {
416     return;
417   }
418   if (isa<GlobalValue>(CA)) {
419     return;
420   }
421   uint32_t e = CA->getNumOperands();
422   if (!e) {
423     return;
424   }
425   AMDILKernel *k;
426   llvm::StringRef name = G->getName().data() + 23;
427   if (mKernels.find(name) != mKernels.end()) {
428     k = mKernels[name];
429   } else {
430     k = new AMDILKernel;
431     k->curSize = 0;
432     k->curRSize = 0;
433     k->curHWSize = 0;
434     k->curHWRSize = 0;
435     k->constSize = 0;
436     k->lvgv = NULL;
437     k->sgv = NULL;
438     memset(k->constSizes, 0, sizeof(uint32_t) * HW_MAX_NUM_CB);
439   }
440   for (uint32_t i = 0; i != e; ++i) {
441     const Value *V = CA->getOperand(i);
442     const Constant *C = dyn_cast<Constant>(V);
443     const ConstantStruct *CS = dyn_cast<ConstantStruct>(C);
444     if (CS && CS->getNumOperands() == 2) {
445       if (mConstMems.find(CS->getOperand(0)->getOperand(0)->getName()) !=
446           mConstMems.end()) {
447         // If we already processesd this string as a constant, lets remove it
448         // from the list of known constants.  This way we don't process unneeded
449         // data and don't generate code/metadata for strings that are never
450         // used.
451         mConstMems.erase(
452             mConstMems.find(CS->getOperand(0)->getOperand(0)->getName()));
453       } else {
454         mIgnoreStr.insert(CS->getOperand(0)->getOperand(0)->getName());
455       }
456       const ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(1));
457       uint32_t val = (uint32_t)CI->getZExtValue();
458       if (val == 1) {
459         k->readOnly.insert(i);
460       } else if (val == 2) {
461         k->writeOnly.insert(i);
462       } else {
463         assert(!"Unknown image type value!");
464       }
465     }
466   }
467   mKernels[name] = k;
468 }
469
470 void AMDILModuleInfo::parseAutoArray(const GlobalValue *GV, bool isRegion) {
471   const GlobalVariable *G = dyn_cast<GlobalVariable>(GV);
472   Type *Ty = (G) ? G->getType() : NULL;
473   AMDILArrayMem tmp;
474   tmp.isHW = true;
475   tmp.offset = 0;
476   tmp.vecSize = getTypeSize(Ty, true);
477   tmp.isRegion = isRegion;
478   mArrayMems[GV->getName()] = tmp;
479 }
480
481 void AMDILModuleInfo::parseConstantPtr(const GlobalValue *GV) {
482   const GlobalVariable *G = dyn_cast<GlobalVariable>(GV);
483   Type *Ty = (G) ? G->getType() : NULL;
484   AMDILConstPtr constAttr;
485   constAttr.name = G->getName();
486   constAttr.size = getTypeSize(Ty, true);
487   constAttr.base = GV;
488   constAttr.isArgument = false;
489   constAttr.isArray = true;
490   constAttr.offset = 0;
491   constAttr.cbNum = 0;
492   constAttr.usesHardware = false;
493   mConstMems[GV->getName()] = constAttr;
494 }
495
496 void AMDILModuleInfo::parseGlobalAnnotate(const GlobalValue *G) {
497   const GlobalVariable *GV = dyn_cast<GlobalVariable>(G);
498   if (!GV->hasInitializer()) {
499     return;
500   }
501   const Constant *CT = GV->getInitializer();
502   if (!CT || isa<GlobalValue>(CT)) {
503     return;
504   }
505   const ConstantArray *CA = dyn_cast<ConstantArray>(CT);
506   if (!CA) {
507     return;
508   }
509
510   unsigned int nKernels = CA->getNumOperands();
511   for (unsigned int i = 0, e = nKernels; i != e; ++i) {
512     parseKernelInformation(CA->getOperand(i));
513   }
514 }
515
516 void AMDILModuleInfo::parseKernelInformation(const Value *V) {
517   if (isa<GlobalValue>(V)) {
518     return;
519   }
520   const ConstantStruct *CS = dyn_cast_or_null<ConstantStruct>(V);
521   if (!CS) {
522     return;
523   }
524   uint32_t N = CS->getNumOperands();
525   if (N != 5) {
526     return;
527   }
528   AMDILKernel *tmp;
529
530   // The first operand is always a pointer to the AMDILKernel.
531   const Constant *CV = dyn_cast<Constant>(CS->getOperand(0));
532   llvm::StringRef AMDILKernelName = "";
533   if (CV->getNumOperands()) {
534     AMDILKernelName = (*(CV->op_begin()))->getName();
535   }
536
537   // If we have images, then we have already created the AMDILKernel and we just need
538   // to get the AMDILKernel information.
539   if (mKernels.find(AMDILKernelName) != mKernels.end()) {
540     tmp = mKernels[AMDILKernelName];
541   } else {
542     tmp = new AMDILKernel;
543     tmp->curSize = 0;
544     tmp->curRSize = 0;
545     tmp->curHWSize = 0;
546     tmp->curHWRSize = 0;
547     tmp->constSize = 0;
548     tmp->lvgv = NULL;
549     tmp->sgv = NULL;
550     memset(tmp->constSizes, 0, sizeof(uint32_t) * HW_MAX_NUM_CB);
551   }
552
553
554   // The second operand is SGV, there can only be one so we don't need to worry
555   // about parsing out multiple data points.
556   CV = dyn_cast<Constant>(CS->getOperand(1));
557
558   llvm::StringRef sgvName;
559   if (CV->getNumOperands()) {
560     sgvName = (*(CV->op_begin()))->getName();
561   }
562
563   if (mKernelArgs.find(sgvName) != mKernelArgs.end()) {
564     tmp->sgv = &mKernelArgs[sgvName];
565   }
566   // The third operand is FGV, which is skipped
567   // The fourth operand is LVGV
568   // There can be multiple local arrays, so we
569   // need to handle each one seperatly
570   CV = dyn_cast<Constant>(CS->getOperand(3));
571   llvm::StringRef lvgvName = "";
572   if (CV->getNumOperands()) {
573     lvgvName = (*(CV->op_begin()))->getName();
574   }
575   if (mLocalArgs.find(lvgvName) != mLocalArgs.end()) {
576     AMDILLocalArg *ptr = &mLocalArgs[lvgvName];
577     tmp->lvgv = ptr;
578     llvm::SmallVector<AMDILArrayMem *, DEFAULT_VEC_SLOTS>::iterator ib, ie;
579     for (ib = ptr->local.begin(), ie = ptr->local.end(); ib != ie; ++ib) {
580       if ((*ib)->isRegion) {
581         if ((*ib)->isHW) {
582           (*ib)->offset = tmp->curHWRSize;
583           tmp->curHWRSize += ((*ib)->vecSize + 15) & ~15;
584         } else {
585           (*ib)->offset = tmp->curRSize;
586           tmp->curRSize += ((*ib)->vecSize + 15) & ~15;
587         }
588       } else {
589         if ((*ib)->isHW) {
590           (*ib)->offset = tmp->curHWSize;
591           tmp->curHWSize += ((*ib)->vecSize + 15) & ~15;
592         } else {
593           (*ib)->offset = tmp->curSize;
594           tmp->curSize += ((*ib)->vecSize + 15) & ~15;
595         }
596       }
597     }
598   }
599
600   // The fifth operand is NULL
601   mKernels[AMDILKernelName] = tmp;
602 }
603
604 AMDILKernel *
605 AMDILModuleInfo::getKernel(const llvm::StringRef &name) {
606   StringMap<AMDILKernel*>::iterator iter = mKernels.find(name);
607   if (iter == mKernels.end()) {
608       return NULL; 
609   } else {
610     return iter->second;
611   }
612 }
613
614 bool AMDILModuleInfo::isKernel(const llvm::StringRef &name) const {
615   return (mKernels.find(name) != mKernels.end());
616 }
617
618 bool AMDILModuleInfo::isWriteOnlyImage(const llvm::StringRef &name,
619                                           uint32_t iID) const {
620   const StringMap<AMDILKernel*>::const_iterator kiter = mKernels.find(name);
621   if (kiter == mKernels.end()) {
622     return false;
623   }
624   return kiter->second->writeOnly.count(iID);
625 }
626 #if 0
627 uint32_t
628 AMDILModuleInfo::getNumWriteImages(const llvm::StringRef &name) const {
629   char *env = NULL;
630   env = getenv("GPU_DISABLE_RAW_UAV");
631   if (env && env[0] == '1') {
632     return 8;
633   }
634   const StringMap<AMDILKernel*>::const_iterator kiter = mKernels.find(name);
635   if (kiter == mKernels.end()) {
636     return 0;
637   } else {
638     return kiter->second->writeOnly.size();
639   }
640 }
641 #endif
642 bool AMDILModuleInfo::isReadOnlyImage(const llvm::StringRef &name,
643                                          uint32_t iID) const {
644   const StringMap<AMDILKernel*>::const_iterator kiter = mKernels.find(name);
645   if (kiter == mKernels.end()) {
646     return false;
647   }
648   return kiter->second->readOnly.count(iID);
649 }
650 #if 0
651 bool AMDILModuleInfo::hasRWG(const llvm::StringRef &name) const {
652   StringMap<AMDILKernel*>::const_iterator iter = mKernels.find(name);
653   if (iter != mKernels.end()) {
654     AMDILKernelAttr *ptr = iter->second->sgv;
655     if (ptr) {
656       return ptr->mHasRWG;
657     }
658   }
659   return false;
660 }
661
662 bool AMDILModuleInfo::hasRWR(const llvm::StringRef &name) const {
663   StringMap<AMDILKernel*>::const_iterator iter = mKernels.find(name);
664   if (iter != mKernels.end()) {
665     AMDILKernelAttr *ptr = iter->second->sgv;
666     if (ptr) {
667       return ptr->mHasRWR;
668     }
669   }
670   return false;
671 }
672
673 uint32_t
674 AMDILModuleInfo::getMaxGroupSize(const llvm::StringRef &name) const {
675   StringMap<AMDILKernel*>::const_iterator iter = mKernels.find(name);
676   if (iter != mKernels.end()) {
677     AMDILKernelAttr *sgv = iter->second->sgv;
678     if (sgv) {
679       return sgv->reqGroupSize[0] * sgv->reqGroupSize[1] * sgv->reqGroupSize[2];
680     }
681   }
682   return mSTM->getDefaultSize(0) *
683          mSTM->getDefaultSize(1) *
684          mSTM->getDefaultSize(2);
685 }
686
687 uint32_t
688 AMDILModuleInfo::getMaxRegionSize(const llvm::StringRef &name) const {
689   StringMap<AMDILKernel*>::const_iterator iter = mKernels.find(name);
690   if (iter != mKernels.end()) {
691     AMDILKernelAttr *sgv = iter->second->sgv;
692     if (sgv) {
693       return sgv->reqRegionSize[0] *
694              sgv->reqRegionSize[1] *
695              sgv->reqRegionSize[2];
696     }
697   }
698   return mSTM->getDefaultSize(0) *
699          mSTM->getDefaultSize(1) *
700          mSTM->getDefaultSize(2);
701 }
702 uint32_t AMDILModuleInfo::getRegionSize(const llvm::StringRef &name) const {
703   StringMap<AMDILKernel*>::const_iterator iter = mKernels.find(name);
704   if (iter != mKernels.end()) {
705     return iter->second->curRSize;
706   } else {
707     return 0;
708   }
709 }
710
711 uint32_t AMDILModuleInfo::getLocalSize(const llvm::StringRef &name) const {
712   StringMap<AMDILKernel*>::const_iterator iter = mKernels.find(name);
713   if (iter != mKernels.end()) {
714     return iter->second->curSize;
715   } else {
716     return 0;
717   }
718 }
719
720 uint32_t AMDILModuleInfo::getConstSize(const llvm::StringRef &name) const {
721   StringMap<AMDILKernel*>::const_iterator iter = mKernels.find(name);
722   if (iter != mKernels.end()) {
723     return iter->second->constSize;
724   } else {
725     return 0;
726   }
727 }
728
729 uint32_t
730 AMDILModuleInfo::getHWRegionSize(const llvm::StringRef &name) const {
731   StringMap<AMDILKernel*>::const_iterator iter = mKernels.find(name);
732   if (iter != mKernels.end()) {
733     return iter->second->curHWRSize;
734   } else {
735     return 0;
736   }
737 }
738
739 uint32_t AMDILModuleInfo::getHWLocalSize(const llvm::StringRef &name) const {
740   StringMap<AMDILKernel*>::const_iterator iter = mKernels.find(name);
741   if (iter != mKernels.end()) {
742     return iter->second->curHWSize;
743   } else {
744     return 0;
745   }
746 }
747 #endif
748
749 int32_t AMDILModuleInfo::getArgID(const Argument *arg) {
750   DenseMap<const Argument *, int32_t>::iterator argiter = mArgIDMap.find(arg);
751   if (argiter != mArgIDMap.end()) {
752     return argiter->second;
753   } else {
754     return -1;
755   }
756 }
757
758
759 uint32_t
760 AMDILModuleInfo::getRegion(const llvm::StringRef &name, uint32_t dim) const {
761   StringMap<AMDILKernel*>::const_iterator iter = mKernels.find(name);
762   if (iter != mKernels.end() && iter->second->sgv) {
763     AMDILKernelAttr *sgv = iter->second->sgv;
764     switch (dim) {
765     default: break;
766     case 0:
767     case 1:
768     case 2:
769       return sgv->reqRegionSize[dim];
770       break;
771     case 3:
772       return sgv->reqRegionSize[0] *
773              sgv->reqRegionSize[1] *
774              sgv->reqRegionSize[2];
775     };
776   }
777   switch (dim) {
778   default:
779     return 1;
780   case 3:
781     return mSTM->getDefaultSize(0) *
782            mSTM->getDefaultSize(1) *
783            mSTM->getDefaultSize(2);
784   case 2:
785   case 1:
786   case 0:
787     return mSTM->getDefaultSize(dim);
788     break;
789   };
790   return 1;
791 }
792
793 StringMap<AMDILConstPtr>::iterator AMDILModuleInfo::consts_begin() {
794   return mConstMems.begin();
795 }
796
797
798 StringMap<AMDILConstPtr>::iterator AMDILModuleInfo::consts_end() {
799   return mConstMems.end();
800 }
801
802 bool AMDILModuleInfo::byteStoreExists(StringRef S) const {
803   return mByteStore.find(S) != mByteStore.end();
804 }
805
806 uint32_t AMDILModuleInfo::getConstPtrSize(const AMDILKernel *krnl,
807                                              const llvm::StringRef &arg)
808 {
809   const AMDILConstPtr *curConst = getConstPtr(krnl, arg);
810   if (curConst) {
811     return curConst->size;
812   } else {
813     return 0;
814   }
815 }
816
817 uint32_t AMDILModuleInfo::getConstPtrOff(const AMDILKernel *krnl,
818                                             const llvm::StringRef &arg)
819 {
820   const AMDILConstPtr *curConst = getConstPtr(krnl, arg);
821   if (curConst) {
822     return curConst->offset;
823   } else {
824     return 0;
825   }
826 }
827
828 uint32_t AMDILModuleInfo::getConstPtrCB(const AMDILKernel *krnl,
829                                            const llvm::StringRef &arg)
830 {
831   const AMDILConstPtr *curConst = getConstPtr(krnl, arg);
832   if (curConst) {
833     return curConst->cbNum;
834   } else {
835     return 0;
836   }
837 }
838
839 void AMDILModuleInfo::calculateCPOffsets(const MachineFunction *MF,
840                                             AMDILKernel *krnl)
841 {
842   const MachineConstantPool *MCP = MF->getConstantPool();
843   if (!MCP) {
844     return;
845   }
846   const std::vector<MachineConstantPoolEntry> consts = MCP->getConstants();
847   size_t numConsts = consts.size();
848   for (size_t x = 0; x < numConsts; ++x) {
849     krnl->CPOffsets.push_back(
850         std::make_pair<uint32_t, const Constant*>(
851           mCurrentCPOffset, consts[x].Val.ConstVal));
852     size_t curSize = getTypeSize(consts[x].Val.ConstVal->getType(), true);
853     // Align the size to the vector boundary
854     curSize = (curSize + 15) & (~15);
855     mCurrentCPOffset += curSize;
856   }
857 }
858
859 bool AMDILModuleInfo::isConstPtrArray(const AMDILKernel *krnl,
860                                          const llvm::StringRef &arg) {
861   const AMDILConstPtr *curConst = getConstPtr(krnl, arg);
862   if (curConst) {
863     return curConst->isArray;
864   } else {
865     return false;
866   }
867 }
868
869 bool AMDILModuleInfo::isConstPtrArgument(const AMDILKernel *krnl,
870                                             const llvm::StringRef &arg)
871 {
872   const AMDILConstPtr *curConst = getConstPtr(krnl, arg);
873   if (curConst) {
874     return curConst->isArgument;
875   } else {
876     return false;
877   }
878 }
879
880 const Value *AMDILModuleInfo::getConstPtrValue(const AMDILKernel *krnl,
881                                                   const llvm::StringRef &arg) {
882   const AMDILConstPtr *curConst = getConstPtr(krnl, arg);
883   if (curConst) {
884     return curConst->base;
885   } else {
886     return NULL;
887   }
888 }
889
890 static void
891 dumpZeroElements(StructType * const T, llvm::raw_ostream &O, bool asBytes);
892 static void
893 dumpZeroElements(IntegerType * const T, llvm::raw_ostream &O, bool asBytes);
894 static void
895 dumpZeroElements(ArrayType * const T, llvm::raw_ostream &O, bool asBytes);
896 static void
897 dumpZeroElements(VectorType * const T, llvm::raw_ostream &O, bool asBytes);
898 static void
899 dumpZeroElements(Type * const T, llvm::raw_ostream &O, bool asBytes);
900
901 void dumpZeroElements(Type * const T, llvm::raw_ostream &O, bool asBytes) {
902   if (!T) {
903     return;
904   }
905   switch(T->getTypeID()) {
906   case Type::X86_FP80TyID:
907   case Type::FP128TyID:
908   case Type::PPC_FP128TyID:
909   case Type::LabelTyID:
910     assert(0 && "These types are not supported by this backend");
911   default:
912   case Type::DoubleTyID:
913     if (asBytes) {
914       O << ":0:0:0:0:0:0:0:0";
915     } else {
916       O << ":0";
917     }
918     break;
919   case Type::FloatTyID:
920   case Type::PointerTyID:
921   case Type::FunctionTyID:
922     if (asBytes) {
923       O << ":0:0:0:0";
924     } else {
925       O << ":0";
926     }
927   case Type::IntegerTyID:
928     dumpZeroElements(dyn_cast<IntegerType>(T), O, asBytes);
929     break;
930   case Type::StructTyID:
931     {
932       const StructType *ST = cast<StructType>(T);
933       if (!ST->isOpaque()) {
934         dumpZeroElements(dyn_cast<StructType>(T), O, asBytes);
935       } else { // A pre-LLVM 3.0 opaque type
936         if (asBytes) {
937           O << ":0:0:0:0";
938         } else {
939           O << ":0";
940         }
941       }
942     }
943     break;
944   case Type::ArrayTyID:
945     dumpZeroElements(dyn_cast<ArrayType>(T), O, asBytes);
946     break;
947   case Type::VectorTyID:
948     dumpZeroElements(dyn_cast<VectorType>(T), O, asBytes);
949     break;
950   };
951 }
952
953 void
954 dumpZeroElements(StructType * const ST, llvm::raw_ostream &O, bool asBytes) {
955   if (!ST) {
956     return;
957   }
958   Type *curType;
959   StructType::element_iterator eib = ST->element_begin();
960   StructType::element_iterator eie = ST->element_end();
961   for (;eib != eie; ++eib) {
962     curType = *eib;
963     dumpZeroElements(curType, O, asBytes);
964   }
965 }
966
967 void
968 dumpZeroElements(IntegerType * const IT, llvm::raw_ostream &O, bool asBytes) {
969   if (asBytes) {
970     unsigned byteWidth = (IT->getBitWidth() >> 3);
971     for (unsigned x = 0; x < byteWidth; ++x) {
972       O << ":0";
973     }
974   }
975 }
976
977 void
978 dumpZeroElements(ArrayType * const AT, llvm::raw_ostream &O, bool asBytes) {
979   size_t size = AT->getNumElements();
980   for (size_t x = 0; x < size; ++x) {
981     dumpZeroElements(AT->getElementType(), O, asBytes);
982   }
983 }
984
985 void
986 dumpZeroElements(VectorType * const VT, llvm::raw_ostream &O, bool asBytes) {
987   size_t size = VT->getNumElements();
988   for (size_t x = 0; x < size; ++x) {
989     dumpZeroElements(VT->getElementType(), O, asBytes);
990   }
991 }
992
993 void AMDILModuleInfo::printConstantValue(const Constant *CAval,
994                                             llvm::raw_ostream &O, bool asBytes) {
995   if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CAval)) {
996     bool isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble;
997     if (isDouble) {
998       double val = CFP->getValueAPF().convertToDouble();
999       union dtol_union {
1000         double d;
1001         uint64_t l;
1002         char c[8];
1003       } conv;
1004       conv.d = val;
1005       if (!asBytes) {
1006         O << ":";
1007         O.write_hex(conv.l);
1008       } else {
1009         for (int i = 0; i < 8; ++i) {
1010           O << ":";
1011           O.write_hex((unsigned)conv.c[i] & 0xFF);
1012         }
1013       }
1014     } else {
1015       float val = CFP->getValueAPF().convertToFloat();
1016       union ftoi_union {
1017         float f;
1018         uint32_t u;
1019         char c[4];
1020       } conv;
1021       conv.f = val;
1022       if (!asBytes) {
1023         O << ":";
1024         O.write_hex(conv.u);
1025       } else {
1026         for (int i = 0; i < 4; ++i) {
1027           O << ":";
1028           O.write_hex((unsigned)conv.c[i] & 0xFF);
1029         }
1030       }
1031     }
1032   } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CAval)) {
1033     uint64_t zVal = CI->getValue().getZExtValue();
1034     if (!asBytes) {
1035       O << ":";
1036       O.write_hex(zVal);
1037     } else {
1038       switch (CI->getBitWidth()) {
1039       default:
1040         {
1041           union ltob_union {
1042             uint64_t l;
1043             char c[8];
1044           } conv;
1045           conv.l = zVal;
1046           for (int i = 0; i < 8; ++i) {
1047             O << ":";
1048             O.write_hex((unsigned)conv.c[i] & 0xFF);
1049           }
1050         }
1051         break;
1052       case 8:
1053         O << ":";
1054         O.write_hex(zVal & 0xFF);
1055         break;
1056       case 16:
1057         {
1058           union stob_union {
1059             uint16_t s;
1060             char c[2];
1061           } conv;
1062           conv.s = (uint16_t)zVal;
1063           O << ":";
1064           O.write_hex((unsigned)conv.c[0] & 0xFF);
1065           O << ":";
1066           O.write_hex((unsigned)conv.c[1] & 0xFF);
1067         }
1068         break;
1069       case 32:
1070         {
1071           union itob_union {
1072             uint32_t i;
1073             char c[4];
1074           } conv;
1075           conv.i = (uint32_t)zVal;
1076           for (int i = 0; i < 4; ++i) {
1077             O << ":";
1078             O.write_hex((unsigned)conv.c[i] & 0xFF);
1079           }
1080         }
1081         break;
1082       }
1083     }
1084   } else if (const ConstantVector *CV = dyn_cast<ConstantVector>(CAval)) {
1085     int y = CV->getNumOperands()-1;
1086     int x = 0;
1087     for (; x < y; ++x) {
1088       printConstantValue(CV->getOperand(x), O, asBytes);
1089     }
1090     printConstantValue(CV->getOperand(x), O, asBytes);
1091   } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CAval)) {
1092     int y = CS->getNumOperands();
1093     int x = 0;
1094     for (; x < y; ++x) {
1095       printConstantValue(CS->getOperand(x), O, asBytes);
1096     }
1097   } else if (const ConstantAggregateZero *CAZ
1098       = dyn_cast<ConstantAggregateZero>(CAval)) {
1099     int y = CAZ->getNumOperands();
1100     if (y > 0) {
1101       int x = 0;
1102       for (; x < y; ++x) {
1103         printConstantValue((llvm::Constant *)CAZ->getOperand(x),
1104             O, asBytes);
1105       }
1106     } else {
1107       if (asBytes) {
1108         dumpZeroElements(CAval->getType(), O, asBytes);
1109       } else {
1110         int y = getNumElements(CAval->getType())-1;
1111         for (int x = 0; x < y; ++x) {
1112           O << ":0";
1113         }
1114         O << ":0";
1115       }
1116     }
1117   } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CAval)) {
1118     int y = CA->getNumOperands();
1119     int x = 0;
1120     for (; x < y; ++x) {
1121       printConstantValue(CA->getOperand(x), O, asBytes);
1122     }
1123   } else if (dyn_cast<ConstantPointerNull>(CAval)) {
1124     O << ":0";
1125     //assert(0 && "Hit condition which was not expected");
1126   } else if (dyn_cast<ConstantExpr>(CAval)) {
1127     O << ":0";
1128     //assert(0 && "Hit condition which was not expected");
1129   } else if (dyn_cast<UndefValue>(CAval)) {
1130     O << ":0";
1131     //assert(0 && "Hit condition which was not expected");
1132   } else {
1133     assert(0 && "Hit condition which was not expected");
1134   }
1135 }
1136 #if 0
1137 static bool isStruct(Type * const T)
1138 {
1139   if (!T) {
1140     return false;
1141   }
1142   switch (T->getTypeID()) {
1143   default:
1144     return false;
1145   case Type::PointerTyID:
1146     return isStruct(T->getContainedType(0));
1147   case Type::StructTyID:
1148     return true;
1149   case Type::ArrayTyID:
1150   case Type::VectorTyID:
1151     return isStruct(dyn_cast<SequentialType>(T)->getElementType());
1152   };
1153
1154 }
1155
1156 void AMDILModuleInfo::dumpDataToCB(llvm::raw_ostream &O, AMDILKernelManager *km,
1157                                       uint32_t id) {
1158   uint32_t size = 0;
1159   for (StringMap<AMDILConstPtr>::iterator cmb = consts_begin(),
1160       cme = consts_end(); cmb != cme; ++cmb) {
1161     if (id == cmb->second.cbNum) {
1162       size += (cmb->second.size + 15) & (~15);
1163     }
1164   }
1165   if (id == 0) {
1166     O << ";#DATASTART:" << (size + mCurrentCPOffset) << "\n";
1167     if (mCurrentCPOffset) {
1168       for (StringMap<AMDILKernel*>::iterator kcpb = mKernels.begin(),
1169           kcpe = mKernels.end(); kcpb != kcpe; ++kcpb) {
1170         const AMDILKernel *k = kcpb->second;
1171         size_t numConsts = k->CPOffsets.size();
1172         for (size_t x = 0; x < numConsts; ++x) {
1173           size_t offset = k->CPOffsets[x].first;
1174           const Constant *C = k->CPOffsets[x].second;
1175           Type *Ty = C->getType();
1176           size_t size = (isStruct(Ty) ? getTypeSize(Ty, true)
1177                                       : getNumElements(Ty));
1178           O << ";#" << km->getTypeName(Ty, symTab) << ":";
1179           O << offset << ":" << size ;
1180           printConstantValue(C, O, isStruct(Ty));
1181           O << "\n";
1182         }
1183       }
1184     }
1185   } else {
1186     O << ";#DATASTART:" << id << ":" << size << "\n";
1187   }
1188
1189   for (StringMap<AMDILConstPtr>::iterator cmb = consts_begin(), cme = consts_end();
1190        cmb != cme; ++cmb) {
1191     if (cmb->second.cbNum != id) {
1192       continue;
1193     }
1194     const GlobalVariable *G = dyn_cast<GlobalVariable>(cmb->second.base);
1195     Type *Ty = (G) ? G->getType() : NULL;
1196     size_t offset = cmb->second.offset;
1197     const Constant *C = G->getInitializer();
1198     size_t size = (isStruct(Ty)
1199         ? getTypeSize(Ty, true)
1200         : getNumElements(Ty));
1201     O << ";#" << km->getTypeName(Ty, symTab) << ":";
1202     if (!id) {
1203       O << (offset + mCurrentCPOffset) << ":" << size;
1204     } else {
1205       O << offset << ":" << size;
1206     }
1207     if (C) {
1208       printConstantValue(C, O, isStruct(Ty));
1209     } else {
1210       assert(0 && "Cannot have a constant pointer"
1211           " without an initializer!");
1212     }
1213     O <<"\n";
1214   }
1215   if (id == 0) {
1216     O << ";#DATAEND\n";
1217   } else {
1218     O << ";#DATAEND:" << id << "\n";
1219   }
1220 }
1221
1222 void
1223 AMDILModuleInfo::dumpDataSection(llvm::raw_ostream &O, AMDILKernelManager *km) {
1224   if (mConstMems.empty() && !mCurrentCPOffset) {
1225     return;
1226   } else {
1227     llvm::DenseSet<uint32_t> const_set;
1228     for (StringMap<AMDILConstPtr>::iterator cmb = consts_begin(), cme = consts_end();
1229          cmb != cme; ++cmb) {
1230       const_set.insert(cmb->second.cbNum);
1231     }
1232     if (mCurrentCPOffset) {
1233       const_set.insert(0);
1234     }
1235     for (llvm::DenseSet<uint32_t>::iterator setb = const_set.begin(),
1236            sete = const_set.end(); setb != sete; ++setb) {
1237       dumpDataToCB(O, km, *setb);
1238     }
1239   }
1240 }
1241 #endif
1242 /// Create a function ID if it is not known or return the known
1243 /// function ID.
1244 uint32_t AMDILModuleInfo::getOrCreateFunctionID(const GlobalValue* func) {
1245   if (func->getName().size()) {
1246     return getOrCreateFunctionID(func->getName());
1247   } 
1248   uint32_t id;
1249   if (mFuncPtrNames.find(func) == mFuncPtrNames.end()) {
1250     id = mFuncPtrNames.size() + RESERVED_FUNCS + mFuncNames.size();
1251     mFuncPtrNames[func] = id;
1252   } else {
1253     id = mFuncPtrNames[func];
1254   }
1255   return id;
1256 }
1257 uint32_t AMDILModuleInfo::getOrCreateFunctionID(const std::string &func) {
1258   uint32_t id;
1259   if (mFuncNames.find(func) == mFuncNames.end()) {
1260     id = mFuncNames.size() + RESERVED_FUNCS + mFuncPtrNames.size();
1261     mFuncNames[func] = id;
1262   } else {
1263     id = mFuncNames[func];
1264   }
1265   return id;
1266 }