hsail_code.cc revision 12888
111856Sbrandon.potter@amd.com/*
211856Sbrandon.potter@amd.com * Copyright (c) 2012-2015 Advanced Micro Devices, Inc.
311856Sbrandon.potter@amd.com * All rights reserved.
411856Sbrandon.potter@amd.com *
511856Sbrandon.potter@amd.com * For use for simulation and test purposes only
611856Sbrandon.potter@amd.com *
711856Sbrandon.potter@amd.com * Redistribution and use in source and binary forms, with or without
811856Sbrandon.potter@amd.com * modification, are permitted provided that the following conditions are met:
911856Sbrandon.potter@amd.com *
1011856Sbrandon.potter@amd.com * 1. Redistributions of source code must retain the above copyright notice,
1111856Sbrandon.potter@amd.com * this list of conditions and the following disclaimer.
1211856Sbrandon.potter@amd.com *
1311856Sbrandon.potter@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice,
1411856Sbrandon.potter@amd.com * this list of conditions and the following disclaimer in the documentation
1511856Sbrandon.potter@amd.com * and/or other materials provided with the distribution.
1611856Sbrandon.potter@amd.com *
1711856Sbrandon.potter@amd.com * 3. Neither the name of the copyright holder nor the names of its contributors
1811856Sbrandon.potter@amd.com * may be used to endorse or promote products derived from this software
1911856Sbrandon.potter@amd.com * without specific prior written permission.
2011856Sbrandon.potter@amd.com *
2111856Sbrandon.potter@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2211856Sbrandon.potter@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2311856Sbrandon.potter@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2411856Sbrandon.potter@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2511856Sbrandon.potter@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2611856Sbrandon.potter@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2711856Sbrandon.potter@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2811856Sbrandon.potter@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2911856Sbrandon.potter@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3011856Sbrandon.potter@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3111856Sbrandon.potter@amd.com * POSSIBILITY OF SUCH DAMAGE.
3211856Sbrandon.potter@amd.com *
3312697Santhony.gutierrez@amd.com * Author: Steve Reinhardt
3411856Sbrandon.potter@amd.com */
3511856Sbrandon.potter@amd.com
3611856Sbrandon.potter@amd.com#include "gpu-compute/hsail_code.hh"
3711856Sbrandon.potter@amd.com
3811856Sbrandon.potter@amd.com#include "arch/gpu_types.hh"
3911856Sbrandon.potter@amd.com#include "arch/hsail/Brig.h"
4011856Sbrandon.potter@amd.com#include "arch/hsail/operand.hh"
4111856Sbrandon.potter@amd.com#include "config/the_gpu_isa.hh"
4211856Sbrandon.potter@amd.com#include "debug/BRIG.hh"
4311856Sbrandon.potter@amd.com#include "debug/HSAILObject.hh"
4411856Sbrandon.potter@amd.com#include "gpu-compute/brig_object.hh"
4512334Sgabeblack@google.com#include "gpu-compute/gpu_static_inst.hh"
4613897Ssteve.reinhardt@amd.com#include "gpu-compute/kernel_cfg.hh"
4711856Sbrandon.potter@amd.com
4811856Sbrandon.potter@amd.comusing namespace Brig;
4911856Sbrandon.potter@amd.com
5011856Sbrandon.potter@amd.comint getBrigDataTypeBytes(BrigType16_t t);
5111856Sbrandon.potter@amd.com
5213029Sbrandon.potter@amd.comHsailCode::HsailCode(const std::string &name_str)
5313029Sbrandon.potter@amd.com    : HsaCode(name_str), private_size(-1), readonly_size(-1)
5413029Sbrandon.potter@amd.com{
5513029Sbrandon.potter@amd.com}
5613029Sbrandon.potter@amd.com
5713029Sbrandon.potter@amd.comvoid
5813029Sbrandon.potter@amd.comHsailCode::init(const BrigDirectiveExecutable *code_dir, const BrigObject *obj,
5913029Sbrandon.potter@amd.com                StorageMap *objStorageMap)
6013029Sbrandon.potter@amd.com{
6111856Sbrandon.potter@amd.com    storageMap = objStorageMap;
6211856Sbrandon.potter@amd.com
6311856Sbrandon.potter@amd.com    // set pointer so that decoding process can find this kernel context when
6411856Sbrandon.potter@amd.com    // needed
6511856Sbrandon.potter@amd.com    obj->currentCode = this;
6611856Sbrandon.potter@amd.com
6711856Sbrandon.potter@amd.com    if (code_dir->base.kind != BRIG_KIND_DIRECTIVE_FUNCTION &&
6811856Sbrandon.potter@amd.com        code_dir->base.kind != BRIG_KIND_DIRECTIVE_KERNEL) {
6913029Sbrandon.potter@amd.com        fatal("unexpected directive kind %d inside kernel/function init\n",
7011856Sbrandon.potter@amd.com              code_dir->base.kind);
7111856Sbrandon.potter@amd.com    }
7211856Sbrandon.potter@amd.com
7311856Sbrandon.potter@amd.com    DPRINTF(HSAILObject, "Initializing code, first code block entry is: %d\n",
7411856Sbrandon.potter@amd.com            code_dir->firstCodeBlockEntry);
7511856Sbrandon.potter@amd.com
7611856Sbrandon.potter@amd.com    // clear these static vars so we can properly track the max index
7711856Sbrandon.potter@amd.com    // for this kernel
7811856Sbrandon.potter@amd.com    SRegOperand::maxRegIdx = 0;
7911856Sbrandon.potter@amd.com    DRegOperand::maxRegIdx = 0;
8011856Sbrandon.potter@amd.com    CRegOperand::maxRegIdx = 0;
8113029Sbrandon.potter@amd.com    setPrivateSize(0);
8211856Sbrandon.potter@amd.com
8311856Sbrandon.potter@amd.com    const BrigBase *entryPtr = brigNext((BrigBase*)code_dir);
8411856Sbrandon.potter@amd.com    const BrigBase *endPtr =
8511856Sbrandon.potter@amd.com        obj->getCodeSectionEntry(code_dir->nextModuleEntry);
8611856Sbrandon.potter@amd.com
8711856Sbrandon.potter@amd.com    // the instruction's byte address (relative to the base addr
8811856Sbrandon.potter@amd.com    // of the code section)
8911856Sbrandon.potter@amd.com    int inst_addr = 0;
9011856Sbrandon.potter@amd.com    // the index that points to the instruction in the instruction
9111856Sbrandon.potter@amd.com    // array
9213029Sbrandon.potter@amd.com    int inst_idx = 0;
9311856Sbrandon.potter@amd.com    std::vector<GPUStaticInst*> instructions;
9411856Sbrandon.potter@amd.com    int funcarg_size_scope = 0;
9511856Sbrandon.potter@amd.com
9611856Sbrandon.potter@amd.com    // walk through instructions in code section and directives in
9711856Sbrandon.potter@amd.com    // directive section in parallel, processing directives that apply
9811856Sbrandon.potter@amd.com    // when we reach the relevant code point.
9911856Sbrandon.potter@amd.com    while (entryPtr < endPtr) {
10011856Sbrandon.potter@amd.com        switch (entryPtr->kind) {
10111856Sbrandon.potter@amd.com          case BRIG_KIND_DIRECTIVE_VARIABLE:
10211856Sbrandon.potter@amd.com           {
10311856Sbrandon.potter@amd.com                const BrigDirectiveVariable *sym =
10411856Sbrandon.potter@amd.com                    (const BrigDirectiveVariable*)entryPtr;
10511856Sbrandon.potter@amd.com
10611856Sbrandon.potter@amd.com                DPRINTF(HSAILObject,"Initializing code, directive is "
10711856Sbrandon.potter@amd.com                        "kind_variable, symbol is: %s\n",
10811856Sbrandon.potter@amd.com                        obj->getString(sym->name));
10911856Sbrandon.potter@amd.com
11011856Sbrandon.potter@amd.com                StorageElement *se = storageMap->addSymbol(sym, obj);
11111856Sbrandon.potter@amd.com
11211856Sbrandon.potter@amd.com                if (sym->segment == BRIG_SEGMENT_PRIVATE) {
11311856Sbrandon.potter@amd.com                    setPrivateSize(se->size);
11411856Sbrandon.potter@amd.com                } else { // spill
11511856Sbrandon.potter@amd.com                    funcarg_size_scope += se->size;
11611856Sbrandon.potter@amd.com                }
11711856Sbrandon.potter@amd.com            }
11811856Sbrandon.potter@amd.com            break;
11911856Sbrandon.potter@amd.com
12011856Sbrandon.potter@amd.com          case BRIG_KIND_DIRECTIVE_LABEL:
12111856Sbrandon.potter@amd.com            {
12211856Sbrandon.potter@amd.com                const BrigDirectiveLabel *lbl =
12311856Sbrandon.potter@amd.com                    (const BrigDirectiveLabel*)entryPtr;
12411856Sbrandon.potter@amd.com
12511856Sbrandon.potter@amd.com                DPRINTF(HSAILObject,"Initializing code, directive is "
12611856Sbrandon.potter@amd.com                        "kind_label, label is: %s \n",
12711856Sbrandon.potter@amd.com                        obj->getString(lbl->name));
12811856Sbrandon.potter@amd.com
12911856Sbrandon.potter@amd.com                labelMap.addLabel(lbl, inst_addr, obj);
13011856Sbrandon.potter@amd.com            }
13111856Sbrandon.potter@amd.com            break;
13211856Sbrandon.potter@amd.com
13311856Sbrandon.potter@amd.com          case BRIG_KIND_DIRECTIVE_PRAGMA:
13411856Sbrandon.potter@amd.com            {
13512392Sjason@lowepower.com                DPRINTF(HSAILObject, "Initializing code, directive "
13611856Sbrandon.potter@amd.com                        "is kind_pragma\n");
13711856Sbrandon.potter@amd.com            }
13811856Sbrandon.potter@amd.com            break;
13911856Sbrandon.potter@amd.com
14011856Sbrandon.potter@amd.com          case BRIG_KIND_DIRECTIVE_COMMENT:
14111856Sbrandon.potter@amd.com            {
14211856Sbrandon.potter@amd.com                DPRINTF(HSAILObject, "Initializing code, directive is "
14311856Sbrandon.potter@amd.com                        "kind_comment\n");
14411856Sbrandon.potter@amd.com            }
14511856Sbrandon.potter@amd.com            break;
14611856Sbrandon.potter@amd.com
14711856Sbrandon.potter@amd.com          case BRIG_KIND_DIRECTIVE_ARG_BLOCK_START:
14811856Sbrandon.potter@amd.com            {
14911856Sbrandon.potter@amd.com                DPRINTF(HSAILObject, "Initializing code, directive is "
15011856Sbrandon.potter@amd.com                        "kind_arg_block_start\n");
15111856Sbrandon.potter@amd.com
15211856Sbrandon.potter@amd.com                storageMap->resetOffset(BRIG_SEGMENT_ARG);
15311856Sbrandon.potter@amd.com                funcarg_size_scope = 0;
15411856Sbrandon.potter@amd.com            }
15511856Sbrandon.potter@amd.com            break;
15611856Sbrandon.potter@amd.com
15711856Sbrandon.potter@amd.com          case BRIG_KIND_DIRECTIVE_ARG_BLOCK_END:
15811856Sbrandon.potter@amd.com            {
15911856Sbrandon.potter@amd.com                DPRINTF(HSAILObject, "Initializing code, directive is "
16013029Sbrandon.potter@amd.com                        "kind_arg_block_end\n");
16111856Sbrandon.potter@amd.com
16211856Sbrandon.potter@amd.com                funcarg_size = funcarg_size < funcarg_size_scope ?
16311856Sbrandon.potter@amd.com                                              funcarg_size_scope : funcarg_size;
16411856Sbrandon.potter@amd.com            }
16511856Sbrandon.potter@amd.com            break;
16611856Sbrandon.potter@amd.com
16711856Sbrandon.potter@amd.com          case BRIG_KIND_DIRECTIVE_END:
16811856Sbrandon.potter@amd.com            DPRINTF(HSAILObject, "Initializing code, dircetive is "
16911856Sbrandon.potter@amd.com                    "kind_end\n");
17011856Sbrandon.potter@amd.com
17111856Sbrandon.potter@amd.com            break;
17211856Sbrandon.potter@amd.com
17311856Sbrandon.potter@amd.com          default:
17411856Sbrandon.potter@amd.com            if (entryPtr->kind >= BRIG_KIND_INST_BEGIN &&
17511856Sbrandon.potter@amd.com                entryPtr->kind <= BRIG_KIND_INST_END) {
17611856Sbrandon.potter@amd.com
17711856Sbrandon.potter@amd.com                BrigInstBase *instPtr = (BrigInstBase*)entryPtr;
17811856Sbrandon.potter@amd.com                TheGpuISA::MachInst machInst = { instPtr, obj };
17911856Sbrandon.potter@amd.com                GPUStaticInst *iptr = decoder.decode(machInst);
18011856Sbrandon.potter@amd.com
18111856Sbrandon.potter@amd.com                if (iptr) {
18211856Sbrandon.potter@amd.com                    DPRINTF(HSAILObject, "Initializing code, processing inst "
18311856Sbrandon.potter@amd.com                            "byte addr #%d idx %d: OPCODE=%d\n", inst_addr,
18413029Sbrandon.potter@amd.com                            inst_idx, instPtr->opcode);
18511856Sbrandon.potter@amd.com
18611856Sbrandon.potter@amd.com                    TheGpuISA::RawMachInst raw_inst = decoder.saveInst(iptr);
18711856Sbrandon.potter@amd.com                    iptr->instNum(inst_idx);
18811856Sbrandon.potter@amd.com                    iptr->instAddr(inst_addr);
18911856Sbrandon.potter@amd.com                    _insts.push_back(raw_inst);
19011856Sbrandon.potter@amd.com                    instructions.push_back(iptr);
19111856Sbrandon.potter@amd.com                }
19211856Sbrandon.potter@amd.com                inst_addr += sizeof(TheGpuISA::RawMachInst);
19311856Sbrandon.potter@amd.com                ++inst_idx;
19411856Sbrandon.potter@amd.com            } else if (entryPtr->kind >= BRIG_KIND_OPERAND_BEGIN &&
19511856Sbrandon.potter@amd.com                       entryPtr->kind < BRIG_KIND_OPERAND_END) {
19611856Sbrandon.potter@amd.com                warn("unexpected operand entry in code segment\n");
19711856Sbrandon.potter@amd.com            } else {
19811856Sbrandon.potter@amd.com                // there are surely some more cases we will need to handle,
19911856Sbrandon.potter@amd.com                // but we'll deal with them as we find them.
20011856Sbrandon.potter@amd.com                fatal("unexpected directive kind %d inside kernel scope\n",
20111856Sbrandon.potter@amd.com                      entryPtr->kind);
20211856Sbrandon.potter@amd.com            }
20311856Sbrandon.potter@amd.com        }
20411856Sbrandon.potter@amd.com
20511856Sbrandon.potter@amd.com        entryPtr = brigNext(entryPtr);
20611856Sbrandon.potter@amd.com    }
20711856Sbrandon.potter@amd.com
20811856Sbrandon.potter@amd.com    // compute Control Flow Graph for current kernel
20911856Sbrandon.potter@amd.com    ControlFlowInfo::assignImmediatePostDominators(instructions);
21011856Sbrandon.potter@amd.com
21113029Sbrandon.potter@amd.com    max_sreg = SRegOperand::maxRegIdx;
21211856Sbrandon.potter@amd.com    max_dreg = DRegOperand::maxRegIdx;
21311856Sbrandon.potter@amd.com    max_creg = CRegOperand::maxRegIdx;
21411856Sbrandon.potter@amd.com
21511856Sbrandon.potter@amd.com    obj->currentCode = nullptr;
21611856Sbrandon.potter@amd.com}
21711856Sbrandon.potter@amd.com
21811856Sbrandon.potter@amd.comHsailCode::HsailCode(const std::string &name_str,
21911856Sbrandon.potter@amd.com                     const BrigDirectiveExecutable *code_dir,
22011856Sbrandon.potter@amd.com                     const BrigObject *obj, StorageMap *objStorageMap)
22111856Sbrandon.potter@amd.com    : HsaCode(name_str), private_size(-1), readonly_size(-1)
22211856Sbrandon.potter@amd.com{
22311856Sbrandon.potter@amd.com    init(code_dir, obj, objStorageMap);
22411856Sbrandon.potter@amd.com}
22511856Sbrandon.potter@amd.com
22611856Sbrandon.potter@amd.comvoid
22711856Sbrandon.potter@amd.comLabelMap::addLabel(const Brig::BrigDirectiveLabel *lblDir, int inst_index,
22811856Sbrandon.potter@amd.com                   const BrigObject *obj)
22911856Sbrandon.potter@amd.com{
23011856Sbrandon.potter@amd.com    std::string lbl_name = obj->getString(lblDir->name);
23111856Sbrandon.potter@amd.com    Label &lbl = map[lbl_name];
23211856Sbrandon.potter@amd.com
23311856Sbrandon.potter@amd.com    if (lbl.defined()) {
23411856Sbrandon.potter@amd.com        fatal("Attempt to redefine existing label %s\n", lbl_name);
23511856Sbrandon.potter@amd.com    }
23611856Sbrandon.potter@amd.com
23711856Sbrandon.potter@amd.com    lbl.define(lbl_name, inst_index);
23811856Sbrandon.potter@amd.com    DPRINTF(HSAILObject, "label %s = %d\n", lbl_name, inst_index);
23911856Sbrandon.potter@amd.com}
24011856Sbrandon.potter@amd.com
24111856Sbrandon.potter@amd.comLabel*
24211856Sbrandon.potter@amd.comLabelMap::refLabel(const Brig::BrigDirectiveLabel *lblDir,
24311856Sbrandon.potter@amd.com                   const BrigObject *obj)
24411856Sbrandon.potter@amd.com{
24511856Sbrandon.potter@amd.com    std::string name = obj->getString(lblDir->name);
24611856Sbrandon.potter@amd.com    Label &lbl = map[name];
24711856Sbrandon.potter@amd.com    lbl.checkName(name);
24811856Sbrandon.potter@amd.com
24911856Sbrandon.potter@amd.com    return &lbl;
25011856Sbrandon.potter@amd.com}
25111856Sbrandon.potter@amd.com
25211856Sbrandon.potter@amd.comint
25311856Sbrandon.potter@amd.comgetBrigDataTypeBytes(BrigType16_t t)
25411856Sbrandon.potter@amd.com{
25511856Sbrandon.potter@amd.com    switch (t) {
25611856Sbrandon.potter@amd.com      case BRIG_TYPE_S8:
25711856Sbrandon.potter@amd.com      case BRIG_TYPE_U8:
25811856Sbrandon.potter@amd.com      case BRIG_TYPE_B8:
25911856Sbrandon.potter@amd.com        return 1;
26011856Sbrandon.potter@amd.com
26111856Sbrandon.potter@amd.com      case BRIG_TYPE_S16:
26211856Sbrandon.potter@amd.com      case BRIG_TYPE_U16:
26311856Sbrandon.potter@amd.com      case BRIG_TYPE_B16:
26411856Sbrandon.potter@amd.com      case BRIG_TYPE_F16:
26511856Sbrandon.potter@amd.com        return 2;
26611856Sbrandon.potter@amd.com
26711856Sbrandon.potter@amd.com      case BRIG_TYPE_S32:
26811856Sbrandon.potter@amd.com      case BRIG_TYPE_U32:
26911856Sbrandon.potter@amd.com      case BRIG_TYPE_B32:
27011856Sbrandon.potter@amd.com      case BRIG_TYPE_F32:
27111856Sbrandon.potter@amd.com        return 4;
27211856Sbrandon.potter@amd.com
27311856Sbrandon.potter@amd.com      case BRIG_TYPE_S64:
27411856Sbrandon.potter@amd.com      case BRIG_TYPE_U64:
27511856Sbrandon.potter@amd.com      case BRIG_TYPE_B64:
27611856Sbrandon.potter@amd.com      case BRIG_TYPE_F64:
27711856Sbrandon.potter@amd.com        return 8;
27811856Sbrandon.potter@amd.com
27911856Sbrandon.potter@amd.com      case BRIG_TYPE_B1:
28011856Sbrandon.potter@amd.com
28111856Sbrandon.potter@amd.com      default:
28211856Sbrandon.potter@amd.com        fatal("unhandled symbol data type %d", t);
28311856Sbrandon.potter@amd.com        return 0;
28411856Sbrandon.potter@amd.com    }
28511856Sbrandon.potter@amd.com}
28611856Sbrandon.potter@amd.com
28711856Sbrandon.potter@amd.comStorageElement*
28811856Sbrandon.potter@amd.comStorageSpace::addSymbol(const BrigDirectiveVariable *sym,
28911856Sbrandon.potter@amd.com                        const BrigObject *obj)
29011856Sbrandon.potter@amd.com{
29111856Sbrandon.potter@amd.com    const char *sym_name = obj->getString(sym->name);
29211856Sbrandon.potter@amd.com    uint64_t size = 0;
29311856Sbrandon.potter@amd.com    uint64_t offset = 0;
29411856Sbrandon.potter@amd.com
29511856Sbrandon.potter@amd.com    if (sym->type & BRIG_TYPE_ARRAY) {
29611856Sbrandon.potter@amd.com        size = getBrigDataTypeBytes(sym->type & ~BRIG_TYPE_ARRAY);
29711856Sbrandon.potter@amd.com        size *= (((uint64_t)sym->dim.hi) << 32 | (uint64_t)sym->dim.lo);
29811856Sbrandon.potter@amd.com
29911856Sbrandon.potter@amd.com        offset = roundUp(nextOffset, getBrigDataTypeBytes(sym->type &
30011856Sbrandon.potter@amd.com                         ~BRIG_TYPE_ARRAY));
30111856Sbrandon.potter@amd.com    } else {
30211856Sbrandon.potter@amd.com        size = getBrigDataTypeBytes(sym->type);
30311856Sbrandon.potter@amd.com        offset = roundUp(nextOffset, getBrigDataTypeBytes(sym->type));
30411856Sbrandon.potter@amd.com    }
30511856Sbrandon.potter@amd.com
30611856Sbrandon.potter@amd.com    nextOffset = offset + size;
30711856Sbrandon.potter@amd.com
30811856Sbrandon.potter@amd.com    DPRINTF(HSAILObject, "Adding SYMBOL %s size %d offset %#x, init: %d\n",
30911856Sbrandon.potter@amd.com            sym_name, size, offset, sym->init);
31011856Sbrandon.potter@amd.com
31111856Sbrandon.potter@amd.com    StorageElement* se = new StorageElement(sym_name, offset, size, sym);
31211856Sbrandon.potter@amd.com    elements.push_back(se);
31311856Sbrandon.potter@amd.com    elements_by_addr.insert(AddrRange(offset, offset + size - 1), se);
31411856Sbrandon.potter@amd.com    elements_by_brigptr[sym] = se;
31513897Ssteve.reinhardt@amd.com
31613897Ssteve.reinhardt@amd.com    return se;
31711856Sbrandon.potter@amd.com}
31811856Sbrandon.potter@amd.com
31911856Sbrandon.potter@amd.comStorageElement*
32011856Sbrandon.potter@amd.comStorageSpace::findSymbol(std::string name)
32111856Sbrandon.potter@amd.com{
32211856Sbrandon.potter@amd.com    for (auto it : elements) {
32311856Sbrandon.potter@amd.com        if (it->name == name) {
32411856Sbrandon.potter@amd.com            return it;
32511856Sbrandon.potter@amd.com        }
32611886Sbrandon.potter@amd.com    }
32711886Sbrandon.potter@amd.com
32811886Sbrandon.potter@amd.com    return nullptr;
32911886Sbrandon.potter@amd.com}
33011886Sbrandon.potter@amd.com
33111886Sbrandon.potter@amd.comStorageElement*
33211886Sbrandon.potter@amd.comStorageSpace::findSymbol(uint64_t addr)
33311856Sbrandon.potter@amd.com{
33411856Sbrandon.potter@amd.com    assert(elements_by_addr.size() > 0);
33511856Sbrandon.potter@amd.com
33611856Sbrandon.potter@amd.com    auto se = elements_by_addr.contains(addr);
33711856Sbrandon.potter@amd.com
33811856Sbrandon.potter@amd.com    if (se == elements_by_addr.end()) {
33911856Sbrandon.potter@amd.com        return nullptr;
34011856Sbrandon.potter@amd.com    } else {
34111856Sbrandon.potter@amd.com        return se->second;
34211856Sbrandon.potter@amd.com    }
34311856Sbrandon.potter@amd.com}
34411856Sbrandon.potter@amd.com
34511856Sbrandon.potter@amd.comStorageElement*
34611856Sbrandon.potter@amd.comStorageSpace::findSymbol(const BrigDirectiveVariable *brigptr)
34711856Sbrandon.potter@amd.com{
34811856Sbrandon.potter@amd.com    assert(elements_by_brigptr.size() > 0);
34911856Sbrandon.potter@amd.com
35011856Sbrandon.potter@amd.com    auto se = elements_by_brigptr.find(brigptr);
35111856Sbrandon.potter@amd.com
35211856Sbrandon.potter@amd.com    if (se == elements_by_brigptr.end()) {
353        return nullptr;
354    } else {
355        return se->second;
356    }
357}
358
359StorageMap::StorageMap(StorageMap *outerScope)
360    : outerScopeMap(outerScope)
361{
362    for (int i = 0; i < NumSegments; ++i)
363        space[i] = new StorageSpace((BrigSegment)i);
364}
365
366StorageElement*
367StorageMap::addSymbol(const BrigDirectiveVariable *sym, const BrigObject *obj)
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
377int
378StorageMap::getSize(Brig::BrigSegment segment)
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
397void
398StorageMap::resetOffset(Brig::BrigSegment segment)
399{
400    space[segment]->resetOffset();
401}
402
403StorageElement*
404StorageMap::findSymbol(BrigSegment segment, std::string name)
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
417StorageElement*
418StorageMap::findSymbol(Brig::BrigSegment segment, uint64_t addr)
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
439StorageElement*
440StorageMap::findSymbol(Brig::BrigSegment segment,
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}
461