extsrc/mesa/src/mesa/drivers/dri/i965/brw_fs.cpp
/**
 * Walks through basic blocks, locking for repeated MRF writes and
 * removing the later ones.
 */
Walks through basic blocks, locking for repeated MRF writes and
removing the later ones.
Walks through basic blocks locking for repeated MRF writes and removing the later ones .
bool
fs_visitor::remove_duplicate_mrf_writes()
{
   fs_inst *last_mrf_move[16];
   bool progress = false;
   if (c->dispatch_width == 16)
      return false;
   memset(last_mrf_move, 0, sizeof(last_mrf_move));
   foreach_list_safe(node, &this->instructions) {
      fs_inst *inst = (fs_inst *)node;
      switch (inst->opcode) {
      case BRW_OPCODE_DO:
      case BRW_OPCODE_WHILE:
      case BRW_OPCODE_IF:
      case BRW_OPCODE_ELSE:
      case BRW_OPCODE_ENDIF:
	 memset(last_mrf_move, 0, sizeof(last_mrf_move));
	 continue;
      default:
	 break;
      }
      if (inst->opcode == BRW_OPCODE_MOV &&
	  inst->dst.file == MRF) {
	 fs_inst *prev_inst = last_mrf_move[inst->dst.reg];
	 if (prev_inst && inst->equals(prev_inst)) {
	    inst->remove();
	    progress = true;
	    continue;
	 }
      }
      if (inst->dst.file == MRF) {
	 last_mrf_move[inst->dst.reg] = NULL;
      }
      if (inst->mlen > 0) {
	 for (int i = 0; i < implied_mrf_writes(inst); i++) {
	    last_mrf_move[inst->base_mrf + i] = NULL;
	 }
      }
      if (inst->dst.file == GRF) {
	 for (unsigned int i = 0; i < Elements(last_mrf_move); i++) {
	    if (last_mrf_move[i] &&
		last_mrf_move[i]->src[0].reg == inst->dst.reg) {
	       last_mrf_move[i] = NULL;
	    }
	 }
      }
      if (inst->opcode == BRW_OPCODE_MOV &&
	  inst->dst.file == MRF &&
	  inst->src[0].file == GRF &&
	  !inst->predicated) {
	 last_mrf_move[inst->dst.reg] = inst;
      }
   }
   return progress;
}
bool fs_visitor :: remove_duplicate_mrf_writes ( ) { fs_inst * last_mrf_move [ 16 ] ; bool progress = false ; if ( c -> dispatch_width == 16 ) return false ; memset ( last_mrf_move , 0 , sizeof ( last_mrf_move ) ) ; foreach_list_safe ( node , & this -> instructions ) { fs_inst * inst = ( fs_inst * ) node ; switch ( inst -> opcode ) { case BRW_OPCODE_DO : case BRW_OPCODE_WHILE : case BRW_OPCODE_IF : case BRW_OPCODE_ELSE : case BRW_OPCODE_ENDIF : memset ( last_mrf_move , 0 , sizeof ( last_mrf_move ) ) ; continue ; default : break ; } if ( inst -> opcode == BRW_OPCODE_MOV && inst -> dst . file == MRF ) { fs_inst * prev_inst = last_mrf_move [ inst -> dst . reg ] ; if ( prev_inst && inst -> equals ( prev_inst ) ) { inst -> remove ( ) ; progress = true ; continue ; } } if ( inst -> dst . file == MRF ) { last_mrf_move [ inst -> dst . reg ] = NULL ; } if ( inst -> mlen > 0 ) { for ( int i = 0 ; i < implied_mrf_writes ( inst ) ; i ++ ) { last_mrf_move [ inst -> base_mrf + i ] = NULL ; } } if ( inst -> dst . file == GRF ) { for ( unsigned int i = 0 ; i < Elements ( last_mrf_move ) ; i ++ ) { if ( last_mrf_move [ i ] && last_mrf_move [ i ] -> src [ 0 ] . reg == inst -> dst . reg ) { last_mrf_move [ i ] = NULL ; } } } if ( inst -> opcode == BRW_OPCODE_MOV && inst -> dst . file == MRF && inst -> src [ 0 ] . file == GRF && ! inst -> predicated ) { last_mrf_move [ inst -> dst . reg ] = inst ; } } return progress ; }
Walks through basic blocks, locking for repeated MRF writes and
 removing the later ones.
Walks through basic blocks locking for repeated MRF writes and removing the later ones .
/* Need to update the MRF tracking for compressed instructions. */ /* Clear out the last-write records for MRFs that were overwritten. */ /* Found a SEND instruction, which will include two or fewer
	  * implied MRF writes.  We could do better here.
	  */ /* Clear out any MRF move records whose sources got overwritten. */