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,101 @@ 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
+ " -fgpu-rdc" ,
1917
+ " -finline-functions" ,
1918
+ " -fno-signed-zeros" ,
1919
+ " -fno-rounding-math" ,
1920
+ " -fno-experimental-relative-c++-abi-vtables" ,
1921
+ " -fno-autolink" ,
1922
+ " -freciprocal-math" ,
1923
+ " -funsafe-math-optimizations" ,
1924
+ " -fvisibility=hidden" ,
1925
+ " -O0" ,
1926
+ " -O1" ,
1927
+ " -O2" ,
1928
+ " -O3" ,
1929
+ " --save-temps" };
1930
+
1931
+ amd_comgr_status_t AMDGPUCompiler::extractSpirvFlags (DataSet *BcSet) {
1932
+
1933
+ for (auto *Bc : BcSet->DataObjects ) {
1934
+ // Create SPIRV IR Module from Bitcode Buffer
1935
+ SMDiagnostic SMDiag;
1936
+ LLVMContext Context;
1937
+ Context.setDiagnosticHandler (
1938
+ std::make_unique<AMDGPUCompilerDiagnosticHandler>(this ->LogS ), true );
1939
+
1940
+ auto Mod = getLazyIRModule (
1941
+ MemoryBuffer::getMemBuffer (StringRef (Bc->Data , Bc->Size ), " " , false ),
1942
+ SMDiag, Context, true );
1943
+
1944
+ if (!Mod) {
1945
+ SMDiag.print (" SPIR-V Bitcode" , LogS, /* ShowColors */ false );
1946
+ return AMD_COMGR_STATUS_ERROR;
1947
+ }
1948
+
1949
+ if (verifyModule (*Mod, &LogS))
1950
+ return AMD_COMGR_STATUS_ERROR;
1951
+
1952
+ // Fetch @llvm.cmdline
1953
+ GlobalVariable *CmdLine = Mod->getNamedGlobal (" llvm.cmdline" );
1954
+
1955
+ // Return if no @llvm.cmdline
1956
+ if (!CmdLine)
1957
+ return AMD_COMGR_STATUS_SUCCESS;
1958
+
1959
+ if (ConstantDataSequential *CDS =
1960
+ dyn_cast<ConstantDataSequential>(CmdLine->getInitializer ())) {
1961
+
1962
+ // Add each valid null-terminated '\0' string to Flags
1963
+ std::string Tmp;
1964
+ StringRef CmdLineRaw = CDS->getRawDataValues ();
1965
+ std::stringstream ss (CmdLineRaw.str ());
1966
+ while (getline (ss, Tmp, ' \0 ' )) {
1967
+ if (Tmp == " --hipstdpar" || Tmp == " -amdgpu-enable-hipstdpar" ) {
1968
+ Bc->SpirvFlags .push_back (" -mllvm" );
1969
+ Bc->SpirvFlags .push_back (" -amdgpu-enable-hipstdpar" );
1970
+ } else if (ValidSpirvFlags.count (Tmp)) {
1971
+ Bc->SpirvFlags .push_back (Saver.save (Tmp.c_str ()).data ());
1972
+ }
1973
+ }
1974
+ }
1975
+
1976
+ // COV5 required for SPIRV
1977
+ Bc->SpirvFlags .push_back (" -mcode-object-version=5" );
1978
+
1979
+ if (env::shouldEmitVerboseLogs ()) {
1980
+ LogS << " SPIR-V Flags: " << Bc->Name << " \n " ;
1981
+ for (auto Flag : Bc->SpirvFlags )
1982
+ LogS << " " << Flag << " \n " ;
1983
+ }
1984
+ }
1985
+
1986
+ return AMD_COMGR_STATUS_SUCCESS;
1987
+ }
1988
+
1891
1989
amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode () {
1990
+ return translateSpirvToBitcodeImpl (InSet, DataSet::convert (OutSetT));
1991
+ }
1992
+
1993
+ amd_comgr_status_t
1994
+ AMDGPUCompiler::translateSpirvToBitcodeImpl (DataSet *SpirvInSet,
1995
+ DataSet *BcOutSet) {
1892
1996
#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 " ;
1997
+ LogS << " Calling AMDGPUCompiler::translateSpirvToBitcodeImpl () not "
1998
+ << " supported. Comgr is built with -DCOMGR_DISABLE_SPIRV. Re-build LLVM "
1999
+ << " and Comgr with LLVM-SPIRV-Translator support to continue.\n " ;
1896
2000
return AMD_COMGR_STATUS_ERROR;
1897
2001
#else
1898
2002
if (auto Status = createTmpDirs ()) {
@@ -1901,7 +2005,7 @@ amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() {
1901
2005
1902
2006
auto Cache = CommandCache::get (LogS);
1903
2007
1904
- for (auto *Input : InSet ->DataObjects ) {
2008
+ for (auto *Input : SpirvInSet ->DataObjects ) {
1905
2009
1906
2010
if (env::shouldSaveTemps ()) {
1907
2011
if (auto Status = outputToFile (Input, getFilePath (Input, InputDir))) {
@@ -1939,7 +2043,8 @@ amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() {
1939
2043
Output->setName (std::string (Input->Name ) + std::string (" .bc" ));
1940
2044
Output->setData (OutBuf);
1941
2045
1942
- if (auto Status = amd_comgr_data_set_add (OutSetT, OutputT)) {
2046
+ if (auto Status =
2047
+ amd_comgr_data_set_add (DataSet::convert (BcOutSet), OutputT)) {
1943
2048
return Status;
1944
2049
}
1945
2050
@@ -1960,6 +2065,50 @@ amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() {
1960
2065
#endif
1961
2066
}
1962
2067
2068
+ amd_comgr_status_t AMDGPUCompiler::compileSpirvToRelocatable () {
2069
+ if (auto Status = createTmpDirs ()) {
2070
+ return Status;
2071
+ }
2072
+
2073
+ for (auto *Input : InSet->DataObjects ) {
2074
+ if (Input->DataKind != AMD_COMGR_DATA_KIND_SPIRV)
2075
+ return AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT;
2076
+ }
2077
+
2078
+ // Translate .spv to .bc
2079
+ amd_comgr_data_set_t TranslatedSpirvT;
2080
+ if (auto Status = amd_comgr_create_data_set (&TranslatedSpirvT))
2081
+ return Status;
2082
+ DataSet *TranslatedSpirv = DataSet::convert (TranslatedSpirvT);
2083
+
2084
+ if (auto Status = translateSpirvToBitcodeImpl (InSet, TranslatedSpirv))
2085
+ return Status;
2086
+
2087
+ // Extract any SPIR-V flags from @llvm.cmdline
2088
+ if (auto Status = extractSpirvFlags (TranslatedSpirv))
2089
+ return Status;
2090
+
2091
+ // Compile bitcode to relocatable
2092
+ if (ActionInfo->IsaName ) {
2093
+ if (auto Status = addTargetIdentifierFlags (ActionInfo->IsaName )) {
2094
+ return Status;
2095
+ }
2096
+ }
2097
+
2098
+ if (ActionInfo->ShouldLinkDeviceLibs ) {
2099
+ if (auto Status = addDeviceLibraries ()) {
2100
+ return Status;
2101
+ }
2102
+ }
2103
+
2104
+ Args.push_back (" -c" );
2105
+
2106
+ Args.push_back (" -mllvm" );
2107
+ Args.push_back (" -amdgpu-internalize-symbols" );
2108
+
2109
+ return processFiles (AMD_COMGR_DATA_KIND_RELOCATABLE, " .o" , TranslatedSpirv);
2110
+ }
2111
+
1963
2112
AMDGPUCompiler::AMDGPUCompiler (DataAction *ActionInfo, DataSet *InSet,
1964
2113
DataSet *OutSet, raw_ostream &LogS)
1965
2114
: ActionInfo(ActionInfo), InSet(InSet), OutSetT(DataSet::convert(OutSet)),
0 commit comments