Пример #1
0
static bool
loop_is_dead(nir_loop *loop)
{
   nir_block *before = nir_cf_node_as_block(nir_cf_node_prev(&loop->cf_node));
   nir_block *after = nir_cf_node_as_block(nir_cf_node_next(&loop->cf_node));

   if (!exec_list_is_empty(&after->instr_list) &&
       nir_block_first_instr(after)->type == nir_instr_type_phi)
      return false;

   if (!nir_foreach_block_in_cf_node(&loop->cf_node, block_has_no_side_effects,
                                     NULL))
      return false;

   nir_function_impl *impl = nir_cf_node_get_function(&loop->cf_node);
   nir_metadata_require(impl, nir_metadata_live_variables |
                              nir_metadata_dominance);

   for (nir_block *cur = after->imm_dom; cur != before; cur = cur->imm_dom) {
      nir_foreach_instr(cur, instr) {
         if (!nir_foreach_ssa_def(instr, def_not_live_out, after))
            return false;
      }
   }

   return true;
}
Пример #2
0
static bool
constant_fold_intrinsic_instr(nir_intrinsic_instr *instr)
{
   bool progress = false;

   if (instr->intrinsic == nir_intrinsic_discard_if &&
       nir_src_is_const(instr->src[0])) {
      if (nir_src_as_bool(instr->src[0])) {
         /* This method of getting a nir_shader * from a nir_instr is
          * admittedly gross, but given the rarity of hitting this case I think
          * it's preferable to plumbing an otherwise unused nir_shader *
          * parameter through four functions to get here.
          */
         nir_cf_node *cf_node = &instr->instr.block->cf_node;
         nir_function_impl *impl = nir_cf_node_get_function(cf_node);
         nir_shader *shader = impl->function->shader;

         nir_intrinsic_instr *discard =
            nir_intrinsic_instr_create(shader, nir_intrinsic_discard);
         nir_instr_insert_before(&instr->instr, &discard->instr);
         nir_instr_remove(&instr->instr);
         progress = true;
      } else {
         /* We're not discarding, just delete the instruction */
         nir_instr_remove(&instr->instr);
         progress = true;
      }
   }

   return progress;
}
static void
lower_load_const_instr_scalar(nir_load_const_instr *lower)
{
   if (lower->def.num_components == 1)
      return;

   nir_builder b;
   nir_builder_init(&b, nir_cf_node_get_function(&lower->instr.block->cf_node));
   b.cursor = nir_before_instr(&lower->instr);

   /* Emit the individual loads. */
   nir_ssa_def *loads[4];
   for (unsigned i = 0; i < lower->def.num_components; i++) {
      nir_load_const_instr *load_comp = nir_load_const_instr_create(b.shader, 1);
      load_comp->value.u[0] = lower->value.u[i];
      nir_builder_instr_insert(&b, &load_comp->instr);
      loads[i] = &load_comp->def;
   }

   /* Batch things back together into a vector. */
   nir_ssa_def *vec = nir_vec(&b, loads, lower->def.num_components);

   /* Replace the old load with a reference to our reconstructed vector. */
   nir_ssa_def_rewrite_uses(&lower->def, nir_src_for_ssa(vec));
   nir_instr_remove(&lower->instr);
}
Пример #4
0
static bool
vc4_nir_lower_txf_ms_block(nir_block *block, void *arg)
{
    struct vc4_compile *c = arg;
    nir_function_impl *impl =
        nir_cf_node_get_function(&block->cf_node);

    nir_builder b;
    nir_builder_init(&b, impl);

    nir_foreach_instr_safe(block, instr) {
        if (instr->type == nir_instr_type_tex) {
            vc4_nir_lower_txf_ms_instr(c, &b,
                                       nir_instr_as_tex(instr));
        }
    }

    return true;
}