Пример #1
0
 /**
  * Emit a typed surface read opcode.  \p dims determines the number of
  * components of the address and \p size the number of components of the
  * returned value.
  */
 fs_reg
 emit_typed_read(const fs_builder &bld, const fs_reg &surface,
                 const fs_reg &addr, unsigned dims, unsigned size)
 {
    return emit_send(bld, SHADER_OPCODE_TYPED_SURFACE_READ_LOGICAL,
                     addr, fs_reg(), surface, dims, size, size);
 }
Пример #2
0
void
brw_blorp_eu_emitter::emit_texture_lookup(const struct brw_reg &dst,
                                          enum opcode op,
                                          unsigned base_mrf,
                                          unsigned msg_length)
{
   fs_inst *inst = new (mem_ctx) fs_inst(op, dst, brw_message_reg(base_mrf),
                                         fs_reg(0u));

   inst->base_mrf = base_mrf;
   inst->mlen = msg_length;
   inst->header_size = 0;

   insts.push_tail(inst);
}
Пример #3
0
bool
fs_visitor::opt_cse_local(bblock_t *block, exec_list *aeb)
{
   bool progress = false;

   void *mem_ctx = ralloc_context(this->mem_ctx);

   for (fs_inst *inst = (fs_inst *)block->start;
	inst != block->end->next;
	inst = (fs_inst *) inst->next) {

      /* Skip some cases. */
      if (is_expression(inst) && !inst->predicate && inst->mlen == 0 &&
          !inst->force_uncompressed && !inst->force_sechalf &&
          !inst->conditional_mod)
      {
	 bool found = false;

	 aeb_entry *entry;
	 foreach_list(entry_node, aeb) {
	    entry = (aeb_entry *) entry_node;

	    /* Match current instruction's expression against those in AEB. */
	    if (inst->opcode == entry->generator->opcode &&
		inst->saturate == entry->generator->saturate &&
		operands_match(entry->generator->src, inst->src)) {

	       found = true;
	       progress = true;
	       break;
	    }
	 }

	 if (!found) {
	    /* Our first sighting of this expression.  Create an entry. */
	    aeb_entry *entry = ralloc(mem_ctx, aeb_entry);
	    entry->tmp = reg_undef;
	    entry->generator = inst;
	    aeb->push_tail(entry);
	 } else {
	    /* This is at least our second sighting of this expression.
	     * If we don't have a temporary already, make one.
	     */
	    bool no_existing_temp = entry->tmp.file == BAD_FILE;
	    if (no_existing_temp) {
	       entry->tmp = fs_reg(this, glsl_type::float_type);
	       entry->tmp.type = inst->dst.type;

	       fs_inst *copy = new(ralloc_parent(inst))
		  fs_inst(BRW_OPCODE_MOV, entry->generator->dst, entry->tmp);
	       entry->generator->insert_after(copy);
	       entry->generator->dst = entry->tmp;
	    }

	    /* dest <- temp */
	    fs_inst *copy = new(ralloc_parent(inst))
	       fs_inst(BRW_OPCODE_MOV, inst->dst, entry->tmp);
	    inst->replace_with(copy);

	    /* Appending an instruction may have changed our bblock end. */
	    if (inst == block->end) {
	       block->end = copy;
	    }

	    /* Continue iteration with copy->next */
	    inst = copy;
	 }
      }
bool
fs_visitor::dead_code_eliminate()
{
   bool progress = false;

   calculate_live_intervals();

   int num_vars = live_intervals->num_vars;
   BITSET_WORD *live = ralloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));

   foreach_block (block, cfg) {
      memcpy(live, live_intervals->bd[block->num].liveout,
             sizeof(BITSET_WORD) * BITSET_WORDS(num_vars));

      foreach_inst_in_block_reverse(fs_inst, inst, block) {
         if (inst->dst.file == GRF &&
             !inst->has_side_effects() &&
             !inst->writes_flag()) {
            bool result_live = false;

            if (inst->regs_written == 1) {
               int var = live_intervals->var_from_reg(&inst->dst);
               result_live = BITSET_TEST(live, var);
            } else {
               int var = live_intervals->var_from_vgrf[inst->dst.reg];
               for (int i = 0; i < inst->regs_written; i++) {
                  result_live = result_live || BITSET_TEST(live, var + i);
               }
            }

            if (!result_live) {
               progress = true;

               if (inst->writes_accumulator) {
                  inst->dst = fs_reg(retype(brw_null_reg(), inst->dst.type));
               } else {
                  inst->opcode = BRW_OPCODE_NOP;
                  continue;
               }
            }
         }

         if (inst->dst.file == GRF) {
            if (!inst->is_partial_write()) {
               int var = live_intervals->var_from_vgrf[inst->dst.reg];
               for (int i = 0; i < inst->regs_written; i++) {
                  BITSET_CLEAR(live, var + inst->dst.reg_offset + i);
               }
            }
         }

         for (int i = 0; i < inst->sources; i++) {
            if (inst->src[i].file == GRF) {
               int var = live_intervals->var_from_vgrf[inst->src[i].reg];

               for (int j = 0; j < inst->regs_read(this, i); j++) {
                  BITSET_SET(live, var + inst->src[i].reg_offset + j);
               }
            }
         }
      }
   }
Пример #5
0
bool
fs_visitor::opt_cse_local(bblock_t *block, exec_list *aeb)
{
   bool progress = false;

   void *cse_ctx = ralloc_context(NULL);

   int ip = block->start_ip;
   for (fs_inst *inst = (fs_inst *)block->start;
        inst != block->end->next;
        inst = (fs_inst *) inst->next) {

      /* Skip some cases. */
      if (is_expression(inst) && !inst->is_partial_write() &&
          (inst->dst.file != HW_REG || inst->dst.is_null()))
      {
         bool found = false;

         aeb_entry *entry;
         foreach_list(entry_node, aeb) {
            entry = (aeb_entry *) entry_node;

            /* Match current instruction's expression against those in AEB. */
            if (instructions_match(inst, entry->generator)) {
               found = true;
               progress = true;
               break;
            }
         }

         if (!found) {
            /* Our first sighting of this expression.  Create an entry. */
            aeb_entry *entry = ralloc(cse_ctx, aeb_entry);
            entry->tmp = reg_undef;
            entry->generator = inst;
            aeb->push_tail(entry);
         } else {
            /* This is at least our second sighting of this expression.
             * If we don't have a temporary already, make one.
             */
            bool no_existing_temp = entry->tmp.file == BAD_FILE;
            if (no_existing_temp && !entry->generator->dst.is_null()) {
               int written = entry->generator->regs_written;

               fs_reg orig_dst = entry->generator->dst;
               fs_reg tmp = fs_reg(GRF, virtual_grf_alloc(written),
                                   orig_dst.type);
               entry->tmp = tmp;
               entry->generator->dst = tmp;

               fs_inst *copy;
               if (written > 1) {
                  fs_reg *sources = ralloc_array(mem_ctx, fs_reg, written);
                  for (int i = 0; i < written; i++) {
                     sources[i] = tmp;
                     sources[i].reg_offset = i;
                  }
                  copy = LOAD_PAYLOAD(orig_dst, sources, written);
               } else {
                  copy = MOV(orig_dst, tmp);
                  copy->force_writemask_all =
                     entry->generator->force_writemask_all;
               }
               entry->generator->insert_after(copy);
            }

            /* dest <- temp */
            if (!inst->dst.is_null()) {
               int written = inst->regs_written;
               assert(written == entry->generator->regs_written);
               assert(inst->dst.type == entry->tmp.type);
               fs_reg dst = inst->dst;
               fs_reg tmp = entry->tmp;
               fs_inst *copy;
               if (written > 1) {
                  fs_reg *sources = ralloc_array(mem_ctx, fs_reg, written);
                  for (int i = 0; i < written; i++) {
                     sources[i] = tmp;
                     sources[i].reg_offset = i;
                  }
                  copy = LOAD_PAYLOAD(dst, sources, written);
               } else {
                  copy = MOV(dst, tmp);
                  copy->force_writemask_all = inst->force_writemask_all;
               }
               inst->insert_before(copy);
            }

            /* Set our iterator so that next time through the loop inst->next
             * will get the instruction in the basic block after the one we've
             * removed.
             */
            fs_inst *prev = (fs_inst *)inst->prev;

            inst->remove();

            /* Appending an instruction may have changed our bblock end. */
            if (inst == block->end) {
               block->end = prev;
            }

            inst = prev;
         }
      }
Пример #6
0
bool
fs_visitor::opt_cse_local(bblock_t *block, exec_list *aeb)
{
   bool progress = false;

   void *mem_ctx = ralloc_context(this->mem_ctx);

   int ip = block->start_ip;
   for (fs_inst *inst = (fs_inst *)block->start;
	inst != block->end->next;
	inst = (fs_inst *) inst->next) {

      /* Skip some cases. */
      if (is_expression(inst) &&
          !inst->predicate &&
          !inst->is_partial_write() &&
          !inst->conditional_mod)
      {
	 bool found = false;

	 aeb_entry *entry;
	 foreach_list(entry_node, aeb) {
	    entry = (aeb_entry *) entry_node;

	    /* Match current instruction's expression against those in AEB. */
	    if (inst->opcode == entry->generator->opcode &&
		inst->saturate == entry->generator->saturate &&
                inst->dst.type == entry->generator->dst.type &&
                operands_match(entry->generator->src, inst->src)) {

	       found = true;
	       progress = true;
	       break;
	    }
	 }

	 if (!found) {
	    /* Our first sighting of this expression.  Create an entry. */
	    aeb_entry *entry = ralloc(mem_ctx, aeb_entry);
	    entry->tmp = reg_undef;
	    entry->generator = inst;
	    aeb->push_tail(entry);
	 } else {
	    /* This is at least our second sighting of this expression.
	     * If we don't have a temporary already, make one.
	     */
	    bool no_existing_temp = entry->tmp.file == BAD_FILE;
	    if (no_existing_temp) {
               int written = entry->generator->regs_written;

               fs_reg orig_dst = entry->generator->dst;
               fs_reg tmp = fs_reg(GRF, virtual_grf_alloc(written),
                                   orig_dst.type);
               entry->tmp = tmp;
               entry->generator->dst = tmp;

               for (int i = 0; i < written; i++) {
                  fs_inst *copy = MOV(orig_dst, tmp);
                  copy->force_writemask_all =
                     entry->generator->force_writemask_all;
                  entry->generator->insert_after(copy);

                  orig_dst.reg_offset++;
                  tmp.reg_offset++;
               }
	    }

	    /* dest <- temp */
            int written = inst->regs_written;
            assert(written == entry->generator->regs_written);
            assert(inst->dst.type == entry->tmp.type);
            fs_reg dst = inst->dst;
            fs_reg tmp = entry->tmp;
            fs_inst *copy = NULL;
            for (int i = 0; i < written; i++) {
               copy = MOV(dst, tmp);
               copy->force_writemask_all = inst->force_writemask_all;
               inst->insert_before(copy);

               dst.reg_offset++;
               tmp.reg_offset++;
            }
            inst->remove();

	    /* Appending an instruction may have changed our bblock end. */
	    if (inst == block->end) {
	       block->end = copy;
	    }

	    /* Continue iteration with copy->next */
	    inst = copy;
	 }
      }