gallivm: Disable workaround for PR12833 on LLVM 3.2+.
[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 #include <llvm-c/Core.h>
54 #include <llvm-c/ExecutionEngine.h>
55 #include <llvm/Target/TargetOptions.h>
56 #include <llvm/ExecutionEngine/ExecutionEngine.h>
57 #include <llvm/ADT/Triple.h>
58 #include <llvm/ExecutionEngine/JITMemoryManager.h>
59 #include <llvm/Support/CommandLine.h>
60 #include <llvm/Support/Host.h>
61 #include <llvm/Support/PrettyStackTrace.h>
62
63 #include <llvm/Support/TargetSelect.h>
64
65 #if HAVE_LLVM >= 0x0303
66 #include <llvm/IR/IRBuilder.h>
67 #include <llvm/IR/Module.h>
68 #include <llvm/Support/CBindingWrapping.h>
69 #endif
70
71 #include "pipe/p_config.h"
72 #include "util/u_debug.h"
73 #include "util/u_cpu_detect.h"
74
75 #include "lp_bld_misc.h"
76
77 namespace {
78
79 class LLVMEnsureMultithreaded {
80 public:
81 LLVMEnsureMultithreaded()
82 {
83 #if HAVE_LLVM < 0x0303
84 if (!llvm::llvm_is_multithreaded()) {
85 llvm::llvm_start_multithreaded();
86 }
87 #else
88 if (!LLVMIsMultithreaded()) {
89 LLVMStartMultithreaded();
90 }
91 #endif
92 }
93 };
94
95 static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;
96
97 }
98
99 extern "C" void
100 lp_set_target_options(void)
101 {
102 #if HAVE_LLVM < 0x0304
103 /*
104 * By default LLVM adds a signal handler to output a pretty stack trace.
105 * This signal handler is never removed, causing problems when unloading the
106 * shared object where the gallium driver resides.
107 */
108 llvm::DisablePrettyStackTrace = true;
109 #endif
110
111 // If we have a native target, initialize it to ensure it is linked in and
112 // usable by the JIT.
113 llvm::InitializeNativeTarget();
114
115 llvm::InitializeNativeTargetAsmPrinter();
116
117 llvm::InitializeNativeTargetDisassembler();
118 }
119
120
121 extern "C"
122 LLVMValueRef
123 lp_build_load_volatile(LLVMBuilderRef B, LLVMValueRef PointerVal,
124 const char *Name)
125 {
126 return llvm::wrap(llvm::unwrap(B)->CreateLoad(llvm::unwrap(PointerVal), true, Name));
127 }
128
129
130 extern "C"
131 void
132 lp_set_load_alignment(LLVMValueRef Inst,
133 unsigned Align)
134 {
135 llvm::unwrap<llvm::LoadInst>(Inst)->setAlignment(Align);
136 }
137
138 extern "C"
139 void
140 lp_set_store_alignment(LLVMValueRef Inst,
141 unsigned Align)
142 {
143 llvm::unwrap<llvm::StoreInst>(Inst)->setAlignment(Align);
144 }
145
146
147 /*
148 * Delegating is tedious but the default manager class is hidden in an
149 * anonymous namespace in LLVM, so we cannot just derive from it to change
150 * its behavior.
151 */
152 class DelegatingJITMemoryManager : public llvm::JITMemoryManager {
153
154 protected:
155 virtual llvm::JITMemoryManager *mgr() const = 0;
156
157 public:
158 /*
159 * From JITMemoryManager
160 */
161 virtual void setMemoryWritable() {
162 mgr()->setMemoryWritable();
163 }
164 virtual void setMemoryExecutable() {
165 mgr()->setMemoryExecutable();
166 }
167 virtual void setPoisonMemory(bool poison) {
168 mgr()->setPoisonMemory(poison);
169 }
170 virtual void AllocateGOT() {
171 mgr()->AllocateGOT();
172 /*
173 * isManagingGOT() is not virtual in base class so we can't delegate.
174 * Instead we mirror the value of HasGOT in our instance.
175 */
176 HasGOT = mgr()->isManagingGOT();
177 }
178 virtual uint8_t *getGOTBase() const {
179 return mgr()->getGOTBase();
180 }
181 virtual uint8_t *startFunctionBody(const llvm::Function *F,
182 uintptr_t &ActualSize) {
183 return mgr()->startFunctionBody(F, ActualSize);
184 }
185 virtual uint8_t *allocateStub(const llvm::GlobalValue *F,
186 unsigned StubSize,
187 unsigned Alignment) {
188 return mgr()->allocateStub(F, StubSize, Alignment);
189 }
190 virtual void endFunctionBody(const llvm::Function *F,
191 uint8_t *FunctionStart,
192 uint8_t *FunctionEnd) {
193 mgr()->endFunctionBody(F, FunctionStart, FunctionEnd);
194 }
195 virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
196 return mgr()->allocateSpace(Size, Alignment);
197 }
198 virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
199 return mgr()->allocateGlobal(Size, Alignment);
200 }
201 virtual void deallocateFunctionBody(void *Body) {
202 mgr()->deallocateFunctionBody(Body);
203 }
204 #if HAVE_LLVM < 0x0304
205 virtual uint8_t *startExceptionTable(const llvm::Function *F,
206 uintptr_t &ActualSize) {
207 return mgr()->startExceptionTable(F, ActualSize);
208 }
209 virtual void endExceptionTable(const llvm::Function *F,
210 uint8_t *TableStart,
211 uint8_t *TableEnd,
212 uint8_t *FrameRegister) {
213 mgr()->endExceptionTable(F, TableStart, TableEnd,
214 FrameRegister);
215 }
216 virtual void deallocateExceptionTable(void *ET) {
217 mgr()->deallocateExceptionTable(ET);
218 }
219 #endif
220 virtual bool CheckInvariants(std::string &s) {
221 return mgr()->CheckInvariants(s);
222 }
223 virtual size_t GetDefaultCodeSlabSize() {
224 return mgr()->GetDefaultCodeSlabSize();
225 }
226 virtual size_t GetDefaultDataSlabSize() {
227 return mgr()->GetDefaultDataSlabSize();
228 }
229 virtual size_t GetDefaultStubSlabSize() {
230 return mgr()->GetDefaultStubSlabSize();
231 }
232 virtual unsigned GetNumCodeSlabs() {
233 return mgr()->GetNumCodeSlabs();
234 }
235 virtual unsigned GetNumDataSlabs() {
236 return mgr()->GetNumDataSlabs();
237 }
238 virtual unsigned GetNumStubSlabs() {
239 return mgr()->GetNumStubSlabs();
240 }
241
242 /*
243 * From RTDyldMemoryManager
244 */
245 #if HAVE_LLVM >= 0x0304
246 virtual uint8_t *allocateCodeSection(uintptr_t Size,
247 unsigned Alignment,
248 unsigned SectionID,
249 llvm::StringRef SectionName) {
250 return mgr()->allocateCodeSection(Size, Alignment, SectionID,
251 SectionName);
252 }
253 #else
254 virtual uint8_t *allocateCodeSection(uintptr_t Size,
255 unsigned Alignment,
256 unsigned SectionID) {
257 return mgr()->allocateCodeSection(Size, Alignment, SectionID);
258 }
259 #endif
260 #if HAVE_LLVM >= 0x0303
261 virtual uint8_t *allocateDataSection(uintptr_t Size,
262 unsigned Alignment,
263 unsigned SectionID,
264 #if HAVE_LLVM >= 0x0304
265 llvm::StringRef SectionName,
266 #endif
267 bool IsReadOnly) {
268 return mgr()->allocateDataSection(Size, Alignment, SectionID,
269 #if HAVE_LLVM >= 0x0304
270 SectionName,
271 #endif
272 IsReadOnly);
273 }
274 #if HAVE_LLVM >= 0x0304
275 virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
276 mgr()->registerEHFrames(Addr, LoadAddr, Size);
277 }
278 virtual void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
279 mgr()->deregisterEHFrames(Addr, LoadAddr, Size);
280 }
281 #else
282 virtual void registerEHFrames(llvm::StringRef SectionData) {
283 mgr()->registerEHFrames(SectionData);
284 }
285 #endif
286 #else
287 virtual uint8_t *allocateDataSection(uintptr_t Size,
288 unsigned Alignment,
289 unsigned SectionID) {
290 return mgr()->allocateDataSection(Size, Alignment, SectionID);
291 }
292 #endif
293 virtual void *getPointerToNamedFunction(const std::string &Name,
294 bool AbortOnFailure=true) {
295 return mgr()->getPointerToNamedFunction(Name, AbortOnFailure);
296 }
297 #if HAVE_LLVM == 0x0303
298 virtual bool applyPermissions(std::string *ErrMsg = 0) {
299 return mgr()->applyPermissions(ErrMsg);
300 }
301 #elif HAVE_LLVM > 0x0303
302 virtual bool finalizeMemory(std::string *ErrMsg = 0) {
303 return mgr()->finalizeMemory(ErrMsg);
304 }
305 #endif
306 };
307
308
309 /*
310 * Delegate memory management to one shared manager for more efficient use
311 * of memory than creating a separate pool for each LLVM engine.
312 * Keep generated code until freeGeneratedCode() is called, instead of when
313 * memory manager is destroyed, which happens during engine destruction.
314 * This allows additional memory savings as we don't have to keep the engine
315 * around in order to use the code.
316 * All methods are delegated to the shared manager except destruction and
317 * deallocating code. For the latter we just remember what needs to be
318 * deallocated later. The shared manager is deleted once it is empty.
319 */
320 class ShaderMemoryManager : public DelegatingJITMemoryManager {
321
322 static llvm::JITMemoryManager *TheMM;
323 static unsigned NumUsers;
324
325 struct GeneratedCode {
326 typedef std::vector<void *> Vec;
327 Vec FunctionBody, ExceptionTable;
328
329 GeneratedCode() {
330 ++NumUsers;
331 }
332
333 ~GeneratedCode() {
334 /*
335 * Deallocate things as previously requested and
336 * free shared manager when no longer used.
337 */
338 Vec::iterator i;
339
340 assert(TheMM);
341 for ( i = FunctionBody.begin(); i != FunctionBody.end(); ++i )
342 TheMM->deallocateFunctionBody(*i);
343 #if HAVE_LLVM < 0x0304
344 for ( i = ExceptionTable.begin(); i != ExceptionTable.end(); ++i )
345 TheMM->deallocateExceptionTable(*i);
346 #endif
347 --NumUsers;
348 if (NumUsers == 0) {
349 delete TheMM;
350 TheMM = 0;
351 }
352 }
353 };
354
355 GeneratedCode *code;
356
357 llvm::JITMemoryManager *mgr() const {
358 if (!TheMM) {
359 TheMM = CreateDefaultMemManager();
360 }
361 return TheMM;
362 }
363
364 public:
365
366 ShaderMemoryManager() {
367 code = new GeneratedCode;
368 }
369
370 virtual ~ShaderMemoryManager() {
371 /*
372 * 'code' is purposely not deleted. It is the user's responsibility
373 * to call getGeneratedCode() and freeGeneratedCode().
374 */
375 }
376
377 struct lp_generated_code *getGeneratedCode() {
378 return (struct lp_generated_code *) code;
379 }
380
381 static void freeGeneratedCode(struct lp_generated_code *code) {
382 delete (GeneratedCode *) code;
383 }
384
385 #if HAVE_LLVM < 0x0304
386 virtual void deallocateExceptionTable(void *ET) {
387 // remember for later deallocation
388 code->ExceptionTable.push_back(ET);
389 }
390 #endif
391
392 virtual void deallocateFunctionBody(void *Body) {
393 // remember for later deallocation
394 code->FunctionBody.push_back(Body);
395 }
396 };
397
398 llvm::JITMemoryManager *ShaderMemoryManager::TheMM = 0;
399 unsigned ShaderMemoryManager::NumUsers = 0;
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 unsigned OptLevel,
418 int useMCJIT,
419 char **OutError)
420 {
421 using namespace llvm;
422
423 std::string Error;
424 EngineBuilder builder(unwrap(M));
425
426 /**
427 * LLVM 3.1+ haven't more "extern unsigned llvm::StackAlignmentOverride" and
428 * friends for configuring code generation options, like stack alignment.
429 */
430 TargetOptions options;
431 #if defined(PIPE_ARCH_X86)
432 options.StackAlignmentOverride = 4;
433 #if HAVE_LLVM < 0x0304
434 options.RealignStack = true;
435 #endif
436 #endif
437
438 #if defined(DEBUG)
439 options.JITEmitDebugInfo = true;
440 #endif
441
442 #if defined(DEBUG) || defined(PROFILE)
443 #if HAVE_LLVM < 0x0304
444 options.NoFramePointerElimNonLeaf = true;
445 #endif
446 options.NoFramePointerElim = true;
447 #endif
448
449 builder.setEngineKind(EngineKind::JIT)
450 .setErrorStr(&Error)
451 .setTargetOptions(options)
452 .setOptLevel((CodeGenOpt::Level)OptLevel);
453
454 if (useMCJIT) {
455 builder.setUseMCJIT(true);
456 #ifdef _WIN32
457 /*
458 * MCJIT works on Windows, but currently only through ELF object format.
459 */
460 std::string targetTriple = llvm::sys::getProcessTriple();
461 targetTriple.append("-elf");
462 unwrap(M)->setTargetTriple(targetTriple);
463 #endif
464 }
465
466 llvm::SmallVector<std::string, 1> MAttrs;
467 if (util_cpu_caps.has_avx) {
468 /*
469 * AVX feature is not automatically detected from CPUID by the X86 target
470 * yet, because the old (yet default) JIT engine is not capable of
471 * emitting the opcodes. But as we're using MCJIT here, it is safe to
472 * add set this attribute.
473 */
474 MAttrs.push_back("+avx");
475 if (util_cpu_caps.has_f16c) {
476 MAttrs.push_back("+f16c");
477 }
478 builder.setMAttrs(MAttrs);
479 }
480
481 ShaderMemoryManager *MM = new ShaderMemoryManager();
482 *OutCode = MM->getGeneratedCode();
483
484 builder.setJITMemoryManager(MM);
485
486 ExecutionEngine *JIT;
487 #if HAVE_LLVM >= 0x0302
488 JIT = builder.create();
489 #else
490 /*
491 * Workaround http://llvm.org/PR12833
492 */
493 StringRef MArch = "";
494 StringRef MCPU = "";
495 Triple TT(unwrap(M)->getTargetTriple());
496 JIT = builder.create(builder.selectTarget(TT, MArch, MCPU, MAttrs));
497 #endif
498 if (JIT) {
499 *OutJIT = wrap(JIT);
500 return 0;
501 }
502 lp_free_generated_code(*OutCode);
503 *OutCode = 0;
504 delete MM;
505 *OutError = strdup(Error.c_str());
506 return 1;
507 }
508
509
510 extern "C"
511 void
512 lp_free_generated_code(struct lp_generated_code *code)
513 {
514 ShaderMemoryManager::freeGeneratedCode(code);
515 }