mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 20:38:06 +02:00
ir3: Make predecessors an array
We need a stable order in order to create phi instructions. In the future we can make this more sophisticated in order to make manipulating the CFG easier, but for now that only happens after RA, so we won't have to worry about it. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10591>
This commit is contained in:
parent
0bd68b8386
commit
dd55bd8f68
6 changed files with 56 additions and 26 deletions
|
|
@ -352,10 +352,41 @@ struct ir3_block * ir3_block_create(struct ir3 *shader)
|
|||
block->shader = shader;
|
||||
list_inithead(&block->node);
|
||||
list_inithead(&block->instr_list);
|
||||
block->predecessors = _mesa_pointer_set_create(block);
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
void ir3_block_add_predecessor(struct ir3_block *block, struct ir3_block *pred)
|
||||
{
|
||||
array_insert(block, block->predecessors, pred);
|
||||
}
|
||||
|
||||
void ir3_block_remove_predecessor(struct ir3_block *block, struct ir3_block *pred)
|
||||
{
|
||||
for (unsigned i = 0; i < block->predecessors_count; i++) {
|
||||
if (block->predecessors[i] == pred) {
|
||||
if (i < block->predecessors_count - 1) {
|
||||
block->predecessors[i] =
|
||||
block->predecessors[block->predecessors_count - 1];
|
||||
}
|
||||
|
||||
block->predecessors_count--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned ir3_block_get_pred_index(struct ir3_block *block, struct ir3_block *pred)
|
||||
{
|
||||
for (unsigned i = 0; i < block->predecessors_count; i++) {
|
||||
if (block->predecessors[i] == pred) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
unreachable("ir3_block_get_pred_index() invalid predecessor");
|
||||
}
|
||||
|
||||
static struct ir3_instruction *instr_create(struct ir3_block *block, int nreg)
|
||||
{
|
||||
struct ir3_instruction *instr;
|
||||
|
|
|
|||
|
|
@ -550,7 +550,7 @@ struct ir3_block {
|
|||
struct ir3_instruction *condition;
|
||||
struct ir3_block *successors[2];
|
||||
|
||||
struct set *predecessors; /* set of ir3_block */
|
||||
DECLARE_ARRAY(struct ir3_block *, predecessors);
|
||||
|
||||
uint16_t start_ip, end_ip;
|
||||
|
||||
|
|
@ -579,6 +579,10 @@ block_id(struct ir3_block *block)
|
|||
#endif
|
||||
}
|
||||
|
||||
void ir3_block_add_predecessor(struct ir3_block *block, struct ir3_block *pred);
|
||||
void ir3_block_remove_predecessor(struct ir3_block *block, struct ir3_block *pred);
|
||||
unsigned ir3_block_get_pred_index(struct ir3_block *block, struct ir3_block *pred);
|
||||
|
||||
struct ir3_shader_variant;
|
||||
|
||||
struct ir3 * ir3_create(struct ir3_compiler *compiler, struct ir3_shader_variant *v);
|
||||
|
|
|
|||
|
|
@ -2959,7 +2959,7 @@ setup_predecessors(struct ir3 *ir)
|
|||
foreach_block(block, &ir->block_list) {
|
||||
for (int i = 0; i < ARRAY_SIZE(block->successors); i++) {
|
||||
if (block->successors[i])
|
||||
_mesa_set_add(block->successors[i]->predecessors, block);
|
||||
ir3_block_add_predecessor(block->successors[i], block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,8 +149,8 @@ distance(struct ir3_block *block, struct ir3_instruction *instr,
|
|||
/* (ab)use block->data to prevent recursion: */
|
||||
block->data = block;
|
||||
|
||||
set_foreach (block->predecessors, entry) {
|
||||
struct ir3_block *pred = (struct ir3_block *)entry->key;
|
||||
for (unsigned i = 0; i < block->predecessors_count; i++) {
|
||||
struct ir3_block *pred = block->predecessors[i];
|
||||
unsigned n;
|
||||
|
||||
n = distance(pred, instr, min, pred);
|
||||
|
|
@ -288,8 +288,8 @@ delay_calc_array(struct ir3_block *block, unsigned array_id,
|
|||
/* (ab)use block->data to prevent recursion: */
|
||||
block->data = block;
|
||||
|
||||
set_foreach (block->predecessors, entry) {
|
||||
struct ir3_block *pred = (struct ir3_block *)entry->key;
|
||||
for (unsigned i = 0; i < block->predecessors_count; i++) {
|
||||
struct ir3_block *pred = block->predecessors[i];
|
||||
unsigned delay =
|
||||
delay_calc_array(pred, array_id, consumer, srcn, soft, pred, maxd);
|
||||
|
||||
|
|
|
|||
|
|
@ -97,8 +97,8 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block)
|
|||
bool mergedregs = ctx->so->mergedregs;
|
||||
|
||||
/* our input state is the OR of all predecessor blocks' state: */
|
||||
set_foreach(block->predecessors, entry) {
|
||||
struct ir3_block *predecessor = (struct ir3_block *)entry->key;
|
||||
for (unsigned i = 0; i < block->predecessors_count; i++) {
|
||||
struct ir3_block *predecessor = block->predecessors[i];
|
||||
struct ir3_legalize_block_data *pbd = predecessor->data;
|
||||
struct ir3_legalize_state *pstate = &pbd->state;
|
||||
|
||||
|
|
@ -480,7 +480,7 @@ remove_unused_block(struct ir3_block *old_target)
|
|||
for (unsigned i = 0; i < ARRAY_SIZE(old_target->successors); i++) {
|
||||
if (old_target->successors[i]) {
|
||||
struct ir3_block *succ = old_target->successors[i];
|
||||
_mesa_set_remove_key(succ->predecessors, old_target);
|
||||
ir3_block_remove_predecessor(succ, old_target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -500,13 +500,12 @@ retarget_jump(struct ir3_instruction *instr, struct ir3_block *new_target)
|
|||
}
|
||||
|
||||
/* update new target's predecessors: */
|
||||
_mesa_set_add(new_target->predecessors, cur_block);
|
||||
ir3_block_add_predecessor(new_target, cur_block);
|
||||
|
||||
/* and remove old_target's predecessor: */
|
||||
debug_assert(_mesa_set_search(old_target->predecessors, cur_block));
|
||||
_mesa_set_remove_key(old_target->predecessors, cur_block);
|
||||
ir3_block_remove_predecessor(old_target, cur_block);
|
||||
|
||||
if (old_target->predecessors->entries == 0)
|
||||
if (old_target->predecessors_count == 0)
|
||||
remove_unused_block(old_target);
|
||||
|
||||
instr->cat0.target = new_target;
|
||||
|
|
@ -588,17 +587,17 @@ static void
|
|||
mark_xvergence_points(struct ir3 *ir)
|
||||
{
|
||||
foreach_block (block, &ir->block_list) {
|
||||
if (block->predecessors->entries > 1) {
|
||||
if (block->predecessors_count > 1) {
|
||||
/* if a block has more than one possible predecessor, then
|
||||
* the first instruction is a convergence point.
|
||||
*/
|
||||
mark_jp(block);
|
||||
} else if (block->predecessors->entries == 1) {
|
||||
} else if (block->predecessors_count == 1) {
|
||||
/* If a block has one predecessor, which has multiple possible
|
||||
* successors, it is a divergence point.
|
||||
*/
|
||||
set_foreach(block->predecessors, entry) {
|
||||
struct ir3_block *predecessor = (struct ir3_block *)entry->key;
|
||||
for (unsigned i = 0; i < block->predecessors_count; i++) {
|
||||
struct ir3_block *predecessor = block->predecessors[i];
|
||||
if (predecessor->successors[1]) {
|
||||
mark_jp(block);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -355,16 +355,12 @@ print_block(struct ir3_block *block, int lvl)
|
|||
{
|
||||
tab(lvl); printf("block%u {\n", block_id(block));
|
||||
|
||||
/* computerator (ir3 assembler) doesn't really use blocks for flow
|
||||
* control, so block->predecessors will be null.
|
||||
*/
|
||||
if (block->predecessors && block->predecessors->entries > 0) {
|
||||
unsigned i = 0;
|
||||
if (block->predecessors_count > 0) {
|
||||
tab(lvl+1);
|
||||
printf("pred: ");
|
||||
set_foreach (block->predecessors, entry) {
|
||||
struct ir3_block *pred = (struct ir3_block *)entry->key;
|
||||
if (i++)
|
||||
for (unsigned i = 0; i < block->predecessors_count; i++) {
|
||||
struct ir3_block *pred = block->predecessors[i];
|
||||
if (i != 0)
|
||||
printf(", ");
|
||||
printf("block%u", block_id(pred));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue