• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "util/detect.h"
30 #include "util/compiler.h"
31 #include "util/macros.h"
32 #include "util/u_cpu_detect.h"
33 #include "util/u_debug.h"
34 #include "util/u_memory.h"
35 #include "util/os_time.h"
36 #include "lp_bld.h"
37 #include "lp_bld_debug.h"
38 #include "lp_bld_misc.h"
39 #include "lp_bld_init.h"
40 #include "lp_bld_coro.h"
41 #include "lp_bld_printf.h"
42 
43 #include <llvm/Config/llvm-config.h>
44 #include <llvm-c/Analysis.h>
45 #include <llvm-c/BitWriter.h>
46 #if GALLIVM_USE_NEW_PASS == 1
47 #include <llvm-c/Transforms/PassBuilder.h>
48 #elif GALLIVM_HAVE_CORO == 1
49 #include <llvm-c/Transforms/Scalar.h>
50 #if LLVM_VERSION_MAJOR >= 7
51 #include <llvm-c/Transforms/Utils.h>
52 #endif
53 #if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 || DETECT_ARCH_ARM || DETECT_ARCH_S390 || DETECT_ARCH_MIPS64)
54 #include <llvm-c/Transforms/IPO.h>
55 #endif
56 #include <llvm-c/Transforms/Coroutines.h>
57 #endif
58 
59 unsigned gallivm_perf = 0;
60 
61 static const struct debug_named_value lp_bld_perf_flags[] = {
62    { "brilinear", GALLIVM_PERF_BRILINEAR, "enable brilinear optimization" },
63    { "rho_approx", GALLIVM_PERF_RHO_APPROX, "enable rho_approx optimization" },
64    { "no_quad_lod", GALLIVM_PERF_NO_QUAD_LOD, "disable quad_lod optimization" },
65    { "no_aos_sampling", GALLIVM_PERF_NO_AOS_SAMPLING, "disable aos sampling optimization" },
66    { "nopt",   GALLIVM_PERF_NO_OPT, "disable optimization passes to speed up shader compilation" },
67    DEBUG_NAMED_VALUE_END
68 };
69 
70 unsigned gallivm_debug = 0;
71 
72 static const struct debug_named_value lp_bld_debug_flags[] = {
73    { "tgsi",   GALLIVM_DEBUG_TGSI, NULL },
74    { "ir",     GALLIVM_DEBUG_IR, NULL },
75    { "asm",    GALLIVM_DEBUG_ASM, NULL },
76    { "perf",   GALLIVM_DEBUG_PERF, NULL },
77    { "gc",     GALLIVM_DEBUG_GC, NULL },
78 /* Don't allow setting DUMP_BC for release builds, since writing the files may be an issue with setuid. */
79 #ifdef DEBUG
80    { "dumpbc", GALLIVM_DEBUG_DUMP_BC, NULL },
81 #endif
82    DEBUG_NAMED_VALUE_END
83 };
84 
85 DEBUG_GET_ONCE_FLAGS_OPTION(gallivm_debug, "GALLIVM_DEBUG", lp_bld_debug_flags, 0)
86 
87 
88 static bool gallivm_initialized = false;
89 
90 unsigned lp_native_vector_width;
91 
92 
93 /*
94  * Optimization values are:
95  * - 0: None (-O0)
96  * - 1: Less (-O1)
97  * - 2: Default (-O2, -Os)
98  * - 3: Aggressive (-O3)
99  *
100  * See also CodeGenOpt::Level in llvm/Target/TargetMachine.h
101  */
102 enum LLVM_CodeGenOpt_Level {
103    None,        // -O0
104    Less,        // -O1
105    Default,     // -O2, -Os
106    Aggressive   // -O3
107 };
108 
109 
110 /**
111  * Create the LLVM (optimization) pass manager and install
112  * relevant optimization passes.
113  * \return  TRUE for success, FALSE for failure
114  */
115 static bool
create_pass_manager(struct gallivm_state * gallivm)116 create_pass_manager(struct gallivm_state *gallivm)
117 {
118 #if GALLIVM_USE_NEW_PASS == 0
119    assert(!gallivm->passmgr);
120    assert(gallivm->target);
121 
122    gallivm->passmgr = LLVMCreateFunctionPassManagerForModule(gallivm->module);
123    if (!gallivm->passmgr)
124       return false;
125 
126 #if GALLIVM_HAVE_CORO == 1
127    gallivm->cgpassmgr = LLVMCreatePassManager();
128 #endif
129    /*
130     * TODO: some per module pass manager with IPO passes might be helpful -
131     * the generated texture functions may benefit from inlining if they are
132     * simple, or constant propagation into them, etc.
133     */
134 
135    {
136       char *td_str;
137       // New ones from the Module.
138       td_str = LLVMCopyStringRepOfTargetData(gallivm->target);
139       LLVMSetDataLayout(gallivm->module, td_str);
140       free(td_str);
141    }
142 
143 #if GALLIVM_HAVE_CORO == 1
144 #if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 || DETECT_ARCH_ARM || DETECT_ARCH_S390 || DETECT_ARCH_MIPS64)
145    LLVMAddArgumentPromotionPass(gallivm->cgpassmgr);
146    LLVMAddFunctionAttrsPass(gallivm->cgpassmgr);
147 #endif
148    LLVMAddCoroEarlyPass(gallivm->cgpassmgr);
149    LLVMAddCoroSplitPass(gallivm->cgpassmgr);
150    LLVMAddCoroElidePass(gallivm->cgpassmgr);
151 #endif
152 
153    if ((gallivm_perf & GALLIVM_PERF_NO_OPT) == 0) {
154       /*
155        * TODO: Evaluate passes some more - keeping in mind
156        * both quality of generated code and compile times.
157        */
158       /*
159        * NOTE: if you change this, don't forget to change the output
160        * with GALLIVM_DEBUG_DUMP_BC in gallivm_compile_module.
161        */
162       LLVMAddScalarReplAggregatesPass(gallivm->passmgr);
163       LLVMAddEarlyCSEPass(gallivm->passmgr);
164       LLVMAddCFGSimplificationPass(gallivm->passmgr);
165       /*
166        * FIXME: LICM is potentially quite useful. However, for some
167        * rather crazy shaders the compile time can reach _hours_ per shader,
168        * due to licm implying lcssa (since llvm 3.5), which can take forever.
169        * Even for sane shaders, the cost of licm is rather high (and not just
170        * due to lcssa, licm itself too), though mostly only in cases when it
171        * can actually move things, so having to disable it is a pity.
172        * LLVMAddLICMPass(gallivm->passmgr);
173        */
174       LLVMAddReassociatePass(gallivm->passmgr);
175       LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
176 #if LLVM_VERSION_MAJOR <= 11
177       LLVMAddConstantPropagationPass(gallivm->passmgr);
178 #else
179       LLVMAddInstructionSimplifyPass(gallivm->passmgr);
180 #endif
181       LLVMAddInstructionCombiningPass(gallivm->passmgr);
182       LLVMAddGVNPass(gallivm->passmgr);
183    }
184    else {
185       /* We need at least this pass to prevent the backends to fail in
186        * unexpected ways.
187        */
188       LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
189    }
190 #if GALLIVM_HAVE_CORO == 1
191    LLVMAddCoroCleanupPass(gallivm->passmgr);
192 #endif
193 #endif
194    return true;
195 }
196 
197 /**
198  * Free gallivm object's LLVM allocations, but not any generated code
199  * nor the gallivm object itself.
200  */
201 void
gallivm_free_ir(struct gallivm_state * gallivm)202 gallivm_free_ir(struct gallivm_state *gallivm)
203 {
204 #if GALLIVM_USE_NEW_PASS == 0
205    if (gallivm->passmgr) {
206       LLVMDisposePassManager(gallivm->passmgr);
207    }
208 
209 #if GALLIVM_HAVE_CORO == 1
210    if (gallivm->cgpassmgr) {
211       LLVMDisposePassManager(gallivm->cgpassmgr);
212    }
213 #endif
214 #endif
215 
216    if (gallivm->engine) {
217       /* This will already destroy any associated module */
218       LLVMDisposeExecutionEngine(gallivm->engine);
219    } else if (gallivm->module) {
220       LLVMDisposeModule(gallivm->module);
221    }
222 
223    if (gallivm->cache) {
224       lp_free_objcache(gallivm->cache->jit_obj_cache);
225       free(gallivm->cache->data);
226    }
227    FREE(gallivm->module_name);
228 
229    if (gallivm->target) {
230       LLVMDisposeTargetData(gallivm->target);
231    }
232 
233    if (gallivm->builder)
234       LLVMDisposeBuilder(gallivm->builder);
235 
236    /* The LLVMContext should be owned by the parent of gallivm. */
237 
238    gallivm->engine = NULL;
239    gallivm->target = NULL;
240    gallivm->module = NULL;
241    gallivm->module_name = NULL;
242 #if GALLIVM_USE_NEW_PASS == 0
243 #if GALLIVM_HAVE_CORO == 1
244    gallivm->cgpassmgr = NULL;
245 #endif
246    gallivm->passmgr = NULL;
247 #endif
248    gallivm->context = NULL;
249    gallivm->builder = NULL;
250    gallivm->cache = NULL;
251 }
252 
253 
254 /**
255  * Free LLVM-generated code.  Should be done AFTER gallivm_free_ir().
256  */
257 static void
gallivm_free_code(struct gallivm_state * gallivm)258 gallivm_free_code(struct gallivm_state *gallivm)
259 {
260    assert(!gallivm->module);
261    assert(!gallivm->engine);
262    lp_free_generated_code(gallivm->code);
263    gallivm->code = NULL;
264    lp_free_memory_manager(gallivm->memorymgr);
265    gallivm->memorymgr = NULL;
266 }
267 
268 
269 static bool
init_gallivm_engine(struct gallivm_state * gallivm)270 init_gallivm_engine(struct gallivm_state *gallivm)
271 {
272    if (1) {
273       enum LLVM_CodeGenOpt_Level optlevel;
274       char *error = NULL;
275       int ret;
276 
277       if (gallivm_perf & GALLIVM_PERF_NO_OPT) {
278          optlevel = None;
279       }
280       else {
281          optlevel = Default;
282       }
283 
284       ret = lp_build_create_jit_compiler_for_module(&gallivm->engine,
285                                                     &gallivm->code,
286                                                     gallivm->cache,
287                                                     gallivm->module,
288                                                     gallivm->memorymgr,
289                                                     (unsigned) optlevel,
290                                                     &error);
291       if (ret) {
292          _debug_printf("%s\n", error);
293          LLVMDisposeMessage(error);
294          goto fail;
295       }
296    }
297 
298    if (0) {
299        /*
300         * Dump the data layout strings.
301         */
302 
303        LLVMTargetDataRef target = LLVMGetExecutionEngineTargetData(gallivm->engine);
304        char *data_layout;
305        char *engine_data_layout;
306 
307        data_layout = LLVMCopyStringRepOfTargetData(gallivm->target);
308        engine_data_layout = LLVMCopyStringRepOfTargetData(target);
309 
310        if (1) {
311           debug_printf("module target data = %s\n", data_layout);
312           debug_printf("engine target data = %s\n", engine_data_layout);
313        }
314 
315        free(data_layout);
316        free(engine_data_layout);
317    }
318 
319    return true;
320 
321 fail:
322    return false;
323 }
324 
325 
326 /**
327  * Allocate gallivm LLVM objects.
328  * \return  TRUE for success, FALSE for failure
329  */
330 static bool
init_gallivm_state(struct gallivm_state * gallivm,const char * name,LLVMContextRef context,struct lp_cached_code * cache)331 init_gallivm_state(struct gallivm_state *gallivm, const char *name,
332                    LLVMContextRef context, struct lp_cached_code *cache)
333 {
334    assert(!gallivm->context);
335    assert(!gallivm->module);
336 
337    if (!lp_build_init())
338       return false;
339 
340    gallivm->context = context;
341    gallivm->cache = cache;
342    if (!gallivm->context)
343       goto fail;
344 
345    gallivm->module_name = NULL;
346    if (name) {
347       size_t size = strlen(name) + 1;
348       gallivm->module_name = MALLOC(size);
349       if (gallivm->module_name) {
350          memcpy(gallivm->module_name, name, size);
351       }
352    }
353 
354    gallivm->module = LLVMModuleCreateWithNameInContext(name,
355                                                        gallivm->context);
356    if (!gallivm->module)
357       goto fail;
358 
359 #if DETECT_ARCH_X86
360    lp_set_module_stack_alignment_override(gallivm->module, 4);
361 #endif
362 
363    gallivm->builder = LLVMCreateBuilderInContext(gallivm->context);
364    if (!gallivm->builder)
365       goto fail;
366 
367    gallivm->memorymgr = lp_get_default_memory_manager();
368    if (!gallivm->memorymgr)
369       goto fail;
370 
371    /* FIXME: MC-JIT only allows compiling one module at a time, and it must be
372     * complete when MC-JIT is created. So defer the MC-JIT engine creation for
373     * now.
374     */
375 
376    /*
377     * MC-JIT engine compiles the module immediately on creation, so we can't
378     * obtain the target data from it.  Instead we create a target data layout
379     * from a string.
380     *
381     * The produced layout strings are not precisely the same, but should make
382     * no difference for the kind of optimization passes we run.
383     *
384     * For reference this is the layout string on x64:
385     *
386     *   e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64
387     *
388     * See also:
389     * - http://llvm.org/docs/LangRef.html#datalayout
390     */
391 
392    {
393       const unsigned pointer_size = 8 * sizeof(void *);
394       char layout[512];
395       snprintf(layout, sizeof layout, "%c-p:%u:%u:%u-i64:64:64-a0:0:%u-s0:%u:%u",
396 #if UTIL_ARCH_LITTLE_ENDIAN
397                     'e', // little endian
398 #else
399                     'E', // big endian
400 #endif
401                     pointer_size, pointer_size, pointer_size, // pointer size, abi alignment, preferred alignment
402                     pointer_size, // aggregate preferred alignment
403                     pointer_size, pointer_size); // stack objects abi alignment, preferred alignment
404 
405       gallivm->target = LLVMCreateTargetData(layout);
406       if (!gallivm->target) {
407          return false;
408       }
409    }
410 
411    if (!create_pass_manager(gallivm))
412       goto fail;
413 
414    lp_build_coro_declare_malloc_hooks(gallivm);
415    return true;
416 
417 fail:
418    gallivm_free_ir(gallivm);
419    gallivm_free_code(gallivm);
420    return false;
421 }
422 
423 unsigned
lp_build_init_native_width(void)424 lp_build_init_native_width(void)
425 {
426    // Default to 256 until we're confident llvmpipe with 512 is as correct and not slower than 256
427    lp_native_vector_width = MIN2(util_get_cpu_caps()->max_vector_bits, 256);
428    assert(lp_native_vector_width);
429 
430    lp_native_vector_width = debug_get_num_option("LP_NATIVE_VECTOR_WIDTH", lp_native_vector_width);
431    assert(lp_native_vector_width);
432 
433    return lp_native_vector_width;
434 }
435 
436 bool
lp_build_init(void)437 lp_build_init(void)
438 {
439    lp_build_init_native_width();
440    if (gallivm_initialized)
441       return true;
442 
443 
444    /* LLVMLinkIn* are no-ops at runtime.  They just ensure the respective
445     * component is linked at buildtime, which is sufficient for its static
446     * constructors to be called at load time.
447     */
448    LLVMLinkInMCJIT();
449 
450    gallivm_debug = debug_get_option_gallivm_debug();
451 
452    gallivm_perf = debug_get_flags_option("GALLIVM_PERF", lp_bld_perf_flags, 0 );
453 
454    lp_set_target_options();
455 
456 #if DETECT_ARCH_PPC_64
457    /* Set the NJ bit in VSCR to 0 so denormalized values are handled as
458     * specified by IEEE standard (PowerISA 2.06 - Section 6.3). This guarantees
459     * that some rounding and half-float to float handling does not round
460     * incorrectly to 0.
461     * XXX: should eventually follow same logic on all platforms.
462     * Right now denorms get explicitly disabled (but elsewhere) for x86,
463     * whereas ppc64 explicitly enables them...
464     */
465    if (util_get_cpu_caps()->has_altivec) {
466       unsigned short mask[] = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
467                                 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF };
468       __asm (
469         "mfvscr %%v1\n"
470         "vand   %0,%%v1,%0\n"
471         "mtvscr %0"
472         :
473         : "r" (*mask)
474       );
475    }
476 #endif
477 
478    gallivm_initialized = true;
479 
480    return true;
481 }
482 
483 
484 
485 /**
486  * Create a new gallivm_state object.
487  */
488 struct gallivm_state *
gallivm_create(const char * name,LLVMContextRef context,struct lp_cached_code * cache)489 gallivm_create(const char *name, LLVMContextRef context,
490                struct lp_cached_code *cache)
491 {
492    struct gallivm_state *gallivm;
493 
494    gallivm = CALLOC_STRUCT(gallivm_state);
495    if (gallivm) {
496       if (!init_gallivm_state(gallivm, name, context, cache)) {
497          FREE(gallivm);
498          gallivm = NULL;
499       }
500    }
501 
502    assert(gallivm != NULL);
503    return gallivm;
504 }
505 
506 
507 /**
508  * Destroy a gallivm_state object.
509  */
510 void
gallivm_destroy(struct gallivm_state * gallivm)511 gallivm_destroy(struct gallivm_state *gallivm)
512 {
513    gallivm_free_ir(gallivm);
514    gallivm_free_code(gallivm);
515    FREE(gallivm);
516 }
517 
518 
519 /**
520  * Validate a function.
521  * Verification is only done with debug builds.
522  */
523 void
gallivm_verify_function(struct gallivm_state * gallivm,LLVMValueRef func)524 gallivm_verify_function(struct gallivm_state *gallivm,
525                         LLVMValueRef func)
526 {
527    /* Verify the LLVM IR.  If invalid, dump and abort */
528 #ifdef DEBUG
529    if (LLVMVerifyFunction(func, LLVMPrintMessageAction)) {
530       lp_debug_dump_value(func);
531       assert(0);
532       return;
533    }
534 #endif
535 
536    if (gallivm_debug & GALLIVM_DEBUG_IR) {
537       /* Print the LLVM IR to stderr */
538       lp_debug_dump_value(func);
539       debug_printf("\n");
540    }
541 }
542 
lp_init_clock_hook(struct gallivm_state * gallivm)543 void lp_init_clock_hook(struct gallivm_state *gallivm)
544 {
545    if (gallivm->get_time_hook)
546       return;
547 
548    LLVMTypeRef get_time_type = LLVMFunctionType(LLVMInt64TypeInContext(gallivm->context), NULL, 0, 1);
549    gallivm->get_time_hook = LLVMAddFunction(gallivm->module, "get_time_hook", get_time_type);
550 }
551 
552 /**
553  * Compile a module.
554  * This does IR optimization on all functions in the module.
555  */
556 void
gallivm_compile_module(struct gallivm_state * gallivm)557 gallivm_compile_module(struct gallivm_state *gallivm)
558 {
559    int64_t time_begin = 0;
560 
561    assert(!gallivm->compiled);
562 
563    if (gallivm->builder) {
564       LLVMDisposeBuilder(gallivm->builder);
565       gallivm->builder = NULL;
566    }
567 
568    LLVMSetDataLayout(gallivm->module, "");
569    assert(!gallivm->engine);
570    if (!init_gallivm_engine(gallivm)) {
571       assert(0);
572    }
573    assert(gallivm->engine);
574 
575    if (gallivm->cache && gallivm->cache->data_size) {
576       goto skip_cached;
577    }
578 
579    /* Dump bitcode to a file */
580    if (gallivm_debug & GALLIVM_DEBUG_DUMP_BC) {
581       char filename[256];
582       assert(gallivm->module_name);
583       snprintf(filename, sizeof(filename), "ir_%s.bc", gallivm->module_name);
584       LLVMWriteBitcodeToFile(gallivm->module, filename);
585       debug_printf("%s written\n", filename);
586       debug_printf("Invoke as \"opt %s %s | llc -O%d %s%s\"\n",
587                    gallivm_perf & GALLIVM_PERF_NO_OPT ? "-mem2reg" :
588                    "-sroa -early-cse -simplifycfg -reassociate "
589                    "-mem2reg -constprop -instcombine -gvn",
590                    filename, gallivm_perf & GALLIVM_PERF_NO_OPT ? 0 : 2,
591                    "[-mcpu=<-mcpu option>] ",
592                    "[-mattr=<-mattr option(s)>]");
593    }
594 
595    if (gallivm_debug & GALLIVM_DEBUG_PERF)
596       time_begin = os_time_get();
597 
598 #if GALLIVM_USE_NEW_PASS == 1
599    char passes[1024];
600    passes[0] = 0;
601 
602    /*
603     * there should be some way to combine these two pass runs but I'm not seeing it,
604     * at the time of writing.
605     */
606    strcpy(passes, "default<O0>");
607 
608    LLVMPassBuilderOptionsRef opts = LLVMCreatePassBuilderOptions();
609    LLVMRunPasses(gallivm->module, passes, LLVMGetExecutionEngineTargetMachine(gallivm->engine), opts);
610 
611    if (!(gallivm_perf & GALLIVM_PERF_NO_OPT))
612       strcpy(passes, "sroa,early-cse,simplifycfg,reassociate,mem2reg,instsimplify,instcombine");
613    else
614       strcpy(passes, "mem2reg");
615 
616    LLVMRunPasses(gallivm->module, passes, LLVMGetExecutionEngineTargetMachine(gallivm->engine), opts);
617    LLVMDisposePassBuilderOptions(opts);
618 #else
619 #if GALLIVM_HAVE_CORO == 1
620    LLVMRunPassManager(gallivm->cgpassmgr, gallivm->module);
621 #endif
622    /* Run optimization passes */
623    LLVMInitializeFunctionPassManager(gallivm->passmgr);
624    LLVMValueRef func;
625    func = LLVMGetFirstFunction(gallivm->module);
626    while (func) {
627       if (0) {
628          debug_printf("optimizing func %s...\n", LLVMGetValueName(func));
629       }
630 
631    /* Disable frame pointer omission on debug/profile builds */
632    /* XXX: And workaround http://llvm.org/PR21435 */
633 #if defined(DEBUG) || defined(PROFILE) || DETECT_ARCH_X86 || DETECT_ARCH_X86_64
634       LLVMAddTargetDependentFunctionAttr(func, "no-frame-pointer-elim", "true");
635       LLVMAddTargetDependentFunctionAttr(func, "no-frame-pointer-elim-non-leaf", "true");
636 #endif
637 
638       LLVMRunFunctionPassManager(gallivm->passmgr, func);
639       func = LLVMGetNextFunction(func);
640    }
641    LLVMFinalizeFunctionPassManager(gallivm->passmgr);
642 #endif
643    if (gallivm_debug & GALLIVM_DEBUG_PERF) {
644       int64_t time_end = os_time_get();
645       int time_msec = (int)((time_end - time_begin) / 1000);
646       assert(gallivm->module_name);
647       debug_printf("optimizing module %s took %d msec\n",
648                    gallivm->module_name, time_msec);
649    }
650 
651    /* Setting the module's DataLayout to an empty string will cause the
652     * ExecutionEngine to copy to the DataLayout string from its target machine
653     * to the module.  As of LLVM 3.8 the module and the execution engine are
654     * required to have the same DataLayout.
655     *
656     * We must make sure we do this after running the optimization passes,
657     * because those passes need a correct datalayout string.  For example, if
658     * those optimization passes see an empty datalayout, they will assume this
659     * is a little endian target and will do optimizations that break big endian
660     * machines.
661     *
662     * TODO: This is just a temporary work-around.  The correct solution is for
663     * gallivm_init_state() to create a TargetMachine and pull the DataLayout
664     * from there.  Currently, the TargetMachine used by llvmpipe is being
665     * implicitly created by the EngineBuilder in
666     * lp_build_create_jit_compiler_for_module()
667     */
668  skip_cached:
669 
670    ++gallivm->compiled;
671 
672    lp_init_printf_hook(gallivm);
673    LLVMAddGlobalMapping(gallivm->engine, gallivm->debug_printf_hook, debug_printf);
674 
675    lp_init_clock_hook(gallivm);
676    LLVMAddGlobalMapping(gallivm->engine, gallivm->get_time_hook, os_time_get_nano);
677 
678    lp_build_coro_add_malloc_hooks(gallivm);
679 
680    if (gallivm_debug & GALLIVM_DEBUG_ASM) {
681       LLVMValueRef llvm_func = LLVMGetFirstFunction(gallivm->module);
682 
683       while (llvm_func) {
684          /*
685           * Need to filter out functions which don't have an implementation,
686           * such as the intrinsics. May not be sufficient in case of IPO?
687           * LLVMGetPointerToGlobal() will abort otherwise.
688           */
689          if (!LLVMIsDeclaration(llvm_func)) {
690             void *func_code = LLVMGetPointerToGlobal(gallivm->engine, llvm_func);
691             lp_disassemble(llvm_func, func_code);
692          }
693          llvm_func = LLVMGetNextFunction(llvm_func);
694       }
695    }
696 
697 #if defined(PROFILE)
698    {
699       LLVMValueRef llvm_func = LLVMGetFirstFunction(gallivm->module);
700 
701       while (llvm_func) {
702          if (!LLVMIsDeclaration(llvm_func)) {
703             void *func_code = LLVMGetPointerToGlobal(gallivm->engine, llvm_func);
704             lp_profile(llvm_func, func_code);
705          }
706          llvm_func = LLVMGetNextFunction(llvm_func);
707       }
708    }
709 #endif
710 }
711 
712 
713 
714 func_pointer
gallivm_jit_function(struct gallivm_state * gallivm,LLVMValueRef func)715 gallivm_jit_function(struct gallivm_state *gallivm,
716                      LLVMValueRef func)
717 {
718    void *code;
719    func_pointer jit_func;
720    int64_t time_begin = 0;
721 
722    assert(gallivm->compiled);
723    assert(gallivm->engine);
724 
725    if (gallivm_debug & GALLIVM_DEBUG_PERF)
726       time_begin = os_time_get();
727 
728    code = LLVMGetPointerToGlobal(gallivm->engine, func);
729    assert(code);
730    jit_func = pointer_to_func(code);
731 
732    if (gallivm_debug & GALLIVM_DEBUG_PERF) {
733       int64_t time_end = os_time_get();
734       int time_msec = (int)(time_end - time_begin) / 1000;
735       debug_printf("   jitting func %s took %d msec\n",
736                    LLVMGetValueName(func), time_msec);
737    }
738 
739    return jit_func;
740 }
741 
gallivm_get_perf_flags(void)742 unsigned gallivm_get_perf_flags(void)
743 {
744    return gallivm_perf;
745 }
746