From 40bfc4cf204e1f49acf1e9f1fbe203780358116d Mon Sep 17 00:00:00 2001 From: foreman Date: Tue, 25 Sep 2018 17:47:26 -0400 Subject: [PATCH] P4 to Git Change 1610640 by gandryey@gera-w8 on 2018/09/25 17:34:09 SWDEV-79445 - OCL generic changes and code clean-up Program compilation clean-up. Step#4: - Add common method FindGlobalVarSize() and metadata setup to the abstraction layer Affected files ... ... //depot/stg/opencl/drivers/opencl/runtime/device/devprogram.cpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/devprogram.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprogram.cpp#76 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprogram.hpp#32 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.cpp#89 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.hpp#38 edit --- rocclr/runtime/device/devprogram.cpp | 98 ++++++++++++++++++++++- rocclr/runtime/device/devprogram.hpp | 16 +++- rocclr/runtime/device/pal/palprogram.cpp | 86 +------------------- rocclr/runtime/device/pal/palprogram.hpp | 15 +--- rocclr/runtime/device/rocm/rocprogram.cpp | 87 +------------------- rocclr/runtime/device/rocm/rocprogram.hpp | 7 +- 6 files changed, 119 insertions(+), 190 deletions(-) diff --git a/rocclr/runtime/device/devprogram.cpp b/rocclr/runtime/device/devprogram.cpp index 509476932d..d0009c311c 100644 --- a/rocclr/runtime/device/devprogram.cpp +++ b/rocclr/runtime/device/devprogram.cpp @@ -56,7 +56,8 @@ Program::Program(amd::Device& device) buildError_(CL_SUCCESS), machineTarget_(nullptr), globalVariableTotalSize_(0), - programOptions_(nullptr) + programOptions_(nullptr), + metadata_(nullptr) { memset(&binOpts_, 0, sizeof(binOpts_)); binOpts_.struct_size = sizeof(binOpts_); @@ -67,7 +68,10 @@ Program::Program(amd::Device& device) } // ================================================================================================ -Program::~Program() { clear(); } +Program::~Program() { + clear(); + delete metadata_; +} // ================================================================================================ void Program::clear() { @@ -1369,4 +1373,94 @@ aclType Program::getNextCompilationStageFromBinary(amd::option::Options* options } return continueCompileFrom; } + +// ================================================================================================ +bool Program::FindGlobalVarSize(void* binary, size_t binSize) { +#if defined(WITH_LIGHTNING_COMPILER) + size_t progvarsTotalSize = 0; + size_t dynamicSize = 0; + size_t progvarsWriteSize = 0; + + // Begin the Elf image from memory + Elf* e = elf_memory((char*)binary, binSize, nullptr); + if (elf_kind(e) != ELF_K_ELF) { + buildLog_ += "Error while reading the ELF program binary\n"; + return false; + } + + size_t numpHdrs; + if (elf_getphdrnum(e, &numpHdrs) != 0) { + buildLog_ += "Error while reading the ELF program binary\n"; + return false; + } + + for (size_t i = 0; i < numpHdrs; ++i) { + GElf_Phdr pHdr; + if (gelf_getphdr(e, i, &pHdr) != &pHdr) { + continue; + } + // Look for the runtime metadata note + if (pHdr.p_type == PT_NOTE && pHdr.p_align >= sizeof(int)) { + // Iterate over the notes in this segment + address ptr = (address)binary + pHdr.p_offset; + address segmentEnd = ptr + pHdr.p_filesz; + + while (ptr < segmentEnd) { + Elf_Note* note = (Elf_Note*)ptr; + address name = (address)¬e[1]; + address desc = name + amd::alignUp(note->n_namesz, sizeof(int)); + + if (note->n_type == 7 || + note->n_type == 8) { + buildLog_ += "Error: object code with old metadata is not supported\n"; + return false; + } + else if (note->n_type == 10 /* NT_AMD_AMDGPU_HSA_METADATA */ && + note->n_namesz == sizeof "AMD" && + !memcmp(name, "AMD", note->n_namesz)) { + std::string metadataStr((const char*)desc, (size_t)note->n_descsz); + metadata_ = new CodeObjectMD(); + if (llvm::AMDGPU::HSAMD::fromString(metadataStr, *metadata_)) { + buildLog_ += "Error: failed to process metadata\n"; + return false; + } + // We've found and loaded the runtime metadata, exit the + // note record loop now. + break; + } + ptr += sizeof(*note) + amd::alignUp(note->n_namesz, sizeof(int)) + + amd::alignUp(note->n_descsz, sizeof(int)); + } + } + // Accumulate the size of R & !X loadable segments + else if (pHdr.p_type == PT_LOAD && !(pHdr.p_flags & PF_X)) { + if (pHdr.p_flags & PF_R) { + progvarsTotalSize += pHdr.p_memsz; + } + if (pHdr.p_flags & PF_W) { + progvarsWriteSize += pHdr.p_memsz; + } + } + else if (pHdr.p_type == PT_DYNAMIC) { + dynamicSize += pHdr.p_memsz; + } + } + + elf_end(e); + + if (!metadata_) { + buildLog_ += + "Error: runtime metadata section not present in ELF program binary\n"; + return false; + } + + progvarsTotalSize -= dynamicSize; + setGlobalVariableTotalSize(progvarsTotalSize); + + if (progvarsWriteSize != dynamicSize) { + hasGlobalStores_ = true; + } +#endif // defined(WITH_LIGHTNING_COMPILER) + return true; +} } diff --git a/rocclr/runtime/device/devprogram.hpp b/rocclr/runtime/device/devprogram.hpp index 4088bf037c..c669607f77 100644 --- a/rocclr/runtime/device/devprogram.hpp +++ b/rocclr/runtime/device/devprogram.hpp @@ -16,16 +16,21 @@ namespace llvm { namespace AMDGPU { namespace HSAMD { + struct Metadata; namespace Kernel { struct Metadata; }}}} -//typedef llvm::AMDGPU::HSAMD::Metadata CodeObjectMD; +#define LC_METADATA 1 +typedef llvm::AMDGPU::HSAMD::Metadata CodeObjectMD; typedef llvm::AMDGPU::HSAMD::Kernel::Metadata KernelMD; //typedef llvm::AMDGPU::HSAMD::Kernel::Arg::Metadata KernelArgMD; - #endif // defined(WITH_LIGHTNING_COMPILER) +#ifndef LC_METADATA +typedef char CodeObjectMD; +#endif + namespace amd { namespace hsa { namespace loader { @@ -106,6 +111,8 @@ class Program : public amd::HeapObject { size_t globalVariableTotalSize_; amd::option::Options* programOptions_; + CodeObjectMD* metadata_; //!< Runtime metadata + public: //! Construct a section. Program(amd::Device& device); @@ -186,6 +193,8 @@ class Program : public amd::HeapObject { //! Global variables are a part of the code segment bool hasGlobalStores() const { return hasGlobalStores_; } + const CodeObjectMD* metadata() const { return metadata_; } + protected: //! Compile the device program with LC path bool compileImplLC(const std::string& sourceCode, @@ -266,6 +275,9 @@ class Program : public amd::HeapObject { */ aclType getNextCompilationStageFromBinary(amd::option::Options* options); + //! Finds the total size of all global variables in the program + bool FindGlobalVarSize(void* binary, size_t binSize); + private: //! Disable default copy constructor Program(const Program&); diff --git a/rocclr/runtime/device/pal/palprogram.cpp b/rocclr/runtime/device/pal/palprogram.cpp index 014a635d71..c2d85194f4 100644 --- a/rocclr/runtime/device/pal/palprogram.cpp +++ b/rocclr/runtime/device/pal/palprogram.cpp @@ -1119,7 +1119,7 @@ bool LightningProgram::setKernels(amd::option::Options* options, void* binary, s hsa_agent_t agent; agent.handle = 1; - executable_ = loader_->CreateExecutable(HSA_PROFILE_FULL, NULL); + executable_ = loader_->CreateExecutable(HSA_PROFILE_FULL, nullptr); if (executable_ == nullptr) { buildLog_ += "Error: Executable for AMD HSA Code Object isn't created.\n"; return false; @@ -1140,89 +1140,11 @@ bool LightningProgram::setKernels(amd::option::Options* options, void* binary, s return false; } - size_t progvarsTotalSize = 0; - size_t dynamicSize = 0; - size_t progvarsWriteSize = 0; - - // Begin the Elf image from memory - Elf* e = elf_memory((char*)binary, size, NULL); - if (elf_kind(e) != ELF_K_ELF) { - buildLog_ += "Error while reading the ELF program binary\n"; + // Find the size of global variables from the binary + if (!FindGlobalVarSize(binary, size)) { return false; } - size_t numpHdrs; - if (elf_getphdrnum(e, &numpHdrs) != 0) { - buildLog_ += "Error while reading the ELF program binary\n"; - return false; - } - - for (size_t i = 0; i < numpHdrs; ++i) { - GElf_Phdr pHdr; - if (gelf_getphdr(e, i, &pHdr) != &pHdr) { - continue; - } - // Look for the runtime metadata note - if (pHdr.p_type == PT_NOTE && pHdr.p_align >= sizeof(int)) { - // Iterate over the notes in this segment - address ptr = (address)binary + pHdr.p_offset; - address segmentEnd = ptr + pHdr.p_filesz; - - while (ptr < segmentEnd) { - Elf_Note* note = (Elf_Note*)ptr; - address name = (address)¬e[1]; - address desc = name + amd::alignUp(note->n_namesz, sizeof(int)); - - //! @todo: Use constants and enums defined in AMDGPUPTNote.h. - //! In order to switch to using constants and enums defined in - //! AMDGPUPTNote.h, we need to clean up internal header files. - if (note->n_type == 7 || note->n_type == 8) { - buildLog_ += - "Error: object code with old metadata is not " - "supported\n"; - return false; - } else if (note->n_type == 10 /*AMDGPU::ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_METADATA*/ - && note->n_namesz == sizeof "AMD" && !memcmp(name, "AMD", note->n_namesz)) { - std::string metadataStr((const char*)desc, (size_t)note->n_descsz); - metadata_ = new CodeObjectMD(); - if (llvm::AMDGPU::HSAMD::fromString(metadataStr, *metadata_)) { - buildLog_ += "Error: failed to process metadata\n"; - return false; - } - // We've found and loaded the runtime metadata, exit the - // note record loop now. - break; - } - ptr += sizeof(*note) + amd::alignUp(note->n_namesz, sizeof(int)) + - amd::alignUp(note->n_descsz, sizeof(int)); - } - } - // Accumulate the size of R & !X loadable segments - else if (pHdr.p_type == PT_LOAD && !(pHdr.p_flags & PF_X)) { - if (pHdr.p_flags & PF_R) { - progvarsTotalSize += pHdr.p_memsz; - } - if (pHdr.p_flags & PF_W) { - progvarsWriteSize += pHdr.p_memsz; - } - } - else if (pHdr.p_type == PT_DYNAMIC) { - dynamicSize += pHdr.p_memsz; - } - } - - elf_end(e); - - if (!metadata_) { - buildLog_ += - "Error: runtime metadata section not present in " - "ELF program binary\n"; - return false; - } - - progvarsTotalSize -= dynamicSize; - setGlobalVariableTotalSize(progvarsTotalSize); - // Get the list of kernels std::vector kernelNameList; status = executable_->IterateSymbols(GetKernelNamesCallback, &kernelNameList); @@ -1276,8 +1198,6 @@ bool LightningProgram::setKernels(amd::option::Options* options, void* binary, s return true; } -LightningProgram::~LightningProgram() { delete metadata_; } - #endif // defined(WITH_LIGHTNING_COMPILER) } // namespace pal diff --git a/rocclr/runtime/device/pal/palprogram.hpp b/rocclr/runtime/device/pal/palprogram.hpp index 7a0abc5626..da50786dbc 100644 --- a/rocclr/runtime/device/pal/palprogram.hpp +++ b/rocclr/runtime/device/pal/palprogram.hpp @@ -231,25 +231,19 @@ class HSAILProgram : public device::Program { class LightningProgram : public HSAILProgram { public: LightningProgram(NullDevice& device) - : HSAILProgram(device) - , metadata_(nullptr) { + : HSAILProgram(device) { isLC_ = true; xnackEnabled_ = dev().hwInfo()->xnackEnabled_; machineTarget_ = dev().hwInfo()->machineTarget_; } LightningProgram(Device& device) - : HSAILProgram(device) - , metadata_(nullptr) { + : HSAILProgram(device) { isLC_ = true; xnackEnabled_ = dev().hwInfo()->xnackEnabled_; machineTarget_ = dev().hwInfo()->machineTarget_; } - - const CodeObjectMD* metadata() const { return metadata_; } - - private: - virtual ~LightningProgram(); + virtual ~LightningProgram() {} protected: virtual bool linkImpl(amd::option::Options* options) override; @@ -261,9 +255,6 @@ class LightningProgram : public HSAILProgram { bool setKernels(amd::option::Options* options, void* binary, size_t size); virtual bool createBinary(amd::option::Options* options) override; - - private: - CodeObjectMD* metadata_; //!< Runtime metadata }; #endif // defined(WITH_LIGHTNING_COMPILER) diff --git a/rocclr/runtime/device/rocm/rocprogram.cpp b/rocclr/runtime/device/rocm/rocprogram.cpp index 089138acdc..5e461c2d33 100644 --- a/rocclr/runtime/device/rocm/rocprogram.cpp +++ b/rocclr/runtime/device/rocm/rocprogram.cpp @@ -503,11 +503,6 @@ LightningProgram::LightningProgram(roc::NullDevice& device) isLC_ = true; xnackEnabled_ = dev().deviceInfo().xnackEnabled_; machineTarget_ = dev().deviceInfo().machineTarget_; - metadata_ = nullptr; -} - -LightningProgram::~LightningProgram() { - delete metadata_; } bool LightningProgram::createBinary(amd::option::Options* options) { @@ -849,89 +844,11 @@ bool LightningProgram::linkImpl(amd::option::Options* options) { } bool LightningProgram::setKernels(amd::option::Options* options, void* binary, size_t binSize) { - size_t progvarsTotalSize = 0; - size_t dynamicSize = 0; - size_t progvarsWriteSize = 0; - - // Begin the Elf image from memory - Elf* e = elf_memory((char*)binary, binSize, nullptr); - if (elf_kind(e) != ELF_K_ELF) { - buildLog_ += "Error while reading the ELF program binary\n"; + // Find the size of global variables from the binary + if (!FindGlobalVarSize(binary, binSize)) { return false; } - size_t numpHdrs; - if (elf_getphdrnum(e, &numpHdrs) != 0) { - buildLog_ += "Error while reading the ELF program binary\n"; - return false; - } - - for (size_t i = 0; i < numpHdrs; ++i) { - GElf_Phdr pHdr; - if (gelf_getphdr(e, i, &pHdr) != &pHdr) { - continue; - } - // Look for the runtime metadata note - if (pHdr.p_type == PT_NOTE && pHdr.p_align >= sizeof(int)) { - // Iterate over the notes in this segment - address ptr = (address)binary + pHdr.p_offset; - address segmentEnd = ptr + pHdr.p_filesz; - - while (ptr < segmentEnd) { - Elf_Note* note = (Elf_Note*)ptr; - address name = (address)¬e[1]; - address desc = name + amd::alignUp(note->n_namesz, sizeof(int)); - - if (note->n_type == 7 || note->n_type == 8) { - buildLog_ += - "Error: object code with old metadata is not " - "supported\n"; - return false; - } else if (note->n_type == 10 /* NT_AMD_AMDGPU_HSA_METADATA */ && - note->n_namesz == sizeof "AMD" && - !memcmp(name, "AMD", note->n_namesz)) { - std::string metadataStr((const char*)desc, (size_t)note->n_descsz); - metadata_ = new CodeObjectMD(); - if (llvm::AMDGPU::HSAMD::fromString(metadataStr, *metadata_)) { - buildLog_ += "Error: failed to process metadata\n"; - return false; - } - // We've found and loaded the runtime metadata, exit the - // note record loop now. - break; - } - ptr += sizeof(*note) + amd::alignUp(note->n_namesz, sizeof(int)) + - amd::alignUp(note->n_descsz, sizeof(int)); - } - } - // Accumulate the size of R & !X loadable segments - else if (pHdr.p_type == PT_LOAD && !(pHdr.p_flags & PF_X)) { - if (pHdr.p_flags & PF_R) { - progvarsTotalSize += pHdr.p_memsz; - } - if (pHdr.p_flags & PF_W) { - progvarsWriteSize += pHdr.p_memsz; - } - } else if (pHdr.p_type == PT_DYNAMIC) { - dynamicSize += pHdr.p_memsz; - } - } - - elf_end(e); - - if (!metadata_) { - buildLog_ += - "Error: runtime metadata section not present in " - "ELF program binary\n"; - return false; - } - - if (progvarsWriteSize != dynamicSize) { - hasGlobalStores_ = true; - } - progvarsTotalSize -= dynamicSize; - setGlobalVariableTotalSize(progvarsTotalSize); - saveBinaryAndSetType(TYPE_EXECUTABLE, binary, binSize); //Load the stored copy of the ELF binary. diff --git a/rocclr/runtime/device/rocm/rocprogram.hpp b/rocclr/runtime/device/rocm/rocprogram.hpp index dac67241dc..66c17fd5bb 100644 --- a/rocclr/runtime/device/rocm/rocprogram.hpp +++ b/rocclr/runtime/device/rocm/rocprogram.hpp @@ -108,10 +108,7 @@ private: class LightningProgram : public roc::Program { public: LightningProgram(roc::NullDevice& device); - virtual ~LightningProgram(); - - //! Returns the program metadata. - const CodeObjectMD* metadata() const { return metadata_; } + virtual ~LightningProgram() {} protected: virtual bool linkImpl(amd::option::Options* options) final; @@ -127,8 +124,6 @@ private: bool saveBinaryAndSetType(type_t type, void* rawBinary, size_t size); bool setKernels(amd::option::Options* options, void* binary, size_t binSize); - - CodeObjectMD* metadata_; //!< Runtime metadata }; #endif // defined(WITH_LIGHTNING_COMPILER)