i965/vec4: split VEC4_OPCODE_FROM_DOUBLE into one opcode per destination's type
[mesa.git] / src / compiler / nir / nir_inline_functions.c
index a4365b5db231a179391df966ad1a70e3063567fe..b91e7bc86da8f0192eeb429f15b7e89febde4d01 100644 (file)
 static bool inline_function_impl(nir_function_impl *impl, struct set *inlined);
 
 static void
-rewrite_param_derefs(nir_instr *instr, nir_call_instr *call)
+convert_deref_to_param_deref(nir_instr *instr, nir_deref_var **deref,
+                             nir_call_instr *call)
 {
-   if (instr->type != nir_instr_type_intrinsic)
+   /* This isn't a parameter, just return the deref */
+   if ((*deref)->var->data.mode != nir_var_param)
       return;
 
-   nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
+   int param_idx = (*deref)->var->data.location;
 
-   for (unsigned i = 0;
-        i < nir_intrinsic_infos[intrin->intrinsic].num_variables; i++) {
-      if (intrin->variables[i]->var->data.mode != nir_var_param)
-         continue;
+   nir_deref_var *call_deref;
+   if (param_idx >= 0) {
+      assert(param_idx < call->callee->num_params);
+      call_deref = call->params[param_idx];
+   } else {
+      call_deref = call->return_deref;
+   }
+   assert(call_deref);
+
+   /* Now we make a new deref by concatenating the deref in the call's
+    * parameter with the deref we were given.
+    */
+   nir_deref_var *new_deref = nir_deref_var_clone(call_deref, instr);
+   nir_deref *new_tail = nir_deref_tail(&new_deref->deref);
+   new_tail->child = (*deref)->deref.child;
+   ralloc_steal(new_tail, new_tail->child);
+   *deref = new_deref;
+}
 
-      int param_idx = intrin->variables[i]->var->data.location;
+static void
+rewrite_param_derefs(nir_instr *instr, nir_call_instr *call)
+{
+   switch (instr->type) {
+   case nir_instr_type_intrinsic: {
+      nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
 
-      nir_deref_var *call_deref;
-      if (param_idx >= 0) {
-         assert(param_idx < call->callee->num_params);
-         call_deref = call->params[param_idx];
-      } else {
-         call_deref = call->return_deref;
+      for (unsigned i = 0;
+           i < nir_intrinsic_infos[intrin->intrinsic].num_variables; i++) {
+         convert_deref_to_param_deref(instr, &intrin->variables[i], call);
       }
-      assert(call_deref);
+      break;
+   }
+
+   case nir_instr_type_tex: {
+      nir_tex_instr *tex = nir_instr_as_tex(instr);
+      if (tex->texture)
+         convert_deref_to_param_deref(&tex->instr, &tex->texture, call);
+      if (tex->sampler)
+         convert_deref_to_param_deref(&tex->instr, &tex->sampler, call);
+      break;
+   }
 
-      nir_deref_var *new_deref = nir_deref_as_var(nir_copy_deref(intrin, &call_deref->deref));
-      nir_deref *new_tail = nir_deref_tail(&new_deref->deref);
-      new_tail->child = intrin->variables[i]->deref.child;
-      ralloc_steal(new_tail, new_tail->child);
-      intrin->variables[i] = new_deref;
+   default:
+      break; /* Nothing else has derefs */
    }
 }