From 3cb9e8dc3b330f18edb03697021fceaad1828038 Mon Sep 17 00:00:00 2001 From: Victor Chiletto Date: Tue, 20 Aug 2024 11:48:46 -0300 Subject: [PATCH] vkd3d-shader/hlsl: Explicitly track the copy propagation state stack. --- libs/vkd3d-shader/hlsl_codegen.c | 87 +++++++++++++++++++------------- 1 file changed, 53 insertions(+), 34 deletions(-) diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index e28f4512..59743612 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1359,8 +1359,8 @@ struct copy_propagation_var_def struct copy_propagation_state { - struct rb_tree var_defs; - struct copy_propagation_state *parent; + struct rb_tree *scope_var_defs; + size_t scope_count, scopes_capacity; }; static int copy_propagation_var_def_compare(const void *key, const struct rb_entry *entry) @@ -1382,6 +1382,38 @@ static void copy_propagation_var_def_destroy(struct rb_entry *entry, void *conte vkd3d_free(var_def); } +static size_t copy_propagation_push_scope(struct copy_propagation_state *state, struct hlsl_ctx *ctx) +{ + if (!(hlsl_array_reserve(ctx, (void **)&state->scope_var_defs, &state->scopes_capacity, + state->scope_count + 1, sizeof(*state->scope_var_defs)))) + return false; + + rb_init(&state->scope_var_defs[state->scope_count++], copy_propagation_var_def_compare); + + return state->scope_count; +} + +static size_t copy_propagation_pop_scope(struct copy_propagation_state *state) +{ + rb_destroy(&state->scope_var_defs[--state->scope_count], copy_propagation_var_def_destroy, NULL); + + return state->scope_count; +} + +static bool copy_propagation_state_init(struct copy_propagation_state *state, struct hlsl_ctx *ctx) +{ + memset(state, 0, sizeof(*state)); + + return copy_propagation_push_scope(state, ctx); +} + +static void copy_propagation_state_destroy(struct copy_propagation_state *state) +{ + while (copy_propagation_pop_scope(state)); + + vkd3d_free(state->scope_var_defs); +} + static struct copy_propagation_value *copy_propagation_get_value_at_time( struct copy_propagation_component_trace *trace, unsigned int time) { @@ -1399,9 +1431,10 @@ static struct copy_propagation_value *copy_propagation_get_value_at_time( static struct copy_propagation_value *copy_propagation_get_value(const struct copy_propagation_state *state, const struct hlsl_ir_var *var, unsigned int component, unsigned int time) { - for (; state; state = state->parent) + for (size_t i = state->scope_count - 1; i < state->scope_count; i--) { - struct rb_entry *entry = rb_get(&state->var_defs, var); + struct rb_tree *tree = &state->scope_var_defs[i]; + struct rb_entry *entry = rb_get(tree, var); if (entry) { struct copy_propagation_var_def *var_def = RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); @@ -1427,7 +1460,8 @@ static struct copy_propagation_value *copy_propagation_get_value(const struct co static struct copy_propagation_var_def *copy_propagation_create_var_def(struct hlsl_ctx *ctx, struct copy_propagation_state *state, struct hlsl_ir_var *var) { - struct rb_entry *entry = rb_get(&state->var_defs, var); + struct rb_tree *tree = &state->scope_var_defs[state->scope_count - 1]; + struct rb_entry *entry = rb_get(tree, var); struct copy_propagation_var_def *var_def; unsigned int component_count = hlsl_type_component_count(var->data_type); int res; @@ -1440,7 +1474,7 @@ static struct copy_propagation_var_def *copy_propagation_create_var_def(struct h var_def->var = var; - res = rb_put(&state->var_defs, var, &var_def->entry); + res = rb_put(tree, var, &var_def->entry); VKD3D_ASSERT(!res); return var_def; @@ -1820,18 +1854,6 @@ static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_s } } -static void copy_propagation_state_init(struct hlsl_ctx *ctx, struct copy_propagation_state *state, - struct copy_propagation_state *parent) -{ - rb_init(&state->var_defs, copy_propagation_var_def_compare); - state->parent = parent; -} - -static void copy_propagation_state_destroy(struct copy_propagation_state *state) -{ - rb_destroy(&state->var_defs, copy_propagation_var_def_destroy, NULL); -} - static void copy_propagation_invalidate_from_block(struct hlsl_ctx *ctx, struct copy_propagation_state *state, struct hlsl_block *block, unsigned int time) { @@ -1900,16 +1922,15 @@ static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_b static bool copy_propagation_process_if(struct hlsl_ctx *ctx, struct hlsl_ir_if *iff, struct copy_propagation_state *state) { - struct copy_propagation_state inner_state; bool progress = false; - copy_propagation_state_init(ctx, &inner_state, state); - progress |= copy_propagation_transform_block(ctx, &iff->then_block, &inner_state); - copy_propagation_state_destroy(&inner_state); + copy_propagation_push_scope(state, ctx); + progress |= copy_propagation_transform_block(ctx, &iff->then_block, state); + copy_propagation_pop_scope(state); - copy_propagation_state_init(ctx, &inner_state, state); - progress |= copy_propagation_transform_block(ctx, &iff->else_block, &inner_state); - copy_propagation_state_destroy(&inner_state); + copy_propagation_push_scope(state, ctx); + progress |= copy_propagation_transform_block(ctx, &iff->else_block, state); + copy_propagation_pop_scope(state); /* Ideally we'd invalidate the outer state looking at what was * touched in the two inner states, but this doesn't work for @@ -1924,14 +1945,13 @@ static bool copy_propagation_process_if(struct hlsl_ctx *ctx, struct hlsl_ir_if static bool copy_propagation_process_loop(struct hlsl_ctx *ctx, struct hlsl_ir_loop *loop, struct copy_propagation_state *state) { - struct copy_propagation_state inner_state; bool progress = false; copy_propagation_invalidate_from_block(ctx, state, &loop->body, loop->node.index); - copy_propagation_state_init(ctx, &inner_state, state); - progress |= copy_propagation_transform_block(ctx, &loop->body, &inner_state); - copy_propagation_state_destroy(&inner_state); + copy_propagation_push_scope(state, ctx); + progress |= copy_propagation_transform_block(ctx, &loop->body, state); + copy_propagation_pop_scope(state); return progress; } @@ -1939,15 +1959,14 @@ static bool copy_propagation_process_loop(struct hlsl_ctx *ctx, struct hlsl_ir_l static bool copy_propagation_process_switch(struct hlsl_ctx *ctx, struct hlsl_ir_switch *s, struct copy_propagation_state *state) { - struct copy_propagation_state inner_state; struct hlsl_ir_switch_case *c; bool progress = false; LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) { - copy_propagation_state_init(ctx, &inner_state, state); - progress |= copy_propagation_transform_block(ctx, &c->body, &inner_state); - copy_propagation_state_destroy(&inner_state); + copy_propagation_push_scope(state, ctx); + progress |= copy_propagation_transform_block(ctx, &c->body, state); + copy_propagation_pop_scope(state); } LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) @@ -2015,7 +2034,7 @@ bool hlsl_copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *bloc index_instructions(block, 2); - copy_propagation_state_init(ctx, &state, NULL); + copy_propagation_state_init(&state, ctx); progress = copy_propagation_transform_block(ctx, block, &state);