gallivm: initialize init_native_targets_once_flag correctly
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_misc.cpp
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 #ifndef __STDC_LIMIT_MACROS
36 #define __STDC_LIMIT_MACROS
37 #endif
38
39 #ifndef __STDC_CONSTANT_MACROS
40 #define __STDC_CONSTANT_MACROS
41 #endif
42
43 // Undef these vars just to silence warnings
44 #undef PACKAGE_BUGREPORT
45 #undef PACKAGE_NAME
46 #undef PACKAGE_STRING
47 #undef PACKAGE_TARNAME
48 #undef PACKAGE_VERSION
49
50
51 #include <stddef.h>
52
53 // Workaround http://llvm.org/PR23628
54 #if HAVE_LLVM >= 0x0307
55 # pragma push_macro("DEBUG")
56 # undef DEBUG
57 #endif
58
59 #include <llvm-c/Core.h>
60 #include <llvm-c/ExecutionEngine.h>
61 #include <llvm/Target/TargetOptions.h>
62 #include <llvm/ExecutionEngine/ExecutionEngine.h>
63 #include <llvm/ADT/Triple.h>
64 #if HAVE_LLVM >= 0x0307
65 #include <llvm/Analysis/TargetLibraryInfo.h>
66 #else
67 #include <llvm/Target/TargetLibraryInfo.h>
68 #endif
69 #if HAVE_LLVM < 0x0306
70 #include <llvm/ExecutionEngine/JITMemoryManager.h>
71 #else
72 #include <llvm/ExecutionEngine/SectionMemoryManager.h>
73 #endif
74 #include <llvm/Support/CommandLine.h>
75 #include <llvm/Support/Host.h>
76 #include <llvm/Support/PrettyStackTrace.h>
77
78 #include <llvm/Support/TargetSelect.h>
79
80 #include <llvm/IR/IRBuilder.h>
81 #include <llvm/IR/Module.h>
82 #include <llvm/Support/CBindingWrapping.h>
83
84 #include <llvm/Config/llvm-config.h>
85 #if LLVM_USE_INTEL_JITEVENTS
86 #include <llvm/ExecutionEngine/JITEventListener.h>
87 #endif
88
89 // Workaround http://llvm.org/PR23628
90 #if HAVE_LLVM >= 0x0307
91 # pragma pop_macro("DEBUG")
92 #endif
93
94 #include "c11/threads.h"
95 #include "os/os_thread.h"
96 #include "pipe/p_config.h"
97 #include "util/u_debug.h"
98 #include "util/u_cpu_detect.h"
99
100 #include "lp_bld_misc.h"
101
102 namespace {
103
104 class LLVMEnsureMultithreaded {
105 public:
106 LLVMEnsureMultithreaded()
107 {
108 if (!LLVMIsMultithreaded()) {
109 LLVMStartMultithreaded();
110 }
111 }
112 };
113
114 static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;
115
116 }
117
118 static once_flag init_native_targets_once_flag = ONCE_FLAG_INIT;
119
120 static void init_native_targets()
121 {
122 // If we have a native target, initialize it to ensure it is linked in and
123 // usable by the JIT.
124 llvm::InitializeNativeTarget();
125
126 llvm::InitializeNativeTargetAsmPrinter();
127
128 llvm::InitializeNativeTargetDisassembler();
129 }
130
131 /**
132 * The llvm target registry is not thread-safe, so drivers and state-trackers
133 * that want to initialize targets should use the gallivm_init_llvm_targets()
134 * function to safely initialize targets.
135 *
136 * LLVM targets should be initialized before the driver or state-tracker tries
137 * to access the registry.
138 */
139 extern "C" void
140 gallivm_init_llvm_targets(void)
141 {
142 call_once(&init_native_targets_once_flag, init_native_targets);
143 }
144
145 extern "C" void
146 lp_set_target_options(void)
147 {
148 #if HAVE_LLVM < 0x0304
149 /*
150 * By default LLVM adds a signal handler to output a pretty stack trace.
151 * This signal handler is never removed, causing problems when unloading the
152 * shared object where the gallium driver resides.
153 */
154 llvm::DisablePrettyStackTrace = true;
155 #endif
156
157 gallivm_init_llvm_targets();
158 }
159
160 extern "C"
161 LLVMTargetLibraryInfoRef
162 gallivm_create_target_library_info(const char *triple)
163 {
164 return reinterpret_cast<LLVMTargetLibraryInfoRef>(
165 #if HAVE_LLVM < 0x0307
166 new llvm::TargetLibraryInfo(
167 #else
168 new llvm::TargetLibraryInfoImpl(
169 #endif
170 llvm::Triple(triple)));
171 }
172
173 extern "C"
174 void
175 gallivm_dispose_target_library_info(LLVMTargetLibraryInfoRef library_info)
176 {
177 delete reinterpret_cast<
178 #if HAVE_LLVM < 0x0307
179 llvm::TargetLibraryInfo
180 #else
181 llvm::TargetLibraryInfoImpl
182 #endif
183 *>(library_info);
184 }
185
186
187 #if HAVE_LLVM < 0x0304
188
189 extern "C"
190 void
191 LLVMSetAlignmentBackport(LLVMValueRef V,
192 unsigned Bytes)
193 {
194 switch (LLVMGetInstructionOpcode(V)) {
195 case LLVMLoad:
196 llvm::unwrap<llvm::LoadInst>(V)->setAlignment(Bytes);
197 break;
198 case LLVMStore:
199 llvm::unwrap<llvm::StoreInst>(V)->setAlignment(Bytes);
200 break;
201 default:
202 assert(0);
203 break;
204 }
205 }
206
207 #endif
208
209
210 #if HAVE_LLVM < 0x0306
211 typedef llvm::JITMemoryManager BaseMemoryManager;
212 #else
213 typedef llvm::RTDyldMemoryManager BaseMemoryManager;
214 #endif
215
216
217 /*
218 * Delegating is tedious but the default manager class is hidden in an
219 * anonymous namespace in LLVM, so we cannot just derive from it to change
220 * its behavior.
221 */
222 class DelegatingJITMemoryManager : public BaseMemoryManager {
223
224 protected:
225 virtual BaseMemoryManager *mgr() const = 0;
226
227 public:
228 #if HAVE_LLVM < 0x0306
229 /*
230 * From JITMemoryManager
231 */
232 virtual void setMemoryWritable() {
233 mgr()->setMemoryWritable();
234 }
235 virtual void setMemoryExecutable() {
236 mgr()->setMemoryExecutable();
237 }
238 virtual void setPoisonMemory(bool poison) {
239 mgr()->setPoisonMemory(poison);
240 }
241 virtual void AllocateGOT() {
242 mgr()->AllocateGOT();
243 /*
244 * isManagingGOT() is not virtual in base class so we can't delegate.
245 * Instead we mirror the value of HasGOT in our instance.
246 */
247 HasGOT = mgr()->isManagingGOT();
248 }
249 virtual uint8_t *getGOTBase() const {
250 return mgr()->getGOTBase();
251 }
252 virtual uint8_t *startFunctionBody(const llvm::Function *F,
253 uintptr_t &ActualSize) {
254 return mgr()->startFunctionBody(F, ActualSize);
255 }
256 virtual uint8_t *allocateStub(const llvm::GlobalValue *F,
257 unsigned StubSize,
258 unsigned Alignment) {
259 return mgr()->allocateStub(F, StubSize, Alignment);
260 }
261 virtual void endFunctionBody(const llvm::Function *F,
262 uint8_t *FunctionStart,
263 uint8_t *FunctionEnd) {
264 mgr()->endFunctionBody(F, FunctionStart, FunctionEnd);
265 }
266 virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
267 return mgr()->allocateSpace(Size, Alignment);
268 }
269 virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
270 return mgr()->allocateGlobal(Size, Alignment);
271 }
272 virtual void deallocateFunctionBody(void *Body) {
273 mgr()->deallocateFunctionBody(Body);
274 }
275 #if HAVE_LLVM < 0x0304
276 virtual uint8_t *startExceptionTable(const llvm::Function *F,
277 uintptr_t &ActualSize) {
278 return mgr()->startExceptionTable(F, ActualSize);
279 }
280 virtual void endExceptionTable(const llvm::Function *F,
281 uint8_t *TableStart,
282 uint8_t *TableEnd,
283 uint8_t *FrameRegister) {
284 mgr()->endExceptionTable(F, TableStart, TableEnd,
285 FrameRegister);
286 }
287 virtual void deallocateExceptionTable(void *ET) {
288 mgr()->deallocateExceptionTable(ET);
289 }
290 #endif
291 virtual bool CheckInvariants(std::string &s) {
292 return mgr()->CheckInvariants(s);
293 }
294 virtual size_t GetDefaultCodeSlabSize() {
295 return mgr()->GetDefaultCodeSlabSize();
296 }
297 virtual size_t GetDefaultDataSlabSize() {
298 return mgr()->GetDefaultDataSlabSize();
299 }
300 virtual size_t GetDefaultStubSlabSize() {
301 return mgr()->GetDefaultStubSlabSize();
302 }
303 virtual unsigned GetNumCodeSlabs() {
304 return mgr()->GetNumCodeSlabs();
305 }
306 virtual unsigned GetNumDataSlabs() {
307 return mgr()->GetNumDataSlabs();
308 }
309 virtual unsigned GetNumStubSlabs() {
310 return mgr()->GetNumStubSlabs();
311 }
312 #endif
313
314 /*
315 * From RTDyldMemoryManager
316 */
317 #if HAVE_LLVM >= 0x0304
318 virtual uint8_t *allocateCodeSection(uintptr_t Size,
319 unsigned Alignment,
320 unsigned SectionID,
321 llvm::StringRef SectionName) {
322 return mgr()->allocateCodeSection(Size, Alignment, SectionID,
323 SectionName);
324 }
325 #else
326 virtual uint8_t *allocateCodeSection(uintptr_t Size,
327 unsigned Alignment,
328 unsigned SectionID) {
329 return mgr()->allocateCodeSection(Size, Alignment, SectionID);
330 }
331 #endif
332 virtual uint8_t *allocateDataSection(uintptr_t Size,
333 unsigned Alignment,
334 unsigned SectionID,
335 #if HAVE_LLVM >= 0x0304
336 llvm::StringRef SectionName,
337 #endif
338 bool IsReadOnly) {
339 return mgr()->allocateDataSection(Size, Alignment, SectionID,
340 #if HAVE_LLVM >= 0x0304
341 SectionName,
342 #endif
343 IsReadOnly);
344 }
345 #if HAVE_LLVM >= 0x0304
346 virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
347 mgr()->registerEHFrames(Addr, LoadAddr, Size);
348 }
349 virtual void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
350 mgr()->deregisterEHFrames(Addr, LoadAddr, Size);
351 }
352 #else
353 virtual void registerEHFrames(llvm::StringRef SectionData) {
354 mgr()->registerEHFrames(SectionData);
355 }
356 #endif
357 virtual void *getPointerToNamedFunction(const std::string &Name,
358 bool AbortOnFailure=true) {
359 return mgr()->getPointerToNamedFunction(Name, AbortOnFailure);
360 }
361 #if HAVE_LLVM <= 0x0303
362 virtual bool applyPermissions(std::string *ErrMsg = 0) {
363 return mgr()->applyPermissions(ErrMsg);
364 }
365 #else
366 virtual bool finalizeMemory(std::string *ErrMsg = 0) {
367 return mgr()->finalizeMemory(ErrMsg);
368 }
369 #endif
370 };
371
372
373 /*
374 * Delegate memory management to one shared manager for more efficient use
375 * of memory than creating a separate pool for each LLVM engine.
376 * Keep generated code until freeGeneratedCode() is called, instead of when
377 * memory manager is destroyed, which happens during engine destruction.
378 * This allows additional memory savings as we don't have to keep the engine
379 * around in order to use the code.
380 * All methods are delegated to the shared manager except destruction and
381 * deallocating code. For the latter we just remember what needs to be
382 * deallocated later. The shared manager is deleted once it is empty.
383 */
384 class ShaderMemoryManager : public DelegatingJITMemoryManager {
385
386 BaseMemoryManager *TheMM;
387
388 struct GeneratedCode {
389 typedef std::vector<void *> Vec;
390 Vec FunctionBody, ExceptionTable;
391 BaseMemoryManager *TheMM;
392
393 GeneratedCode(BaseMemoryManager *MM) {
394 TheMM = MM;
395 }
396
397 ~GeneratedCode() {
398 /*
399 * Deallocate things as previously requested and
400 * free shared manager when no longer used.
401 */
402 #if HAVE_LLVM < 0x0306
403 Vec::iterator i;
404
405 assert(TheMM);
406 for ( i = FunctionBody.begin(); i != FunctionBody.end(); ++i )
407 TheMM->deallocateFunctionBody(*i);
408 #if HAVE_LLVM < 0x0304
409 for ( i = ExceptionTable.begin(); i != ExceptionTable.end(); ++i )
410 TheMM->deallocateExceptionTable(*i);
411 #endif /* HAVE_LLVM < 0x0304 */
412 #endif /* HAVE_LLVM < 0x0306 */
413 }
414 };
415
416 GeneratedCode *code;
417
418 BaseMemoryManager *mgr() const {
419 return TheMM;
420 }
421
422 public:
423
424 ShaderMemoryManager(BaseMemoryManager* MM) {
425 TheMM = MM;
426 code = new GeneratedCode(MM);
427 }
428
429 virtual ~ShaderMemoryManager() {
430 /*
431 * 'code' is purposely not deleted. It is the user's responsibility
432 * to call getGeneratedCode() and freeGeneratedCode().
433 */
434 }
435
436 struct lp_generated_code *getGeneratedCode() {
437 return (struct lp_generated_code *) code;
438 }
439
440 static void freeGeneratedCode(struct lp_generated_code *code) {
441 delete (GeneratedCode *) code;
442 }
443
444 #if HAVE_LLVM < 0x0304
445 virtual void deallocateExceptionTable(void *ET) {
446 // remember for later deallocation
447 code->ExceptionTable.push_back(ET);
448 }
449 #endif
450
451 virtual void deallocateFunctionBody(void *Body) {
452 // remember for later deallocation
453 code->FunctionBody.push_back(Body);
454 }
455 };
456
457
458 /**
459 * Same as LLVMCreateJITCompilerForModule, but:
460 * - allows using MCJIT and enabling AVX feature where available.
461 * - set target options
462 *
463 * See also:
464 * - llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
465 * - llvm/tools/lli/lli.cpp
466 * - http://markmail.org/message/ttkuhvgj4cxxy2on#query:+page:1+mid:aju2dggerju3ivd3+state:results
467 */
468 extern "C"
469 LLVMBool
470 lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
471 lp_generated_code **OutCode,
472 LLVMModuleRef M,
473 LLVMMCJITMemoryManagerRef CMM,
474 unsigned OptLevel,
475 int useMCJIT,
476 char **OutError)
477 {
478 using namespace llvm;
479
480 std::string Error;
481 #if HAVE_LLVM >= 0x0306
482 EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
483 #else
484 EngineBuilder builder(unwrap(M));
485 #endif
486
487 /**
488 * LLVM 3.1+ haven't more "extern unsigned llvm::StackAlignmentOverride" and
489 * friends for configuring code generation options, like stack alignment.
490 */
491 TargetOptions options;
492 #if defined(PIPE_ARCH_X86)
493 options.StackAlignmentOverride = 4;
494 #if HAVE_LLVM < 0x0304
495 options.RealignStack = true;
496 #endif
497 #endif
498
499 #if defined(DEBUG) && HAVE_LLVM < 0x0307
500 options.JITEmitDebugInfo = true;
501 #endif
502
503 /* XXX: Workaround http://llvm.org/PR21435 */
504 #if defined(DEBUG) || defined(PROFILE) || \
505 (HAVE_LLVM >= 0x0303 && (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)))
506 #if HAVE_LLVM < 0x0304
507 options.NoFramePointerElimNonLeaf = true;
508 #endif
509 #if HAVE_LLVM < 0x0307
510 options.NoFramePointerElim = true;
511 #endif
512 #endif
513
514 builder.setEngineKind(EngineKind::JIT)
515 .setErrorStr(&Error)
516 .setTargetOptions(options)
517 .setOptLevel((CodeGenOpt::Level)OptLevel);
518
519 if (useMCJIT) {
520 #if HAVE_LLVM < 0x0306
521 builder.setUseMCJIT(true);
522 #endif
523 #ifdef _WIN32
524 /*
525 * MCJIT works on Windows, but currently only through ELF object format.
526 *
527 * XXX: We could use `LLVM_HOST_TRIPLE "-elf"` but LLVM_HOST_TRIPLE has
528 * different strings for MinGW/MSVC, so better play it safe and be
529 * explicit.
530 */
531 # ifdef _WIN64
532 LLVMSetTarget(M, "x86_64-pc-win32-elf");
533 # else
534 LLVMSetTarget(M, "i686-pc-win32-elf");
535 # endif
536 #endif
537 }
538
539 llvm::SmallVector<std::string, 16> MAttrs;
540
541 #if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
542 /*
543 * We need to unset attributes because sometimes LLVM mistakenly assumes
544 * certain features are present given the processor name.
545 *
546 * https://bugs.freedesktop.org/show_bug.cgi?id=92214
547 * http://llvm.org/PR25021
548 * http://llvm.org/PR19429
549 * http://llvm.org/PR16721
550 */
551 MAttrs.push_back(util_cpu_caps.has_sse ? "+sse" : "-sse" );
552 MAttrs.push_back(util_cpu_caps.has_sse2 ? "+sse2" : "-sse2" );
553 MAttrs.push_back(util_cpu_caps.has_sse3 ? "+sse3" : "-sse3" );
554 MAttrs.push_back(util_cpu_caps.has_ssse3 ? "+ssse3" : "-ssse3" );
555 #if HAVE_LLVM >= 0x0304
556 MAttrs.push_back(util_cpu_caps.has_sse4_1 ? "+sse4.1" : "-sse4.1");
557 #else
558 MAttrs.push_back(util_cpu_caps.has_sse4_1 ? "+sse41" : "-sse41" );
559 #endif
560 #if HAVE_LLVM >= 0x0304
561 MAttrs.push_back(util_cpu_caps.has_sse4_2 ? "+sse4.2" : "-sse4.2");
562 #else
563 MAttrs.push_back(util_cpu_caps.has_sse4_2 ? "+sse42" : "-sse42" );
564 #endif
565 /*
566 * AVX feature is not automatically detected from CPUID by the X86 target
567 * yet, because the old (yet default) JIT engine is not capable of
568 * emitting the opcodes. On newer llvm versions it is and at least some
569 * versions (tested with 3.3) will emit avx opcodes without this anyway.
570 */
571 MAttrs.push_back(util_cpu_caps.has_avx ? "+avx" : "-avx");
572 MAttrs.push_back(util_cpu_caps.has_f16c ? "+f16c" : "-f16c");
573 MAttrs.push_back(util_cpu_caps.has_avx2 ? "+avx2" : "-avx2");
574 /* disable avx512 and all subvariants */
575 #if HAVE_LLVM >= 0x0304
576 MAttrs.push_back("-avx512cd");
577 MAttrs.push_back("-avx512er");
578 MAttrs.push_back("-avx512f");
579 MAttrs.push_back("-avx512pf");
580 #endif
581 #if HAVE_LLVM >= 0x0305
582 MAttrs.push_back("-avx512bw");
583 MAttrs.push_back("-avx512dq");
584 MAttrs.push_back("-avx512vl");
585 #endif
586 #endif
587
588 #if defined(PIPE_ARCH_PPC)
589 MAttrs.push_back(util_cpu_caps.has_altivec ? "+altivec" : "-altivec");
590 #if HAVE_LLVM >= 0x0304
591 /*
592 * Make sure VSX instructions are disabled
593 * See LLVM bug https://llvm.org/bugs/show_bug.cgi?id=25503#c7
594 */
595 if (util_cpu_caps.has_altivec) {
596 MAttrs.push_back("-vsx");
597 }
598 #endif
599 #endif
600
601 builder.setMAttrs(MAttrs);
602
603 #if HAVE_LLVM >= 0x0305
604 StringRef MCPU = llvm::sys::getHostCPUName();
605 /*
606 * The cpu bits are no longer set automatically, so need to set mcpu manually.
607 * Note that the MAttrs set above will be sort of ignored (since we should
608 * not set any which would not be set by specifying the cpu anyway).
609 * It ought to be safe though since getHostCPUName() should include bits
610 * not only from the cpu but environment as well (for instance if it's safe
611 * to use avx instructions which need OS support). According to
612 * http://llvm.org/bugs/show_bug.cgi?id=19429 however if I understand this
613 * right it may be necessary to specify older cpu (or disable mattrs) though
614 * when not using MCJIT so no instructions are generated which the old JIT
615 * can't handle. Not entirely sure if we really need to do anything yet.
616 */
617 builder.setMCPU(MCPU);
618 #endif
619
620 ShaderMemoryManager *MM = NULL;
621 if (useMCJIT) {
622 BaseMemoryManager* JMM = reinterpret_cast<BaseMemoryManager*>(CMM);
623 MM = new ShaderMemoryManager(JMM);
624 *OutCode = MM->getGeneratedCode();
625
626 #if HAVE_LLVM >= 0x0306
627 builder.setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager>(MM));
628 MM = NULL; // ownership taken by std::unique_ptr
629 #elif HAVE_LLVM > 0x0303
630 builder.setMCJITMemoryManager(MM);
631 #else
632 builder.setJITMemoryManager(MM);
633 #endif
634 } else {
635 #if HAVE_LLVM < 0x0306
636 BaseMemoryManager* JMM = reinterpret_cast<BaseMemoryManager*>(CMM);
637 MM = new ShaderMemoryManager(JMM);
638 *OutCode = MM->getGeneratedCode();
639
640 builder.setJITMemoryManager(MM);
641 #else
642 assert(0);
643 #endif
644 }
645
646 ExecutionEngine *JIT;
647
648 JIT = builder.create();
649 #if LLVM_USE_INTEL_JITEVENTS
650 JITEventListener *JEL = JITEventListener::createIntelJITEventListener();
651 JIT->RegisterJITEventListener(JEL);
652 #endif
653 if (JIT) {
654 *OutJIT = wrap(JIT);
655 return 0;
656 }
657 lp_free_generated_code(*OutCode);
658 *OutCode = 0;
659 delete MM;
660 *OutError = strdup(Error.c_str());
661 return 1;
662 }
663
664
665 extern "C"
666 void
667 lp_free_generated_code(struct lp_generated_code *code)
668 {
669 ShaderMemoryManager::freeGeneratedCode(code);
670 }
671
672 extern "C"
673 LLVMMCJITMemoryManagerRef
674 lp_get_default_memory_manager()
675 {
676 BaseMemoryManager *mm;
677 #if HAVE_LLVM < 0x0306
678 mm = llvm::JITMemoryManager::CreateDefaultMemManager();
679 #else
680 mm = new llvm::SectionMemoryManager();
681 #endif
682 return reinterpret_cast<LLVMMCJITMemoryManagerRef>(mm);
683 }
684
685 extern "C"
686 void
687 lp_free_memory_manager(LLVMMCJITMemoryManagerRef memorymgr)
688 {
689 delete reinterpret_cast<BaseMemoryManager*>(memorymgr);
690 }