5959#include " clang/FrontendTool/Utils.h"
6060#include " llvm/ADT/StringExtras.h"
6161#include " llvm/Bitcode/BitcodeWriter.h"
62+ #include " llvm/IR/Constants.h"
6263#include " llvm/IR/LLVMContext.h"
6364#include " llvm/IR/Module.h"
6465#include " llvm/IR/Verifier.h"
@@ -875,7 +876,8 @@ amd_comgr_status_t AMDGPUCompiler::removeTmpDirs() {
875876#endif
876877}
877878
878- amd_comgr_status_t AMDGPUCompiler::processFile (const char *InputFilePath,
879+ amd_comgr_status_t AMDGPUCompiler::processFile (DataObject *Input,
880+ const char *InputFilePath,
879881 const char *OutputFilePath) {
880882 SmallVector<const char *, 128 > Argv = Args;
881883
@@ -896,6 +898,12 @@ amd_comgr_status_t AMDGPUCompiler::processFile(const char *InputFilePath,
896898 Argv.push_back (" -save-temps=obj" );
897899 }
898900
901+ // Add SPIR-V flags
902+ for (auto Flag : Input->SpirvFlags ) {
903+ Argv.push_back (" -Xclang" );
904+ Argv.push_back (Flag);
905+ }
906+
899907 Argv.push_back (InputFilePath);
900908
901909 Argv.push_back (" -o" );
@@ -907,6 +915,12 @@ amd_comgr_status_t AMDGPUCompiler::processFile(const char *InputFilePath,
907915amd_comgr_status_t
908916AMDGPUCompiler::processFiles (amd_comgr_data_kind_t OutputKind,
909917 const char *OutputSuffix) {
918+ return processFiles (OutputKind, OutputSuffix, InSet);
919+ }
920+
921+ amd_comgr_status_t
922+ AMDGPUCompiler::processFiles (amd_comgr_data_kind_t OutputKind,
923+ const char *OutputSuffix, DataSet *InSet) {
910924 for (auto *Input : InSet->DataObjects ) {
911925 if (Input->DataKind != AMD_COMGR_DATA_KIND_INCLUDE) {
912926 continue ;
@@ -944,7 +958,7 @@ AMDGPUCompiler::processFiles(amd_comgr_data_kind_t OutputKind,
944958 auto OutputFilePath = getFilePath (Output, OutputDir);
945959
946960 if (auto Status =
947- processFile (InputFilePath.c_str (), OutputFilePath.c_str ())) {
961+ processFile (Input, InputFilePath.c_str (), OutputFilePath.c_str ())) {
948962 return Status;
949963 }
950964
@@ -1868,19 +1882,115 @@ amd_comgr_status_t AMDGPUCompiler::linkToExecutable() {
18681882 return amd_comgr_data_set_add (OutSetT, OutputT);
18691883}
18701884
1885+ // TODO: Generalize this list to include all -cc1 flags and arguments that are
1886+ // still valid in a bitcode compilation context
1887+ static inline const std::unordered_set<std::string_view> ValidSpirvFlags{
1888+ " -fapprox-func" ,
1889+ " -fcolor-diagnostics" ,
1890+ " -fconvergent-functions" ,
1891+ " -fexceptions" ,
1892+ " -ffast-math" ,
1893+ " -ffinite-math-only" ,
1894+ " -ffp-contract=fast" ,
1895+ " -ffp-contract=fast-honor-pragmas" ,
1896+ " -ffp-contract=on" ,
1897+ " -fgpu-rdc" ,
1898+ " -finline-functions" ,
1899+ " -fno-autolink" ,
1900+ " -fno-experimental-relative-c++-abi-vtables" ,
1901+ " -fno-rounding-math" ,
1902+ " -fno-signed-zeros" ,
1903+ " -fno-threadsafe-statics" ,
1904+ " -freciprocal-math" ,
1905+ " -funsafe-math-optimizations" ,
1906+ " -fvisibility=hidden" ,
1907+ " -O0" ,
1908+ " -O1" ,
1909+ " -O2" ,
1910+ " -O3" ,
1911+ " --save-temps" };
1912+
1913+ amd_comgr_status_t AMDGPUCompiler::extractSpirvFlags (DataSet *BcSet) {
1914+
1915+ for (auto *Bc : BcSet->DataObjects ) {
1916+ // Create SPIR-V IR Module from Bitcode Buffer
1917+ SMDiagnostic SMDiag;
1918+ LLVMContext Context;
1919+ Context.setDiagnosticHandler (
1920+ std::make_unique<AMDGPUCompilerDiagnosticHandler>(this ->LogS ), true );
1921+
1922+ auto Mod = getLazyIRModule (
1923+ MemoryBuffer::getMemBuffer (StringRef (Bc->Data , Bc->Size ), " " , false ),
1924+ SMDiag, Context, true );
1925+
1926+ if (!Mod) {
1927+ SMDiag.print (" SPIR-V Bitcode" , LogS, /* ShowColors */ false );
1928+ return AMD_COMGR_STATUS_ERROR;
1929+ }
1930+
1931+ if (verifyModule (*Mod, &LogS))
1932+ return AMD_COMGR_STATUS_ERROR;
1933+
1934+ // Fetch @llvm.cmdline
1935+ GlobalVariable *CmdLine = Mod->getNamedGlobal (" llvm.cmdline" );
1936+
1937+ // Return if no @llvm.cmdline
1938+ if (!CmdLine)
1939+ return AMD_COMGR_STATUS_SUCCESS;
1940+
1941+ if (ConstantDataSequential *CDS =
1942+ dyn_cast<ConstantDataSequential>(CmdLine->getInitializer ())) {
1943+
1944+ // Add each valid null-terminated '\0' string to Flags
1945+ std::string Tmp;
1946+ StringRef CmdLineRaw = CDS->getRawDataValues ();
1947+ std::stringstream ss (CmdLineRaw.str ());
1948+ while (getline (ss, Tmp, ' \0 ' )) {
1949+ if (Tmp == " --hipstdpar" || Tmp == " -amdgpu-enable-hipstdpar" ) {
1950+ Bc->SpirvFlags .push_back (" -mllvm" );
1951+ Bc->SpirvFlags .push_back (" -amdgpu-enable-hipstdpar" );
1952+ } else if (Tmp == " -amdgpu-spill-cfi-saved-regs" ) {
1953+ Bc->SpirvFlags .push_back (" -mllvm" );
1954+ Bc->SpirvFlags .push_back (" -amdgpu-spill-cfi-saved-regs" );
1955+ } else if (ValidSpirvFlags.count (Tmp)) {
1956+ Bc->SpirvFlags .push_back (Saver.save (Tmp.c_str ()).data ());
1957+ }
1958+ }
1959+ }
1960+
1961+ // COV5 required for SPIR-V
1962+ Bc->SpirvFlags .push_back (" -mcode-object-version=5" );
1963+
1964+ if (env::shouldEmitVerboseLogs ()) {
1965+ LogS << " SPIR-V Flags: " << Bc->Name << " \n " ;
1966+ for (auto Flag : Bc->SpirvFlags )
1967+ LogS << " " << Flag << " \n " ;
1968+ }
1969+ }
1970+
1971+ return AMD_COMGR_STATUS_SUCCESS;
1972+ }
1973+
18711974amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode () {
1975+ return translateSpirvToBitcodeImpl (InSet, DataSet::convert (OutSetT));
1976+ }
1977+
1978+ amd_comgr_status_t
1979+ AMDGPUCompiler::translateSpirvToBitcodeImpl (DataSet *SpirvInSet,
1980+ DataSet *BcOutSet) {
18721981#ifdef COMGR_DISABLE_SPIRV
1873- LogS << " Calling AMDGPUCompiler::translateSpirvToBitcode () not supported "
1874- << " Comgr is built with -DCOMGR_DISABLE_SPIRV. Re-build LLVM and Comgr "
1875- << " with LLVM-SPIRV-Translator support to continue.\n " ;
1982+ LogS << " Calling AMDGPUCompiler::translateSpirvToBitcodeImpl () not "
1983+ << " supported. Comgr is built with -DCOMGR_DISABLE_SPIRV. Re-build LLVM "
1984+ << " and Comgr with LLVM-SPIRV-Translator support to continue.\n " ;
18761985 return AMD_COMGR_STATUS_ERROR;
18771986#else
18781987 if (auto Status = createTmpDirs ()) {
18791988 return Status;
18801989 }
18811990
18821991 auto Cache = CommandCache::get (LogS);
1883- for (auto *Input : InSet->DataObjects ) {
1992+
1993+ for (auto *Input : SpirvInSet->DataObjects ) {
18841994
18851995 if (env::shouldSaveTemps ()) {
18861996 if (auto Status = outputToFile (Input, getFilePath (Input, InputDir))) {
@@ -1918,7 +2028,8 @@ amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() {
19182028 Output->setName (std::string (Input->Name ) + std::string (" .bc" ));
19192029 Output->setData (OutBuf);
19202030
1921- if (auto Status = amd_comgr_data_set_add (OutSetT, OutputT)) {
2031+ if (auto Status =
2032+ amd_comgr_data_set_add (DataSet::convert (BcOutSet), OutputT)) {
19222033 return Status;
19232034 }
19242035
@@ -1937,6 +2048,50 @@ amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() {
19372048#endif
19382049}
19392050
2051+ amd_comgr_status_t AMDGPUCompiler::compileSpirvToRelocatable () {
2052+ if (auto Status = createTmpDirs ()) {
2053+ return Status;
2054+ }
2055+
2056+ for (auto *Input : InSet->DataObjects ) {
2057+ if (Input->DataKind != AMD_COMGR_DATA_KIND_SPIRV)
2058+ return AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT;
2059+ }
2060+
2061+ // Translate .spv to .bc
2062+ amd_comgr_data_set_t TranslatedSpirvT;
2063+ if (auto Status = amd_comgr_create_data_set (&TranslatedSpirvT))
2064+ return Status;
2065+ DataSet *TranslatedSpirv = DataSet::convert (TranslatedSpirvT);
2066+
2067+ if (auto Status = translateSpirvToBitcodeImpl (InSet, TranslatedSpirv))
2068+ return Status;
2069+
2070+ // Extract relevant -cc1 flags from @llvm.cmdline
2071+ if (auto Status = extractSpirvFlags (TranslatedSpirv))
2072+ return Status;
2073+
2074+ // Compile bitcode to relocatable
2075+ if (ActionInfo->IsaName ) {
2076+ if (auto Status = addTargetIdentifierFlags (ActionInfo->IsaName )) {
2077+ return Status;
2078+ }
2079+ }
2080+
2081+ if (ActionInfo->ShouldLinkDeviceLibs ) {
2082+ if (auto Status = addDeviceLibraries ()) {
2083+ return Status;
2084+ }
2085+ }
2086+
2087+ Args.push_back (" -c" );
2088+
2089+ Args.push_back (" -mllvm" );
2090+ Args.push_back (" -amdgpu-internalize-symbols" );
2091+
2092+ return processFiles (AMD_COMGR_DATA_KIND_RELOCATABLE, " .o" , TranslatedSpirv);
2093+ }
2094+
19402095AMDGPUCompiler::AMDGPUCompiler (DataAction *ActionInfo, DataSet *InSet,
19412096 DataSet *OutSet, raw_ostream &LogS)
19422097 : ActionInfo(ActionInfo), InSet(InSet), OutSetT(DataSet::convert(OutSet)),
0 commit comments