lima/ppir: add node dependency types

Currently we add dependecies in 3 cases:
1) One node consumes value produced by another node
2) Sequency dependencies
3) Write after read dependencies

2) and 3) only affect scheduler decisions since we still can use pipeline
register if we have only 1 dependency of type 1).

Add 3 dependency types and mark dependencies as we add them.

Reviewed-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
This commit is contained in:
Vasily Khoruzhick 2019-09-14 11:01:03 -07:00
parent 4fcfed426a
commit 780985d1b8
6 changed files with 58 additions and 28 deletions

View File

@ -96,7 +96,7 @@ static bool ppir_lower_load(ppir_block *block, ppir_node *node)
return true;
}
assert(ppir_node_has_single_succ(node) || ppir_node_is_root(node));
assert(ppir_node_has_single_src_succ(node) || ppir_node_is_root(node));
ppir_node *succ = ppir_node_first_succ(node);
if (dest->type != ppir_target_register) {
switch (succ->type) {
@ -155,7 +155,7 @@ static bool ppir_lower_texture(ppir_block *block, ppir_node *node)
ppir_node *src_coords = ppir_node_get_src(node, 0)->node;
ppir_load_node *load = NULL;
if (src_coords && ppir_node_has_single_succ(src_coords) &&
if (src_coords && ppir_node_has_single_src_succ(src_coords) &&
(src_coords->op == ppir_op_load_coords))
load = ppir_node_to_load(src_coords);
else {
@ -174,16 +174,16 @@ static bool ppir_lower_texture(ppir_block *block, ppir_node *node)
ppir_node_foreach_pred_safe(node, dep) {
ppir_node *pred = dep->pred;
ppir_node_remove_dep(dep);
ppir_node_add_dep(&load->node, pred);
ppir_node_add_dep(&load->node, pred, ppir_dep_src);
}
ppir_node_add_dep(node, &load->node);
ppir_node_add_dep(node, &load->node, ppir_dep_src);
}
assert(load);
load_tex->src_coords.type = load->dest.type = ppir_target_pipeline;
load_tex->src_coords.pipeline = load->dest.pipeline = ppir_pipeline_reg_discard;
if (ppir_node_has_single_succ(node)) {
if (ppir_node_has_single_src_succ(node)) {
ppir_node *succ = ppir_node_first_succ(node);
switch (succ->type) {
case ppir_node_type_alu:
@ -248,11 +248,11 @@ static bool ppir_lower_select(ppir_block *block, ppir_node *node)
if (dep)
ppir_node_replace_pred(dep, move);
else
ppir_node_add_dep(node, move);
ppir_node_add_dep(node, move, ppir_dep_src);
/* pred can be a register */
if (pred)
ppir_node_add_dep(move, pred);
ppir_node_add_dep(move, pred, ppir_dep_src);
src->swizzle[0] = 0;
ppir_node_target_assign(alu->src, move);
@ -350,7 +350,7 @@ static bool ppir_lower_branch(ppir_block *block, ppir_node *node)
branch->num_src = 2;
ppir_node_add_dep(&branch->node, &zero->node);
ppir_node_add_dep(&branch->node, &zero->node, ppir_dep_src);
list_addtail(&zero->node.list, &node->list);
return true;

View File

@ -143,7 +143,7 @@ static void ppir_node_add_src(ppir_compiler *comp, ppir_node *node,
}
if (child->op != ppir_op_undef)
ppir_node_add_dep(node, child);
ppir_node_add_dep(node, child, ppir_dep_src);
}
else {
nir_register *reg = ns->reg.reg;
@ -158,7 +158,7 @@ static void ppir_node_add_src(ppir_compiler *comp, ppir_node *node,
}
/* Don't add dummies or recursive deps for ops like r1 = r1 + ssa1 */
if (child && node != child && child->op != ppir_op_undef)
ppir_node_add_dep(node, child);
ppir_node_add_dep(node, child, ppir_dep_src);
}
}
@ -750,7 +750,7 @@ static void ppir_add_ordering_deps(ppir_compiler *comp)
ppir_node *prev_node = NULL;
list_for_each_entry_rev(ppir_node, node, &block->node_list, list) {
if (prev_node && ppir_node_is_root(node) && node->op != ppir_op_const) {
ppir_node_add_dep(prev_node, node);
ppir_node_add_dep(prev_node, node, ppir_dep_sequence);
}
if (node->op == ppir_op_discard ||
node->op == ppir_op_store_color ||
@ -793,8 +793,10 @@ static void ppir_add_write_after_read_deps(ppir_compiler *comp)
ppir_src *src = ppir_node_get_src(node, i);
if (src && src->type == ppir_target_register &&
src->reg == reg &&
write)
ppir_node_add_dep(write, node);
write) {
ppir_debug("Adding dep %d for write %d\n", node->index, write->index);
ppir_node_add_dep(write, node, ppir_dep_write_after_read);
}
}
ppir_dest *dest = ppir_node_get_dest(node);
if (dest && dest->type == ppir_target_register &&

View File

@ -387,7 +387,8 @@ void *ppir_node_create(ppir_block *block, ppir_op op, int index, unsigned mask)
return node;
}
void ppir_node_add_dep(ppir_node *succ, ppir_node *pred)
void ppir_node_add_dep(ppir_node *succ, ppir_node *pred,
ppir_dep_type type)
{
/* don't add dep for two nodes from different block */
if (succ->block != pred->block)
@ -402,6 +403,7 @@ void ppir_node_add_dep(ppir_node *succ, ppir_node *pred)
ppir_dep *dep = ralloc(succ, ppir_dep);
dep->pred = pred;
dep->succ = succ;
dep->type = type;
list_addtail(&dep->pred_link, &succ->pred_list);
list_addtail(&dep->succ_link, &pred->succ_list);
}
@ -661,7 +663,7 @@ ppir_node_clone_tex(ppir_block *block, ppir_node *node)
switch (src->type) {
case ppir_target_ssa: {
ppir_node_target_assign(new_src, new_tex_coords);
ppir_node_add_dep(&new_tnode->node, new_tex_coords);
ppir_node_add_dep(&new_tnode->node, new_tex_coords, ppir_dep_src);
break;
}
case ppir_target_register: {
@ -737,8 +739,25 @@ ppir_node *ppir_node_insert_mov(ppir_node *node)
alu->src->swizzle[s] = s;
ppir_node_replace_all_succ(move, node);
ppir_node_add_dep(move, node);
ppir_node_add_dep(move, node, ppir_dep_src);
list_addtail(&move->list, &node->list);
return move;
}
bool ppir_node_has_single_src_succ(ppir_node *node)
{
if (list_is_singular(&node->succ_list) &&
list_first_entry(&node->succ_list,
ppir_dep, succ_link)->type == ppir_dep_src)
return true;
int cnt = 0;
ppir_node_foreach_succ(node, dep) {
if (dep->type != ppir_dep_src)
continue;
cnt++;
}
return cnt == 1;
}

View File

@ -50,7 +50,7 @@ static bool ppir_do_node_to_instr_pipeline(ppir_block *block, ppir_node *node)
if (!dest || dest->type != ppir_target_pipeline)
return false;
assert(ppir_node_has_single_succ(node));
assert(ppir_node_has_single_src_succ(node));
ppir_node *succ = ppir_node_first_succ(node);
assert(succ);
assert(succ->instr);
@ -74,7 +74,7 @@ static bool ppir_do_one_node_to_instr(ppir_block *block, ppir_node *node, ppir_n
* by using pipeline reg ^vmul/^fmul */
ppir_alu_node *alu = ppir_node_to_alu(node);
if (alu->dest.type == ppir_target_ssa &&
ppir_node_has_single_succ(node)) {
ppir_node_has_single_src_succ(node)) {
ppir_node *succ = ppir_node_first_succ(node);
if (succ->instr_pos == PPIR_INSTR_SLOT_ALU_VEC_ADD) {
node->instr_pos = PPIR_INSTR_SLOT_ALU_VEC_MUL;
@ -115,7 +115,7 @@ static bool ppir_do_one_node_to_instr(ppir_block *block, ppir_node *node, ppir_n
}
/* Load cannot be pipelined, likely slot is already taken. Create a mov */
assert(ppir_node_has_single_succ(node));
assert(ppir_node_has_single_src_succ(node));
ppir_dest *dest = ppir_node_get_dest(node);
assert(dest->type == ppir_target_pipeline);
ppir_pipeline pipeline_reg = dest->pipeline;

View File

@ -136,8 +136,15 @@ typedef struct {
extern const ppir_op_info ppir_op_infos[];
typedef enum {
ppir_dep_src,
ppir_dep_write_after_read,
ppir_dep_sequence,
} ppir_dep_type;
typedef struct {
void *pred, *succ;
ppir_dep_type type;
struct list_head pred_link;
struct list_head succ_link;
} ppir_dep;
@ -377,7 +384,7 @@ typedef struct ppir_compiler {
} ppir_compiler;
void *ppir_node_create(ppir_block *block, ppir_op op, int index, unsigned mask);
void ppir_node_add_dep(ppir_node *succ, ppir_node *pred);
void ppir_node_add_dep(ppir_node *succ, ppir_node *pred, ppir_dep_type type);
void ppir_node_remove_dep(ppir_dep *dep);
void ppir_node_delete(ppir_node *node);
void ppir_node_print_prog(ppir_compiler *comp);
@ -404,6 +411,8 @@ static inline bool ppir_node_has_single_succ(ppir_node *node)
return list_is_singular(&node->succ_list);
}
bool ppir_node_has_single_src_succ(ppir_node *node);
static inline ppir_node *ppir_node_first_succ(ppir_node *node)
{
return list_first_entry(&node->succ_list, ppir_dep, succ_link)->succ;

View File

@ -324,10 +324,10 @@ static bool ppir_update_spilled_src(ppir_compiler *comp, ppir_block *block,
ppir_node_foreach_pred_safe(node, dep) {
ppir_node *pred = dep->pred;
ppir_node_remove_dep(dep);
ppir_node_add_dep(load_node, pred);
ppir_node_add_dep(load_node, pred, ppir_dep_src);
}
ppir_node_add_dep(node, move_node);
ppir_node_add_dep(move_node, load_node);
ppir_node_add_dep(node, move_node, ppir_dep_src);
ppir_node_add_dep(move_node, load_node, ppir_dep_src);
*fill_node = move_node;
@ -392,10 +392,10 @@ static bool ppir_update_spilled_dest_load(ppir_compiler *comp, ppir_block *block
ppir_node_foreach_pred_safe(node, dep) {
ppir_node *pred = dep->pred;
ppir_node_remove_dep(dep);
ppir_node_add_dep(load_node, pred);
ppir_node_add_dep(load_node, pred, ppir_dep_src);
}
ppir_node_add_dep(node, move_node);
ppir_node_add_dep(move_node, load_node);
ppir_node_add_dep(node, move_node, ppir_dep_src);
ppir_node_add_dep(move_node, load_node, ppir_dep_src);
return true;
}
@ -426,9 +426,9 @@ static bool ppir_update_spilled_dest(ppir_compiler *comp, ppir_block *block,
ppir_node_foreach_succ_safe(node, dep) {
ppir_node *succ = dep->succ;
ppir_node_remove_dep(dep);
ppir_node_add_dep(succ, store_node);
ppir_node_add_dep(succ, store_node, ppir_dep_src);
}
ppir_node_add_dep(store_node, node);
ppir_node_add_dep(store_node, node, ppir_dep_src);
/* If the store temp slot is empty, we can insert the store_temp
* there and use it directly. Exceptionally, if the node is in the