src/lima/pp_lir/peephole.c
//Moves uses of a texld instruction into the instruction, hopefully replacing
//uses of the register with pipeline registers so that we can delete the
//move instruction and register
Moves uses of a texld instruction into the instruction, hopefully replacing
uses of the register with pipeline registers so that we can delete the
move instruction and register
Moves uses of a texld instruction into the instruction hopefully replacing uses of the register with pipeline registers so that we can delete the move instruction and register
static bool peephole_texture(lima_pp_lir_scheduled_instr_t* instr)
{
	if (!instr->texld_instr)
		return true;
	if (instr->temp_store_instr ||
		instr->branch_instr)
		return true;
	lima_pp_lir_instr_t* move =
		find_single_pipeline_move(instr, lima_pp_lir_pipeline_reg_sampler, 4);
	if (!instr)
		return true;
	lima_pp_lir_reg_t* reg = move->dest.reg;
	ptrset_t sched_uses;
	if (!ptrset_create(&sched_uses))
		return false;
	ptrset_iter_t iter = ptrset_iter_create(reg->uses);
	lima_pp_lir_instr_t* use_instr;
	ptrset_iter_for_each(iter, use_instr)
	{
		lima_pp_lir_scheduled_instr_t* sched_use = use_instr->sched_instr;
		if (sched_use == instr)
			continue;
		ptrset_add(&sched_uses, sched_use);
	}
	iter = ptrset_iter_create(sched_uses);
	lima_pp_lir_scheduled_instr_t* use;
	ptrset_iter_for_each(iter, use)
	{
		if (!ptrset_contains(instr->min_succs, use))
			continue;
		unsigned move_instr_pos;
		bool move_instr_possible[5];
		bool removed_move = false;
		if (ptrset_size(sched_uses) == 1 &&
			(!use->temp_store_instr ||
			 !ptrset_contains(reg->uses, use->temp_store_instr)) &&
			(!use->branch_instr ||
			 !ptrset_contains(reg->uses, use->branch_instr)) &&
			(!instr->temp_store_instr ||
			 !ptrset_contains(reg->uses, instr->temp_store_instr)) &&
			(!instr->branch_instr ||
			 !ptrset_contains(reg->uses, instr->branch_instr)))
		{
			move_instr_pos = alu_instr_pos(instr, move);
			unsigned i;
			for (i = 0; i < 5; i++)
				move_instr_possible[i] =
					instr->possible_alu_instr_pos[move_instr_pos][i];
			instr->alu_instrs[move_instr_pos] = NULL;
			for (i = 0; i < 5; i++)
				instr->possible_alu_instr_pos[move_instr_pos][i] = false;
			removed_move = true;
		}
		if (lima_pp_lir_instr_combine_after(use, instr))
		{
			lima_pp_lir_block_remove(use);
			ptrset_remove(&sched_uses, use);
			unsigned i;
			for (i = 0; i < 5; i++)
				if (ptrset_contains(reg->uses, instr->alu_instrs[i]))
					reg_to_pipeline_reg(instr->alu_instrs[i], reg,
										lima_pp_lir_pipeline_reg_sampler);
			if (removed_move)
			{
				lima_pp_lir_instr_delete(move);
				delete_reg(reg, instr->block->prog);
			}
			continue;
		}
		if (removed_move)
		{
			instr->alu_instrs[move_instr_pos] = move;
			unsigned i;
			for (i = 0; i < 5; i++)
				instr->possible_alu_instr_pos[move_instr_pos][i] =
					move_instr_possible[i];
		}
	}
	ptrset_delete(sched_uses);
	return true;
}
static bool peephole_texture ( lima_pp_lir_scheduled_instr_t * instr ) { if ( ! instr -> texld_instr ) return true ; if ( instr -> temp_store_instr || instr -> branch_instr ) return true ; lima_pp_lir_instr_t * move = find_single_pipeline_move ( instr , lima_pp_lir_pipeline_reg_sampler , 4 ) ; if ( ! instr ) return true ; lima_pp_lir_reg_t * reg = move -> dest . reg ; ptrset_t sched_uses ; if ( ! ptrset_create ( & sched_uses ) ) return false ; ptrset_iter_t iter = ptrset_iter_create ( reg -> uses ) ; lima_pp_lir_instr_t * use_instr ; ptrset_iter_for_each ( iter , use_instr ) { lima_pp_lir_scheduled_instr_t * sched_use = use_instr -> sched_instr ; if ( sched_use == instr ) continue ; ptrset_add ( & sched_uses , sched_use ) ; } iter = ptrset_iter_create ( sched_uses ) ; lima_pp_lir_scheduled_instr_t * use ; ptrset_iter_for_each ( iter , use ) { if ( ! ptrset_contains ( instr -> min_succs , use ) ) continue ; unsigned move_instr_pos ; bool move_instr_possible [ 5 ] ; bool removed_move = false ; if ( ptrset_size ( sched_uses ) == 1 && ( ! use -> temp_store_instr || ! ptrset_contains ( reg -> uses , use -> temp_store_instr ) ) && ( ! use -> branch_instr || ! ptrset_contains ( reg -> uses , use -> branch_instr ) ) && ( ! instr -> temp_store_instr || ! ptrset_contains ( reg -> uses , instr -> temp_store_instr ) ) && ( ! instr -> branch_instr || ! ptrset_contains ( reg -> uses , instr -> branch_instr ) ) ) { move_instr_pos = alu_instr_pos ( instr , move ) ; unsigned i ; for ( i = 0 ; i < 5 ; i ++ ) move_instr_possible [ i ] = instr -> possible_alu_instr_pos [ move_instr_pos ] [ i ] ; instr -> alu_instrs [ move_instr_pos ] = NULL ; for ( i = 0 ; i < 5 ; i ++ ) instr -> possible_alu_instr_pos [ move_instr_pos ] [ i ] = false ; removed_move = true ; } if ( lima_pp_lir_instr_combine_after ( use , instr ) ) { lima_pp_lir_block_remove ( use ) ; ptrset_remove ( & sched_uses , use ) ; unsigned i ; for ( i = 0 ; i < 5 ; i ++ ) if ( ptrset_contains ( reg -> uses , instr -> alu_instrs [ i ] ) ) reg_to_pipeline_reg ( instr -> alu_instrs [ i ] , reg , lima_pp_lir_pipeline_reg_sampler ) ; if ( removed_move ) { lima_pp_lir_instr_delete ( move ) ; delete_reg ( reg , instr -> block -> prog ) ; } continue ; } if ( removed_move ) { instr -> alu_instrs [ move_instr_pos ] = move ; unsigned i ; for ( i = 0 ; i < 5 ; i ++ ) instr -> possible_alu_instr_pos [ move_instr_pos ] [ i ] = move_instr_possible [ i ] ; } } ptrset_delete ( sched_uses ) ; return true ; }
Moves uses of a texld instruction into the instruction, hopefully replacing
uses of the register with pipeline registers so that we can delete the
move instruction and register
Moves uses of a texld instruction into the instruction hopefully replacing uses of the register with pipeline registers so that we can delete the move instruction and register
//Optimization: if there's only one use, then if we can merge it //successfully then we don't need the move instruction, so //temporarily remove it and only add it back in if merging the //instructions doesn't work //Undo the optimization since it didn't work