58
58
#include " clang/FrontendTool/Utils.h"
59
59
#include " llvm/ADT/StringExtras.h"
60
60
#include " llvm/Bitcode/BitcodeWriter.h"
61
+ #include " llvm/IR/Constants.h"
61
62
#include " llvm/IR/LLVMContext.h"
62
63
#include " llvm/IR/Module.h"
63
64
#include " llvm/IR/Verifier.h"
@@ -877,7 +878,8 @@ amd_comgr_status_t AMDGPUCompiler::removeTmpDirs() {
877
878
#endif
878
879
}
879
880
880
- amd_comgr_status_t AMDGPUCompiler::processFile (const char *InputFilePath,
881
+ amd_comgr_status_t AMDGPUCompiler::processFile (DataObject *Input,
882
+ const char *InputFilePath,
881
883
const char *OutputFilePath) {
882
884
SmallVector<const char *, 128 > Argv = Args;
883
885
@@ -899,6 +901,12 @@ amd_comgr_status_t AMDGPUCompiler::processFile(const char *InputFilePath,
899
901
Argv.push_back (" -save-temps=obj" );
900
902
}
901
903
904
+ // Add SPIR-V flags
905
+ for (auto Flag : Input->SpirvFlags ) {
906
+ Argv.push_back (" -Xclang" );
907
+ Argv.push_back (Flag);
908
+ }
909
+
902
910
Argv.push_back (InputFilePath);
903
911
904
912
Argv.push_back (" -o" );
@@ -910,6 +918,12 @@ amd_comgr_status_t AMDGPUCompiler::processFile(const char *InputFilePath,
910
918
amd_comgr_status_t
911
919
AMDGPUCompiler::processFiles (amd_comgr_data_kind_t OutputKind,
912
920
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) {
913
927
for (auto *Input : InSet->DataObjects ) {
914
928
if (Input->DataKind != AMD_COMGR_DATA_KIND_INCLUDE) {
915
929
continue ;
@@ -947,7 +961,7 @@ AMDGPUCompiler::processFiles(amd_comgr_data_kind_t OutputKind,
947
961
auto OutputFilePath = getFilePath (Output, OutputDir);
948
962
949
963
if (auto Status =
950
- processFile (InputFilePath.c_str (), OutputFilePath.c_str ())) {
964
+ processFile (Input, InputFilePath.c_str (), OutputFilePath.c_str ())) {
951
965
return Status;
952
966
}
953
967
@@ -1888,11 +1902,106 @@ amd_comgr_status_t AMDGPUCompiler::linkToExecutable() {
1888
1902
return amd_comgr_data_set_add (OutSetT, OutputT);
1889
1903
}
1890
1904
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
+
1891
1994
amd_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) {
1892
2001
#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 " ;
1896
2005
return AMD_COMGR_STATUS_ERROR;
1897
2006
#else
1898
2007
if (auto Status = createTmpDirs ()) {
@@ -1901,7 +2010,7 @@ amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() {
1901
2010
1902
2011
auto Cache = CommandCache::get (LogS);
1903
2012
1904
- for (auto *Input : InSet ->DataObjects ) {
2013
+ for (auto *Input : SpirvInSet ->DataObjects ) {
1905
2014
1906
2015
if (env::shouldSaveTemps ()) {
1907
2016
if (auto Status = outputToFile (Input, getFilePath (Input, InputDir))) {
@@ -1939,7 +2048,8 @@ amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() {
1939
2048
Output->setName (std::string (Input->Name ) + std::string (" .bc" ));
1940
2049
Output->setData (OutBuf);
1941
2050
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)) {
1943
2053
return Status;
1944
2054
}
1945
2055
@@ -1960,6 +2070,50 @@ amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() {
1960
2070
#endif
1961
2071
}
1962
2072
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
+
1963
2117
AMDGPUCompiler::AMDGPUCompiler (DataAction *ActionInfo, DataSet *InSet,
1964
2118
DataSet *OutSet, raw_ostream &LogS)
1965
2119
: ActionInfo(ActionInfo), InSet(InSet), OutSetT(DataSet::convert(OutSet)),
0 commit comments