}
-ast_struct_specifier::ast_struct_specifier(void *lin_ctx, const char *identifier,
+ast_struct_specifier::ast_struct_specifier(const char *identifier,
ast_declarator_list *declarator_list)
+ : name(identifier), layout(NULL), declarations(), is_declaration(true),
+ type(NULL)
{
- if (identifier == NULL) {
- /* All anonymous structs have the same name. This simplifies matching of
- * globals whose type is an unnamed struct.
- *
- * It also avoids a memory leak when the same shader is compiled over and
- * over again.
- */
- identifier = "#anon_struct";
- }
- name = identifier;
this->declarations.push_degenerate_list_at_head(&declarator_list->link);
- is_declaration = true;
- layout = NULL;
- type = NULL;
}
void ast_subroutine_list::print(void) const
shader->bound_image = state->bound_image_specified;
}
+/* src can be NULL if only the symbols found in the exec_list should be
+ * copied
+ */
+void
+_mesa_glsl_copy_symbols_from_table(struct exec_list *shader_ir,
+ struct glsl_symbol_table *src,
+ struct glsl_symbol_table *dest)
+{
+ foreach_in_list (ir_instruction, ir, shader_ir) {
+ switch (ir->ir_type) {
+ case ir_type_function:
+ dest->add_function((ir_function *) ir);
+ break;
+ case ir_type_variable: {
+ ir_variable *const var = (ir_variable *) ir;
+
+ if (var->data.mode != ir_var_temporary)
+ dest->add_variable(var);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (src != NULL) {
+ /* Explicitly copy the gl_PerVertex interface definitions because these
+ * are needed to check they are the same during the interstage link.
+ * They can’t necessarily be found via the exec_list because the members
+ * might not be referenced. The GL spec still requires that they match
+ * in that case.
+ */
+ const glsl_type *iface =
+ src->get_interface("gl_PerVertex", ir_var_shader_in);
+ if (iface)
+ dest->add_interface(iface->name, iface, ir_var_shader_in);
+
+ iface = src->get_interface("gl_PerVertex", ir_var_shader_out);
+ if (iface)
+ dest->add_interface(iface->name, iface, ir_var_shader_out);
+ }
+}
+
extern "C" {
static void
static void
opt_shader_and_create_symbol_table(struct gl_context *ctx,
+ struct glsl_symbol_table *source_symbols,
struct gl_shader *shader)
{
assert(shader->CompileStatus != compile_failure &&
* We don't have to worry about types or interface-types here because those
* are fly-weights that are looked up by glsl_type.
*/
- foreach_in_list (ir_instruction, ir, shader->ir) {
- switch (ir->ir_type) {
- case ir_type_function:
- shader->symbols->add_function((ir_function *) ir);
- break;
- case ir_type_variable: {
- ir_variable *const var = (ir_variable *) ir;
-
- if (var->data.mode != ir_var_temporary)
- shader->symbols->add_variable(var);
- break;
- }
- default:
- break;
- }
- }
-
- _mesa_glsl_initialize_derived_variables(ctx, shader);
+ _mesa_glsl_copy_symbols_from_table(shader->ir, source_symbols,
+ shader->symbols);
}
void
return;
if (shader->CompileStatus == compiled_no_opts) {
- opt_shader_and_create_symbol_table(ctx, shader);
+ opt_shader_and_create_symbol_table(ctx,
+ NULL, /* source_symbols */
+ shader);
shader->CompileStatus = compile_success;
return;
}
lower_subroutine(shader->ir, state);
if (!ctx->Cache || force_recompile)
- opt_shader_and_create_symbol_table(ctx, shader);
+ opt_shader_and_create_symbol_table(ctx, state->symbols, shader);
else {
reparent_ir(shader->ir, shader->ir);
shader->CompileStatus = compiled_no_opts;
options->EmitNoCont, options->EmitNoLoops);
OPT(do_vec_index_to_swizzle, ir);
OPT(lower_vector_insert, ir, false);
- OPT(do_swizzle_swizzle, ir);
- OPT(do_noop_swizzle, ir);
+ OPT(optimize_swizzles, ir);
OPT(optimize_split_arrays, ir, linked);
OPT(optimize_redundant_jumps, ir);
if (options->MaxUnrollIterations) {
loop_state *ls = analyze_loop_variables(ir);
if (ls->loop_found) {
- OPT(unroll_loops, ir, ls, options);
+ bool loop_progress = unroll_loops(ir, ls, options);
+ while (loop_progress) {
+ loop_progress = false;
+ loop_progress |= do_constant_propagation(ir);
+ loop_progress |= do_if_simplification(ir);
+ }
+ progress |= loop_progress;
}
delete ls;
}