void rc_get_stats(struct radeon_compiler *c, struct rc_program_stats *s)
{
	int max_reg = -1;
	struct rc_instruction * tmp;
	memset(s, 0, sizeof(*s));

	for(tmp = c->Program.Instructions.Next; tmp != &c->Program.Instructions;
							tmp = tmp->Next){
		const struct rc_opcode_info * info;
		rc_for_all_reads_mask(tmp, reg_count_callback, &max_reg);
		if (tmp->Type == RC_INSTRUCTION_NORMAL) {
			if (tmp->U.I.PreSub.Opcode != RC_PRESUB_NONE)
				s->num_presub_ops++;
			info = rc_get_opcode_info(tmp->U.I.Opcode);
		} else {
			if (tmp->U.P.RGB.Src[RC_PAIR_PRESUB_SRC].Used)
				s->num_presub_ops++;
			if (tmp->U.P.Alpha.Src[RC_PAIR_PRESUB_SRC].Used)
				s->num_presub_ops++;
			/* Assuming alpha will never be a flow control or
			 * a tex instruction. */
			if (tmp->U.P.Alpha.Opcode != RC_OPCODE_NOP)
				s->num_alpha_insts++;
			if (tmp->U.P.RGB.Opcode != RC_OPCODE_NOP)
				s->num_rgb_insts++;
			info = rc_get_opcode_info(tmp->U.P.RGB.Opcode);
		}
		if (info->IsFlowControl)
			s->num_fc_insts++;
		if (info->HasTexture)
			s->num_tex_insts++;
		s->num_insts++;
	}
	s->num_temp_regs = max_reg + 1;
}
/**
 * Calls a callback function for all sourced register channels.
 *
 * This is conservative, i.e. channels may be called multiple times,
 * and the writemask of the instruction is not taken into account.
 */
void rc_for_all_reads_chan(struct rc_instruction * inst, rc_read_write_chan_fn cb, void * userdata)
{
	struct mask_to_chan_data d;
	d.UserData = userdata;
	d.Fn = cb;
	rc_for_all_reads_mask(inst, &mask_to_chan_cb, &d);
}
Example #3
0
/**
 * This function fills in the parameter 'used' with a writemask that
 * represent which components of each temporary register are used by the
 * program.  This is meant to be combined with rc_find_free_temporary_list as a
 * more efficient version of rc_find_free_temporary.
 * @param used The function does not initialize this parameter.
 */
void rc_get_used_temporaries(
	struct radeon_compiler * c,
	unsigned char * used,
	unsigned int used_length)
{
	struct rc_instruction * inst;
	struct get_used_temporaries_data d;
	d.Used = used;
	d.UsedLength = used_length;

	for(inst = c->Program.Instructions.Next;
			inst != &c->Program.Instructions; inst = inst->Next) {

		rc_for_all_reads_mask(inst, get_used_temporaries_cb, &d);
		rc_for_all_writes_mask(inst, get_used_temporaries_cb, &d);
	}
}
void rc_get_stats(struct radeon_compiler *c, struct rc_program_stats *s)
{
	struct rc_instruction * tmp;
	memset(s, 0, sizeof(*s));

	for(tmp = c->Program.Instructions.Next; tmp != &c->Program.Instructions;
							tmp = tmp->Next){
		const struct rc_opcode_info * info;
		rc_for_all_reads_mask(tmp, reg_count_callback, s);
		if (tmp->Type == RC_INSTRUCTION_NORMAL) {
			info = rc_get_opcode_info(tmp->U.I.Opcode);
			if (info->Opcode == RC_OPCODE_BEGIN_TEX)
				continue;
			if (tmp->U.I.PreSub.Opcode != RC_PRESUB_NONE)
				s->num_presub_ops++;
		} else {
			if (tmp->U.P.RGB.Src[RC_PAIR_PRESUB_SRC].Used)
				s->num_presub_ops++;
			if (tmp->U.P.Alpha.Src[RC_PAIR_PRESUB_SRC].Used)
				s->num_presub_ops++;
			/* Assuming alpha will never be a flow control or
			 * a tex instruction. */
			if (tmp->U.P.Alpha.Opcode != RC_OPCODE_NOP)
				s->num_alpha_insts++;
			if (tmp->U.P.RGB.Opcode != RC_OPCODE_NOP)
				s->num_rgb_insts++;
			if (tmp->U.P.RGB.Omod != RC_OMOD_MUL_1 &&
				tmp->U.P.RGB.Omod != RC_OMOD_DISABLE) {
				s->num_omod_ops++;
			}
			if (tmp->U.P.Alpha.Omod != RC_OMOD_MUL_1 &&
				tmp->U.P.Alpha.Omod != RC_OMOD_DISABLE) {
				s->num_omod_ops++;
			}
			info = rc_get_opcode_info(tmp->U.P.RGB.Opcode);
		}
		if (info->IsFlowControl)
			s->num_fc_insts++;
		if (info->HasTexture)
			s->num_tex_insts++;
		s->num_insts++;
	}
	/* Increment here because the reg_count_callback store the max
	 * temporary reg index in s->nun_temp_regs. */
	s->num_temp_regs++;
}
static void compute_live_intervals(struct radeon_compiler *c,
				   struct regalloc_state *s)
{
	memset(s, 0, sizeof(*s));
	s->C = c;
	s->NumHwTemporaries = c->max_temp_regs;
	s->HwTemporary =
		memory_pool_malloc(&c->Pool,
				   s->NumHwTemporaries * sizeof(struct hardware_register));
	memset(s->HwTemporary, 0, s->NumHwTemporaries * sizeof(struct hardware_register));

	rc_recompute_ips(s->C);

	for(struct rc_instruction * inst = s->C->Program.Instructions.Next;
	    inst != &s->C->Program.Instructions;
	    inst = inst->Next) {

		/* For all instructions inside of a loop, the ENDLOOP
		 * instruction is used as the end of the live interval. */
		if (inst->U.I.Opcode == RC_OPCODE_BGNLOOP && !s->end_loop) {
			int loops = 1;
			struct rc_instruction * tmp;
			for(tmp = inst->Next;
					tmp != &s->C->Program.Instructions;
					tmp = tmp->Next) {
				if (tmp->U.I.Opcode == RC_OPCODE_BGNLOOP) {
					loops++;
				} else if (tmp->U.I.Opcode
							== RC_OPCODE_ENDLOOP) {
					if(!--loops) {
						s->end_loop = tmp->IP;
						break;
					}
				}
			}
		}

		if (inst->IP == s->end_loop)
			s->end_loop = 0;

		rc_for_all_reads_mask(inst, scan_callback, s);
		rc_for_all_writes_mask(inst, scan_callback, s);
	}
}