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 #include "util/u_debug.h"
29 #include "util/u_cpu_detect.h"
30 #include "lp_bld.h"
31 #include "lp_bld_debug.h"
32 #include "lp_bld_init.h"
33 #include "lp_bld_type.h"
34
35 #include <llvm-c/Core.h>
36 #include <llvm-c/Analysis.h>
37
38 unsigned gallivm_perf = 0;
39
40 static const struct debug_named_value lp_bld_perf_flags[] = {
41 { "brilinear", GALLIVM_PERF_BRILINEAR, "enable brilinear optimization" },
42 { "rho_approx", GALLIVM_PERF_RHO_APPROX, "enable rho_approx optimization" },
43 { "no_quad_lod", GALLIVM_PERF_NO_QUAD_LOD, "disable quad_lod optimization" },
44 { "no_aos_sampling", GALLIVM_PERF_NO_AOS_SAMPLING, "disable aos sampling optimization" },
45 { "nopt", GALLIVM_PERF_NO_OPT, "disable optimization passes to speed up shader compilation" },
46 DEBUG_NAMED_VALUE_END
47 };
48
49 unsigned gallivm_debug = 0;
50
51 static const struct debug_named_value lp_bld_debug_flags[] = {
52 { "tgsi", GALLIVM_DEBUG_TGSI, NULL },
53 { "ir", GALLIVM_DEBUG_IR, NULL },
54 { "asm", GALLIVM_DEBUG_ASM, NULL },
55 { "perf", GALLIVM_DEBUG_PERF, NULL },
56 { "gc", GALLIVM_DEBUG_GC, NULL },
57 /* Don't allow setting DUMP_BC for release builds, since writing the files may be an issue with setuid. */
58 #if MESA_DEBUG
59 { "dumpbc", GALLIVM_DEBUG_DUMP_BC, NULL },
60 #endif
61 DEBUG_NAMED_VALUE_END
62 };
63
64 DEBUG_GET_ONCE_FLAGS_OPTION(gallivm_debug, "GALLIVM_DEBUG", lp_bld_debug_flags, 0)
65
66 unsigned lp_native_vector_width;
67
68 unsigned
lp_build_init_native_width(void)69 lp_build_init_native_width(void)
70 {
71 // Default to 256 until we're confident llvmpipe with 512 is as correct and not slower than 256
72 lp_native_vector_width = MIN2(util_get_cpu_caps()->max_vector_bits, 256);
73 assert(lp_native_vector_width);
74
75 lp_native_vector_width = debug_get_num_option("LP_NATIVE_VECTOR_WIDTH", lp_native_vector_width);
76 assert(lp_native_vector_width);
77
78 return lp_native_vector_width;
79 }
80
81 void
lp_init_env_options(void)82 lp_init_env_options(void)
83 {
84 gallivm_debug = debug_get_option_gallivm_debug();
85
86 gallivm_perf = debug_get_flags_option("GALLIVM_PERF", lp_bld_perf_flags, 0 );
87 }
88
89 unsigned
gallivm_get_perf_flags(void)90 gallivm_get_perf_flags(void)
91 {
92 return gallivm_perf;
93 }
94
95 void
lp_init_clock_hook(struct gallivm_state * gallivm)96 lp_init_clock_hook(struct gallivm_state *gallivm)
97 {
98 if (gallivm->get_time_hook)
99 return;
100
101 LLVMTypeRef get_time_type = LLVMFunctionType(LLVMInt64TypeInContext(gallivm->context), NULL, 0, 1);
102 gallivm->get_time_hook = LLVMAddFunction(gallivm->module, "get_time_hook", get_time_type);
103 }
104
105 /**
106 * Validate a function.
107 * Verification is only done with debug builds.
108 */
109 void
gallivm_verify_function(struct gallivm_state * gallivm,LLVMValueRef func)110 gallivm_verify_function(struct gallivm_state *gallivm,
111 LLVMValueRef func)
112 {
113 /* Verify the LLVM IR. If invalid, dump and abort */
114 #if MESA_DEBUG
115 if (LLVMVerifyFunction(func, LLVMPrintMessageAction)) {
116 lp_debug_dump_value(func);
117 assert(0);
118 return;
119 }
120 #endif
121
122 if (gallivm_debug & GALLIVM_DEBUG_IR) {
123 /* Print the LLVM IR to stderr */
124 lp_debug_dump_value(func);
125 debug_printf("\n");
126 }
127 }
128