LLVM 24.0.0git
SPIRVAPI.cpp
Go to the documentation of this file.
1//===-- SPIRVAPI.cpp - SPIR-V Backend API ---------------------*- C++ -*---===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "SPIRVCommandLine.h"
10#include "SPIRVSubtarget.h"
11#include "SPIRVTargetMachine.h"
15#include "llvm/IR/DataLayout.h"
16#include "llvm/IR/LLVMContext.h"
17#include "llvm/IR/Module.h"
18#include "llvm/IR/Verifier.h"
25#include <optional>
26#include <string>
27#include <vector>
28
29using namespace llvm;
30
31namespace {
32
33std::once_flag InitOnceFlag;
34void InitializeSPIRVTarget() {
35 std::call_once(InitOnceFlag, []() {
39 LLVMInitializeSPIRVAsmPrinter();
40 });
41}
42} // namespace
43
44namespace llvm {
45
46// The goal of this function is to facilitate integration of SPIRV Backend into
47// tools and libraries by means of exposing an API call that translate LLVM
48// module to SPIR-V and write results into a string as binary SPIR-V output,
49// providing diagnostics on fail and means of configuring translation.
50extern "C" LLVM_EXTERNAL_VISIBILITY bool
51SPIRVTranslate(Module *M, std::string &SpirvObj, std::string &ErrMsg,
52 const std::vector<std::string> &AllowExtNames,
53 llvm::CodeGenOptLevel OLevel, Triple TargetTriple) {
54 // Fallbacks for option values.
55 static const std::string DefaultTriple = "spirv64-unknown-unknown";
56 static const std::string DefaultMArch = "";
57
58 ExtensionSet AllowedExtIds;
59 StringRef UnknownExt =
60 SPIRVExtensionsParser::checkExtensions(AllowExtNames, AllowedExtIds);
61 if (!UnknownExt.empty()) {
62 ErrMsg = "Unknown SPIR-V extension: " + UnknownExt.str();
63 return false;
64 }
65
66 // SPIR-V-specific target initialization.
67 InitializeSPIRVTarget();
68
69 if (TargetTriple.getTriple().empty()) {
70 TargetTriple.setTriple(DefaultTriple);
71 M->setTargetTriple(TargetTriple);
72 }
73 const Target *TheTarget =
74 TargetRegistry::lookupTarget(DefaultMArch, TargetTriple, ErrMsg);
75 if (!TheTarget)
76 return false;
77
78 // A call to codegen::getTargetOptions(TargetTriple) hits an
79 // assertion in one of the codegen flag getters in
80 // llvm/lib/CodeGen/CommandFlags.cpp:
81 // `...View && "RegisterCodeGenFlags not created."' failed.
83 std::optional<Reloc::Model> RM;
84 std::optional<CodeModel::Model> CM;
85 std::unique_ptr<TargetMachine> Target(TheTarget->createTargetMachine(
86 TargetTriple, "", "", Options, RM, CM, OLevel));
87 if (!Target) {
88 ErrMsg = "Could not allocate target machine!";
89 return false;
90 }
91
92 // Set available extensions.
93 SPIRVTargetMachine *STM = static_cast<SPIRVTargetMachine *>(Target.get());
94 const_cast<SPIRVSubtarget *>(STM->getSubtargetImpl())
95 ->initAvailableExtensions(AllowedExtIds);
96
97 if (M->getCodeModel())
98 Target->setCodeModel(*M->getCodeModel());
99
100 std::string DLStr = M->getDataLayoutStr();
102 DLStr.empty() ? TargetTriple.computeDataLayout() : DLStr);
103 if (!MaybeDL) {
104 ErrMsg = toString(MaybeDL.takeError());
105 return false;
106 }
107 M->setDataLayout(MaybeDL.get());
108
109 SmallString<4096> OutBuffer;
110 raw_svector_ostream OutStream(OutBuffer);
111 if (Error Err = runCodeGenPipeline(*Target, *M, OutStream, nullptr,
113 ErrMsg = toString(std::move(Err));
114 return false;
115 }
116 SpirvObj = OutBuffer.str();
117
118 return true;
119}
120
121// TODO: Remove this wrapper after existing clients switch into a newer
122// implementation of SPIRVTranslate().
123extern "C" LLVM_EXTERNAL_VISIBILITY bool
124SPIRVTranslateModule(Module *M, std::string &SpirvObj, std::string &ErrMsg,
125 const std::vector<std::string> &AllowExtNames,
126 const std::vector<std::string> &Opts) {
127 // optional: Opts[0] is a string representation of Triple,
128 // take Module triple otherwise
129 Triple TargetTriple = Opts.empty() || Opts[0].empty()
130 ? M->getTargetTriple()
131 : Triple(Triple::normalize(Opts[0]));
132 // optional: Opts[1] is a string representation of CodeGenOptLevel,
133 // no optimization otherwise
135 if (Opts.size() > 1 && !Opts[1].empty()) {
136 if (auto Level = CodeGenOpt::parseLevel(Opts[1][0])) {
137 OLevel = *Level;
138 } else {
139 ErrMsg = "Invalid optimization level!";
140 return false;
141 }
142 }
143 return SPIRVTranslate(M, SpirvObj, ErrMsg, AllowExtNames, OLevel,
144 std::move(TargetTriple));
145}
146
147} // namespace llvm
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
Module.h This file contains the declarations for the Module class.
static LVOptions Options
Definition LVOptions.cpp:25
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSPIRVTargetMC()
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSPIRVTargetInfo()
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSPIRVTarget()
Target-Independent Code Generator Pass Configuration Options pass.
static LLVM_ABI Expected< DataLayout > parse(StringRef LayoutString)
Parse a data layout string and return the layout.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
reference get()
Returns a reference to the stored T value.
Definition Error.h:582
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
void initAvailableExtensions(const ExtensionSet &AllowedExtIds)
const SPIRVSubtarget * getSubtargetImpl() const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
StringRef str() const
Explicit conversion to StringRef.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
Target - Wrapper for Target specific information.
TargetMachine * createTargetMachine(const Triple &TT, StringRef CPU, StringRef Features, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM=std::nullopt, CodeGenOptLevel OL=CodeGenOptLevel::Default, bool JIT=false) const
createTargetMachine - Create a target specific machine implementation for the specified Triple.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
LLVM_ABI std::string computeDataLayout(StringRef ABIName="") const
Compute the LLVM IR data layout string based on the triple.
LLVM_ABI void setTriple(const Twine &Str)
Set all components to the new triple Str.
Definition Triple.cpp:1680
static LLVM_ABI std::string normalize(StringRef Str, CanonicalForm Form=CanonicalForm::ANY)
Turn an arbitrary machine specification into the canonical triple form (or something sensible that th...
Definition Triple.cpp:1192
const std::string & getTriple() const
Definition Triple.h:582
A raw_ostream that writes to an SmallVector or SmallString.
std::optional< CodeGenOptLevel > parseLevel(char C)
Parse C as a single digit integer and get matching CodeGenLevel.
Definition CodeGen.h:299
This is an optimization pass for GlobalISel generic memory operations.
DenseSet< SPIRV::Extension::Extension > ExtensionSet
LLVM_EXTERNAL_VISIBILITY bool SPIRVTranslate(Module *M, std::string &SpirvObj, std::string &ErrMsg, const std::vector< std::string > &AllowExtNames, llvm::CodeGenOptLevel OLevel, Triple TargetTriple)
Definition SPIRVAPI.cpp:51
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:280
LLVM_EXTERNAL_VISIBILITY bool SPIRVTranslateModule(Module *M, std::string &SpirvObj, std::string &ErrMsg, const std::vector< std::string > &AllowExtNames, const std::vector< std::string > &Opts)
Definition SPIRVAPI.cpp:124
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
LLVM_ABI Error runCodeGenPipeline(TargetMachine &TM, Module &M, raw_pwrite_stream &OS, raw_pwrite_stream *DwoOS, CodeGenFileType CGFT, bool DisableVerify=true, bool DisableSimplifyLibCalls=false, IntrusiveRefCntPtr< vfs::FileSystem > VFS=vfs::getRealFileSystem())
static StringRef checkExtensions(ArrayRef< std::string > ExtNames, ExtensionSet &AllowedExtensions)
Validates and converts extension names into internal enum values.
static LLVM_ABI const Target * lookupTarget(const Triple &TheTriple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.