From: Victor Chiletto vchiletto@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 6 ---- libs/vkd3d-shader/hlsl_codegen.c | 50 ++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 2372af026..9c2339124 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -527,12 +527,6 @@ static void resolve_loop_continue(struct hlsl_ctx *ctx, struct hlsl_block *block } list_move_before(&instr->entry, &cond_block.instrs); } - else if (type == LOOP_FOR) - { - if (!hlsl_clone_block(ctx, &cond_block, iter)) - return; - list_move_before(&instr->entry, &cond_block.instrs); - } jump->type = HLSL_IR_JUMP_CONTINUE; } } diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 87c0081ec..8a94b4b8a 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2394,6 +2394,55 @@ static bool remove_trivial_conditional_branches(struct hlsl_ctx *ctx, struct hls return true; }
+ +static void transform_insert_continue_iter_blocks(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_block *iter) +{ + struct hlsl_ir_node *node; + + LIST_FOR_EACH_ENTRY(node, &block->instrs, struct hlsl_ir_node, entry) + { + switch (node->type) + { + case HLSL_IR_LOOP: + { + struct hlsl_ir_loop *loop = hlsl_ir_loop(node); + transform_insert_continue_iter_blocks(ctx, &loop->body, &loop->iter); + break; + } + case HLSL_IR_IF: + { + struct hlsl_ir_if *iff = hlsl_ir_if(node); + transform_insert_continue_iter_blocks(ctx, &iff->then_block, iter); + transform_insert_continue_iter_blocks(ctx, &iff->else_block, iter); + break; + } + case HLSL_IR_SWITCH: + { + struct hlsl_ir_switch *s = hlsl_ir_switch(node); + struct hlsl_ir_switch_case *c; + + LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) + transform_insert_continue_iter_blocks(ctx, &c->body, iter); + + break; + } + case HLSL_IR_JUMP: + { + struct hlsl_ir_jump *jump = hlsl_ir_jump(node); + if (jump->type == HLSL_IR_JUMP_CONTINUE && !list_empty(&iter->instrs)) + { + struct hlsl_block clone; + hlsl_clone_block(ctx, &clone, iter); + list_move_before(&node->entry, &clone.instrs); + } + break; + } + default: + break; + } + } +} + static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_switch_case *c, *def = NULL; @@ -5523,6 +5572,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL); } while (progress); + transform_insert_continue_iter_blocks(ctx, body, NULL); remove_unreachable_code(ctx, body); hlsl_transform_ir(ctx, normalize_switch_cases, body, NULL);