vkd3d-shader/hlsl: Remove loop_unrolling_find_unrollable_loop().

Since loop unrolling doesn't clone the entire program anymore, we can
express it as a hlsl_transform_ir() transform.
This commit is contained in:
Victor Chiletto 2024-10-14 11:42:09 -03:00 committed by Henri Verbeet
parent de3a365fea
commit 5d8448a44e
Notes: Henri Verbeet 2024-12-12 17:48:02 +01:00
Approved-by: Francisco Casas (@fcasas)
Approved-by: Elizabeth Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1053

View File

@ -10158,81 +10158,26 @@ fail:
return false;
}
/*
* loop_unrolling_find_unrollable_loop() is not the normal way to do things;
* normal passes simply iterate over the whole block and apply a transformation
* to every relevant instruction. However, loop unrolling can fail, and we want
* to leave the loop in its previous state in that case. That isn't a problem by
* itself, except that loop unrolling needs copy-prop in order to work properly,
* and copy-prop state at the time of the loop depends on the rest of the program
* up to that point. This means we need to clone the whole program, and at that
* point we have to search it again anyway to find the clone of the loop we were
* going to unroll.
*
* FIXME: Ideally we wouldn't clone the whole program; instead we would run copyprop
* up until the loop instruction, clone just that loop, then use copyprop again
* with the saved state after unrolling. However, copyprop currently isn't built
* for that yet [notably, it still relies on indices]. Note also this still doesn't
* really let us use transform_ir() anyway [since we don't have a good way to say
* "copyprop from the beginning of the program up to the instruction we're
* currently processing" from the callback]; we'd have to use a dedicated
* recursive function instead. */
static struct hlsl_ir_loop *loop_unrolling_find_unrollable_loop(struct hlsl_ctx *ctx, struct hlsl_block *block)
static bool unroll_loops(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, void *context)
{
struct hlsl_ir_node *instr;
struct hlsl_block *program = context;
struct hlsl_ir_loop *loop;
LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry)
{
switch (instr->type)
{
case HLSL_IR_LOOP:
{
struct hlsl_ir_loop *nested_loop;
struct hlsl_ir_loop *loop = hlsl_ir_loop(instr);
if (node->type != HLSL_IR_LOOP)
return true;
if ((nested_loop = loop_unrolling_find_unrollable_loop(ctx, &loop->body)))
return nested_loop;
loop = hlsl_ir_loop(node);
if (loop->unroll_type == HLSL_IR_LOOP_UNROLL || loop->unroll_type == HLSL_IR_LOOP_FORCE_UNROLL)
return loop;
if (loop->unroll_type != HLSL_IR_LOOP_UNROLL && loop->unroll_type != HLSL_IR_LOOP_FORCE_UNROLL)
return true;
break;
}
case HLSL_IR_IF:
{
struct hlsl_ir_loop *loop;
struct hlsl_ir_if *iff = hlsl_ir_if(instr);
if (!loop_unrolling_unroll_loop(ctx, program, loop))
loop->unroll_type = HLSL_IR_LOOP_FORCE_LOOP;
if ((loop = loop_unrolling_find_unrollable_loop(ctx, &iff->then_block)))
return loop;
if ((loop = loop_unrolling_find_unrollable_loop(ctx, &iff->else_block)))
return loop;
break;
}
case HLSL_IR_SWITCH:
{
struct hlsl_ir_switch *s = hlsl_ir_switch(instr);
struct hlsl_ir_switch_case *c;
struct hlsl_ir_loop *loop;
LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry)
{
if ((loop = loop_unrolling_find_unrollable_loop(ctx, &c->body)))
return loop;
}
break;
}
default:
break;
}
}
return NULL;
return true;
}
static void transform_unroll_loops(struct hlsl_ctx *ctx, struct hlsl_block *block)
static void loop_unrolling_execute(struct hlsl_ctx *ctx, struct hlsl_block *block)
{
bool progress;
@ -10245,16 +10190,7 @@ static void transform_unroll_loops(struct hlsl_ctx *ctx, struct hlsl_block *bloc
} while (progress);
hlsl_transform_ir(ctx, split_matrix_copies, block, NULL);
while (true)
{
struct hlsl_ir_loop *loop = NULL;
if (!(loop = loop_unrolling_find_unrollable_loop(ctx, block)))
return;
if (!loop_unrolling_unroll_loop(ctx, block, loop))
loop->unroll_type = HLSL_IR_LOOP_FORCE_LOOP;
}
hlsl_transform_ir(ctx, unroll_loops, block, block);
}
static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
@ -10503,7 +10439,7 @@ static void process_entry_function(struct hlsl_ctx *ctx,
hlsl_transform_ir(ctx, lower_discard_nz, body, NULL);
}
transform_unroll_loops(ctx, body);
loop_unrolling_execute(ctx, body);
hlsl_run_const_passes(ctx, body);
remove_unreachable_code(ctx, body);