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