Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/SPIRV/SPIRVAPI.cpp
213799 views
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"
12
#include "llvm/Analysis/TargetLibraryInfo.h"
13
#include "llvm/CodeGen/CommandFlags.h"
14
#include "llvm/CodeGen/MachineModuleInfo.h"
15
#include "llvm/CodeGen/TargetPassConfig.h"
16
#include "llvm/CodeGen/TargetSubtargetInfo.h"
17
#include "llvm/IR/DataLayout.h"
18
#include "llvm/IR/LLVMContext.h"
19
#include "llvm/IR/LegacyPassManager.h"
20
#include "llvm/IR/Module.h"
21
#include "llvm/IR/Verifier.h"
22
#include "llvm/MC/TargetRegistry.h"
23
#include "llvm/Pass.h"
24
#include "llvm/Support/TargetSelect.h"
25
#include "llvm/Target/TargetLoweringObjectFile.h"
26
#include "llvm/Target/TargetMachine.h"
27
#include "llvm/TargetParser/SubtargetFeature.h"
28
#include "llvm/TargetParser/Triple.h"
29
#include <optional>
30
#include <string>
31
#include <vector>
32
33
using namespace llvm;
34
35
namespace {
36
37
std::once_flag InitOnceFlag;
38
void InitializeSPIRVTarget() {
39
std::call_once(InitOnceFlag, []() {
40
LLVMInitializeSPIRVTargetInfo();
41
LLVMInitializeSPIRVTarget();
42
LLVMInitializeSPIRVTargetMC();
43
LLVMInitializeSPIRVAsmPrinter();
44
});
45
}
46
} // namespace
47
48
namespace llvm {
49
50
// The goal of this function is to facilitate integration of SPIRV Backend into
51
// tools and libraries by means of exposing an API call that translate LLVM
52
// module to SPIR-V and write results into a string as binary SPIR-V output,
53
// providing diagnostics on fail and means of configuring translation.
54
extern "C" LLVM_EXTERNAL_VISIBILITY bool
55
SPIRVTranslate(Module *M, std::string &SpirvObj, std::string &ErrMsg,
56
const std::vector<std::string> &AllowExtNames,
57
llvm::CodeGenOptLevel OLevel, Triple TargetTriple) {
58
// Fallbacks for option values.
59
static const std::string DefaultTriple = "spirv64-unknown-unknown";
60
static const std::string DefaultMArch = "";
61
62
std::set<SPIRV::Extension::Extension> AllowedExtIds;
63
StringRef UnknownExt =
64
SPIRVExtensionsParser::checkExtensions(AllowExtNames, AllowedExtIds);
65
if (!UnknownExt.empty()) {
66
ErrMsg = "Unknown SPIR-V extension: " + UnknownExt.str();
67
return false;
68
}
69
70
// SPIR-V-specific target initialization.
71
InitializeSPIRVTarget();
72
73
if (TargetTriple.getTriple().empty()) {
74
TargetTriple.setTriple(DefaultTriple);
75
M->setTargetTriple(TargetTriple);
76
}
77
const Target *TheTarget =
78
TargetRegistry::lookupTarget(DefaultMArch, TargetTriple, ErrMsg);
79
if (!TheTarget)
80
return false;
81
82
// A call to codegen::InitTargetOptionsFromCodeGenFlags(TargetTriple)
83
// hits the following assertion: llvm/lib/CodeGen/CommandFlags.cpp:78:
84
// llvm::FPOpFusion::FPOpFusionMode llvm::codegen::getFuseFPOps(): Assertion
85
// `FuseFPOpsView && "RegisterCodeGenFlags not created."' failed.
86
TargetOptions Options;
87
std::optional<Reloc::Model> RM;
88
std::optional<CodeModel::Model> CM;
89
std::unique_ptr<TargetMachine> Target(TheTarget->createTargetMachine(
90
TargetTriple, "", "", Options, RM, CM, OLevel));
91
if (!Target) {
92
ErrMsg = "Could not allocate target machine!";
93
return false;
94
}
95
96
// Set available extensions.
97
SPIRVTargetMachine *STM = static_cast<SPIRVTargetMachine *>(Target.get());
98
const_cast<SPIRVSubtarget *>(STM->getSubtargetImpl())
99
->initAvailableExtensions(AllowedExtIds);
100
101
if (M->getCodeModel())
102
Target->setCodeModel(*M->getCodeModel());
103
104
std::string DLStr = M->getDataLayoutStr();
105
Expected<DataLayout> MaybeDL = DataLayout::parse(
106
DLStr.empty() ? Target->createDataLayout().getStringRepresentation()
107
: DLStr);
108
if (!MaybeDL) {
109
ErrMsg = toString(MaybeDL.takeError());
110
return false;
111
}
112
M->setDataLayout(MaybeDL.get());
113
114
TargetLibraryInfoImpl TLII(M->getTargetTriple());
115
legacy::PassManager PM;
116
PM.add(new TargetLibraryInfoWrapperPass(TLII));
117
std::unique_ptr<MachineModuleInfoWrapperPass> MMIWP(
118
new MachineModuleInfoWrapperPass(Target.get()));
119
const_cast<TargetLoweringObjectFile *>(Target->getObjFileLowering())
120
->Initialize(MMIWP->getMMI().getContext(), *Target);
121
122
SmallString<4096> OutBuffer;
123
raw_svector_ostream OutStream(OutBuffer);
124
if (Target->addPassesToEmitFile(PM, OutStream, nullptr,
125
CodeGenFileType::ObjectFile)) {
126
ErrMsg = "Target machine cannot emit a file of this type";
127
return false;
128
}
129
130
PM.run(*M);
131
SpirvObj = OutBuffer.str();
132
133
return true;
134
}
135
136
// TODO: Remove this wrapper after existing clients switch into a newer
137
// implementation of SPIRVTranslate().
138
extern "C" LLVM_EXTERNAL_VISIBILITY bool
139
SPIRVTranslateModule(Module *M, std::string &SpirvObj, std::string &ErrMsg,
140
const std::vector<std::string> &AllowExtNames,
141
const std::vector<std::string> &Opts) {
142
// optional: Opts[0] is a string representation of Triple,
143
// take Module triple otherwise
144
Triple TargetTriple = Opts.empty() || Opts[0].empty()
145
? M->getTargetTriple()
146
: Triple(Triple::normalize(Opts[0]));
147
// optional: Opts[1] is a string representation of CodeGenOptLevel,
148
// no optimization otherwise
149
llvm::CodeGenOptLevel OLevel = CodeGenOptLevel::None;
150
if (Opts.size() > 1 && !Opts[1].empty()) {
151
if (auto Level = CodeGenOpt::parseLevel(Opts[1][0])) {
152
OLevel = *Level;
153
} else {
154
ErrMsg = "Invalid optimization level!";
155
return false;
156
}
157
}
158
return SPIRVTranslate(M, SpirvObj, ErrMsg, AllowExtNames, OLevel,
159
TargetTriple);
160
}
161
162
} // namespace llvm
163
164