gallivm/llvmpipe: squash merge of the llvm-context branch
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_init.c
1 /**************************************************************************
2 *
3 * Copyright 2009 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 above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29 #include "pipe/p_compiler.h"
30 #include "util/u_cpu_detect.h"
31 #include "util/u_debug.h"
32 #include "util/u_memory.h"
33 #include "lp_bld_debug.h"
34 #include "lp_bld_init.h"
35
36 #include <llvm-c/Transforms/Scalar.h>
37
38
39 #ifdef DEBUG
40 unsigned gallivm_debug = 0;
41
42 static const struct debug_named_value lp_bld_debug_flags[] = {
43 { "tgsi", GALLIVM_DEBUG_TGSI, NULL },
44 { "ir", GALLIVM_DEBUG_IR, NULL },
45 { "asm", GALLIVM_DEBUG_ASM, NULL },
46 { "nopt", GALLIVM_DEBUG_NO_OPT, NULL },
47 { "perf", GALLIVM_DEBUG_PERF, NULL },
48 { "no_brilinear", GALLIVM_DEBUG_NO_BRILINEAR, NULL },
49 { "gc", GALLIVM_DEBUG_GC, NULL },
50 DEBUG_NAMED_VALUE_END
51 };
52
53 DEBUG_GET_ONCE_FLAGS_OPTION(gallivm_debug, "GALLIVM_DEBUG", lp_bld_debug_flags, 0)
54 #endif
55
56
57 static boolean gallivm_initialized = FALSE;
58
59
60 /*
61 * Optimization values are:
62 * - 0: None (-O0)
63 * - 1: Less (-O1)
64 * - 2: Default (-O2, -Os)
65 * - 3: Aggressive (-O3)
66 *
67 * See also CodeGenOpt::Level in llvm/Target/TargetMachine.h
68 */
69 enum LLVM_CodeGenOpt_Level {
70 #if HAVE_LLVM >= 0x207
71 None, // -O0
72 Less, // -O1
73 Default, // -O2, -Os
74 Aggressive // -O3
75 #else
76 Default,
77 None,
78 Aggressive
79 #endif
80 };
81
82
83 /**
84 * LLVM 2.6 permits only one ExecutionEngine to be created. This is it.
85 */
86 static LLVMExecutionEngineRef GlobalEngine = NULL;
87
88 /**
89 * Same gallivm state shared by all contexts.
90 */
91 static struct gallivm_state *GlobalGallivm = NULL;
92
93
94
95
96 extern void
97 lp_register_oprofile_jit_event_listener(LLVMExecutionEngineRef EE);
98
99 extern void
100 lp_set_target_options(void);
101
102
103
104 /**
105 * Create the LLVM (optimization) pass manager and install
106 * relevant optimization passes.
107 * \return TRUE for success, FALSE for failure
108 */
109 static boolean
110 create_pass_manager(struct gallivm_state *gallivm)
111 {
112 assert(!gallivm->passmgr);
113
114 gallivm->passmgr = LLVMCreateFunctionPassManager(gallivm->provider);
115 if (!gallivm->passmgr)
116 return FALSE;
117
118 LLVMAddTargetData(gallivm->target, gallivm->passmgr);
119
120 if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) {
121 /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
122 * but there are more on SVN.
123 * TODO: Add more passes.
124 */
125 LLVMAddCFGSimplificationPass(gallivm->passmgr);
126
127 if (HAVE_LLVM >= 0x207 && sizeof(void*) == 4) {
128 /* For LLVM >= 2.7 and 32-bit build, use this order of passes to
129 * avoid generating bad code.
130 * Test with piglit glsl-vs-sqrt-zero test.
131 */
132 LLVMAddConstantPropagationPass(gallivm->passmgr);
133 LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
134 }
135 else {
136 LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
137 LLVMAddConstantPropagationPass(gallivm->passmgr);
138 }
139
140 if (util_cpu_caps.has_sse4_1) {
141 /* FIXME: There is a bug in this pass, whereby the combination
142 * of fptosi and sitofp (necessary for trunc/floor/ceil/round
143 * implementation) somehow becomes invalid code.
144 */
145 LLVMAddInstructionCombiningPass(gallivm->passmgr);
146 }
147 LLVMAddGVNPass(gallivm->passmgr);
148 }
149 else {
150 /* We need at least this pass to prevent the backends to fail in
151 * unexpected ways.
152 */
153 LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
154 }
155
156 return TRUE;
157 }
158
159
160 /**
161 * Free gallivm object's LLVM allocations, but not the gallivm object itself.
162 */
163 static void
164 free_gallivm_state(struct gallivm_state *gallivm)
165 {
166 #if HAVE_LLVM >= 0x207 /* XXX or 0x208? */
167 /* This leads to crashes w/ some versions of LLVM */
168 LLVMModuleRef mod;
169 char *error;
170
171 if (gallivm->engine && gallivm->provider)
172 LLVMRemoveModuleProvider(gallivm->engine, gallivm->provider,
173 &mod, &error);
174 #endif
175
176 #if 0
177 /* XXX this seems to crash with all versions of LLVM */
178 if (gallivm->provider)
179 LLVMDisposeModuleProvider(gallivm->provider);
180 #endif
181
182 if (gallivm->passmgr)
183 LLVMDisposePassManager(gallivm->passmgr);
184
185 #if HAVE_LLVM >= 0x207
186 if (gallivm->module)
187 LLVMDisposeModule(gallivm->module);
188 #endif
189
190 #if 0
191 /* Don't free the exec engine, it's a global/singleton */
192 if (gallivm->engine)
193 LLVMDisposeExecutionEngine(gallivm->engine);
194 #endif
195
196 #if 0
197 /* Don't free the TargetData, it's owned by the exec engine */
198 LLVMDisposeTargetData(gallivm->target);
199 #endif
200
201 if (gallivm->context)
202 LLVMContextDispose(gallivm->context);
203
204 if (gallivm->builder)
205 LLVMDisposeBuilder(gallivm->builder);
206
207 gallivm->engine = NULL;
208 gallivm->target = NULL;
209 gallivm->module = NULL;
210 gallivm->provider = NULL;
211 gallivm->passmgr = NULL;
212 gallivm->context = NULL;
213 gallivm->builder = NULL;
214 }
215
216
217 /**
218 * Allocate gallivm LLVM objects.
219 * \return TRUE for success, FALSE for failure
220 */
221 static boolean
222 init_gallivm_state(struct gallivm_state *gallivm)
223 {
224 assert(gallivm_initialized);
225 assert(!gallivm->context);
226 assert(!gallivm->module);
227 assert(!gallivm->provider);
228
229 gallivm->context = LLVMContextCreate();
230 if (!gallivm->context)
231 goto fail;
232
233 gallivm->module = LLVMModuleCreateWithNameInContext("gallivm",
234 gallivm->context);
235 if (!gallivm->module)
236 goto fail;
237
238 gallivm->provider =
239 LLVMCreateModuleProviderForExistingModule(gallivm->module);
240 if (!gallivm->provider)
241 goto fail;
242
243 if (!GlobalEngine) {
244 /* We can only create one LLVMExecutionEngine (w/ LLVM 2.6 anyway) */
245 enum LLVM_CodeGenOpt_Level optlevel;
246 char *error = NULL;
247
248 if (gallivm_debug & GALLIVM_DEBUG_NO_OPT) {
249 optlevel = None;
250 }
251 else {
252 optlevel = Default;
253 }
254
255 if (LLVMCreateJITCompiler(&GlobalEngine, gallivm->provider,
256 (unsigned) optlevel, &error)) {
257 _debug_printf("%s\n", error);
258 LLVMDisposeMessage(error);
259 goto fail;
260 }
261
262 #if defined(DEBUG) || defined(PROFILE)
263 lp_register_oprofile_jit_event_listener(GlobalEngine);
264 #endif
265 }
266
267 gallivm->engine = GlobalEngine;
268
269 LLVMAddModuleProvider(gallivm->engine, gallivm->provider);//new
270
271 gallivm->target = LLVMGetExecutionEngineTargetData(gallivm->engine);
272 if (!gallivm->target)
273 goto fail;
274
275 if (!create_pass_manager(gallivm))
276 goto fail;
277
278 gallivm->builder = LLVMCreateBuilderInContext(gallivm->context);
279 if (!gallivm->builder)
280 goto fail;
281
282 return TRUE;
283
284 fail:
285 free_gallivm_state(gallivm);
286 return FALSE;
287 }
288
289
290 struct callback
291 {
292 garbage_collect_callback_func func;
293 void *cb_data;
294 };
295
296
297 #define MAX_CALLBACKS 32
298 static struct callback Callbacks[MAX_CALLBACKS];
299 static unsigned NumCallbacks = 0;
300
301
302 /**
303 * Register a function with gallivm which will be called when we
304 * do garbage collection.
305 */
306 void
307 gallivm_register_garbage_collector_callback(garbage_collect_callback_func func,
308 void *cb_data)
309 {
310 unsigned i;
311
312 for (i = 0; i < NumCallbacks; i++) {
313 if (Callbacks[i].func == func && Callbacks[i].cb_data == cb_data) {
314 /* already in list: no-op */
315 return;
316 }
317 }
318
319 assert(NumCallbacks < MAX_CALLBACKS);
320 if (NumCallbacks < MAX_CALLBACKS) {
321 Callbacks[NumCallbacks].func = func;
322 Callbacks[NumCallbacks].cb_data = cb_data;
323 NumCallbacks++;
324 }
325 }
326
327
328 /**
329 * Remove a callback.
330 */
331 void
332 gallivm_remove_garbage_collector_callback(garbage_collect_callback_func func,
333 void *cb_data)
334 {
335 unsigned i;
336
337 for (i = 0; i < NumCallbacks; i++) {
338 if (Callbacks[i].func == func && Callbacks[i].cb_data == cb_data) {
339 /* found, now remove it */
340 NumCallbacks--;
341 for ( ; i < NumCallbacks; i++) {
342 Callbacks[i] = Callbacks[i + 1];
343 }
344 return;
345 }
346 }
347 }
348
349
350 /**
351 * Call the callback functions (which are typically in the
352 * draw module and llvmpipe driver.
353 */
354 static void
355 call_garbage_collector_callbacks(void)
356 {
357 unsigned i;
358
359 for (i = 0; i < NumCallbacks; i++) {
360 Callbacks[i].func(Callbacks[i].cb_data);
361 }
362 }
363
364
365
366 /**
367 * Other gallium components using gallivm should call this periodically
368 * to let us do garbage collection (or at least try to free memory
369 * accumulated by the LLVM libraries).
370 */
371 void
372 gallivm_garbage_collect(struct gallivm_state *gallivm)
373 {
374 if (gallivm->context) {
375 if (gallivm_debug & GALLIVM_DEBUG_GC)
376 debug_printf("***** Doing LLVM garbage collection\n");
377
378 call_garbage_collector_callbacks();
379 free_gallivm_state(gallivm);
380 init_gallivm_state(gallivm);
381 }
382 }
383
384
385 void
386 lp_build_init(void)
387 {
388 #ifdef DEBUG
389 gallivm_debug = debug_get_option_gallivm_debug();
390 #endif
391
392 lp_set_target_options();
393
394 LLVMInitializeNativeTarget();
395
396 LLVMLinkInJIT();
397
398 util_cpu_detect();
399
400 gallivm_initialized = TRUE;
401
402 #if 0
403 /* For simulating less capable machines */
404 util_cpu_caps.has_sse3 = 0;
405 util_cpu_caps.has_ssse3 = 0;
406 util_cpu_caps.has_sse4_1 = 0;
407 #endif
408 }
409
410
411
412 /**
413 * Create a new gallivm_state object.
414 * Note that we return a singleton.
415 */
416 struct gallivm_state *
417 gallivm_create(void)
418 {
419 if (!GlobalGallivm) {
420 GlobalGallivm = CALLOC_STRUCT(gallivm_state);
421 if (GlobalGallivm) {
422 if (!init_gallivm_state(GlobalGallivm)) {
423 FREE(GlobalGallivm);
424 GlobalGallivm = NULL;
425 }
426 }
427 }
428 return GlobalGallivm;
429 }
430
431
432 /**
433 * Destroy a gallivm_state object.
434 */
435 void
436 gallivm_destroy(struct gallivm_state *gallivm)
437 {
438 /* No-op: don't destroy the singleton */
439 (void) gallivm;
440 }
441
442
443
444 /*
445 * Hack to allow the linking of release LLVM static libraries on a debug build.
446 *
447 * See also:
448 * - http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/7234ea2b-0042-42ed-b4e2-5d8644dfb57d
449 */
450 #if defined(_MSC_VER) && defined(_DEBUG)
451 #include <crtdefs.h>
452 _CRTIMP void __cdecl
453 _invalid_parameter_noinfo(void) {}
454 #endif