Exemple #1
0
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;
	}
}
void
ir3_cp(struct ir3 *ir, struct ir3_shader_variant *so)
{
	struct ir3_cp_ctx ctx = {
			.shader = ir,
			.so = so,
	};

	ir3_clear_mark(ir);

	for (unsigned i = 0; i < ir->noutputs; i++) {
		if (ir->outputs[i]) {
			instr_cp(&ctx, ir->outputs[i]);
			ir->outputs[i] = eliminate_output_mov(ir->outputs[i]);
		}
	}

	list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
		if (block->condition) {
			instr_cp(&ctx, block->condition);
			block->condition = eliminate_output_mov(block->condition);
		}

		for (unsigned i = 0; i < block->keeps_count; i++) {
			instr_cp(&ctx, block->keeps[i]);
			block->keeps[i] = eliminate_output_mov(block->keeps[i]);
		}
	}
}
Exemple #3
0
int ir3_block_sched(struct ir3_block *block)
{
	struct ir3_sched_ctx ctx = {0};
	ir3_clear_mark(block->shader);
	block_sched(&ctx, block);
	if (ctx.error)
		return -1;
	return 0;
}
Exemple #4
0
void
ir3_cp(struct ir3 *ir, struct ir3_shader_variant *so)
{
	struct ir3_cp_ctx ctx = {
			.shader = ir,
			.so = so,
	};

	/* This is a bit annoying, and probably wouldn't be necessary if we
	 * tracked a reverse link from producing instruction to consumer.
	 * But we need to know when we've eliminated the last consumer of
	 * a mov, so we need to do a pass to first count consumers of a
	 * mov.
	 */
	list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
		list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
			struct ir3_instruction *src;

			/* by the way, we don't account for false-dep's, so the CP
			 * pass should always happen before false-dep's are inserted
			 */
			debug_assert(instr->deps_count == 0);

			foreach_ssa_src(src, instr) {
				src->use_count++;
			}
		}
	}

	ir3_clear_mark(ir);

	for (unsigned i = 0; i < ir->noutputs; i++) {
		if (ir->outputs[i]) {
			instr_cp(&ctx, ir->outputs[i]);
			ir->outputs[i] = eliminate_output_mov(ir->outputs[i]);
		}
	}

	list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
		if (block->condition) {
			instr_cp(&ctx, block->condition);
			block->condition = eliminate_output_mov(block->condition);
		}

		for (unsigned i = 0; i < block->keeps_count; i++) {
			instr_cp(&ctx, block->keeps[i]);
			block->keeps[i] = eliminate_output_mov(block->keeps[i]);
		}
	}
}
Exemple #5
0
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;
	}
}
Exemple #6
0
void
ir3_group(struct ir3 *ir)
{
	ir3_clear_mark(ir);
	find_neighbors(ir);
}