2 * Copyright © 2011 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
25 * \file test_optpass.cpp
27 * Standalone test for optimization passes.
29 * This file provides the "optpass" command for the standalone
30 * glsl_test app. It accepts either GLSL or high-level IR as input,
31 * and performs the optimiation passes specified on the command line.
32 * It outputs the IR, both before and after optimiations.
41 #include "ir_optimization.h"
42 #include "ir_print_visitor.h"
44 #include "ir_reader.h"
45 #include "standalone_scaffolding.h"
49 static string
read_stdin_to_eof()
57 do_optimization(struct exec_list
*ir
, const char *optimization
)
65 if (sscanf(optimization
, "do_common_optimization ( %d , %d ) ",
66 &int_0
, &int_1
) == 2) {
67 return do_common_optimization(ir
, int_0
!= 0, false, int_1
);
68 } else if (strcmp(optimization
, "do_algebraic") == 0) {
69 return do_algebraic(ir
);
70 } else if (strcmp(optimization
, "do_constant_folding") == 0) {
71 return do_constant_folding(ir
);
72 } else if (strcmp(optimization
, "do_constant_variable") == 0) {
73 return do_constant_variable(ir
);
74 } else if (strcmp(optimization
, "do_constant_variable_unlinked") == 0) {
75 return do_constant_variable_unlinked(ir
);
76 } else if (strcmp(optimization
, "do_copy_propagation") == 0) {
77 return do_copy_propagation(ir
);
78 } else if (strcmp(optimization
, "do_copy_propagation_elements") == 0) {
79 return do_copy_propagation_elements(ir
);
80 } else if (strcmp(optimization
, "do_constant_propagation") == 0) {
81 return do_constant_propagation(ir
);
82 } else if (strcmp(optimization
, "do_dead_code") == 0) {
83 return do_dead_code(ir
, false);
84 } else if (strcmp(optimization
, "do_dead_code_local") == 0) {
85 return do_dead_code_local(ir
);
86 } else if (strcmp(optimization
, "do_dead_code_unlinked") == 0) {
87 return do_dead_code_unlinked(ir
);
88 } else if (strcmp(optimization
, "do_dead_functions") == 0) {
89 return do_dead_functions(ir
);
90 } else if (strcmp(optimization
, "do_function_inlining") == 0) {
91 return do_function_inlining(ir
);
92 } else if (sscanf(optimization
,
93 "do_lower_jumps ( %d , %d , %d , %d , %d ) ",
94 &int_0
, &int_1
, &int_2
, &int_3
, &int_4
) == 5) {
95 return do_lower_jumps(ir
, int_0
!= 0, int_1
!= 0, int_2
!= 0,
96 int_3
!= 0, int_4
!= 0);
97 } else if (strcmp(optimization
, "do_lower_texture_projection") == 0) {
98 return do_lower_texture_projection(ir
);
99 } else if (strcmp(optimization
, "do_if_simplification") == 0) {
100 return do_if_simplification(ir
);
101 } else if (strcmp(optimization
, "do_discard_simplification") == 0) {
102 return do_discard_simplification(ir
);
103 } else if (sscanf(optimization
, "lower_if_to_cond_assign ( %d ) ",
105 return lower_if_to_cond_assign(ir
, int_0
);
106 } else if (strcmp(optimization
, "do_mat_op_to_vec") == 0) {
107 return do_mat_op_to_vec(ir
);
108 } else if (strcmp(optimization
, "do_noop_swizzle") == 0) {
109 return do_noop_swizzle(ir
);
110 } else if (strcmp(optimization
, "do_structure_splitting") == 0) {
111 return do_structure_splitting(ir
);
112 } else if (strcmp(optimization
, "do_swizzle_swizzle") == 0) {
113 return do_swizzle_swizzle(ir
);
114 } else if (strcmp(optimization
, "do_tree_grafting") == 0) {
115 return do_tree_grafting(ir
);
116 } else if (strcmp(optimization
, "do_vec_index_to_cond_assign") == 0) {
117 return do_vec_index_to_cond_assign(ir
);
118 } else if (strcmp(optimization
, "do_vec_index_to_swizzle") == 0) {
119 return do_vec_index_to_swizzle(ir
);
120 } else if (strcmp(optimization
, "lower_discard") == 0) {
121 return lower_discard(ir
);
122 } else if (sscanf(optimization
, "lower_instructions ( %d ) ",
124 return lower_instructions(ir
, int_0
);
125 } else if (strcmp(optimization
, "lower_noise") == 0) {
126 return lower_noise(ir
);
127 } else if (sscanf(optimization
, "lower_variable_index_to_cond_assign "
128 "( %d , %d , %d , %d ) ", &int_0
, &int_1
, &int_2
,
130 return lower_variable_index_to_cond_assign(ir
, int_0
!= 0, int_1
!= 0,
131 int_2
!= 0, int_3
!= 0);
132 } else if (sscanf(optimization
, "lower_quadop_vector ( %d ) ",
134 return lower_quadop_vector(ir
, int_0
!= 0);
135 } else if (strcmp(optimization
, "optimize_redundant_jumps") == 0) {
136 return optimize_redundant_jumps(ir
);
138 printf("Unrecognized optimization %s\n", optimization
);
145 do_optimization_passes(struct exec_list
*ir
, char **optimizations
,
146 int num_optimizations
, bool quiet
)
148 GLboolean overall_progress
= false;
150 for (int i
= 0; i
< num_optimizations
; ++i
) {
151 const char *optimization
= optimizations
[i
];
153 printf("*** Running optimization %s...", optimization
);
155 GLboolean progress
= do_optimization(ir
, optimization
);
157 printf("%s\n", progress
? "progress" : "no progress");
159 validate_ir_tree(ir
);
161 overall_progress
= overall_progress
|| progress
;
164 return overall_progress
;
167 int test_optpass(int argc
, char **argv
)
169 int input_format_ir
= 0; /* 0=glsl, 1=ir */
171 int shader_type
= GL_VERTEX_SHADER
;
174 const struct option optpass_opts
[] = {
175 { "input-ir", no_argument
, &input_format_ir
, 1 },
176 { "input-glsl", no_argument
, &input_format_ir
, 0 },
177 { "loop", no_argument
, &loop
, 1 },
178 { "vertex-shader", no_argument
, &shader_type
, GL_VERTEX_SHADER
},
179 { "fragment-shader", no_argument
, &shader_type
, GL_FRAGMENT_SHADER
},
180 { "quiet", no_argument
, &quiet
, 1 },
186 while ((c
= getopt_long(argc
, argv
, "", optpass_opts
, &idx
)) != -1) {
188 printf("*** usage: %s optpass <optimizations> <options>\n", argv
[0]);
190 printf("Possible options are:\n");
191 printf(" --input-ir: input format is IR\n");
192 printf(" --input-glsl: input format is GLSL (the default)\n");
193 printf(" --loop: run optimizations repeatedly until no progress\n");
194 printf(" --vertex-shader: test with a vertex shader (the default)\n");
195 printf(" --fragment-shader: test with a fragment shader\n");
200 struct gl_context local_ctx
;
201 struct gl_context
*ctx
= &local_ctx
;
202 initialize_context_to_defaults(ctx
, API_OPENGL
);
204 ctx
->Driver
.NewShader
= _mesa_new_shader
;
206 struct gl_shader
*shader
= rzalloc(NULL
, struct gl_shader
);
207 shader
->Type
= shader_type
;
209 string input
= read_stdin_to_eof();
211 struct _mesa_glsl_parse_state
*state
212 = new(shader
) _mesa_glsl_parse_state(ctx
, shader
->Type
, shader
);
214 if (input_format_ir
) {
215 shader
->ir
= new(shader
) exec_list
;
216 _mesa_glsl_initialize_types(state
);
217 _mesa_glsl_read_ir(state
, shader
->ir
, input
.c_str(), true);
219 shader
->Source
= input
.c_str();
220 const char *source
= shader
->Source
;
221 state
->error
= preprocess(state
, &source
, &state
->info_log
,
222 state
->extensions
, ctx
->API
) != 0;
225 _mesa_glsl_lexer_ctor(state
, source
);
226 _mesa_glsl_parse(state
);
227 _mesa_glsl_lexer_dtor(state
);
230 shader
->ir
= new(shader
) exec_list
;
231 if (!state
->error
&& !state
->translation_unit
.is_empty())
232 _mesa_ast_to_hir(shader
->ir
, state
);
235 /* Print out the initial IR */
236 if (!state
->error
&& !quiet
) {
237 printf("*** pre-optimization IR:\n");
238 _mesa_print_ir(shader
->ir
, state
);
242 /* Optimization passes */
246 progress
= do_optimization_passes(shader
->ir
, &argv
[optind
],
247 argc
- optind
, quiet
!= 0);
248 } while (loop
&& progress
);
251 /* Print out the resulting IR */
254 printf("*** resulting IR:\n");
256 _mesa_print_ir(shader
->ir
, state
);
263 printf("*** error(s) occurred:\n");
264 printf("%s\n", state
->info_log
);