mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
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:
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
@ -10158,81 +10158,26 @@ fail:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static bool unroll_loops(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, void *context)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
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)
|
if (node->type != HLSL_IR_LOOP)
|
||||||
{
|
return true;
|
||||||
switch (instr->type)
|
|
||||||
{
|
|
||||||
case HLSL_IR_LOOP:
|
|
||||||
{
|
|
||||||
struct hlsl_ir_loop *nested_loop;
|
|
||||||
struct hlsl_ir_loop *loop = hlsl_ir_loop(instr);
|
|
||||||
|
|
||||||
if ((nested_loop = loop_unrolling_find_unrollable_loop(ctx, &loop->body)))
|
loop = hlsl_ir_loop(node);
|
||||||
return nested_loop;
|
|
||||||
|
|
||||||
if (loop->unroll_type == HLSL_IR_LOOP_UNROLL || loop->unroll_type == HLSL_IR_LOOP_FORCE_UNROLL)
|
if (loop->unroll_type != HLSL_IR_LOOP_UNROLL && loop->unroll_type != HLSL_IR_LOOP_FORCE_UNROLL)
|
||||||
return loop;
|
return true;
|
||||||
|
|
||||||
break;
|
if (!loop_unrolling_unroll_loop(ctx, program, loop))
|
||||||
}
|
loop->unroll_type = HLSL_IR_LOOP_FORCE_LOOP;
|
||||||
case HLSL_IR_IF:
|
|
||||||
{
|
|
||||||
struct hlsl_ir_loop *loop;
|
|
||||||
struct hlsl_ir_if *iff = hlsl_ir_if(instr);
|
|
||||||
|
|
||||||
if ((loop = loop_unrolling_find_unrollable_loop(ctx, &iff->then_block)))
|
return true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
bool progress;
|
||||||
|
|
||||||
@ -10245,16 +10190,7 @@ static void transform_unroll_loops(struct hlsl_ctx *ctx, struct hlsl_block *bloc
|
|||||||
} while (progress);
|
} while (progress);
|
||||||
hlsl_transform_ir(ctx, split_matrix_copies, block, NULL);
|
hlsl_transform_ir(ctx, split_matrix_copies, block, NULL);
|
||||||
|
|
||||||
while (true)
|
hlsl_transform_ir(ctx, unroll_loops, block, block);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_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);
|
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);
|
hlsl_run_const_passes(ctx, body);
|
||||||
|
|
||||||
remove_unreachable_code(ctx, body);
|
remove_unreachable_code(ctx, body);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user