|
81 | 81 | #include "llvm/Support/WithColor.h"
|
82 | 82 | #include "llvm/TargetParser/Host.h"
|
83 | 83 |
|
| 84 | +#include "LLVMSPIRVLib/LLVMSPIRVLib.h" |
84 | 85 | #include "time-stat/ts-interface.h"
|
85 | 86 |
|
86 | 87 | #include <csignal>
|
| 88 | +#include <sstream> |
87 | 89 |
|
88 | 90 | LLD_HAS_DRIVER(elf)
|
89 | 91 |
|
@@ -1849,6 +1851,63 @@ amd_comgr_status_t AMDGPUCompiler::linkToExecutable() {
|
1849 | 1851 | return amd_comgr_data_set_add(OutSetT, OutputT);
|
1850 | 1852 | }
|
1851 | 1853 |
|
| 1854 | +amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() { |
| 1855 | + if (auto Status = createTmpDirs()) { |
| 1856 | + return Status; |
| 1857 | + } |
| 1858 | + |
| 1859 | + LLVMContext Context; |
| 1860 | + Context.setDiagnosticHandler( |
| 1861 | + std::make_unique<AMDGPUCompilerDiagnosticHandler>(this), true); |
| 1862 | + |
| 1863 | + for (auto *Input : InSet->DataObjects) { |
| 1864 | + |
| 1865 | + if (Input->DataKind != AMD_COMGR_DATA_KIND_SPIRV) { |
| 1866 | + return AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT; |
| 1867 | + } |
| 1868 | + |
| 1869 | + // TODO: With C++23, we should investigate replacing with spanstream |
| 1870 | + // to avoid memory copies: |
| 1871 | + // https://en.cppreference.com/w/cpp/io/basic_ispanstream |
| 1872 | + std::istringstream ISS(std::string(Input->Data, Input->Size)); |
| 1873 | + |
| 1874 | + llvm::Module *M; |
| 1875 | + std::string Err; |
| 1876 | + |
| 1877 | + if (!llvm::readSpirv(Context, ISS, M, Err)) { |
| 1878 | + LogS << "Failed to load SPIR-V as LLVM Module: " << Err << '\n'; |
| 1879 | + return AMD_COMGR_STATUS_ERROR; |
| 1880 | + } |
| 1881 | + |
| 1882 | + SmallString<0> OutBuf; |
| 1883 | + BitcodeWriter Writer(OutBuf); |
| 1884 | + Writer.writeModule(*M, false, nullptr, false, nullptr); |
| 1885 | + Writer.writeSymtab(); |
| 1886 | + Writer.writeStrtab(); |
| 1887 | + |
| 1888 | + amd_comgr_data_t OutputT; |
| 1889 | + if (auto Status = amd_comgr_create_data(AMD_COMGR_DATA_KIND_BC, &OutputT)) { |
| 1890 | + return Status; |
| 1891 | + } |
| 1892 | + |
| 1893 | + // OutputT can be released after addition to the data_set |
| 1894 | + ScopedDataObjectReleaser SDOR(OutputT); |
| 1895 | + |
| 1896 | + DataObject *Output = DataObject::convert(OutputT); |
| 1897 | + Output->setName(std::string(Input->Name) + std::string(".bc")); |
| 1898 | + Output->setData(OutBuf); |
| 1899 | + |
| 1900 | + if (auto Status = amd_comgr_data_set_add(OutSetT, OutputT)) { |
| 1901 | + return Status; |
| 1902 | + } |
| 1903 | + |
| 1904 | + LogS << "SPIR-V Translation: amd-llvm-spirv -r " << Input->Name << " " << |
| 1905 | + Output->Name << "\n"; |
| 1906 | + } |
| 1907 | + |
| 1908 | + return AMD_COMGR_STATUS_SUCCESS; |
| 1909 | +} |
| 1910 | + |
1852 | 1911 | AMDGPUCompiler::AMDGPUCompiler(DataAction *ActionInfo, DataSet *InSet,
|
1853 | 1912 | DataSet *OutSet, raw_ostream &LogS)
|
1854 | 1913 | : ActionInfo(ActionInfo), InSet(InSet), OutSetT(DataSet::convert(OutSet)),
|
|
0 commit comments