LLVM 21.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"
18#include "llvm/IR/DataLayout.h"
19#include "llvm/IR/LLVMContext.h"
21#include "llvm/IR/Module.h"
22#include "llvm/IR/Verifier.h"
26#include "llvm/Pass.h"
35#include <optional>
36#include <string>
37#include <utility>
38#include <vector>
39
40using namespace llvm;
41
42namespace {
43
44std::once_flag InitOnceFlag;
45void InitializeSPIRVTarget() {
46 std::call_once(InitOnceFlag, []() {
51 });
52}
53} // namespace
54
55namespace llvm {
56
57// The goal of this function is to facilitate integration of SPIRV Backend into
58// tools and libraries by means of exposing an API call that translate LLVM
59// module to SPIR-V and write results into a string as binary SPIR-V output,
60// providing diagnostics on fail and means of configuring translation.
61extern "C" LLVM_EXTERNAL_VISIBILITY bool
62SPIRVTranslate(Module *M, std::string &SpirvObj, std::string &ErrMsg,
63 const std::vector<std::string> &AllowExtNames,
64 llvm::CodeGenOptLevel OLevel, Triple TargetTriple) {
65 // Fallbacks for option values.
66 static const std::string DefaultTriple = "spirv64-unknown-unknown";
67 static const std::string DefaultMArch = "";
68
69 std::set<SPIRV::Extension::Extension> AllowedExtIds;
70 StringRef UnknownExt =
71 SPIRVExtensionsParser::checkExtensions(AllowExtNames, AllowedExtIds);
72 if (!UnknownExt.empty()) {
73 ErrMsg = "Unknown SPIR-V extension: " + UnknownExt.str();
74 return false;
75 }
76
77 // SPIR-V-specific target initialization.
78 InitializeSPIRVTarget();
79
80 if (TargetTriple.getTriple().empty()) {
81 TargetTriple.setTriple(DefaultTriple);
82 M->setTargetTriple(DefaultTriple);
83 }
84 const Target *TheTarget =
85 TargetRegistry::lookupTarget(DefaultMArch, TargetTriple, ErrMsg);
86 if (!TheTarget)
87 return false;
88
89 // A call to codegen::InitTargetOptionsFromCodeGenFlags(TargetTriple)
90 // hits the following assertion: llvm/lib/CodeGen/CommandFlags.cpp:78:
91 // llvm::FPOpFusion::FPOpFusionMode llvm::codegen::getFuseFPOps(): Assertion
92 // `FuseFPOpsView && "RegisterCodeGenFlags not created."' failed.
94 std::optional<Reloc::Model> RM;
95 std::optional<CodeModel::Model> CM;
96 std::unique_ptr<TargetMachine> Target(TheTarget->createTargetMachine(
97 TargetTriple.getTriple(), "", "", Options, RM, CM, OLevel));
98 if (!Target) {
99 ErrMsg = "Could not allocate target machine!";
100 return false;
101 }
102
103 // Set available extensions.
104 SPIRVTargetMachine *STM = static_cast<SPIRVTargetMachine *>(Target.get());
105 const_cast<SPIRVSubtarget *>(STM->getSubtargetImpl())
106 ->initAvailableExtensions(AllowedExtIds);
107
108 if (M->getCodeModel())
109 Target->setCodeModel(*M->getCodeModel());
110
111 std::string DLStr = M->getDataLayoutStr();
113 DLStr.empty() ? Target->createDataLayout().getStringRepresentation()
114 : DLStr);
115 if (!MaybeDL) {
116 ErrMsg = toString(MaybeDL.takeError());
117 return false;
118 }
119 M->setDataLayout(MaybeDL.get());
120
121 TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple()));
123 PM.add(new TargetLibraryInfoWrapperPass(TLII));
124 std::unique_ptr<MachineModuleInfoWrapperPass> MMIWP(
126 const_cast<TargetLoweringObjectFile *>(Target->getObjFileLowering())
127 ->Initialize(MMIWP.get()->getMMI().getContext(), *Target);
128
129 SmallString<4096> OutBuffer;
130 raw_svector_ostream OutStream(OutBuffer);
131 if (Target->addPassesToEmitFile(PM, OutStream, nullptr,
133 ErrMsg = "Target machine cannot emit a file of this type";
134 return false;
135 }
136
137 PM.run(*M);
138 SpirvObj = OutBuffer.str();
139
140 return true;
141}
142
143// TODO: Remove this wrapper after existing clients switch into a newer
144// implementation of SPIRVTranslate().
145extern "C" LLVM_EXTERNAL_VISIBILITY bool
146SPIRVTranslateModule(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
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
169} // namespace llvm
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:128
Module.h This file contains the declarations for the Module class.
static LVOptions Options
Definition: LVOptions.cpp:25
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSPIRVAsmPrinter()
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSPIRVTargetMC()
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSPIRVTargetInfo()
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSPIRVTarget()
Target-Independent Code Generator Pass Configuration Options pass.
static Expected< DataLayout > parse(StringRef LayoutString)
Parse a data layout string and return the layout.
Definition: DataLayout.cpp:264
Tagged union holding either a T or a Error.
Definition: Error.h:481
Error takeError()
Take ownership of the stored error.
Definition: Error.h:608
reference get()
Returns a reference to the stored T value.
Definition: Error.h:578
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
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.
Definition: SmallString.h:254
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:229
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:147
Implementation of the target library information.
Target - Wrapper for Target specific information.
TargetMachine * createTargetMachine(StringRef 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:44
void setTriple(const Twine &Str)
Set all components to the new triple Str.
Definition: Triple.cpp:1577
static 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:1131
const std::string & getTriple() const
Definition: Triple.h:464
PassManager manages ModulePassManagers.
void add(Pass *P) override
Add a pass to the queue of passes to run.
bool run(Module &M)
run - Execute all of the passes scheduled for execution.
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:691
std::optional< CodeGenOptLevel > parseLevel(char C)
Parse C as a single digit integer and get matching CodeGenLevel.
Definition: CodeGen.h:73
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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:62
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:54
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:146
const char * toString(DWARFSectionKind Kind)
static llvm::StringRef checkExtensions(const std::vector< std::string > &ExtNames, std::set< SPIRV::Extension::Extension > &AllowedExtensions)
Validates and converts extension names into internal enum values.
static const Target * lookupTarget(StringRef Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.