1 /**************************************************************************
2 *
3 * Copyright 2010 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
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 NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 **************************************************************************/
27
28
29 /**
30 * The purpose of this module is to expose LLVM functionality not available
31 * through the C++ bindings.
32 */
33
34
35 // Undef these vars just to silence warnings
36 #undef PACKAGE_BUGREPORT
37 #undef PACKAGE_NAME
38 #undef PACKAGE_STRING
39 #undef PACKAGE_TARNAME
40 #undef PACKAGE_VERSION
41
42
43 #include <stddef.h>
44
45 #include <llvm/Config/llvm-config.h>
46
47 #if LLVM_VERSION_MAJOR < 7
48 // Workaround http://llvm.org/PR23628
49 #pragma push_macro("DEBUG")
50 #undef DEBUG
51 #endif
52
53 #include <llvm/Config/llvm-config.h>
54 #include <llvm-c/Core.h>
55 #include <llvm-c/Support.h>
56 #include <llvm-c/ExecutionEngine.h>
57 #include <llvm/Target/TargetOptions.h>
58 #include <llvm/ExecutionEngine/ExecutionEngine.h>
59 #include <llvm/ADT/Triple.h>
60 #include <llvm/Analysis/TargetLibraryInfo.h>
61 #include <llvm/ExecutionEngine/SectionMemoryManager.h>
62 #include <llvm/Support/CommandLine.h>
63 #include <llvm/Support/Host.h>
64 #include <llvm/Support/PrettyStackTrace.h>
65 #include <llvm/ExecutionEngine/ObjectCache.h>
66 #include <llvm/Support/TargetSelect.h>
67 #if LLVM_VERSION_MAJOR >= 15
68 #include <llvm/Support/MemoryBuffer.h>
69 #endif
70
71 #if LLVM_VERSION_MAJOR < 11
72 #include <llvm/IR/CallSite.h>
73 #endif
74 #include <llvm/IR/IRBuilder.h>
75 #include <llvm/IR/Module.h>
76 #include <llvm/Support/CBindingWrapping.h>
77
78 #include <llvm/Config/llvm-config.h>
79 #if LLVM_USE_INTEL_JITEVENTS
80 #include <llvm/ExecutionEngine/JITEventListener.h>
81 #endif
82
83 #if LLVM_VERSION_MAJOR < 7
84 // Workaround http://llvm.org/PR23628
85 #pragma pop_macro("DEBUG")
86 #endif
87
88 #include "c11/threads.h"
89 #include "os/os_thread.h"
90 #include "pipe/p_config.h"
91 #include "util/u_debug.h"
92 #include "util/u_cpu_detect.h"
93
94 #include "lp_bld_misc.h"
95 #include "lp_bld_debug.h"
96
97 namespace {
98
99 class LLVMEnsureMultithreaded {
100 public:
LLVMEnsureMultithreaded()101 LLVMEnsureMultithreaded()
102 {
103 if (!LLVMIsMultithreaded()) {
104 LLVMStartMultithreaded();
105 }
106 }
107 };
108
109 static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;
110
111 }
112
113 static once_flag init_native_targets_once_flag = ONCE_FLAG_INIT;
114
init_native_targets()115 static void init_native_targets()
116 {
117 // If we have a native target, initialize it to ensure it is linked in and
118 // usable by the JIT.
119 llvm::InitializeNativeTarget();
120
121 llvm::InitializeNativeTargetAsmPrinter();
122
123 llvm::InitializeNativeTargetDisassembler();
124 #if DEBUG
125 {
126 char *env_llc_options = getenv("GALLIVM_LLC_OPTIONS");
127 if (env_llc_options) {
128 char *option;
129 char *options[64] = {(char *) "llc"}; // Warning without cast
130 int n;
131 for (n = 0, option = strtok(env_llc_options, " "); option; n++, option = strtok(NULL, " ")) {
132 options[n + 1] = option;
133 }
134 if (gallivm_debug & (GALLIVM_DEBUG_IR | GALLIVM_DEBUG_ASM | GALLIVM_DEBUG_DUMP_BC)) {
135 debug_printf("llc additional options (%d):\n", n);
136 for (int i = 1; i <= n; i++)
137 debug_printf("\t%s\n", options[i]);
138 debug_printf("\n");
139 }
140 LLVMParseCommandLineOptions(n + 1, options, NULL);
141 }
142 }
143 #endif
144 }
145
146 extern "C" void
lp_set_target_options(void)147 lp_set_target_options(void)
148 {
149 /* The llvm target registry is not thread-safe, so drivers and gallium frontends
150 * that want to initialize targets should use the lp_set_target_options()
151 * function to safely initialize targets.
152 *
153 * LLVM targets should be initialized before the driver or gallium frontend tries
154 * to access the registry.
155 */
156 call_once(&init_native_targets_once_flag, init_native_targets);
157 }
158
159 extern "C"
160 LLVMTargetLibraryInfoRef
gallivm_create_target_library_info(const char * triple)161 gallivm_create_target_library_info(const char *triple)
162 {
163 return reinterpret_cast<LLVMTargetLibraryInfoRef>(
164 new llvm::TargetLibraryInfoImpl(
165 llvm::Triple(triple)));
166 }
167
168 extern "C"
169 void
gallivm_dispose_target_library_info(LLVMTargetLibraryInfoRef library_info)170 gallivm_dispose_target_library_info(LLVMTargetLibraryInfoRef library_info)
171 {
172 delete reinterpret_cast<
173 llvm::TargetLibraryInfoImpl
174 *>(library_info);
175 }
176
177
178 typedef llvm::RTDyldMemoryManager BaseMemoryManager;
179
180
181 /*
182 * Delegating is tedious but the default manager class is hidden in an
183 * anonymous namespace in LLVM, so we cannot just derive from it to change
184 * its behavior.
185 */
186 class DelegatingJITMemoryManager : public BaseMemoryManager {
187
188 protected:
189 virtual BaseMemoryManager *mgr() const = 0;
190
191 public:
192 /*
193 * From RTDyldMemoryManager
194 */
allocateCodeSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,llvm::StringRef SectionName)195 virtual uint8_t *allocateCodeSection(uintptr_t Size,
196 unsigned Alignment,
197 unsigned SectionID,
198 llvm::StringRef SectionName) {
199 return mgr()->allocateCodeSection(Size, Alignment, SectionID,
200 SectionName);
201 }
allocateDataSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,llvm::StringRef SectionName,bool IsReadOnly)202 virtual uint8_t *allocateDataSection(uintptr_t Size,
203 unsigned Alignment,
204 unsigned SectionID,
205 llvm::StringRef SectionName,
206 bool IsReadOnly) {
207 return mgr()->allocateDataSection(Size, Alignment, SectionID,
208 SectionName,
209 IsReadOnly);
210 }
registerEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)211 virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
212 mgr()->registerEHFrames(Addr, LoadAddr, Size);
213 }
214 #if LLVM_VERSION_MAJOR >= 5
deregisterEHFrames()215 virtual void deregisterEHFrames() {
216 mgr()->deregisterEHFrames();
217 }
218 #else
deregisterEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)219 virtual void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
220 mgr()->deregisterEHFrames(Addr, LoadAddr, Size);
221 }
222 #endif
getPointerToNamedFunction(const std::string & Name,bool AbortOnFailure=true)223 virtual void *getPointerToNamedFunction(const std::string &Name,
224 bool AbortOnFailure=true) {
225 return mgr()->getPointerToNamedFunction(Name, AbortOnFailure);
226 }
finalizeMemory(std::string * ErrMsg=0)227 virtual bool finalizeMemory(std::string *ErrMsg = 0) {
228 return mgr()->finalizeMemory(ErrMsg);
229 }
230 };
231
232
233 /*
234 * Delegate memory management to one shared manager for more efficient use
235 * of memory than creating a separate pool for each LLVM engine.
236 * Keep generated code until freeGeneratedCode() is called, instead of when
237 * memory manager is destroyed, which happens during engine destruction.
238 * This allows additional memory savings as we don't have to keep the engine
239 * around in order to use the code.
240 * All methods are delegated to the shared manager except destruction and
241 * deallocating code. For the latter we just remember what needs to be
242 * deallocated later. The shared manager is deleted once it is empty.
243 */
244 class ShaderMemoryManager : public DelegatingJITMemoryManager {
245
246 BaseMemoryManager *TheMM;
247
248 struct GeneratedCode {
249 typedef std::vector<void *> Vec;
250 Vec FunctionBody, ExceptionTable;
251 BaseMemoryManager *TheMM;
252
GeneratedCodeShaderMemoryManager::GeneratedCode253 GeneratedCode(BaseMemoryManager *MM) {
254 TheMM = MM;
255 }
256
~GeneratedCodeShaderMemoryManager::GeneratedCode257 ~GeneratedCode() {
258 }
259 };
260
261 GeneratedCode *code;
262
mgr() const263 BaseMemoryManager *mgr() const {
264 return TheMM;
265 }
266
267 public:
268
ShaderMemoryManager(BaseMemoryManager * MM)269 ShaderMemoryManager(BaseMemoryManager* MM) {
270 TheMM = MM;
271 code = new GeneratedCode(MM);
272 }
273
~ShaderMemoryManager()274 virtual ~ShaderMemoryManager() {
275 /*
276 * 'code' is purposely not deleted. It is the user's responsibility
277 * to call getGeneratedCode() and freeGeneratedCode().
278 */
279 }
280
getGeneratedCode()281 struct lp_generated_code *getGeneratedCode() {
282 return (struct lp_generated_code *) code;
283 }
284
freeGeneratedCode(struct lp_generated_code * code)285 static void freeGeneratedCode(struct lp_generated_code *code) {
286 delete (GeneratedCode *) code;
287 }
288
deallocateFunctionBody(void * Body)289 virtual void deallocateFunctionBody(void *Body) {
290 // remember for later deallocation
291 code->FunctionBody.push_back(Body);
292 }
293 };
294
295 class LPObjectCache : public llvm::ObjectCache {
296 private:
297 bool has_object;
298 struct lp_cached_code *cache_out;
299 public:
LPObjectCache(struct lp_cached_code * cache)300 LPObjectCache(struct lp_cached_code *cache) {
301 cache_out = cache;
302 has_object = false;
303 }
304
~LPObjectCache()305 ~LPObjectCache() {
306 }
notifyObjectCompiled(const llvm::Module * M,llvm::MemoryBufferRef Obj)307 void notifyObjectCompiled(const llvm::Module *M, llvm::MemoryBufferRef Obj) {
308 const std::string ModuleID = M->getModuleIdentifier();
309 if (has_object)
310 fprintf(stderr, "CACHE ALREADY HAS MODULE OBJECT\n");
311 has_object = true;
312 cache_out->data_size = Obj.getBufferSize();
313 cache_out->data = malloc(cache_out->data_size);
314 memcpy(cache_out->data, Obj.getBufferStart(), cache_out->data_size);
315 }
316
getObject(const llvm::Module * M)317 virtual std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module *M) {
318 if (cache_out->data_size) {
319 return llvm::MemoryBuffer::getMemBuffer(llvm::StringRef((const char *)cache_out->data, cache_out->data_size), "", false);
320 }
321 return NULL;
322 }
323
324 };
325
326 /**
327 * Same as LLVMCreateJITCompilerForModule, but:
328 * - allows using MCJIT and enabling AVX feature where available.
329 * - set target options
330 *
331 * See also:
332 * - llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
333 * - llvm/tools/lli/lli.cpp
334 * - http://markmail.org/message/ttkuhvgj4cxxy2on#query:+page:1+mid:aju2dggerju3ivd3+state:results
335 */
336 extern "C"
337 LLVMBool
lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef * OutJIT,lp_generated_code ** OutCode,struct lp_cached_code * cache_out,LLVMModuleRef M,LLVMMCJITMemoryManagerRef CMM,unsigned OptLevel,char ** OutError)338 lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
339 lp_generated_code **OutCode,
340 struct lp_cached_code *cache_out,
341 LLVMModuleRef M,
342 LLVMMCJITMemoryManagerRef CMM,
343 unsigned OptLevel,
344 char **OutError)
345 {
346 using namespace llvm;
347
348 std::string Error;
349 EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
350
351 /**
352 * LLVM 3.1+ haven't more "extern unsigned llvm::StackAlignmentOverride" and
353 * friends for configuring code generation options, like stack alignment.
354 */
355 TargetOptions options;
356 #if defined(PIPE_ARCH_X86) && LLVM_VERSION_MAJOR < 13
357 options.StackAlignmentOverride = 4;
358 #endif
359
360 builder.setEngineKind(EngineKind::JIT)
361 .setErrorStr(&Error)
362 .setTargetOptions(options)
363 .setOptLevel((CodeGenOpt::Level)OptLevel);
364
365 #ifdef _WIN32
366 /*
367 * MCJIT works on Windows, but currently only through ELF object format.
368 *
369 * XXX: We could use `LLVM_HOST_TRIPLE "-elf"` but LLVM_HOST_TRIPLE has
370 * different strings for MinGW/MSVC, so better play it safe and be
371 * explicit.
372 */
373 # ifdef _WIN64
374 LLVMSetTarget(M, "x86_64-pc-win32-elf");
375 # else
376 LLVMSetTarget(M, "i686-pc-win32-elf");
377 # endif
378 #endif
379
380 llvm::SmallVector<std::string, 16> MAttrs;
381
382 #if LLVM_VERSION_MAJOR >= 4 && (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) || defined(PIPE_ARCH_ARM))
383 /* llvm-3.3+ implements sys::getHostCPUFeatures for Arm
384 * and llvm-3.7+ for x86, which allows us to enable/disable
385 * code generation based on the results of cpuid on these
386 * architectures.
387 */
388 llvm::StringMap<bool> features;
389 llvm::sys::getHostCPUFeatures(features);
390
391 for (StringMapIterator<bool> f = features.begin();
392 f != features.end();
393 ++f) {
394 MAttrs.push_back(((*f).second ? "+" : "-") + (*f).first().str());
395 }
396 #elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
397 /*
398 * We need to unset attributes because sometimes LLVM mistakenly assumes
399 * certain features are present given the processor name.
400 *
401 * https://bugs.freedesktop.org/show_bug.cgi?id=92214
402 * http://llvm.org/PR25021
403 * http://llvm.org/PR19429
404 * http://llvm.org/PR16721
405 */
406 MAttrs.push_back(util_get_cpu_caps()->has_sse ? "+sse" : "-sse" );
407 MAttrs.push_back(util_get_cpu_caps()->has_sse2 ? "+sse2" : "-sse2" );
408 MAttrs.push_back(util_get_cpu_caps()->has_sse3 ? "+sse3" : "-sse3" );
409 MAttrs.push_back(util_get_cpu_caps()->has_ssse3 ? "+ssse3" : "-ssse3" );
410 MAttrs.push_back(util_get_cpu_caps()->has_sse4_1 ? "+sse4.1" : "-sse4.1");
411 MAttrs.push_back(util_get_cpu_caps()->has_sse4_2 ? "+sse4.2" : "-sse4.2");
412 /*
413 * AVX feature is not automatically detected from CPUID by the X86 target
414 * yet, because the old (yet default) JIT engine is not capable of
415 * emitting the opcodes. On newer llvm versions it is and at least some
416 * versions (tested with 3.3) will emit avx opcodes without this anyway.
417 */
418 MAttrs.push_back(util_get_cpu_caps()->has_avx ? "+avx" : "-avx");
419 MAttrs.push_back(util_get_cpu_caps()->has_f16c ? "+f16c" : "-f16c");
420 MAttrs.push_back(util_get_cpu_caps()->has_fma ? "+fma" : "-fma");
421 MAttrs.push_back(util_get_cpu_caps()->has_avx2 ? "+avx2" : "-avx2");
422 /* disable avx512 and all subvariants */
423 MAttrs.push_back("-avx512cd");
424 MAttrs.push_back("-avx512er");
425 MAttrs.push_back("-avx512f");
426 MAttrs.push_back("-avx512pf");
427 MAttrs.push_back("-avx512bw");
428 MAttrs.push_back("-avx512dq");
429 MAttrs.push_back("-avx512vl");
430 #endif
431 #if defined(PIPE_ARCH_ARM)
432 if (!util_get_cpu_caps()->has_neon) {
433 MAttrs.push_back("-neon");
434 MAttrs.push_back("-crypto");
435 MAttrs.push_back("-vfp2");
436 }
437 #endif
438
439 #if defined(PIPE_ARCH_PPC)
440 MAttrs.push_back(util_get_cpu_caps()->has_altivec ? "+altivec" : "-altivec");
441 #if (LLVM_VERSION_MAJOR < 4)
442 /*
443 * Make sure VSX instructions are disabled
444 * See LLVM bugs:
445 * https://llvm.org/bugs/show_bug.cgi?id=25503#c7 (fixed in 3.8.1)
446 * https://llvm.org/bugs/show_bug.cgi?id=26775 (fixed in 3.8.1)
447 * https://llvm.org/bugs/show_bug.cgi?id=33531 (fixed in 4.0)
448 * https://llvm.org/bugs/show_bug.cgi?id=34647 (llc performance on certain unusual shader IR; intro'd in 4.0, pending as of 5.0)
449 */
450 if (util_get_cpu_caps()->has_altivec) {
451 MAttrs.push_back("-vsx");
452 }
453 #else
454 /*
455 * Bug 25503 is fixed, by the same fix that fixed
456 * bug 26775, in versions of LLVM later than 3.8 (starting with 3.8.1).
457 * BZ 33531 actually comprises more than one bug, all of
458 * which are fixed in LLVM 4.0.
459 *
460 * With LLVM 4.0 or higher:
461 * Make sure VSX instructions are ENABLED (if supported), unless
462 * VSX instructions are explicitly enabled/disabled via GALLIVM_VSX=1 or 0.
463 */
464 if (util_get_cpu_caps()->has_altivec) {
465 MAttrs.push_back(util_get_cpu_caps()->has_vsx ? "+vsx" : "-vsx");
466 }
467 #endif
468 #endif
469
470 #if defined(PIPE_ARCH_MIPS64)
471 MAttrs.push_back(util_get_cpu_caps()->has_msa ? "+msa" : "-msa");
472 /* MSA requires a 64-bit FPU register file */
473 MAttrs.push_back("+fp64");
474 #endif
475
476 builder.setMAttrs(MAttrs);
477
478 if (gallivm_debug & (GALLIVM_DEBUG_IR | GALLIVM_DEBUG_ASM | GALLIVM_DEBUG_DUMP_BC)) {
479 int n = MAttrs.size();
480 if (n > 0) {
481 debug_printf("llc -mattr option(s): ");
482 for (int i = 0; i < n; i++)
483 debug_printf("%s%s", MAttrs[i].c_str(), (i < n - 1) ? "," : "");
484 debug_printf("\n");
485 }
486 }
487
488 StringRef MCPU = llvm::sys::getHostCPUName();
489 /*
490 * The cpu bits are no longer set automatically, so need to set mcpu manually.
491 * Note that the MAttrs set above will be sort of ignored (since we should
492 * not set any which would not be set by specifying the cpu anyway).
493 * It ought to be safe though since getHostCPUName() should include bits
494 * not only from the cpu but environment as well (for instance if it's safe
495 * to use avx instructions which need OS support). According to
496 * http://llvm.org/bugs/show_bug.cgi?id=19429 however if I understand this
497 * right it may be necessary to specify older cpu (or disable mattrs) though
498 * when not using MCJIT so no instructions are generated which the old JIT
499 * can't handle. Not entirely sure if we really need to do anything yet.
500 */
501
502 #ifdef PIPE_ARCH_PPC_64
503 /*
504 * Large programs, e.g. gnome-shell and firefox, may tax the addressability
505 * of the Medium code model once dynamically generated JIT-compiled shader
506 * programs are linked in and relocated. Yet the default code model as of
507 * LLVM 8 is Medium or even Small.
508 * The cost of changing from Medium to Large is negligible:
509 * - an additional 8-byte pointer stored immediately before the shader entrypoint;
510 * - change an add-immediate (addis) instruction to a load (ld).
511 */
512 builder.setCodeModel(CodeModel::Large);
513
514 #if UTIL_ARCH_LITTLE_ENDIAN
515 /*
516 * Versions of LLVM prior to 4.0 lacked a table entry for "POWER8NVL",
517 * resulting in (big-endian) "generic" being returned on
518 * little-endian Power8NVL systems. The result was that code that
519 * attempted to load the least significant 32 bits of a 64-bit quantity
520 * from memory loaded the wrong half. This resulted in failures in some
521 * Piglit tests, e.g.
522 * .../arb_gpu_shader_fp64/execution/conversion/frag-conversion-explicit-double-uint
523 */
524 if (MCPU == "generic")
525 MCPU = "pwr8";
526 #endif
527 #endif
528
529 #if defined(PIPE_ARCH_MIPS64)
530 /*
531 * ls3a4000 CPU and ls2k1000 SoC is a mips64r5 compatible with MSA SIMD
532 * instruction set implemented, while ls3a3000 is mips64r2 compatible
533 * only. getHostCPUName() return "generic" on all loongson
534 * mips CPU currently. So we override the MCPU to mips64r5 if MSA is
535 * implemented, feedback to mips64r2 for all other ordinary mips64 cpu.
536 */
537 if (MCPU == "generic")
538 MCPU = util_get_cpu_caps()->has_msa ? "mips64r5" : "mips64r2";
539 #endif
540
541 builder.setMCPU(MCPU);
542 if (gallivm_debug & (GALLIVM_DEBUG_IR | GALLIVM_DEBUG_ASM | GALLIVM_DEBUG_DUMP_BC)) {
543 debug_printf("llc -mcpu option: %s\n", MCPU.str().c_str());
544 }
545
546 ShaderMemoryManager *MM = NULL;
547 BaseMemoryManager* JMM = reinterpret_cast<BaseMemoryManager*>(CMM);
548 MM = new ShaderMemoryManager(JMM);
549 *OutCode = MM->getGeneratedCode();
550
551 builder.setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager>(MM));
552 MM = NULL; // ownership taken by std::unique_ptr
553
554 ExecutionEngine *JIT;
555
556 JIT = builder.create();
557
558 if (cache_out) {
559 LPObjectCache *objcache = new LPObjectCache(cache_out);
560 JIT->setObjectCache(objcache);
561 cache_out->jit_obj_cache = (void *)objcache;
562 }
563
564 #if LLVM_USE_INTEL_JITEVENTS
565 JITEventListener *JEL = JITEventListener::createIntelJITEventListener();
566 JIT->RegisterJITEventListener(JEL);
567 #endif
568 if (JIT) {
569 *OutJIT = wrap(JIT);
570 return 0;
571 }
572 lp_free_generated_code(*OutCode);
573 *OutCode = 0;
574 delete MM;
575 *OutError = strdup(Error.c_str());
576 return 1;
577 }
578
579
580 extern "C"
581 void
lp_free_generated_code(struct lp_generated_code * code)582 lp_free_generated_code(struct lp_generated_code *code)
583 {
584 ShaderMemoryManager::freeGeneratedCode(code);
585 }
586
587 extern "C"
588 LLVMMCJITMemoryManagerRef
lp_get_default_memory_manager()589 lp_get_default_memory_manager()
590 {
591 BaseMemoryManager *mm;
592 mm = new llvm::SectionMemoryManager();
593 return reinterpret_cast<LLVMMCJITMemoryManagerRef>(mm);
594 }
595
596 extern "C"
597 void
lp_free_memory_manager(LLVMMCJITMemoryManagerRef memorymgr)598 lp_free_memory_manager(LLVMMCJITMemoryManagerRef memorymgr)
599 {
600 delete reinterpret_cast<BaseMemoryManager*>(memorymgr);
601 }
602
603 extern "C" void
lp_free_objcache(void * objcache_ptr)604 lp_free_objcache(void *objcache_ptr)
605 {
606 LPObjectCache *objcache = (LPObjectCache *)objcache_ptr;
607 delete objcache;
608 }
609
610 extern "C" LLVMValueRef
lp_get_called_value(LLVMValueRef call)611 lp_get_called_value(LLVMValueRef call)
612 {
613 return LLVMGetCalledValue(call);
614 }
615
616 extern "C" bool
lp_is_function(LLVMValueRef v)617 lp_is_function(LLVMValueRef v)
618 {
619 return LLVMGetValueKind(v) == LLVMFunctionValueKind;
620 }
621
622 extern "C" void
lp_set_module_stack_alignment_override(LLVMModuleRef MRef,unsigned align)623 lp_set_module_stack_alignment_override(LLVMModuleRef MRef, unsigned align)
624 {
625 #if LLVM_VERSION_MAJOR >= 13
626 llvm::Module *M = llvm::unwrap(MRef);
627 M->setOverrideStackAlignment(align);
628 #endif
629 }
630