gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
hsail_code.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2015 Advanced Micro Devices, Inc.
3  * All rights reserved.
4  *
5  * For use for simulation and test purposes only
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its contributors
18  * may be used to endorse or promote products derived from this software
19  * without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Author: Steve Reinhardt
34  */
35 
37 
38 #include "arch/gpu_types.hh"
39 #include "arch/hsail/Brig.h"
40 #include "arch/hsail/operand.hh"
41 #include "config/the_gpu_isa.hh"
42 #include "debug/BRIG.hh"
43 #include "debug/HSAILObject.hh"
47 
48 using namespace Brig;
49 
51 
52 HsailCode::HsailCode(const std::string &name_str)
53  : HsaCode(name_str), private_size(-1), readonly_size(-1)
54 {
55 }
56 
57 void
59  StorageMap *objStorageMap)
60 {
61  storageMap = objStorageMap;
62 
63  // set pointer so that decoding process can find this kernel context when
64  // needed
65  obj->currentCode = this;
66 
67  if (code_dir->base.kind != BRIG_KIND_DIRECTIVE_FUNCTION &&
68  code_dir->base.kind != BRIG_KIND_DIRECTIVE_KERNEL) {
69  fatal("unexpected directive kind %d inside kernel/function init\n",
70  code_dir->base.kind);
71  }
72 
73  DPRINTF(HSAILObject, "Initializing code, first code block entry is: %d\n",
74  code_dir->firstCodeBlockEntry);
75 
76  // clear these static vars so we can properly track the max index
77  // for this kernel
81  setPrivateSize(0);
82 
83  const BrigBase *entryPtr = brigNext((BrigBase*)code_dir);
84  const BrigBase *endPtr =
85  obj->getCodeSectionEntry(code_dir->nextModuleEntry);
86 
87  // the instruction's byte address (relative to the base addr
88  // of the code section)
89  int inst_addr = 0;
90  // the index that points to the instruction in the instruction
91  // array
92  int inst_idx = 0;
93  std::vector<GPUStaticInst*> instructions;
94  int funcarg_size_scope = 0;
95 
96  // walk through instructions in code section and directives in
97  // directive section in parallel, processing directives that apply
98  // when we reach the relevant code point.
99  while (entryPtr < endPtr) {
100  switch (entryPtr->kind) {
102  {
103  const BrigDirectiveVariable *sym =
104  (const BrigDirectiveVariable*)entryPtr;
105 
106  DPRINTF(HSAILObject,"Initializing code, directive is "
107  "kind_variable, symbol is: %s\n",
108  obj->getString(sym->name));
109 
110  StorageElement *se = storageMap->addSymbol(sym, obj);
111 
112  if (sym->segment == BRIG_SEGMENT_PRIVATE) {
113  setPrivateSize(se->size);
114  } else { // spill
115  funcarg_size_scope += se->size;
116  }
117  }
118  break;
119 
121  {
122  const BrigDirectiveLabel *lbl =
123  (const BrigDirectiveLabel*)entryPtr;
124 
125  DPRINTF(HSAILObject,"Initializing code, directive is "
126  "kind_label, label is: %s \n",
127  obj->getString(lbl->name));
128 
129  labelMap.addLabel(lbl, inst_addr, obj);
130  }
131  break;
132 
134  {
135  DPRINTF(HSAILObject, "Initializing code, directive "
136  "is kind_pragma\n");
137  }
138  break;
139 
141  {
142  DPRINTF(HSAILObject, "Initializing code, directive is "
143  "kind_comment\n");
144  }
145  break;
146 
148  {
149  DPRINTF(HSAILObject, "Initializing code, directive is "
150  "kind_arg_block_start\n");
151 
153  funcarg_size_scope = 0;
154  }
155  break;
156 
158  {
159  DPRINTF(HSAILObject, "Initializing code, directive is "
160  "kind_arg_block_end\n");
161 
162  funcarg_size = funcarg_size < funcarg_size_scope ?
163  funcarg_size_scope : funcarg_size;
164  }
165  break;
166 
168  DPRINTF(HSAILObject, "Initializing code, dircetive is "
169  "kind_end\n");
170 
171  break;
172 
173  default:
174  if (entryPtr->kind >= BRIG_KIND_INST_BEGIN &&
175  entryPtr->kind <= BRIG_KIND_INST_END) {
176 
177  BrigInstBase *instPtr = (BrigInstBase*)entryPtr;
178  TheGpuISA::MachInst machInst = { instPtr, obj };
179  GPUStaticInst *iptr = decoder.decode(machInst);
180 
181  if (iptr) {
182  DPRINTF(HSAILObject, "Initializing code, processing inst "
183  "byte addr #%d idx %d: OPCODE=%d\n", inst_addr,
184  inst_idx, instPtr->opcode);
185 
186  TheGpuISA::RawMachInst raw_inst = decoder.saveInst(iptr);
187  iptr->instNum(inst_idx);
188  iptr->instAddr(inst_addr);
189  _insts.push_back(raw_inst);
190  instructions.push_back(iptr);
191  }
192  inst_addr += sizeof(TheGpuISA::RawMachInst);
193  ++inst_idx;
194  } else if (entryPtr->kind >= BRIG_KIND_OPERAND_BEGIN &&
195  entryPtr->kind < BRIG_KIND_OPERAND_END) {
196  warn("unexpected operand entry in code segment\n");
197  } else {
198  // there are surely some more cases we will need to handle,
199  // but we'll deal with them as we find them.
200  fatal("unexpected directive kind %d inside kernel scope\n",
201  entryPtr->kind);
202  }
203  }
204 
205  entryPtr = brigNext(entryPtr);
206  }
207 
208  // compute Control Flow Graph for current kernel
210 
214 
215  obj->currentCode = nullptr;
216 }
217 
218 HsailCode::HsailCode(const std::string &name_str,
219  const BrigDirectiveExecutable *code_dir,
220  const BrigObject *obj, StorageMap *objStorageMap)
221  : HsaCode(name_str), private_size(-1), readonly_size(-1)
222 {
223  init(code_dir, obj, objStorageMap);
224 }
225 
226 void
227 LabelMap::addLabel(const Brig::BrigDirectiveLabel *lblDir, int inst_index,
228  const BrigObject *obj)
229 {
230  std::string lbl_name = obj->getString(lblDir->name);
231  Label &lbl = map[lbl_name];
232 
233  if (lbl.defined()) {
234  fatal("Attempt to redefine existing label %s\n", lbl_name);
235  }
236 
237  lbl.define(lbl_name, inst_index);
238  DPRINTF(HSAILObject, "label %s = %d\n", lbl_name, inst_index);
239 }
240 
241 Label*
243  const BrigObject *obj)
244 {
245  std::string name = obj->getString(lblDir->name);
246  Label &lbl = map[name];
247  lbl.checkName(name);
248 
249  return &lbl;
250 }
251 
252 int
254 {
255  switch (t) {
256  case BRIG_TYPE_S8:
257  case BRIG_TYPE_U8:
258  case BRIG_TYPE_B8:
259  return 1;
260 
261  case BRIG_TYPE_S16:
262  case BRIG_TYPE_U16:
263  case BRIG_TYPE_B16:
264  case BRIG_TYPE_F16:
265  return 2;
266 
267  case BRIG_TYPE_S32:
268  case BRIG_TYPE_U32:
269  case BRIG_TYPE_B32:
270  case BRIG_TYPE_F32:
271  return 4;
272 
273  case BRIG_TYPE_S64:
274  case BRIG_TYPE_U64:
275  case BRIG_TYPE_B64:
276  case BRIG_TYPE_F64:
277  return 8;
278 
279  case BRIG_TYPE_B1:
280 
281  default:
282  fatal("unhandled symbol data type %d", t);
283  return 0;
284  }
285 }
286 
289  const BrigObject *obj)
290 {
291  const char *sym_name = obj->getString(sym->name);
292  uint64_t size = 0;
293  uint64_t offset = 0;
294 
295  if (sym->type & BRIG_TYPE_ARRAY) {
296  size = getBrigDataTypeBytes(sym->type & ~BRIG_TYPE_ARRAY);
297  size *= (((uint64_t)sym->dim.hi) << 32 | (uint64_t)sym->dim.lo);
298 
300  ~BRIG_TYPE_ARRAY));
301  } else {
302  size = getBrigDataTypeBytes(sym->type);
303  offset = roundUp(nextOffset, getBrigDataTypeBytes(sym->type));
304  }
305 
306  nextOffset = offset + size;
307 
308  DPRINTF(HSAILObject, "Adding %s SYMBOL %s size %d offset 0x%x, init: %d\n",
309  segmentNames[segment], sym_name, size, offset, sym->init);
310 
311  StorageElement* se = new StorageElement(sym_name, offset, size, sym);
312  elements.push_back(se);
313  elements_by_addr.insert(AddrRange(offset, offset + size - 1), se);
314  elements_by_brigptr[sym] = se;
315 
316  return se;
317 }
318 
321 {
322  for (auto it : elements) {
323  if (it->name == name) {
324  return it;
325  }
326  }
327 
328  return nullptr;
329 }
330 
333 {
334  assert(elements_by_addr.size() > 0);
335 
336  auto se = elements_by_addr.find(addr);
337 
338  if (se == elements_by_addr.end()) {
339  return nullptr;
340  } else {
341  return se->second;
342  }
343 }
344 
347 {
348  assert(elements_by_brigptr.size() > 0);
349 
350  auto se = elements_by_brigptr.find(brigptr);
351 
352  if (se == elements_by_brigptr.end()) {
353  return nullptr;
354  } else {
355  return se->second;
356  }
357 }
358 
360  : outerScopeMap(outerScope)
361 {
362  for (int i = 0; i < NumSegments; ++i)
363  space[i] = new StorageSpace((BrigSegment)i);
364 }
365 
368 {
369  BrigSegment8_t segment = sym->segment;
370 
371  assert(segment >= Brig::BRIG_SEGMENT_FLAT);
372  assert(segment < NumSegments);
373 
374  return space[segment]->addSymbol(sym, obj);
375 }
376 
377 int
379 {
380  assert(segment > Brig::BRIG_SEGMENT_GLOBAL);
381  assert(segment < NumSegments);
382 
383  if (segment != Brig::BRIG_SEGMENT_GROUP &&
384  segment != Brig::BRIG_SEGMENT_READONLY) {
385  return space[segment]->getSize();
386  } else {
387  int ret = space[segment]->getSize();
388 
389  if (outerScopeMap) {
390  ret += outerScopeMap->getSize(segment);
391  }
392 
393  return ret;
394  }
395 }
396 
397 void
399 {
400  space[segment]->resetOffset();
401 }
402 
405 {
406  StorageElement *se = space[segment]->findSymbol(name);
407 
408  if (se)
409  return se;
410 
411  if (outerScopeMap)
412  return outerScopeMap->findSymbol(segment, name);
413 
414  return nullptr;
415 }
416 
419 {
420  StorageSpace *sp = space[segment];
421 
422  if (!sp) {
423  // there is no memory in segment?
424  return nullptr;
425  }
426 
427  StorageElement *se = sp->findSymbol(addr);
428 
429  if (se)
430  return se;
431 
432  if (outerScopeMap)
433  return outerScopeMap->findSymbol(segment, addr);
434 
435  return nullptr;
436 
437 }
438 
441  const BrigDirectiveVariable *brigptr)
442 {
443  StorageSpace *sp = space[segment];
444 
445  if (!sp) {
446  // there is no memory in segment?
447  return nullptr;
448  }
449 
450  StorageElement *se = sp->findSymbol(brigptr);
451 
452  if (se)
453  return se;
454 
455  if (outerScopeMap)
456  return outerScopeMap->findSymbol(segment, brigptr);
457 
458  return nullptr;
459 
460 }
const_iterator end() const
HsailCode * currentCode
Definition: brig_object.hh:118
#define DPRINTF(x,...)
Definition: trace.hh:212
const_iterator insert(const AddrRange &r, const V &d)
int getSize(Brig::BrigSegment segment)
Definition: hsail_code.cc:378
BrigDataOffsetString32_t name
Definition: Brig.h:1268
int getBrigDataTypeBytes(BrigType16_t t)
Definition: hsail_code.cc:253
Defines classes encapsulating HSAIL instruction operands.
const std::string & name()
Definition: trace.cc:49
Bitfield< 7 > i
Definition: miscregs.hh:1378
Label * refLabel(const Brig::BrigDirectiveLabel *lbl, const BrigObject *obj)
Definition: hsail_code.cc:242
void instAddr(int inst_addr)
StorageElement * addSymbol(const Brig::BrigDirectiveVariable *sym, const BrigObject *obj)
Definition: hsail_code.cc:367
BrigOperandOffset32_t init
Definition: Brig.h:1290
ip6_addr_t addr
Definition: inet.hh:335
void checkName(std::string &_name)
Definition: hsail_code.hh:179
Bitfield< 0 > sp
Definition: miscregs.hh:1386
bool defined()
Definition: hsail_code.hh:176
DirVarToSE_map elements_by_brigptr
Definition: hsail_code.hh:245
void instNum(int num)
void setPrivateSize(int32_t _private_size)
Definition: hsail_code.hh:435
Bitfield< 23, 0 > offset
Definition: types.hh:149
uint16_t BrigType16_t
Definition: Brig.h:142
StorageElement * findSymbol(Brig::BrigSegment segment, std::string name)
Definition: hsail_code.cc:404
LabelMap labelMap
Definition: hsail_code.hh:327
static unsigned maxRegIdx
Definition: operand.hh:292
Brig::BrigSegment segment
Definition: hsail_code.hh:248
T roundUp(const T &val, const U &align)
Definition: intmath.hh:205
StorageSpace * space[NumSegments]
Definition: hsail_code.hh:270
StorageElement * addSymbol(const Brig::BrigDirectiveVariable *sym, const BrigObject *obj)
Definition: hsail_code.cc:288
void define(std::string &_name, int _value)
Definition: hsail_code.hh:189
std::size_t size() const
static unsigned maxRegIdx
Definition: operand.hh:228
uint32_t MachInst
Definition: types.hh:40
BrigKind16_t kind
Definition: Brig.h:1180
#define warn(...)
Definition: misc.hh:219
void resetOffset(Brig::BrigSegment segment)
Definition: hsail_code.cc:398
static void assignImmediatePostDominators(const std::vector< GPUStaticInst * > &instructions)
Compute immediate post-dominator instruction for kernel instructions.
Definition: kernel_cfg.cc:50
uint32_t lo
Definition: Brig.h:1164
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:72
const char * getString(int offs) const
Definition: brig_object.cc:92
T * brigNext(T *ptr)
Definition: brig_object.hh:125
uint64_t nextOffset
Definition: hsail_code.hh:247
#define fatal(...)
Definition: misc.hh:163
StorageElement * findSymbol(std::string name)
Definition: hsail_code.cc:320
StorageMap * storageMap
Definition: hsail_code.hh:326
const int NumSegments
Definition: hsail_code.hh:219
StorageMap(StorageMap *outerScope=nullptr)
Definition: hsail_code.cc:359
const Brig::BrigBase * getCodeSectionEntry(int offs) const
Definition: brig_object.cc:98
std::list< StorageElement * > elements
Definition: hsail_code.hh:243
BrigSegment
Definition: Brig.h:925
const_iterator find(const AddrRange &r) const
TheGpuISA::Decoder decoder
Definition: hsail_code.hh:324
AddrRangeMap< StorageElement * > elements_by_addr
Definition: hsail_code.hh:244
static unsigned maxRegIdx
Definition: operand.hh:123
uint32_t max_creg
Definition: hsail_code.hh:337
void init(const Brig::BrigDirectiveExecutable *code_dir, const BrigObject *obj, StorageMap *objStorageMap)
Definition: hsail_code.cc:58
int size()
Definition: pagetable.hh:146
BrigSegment8_t segment
Definition: Brig.h:1299
std::map< std::string, Label > map
Definition: hsail_code.hh:207
uint32_t hi
Definition: Brig.h:1165
BrigCodeOffset32_t nextModuleEntry
Definition: Brig.h:1242
void resetOffset()
Definition: hsail_code.hh:264
BrigDataOffsetString32_t name
Definition: Brig.h:1289
uint32_t max_dreg
Definition: hsail_code.hh:339
uint32_t max_sreg
Definition: hsail_code.hh:338
int funcarg_size
Definition: hsa_code.hh:90
Bitfield< 5 > t
Definition: miscregs.hh:1382
uint8_t BrigSegment8_t
Definition: Brig.h:138
HsailCode(const std::string &name_str, const Brig::BrigDirectiveExecutable *code_dir, const BrigObject *obj, StorageMap *objStorageMap)
Definition: hsail_code.cc:218
StorageMap * outerScopeMap
Definition: hsail_code.hh:269
const char * segmentNames[]
Definition: brig_object.cc:69
BrigCodeOffset32_t firstCodeBlockEntry
Definition: Brig.h:1241
std::vector< TheGpuISA::RawMachInst > _insts
Definition: hsa_code.hh:95
BrigOpcode16_t opcode
Definition: Brig.h:1321
void addLabel(const Brig::BrigDirectiveLabel *lbl, int inst_index, const BrigObject *obj)
Definition: hsail_code.cc:227
uint32_t RawMachInst
Definition: gpu_types.hh:54

Generated on Fri Jun 9 2017 13:03:48 for gem5 by doxygen 1.8.6