vkd3d-shader/ir: Use iterators in struct vsir_block.

This commit is contained in:
Francisco Casas
2025-09-02 21:48:06 -04:00
committed by Henri Verbeet
parent 390e31a2dd
commit b7a36fef6a
Notes: Henri Verbeet 2025-09-29 13:04:35 +02:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1739

View File

@@ -4929,7 +4929,7 @@ struct vsir_block
* LABEL that introduces the block. `end' points to the terminator * LABEL that introduces the block. `end' points to the terminator
* instruction (either BRANCH or RET). They can coincide, meaning * instruction (either BRANCH or RET). They can coincide, meaning
* that the block is empty. */ * that the block is empty. */
struct vkd3d_shader_instruction *begin, *end; struct vsir_program_iterator begin, end;
struct vsir_block_list predecessors, successors; struct vsir_block_list predecessors, successors;
uint32_t *dominates; uint32_t *dominates;
}; };
@@ -5248,19 +5248,21 @@ static void vsir_cfg_dump_dot(struct vsir_cfg *cfg)
for (i = 0; i < cfg->block_count; ++i) for (i = 0; i < cfg->block_count; ++i)
{ {
struct vsir_block *block = &cfg->blocks[i]; struct vsir_block *block = &cfg->blocks[i];
struct vkd3d_shader_instruction *end;
const char *shape; const char *shape;
if (block->label == 0) if (block->label == 0)
continue; continue;
switch (block->end->opcode) end = vsir_program_iterator_current(&block->end);
switch (end->opcode)
{ {
case VSIR_OP_RET: case VSIR_OP_RET:
shape = "trapezium"; shape = "trapezium";
break; break;
case VSIR_OP_BRANCH: case VSIR_OP_BRANCH:
shape = vsir_register_is_label(&block->end->src[0].reg) ? "ellipse" : "box"; shape = vsir_register_is_label(&end->src[0].reg) ? "ellipse" : "box";
break; break;
default: default:
@@ -5412,8 +5414,8 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
VKD3D_ASSERT(current_block->label == 0); VKD3D_ASSERT(current_block->label == 0);
if ((ret = vsir_block_init(current_block, label, program->block_count)) < 0) if ((ret = vsir_block_init(current_block, label, program->block_count)) < 0)
goto fail; goto fail;
current_block->begin = vsir_program_iterator_next(it); current_block->begin = *it;
vsir_program_iterator_prev(it); vsir_program_iterator_next(&current_block->begin);
if (!cfg->entry) if (!cfg->entry)
cfg->entry = current_block; cfg->entry = current_block;
break; break;
@@ -5422,7 +5424,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
case VSIR_OP_BRANCH: case VSIR_OP_BRANCH:
case VSIR_OP_RET: case VSIR_OP_RET:
VKD3D_ASSERT(current_block); VKD3D_ASSERT(current_block);
current_block->end = ins; current_block->end = *it;
current_block = NULL; current_block = NULL;
break; break;
@@ -5446,27 +5448,29 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
for (i = 0; i < cfg->block_count; ++i) for (i = 0; i < cfg->block_count; ++i)
{ {
struct vsir_block *block = &cfg->blocks[i]; struct vsir_block *block = &cfg->blocks[i];
struct vkd3d_shader_instruction *end;
if (block->label == 0) if (block->label == 0)
continue; continue;
switch (block->end->opcode) end = vsir_program_iterator_current(&block->end);
switch (end->opcode)
{ {
case VSIR_OP_RET: case VSIR_OP_RET:
break; break;
case VSIR_OP_BRANCH: case VSIR_OP_BRANCH:
if (vsir_register_is_label(&block->end->src[0].reg)) if (vsir_register_is_label(&end->src[0].reg))
{ {
if ((ret = vsir_cfg_add_edge(cfg, block, &block->end->src[0])) < 0) if ((ret = vsir_cfg_add_edge(cfg, block, &end->src[0])) < 0)
goto fail; goto fail;
} }
else else
{ {
if ((ret = vsir_cfg_add_edge(cfg, block, &block->end->src[1])) < 0) if ((ret = vsir_cfg_add_edge(cfg, block, &end->src[1])) < 0)
goto fail; goto fail;
if ((ret = vsir_cfg_add_edge(cfg, block, &block->end->src[2])) < 0) if ((ret = vsir_cfg_add_edge(cfg, block, &end->src[2])) < 0)
goto fail; goto fail;
} }
break; break;
@@ -5650,8 +5654,10 @@ static enum vkd3d_result vsir_cfg_compute_loops(struct vsir_cfg *cfg)
if (cfg->loops_by_header[header->label - 1] != SIZE_MAX) if (cfg->loops_by_header[header->label - 1] != SIZE_MAX)
{ {
struct vkd3d_shader_instruction *begin = vsir_program_iterator_current(&header->begin);
FIXME("Block %u is header to more than one loop, this is not implemented.\n", header->label); FIXME("Block %u is header to more than one loop, this is not implemented.\n", header->label);
vkd3d_shader_error(cfg->message_context, &header->begin->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, vkd3d_shader_error(cfg->message_context, &begin->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
"Block %u is header to more than one loop, this is not implemented.", header->label); "Block %u is header to more than one loop, this is not implemented.", header->label);
return VKD3D_ERROR_NOT_IMPLEMENTED; return VKD3D_ERROR_NOT_IMPLEMENTED;
} }
@@ -5733,8 +5739,10 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg)
if (in_degrees[i] == 0 && block != cfg->entry) if (in_degrees[i] == 0 && block != cfg->entry)
{ {
struct vkd3d_shader_instruction *begin = vsir_program_iterator_current(&block->begin);
WARN("Unexpected entry point %u.\n", block->label); WARN("Unexpected entry point %u.\n", block->label);
vkd3d_shader_error(cfg->message_context, &block->begin->location, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, vkd3d_shader_error(cfg->message_context, &begin->location, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
"Block %u is unreachable from the entry point.", block->label); "Block %u is unreachable from the entry point.", block->label);
ret = VKD3D_ERROR_INVALID_SHADER; ret = VKD3D_ERROR_INVALID_SHADER;
goto fail; goto fail;
@@ -5743,8 +5751,10 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg)
if (in_degrees[cfg->entry->label - 1] != 0) if (in_degrees[cfg->entry->label - 1] != 0)
{ {
struct vkd3d_shader_instruction *begin = vsir_program_iterator_current(&cfg->entry->begin);
WARN("Entry point has %u incoming forward edges.\n", in_degrees[cfg->entry->label - 1]); WARN("Entry point has %u incoming forward edges.\n", in_degrees[cfg->entry->label - 1]);
vkd3d_shader_error(cfg->message_context, &cfg->entry->begin->location, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, vkd3d_shader_error(cfg->message_context, &begin->location, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
"The entry point block has %u incoming forward edges.", in_degrees[cfg->entry->label - 1]); "The entry point block has %u incoming forward edges.", in_degrees[cfg->entry->label - 1]);
ret = VKD3D_ERROR_INVALID_SHADER; ret = VKD3D_ERROR_INVALID_SHADER;
goto fail; goto fail;
@@ -5846,9 +5856,11 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg)
if (cfg->order.count != cfg->block_count) if (cfg->order.count != cfg->block_count)
{ {
struct vkd3d_shader_instruction *begin = vsir_program_iterator_current(&cfg->entry->begin);
/* There is a cycle of forward edges. */ /* There is a cycle of forward edges. */
WARN("The control flow graph is not reducible.\n"); WARN("The control flow graph is not reducible.\n");
vkd3d_shader_error(cfg->message_context, &cfg->entry->begin->location, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, vkd3d_shader_error(cfg->message_context, &begin->location, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
"The control flow graph is not reducible."); "The control flow graph is not reducible.");
ret = VKD3D_ERROR_INVALID_SHADER; ret = VKD3D_ERROR_INVALID_SHADER;
goto fail; goto fail;
@@ -6107,6 +6119,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg)
{ {
struct vsir_block *block = cfg->order.blocks[i]; struct vsir_block *block = cfg->order.blocks[i];
struct vsir_cfg_structure *structure; struct vsir_cfg_structure *structure;
struct vkd3d_shader_instruction *end;
VKD3D_ASSERT(stack_depth > 0); VKD3D_ASSERT(stack_depth > 0);
@@ -6132,16 +6145,17 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg)
structure->u.block = block; structure->u.block = block;
/* Generate between zero and two jump instructions. */ /* Generate between zero and two jump instructions. */
switch (block->end->opcode) end = vsir_program_iterator_current(&block->end);
switch (end->opcode)
{ {
case VSIR_OP_BRANCH: case VSIR_OP_BRANCH:
{ {
struct vsir_cfg_edge_action action_true, action_false; struct vsir_cfg_edge_action action_true, action_false;
bool invert_condition = false; bool invert_condition = false;
if (vsir_register_is_label(&block->end->src[0].reg)) if (vsir_register_is_label(&end->src[0].reg))
{ {
unsigned int target = label_from_src_param(&block->end->src[0]); unsigned int target = label_from_src_param(&end->src[0]);
struct vsir_block *successor = &cfg->blocks[target - 1]; struct vsir_block *successor = &cfg->blocks[target - 1];
vsir_cfg_compute_edge_action(cfg, block, successor, &action_true); vsir_cfg_compute_edge_action(cfg, block, successor, &action_true);
@@ -6149,12 +6163,12 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg)
} }
else else
{ {
unsigned int target = label_from_src_param(&block->end->src[1]); unsigned int target = label_from_src_param(&end->src[1]);
struct vsir_block *successor = &cfg->blocks[target - 1]; struct vsir_block *successor = &cfg->blocks[target - 1];
vsir_cfg_compute_edge_action(cfg, block, successor, &action_true); vsir_cfg_compute_edge_action(cfg, block, successor, &action_true);
target = label_from_src_param(&block->end->src[2]); target = label_from_src_param(&end->src[2]);
successor = &cfg->blocks[target - 1]; successor = &cfg->blocks[target - 1];
vsir_cfg_compute_edge_action(cfg, block, successor, &action_false); vsir_cfg_compute_edge_action(cfg, block, successor, &action_false);
@@ -6206,7 +6220,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg)
goto fail; goto fail;
structure->u.jump.type = action_true.jump_type; structure->u.jump.type = action_true.jump_type;
structure->u.jump.target = action_true.target; structure->u.jump.target = action_true.target;
structure->u.jump.condition = &block->end->src[0]; structure->u.jump.condition = &vsir_program_iterator_current(&block->end)->src[0];
structure->u.jump.invert_condition = invert_condition; structure->u.jump.invert_condition = invert_condition;
} }
@@ -6691,15 +6705,27 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_block(struct vsir_cfg *cfg
struct vsir_block *block) struct vsir_block *block)
{ {
struct vsir_cfg_emit_target *target = cfg->target; struct vsir_cfg_emit_target *target = cfg->target;
struct vkd3d_shader_instruction *ins, *end;
struct vsir_program_iterator it;
size_t ins_count = 0;
it = block->begin;
end = vsir_program_iterator_current(&block->end);
for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it))
{
++ins_count;
}
if (!reserve_instructions(&target->instructions, &target->ins_capacity, if (!reserve_instructions(&target->instructions, &target->ins_capacity,
target->ins_count + (block->end - block->begin))) target->ins_count + ins_count))
return VKD3D_ERROR_OUT_OF_MEMORY; return VKD3D_ERROR_OUT_OF_MEMORY;
memcpy(&target->instructions[target->ins_count], block->begin, it = block->begin;
(char *)block->end - (char *)block->begin); for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it))
{
target->ins_count += block->end - block->begin; target->instructions[target->ins_count++] = *ins;
}
return VKD3D_OK; return VKD3D_OK;
} }
@@ -7088,7 +7114,9 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v
if (block->label == 0) if (block->label == 0)
continue; continue;
for (ins = block->begin; ins <= block->end; ++ins) it = block->begin;
end = vsir_program_iterator_current(&block->end);
for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it))
{ {
for (j = 0; j < ins->dst_count; ++j) for (j = 0; j < ins->dst_count; ++j)
{ {
@@ -7105,7 +7133,9 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v
if (block->label == 0) if (block->label == 0)
continue; continue;
for (ins = block->begin; ins <= block->end; ++ins) it = block->begin;
end = vsir_program_iterator_current(&block->end);
for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it))
{ {
for (j = 0; j < ins->src_count; ++j) for (j = 0; j < ins->src_count; ++j)
register_map_undominated_use(&ins->src[j].reg, &alloc, block, origin_blocks); register_map_undominated_use(&ins->src[j].reg, &alloc, block, origin_blocks);