lima/ppir: refactor const lowering
Const nodes are now cloned for each user, i.e. const is guaranteed to have exactly one successor, so we can use ppir_do_one_node_to_instr() and drop insert_to_each_succ_instr() Tested-by: Andreas Baierl <ichgeh@imkreisrum.de> Reviewed-by: Qiang Yu <yuq825@gmail.com> Reviewed-by: Erico Nunes <nunes.erico@gmail.com> Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
This commit is contained in:
parent
2b7ba9f239
commit
172f2ad805
|
@ -186,9 +186,18 @@ bool ppir_instr_insert_node(ppir_instr *instr, ppir_node *node)
|
|||
uint8_t swizzle[4] = {0};
|
||||
|
||||
if (ppir_instr_insert_const(&ic, nc, swizzle)) {
|
||||
ppir_node *succ = ppir_node_first_succ(node);
|
||||
ppir_src *src = NULL;
|
||||
for (int s = 0; s < ppir_node_get_src_num(succ); s++) {
|
||||
src = ppir_node_get_src(succ, s);
|
||||
if (src->node == node)
|
||||
break;
|
||||
}
|
||||
assert(src->node == node);
|
||||
|
||||
instr->constant[i] = ic;
|
||||
ppir_instr_update_src_pipeline(
|
||||
instr, ppir_pipeline_reg_const0 + i, &c->dest, swizzle);
|
||||
ppir_update_src_pipeline(ppir_pipeline_reg_const0 + i, src,
|
||||
&c->dest, swizzle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,41 +34,55 @@ static bool ppir_lower_const(ppir_block *block, ppir_node *node)
|
|||
return true;
|
||||
}
|
||||
|
||||
ppir_node *move = NULL;
|
||||
assert(ppir_node_has_single_succ(node));
|
||||
|
||||
ppir_node *succ = ppir_node_first_succ(node);
|
||||
ppir_src *src = ppir_node_get_src_for_pred(succ, node);
|
||||
ppir_dest *dest = ppir_node_get_dest(node);
|
||||
assert(src != NULL);
|
||||
|
||||
switch (succ->type) {
|
||||
case ppir_node_type_alu:
|
||||
case ppir_node_type_branch:
|
||||
/* ALU and branch can consume consts directly */
|
||||
dest->type = src->type = ppir_target_pipeline;
|
||||
/* Reg will be updated in node_to_instr later */
|
||||
dest->pipeline = src->pipeline = ppir_pipeline_reg_const0;
|
||||
return true;
|
||||
default:
|
||||
/* Create a move for everyone else */
|
||||
break;
|
||||
}
|
||||
|
||||
ppir_node *move = ppir_node_create(block, ppir_op_mov, -1, 0);
|
||||
if (unlikely(!move))
|
||||
return false;
|
||||
|
||||
ppir_debug("lower const create move %d for %d\n",
|
||||
move->index, node->index);
|
||||
|
||||
ppir_alu_node *alu = ppir_node_to_alu(move);
|
||||
alu->dest = *dest;
|
||||
alu->num_src = 1;
|
||||
ppir_node_target_assign(alu->src, node);
|
||||
for (int s = 0; s < 4; s++)
|
||||
alu->src->swizzle[s] = s;
|
||||
|
||||
/* const (register) can only be used in alu node, create a move
|
||||
* node for other types of node */
|
||||
ppir_node_foreach_succ_safe(node, dep) {
|
||||
ppir_node *succ = dep->succ;
|
||||
|
||||
if (succ->type != ppir_node_type_alu) {
|
||||
if (!move) {
|
||||
move = ppir_node_create(block, ppir_op_mov, -1, 0);
|
||||
if (unlikely(!move))
|
||||
return false;
|
||||
|
||||
ppir_debug("lower const create move %d for %d\n",
|
||||
move->index, node->index);
|
||||
|
||||
ppir_alu_node *alu = ppir_node_to_alu(move);
|
||||
alu->dest = *dest;
|
||||
alu->num_src = 1;
|
||||
ppir_node_target_assign(alu->src, node);
|
||||
for (int i = 0; i < 4; i++)
|
||||
alu->src->swizzle[i] = i;
|
||||
}
|
||||
|
||||
ppir_node_replace_pred(dep, move);
|
||||
ppir_node_replace_child(succ, node, move);
|
||||
}
|
||||
ppir_node_replace_pred(dep, move);
|
||||
ppir_node_replace_child(succ, node, move);
|
||||
}
|
||||
|
||||
if (move) {
|
||||
ppir_node_add_dep(move, node);
|
||||
list_addtail(&move->list, &node->list);
|
||||
}
|
||||
/* Need to be careful with changing src/dst type here:
|
||||
* it has to be done *after* successors have their children
|
||||
* replaced, otherwise ppir_node_replace_child() won't find
|
||||
* matching src/dst and as result won't work
|
||||
*/
|
||||
alu->src->type = dest->type = ppir_target_pipeline;
|
||||
alu->src->pipeline = dest->pipeline = ppir_pipeline_reg_const0;
|
||||
|
||||
ppir_node_add_dep(move, node);
|
||||
list_addtail(&move->list, &node->list);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -287,11 +301,10 @@ static bool ppir_lower_branch(ppir_block *block, ppir_node *node)
|
|||
if (!zero)
|
||||
return false;
|
||||
|
||||
list_addtail(&zero->node.list, &node->list);
|
||||
|
||||
zero->constant.value[0].f = 0;
|
||||
zero->constant.num = 1;
|
||||
zero->dest.type = ppir_target_ssa;
|
||||
zero->dest.type = ppir_target_pipeline;
|
||||
zero->dest.pipeline = ppir_pipeline_reg_const0;
|
||||
zero->dest.ssa.num_components = 1;
|
||||
zero->dest.ssa.live_in = INT_MAX;
|
||||
zero->dest.ssa.live_out = 0;
|
||||
|
@ -302,13 +315,13 @@ static bool ppir_lower_branch(ppir_block *block, ppir_node *node)
|
|||
* comparision node into branch itself and use current
|
||||
* way as a fallback for complex conditions.
|
||||
*/
|
||||
branch->src[1].type = ppir_target_ssa;
|
||||
branch->src[1].ssa = &zero->dest.ssa;
|
||||
ppir_node_target_assign(&branch->src[1], &zero->node);
|
||||
|
||||
branch->cond_gt = true;
|
||||
branch->cond_lt = true;
|
||||
|
||||
ppir_node_add_dep(&branch->node, &zero->node);
|
||||
list_addtail(&zero->node.list, &node->list);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -340,6 +353,5 @@ bool ppir_lower_prog(ppir_compiler *comp)
|
|||
}
|
||||
}
|
||||
|
||||
ppir_node_print_prog(comp);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -100,6 +100,10 @@ static void ppir_node_add_src(ppir_compiler *comp, ppir_node *node,
|
|||
|
||||
if (ns->is_ssa) {
|
||||
child = comp->var_nodes[ns->ssa->index];
|
||||
/* Clone consts for each successor */
|
||||
if (child->type == ppir_node_type_const)
|
||||
child = ppir_node_clone_const(node->block, child);
|
||||
|
||||
ppir_node_add_dep(node, child);
|
||||
}
|
||||
else {
|
||||
|
@ -624,6 +628,8 @@ bool ppir_compile_nir(struct lima_fs_shader_state *prog, struct nir_shader *nir,
|
|||
if (!ppir_lower_prog(comp))
|
||||
goto err_out0;
|
||||
|
||||
ppir_node_print_prog(comp);
|
||||
|
||||
if (!ppir_node_to_instr(comp))
|
||||
goto err_out0;
|
||||
|
||||
|
|
|
@ -571,3 +571,26 @@ void ppir_node_print_prog(ppir_compiler *comp)
|
|||
}
|
||||
printf("====================\n");
|
||||
}
|
||||
|
||||
ppir_node *ppir_node_clone_const(ppir_block *block, ppir_node *node)
|
||||
{
|
||||
ppir_const_node *cnode = ppir_node_to_const(node);
|
||||
ppir_const_node *new_cnode = ppir_node_create(block, ppir_op_const, -1, 0);
|
||||
|
||||
if (!new_cnode)
|
||||
return NULL;
|
||||
|
||||
list_addtail(&new_cnode->node.list, &block->node_list);
|
||||
|
||||
new_cnode->constant.num = cnode->constant.num;
|
||||
for (int i = 0; i < cnode->constant.num; i++) {
|
||||
new_cnode->constant.value[i] = cnode->constant.value[i];
|
||||
}
|
||||
new_cnode->dest.type = ppir_target_ssa;
|
||||
new_cnode->dest.ssa.num_components = cnode->dest.ssa.num_components;
|
||||
new_cnode->dest.ssa.live_in = INT_MAX;
|
||||
new_cnode->dest.ssa.live_out = 0;
|
||||
new_cnode->dest.write_mask = cnode->dest.write_mask;
|
||||
|
||||
return &new_cnode->node;
|
||||
}
|
||||
|
|
|
@ -37,97 +37,6 @@ static bool create_new_instr(ppir_block *block, ppir_node *node)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool insert_to_each_succ_instr(ppir_block *block, ppir_node *node)
|
||||
{
|
||||
ppir_dest *dest = ppir_node_get_dest(node);
|
||||
assert(dest->type == ppir_target_ssa);
|
||||
|
||||
ppir_node *move = NULL;
|
||||
|
||||
ppir_node_foreach_succ_safe(node, dep) {
|
||||
ppir_node *succ = dep->succ;
|
||||
assert(succ->type == ppir_node_type_alu ||
|
||||
succ->type == ppir_node_type_branch);
|
||||
|
||||
if (!ppir_instr_insert_node(succ->instr, node)) {
|
||||
/* create a move node to insert for failed node */
|
||||
if (!move) {
|
||||
move = ppir_node_create(block, ppir_op_mov, -1, 0);
|
||||
if (unlikely(!move))
|
||||
return false;
|
||||
|
||||
ppir_debug("node_to_instr create move %d for %d\n",
|
||||
move->index, node->index);
|
||||
|
||||
ppir_alu_node *alu = ppir_node_to_alu(move);
|
||||
alu->dest = *dest;
|
||||
alu->num_src = 1;
|
||||
ppir_node_target_assign(alu->src, node);
|
||||
for (int i = 0; i < 4; i++)
|
||||
alu->src->swizzle[i] = i;
|
||||
}
|
||||
|
||||
ppir_node_replace_pred(dep, move);
|
||||
ppir_node_replace_child(succ, node, move);
|
||||
}
|
||||
}
|
||||
|
||||
if (move) {
|
||||
if (!create_new_instr(block, move))
|
||||
return false;
|
||||
|
||||
ASSERTED bool insert_result =
|
||||
ppir_instr_insert_node(move->instr, node);
|
||||
assert(insert_result);
|
||||
|
||||
ppir_node_add_dep(move, node);
|
||||
list_addtail(&move->list, &node->list);
|
||||
}
|
||||
|
||||
/* dupliacte node for each successor */
|
||||
|
||||
bool first = true;
|
||||
struct list_head dup_list;
|
||||
list_inithead(&dup_list);
|
||||
|
||||
ppir_node_foreach_succ_safe(node, dep) {
|
||||
ppir_node *succ = dep->succ;
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
node->instr = succ->instr;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (succ->instr == node->instr)
|
||||
continue;
|
||||
|
||||
list_for_each_entry(ppir_node, dup, &dup_list, list) {
|
||||
if (succ->instr == dup->instr) {
|
||||
ppir_node_replace_pred(dep, dup);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ppir_node *dup = ppir_node_create(block, node->op, -1, 0);
|
||||
if (unlikely(!dup))
|
||||
return false;
|
||||
list_addtail(&dup->list, &dup_list);
|
||||
|
||||
ppir_debug("node_to_instr duplicate %s %d from %d\n",
|
||||
ppir_op_infos[dup->op].name, dup->index, node->index);
|
||||
|
||||
ppir_instr *instr = succ->instr;
|
||||
dup->instr = instr;
|
||||
dup->instr_pos = node->instr_pos;
|
||||
ppir_node_replace_pred(dep, dup);
|
||||
}
|
||||
|
||||
list_splicetail(&dup_list, &node->list);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a node has a pipeline dest, schedule it in the same instruction as its
|
||||
* successor.
|
||||
|
@ -199,8 +108,8 @@ static bool ppir_do_one_node_to_instr(ppir_block *block, ppir_node *node, ppir_n
|
|||
return false;
|
||||
break;
|
||||
case ppir_node_type_const:
|
||||
if (!insert_to_each_succ_instr(block, node))
|
||||
return false;
|
||||
/* Const nodes are supposed to go through do_node_to_instr_pipeline() */
|
||||
assert(false);
|
||||
break;
|
||||
case ppir_node_type_store:
|
||||
{
|
||||
|
|
|
@ -363,6 +363,7 @@ void ppir_node_print_prog(ppir_compiler *comp);
|
|||
void ppir_node_replace_child(ppir_node *parent, ppir_node *old_child, ppir_node *new_child);
|
||||
void ppir_node_replace_all_succ(ppir_node *dst, ppir_node *src);
|
||||
void ppir_node_replace_pred(ppir_dep *dep, ppir_node *new_pred);
|
||||
ppir_node *ppir_node_clone_const(ppir_block *block, ppir_node *node);
|
||||
|
||||
static inline bool ppir_node_is_root(ppir_node *node)
|
||||
{
|
||||
|
@ -468,6 +469,17 @@ static inline ppir_src *ppir_node_get_src(ppir_node *node, int idx)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline ppir_src *ppir_node_get_src_for_pred(ppir_node *node, ppir_node *pred)
|
||||
{
|
||||
for (int i = 0; i < ppir_node_get_src_num(node); i++) {
|
||||
ppir_src *src = ppir_node_get_src(node, i);
|
||||
if (src && src->node == pred)
|
||||
return src;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void ppir_node_target_assign(ppir_src *src, ppir_node *node)
|
||||
{
|
||||
ppir_dest *dest = ppir_node_get_dest(node);
|
||||
|
|
Loading…
Reference in New Issue