5858#include " clang/FrontendTool/Utils.h"
5959#include " llvm/ADT/StringExtras.h"
6060#include " llvm/Bitcode/BitcodeWriter.h"
61+ #include " llvm/IR/Constants.h"
6162#include " llvm/IR/LLVMContext.h"
6263#include " llvm/IR/Module.h"
6364#include " llvm/IR/Verifier.h"
@@ -877,7 +878,8 @@ amd_comgr_status_t AMDGPUCompiler::removeTmpDirs() {
877878#endif
878879}
879880
880- amd_comgr_status_t AMDGPUCompiler::processFile (const char *InputFilePath,
881+ amd_comgr_status_t AMDGPUCompiler::processFile (DataObject *Input,
882+ const char *InputFilePath,
881883 const char *OutputFilePath) {
882884 SmallVector<const char *, 128 > Argv = Args;
883885
@@ -899,6 +901,12 @@ amd_comgr_status_t AMDGPUCompiler::processFile(const char *InputFilePath,
899901 Argv.push_back (" -save-temps=obj" );
900902 }
901903
904+ // Add SPIR-V flags
905+ for (auto Flag : Input->SpirvFlags ) {
906+ Argv.push_back (" -Xclang" );
907+ Argv.push_back (Flag);
908+ }
909+
902910 Argv.push_back (InputFilePath);
903911
904912 Argv.push_back (" -o" );
@@ -910,6 +918,12 @@ amd_comgr_status_t AMDGPUCompiler::processFile(const char *InputFilePath,
910918amd_comgr_status_t
911919AMDGPUCompiler::processFiles (amd_comgr_data_kind_t OutputKind,
912920 const char *OutputSuffix) {
921+ return processFiles (OutputKind, OutputSuffix, InSet);
922+ }
923+
924+ amd_comgr_status_t
925+ AMDGPUCompiler::processFiles (amd_comgr_data_kind_t OutputKind,
926+ const char *OutputSuffix, DataSet *InSet) {
913927 for (auto *Input : InSet->DataObjects ) {
914928 if (Input->DataKind != AMD_COMGR_DATA_KIND_INCLUDE) {
915929 continue ;
@@ -947,7 +961,7 @@ AMDGPUCompiler::processFiles(amd_comgr_data_kind_t OutputKind,
947961 auto OutputFilePath = getFilePath (Output, OutputDir);
948962
949963 if (auto Status =
950- processFile (InputFilePath.c_str (), OutputFilePath.c_str ())) {
964+ processFile (Input, InputFilePath.c_str (), OutputFilePath.c_str ())) {
951965 return Status;
952966 }
953967
@@ -1888,11 +1902,106 @@ amd_comgr_status_t AMDGPUCompiler::linkToExecutable() {
18881902 return amd_comgr_data_set_add (OutSetT, OutputT);
18891903}
18901904
1905+ // TODO: Generalize this list to include all -cc1 flags and arguments that are
1906+ // still valid in a bitcode compilation context
1907+ static inline const std::unordered_set<std::string_view> ValidSpirvFlags{
1908+ " -fapprox-func" ,
1909+ " -fcolor-diagnostics" ,
1910+ " -fconvergent-functions" ,
1911+ " -fexceptions" ,
1912+ " -ffast-math" ,
1913+ " -ffinite-math-only" ,
1914+ " -ffp-contract=fast" ,
1915+ " -ffp-contract=fast-honor-pragmas" ,
1916+ " -ffp-contract=on" ,
1917+ " -fgpu-rdc" ,
1918+ " -finline-functions" ,
1919+ " -fno-autolink" ,
1920+ " -fno-experimental-relative-c++-abi-vtables" ,
1921+ " -fno-rounding-math" ,
1922+ " -fno-signed-zeros" ,
1923+ " -fno-threadsafe-statics" ,
1924+ " -freciprocal-math" ,
1925+ " -funsafe-math-optimizations" ,
1926+ " -fvisibility=hidden" ,
1927+ " -O0" ,
1928+ " -O1" ,
1929+ " -O2" ,
1930+ " -O3" ,
1931+ " --save-temps" };
1932+
1933+ amd_comgr_status_t AMDGPUCompiler::extractSpirvFlags (DataSet *BcSet) {
1934+
1935+ for (auto *Bc : BcSet->DataObjects ) {
1936+ // Create SPIR-V IR Module from Bitcode Buffer
1937+ SMDiagnostic SMDiag;
1938+ LLVMContext Context;
1939+ Context.setDiagnosticHandler (
1940+ std::make_unique<AMDGPUCompilerDiagnosticHandler>(this ->LogS ), true );
1941+
1942+ auto Mod = getLazyIRModule (
1943+ MemoryBuffer::getMemBuffer (StringRef (Bc->Data , Bc->Size ), " " , false ),
1944+ SMDiag, Context, true );
1945+
1946+ if (!Mod) {
1947+ SMDiag.print (" SPIR-V Bitcode" , LogS, /* ShowColors */ false );
1948+ return AMD_COMGR_STATUS_ERROR;
1949+ }
1950+
1951+ if (verifyModule (*Mod, &LogS))
1952+ return AMD_COMGR_STATUS_ERROR;
1953+
1954+ // Fetch @llvm.cmdline
1955+ GlobalVariable *CmdLine = Mod->getNamedGlobal (" llvm.cmdline" );
1956+
1957+ // Return if no @llvm.cmdline
1958+ if (!CmdLine)
1959+ return AMD_COMGR_STATUS_SUCCESS;
1960+
1961+ if (ConstantDataSequential *CDS =
1962+ dyn_cast<ConstantDataSequential>(CmdLine->getInitializer ())) {
1963+
1964+ // Add each valid null-terminated '\0' string to Flags
1965+ std::string Tmp;
1966+ StringRef CmdLineRaw = CDS->getRawDataValues ();
1967+ std::stringstream ss (CmdLineRaw.str ());
1968+ while (getline (ss, Tmp, ' \0 ' )) {
1969+ if (Tmp == " --hipstdpar" || Tmp == " -amdgpu-enable-hipstdpar" ) {
1970+ Bc->SpirvFlags .push_back (" -mllvm" );
1971+ Bc->SpirvFlags .push_back (" -amdgpu-enable-hipstdpar" );
1972+ } else if (Tmp == " -amdgpu-spill-cfi-saved-regs" ) {
1973+ Bc->SpirvFlags .push_back (" -mllvm" );
1974+ Bc->SpirvFlags .push_back (" -amdgpu-spill-cfi-saved-regs" );
1975+ } else if (ValidSpirvFlags.count (Tmp)) {
1976+ Bc->SpirvFlags .push_back (Saver.save (Tmp.c_str ()).data ());
1977+ }
1978+ }
1979+ }
1980+
1981+ // COV5 required for SPIR-V
1982+ Bc->SpirvFlags .push_back (" -mcode-object-version=5" );
1983+
1984+ if (env::shouldEmitVerboseLogs ()) {
1985+ LogS << " SPIR-V Flags: " << Bc->Name << " \n " ;
1986+ for (auto Flag : Bc->SpirvFlags )
1987+ LogS << " " << Flag << " \n " ;
1988+ }
1989+ }
1990+
1991+ return AMD_COMGR_STATUS_SUCCESS;
1992+ }
1993+
18911994amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode () {
1995+ return translateSpirvToBitcodeImpl (InSet, DataSet::convert (OutSetT));
1996+ }
1997+
1998+ amd_comgr_status_t
1999+ AMDGPUCompiler::translateSpirvToBitcodeImpl (DataSet *SpirvInSet,
2000+ DataSet *BcOutSet) {
18922001#ifdef COMGR_DISABLE_SPIRV
1893- LogS << " Calling AMDGPUCompiler::translateSpirvToBitcode () not supported. "
1894- << " Comgr is built with -DCOMGR_DISABLE_SPIRV. Re-build LLVM and Comgr "
1895- << " with LLVM-SPIRV-Translator support to continue.\n " ;
2002+ LogS << " Calling AMDGPUCompiler::translateSpirvToBitcodeImpl () not "
2003+ << " supported. Comgr is built with -DCOMGR_DISABLE_SPIRV. Re-build LLVM "
2004+ << " and Comgr with LLVM-SPIRV-Translator support to continue.\n " ;
18962005 return AMD_COMGR_STATUS_ERROR;
18972006#else
18982007 if (auto Status = createTmpDirs ()) {
@@ -1901,7 +2010,7 @@ amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() {
19012010
19022011 auto Cache = CommandCache::get (LogS);
19032012
1904- for (auto *Input : InSet ->DataObjects ) {
2013+ for (auto *Input : SpirvInSet ->DataObjects ) {
19052014
19062015 if (env::shouldSaveTemps ()) {
19072016 if (auto Status = outputToFile (Input, getFilePath (Input, InputDir))) {
@@ -1939,7 +2048,8 @@ amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() {
19392048 Output->setName (std::string (Input->Name ) + std::string (" .bc" ));
19402049 Output->setData (OutBuf);
19412050
1942- if (auto Status = amd_comgr_data_set_add (OutSetT, OutputT)) {
2051+ if (auto Status =
2052+ amd_comgr_data_set_add (DataSet::convert (BcOutSet), OutputT)) {
19432053 return Status;
19442054 }
19452055
@@ -1960,6 +2070,50 @@ amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() {
19602070#endif
19612071}
19622072
2073+ amd_comgr_status_t AMDGPUCompiler::compileSpirvToRelocatable () {
2074+ if (auto Status = createTmpDirs ()) {
2075+ return Status;
2076+ }
2077+
2078+ for (auto *Input : InSet->DataObjects ) {
2079+ if (Input->DataKind != AMD_COMGR_DATA_KIND_SPIRV)
2080+ return AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT;
2081+ }
2082+
2083+ // Translate .spv to .bc
2084+ amd_comgr_data_set_t TranslatedSpirvT;
2085+ if (auto Status = amd_comgr_create_data_set (&TranslatedSpirvT))
2086+ return Status;
2087+ DataSet *TranslatedSpirv = DataSet::convert (TranslatedSpirvT);
2088+
2089+ if (auto Status = translateSpirvToBitcodeImpl (InSet, TranslatedSpirv))
2090+ return Status;
2091+
2092+ // Extract relevant -cc1 flags from @llvm.cmdline
2093+ if (auto Status = extractSpirvFlags (TranslatedSpirv))
2094+ return Status;
2095+
2096+ // Compile bitcode to relocatable
2097+ if (ActionInfo->IsaName ) {
2098+ if (auto Status = addTargetIdentifierFlags (ActionInfo->IsaName )) {
2099+ return Status;
2100+ }
2101+ }
2102+
2103+ if (ActionInfo->ShouldLinkDeviceLibs ) {
2104+ if (auto Status = addDeviceLibraries ()) {
2105+ return Status;
2106+ }
2107+ }
2108+
2109+ Args.push_back (" -c" );
2110+
2111+ Args.push_back (" -mllvm" );
2112+ Args.push_back (" -amdgpu-internalize-symbols" );
2113+
2114+ return processFiles (AMD_COMGR_DATA_KIND_RELOCATABLE, " .o" , TranslatedSpirv);
2115+ }
2116+
19632117AMDGPUCompiler::AMDGPUCompiler (DataAction *ActionInfo, DataSet *InSet,
19642118 DataSet *OutSet, raw_ostream &LogS)
19652119 : ActionInfo(ActionInfo), InSet(InSet), OutSetT(DataSet::convert(OutSet)),
0 commit comments