mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-12-15 08:03:30 -08:00
vkd3d-shader/ir: Use iterators in struct vsir_block.
This commit is contained in:
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
@@ -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(¤t_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);
|
||||||
|
|||||||
Reference in New Issue
Block a user