tu: Implement fallback linear staging blit for CopyImage
[mesa.git] / src / gallium / state_trackers / clover / llvm / compat.hpp
1 //
2 // Copyright 2016 Francisco Jerez
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
21 //
22
23 ///
24 /// \file
25 /// Some thin wrappers around the Clang/LLVM API used to preserve
26 /// compatibility with older API versions while keeping the ifdef clutter low
27 /// in the rest of the clover::llvm subtree. In case of an API break please
28 /// consider whether it's possible to preserve backwards compatibility by
29 /// introducing a new one-liner inline function or typedef here under the
30 /// compat namespace in order to keep the running code free from preprocessor
31 /// conditionals.
32 ///
33
34 #ifndef CLOVER_LLVM_COMPAT_HPP
35 #define CLOVER_LLVM_COMPAT_HPP
36
37 #include "util/algorithm.hpp"
38
39 #include <llvm/Config/llvm-config.h>
40 #if LLVM_VERSION_MAJOR < 4
41 #include <llvm/Bitcode/ReaderWriter.h>
42 #else
43 #include <llvm/Bitcode/BitcodeReader.h>
44 #include <llvm/Bitcode/BitcodeWriter.h>
45 #endif
46
47 #include <llvm/IR/LLVMContext.h>
48 #include <llvm/Linker/Linker.h>
49 #include <llvm/Transforms/IPO.h>
50 #include <llvm/Transforms/Utils/Cloning.h>
51 #include <llvm/Target/TargetMachine.h>
52 #if LLVM_VERSION_MAJOR >= 4
53 #include <llvm/Support/Error.h>
54 #else
55 #include <llvm/Support/ErrorOr.h>
56 #endif
57
58 #include <llvm/IR/LegacyPassManager.h>
59 #include <llvm/Analysis/TargetLibraryInfo.h>
60
61 #include <clang/Basic/TargetInfo.h>
62 #include <clang/Frontend/CompilerInstance.h>
63
64 #if LLVM_VERSION_MAJOR >= 8
65 #include <clang/Basic/CodeGenOptions.h>
66 #else
67 #include <clang/Frontend/CodeGenOptions.h>
68 #endif
69
70 #if LLVM_VERSION_MAJOR >= 10
71 #include <llvm/Support/CodeGen.h>
72 #endif
73
74 namespace clover {
75 namespace llvm {
76 namespace compat {
77
78 #if LLVM_VERSION_MAJOR >= 10
79 const auto CGFT_ObjectFile = ::llvm::CGFT_ObjectFile;
80 const auto CGFT_AssemblyFile = ::llvm::CGFT_AssemblyFile;
81 typedef ::llvm::CodeGenFileType CodeGenFileType;
82 #else
83 const auto CGFT_ObjectFile = ::llvm::TargetMachine::CGFT_ObjectFile;
84 const auto CGFT_AssemblyFile =
85 ::llvm::TargetMachine::CGFT_AssemblyFile;
86 typedef ::llvm::TargetMachine::CodeGenFileType CodeGenFileType;
87 #endif
88
89 template<typename T, typename AS>
90 unsigned target_address_space(const T &target, const AS lang_as) {
91 const auto &map = target.getAddressSpaceMap();
92 #if LLVM_VERSION_MAJOR >= 5
93 return map[static_cast<unsigned>(lang_as)];
94 #else
95 return map[lang_as - clang::LangAS::Offset];
96 #endif
97 }
98
99 #if LLVM_VERSION_MAJOR >= 10
100 const clang::InputKind ik_opencl = clang::Language::OpenCL;
101 #elif LLVM_VERSION_MAJOR >= 5
102 const clang::InputKind ik_opencl = clang::InputKind::OpenCL;
103 #else
104 const clang::InputKind ik_opencl = clang::IK_OpenCL;
105 #endif
106
107 #if LLVM_VERSION_MAJOR >= 5
108 const clang::LangStandard::Kind lang_opencl10 = clang::LangStandard::lang_opencl10;
109 #else
110 const clang::LangStandard::Kind lang_opencl10 = clang::LangStandard::lang_opencl;
111 #endif
112
113 inline void
114 add_link_bitcode_file(clang::CodeGenOptions &opts,
115 const std::string &path) {
116 #if LLVM_VERSION_MAJOR >= 5
117 clang::CodeGenOptions::BitcodeFileToLink F;
118
119 F.Filename = path;
120 F.PropagateAttrs = true;
121 F.LinkFlags = ::llvm::Linker::Flags::None;
122 opts.LinkBitcodeFiles.emplace_back(F);
123 #else
124 opts.LinkBitcodeFiles.emplace_back(::llvm::Linker::Flags::None, path);
125 #endif
126 }
127
128 #if LLVM_VERSION_MAJOR >= 6
129 const auto default_code_model = ::llvm::None;
130 #else
131 const auto default_code_model = ::llvm::CodeModel::Default;
132 #endif
133
134 template<typename M, typename F> void
135 handle_module_error(M &mod, const F &f) {
136 #if LLVM_VERSION_MAJOR >= 4
137 if (::llvm::Error err = mod.takeError())
138 ::llvm::handleAllErrors(std::move(err), [&](::llvm::ErrorInfoBase &eib) {
139 f(eib.message());
140 });
141 #else
142 if (!mod)
143 f(mod.getError().message());
144 #endif
145 }
146
147 template<typename T> void
148 set_diagnostic_handler(::llvm::LLVMContext &ctx,
149 T *diagnostic_handler, void *data) {
150 #if LLVM_VERSION_MAJOR >= 6
151 ctx.setDiagnosticHandlerCallBack(diagnostic_handler, data);
152 #else
153 ctx.setDiagnosticHandler(diagnostic_handler, data);
154 #endif
155 }
156
157 inline std::unique_ptr< ::llvm::Module>
158 clone_module(const ::llvm::Module &mod)
159 {
160 #if LLVM_VERSION_MAJOR >= 7
161 return ::llvm::CloneModule(mod);
162 #else
163 return ::llvm::CloneModule(&mod);
164 #endif
165 }
166
167 template<typename T> void
168 write_bitcode_to_file(const ::llvm::Module &mod, T &os)
169 {
170 #if LLVM_VERSION_MAJOR >= 7
171 ::llvm::WriteBitcodeToFile(mod, os);
172 #else
173 ::llvm::WriteBitcodeToFile(&mod, os);
174 #endif
175 }
176
177 template<typename TM, typename PM, typename OS, typename FT>
178 bool add_passes_to_emit_file(TM &tm, PM &pm, OS &os, FT &ft)
179 {
180 #if LLVM_VERSION_MAJOR >= 7
181 return tm.addPassesToEmitFile(pm, os, nullptr, ft);
182 #else
183 return tm.addPassesToEmitFile(pm, os, ft);
184 #endif
185 }
186
187 template<typename T> inline bool
188 create_compiler_invocation_from_args(clang::CompilerInvocation &cinv,
189 T copts,
190 clang::DiagnosticsEngine &diag)
191 {
192 #if LLVM_VERSION_MAJOR >= 10
193 return clang::CompilerInvocation::CreateFromArgs(
194 cinv, copts, diag);
195 #else
196 return clang::CompilerInvocation::CreateFromArgs(
197 cinv, copts.data(), copts.data() + copts.size(), diag);
198 #endif
199 }
200
201 template<typename T, typename M>
202 T get_abi_type(const T &arg_type, const M &mod) {
203 #if LLVM_VERSION_MAJOR >= 7
204 return arg_type;
205 #else
206 ::llvm::DataLayout dl(&mod);
207 const unsigned arg_store_size = dl.getTypeStoreSize(arg_type);
208 return !arg_type->isIntegerTy() ? arg_type :
209 dl.getSmallestLegalIntType(mod.getContext(), arg_store_size * 8);
210 #endif
211 }
212 }
213 }
214 }
215
216 #endif