88
99#include " SPIRVCommandLine.h"
1010#include " SPIRVSubtarget.h"
11+ #include " SPIRVTargetMachine.h"
1112#include " llvm/Analysis/TargetLibraryInfo.h"
1213#include " llvm/CodeGen/CommandFlags.h"
1314#include " llvm/CodeGen/MachineFunctionPass.h"
@@ -40,25 +41,6 @@ using namespace llvm;
4041
4142namespace {
4243
43- // Mimic limited number of command line flags from llc to provide a better
44- // user experience when passing options into the translate API call.
45- static cl::opt<char > SpirvOptLevel (" spirv-O" , cl::Hidden, cl::Prefix,
46- cl::init (' 0' ));
47- static cl::opt<std::string> SpirvTargetTriple (" spirv-mtriple" , cl::Hidden,
48- cl::init (" " ));
49-
50- // Utility to accept options in a command line style.
51- void parseSPIRVCommandLineOptions (const std::vector<std::string> &Options,
52- raw_ostream *Errs) {
53- static constexpr const char *Origin = " SPIRVTranslateModule" ;
54- if (!Options.empty ()) {
55- std::vector<const char *> Argv (1 , Origin);
56- for (const auto &Arg : Options)
57- Argv.push_back (Arg.c_str ());
58- cl::ParseCommandLineOptions (Argv.size (), Argv.data (), Origin, Errs);
59- }
60- }
61-
6244std::once_flag InitOnceFlag;
6345void InitializeSPIRVTarget () {
6446 std::call_once (InitOnceFlag, []() {
@@ -75,50 +57,26 @@ namespace llvm {
7557// The goal of this function is to facilitate integration of SPIRV Backend into
7658// tools and libraries by means of exposing an API call that translate LLVM
7759// module to SPIR-V and write results into a string as binary SPIR-V output,
78- // providing diagnostics on fail and means of configuring translation in a style
79- // of command line options.
60+ // providing diagnostics on fail and means of configuring translation.
8061extern " C" LLVM_EXTERNAL_VISIBILITY bool
81- SPIRVTranslateModule (Module *M, std::string &SpirvObj, std::string &ErrMsg,
82- const std::vector<std::string> &AllowExtNames,
83- const std::vector<std::string> &Opts ) {
62+ SPIRVTranslate (Module *M, std::string &SpirvObj, std::string &ErrMsg,
63+ const std::vector<std::string> &AllowExtNames,
64+ llvm::CodeGenOptLevel OLevel, Triple TargetTriple ) {
8465 // Fallbacks for option values.
8566 static const std::string DefaultTriple = " spirv64-unknown-unknown" ;
8667 static const std::string DefaultMArch = " " ;
8768
88- // Parse Opts as if it'd be command line arguments.
89- std::string Errors;
90- raw_string_ostream ErrorStream (Errors);
91- parseSPIRVCommandLineOptions (Opts, &ErrorStream);
92- if (!Errors.empty ()) {
93- ErrMsg = Errors;
94- return false ;
95- }
96-
97- llvm::CodeGenOptLevel OLevel;
98- if (auto Level = CodeGenOpt::parseLevel (SpirvOptLevel)) {
99- OLevel = *Level;
100- } else {
101- ErrMsg = " Invalid optimization level!" ;
102- return false ;
103- }
104-
105- // Overrides/ammends `-spirv-ext` command line switch (if present) by the
106- // explicit list of allowed SPIR-V extensions.
10769 std::set<SPIRV::Extension::Extension> AllowedExtIds;
10870 StringRef UnknownExt =
10971 SPIRVExtensionsParser::checkExtensions (AllowExtNames, AllowedExtIds);
11072 if (!UnknownExt.empty ()) {
11173 ErrMsg = " Unknown SPIR-V extension: " + UnknownExt.str ();
11274 return false ;
11375 }
114- SPIRVSubtarget::addExtensionsToClOpt (AllowedExtIds);
11576
11677 // SPIR-V-specific target initialization.
11778 InitializeSPIRVTarget ();
11879
119- Triple TargetTriple (SpirvTargetTriple.empty ()
120- ? M->getTargetTriple ()
121- : Triple::normalize (SpirvTargetTriple));
12280 if (TargetTriple.getTriple ().empty ()) {
12381 TargetTriple.setTriple (DefaultTriple);
12482 M->setTargetTriple (DefaultTriple);
@@ -142,6 +100,11 @@ SPIRVTranslateModule(Module *M, std::string &SpirvObj, std::string &ErrMsg,
142100 return false ;
143101 }
144102
103+ // Set available extensions.
104+ SPIRVTargetMachine *STM = static_cast <SPIRVTargetMachine *>(Target.get ());
105+ const_cast <SPIRVSubtarget *>(STM->getSubtargetImpl ())
106+ ->initAvailableExtensions (AllowedExtIds);
107+
145108 if (M->getCodeModel ())
146109 Target->setCodeModel (*M->getCodeModel ());
147110
@@ -177,4 +140,30 @@ SPIRVTranslateModule(Module *M, std::string &SpirvObj, std::string &ErrMsg,
177140 return true ;
178141}
179142
143+ // TODO: Remove this wrapper after existing clients switch into a newer
144+ // implementation of SPIRVTranslate().
145+ extern " C" LLVM_EXTERNAL_VISIBILITY bool
146+ SPIRVTranslateModule (Module *M, std::string &SpirvObj, std::string &ErrMsg,
147+ const std::vector<std::string> &AllowExtNames,
148+ const std::vector<std::string> &Opts) {
149+ // optional: Opts[0] is a string representation of Triple,
150+ // take Module triple otherwise
151+ Triple TargetTriple (Opts.empty () || Opts[0 ].empty ()
152+ ? M->getTargetTriple ()
153+ : Triple::normalize (Opts[0 ]));
154+ // optional: Opts[1] is a string representation of CodeGenOptLevel,
155+ // no optimization otherwise
156+ llvm::CodeGenOptLevel OLevel = CodeGenOptLevel::None;
157+ if (Opts.size () > 1 && !Opts[1 ].empty ()) {
158+ if (auto Level = CodeGenOpt::parseLevel (Opts[1 ][0 ])) {
159+ OLevel = *Level;
160+ } else {
161+ ErrMsg = " Invalid optimization level!" ;
162+ return false ;
163+ }
164+ }
165+ return SPIRVTranslate (M, SpirvObj, ErrMsg, AllowExtNames, OLevel,
166+ TargetTriple);
167+ }
168+
180169} // namespace llvm
0 commit comments