static void
lower_texcoord_array(struct gl_linked_shader *shader, const varying_info_visitor *info)
{
   replace_varyings_visitor(shader, info,
                            (1 << MAX_TEXTURE_COORD_UNITS) - 1,
                            1 | 2, true);
}
static void
lower_texcoord_array(exec_list *ir, const varying_info_visitor *info)
{
   replace_varyings_visitor(ir, info,
                            (1 << MAX_TEXTURE_COORD_UNITS) - 1,
                            1 | 2, true);
}
static void
lower_fragdata_array(struct gl_linked_shader *shader)
{
   varying_info_visitor info(ir_var_shader_out, true);
   info.get(shader->ir, 0, NULL);

   replace_varyings_visitor(shader, &info, 0, 0, 0);
}
static void
lower_fragdata_array(exec_list *ir)
{
   varying_info_visitor info(ir_var_shader_out, true);
   info.get(ir, 0, NULL);

   replace_varyings_visitor(ir, &info, 0, 0, 0);
}
void
do_dead_builtin_varyings(struct gl_context *ctx,
                         gl_linked_shader *producer,
                         gl_linked_shader *consumer,
                         unsigned num_tfeedback_decls,
                         tfeedback_decl *tfeedback_decls)
{
   /* Lower the gl_FragData array to separate variables. */
   if (consumer && consumer->Stage == MESA_SHADER_FRAGMENT) {
      lower_fragdata_array(consumer);
   }

   /* Lowering of built-in varyings has no effect with the core context and
    * GLES2, because they are not available there.
    */
   if (ctx->API == API_OPENGL_CORE ||
       ctx->API == API_OPENGLES2) {
      return;
   }

   /* Information about built-in varyings. */
   varying_info_visitor producer_info(ir_var_shader_out);
   varying_info_visitor consumer_info(ir_var_shader_in);

   if (producer) {
      producer_info.get(producer->ir, num_tfeedback_decls, tfeedback_decls);

      if (!consumer) {
         /* At least eliminate unused gl_TexCoord elements. */
         if (producer_info.lower_texcoord_array) {
            lower_texcoord_array(producer, &producer_info);
         }
         return;
      }
   }

   if (consumer) {
      consumer_info.get(consumer->ir, 0, NULL);

      if (!producer) {
         /* At least eliminate unused gl_TexCoord elements. */
         if (consumer_info.lower_texcoord_array) {
            lower_texcoord_array(consumer, &consumer_info);
         }
         return;
      }
   }

   /* Eliminate the outputs unused by the consumer. */
   if (producer_info.lower_texcoord_array ||
       producer_info.color_usage ||
       producer_info.has_fog) {
      replace_varyings_visitor(producer,
                               &producer_info,
                               consumer_info.texcoord_usage,
                               consumer_info.color_usage,
                               consumer_info.has_fog);
   }

   /* The gl_TexCoord fragment shader inputs can be initialized
    * by GL_COORD_REPLACE, so we can't eliminate them.
    *
    * This doesn't prevent elimination of the gl_TexCoord elements which
    * are not read by the fragment shader. We want to eliminate those anyway.
    */
   if (consumer->Stage == MESA_SHADER_FRAGMENT) {
      producer_info.texcoord_usage = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
   }

   /* Eliminate the inputs uninitialized by the producer. */
   if (consumer_info.lower_texcoord_array ||
       consumer_info.color_usage ||
       consumer_info.has_fog) {
      replace_varyings_visitor(consumer,
                               &consumer_info,
                               producer_info.texcoord_usage,
                               producer_info.color_usage,
                               producer_info.has_fog);
   }
}