@@ -6744,7 +6744,6 @@ bool LLVMToSPIRVBase::joinFPContract(Function *F, FPContract C) {
6744
6744
}
6745
6745
llvm_unreachable (" Unhandled FPContract value." );
6746
6746
}
6747
-
6748
6747
} // namespace SPIRV
6749
6748
6750
6749
char LLVMToSPIRVLegacy::ID = 0 ;
@@ -6790,8 +6789,123 @@ bool isValidLLVMModule(Module *M, SPIRVErrorLog &ErrorLog) {
6790
6789
return true ;
6791
6790
}
6792
6791
6792
+ #if defined(LLVM_SPIRV_BACKEND_TARGET_PRESENT)
6793
+ namespace llvm {
6794
+ extern " C" bool
6795
+ SPIRVTranslateModule (Module *M, std::string &SpirvObj, std::string &ErrMsg,
6796
+ const std::vector<std::string> &AllowExtNames,
6797
+ const std::vector<std::string> &Opts);
6798
+ } // namespace llvm
6799
+ #if defined(_SPIRV_SUPPORT_TEXT_FMT)
6800
+ namespace SPIRV {
6801
+ bool convertSpirv (std::istream &IS, std::ostream &OS, std::string &ErrMsg,
6802
+ bool FromText, bool ToText);
6803
+ } // namespace SPIRV
6804
+ #endif // _SPIRV_SUPPORT_TEXT_FMT
6805
+ #endif // LLVM_SPIRV_BACKEND_TARGET_PRESENT
6806
+
6793
6807
namespace {
6794
6808
6809
+ #if defined(LLVM_SPIRV_BACKEND_TARGET_PRESENT)
6810
+ static inline Triple::SubArchType spirvVersionToSubArch (VersionNumber VN) {
6811
+ switch (VN) {
6812
+ case VersionNumber::SPIRV_1_0:
6813
+ return Triple::SPIRVSubArch_v10;
6814
+ case VersionNumber::SPIRV_1_1:
6815
+ return Triple::SPIRVSubArch_v11;
6816
+ case VersionNumber::SPIRV_1_2:
6817
+ return Triple::SPIRVSubArch_v12;
6818
+ case VersionNumber::SPIRV_1_3:
6819
+ return Triple::SPIRVSubArch_v13;
6820
+ case VersionNumber::SPIRV_1_4:
6821
+ return Triple::SPIRVSubArch_v14;
6822
+ case VersionNumber::SPIRV_1_5:
6823
+ return Triple::SPIRVSubArch_v15;
6824
+ case VersionNumber::SPIRV_1_6:
6825
+ return Triple::SPIRVSubArch_v16;
6826
+ }
6827
+ return Triple::NoSubArch;
6828
+ }
6829
+
6830
+ bool runSpirvBackend (Module *M, std::string &Result, std::string &ErrMsg,
6831
+ const SPIRV::TranslatorOpts &TranslatorOpts) {
6832
+ // A list of known extensions supported by SPIR-V Backend: it's to be updated
6833
+ // each time when SPIR-V Backend introduces support for a new extension.
6834
+ static const std::set<ExtensionID> ImplementedBySpirvBE{
6835
+ SPIRV::ExtensionID::SPV_EXT_shader_atomic_float_add,
6836
+ SPIRV::ExtensionID::SPV_EXT_shader_atomic_float16_add,
6837
+ SPIRV::ExtensionID::SPV_EXT_shader_atomic_float_min_max,
6838
+ SPIRV::ExtensionID::SPV_INTEL_arbitrary_precision_integers,
6839
+ SPIRV::ExtensionID::SPV_INTEL_cache_controls,
6840
+ SPIRV::ExtensionID::SPV_INTEL_global_variable_fpga_decorations,
6841
+ SPIRV::ExtensionID::SPV_INTEL_global_variable_host_access,
6842
+ SPIRV::ExtensionID::SPV_INTEL_optnone,
6843
+ SPIRV::ExtensionID::SPV_INTEL_usm_storage_classes,
6844
+ SPIRV::ExtensionID::SPV_INTEL_subgroups,
6845
+ SPIRV::ExtensionID::SPV_KHR_uniform_group_instructions,
6846
+ SPIRV::ExtensionID::SPV_KHR_no_integer_wrap_decoration,
6847
+ SPIRV::ExtensionID::SPV_KHR_float_controls,
6848
+ SPIRV::ExtensionID::SPV_KHR_expect_assume,
6849
+ SPIRV::ExtensionID::SPV_KHR_bit_instructions,
6850
+ SPIRV::ExtensionID::SPV_KHR_linkonce_odr,
6851
+ SPIRV::ExtensionID::SPV_INTEL_inline_assembly,
6852
+ SPIRV::ExtensionID::SPV_INTEL_bfloat16_conversion,
6853
+ SPIRV::ExtensionID::SPV_KHR_subgroup_rotate,
6854
+ SPIRV::ExtensionID::SPV_INTEL_variable_length_array,
6855
+ SPIRV::ExtensionID::SPV_INTEL_function_pointers,
6856
+ SPIRV::ExtensionID::SPV_KHR_shader_clock,
6857
+ SPIRV::ExtensionID::SPV_KHR_cooperative_matrix,
6858
+ SPIRV::ExtensionID::SPV_KHR_non_semantic_info};
6859
+ // The fallback for the Triple value.
6860
+ static const std::string DefaultTriple = " spirv64-unknown-unknown" ;
6861
+ // SPIR-V backend uses the following command line options to conform with
6862
+ // Translator's way to generate SPIR-V or with requirements of the Compute
6863
+ // flavor of SPIR-V. This list is subject to changes and may become empty
6864
+ // eventually.
6865
+ static const std::vector<std::string> Opts{" --avoid-spirv-capabilities" ,
6866
+ " Shader" ,
6867
+ " --translator-compatibility-mode" };
6868
+
6869
+ std::function<bool (SPIRV::ExtensionID)> Filter =
6870
+ [](SPIRV::ExtensionID Ext) -> bool {
6871
+ return ImplementedBySpirvBE.find (Ext) != ImplementedBySpirvBE.end ();
6872
+ };
6873
+ const std::vector<std::string> AllowExtNames =
6874
+ TranslatorOpts.getAllowedSPIRVExtensionNames (Filter);
6875
+
6876
+ // Correct the Triple value if needed
6877
+ Triple TargetTriple (M->getTargetTriple ());
6878
+ if (TargetTriple.isSPIR ()) {
6879
+ TargetTriple.setArch (TargetTriple.getArch () == Triple::spir64
6880
+ ? Triple::spirv64
6881
+ : Triple::spirv32,
6882
+ TargetTriple.getSubArch ());
6883
+ M->setTargetTriple (TargetTriple.str ());
6884
+ // We need to reset Data Layout to conform with the TargetMachine
6885
+ M->setDataLayout (" " );
6886
+ }
6887
+ if (TranslatorOpts.getMaxVersion () != VersionNumber::MaximumVersion) {
6888
+ if (TargetTriple.getTriple ().empty ())
6889
+ TargetTriple.setTriple (DefaultTriple);
6890
+ TargetTriple.setArch (TargetTriple.getArch (),
6891
+ spirvVersionToSubArch (TranslatorOpts.getMaxVersion ()));
6892
+ M->setTargetTriple (TargetTriple.str ());
6893
+ }
6894
+
6895
+ // Translate the Module into SPIR-V
6896
+ return llvm::SPIRVTranslateModule (M, Result, ErrMsg, AllowExtNames, Opts);
6897
+ }
6898
+
6899
+ bool runSpirvBackend (Module *M, std::ostream *OS, std::string &ErrMsg,
6900
+ const SPIRV::TranslatorOpts &TranslatorOpts) {
6901
+ std::string Result;
6902
+ bool Status = runSpirvBackend (M, Result, ErrMsg, TranslatorOpts);
6903
+ if (Status && OS)
6904
+ *OS << Result;
6905
+ return Status;
6906
+ }
6907
+ #endif // LLVM_SPIRV_BACKEND_TARGET_PRESENT
6908
+
6795
6909
VersionNumber getVersionFromTriple (const Triple &TT, SPIRVErrorLog &ErrorLog) {
6796
6910
switch (TT.getSubArch ()) {
6797
6911
case Triple::SPIRVSubArch_v10:
@@ -6885,6 +6999,28 @@ bool llvm::writeSpirv(Module *M, std::ostream &OS, std::string &ErrMsg) {
6885
6999
6886
7000
bool llvm::writeSpirv (Module *M, const SPIRV::TranslatorOpts &Opts,
6887
7001
std::ostream &OS, std::string &ErrMsg) {
7002
+ #if defined(LLVM_SPIRV_BACKEND_TARGET_PRESENT)
7003
+ // Check if a user asks to convert LLVM to SPIR-V using the LLVM SPIR-V
7004
+ // Backend target
7005
+ if (Opts.getUseLLVMTarget ()) {
7006
+ #if !defined(_SPIRV_SUPPORT_TEXT_FMT)
7007
+ return runSpirvBackend (M, &OS, ErrMsg, Opts);
7008
+ #else
7009
+ if (!SPIRVUseTextFormat)
7010
+ return runSpirvBackend (M, &OS, ErrMsg, Opts);
7011
+
7012
+ // SPIR-V Backend always returns a binary: let's use temporary buffers to
7013
+ // store the binary representation and convert it later into Translator's
7014
+ // textual representation
7015
+ std::string BinResult;
7016
+ if (!runSpirvBackend (M, BinResult, ErrMsg, Opts))
7017
+ return false ;
7018
+ std::istringstream IS (BinResult);
7019
+ return SPIRV::convertSpirv (IS, OS, ErrMsg, false /* FromText*/ ,
7020
+ true /* ToText*/ );
7021
+ #endif // _SPIRV_SUPPORT_TEXT_FMT
7022
+ }
7023
+ #endif // LLVM_SPIRV_BACKEND_TARGET_PRESENT
6888
7024
return runSpirvWriterPasses (M, &OS, ErrMsg, Opts);
6889
7025
}
6890
7026
0 commit comments