static void ir3_instr_depth(struct ir3_instruction *instr, unsigned boost, bool falsedep) { struct ir3_instruction *src; /* don't mark falsedep's as used, but otherwise process them normally: */ if (!falsedep) instr->flags &= ~IR3_INSTR_UNUSED; if (ir3_instr_check_mark(instr)) return; instr->depth = 0; foreach_ssa_src_n(src, i, instr) { unsigned sd; /* visit child to compute it's depth: */ ir3_instr_depth(src, boost, __is_false_dep(instr, i)); /* for array writes, no need to delay on previous write: */ if (i == 0) continue; sd = ir3_delayslots(src, instr, i) + src->depth; sd += boost; instr->depth = MAX2(instr->depth, sd); }
void ir3_block_depth(struct ir3_block *block) { unsigned i; block->head = NULL; ir3_clear_mark(block->shader); for (i = 0; i < block->noutputs; i++) if (block->outputs[i]) ir3_instr_depth(block->outputs[i]); /* mark un-used instructions: */ for (i = 0; i < block->shader->instrs_count; i++) { struct ir3_instruction *instr = block->shader->instrs[i]; /* just consider instructions within this block: */ if (instr->block != block) continue; if (!ir3_instr_check_mark(instr)) instr->depth = DEPTH_UNUSED; } /* cleanup unused inputs: */ for (i = 0; i < block->ninputs; i++) { struct ir3_instruction *in = block->inputs[i]; if (in && (in->depth == DEPTH_UNUSED)) block->inputs[i] = NULL; } }
static void ir3_instr_depth(struct ir3_instruction *instr) { struct ir3_instruction *src; /* if we've already visited this instruction, bail now: */ if (ir3_instr_check_mark(instr)) return; instr->depth = 0; foreach_ssa_src_n(src, i, instr) { unsigned sd; /* visit child to compute it's depth: */ ir3_instr_depth(src); /* for array writes, no need to delay on previous write: */ if (i == 0) continue; sd = ir3_delayslots(src, instr, i) + src->depth; instr->depth = MAX2(instr->depth, sd); }
void ir3_block_depth(struct ir3_block *block) { unsigned i; block->head = NULL; ir3_clear_mark(block->shader); for (i = 0; i < block->noutputs; i++) if (block->outputs[i]) ir3_instr_depth(block->outputs[i]); /* at this point, any unvisited input is unused: */ for (i = 0; i < block->ninputs; i++) { struct ir3_instruction *in = block->inputs[i]; if (in && !ir3_instr_check_mark(in)) block->inputs[i] = NULL; } }
static void ir3_instr_depth(struct ir3_instruction *instr) { unsigned i; /* if we've already visited this instruction, bail now: */ if (ir3_instr_check_mark(instr)) return; instr->depth = 0; for (i = 1; i < instr->regs_count; i++) { struct ir3_register *src = instr->regs[i]; if (src->flags & IR3_REG_SSA) { unsigned sd; /* visit child to compute it's depth: */ ir3_instr_depth(src->instr); sd = ir3_delayslots(src->instr, instr, i-1) + src->instr->depth; instr->depth = MAX2(instr->depth, sd); } } /* meta-instructions don't add cycles, other than PHI.. which * might translate to a real instruction.. * * well, not entirely true, fan-in/out, etc might need to need * to generate some extra mov's in edge cases, etc.. probably * we might want to do depth calculation considering the worst * case for these?? */ if (!is_meta(instr)) instr->depth++; insert_by_depth(instr); }