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) {
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 {
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:
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);
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;
}
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;
}
/* 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);
}
}
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 ||
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 &&
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)
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);
}
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: {
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;
+}
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);
* 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;
}
/* 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;
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;
} 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);
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;
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;
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;
}
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