25
25
#include " llvm/IRReader/IRReader.h"
26
26
#include " llvm/LTO/LTO.h"
27
27
#include " llvm/Linker/Linker.h"
28
+ #include " llvm/MC/TargetRegistry.h"
28
29
#include " llvm/Object/Archive.h"
29
30
#include " llvm/Object/ArchiveWriter.h"
30
31
#include " llvm/Object/Binary.h"
48
49
#include " llvm/Support/TargetSelect.h"
49
50
#include " llvm/Support/TimeProfiler.h"
50
51
#include " llvm/Support/WithColor.h"
52
+ #include " llvm/Target/TargetMachine.h"
51
53
52
54
using namespace llvm ;
53
55
using namespace llvm ::opt;
@@ -79,6 +81,7 @@ static const char *Executable;
79
81
static SmallVector<SmallString<128 >> TempFiles;
80
82
81
83
namespace {
84
+
82
85
// Must not overlap with llvm::opt::DriverFlag.
83
86
enum LinkerFlags { LinkerOnlyOption = (1 << 4 ) };
84
87
@@ -124,12 +127,6 @@ const OptTable &getOptTable() {
124
127
exit (EXIT_FAILURE);
125
128
}
126
129
127
- std::string getMainExecutable (const char *Name) {
128
- void *Ptr = (void *)(intptr_t )&getMainExecutable;
129
- auto COWPath = sys::fs::getMainExecutable (Name, Ptr );
130
- return sys::path::parent_path (COWPath).str ();
131
- }
132
-
133
130
Expected<StringRef> createTempFile (const ArgList &Args, const Twine &Prefix,
134
131
StringRef Extension) {
135
132
SmallString<128 > OutputFile;
@@ -211,7 +208,7 @@ Expected<std::unique_ptr<Module>> getBitcodeModule(StringRef File,
211
208
212
209
auto M = getLazyIRFileModule (File, Err, C);
213
210
if (M)
214
- return M ;
211
+ return std::move (M) ;
215
212
return createStringError (Err.getMessage ());
216
213
}
217
214
@@ -313,119 +310,62 @@ Expected<StringRef> linkDeviceCode(ArrayRef<std::string> InputFiles,
313
310
return *BitcodeOutput;
314
311
}
315
312
316
- // / Add any llvm-spirv option that relies on a specific Triple in addition
317
- // / to user supplied options.
318
- static void getSPIRVTransOpts (const ArgList &Args,
319
- SmallVector<StringRef, 8 > &TranslatorArgs,
320
- const llvm::Triple Triple) {
321
- // Enable NonSemanticShaderDebugInfo.200 for non-Windows
322
- const bool IsWindowsMSVC =
323
- Triple.isWindowsMSVCEnvironment () || Args.hasArg (OPT_is_windows_msvc_env);
324
- const bool EnableNonSemanticDebug = !IsWindowsMSVC;
325
- if (EnableNonSemanticDebug) {
326
- TranslatorArgs.push_back (
327
- " -spirv-debug-info-version=nonsemantic-shader-200" );
328
- } else {
329
- TranslatorArgs.push_back (" -spirv-debug-info-version=ocl-100" );
330
- // Prevent crash in the translator if input IR contains DIExpression
331
- // operations which don't have mapping to OpenCL.DebugInfo.100 spec.
332
- TranslatorArgs.push_back (" -spirv-allow-extra-diexpressions" );
333
- }
334
- std::string UnknownIntrinsics (" -spirv-allow-unknown-intrinsics=llvm.genx." );
335
-
336
- TranslatorArgs.push_back (Args.MakeArgString (UnknownIntrinsics));
337
-
338
- // Disable all the extensions by default
339
- std::string ExtArg (" -spirv-ext=-all" );
340
- std::string DefaultExtArg =
341
- " ,+SPV_EXT_shader_atomic_float_add,+SPV_EXT_shader_atomic_float_min_max"
342
- " ,+SPV_KHR_no_integer_wrap_decoration,+SPV_KHR_float_controls"
343
- " ,+SPV_KHR_expect_assume,+SPV_KHR_linkonce_odr" ;
344
- std::string INTELExtArg =
345
- " ,+SPV_INTEL_subgroups,+SPV_INTEL_media_block_io"
346
- " ,+SPV_INTEL_device_side_avc_motion_estimation"
347
- " ,+SPV_INTEL_fpga_loop_controls,+SPV_INTEL_unstructured_loop_controls"
348
- " ,+SPV_INTEL_fpga_reg,+SPV_INTEL_blocking_pipes"
349
- " ,+SPV_INTEL_function_pointers,+SPV_INTEL_kernel_attributes"
350
- " ,+SPV_INTEL_io_pipes,+SPV_INTEL_inline_assembly"
351
- " ,+SPV_INTEL_arbitrary_precision_integers"
352
- " ,+SPV_INTEL_float_controls2,+SPV_INTEL_vector_compute"
353
- " ,+SPV_INTEL_fast_composite"
354
- " ,+SPV_INTEL_arbitrary_precision_fixed_point"
355
- " ,+SPV_INTEL_arbitrary_precision_floating_point"
356
- " ,+SPV_INTEL_variable_length_array,+SPV_INTEL_fp_fast_math_mode"
357
- " ,+SPV_INTEL_long_composites"
358
- " ,+SPV_INTEL_arithmetic_fence"
359
- " ,+SPV_INTEL_global_variable_decorations"
360
- " ,+SPV_INTEL_cache_controls"
361
- " ,+SPV_INTEL_fpga_buffer_location"
362
- " ,+SPV_INTEL_fpga_argument_interfaces"
363
- " ,+SPV_INTEL_fpga_invocation_pipelining_attributes"
364
- " ,+SPV_INTEL_fpga_latency_control"
365
- " ,+SPV_INTEL_task_sequence"
366
- " ,+SPV_KHR_shader_clock"
367
- " ,+SPV_INTEL_bindless_images" ;
368
- ExtArg = ExtArg + DefaultExtArg + INTELExtArg;
369
- ExtArg += " ,+SPV_INTEL_token_type"
370
- " ,+SPV_INTEL_bfloat16_conversion"
371
- " ,+SPV_INTEL_joint_matrix"
372
- " ,+SPV_INTEL_hw_thread_queries"
373
- " ,+SPV_KHR_uniform_group_instructions"
374
- " ,+SPV_INTEL_masked_gather_scatter"
375
- " ,+SPV_INTEL_tensor_float32_conversion"
376
- " ,+SPV_INTEL_optnone"
377
- " ,+SPV_KHR_non_semantic_info"
378
- " ,+SPV_KHR_cooperative_matrix" ;
379
- TranslatorArgs.push_back (Args.MakeArgString (ExtArg));
380
- }
381
-
382
313
// / Run LLVM to SPIR-V translation.
383
- // / Converts 'File' from LLVM bitcode to SPIR-V format using llvm-spirv tool .
314
+ // / Converts 'File' from LLVM bitcode to SPIR-V format using SPIR-V backend .
384
315
// / 'Args' encompasses all arguments required for linking device code and will
385
- // / be parsed to generate options required to be passed into llvm-spirv tool.
386
- static Expected<StringRef> runLLVMToSPIRVTranslation (StringRef File,
387
- const ArgList &Args) {
388
- llvm::TimeTraceScope TimeScope (" LLVMToSPIRVTranslation" );
389
- StringRef LLVMSPIRVPath = Args.getLastArgValue (OPT_llvm_spirv_path_EQ);
390
- Expected<std::string> LLVMToSPIRVProg =
391
- findProgram (Args, " llvm-spirv" , {LLVMSPIRVPath});
392
- if (!LLVMToSPIRVProg)
393
- return LLVMToSPIRVProg.takeError ();
394
-
395
- SmallVector<StringRef, 8 > CmdArgs;
396
- CmdArgs.push_back (*LLVMToSPIRVProg);
397
- const llvm::Triple Triple (Args.getLastArgValue (OPT_triple_EQ));
398
- getSPIRVTransOpts (Args, CmdArgs, Triple);
399
- StringRef LLVMToSPIRVOptions;
400
- if (Arg *A = Args.getLastArg (OPT_llvm_spirv_options_EQ))
401
- LLVMToSPIRVOptions = A->getValue ();
402
- LLVMToSPIRVOptions.split (CmdArgs, " " , /* MaxSplit = */ -1 ,
403
- /* KeepEmpty = */ false );
404
- CmdArgs.append ({" -o" , OutputFile});
405
- CmdArgs.push_back (File);
406
- if (Error Err = executeCommands (*LLVMToSPIRVProg, CmdArgs))
407
- return std::move (Err);
408
-
409
- if (!SPIRVDumpDir.empty ()) {
410
- std::error_code EC =
411
- llvm::sys::fs::create_directory (SPIRVDumpDir, /* IgnoreExisting*/ true );
412
- if (EC)
413
- return createStringError (
414
- EC,
415
- formatv (" failed to create dump directory. path: {0}, error_code: {1}" ,
416
- SPIRVDumpDir, EC.value ()));
417
-
418
- StringRef Path = OutputFile;
419
- StringRef Filename = llvm::sys::path::filename (Path);
420
- SmallString<128 > CopyPath = SPIRVDumpDir;
421
- CopyPath.append (Filename);
422
- EC = llvm::sys::fs::copy_file (Path, CopyPath);
423
- if (EC)
424
- return createStringError (
425
- EC,
426
- formatv (
427
- " failed to copy file. original: {0}, copy: {1}, error_code: {2}" ,
428
- Path, CopyPath, EC.value ()));
316
+ // / be parsed to generate options required to be passed into the backend.
317
+ static Expected<StringRef> runSPIRVCodeGen (StringRef File,
318
+ const ArgList &Args) {
319
+ llvm::TimeTraceScope TimeScope (" SPIR-V code generation" );
320
+
321
+ // Parse input module.
322
+ SMDiagnostic Err;
323
+ LLVMContext C;
324
+ std::unique_ptr<Module> M = parseIRFile (File, Err, C);
325
+ if (!M)
326
+ return createStringError (inconvertibleErrorCode (), Err.getMessage ());
327
+
328
+ Triple TargetTriple (Args.getLastArgValue (OPT_triple_EQ));
329
+ M->setTargetTriple (TargetTriple);
330
+
331
+ // Get a handle to SPIR-V target backend.
332
+ std::string Msg;
333
+ const Target *T = TargetRegistry::lookupTarget (M->getTargetTriple (), Msg);
334
+ if (!T)
335
+ return createStringError (Msg + " : " + M->getTargetTriple ().str ());
336
+
337
+ // Allocate SPIR-V target machine.
338
+ TargetOptions Options;
339
+ std::optional<Reloc::Model> RM;
340
+ std::optional<CodeModel::Model> CM;
341
+ std::unique_ptr<TargetMachine> TM (
342
+ T->createTargetMachine (M->getTargetTriple (), /* CPU */ " " ,
343
+ /* Features */ " " , Options, RM, CM));
344
+ if (!TM)
345
+ return createStringError (" Could not allocate target machine!" );
346
+
347
+ // Set data layout if needed.
348
+ if (M->getDataLayout ().isDefault ())
349
+ M->setDataLayout (TM->createDataLayout ());
350
+
351
+ // Open output file for writing.
352
+ int FD = -1 ;
353
+ if (std::error_code EC = sys::fs::openFileForWrite (OutputFile, FD))
354
+ return errorCodeToError (EC);
355
+ auto OS = std::make_unique<llvm::raw_fd_ostream>(FD, true );
356
+
357
+ // Run SPIR-V codegen passes to generate SPIR-V file.
358
+ legacy::PassManager CodeGenPasses;
359
+ TargetLibraryInfoImpl TLII (M->getTargetTriple ());
360
+ CodeGenPasses.add (new TargetLibraryInfoWrapperPass (TLII));
361
+ if (TM->addPassesToEmitFile (CodeGenPasses, *OS, nullptr ,
362
+ CodeGenFileType::ObjectFile))
363
+ return createStringError (" Failed to execute SPIR-V Backend" );
364
+ CodeGenPasses.run (*M);
365
+
366
+ if (Verbose) {
367
+ errs () << formatv (" SPIR-V Backend: input: {0}, output: {1}\n " , File,
368
+ OutputFile);
429
369
}
430
370
431
371
return OutputFile;
@@ -435,15 +375,15 @@ static Expected<StringRef> runLLVMToSPIRVTranslation(StringRef File,
435
375
// / 1. Link input device code (user code and SYCL device library code).
436
376
// / 2. Run SPIR-V code generation.
437
377
Error runSYCLLink (ArrayRef<std::string> Files, const ArgList &Args) {
438
- llvm::TimeTraceScope TimeScope (" SYCLDeviceLink " );
378
+ llvm::TimeTraceScope TimeScope (" SYCL device linking " );
439
379
440
380
// Link all input bitcode files and SYCL device library files, if any.
441
381
auto LinkedFile = linkDeviceCode (Files, Args);
442
382
if (!LinkedFile)
443
383
reportError (LinkedFile.takeError ());
444
384
445
- // LLVM to SPIR-V translation step
446
- auto SPVFile = runLLVMToSPIRVTranslation (*LinkedFile, Args);
385
+ // SPIR-V code generation step.
386
+ auto SPVFile = runSPIRVCodeGen (*LinkedFile, Args);
447
387
if (!SPVFile)
448
388
return SPVFile.takeError ();
449
389
return Error::success ();
@@ -453,6 +393,11 @@ Error runSYCLLink(ArrayRef<std::string> Files, const ArgList &Args) {
453
393
454
394
int main (int argc, char **argv) {
455
395
InitLLVM X (argc, argv);
396
+ InitializeAllTargetInfos ();
397
+ InitializeAllTargets ();
398
+ InitializeAllTargetMCs ();
399
+ InitializeAllAsmParsers ();
400
+ InitializeAllAsmPrinters ();
456
401
457
402
Executable = argv[0 ];
458
403
sys::PrintStackTraceOnErrorSignal (argv[0 ]);
0 commit comments