P4 to Git Change 1221147 by ashi1@ashi1_win50 on 2015/12/15 15:58:09

SWDEV-83467 - [SPIRV] Add support of SPIRV to CPU
	Modifying runtime and compile time to allow SPIRV binaries to run on CPU since it only runs on HSAIL GPU
	Added changes to allow conversion of CPU's llvmBinaryIsSpir boolean into compiler library's oclElfSections enum
	Cpuprogram.cpp's llvmBinaryIsSpir flag renamed to elfSectionType will now support LLVMIR, SPIR, and SPIRV
	Added SPIRV to compiler lib's elf as new oclElfSections enum
	cpuprogram.cpp changes also made to gpuprogram.cpp's NullProgram to allow compilation

Affected files ...

... //depot/stg/opencl/drivers/opencl/compiler/lib/loaders/elf/elf.cpp#33 edit
... //depot/stg/opencl/drivers/opencl/compiler/lib/loaders/elf/elf.hpp#22 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpuprogram.cpp#69 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/device.cpp#191 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/device.hpp#266 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpucompiler.cpp#152 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprogram.cpp#217 edit


[ROCm/clr commit: 26be053088]
This commit is contained in:
foreman
2015-12-15 16:09:35 -05:00
والد 9a0de9075c
کامیت a8c8c20cd1
7فایلهای تغییر یافته به همراه120 افزوده شده و 50 حذف شده
@@ -105,6 +105,8 @@ namespace {
"Internal usage" },
{ OclElf::SPIR, ".spir", ELF_T_BYTE, 1, SHT_PROGBITS, 0,
"Vendor/Device-independent LLVM IR" },
{ OclElf::SPIRV, ".spirv", ELF_T_BYTE, 1, SHT_PROGBITS, 0,
"SPIR-V Binary" },
};
// index 0 is reserved and must be there (NULL section)
@@ -113,6 +113,7 @@ public:
TEXT,
INTERNAL,
SPIR,
SPIRV,
OCL_ELF_SECTIONS_LAST
} oclElfSections;
@@ -536,11 +536,23 @@ Program::compileBinaryToISA(amd::option::Options* options)
return false;
}
bool spirFlag = std::string::npos != options->clcOptions.find("--spir")
|| llvmBinaryIsSpir_;
aclSections_0_8 spirFlag;
_acl_type_enum_0_8 aclTypeBinaryUsed;
if (std::string::npos != options->clcOptions.find("--spirv")
|| elfSectionType_ == amd::OclElf::SPIRV) {
spirFlag = aclSPIRV;
aclTypeBinaryUsed = ACL_TYPE_SPIRV_BINARY;
} else if (std::string::npos != options->clcOptions.find("--spir")
|| elfSectionType_ == amd::OclElf::SPIR) {
spirFlag = aclSPIR;
aclTypeBinaryUsed = ACL_TYPE_SPIR_BINARY;
} else {
spirFlag = aclLLVMIR;
aclTypeBinaryUsed = ACL_TYPE_LLVMIR_BINARY;
}
if (ACL_SUCCESS != aclInsertSection(compiler(), bin,
llvmBinary_.data(), llvmBinary_.size(),
spirFlag ? aclSPIR : aclLLVMIR )) {
llvmBinary_.data(), llvmBinary_.size(), spirFlag)) {
LogWarning("aclInsertSection failed");
aclBinaryFini(bin);
return false;
@@ -551,8 +563,7 @@ Program::compileBinaryToISA(amd::option::Options* options)
((amd::option::Options*)bin->options)->setBuildNo(options->getBuildNo());
err = aclCompile(compiler(), bin, options->origOptionStr.c_str(),
spirFlag ? ACL_TYPE_SPIR_BINARY : ACL_TYPE_LLVMIR_BINARY,
ACL_TYPE_ISA, NULL);
aclTypeBinaryUsed, ACL_TYPE_ISA, NULL);
buildLog_ += aclGetCompilerLog(compiler());
@@ -865,7 +876,7 @@ Program::compileImpl(
}
llvmBinary_.assign(reinterpret_cast<const char*>(llvmir), size);
llvmBinaryIsSpir_ = false;
elfSectionType_ = amd::OclElf::LLVMIR;
aclBinaryFini(bin);
if (clBinary()->saveSOURCE()) {
@@ -1001,7 +1012,7 @@ Program::linkImpl(amd::option::Options* options)
}
// Need to try recompile, check to see if if LLVM IR is present
if (clBinary()->loadLlvmBinary(llvmBinary_, llvmBinaryIsSpir_) &&
if (clBinary()->loadLlvmBinary(llvmBinary_, elfSectionType_) &&
clBinary()->isRecompilable(llvmBinary_, amd::OclElf::CPU_PLATFORM)) {
// Copy both .source and .llvmir into the elfout_
char *section;
@@ -1014,7 +1025,7 @@ Program::linkImpl(amd::option::Options* options)
}
if (clBinary()->saveLLVMIR()) {
clBinary()->elfOut()->addSection(llvmBinaryIsSpir_?amd::OclElf::SPIR:amd::OclElf::LLVMIR,
clBinary()->elfOut()->addSection(elfSectionType_,
llvmBinary_.data(),
llvmBinary_.size(), false);
}
@@ -1063,7 +1074,7 @@ Program::linkImpl(
{
#if defined(WITH_ONLINE_COMPILER)
std::vector<std::string*> llvmBinaries(inputPrograms.size());
std::vector<bool> llvmBinaryIsSpir(inputPrograms.size());
std::vector<amd::OclElf::oclElfSections> elfSectionType(inputPrograms.size());
std::vector<device::Program*>::const_iterator it
= inputPrograms.begin();
std::vector<device::Program*>::const_iterator itEnd
@@ -1091,7 +1102,7 @@ Program::linkImpl(
}
// Need to try recompile, check to see if if LLVM IR is present
if (program->clBinary()->loadLlvmBinary(program->llvmBinary_, program->llvmBinaryIsSpir_) &&
if (program->clBinary()->loadLlvmBinary(program->llvmBinary_, program->elfSectionType_) &&
program->clBinary()->isRecompilable(program->llvmBinary_,
amd::OclElf::CPU_PLATFORM)) {
// Copy both .source and .llvmir into the elfout_
@@ -1117,7 +1128,7 @@ Program::linkImpl(
}
llvmBinaries[i] = &program->llvmBinary_;
llvmBinaryIsSpir[i] = program->llvmBinaryIsSpir_;
elfSectionType[i] = program->elfSectionType_;
}
acl_error err = ACL_SUCCESS;
@@ -1139,9 +1150,17 @@ Program::linkImpl(
break;
}
_bif_sections_enum_0_8 aclTypeUsed;
if (elfSectionType[i] == amd::OclElf::SPIRV) {
aclTypeUsed = aclSPIRV;
} else if (elfSectionType[i] == amd::OclElf::SPIR) {
aclTypeUsed = aclSPIR;
} else {
aclTypeUsed = aclLLVMIR;
}
err = aclInsertSection(compiler(), libs[i],
llvmBinaries[i]->data(), llvmBinaries[i]->size(),
llvmBinaryIsSpir[i]?aclSPIR:aclLLVMIR);
llvmBinaries[i]->data(), llvmBinaries[i]->size(), aclTypeUsed);
if (err != ACL_SUCCESS) {
LogWarning("aclInsertSection failed");
break;
@@ -1155,7 +1174,7 @@ Program::linkImpl(
if (libs.size() > 0 && err == ACL_SUCCESS) do {
unsigned int numLibs = libs.size() - 1;
bool resultIsSPIR = (llvmBinaryIsSpir[0] && numLibs == 0);
if (numLibs > 0) {
err = aclLink(compiler(), libs[0], libs.size() - 1, &libs[1],
ACL_TYPE_LLVMIR_BINARY, "-create-library", NULL);
@@ -1169,8 +1188,16 @@ Program::linkImpl(
}
size_t size = 0;
_bif_sections_enum_0_8 aclTypeUsed;
if (elfSectionType[0] == amd::OclElf::SPIRV && numLibs == 0) {
aclTypeUsed = aclSPIRV;
} else if (elfSectionType[0] == amd::OclElf::SPIR && numLibs == 0) {
aclTypeUsed = aclSPIR;
} else {
aclTypeUsed = aclLLVMIR;
}
const void* llvmir = aclExtractSection(compiler(), libs[0],
&size, resultIsSPIR?aclSPIR:aclLLVMIR, &err);
&size, aclTypeUsed, &err);
if (err != ACL_SUCCESS) {
LogWarning("aclExtractSection failed");
break;
@@ -1187,7 +1214,7 @@ Program::linkImpl(
}
if (clBinary()->saveLLVMIR()) {
clBinary()->elfOut()->addSection(llvmBinaryIsSpir_?amd::OclElf::SPIR:amd::OclElf::LLVMIR,
clBinary()->elfOut()->addSection(elfSectionType_,
llvmBinary_.data(),
llvmBinary_.size(),
false);
@@ -604,7 +604,7 @@ Program::Program(amd::Device& device)
, type_(TYPE_NONE)
, clBinary_(NULL)
, llvmBinary_()
, llvmBinaryIsSpir_(false)
, elfSectionType_(amd::OclElf::LLVMIR)
, compileOptions_()
, linkOptions_()
, lastBuildOptionsArg_()
@@ -1143,7 +1143,7 @@ Program::setBinary(char* binaryIn, size_t size)
}
case ET_REL:
{
if (clBinary()->isSPIR()) {
if (clBinary()->isSPIR() || clBinary()->isSPIRV()) {
setType(TYPE_INTERMEDIATE);
} else {
setType(TYPE_COMPILED);
@@ -1552,19 +1552,20 @@ void ClBinary::resetElfOut()
}
bool
ClBinary::loadLlvmBinary(std::string& llvmBinary, bool& llvmBinaryIsSpir) const
ClBinary::loadLlvmBinary(std::string& llvmBinary, amd::OclElf::oclElfSections& elfSectionType) const
{
// Check if current binary already has LLVMIR
char *section = NULL;
size_t sz = 0;
if (elfIn_->getSection(amd::OclElf::LLVMIR, &section, &sz) && section && sz > 0) {
llvmBinary.append(section, sz);
llvmBinaryIsSpir = false;
return true;
} else if (elfIn_->getSection(amd::OclElf::SPIR, &section, &sz) && section && sz > 0) {
llvmBinary.append(section, sz);
llvmBinaryIsSpir = true;
return true;
const amd::OclElf::oclElfSections SectionTypes[] =
{amd::OclElf::LLVMIR, amd::OclElf::SPIR, amd::OclElf::SPIRV};
for (int i = 0; i < 3; ++i){
if (elfIn_->getSection(SectionTypes[i], &section, &sz) && section && sz > 0) {
llvmBinary.append(section, sz);
elfSectionType = SectionTypes[i];
return true;
}
}
return false;
@@ -1628,6 +1629,18 @@ ClBinary::isSPIR() const
return false;
}
bool
ClBinary::isSPIRV() const
{
char *section = NULL;
size_t sz = 0;
if (elfIn_->getSection(amd::OclElf::SPIRV, &section, &sz) && section && sz > 0) {
return true;
}
return false;
}
cl_device_partition_property
PartitionType::toCL() const
{
@@ -1012,7 +1012,7 @@ private:
protected:
ClBinary* clBinary_; //!< The CL program binary file
std::string llvmBinary_; //!< LLVM IR binary code
bool llvmBinaryIsSpir_; //!< LLVM IR binary code is in SPIR format
amd::OclElf::oclElfSections elfSectionType_; //!< LLVM IR binary code is in SPIR format
std::string compileOptions_;//!< compile/build options.
std::string linkOptions_; //!< link options.
//!< the option arg passed in to clCompileProgram(), clLinkProgram(),
@@ -1212,7 +1212,7 @@ public:
//! Loads llvmir binary from OCL binary file
bool loadLlvmBinary(
std::string& llvmBinary, //!< LLVMIR binary code
bool& llvmBinaryIsSpir //!< LLVMIR binary is in SPIR format
amd::OclElf::oclElfSections& elfSectionType //!< LLVMIR binary is in SPIR format
) const;
//! Loads compile options from OCL binary file
@@ -1275,6 +1275,8 @@ public:
// Returns TRUE of binary file is SPIR
bool isSPIR() const;
// Returns TRUE of binary file is SPIRV
bool isSPIRV() const;
protected:
enum Flags {
BinaryAllocated = 0x1, //!< Binary was created
@@ -213,7 +213,7 @@ NullProgram::compileImpl(const std::string& src,
}
llvmBinary_.assign(reinterpret_cast<const char*>(ir), len);
llvmBinaryIsSpir_ = false;
elfSectionType_ = amd::OclElf::LLVMIR;
aclBinaryFini(bin);
for (size_t i = 0; i < headerFileNames.size(); ++i) {
@@ -260,11 +260,23 @@ NullProgram::compileBinaryToIL(amd::option::Options* options)
LogWarning("aclBinaryInit failed");
return CL_BUILD_PROGRAM_FAILURE;
}
bool spirFlag = std::string::npos != options->clcOptions.find("--spir")
|| llvmBinaryIsSpir_;
aclSections_0_8 spirFlag;
_acl_type_enum_0_8 aclTypeBinaryUsed;
if (std::string::npos != options->clcOptions.find("--spirv")
|| elfSectionType_ == amd::OclElf::SPIRV) {
spirFlag = aclSPIRV;
aclTypeBinaryUsed = ACL_TYPE_SPIRV_BINARY;
} else if (std::string::npos != options->clcOptions.find("--spir")
|| elfSectionType_ == amd::OclElf::SPIR) {
spirFlag = aclSPIR;
aclTypeBinaryUsed = ACL_TYPE_SPIR_BINARY;
} else {
spirFlag = aclLLVMIR;
aclTypeBinaryUsed = ACL_TYPE_LLVMIR_BINARY;
}
if (ACL_SUCCESS != aclInsertSection(dev().compiler(), bin,
llvmBinary_.data(), llvmBinary_.size(),
spirFlag ? aclSPIR : aclLLVMIR)) {
llvmBinary_.data(), llvmBinary_.size(), spirFlag)) {
LogWarning("aclInsertSection failed");
aclBinaryFini(bin);
return CL_BUILD_PROGRAM_FAILURE;
@@ -289,10 +301,9 @@ NullProgram::compileBinaryToIL(amd::option::Options* options)
if (options->oVariables->BinBIF30) {
type = ACL_TYPE_ISA;
}
err = aclCompile(dev().compiler(), bin, optionStr.c_str(),
spirFlag ? ACL_TYPE_SPIR_BINARY : ACL_TYPE_LLVMIR_BINARY,
type, NULL);
err = aclCompile(dev().compiler(), bin, optionStr.c_str(),
aclTypeBinaryUsed, type, NULL);
buildLog_ += aclGetCompilerLog(dev().compiler());
if (err != ACL_SUCCESS) {
@@ -223,8 +223,8 @@ NullProgram::linkImpl(amd::option::Options* options)
clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, section, sz);
}
if (clBinary()->saveLLVMIR()) {
if (clBinary()->loadLlvmBinary(llvmBinary_, llvmBinaryIsSpir_) && (!llvmBinary_.empty())) {
clBinary()->elfOut()->addSection(llvmBinaryIsSpir_?amd::OclElf::SPIR:amd::OclElf::LLVMIR,
if (clBinary()->loadLlvmBinary(llvmBinary_, elfSectionType_) && (!llvmBinary_.empty())) {
clBinary()->elfOut()->addSection(elfSectionType_,
llvmBinary_.data(), llvmBinary_.size(), false);
}
}
@@ -243,7 +243,7 @@ NullProgram::linkImpl(amd::option::Options* options)
}
return true;
}
else if (clBinary()->loadLlvmBinary(llvmBinary_, llvmBinaryIsSpir_) &&
else if (clBinary()->loadLlvmBinary(llvmBinary_, elfSectionType_) &&
clBinary()->isRecompilable(llvmBinary_, amd::OclElf::CAL_PLATFORM)) {
char *section;
size_t sz;
@@ -260,7 +260,7 @@ NullProgram::linkImpl(amd::option::Options* options)
clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, section, sz);
}
if (clBinary()->saveLLVMIR()) {
clBinary()->elfOut()->addSection(llvmBinaryIsSpir_?amd::OclElf::SPIR:amd::OclElf::LLVMIR,
clBinary()->elfOut()->addSection(elfSectionType_,
llvmBinary_.data(), llvmBinary_.size(), false);
}
}
@@ -509,7 +509,7 @@ NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
bool createLibrary)
{
std::vector<std::string*> llvmBinaries(inputPrograms.size());
std::vector<bool> llvmBinaryIsSpir(inputPrograms.size());
std::vector<amd::OclElf::oclElfSections> elfSectionType(inputPrograms.size());
std::vector<device::Program*>::const_iterator it
= inputPrograms.begin();
std::vector<device::Program*>::const_iterator itEnd
@@ -533,7 +533,7 @@ NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
return false;
}
if (!program->clBinary()->loadLlvmBinary(program->llvmBinary_,
program->llvmBinaryIsSpir_)) {
program->elfSectionType_)) {
buildLog_
+= "Internal error: Failed loading compiled binary!\n";
LogError("Bad OCL Binary");
@@ -560,7 +560,7 @@ NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
}
llvmBinaries[i] = &program->llvmBinary_;
llvmBinaryIsSpir[i] = program->llvmBinaryIsSpir_;
elfSectionType[i] = program->elfSectionType_;
}
acl_error err;
@@ -580,9 +580,16 @@ NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
break;
}
_bif_sections_enum_0_8 aclTypeUsed;
if (elfSectionType[i] == amd::OclElf::SPIRV) {
aclTypeUsed = aclSPIRV;
} else if (elfSectionType[i] == amd::OclElf::SPIR) {
aclTypeUsed = aclSPIR;
} else {
aclTypeUsed = aclLLVMIR;
}
err = aclInsertSection(dev().compiler(), libs[i],
llvmBinaries[i]->data(), llvmBinaries[i]->size(),
llvmBinaryIsSpir[i]?aclSPIR:aclLLVMIR);
llvmBinaries[i]->data(), llvmBinaries[i]->size(), aclTypeUsed);
if (err != ACL_SUCCESS) {
LogWarning("aclInsertSection failed");
break;
@@ -597,7 +604,6 @@ NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
if (libs.size() > 0 && err == ACL_SUCCESS) do {
unsigned int numLibs = libs.size() - 1;
bool resultIsSPIR = (llvmBinaryIsSpir[0] && numLibs == 0);
if (numLibs > 0) {
err = aclLink(dev().compiler(), libs[0], numLibs, &libs[1],
@@ -612,15 +618,23 @@ NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
}
size_t size = 0;
_bif_sections_enum_0_8 aclTypeUsed;
if (elfSectionType[0] == amd::OclElf::SPIRV && numLibs == 0) {
aclTypeUsed = aclSPIRV;
} else if (elfSectionType[0] == amd::OclElf::SPIR && numLibs == 0) {
aclTypeUsed = aclSPIR;
} else {
aclTypeUsed = aclLLVMIR;
}
const void* llvmir = aclExtractSection(dev().compiler(), libs[0],
&size, resultIsSPIR?aclSPIR:aclLLVMIR, &err);
&size, aclTypeUsed, &err);
if (err != ACL_SUCCESS) {
LogWarning("aclExtractSection failed");
break;
}
llvmBinary_.assign(reinterpret_cast<const char*>(llvmir), size);
llvmBinaryIsSpir_ = false;
elfSectionType_ = amd::OclElf::LLVMIR;
} while(0);
std::for_each(libs.begin(), libs.end(), std::ptr_fun(aclBinaryFini));