• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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