extsrc/mesa/src/mesa/drivers/dri/i965/brw_fs.cpp
/**
 * Split large virtual GRFs into separate components if we can.
 *
 * This is mostly duplicated with what brw_fs_vector_splitting does,
 * but that's really conservative because it's afraid of doing
 * splitting that doesn't result in real progress after the rest of
 * the optimization phases, which would cause infinite looping in
 * optimization.  We can do it once here, safely.  This also has the
 * opportunity to split interpolated values, or maybe even uniforms,
 * which we don't have at the IR level.
 *
 * We want to split, because virtual GRFs are what we register
 * allocate and spill (due to contiguousness requirements for some
 * instructions), and they're what we naturally generate in the
 * codegen process, but most virtual GRFs don't actually need to be
 * contiguous sets of GRFs.  If we split, we'll end up with reduced
 * live intervals and better dead code elimination and coalescing.
 */
Split large virtual GRFs into separate components if we can.
This is mostly duplicated with what brw_fs_vector_splitting does,
but that's really conservative because it's afraid of doing
splitting that doesn't result in real progress after the rest of
the optimization phases, which would cause infinite looping in
optimization.  We can do it once here, safely.  This also has the
opportunity to split interpolated values, or maybe even uniforms,
which we don't have at the IR level.

We want to split, because virtual GRFs are what we register
allocate and spill (due to contiguousness requirements for some
instructions), and they're what we naturally generate in the
codegen process, but most virtual GRFs don't actually need to be
contiguous sets of GRFs.  If we split, we'll end up with reduced
live intervals and better dead code elimination and coalescing.
Split large virtual GRFs into separate components if we can . This is mostly duplicated with what brw_fs_vector_splitting does but that ' s really conservative because it ' s afraid of doing splitting that doesn ' t result in real progress after the rest of the optimization phases which would cause infinite looping in optimization . We can do it once here safely . This also has the opportunity to split interpolated values or maybe even uniforms which we don ' t have at the IR level . We want to split because virtual GRFs are what we register allocate and spill ( due to contiguousness requirements for some instructions ) and they ' re what we naturally generate in the codegen process but most virtual GRFs don ' t actually need to be contiguous sets of GRFs . If we split we ' ll end up with reduced live intervals and better dead code elimination and coalescing .
void
fs_visitor::split_virtual_grfs()
{
   int num_vars = this->virtual_grf_next;
   bool split_grf[num_vars];
   int new_virtual_grf[num_vars];
   for (int i = 0; i < num_vars; i++) {
      if (this->virtual_grf_sizes[i] != 1)
	 split_grf[i] = true;
      else
	 split_grf[i] = false;
   }
   if (brw->has_pln &&
       this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].file == GRF) {
      split_grf[this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].reg] =
         false;
   }
   foreach_list(node, &this->instructions) {
      fs_inst *inst = (fs_inst *)node;
      if (inst->is_tex()) {
	 split_grf[inst->dst.reg] = false;
      }
   }
   for (int i = 0; i < num_vars; i++) {
      if (split_grf[i]) {
	 new_virtual_grf[i] = virtual_grf_alloc(1);
	 for (int j = 2; j < this->virtual_grf_sizes[i]; j++) {
	    int reg = virtual_grf_alloc(1);
	    assert(reg == new_virtual_grf[i] + j - 1);
	    (void) reg;
	 }
	 this->virtual_grf_sizes[i] = 1;
      }
   }
   foreach_list(node, &this->instructions) {
      fs_inst *inst = (fs_inst *)node;
      if (inst->dst.file == GRF &&
	  split_grf[inst->dst.reg] &&
	  inst->dst.reg_offset != 0) {
	 inst->dst.reg = (new_virtual_grf[inst->dst.reg] +
			  inst->dst.reg_offset - 1);
	 inst->dst.reg_offset = 0;
      }
      for (int i = 0; i < 3; i++) {
	 if (inst->src[i].file == GRF &&
	     split_grf[inst->src[i].reg] &&
	     inst->src[i].reg_offset != 0) {
	    inst->src[i].reg = (new_virtual_grf[inst->src[i].reg] +
				inst->src[i].reg_offset - 1);
	    inst->src[i].reg_offset = 0;
	 }
      }
   }
   this->live_intervals_valid = false;
}
void fs_visitor :: split_virtual_grfs ( ) { int num_vars = this -> virtual_grf_next ; bool split_grf [ num_vars ] ; int new_virtual_grf [ num_vars ] ; for ( int i = 0 ; i < num_vars ; i ++ ) { if ( this -> virtual_grf_sizes [ i ] != 1 ) split_grf [ i ] = true ; else split_grf [ i ] = false ; } if ( brw -> has_pln && this -> delta_x [ BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC ] . file == GRF ) { split_grf [ this -> delta_x [ BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC ] . reg ] = false ; } foreach_list ( node , & this -> instructions ) { fs_inst * inst = ( fs_inst * ) node ; if ( inst -> is_tex ( ) ) { split_grf [ inst -> dst . reg ] = false ; } } for ( int i = 0 ; i < num_vars ; i ++ ) { if ( split_grf [ i ] ) { new_virtual_grf [ i ] = virtual_grf_alloc ( 1 ) ; for ( int j = 2 ; j < this -> virtual_grf_sizes [ i ] ; j ++ ) { int reg = virtual_grf_alloc ( 1 ) ; assert ( reg == new_virtual_grf [ i ] + j - 1 ) ; ( void ) reg ; } this -> virtual_grf_sizes [ i ] = 1 ; } } foreach_list ( node , & this -> instructions ) { fs_inst * inst = ( fs_inst * ) node ; if ( inst -> dst . file == GRF && split_grf [ inst -> dst . reg ] && inst -> dst . reg_offset != 0 ) { inst -> dst . reg = ( new_virtual_grf [ inst -> dst . reg ] + inst -> dst . reg_offset - 1 ) ; inst -> dst . reg_offset = 0 ; } for ( int i = 0 ; i < 3 ; i ++ ) { if ( inst -> src [ i ] . file == GRF && split_grf [ inst -> src [ i ] . reg ] && inst -> src [ i ] . reg_offset != 0 ) { inst -> src [ i ] . reg = ( new_virtual_grf [ inst -> src [ i ] . reg ] + inst -> src [ i ] . reg_offset - 1 ) ; inst -> src [ i ] . reg_offset = 0 ; } } } this -> live_intervals_valid = false ; }
Split large virtual GRFs into separate components if we can.
Split large virtual GRFs into separate components if we can .
/* Try to split anything > 0 sized. */ /* PLN opcodes rely on the delta_xy being contiguous.  We only have to
       * check this for BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC, because prior to
       * Gen6, that was the only supported interpolation mode, and since Gen6,
       * delta_x and delta_y are in fixed hardware registers.
       */ /* Texturing produces 4 contiguous registers, so no splitting. */ /* Allocate new space for split regs.  Note that the virtual
    * numbers will be contiguous.
    */