Merge remote-tracking branch 'mesa-public/master' into vulkan
[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 < 0x0306
65 #include <llvm/ExecutionEngine/JITMemoryManager.h>
66 #else
67 #include <llvm/ExecutionEngine/SectionMemoryManager.h>
68 #endif
69 #include <llvm/Support/CommandLine.h>
70 #include <llvm/Support/Host.h>
71 #include <llvm/Support/PrettyStackTrace.h>
72
73 #include <llvm/Support/TargetSelect.h>
74
75 #include <llvm/IR/IRBuilder.h>
76 #include <llvm/IR/Module.h>
77 #include <llvm/Support/CBindingWrapping.h>
78
79 // Workaround http://llvm.org/PR23628
80 #if HAVE_LLVM >= 0x0307
81 # pragma pop_macro("DEBUG")
82 #endif
83
84 #include "pipe/p_config.h"
85 #include "util/u_debug.h"
86 #include "util/u_cpu_detect.h"
87
88 #include "lp_bld_misc.h"
89
90 namespace {
91
92 class LLVMEnsureMultithreaded {
93 public:
94 LLVMEnsureMultithreaded()
95 {
96 if (!LLVMIsMultithreaded()) {
97 LLVMStartMultithreaded();
98 }
99 }
100 };
101
102 static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;
103
104 }
105
106 extern "C" void
107 lp_set_target_options(void)
108 {
109 #if HAVE_LLVM < 0x0304
110 /*
111 * By default LLVM adds a signal handler to output a pretty stack trace.
112 * This signal handler is never removed, causing problems when unloading the
113 * shared object where the gallium driver resides.
114 */
115 llvm::DisablePrettyStackTrace = true;
116 #endif
117
118 // If we have a native target, initialize it to ensure it is linked in and
119 // usable by the JIT.
120 llvm::InitializeNativeTarget();
121
122 llvm::InitializeNativeTargetAsmPrinter();
123
124 llvm::InitializeNativeTargetDisassembler();
125 }
126
127
128 extern "C"
129 LLVMValueRef
130 lp_build_load_volatile(LLVMBuilderRef B, LLVMValueRef PointerVal,
131 const char *Name)
132 {
133 return llvm::wrap(llvm::unwrap(B)->CreateLoad(llvm::unwrap(PointerVal), true, Name));
134 }
135
136
137 extern "C"
138 void
139 lp_set_load_alignment(LLVMValueRef Inst,
140 unsigned Align)
141 {
142 llvm::unwrap<llvm::LoadInst>(Inst)->setAlignment(Align);
143 }
144
145 extern "C"
146 void
147 lp_set_store_alignment(LLVMValueRef Inst,
148 unsigned Align)
149 {
150 llvm::unwrap<llvm::StoreInst>(Inst)->setAlignment(Align);
151 }
152
153
154 #if HAVE_LLVM < 0x0306
155 typedef llvm::JITMemoryManager BaseMemoryManager;
156 #else
157 typedef llvm::RTDyldMemoryManager BaseMemoryManager;
158 #endif
159
160
161 /*
162 * Delegating is tedious but the default manager class is hidden in an
163 * anonymous namespace in LLVM, so we cannot just derive from it to change
164 * its behavior.
165 */
166 class DelegatingJITMemoryManager : public BaseMemoryManager {
167
168 protected:
169 virtual BaseMemoryManager *mgr() const = 0;
170
171 public:
172 #if HAVE_LLVM < 0x0306
173 /*
174 * From JITMemoryManager
175 */
176 virtual void setMemoryWritable() {
177 mgr()->setMemoryWritable();
178 }
179 virtual void setMemoryExecutable() {
180 mgr()->setMemoryExecutable();
181 }
182 virtual void setPoisonMemory(bool poison) {
183 mgr()->setPoisonMemory(poison);
184 }
185 virtual void AllocateGOT() {
186 mgr()->AllocateGOT();
187 /*
188 * isManagingGOT() is not virtual in base class so we can't delegate.
189 * Instead we mirror the value of HasGOT in our instance.
190 */
191 HasGOT = mgr()->isManagingGOT();
192 }
193 virtual uint8_t *getGOTBase() const {
194 return mgr()->getGOTBase();
195 }
196 virtual uint8_t *startFunctionBody(const llvm::Function *F,
197 uintptr_t &ActualSize) {
198 return mgr()->startFunctionBody(F, ActualSize);
199 }
200 virtual uint8_t *allocateStub(const llvm::GlobalValue *F,
201 unsigned StubSize,
202 unsigned Alignment) {
203 return mgr()->allocateStub(F, StubSize, Alignment);
204 }
205 virtual void endFunctionBody(const llvm::Function *F,
206 uint8_t *FunctionStart,
207 uint8_t *FunctionEnd) {
208 mgr()->endFunctionBody(F, FunctionStart, FunctionEnd);
209 }
210 virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
211 return mgr()->allocateSpace(Size, Alignment);
212 }
213 virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
214 return mgr()->allocateGlobal(Size, Alignment);
215 }
216 virtual void deallocateFunctionBody(void *Body) {
217 mgr()->deallocateFunctionBody(Body);
218 }
219 #if HAVE_LLVM < 0x0304
220 virtual uint8_t *startExceptionTable(const llvm::Function *F,
221 uintptr_t &ActualSize) {
222 return mgr()->startExceptionTable(F, ActualSize);
223 }
224 virtual void endExceptionTable(const llvm::Function *F,
225 uint8_t *TableStart,
226 uint8_t *TableEnd,
227 uint8_t *FrameRegister) {
228 mgr()->endExceptionTable(F, TableStart, TableEnd,
229 FrameRegister);
230 }
231 virtual void deallocateExceptionTable(void *ET) {
232 mgr()->deallocateExceptionTable(ET);
233 }
234 #endif
235 virtual bool CheckInvariants(std::string &s) {
236 return mgr()->CheckInvariants(s);
237 }
238 virtual size_t GetDefaultCodeSlabSize() {
239 return mgr()->GetDefaultCodeSlabSize();
240 }
241 virtual size_t GetDefaultDataSlabSize() {
242 return mgr()->GetDefaultDataSlabSize();
243 }
244 virtual size_t GetDefaultStubSlabSize() {
245 return mgr()->GetDefaultStubSlabSize();
246 }
247 virtual unsigned GetNumCodeSlabs() {
248 return mgr()->GetNumCodeSlabs();
249 }
250 virtual unsigned GetNumDataSlabs() {
251 return mgr()->GetNumDataSlabs();
252 }
253 virtual unsigned GetNumStubSlabs() {
254 return mgr()->GetNumStubSlabs();
255 }
256 #endif
257
258 /*
259 * From RTDyldMemoryManager
260 */
261 #if HAVE_LLVM >= 0x0304
262 virtual uint8_t *allocateCodeSection(uintptr_t Size,
263 unsigned Alignment,
264 unsigned SectionID,
265 llvm::StringRef SectionName) {
266 return mgr()->allocateCodeSection(Size, Alignment, SectionID,
267 SectionName);
268 }
269 #else
270 virtual uint8_t *allocateCodeSection(uintptr_t Size,
271 unsigned Alignment,
272 unsigned SectionID) {
273 return mgr()->allocateCodeSection(Size, Alignment, SectionID);
274 }
275 #endif
276 virtual uint8_t *allocateDataSection(uintptr_t Size,
277 unsigned Alignment,
278 unsigned SectionID,
279 #if HAVE_LLVM >= 0x0304
280 llvm::StringRef SectionName,
281 #endif
282 bool IsReadOnly) {
283 return mgr()->allocateDataSection(Size, Alignment, SectionID,
284 #if HAVE_LLVM >= 0x0304
285 SectionName,
286 #endif
287 IsReadOnly);
288 }
289 #if HAVE_LLVM >= 0x0304
290 virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
291 mgr()->registerEHFrames(Addr, LoadAddr, Size);
292 }
293 virtual void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
294 mgr()->deregisterEHFrames(Addr, LoadAddr, Size);
295 }
296 #else
297 virtual void registerEHFrames(llvm::StringRef SectionData) {
298 mgr()->registerEHFrames(SectionData);
299 }
300 #endif
301 virtual void *getPointerToNamedFunction(const std::string &Name,
302 bool AbortOnFailure=true) {
303 return mgr()->getPointerToNamedFunction(Name, AbortOnFailure);
304 }
305 #if HAVE_LLVM <= 0x0303
306 virtual bool applyPermissions(std::string *ErrMsg = 0) {
307 return mgr()->applyPermissions(ErrMsg);
308 }
309 #else
310 virtual bool finalizeMemory(std::string *ErrMsg = 0) {
311 return mgr()->finalizeMemory(ErrMsg);
312 }
313 #endif
314 };
315
316
317 /*
318 * Delegate memory management to one shared manager for more efficient use
319 * of memory than creating a separate pool for each LLVM engine.
320 * Keep generated code until freeGeneratedCode() is called, instead of when
321 * memory manager is destroyed, which happens during engine destruction.
322 * This allows additional memory savings as we don't have to keep the engine
323 * around in order to use the code.
324 * All methods are delegated to the shared manager except destruction and
325 * deallocating code. For the latter we just remember what needs to be
326 * deallocated later. The shared manager is deleted once it is empty.
327 */
328 class ShaderMemoryManager : public DelegatingJITMemoryManager {
329
330 BaseMemoryManager *TheMM;
331
332 struct GeneratedCode {
333 typedef std::vector<void *> Vec;
334 Vec FunctionBody, ExceptionTable;
335 BaseMemoryManager *TheMM;
336
337 GeneratedCode(BaseMemoryManager *MM) {
338 TheMM = MM;
339 }
340
341 ~GeneratedCode() {
342 /*
343 * Deallocate things as previously requested and
344 * free shared manager when no longer used.
345 */
346 #if HAVE_LLVM < 0x0306
347 Vec::iterator i;
348
349 assert(TheMM);
350 for ( i = FunctionBody.begin(); i != FunctionBody.end(); ++i )
351 TheMM->deallocateFunctionBody(*i);
352 #if HAVE_LLVM < 0x0304
353 for ( i = ExceptionTable.begin(); i != ExceptionTable.end(); ++i )
354 TheMM->deallocateExceptionTable(*i);
355 #endif /* HAVE_LLVM < 0x0304 */
356 #endif /* HAVE_LLVM < 0x0306 */
357 }
358 };
359
360 GeneratedCode *code;
361
362 BaseMemoryManager *mgr() const {
363 return TheMM;
364 }
365
366 public:
367
368 ShaderMemoryManager(BaseMemoryManager* MM) {
369 TheMM = MM;
370 code = new GeneratedCode(MM);
371 }
372
373 virtual ~ShaderMemoryManager() {
374 /*
375 * 'code' is purposely not deleted. It is the user's responsibility
376 * to call getGeneratedCode() and freeGeneratedCode().
377 */
378 }
379
380 struct lp_generated_code *getGeneratedCode() {
381 return (struct lp_generated_code *) code;
382 }
383
384 static void freeGeneratedCode(struct lp_generated_code *code) {
385 delete (GeneratedCode *) code;
386 }
387
388 #if HAVE_LLVM < 0x0304
389 virtual void deallocateExceptionTable(void *ET) {
390 // remember for later deallocation
391 code->ExceptionTable.push_back(ET);
392 }
393 #endif
394
395 virtual void deallocateFunctionBody(void *Body) {
396 // remember for later deallocation
397 code->FunctionBody.push_back(Body);
398 }
399 };
400
401
402 /**
403 * Same as LLVMCreateJITCompilerForModule, but:
404 * - allows using MCJIT and enabling AVX feature where available.
405 * - set target options
406 *
407 * See also:
408 * - llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
409 * - llvm/tools/lli/lli.cpp
410 * - http://markmail.org/message/ttkuhvgj4cxxy2on#query:+page:1+mid:aju2dggerju3ivd3+state:results
411 */
412 extern "C"
413 LLVMBool
414 lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
415 lp_generated_code **OutCode,
416 LLVMModuleRef M,
417 LLVMMCJITMemoryManagerRef CMM,
418 unsigned OptLevel,
419 int useMCJIT,
420 char **OutError)
421 {
422 using namespace llvm;
423
424 std::string Error;
425 #if HAVE_LLVM >= 0x0306
426 EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
427 #else
428 EngineBuilder builder(unwrap(M));
429 #endif
430
431 /**
432 * LLVM 3.1+ haven't more "extern unsigned llvm::StackAlignmentOverride" and
433 * friends for configuring code generation options, like stack alignment.
434 */
435 TargetOptions options;
436 #if defined(PIPE_ARCH_X86)
437 options.StackAlignmentOverride = 4;
438 #if HAVE_LLVM < 0x0304
439 options.RealignStack = true;
440 #endif
441 #endif
442
443 #if defined(DEBUG) && HAVE_LLVM < 0x0307
444 options.JITEmitDebugInfo = true;
445 #endif
446
447 /* XXX: Workaround http://llvm.org/PR21435 */
448 #if defined(DEBUG) || defined(PROFILE) || \
449 (HAVE_LLVM >= 0x0303 && (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)))
450 #if HAVE_LLVM < 0x0304
451 options.NoFramePointerElimNonLeaf = true;
452 #endif
453 #if HAVE_LLVM < 0x0307
454 options.NoFramePointerElim = true;
455 #endif
456 #endif
457
458 builder.setEngineKind(EngineKind::JIT)
459 .setErrorStr(&Error)
460 .setTargetOptions(options)
461 .setOptLevel((CodeGenOpt::Level)OptLevel);
462
463 if (useMCJIT) {
464 #if HAVE_LLVM < 0x0306
465 builder.setUseMCJIT(true);
466 #endif
467 #ifdef _WIN32
468 /*
469 * MCJIT works on Windows, but currently only through ELF object format.
470 */
471 std::string targetTriple = llvm::sys::getProcessTriple();
472 targetTriple.append("-elf");
473 unwrap(M)->setTargetTriple(targetTriple);
474 #endif
475 }
476
477 llvm::SmallVector<std::string, 1> MAttrs;
478 if (util_cpu_caps.has_avx) {
479 /*
480 * AVX feature is not automatically detected from CPUID by the X86 target
481 * yet, because the old (yet default) JIT engine is not capable of
482 * emitting the opcodes. On newer llvm versions it is and at least some
483 * versions (tested with 3.3) will emit avx opcodes without this anyway.
484 */
485 MAttrs.push_back("+avx");
486 if (util_cpu_caps.has_f16c) {
487 MAttrs.push_back("+f16c");
488 }
489 builder.setMAttrs(MAttrs);
490 }
491
492 #if HAVE_LLVM >= 0x0305
493 StringRef MCPU = llvm::sys::getHostCPUName();
494 /*
495 * The cpu bits are no longer set automatically, so need to set mcpu manually.
496 * Note that the MAttrs set above will be sort of ignored (since we should
497 * not set any which would not be set by specifying the cpu anyway).
498 * It ought to be safe though since getHostCPUName() should include bits
499 * not only from the cpu but environment as well (for instance if it's safe
500 * to use avx instructions which need OS support). According to
501 * http://llvm.org/bugs/show_bug.cgi?id=19429 however if I understand this
502 * right it may be necessary to specify older cpu (or disable mattrs) though
503 * when not using MCJIT so no instructions are generated which the old JIT
504 * can't handle. Not entirely sure if we really need to do anything yet.
505 */
506 builder.setMCPU(MCPU);
507 #endif
508
509 ShaderMemoryManager *MM = NULL;
510 if (useMCJIT) {
511 #if HAVE_LLVM > 0x0303
512 BaseMemoryManager* JMM = reinterpret_cast<BaseMemoryManager*>(CMM);
513 MM = new ShaderMemoryManager(JMM);
514 *OutCode = MM->getGeneratedCode();
515
516 #if HAVE_LLVM >= 0x0306
517 builder.setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager>(MM));
518 MM = NULL; // ownership taken by std::unique_ptr
519 #else
520 builder.setMCJITMemoryManager(MM);
521 #endif
522 #endif
523 } else {
524 #if HAVE_LLVM < 0x0306
525 BaseMemoryManager* JMM = reinterpret_cast<BaseMemoryManager*>(CMM);
526 MM = new ShaderMemoryManager(JMM);
527 *OutCode = MM->getGeneratedCode();
528
529 builder.setJITMemoryManager(MM);
530 #else
531 assert(0);
532 #endif
533 }
534
535 ExecutionEngine *JIT;
536
537 JIT = builder.create();
538 if (JIT) {
539 *OutJIT = wrap(JIT);
540 return 0;
541 }
542 lp_free_generated_code(*OutCode);
543 *OutCode = 0;
544 delete MM;
545 *OutError = strdup(Error.c_str());
546 return 1;
547 }
548
549
550 extern "C"
551 void
552 lp_free_generated_code(struct lp_generated_code *code)
553 {
554 ShaderMemoryManager::freeGeneratedCode(code);
555 }
556
557 extern "C"
558 LLVMMCJITMemoryManagerRef
559 lp_get_default_memory_manager()
560 {
561 BaseMemoryManager *mm;
562 #if HAVE_LLVM < 0x0306
563 mm = llvm::JITMemoryManager::CreateDefaultMemManager();
564 #else
565 mm = new llvm::SectionMemoryManager();
566 #endif
567 return reinterpret_cast<LLVMMCJITMemoryManagerRef>(mm);
568 }
569
570 extern "C"
571 void
572 lp_free_memory_manager(LLVMMCJITMemoryManagerRef memorymgr)
573 {
574 delete reinterpret_cast<BaseMemoryManager*>(memorymgr);
575 }