/*
 * Copyright © 2011 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/**
 * \file test_optpass.cpp
 *
 * Standalone test for optimization passes.
 *
 * This file provides the "optpass" command for the standalone
 * glsl_test app.  It accepts either GLSL or high-level IR as input,
 * and performs the optimiation passes specified on the command line.
 * It outputs the IR, both before and after optimiations.
 */

#include <string>
#include <iostream>
#include <sstream>
#include <getopt.h>

#include "ast.h"
#include "ir_optimization.h"
#include "program.h"
#include "ir_reader.h"
#include "standalone_scaffolding.h"
#include "main/mtypes.h"

using namespace std;

static string read_stdin_to_eof()
{
   stringbuf sb;
   cin.get(sb, '\0');
   return sb.str();
}

static GLboolean
do_optimization(struct exec_list *ir, const char *optimization,
                const struct gl_shader_compiler_options *options)
{
   int int_0;
   int int_1;
   int int_2;
   int int_3;
   int int_4;

   if (sscanf(optimization, "do_common_optimization ( %d ) ", &int_0) == 1) {
      return do_common_optimization(ir, int_0 != 0, false, options, true);
   } else if (strcmp(optimization, "do_algebraic") == 0) {
      return do_algebraic(ir, true, options);
   } else if (strcmp(optimization, "do_constant_folding") == 0) {
      return do_constant_folding(ir);
   } else if (strcmp(optimization, "do_constant_variable") == 0) {
      return do_constant_variable(ir);
   } else if (strcmp(optimization, "do_constant_variable_unlinked") == 0) {
      return do_constant_variable_unlinked(ir);
   } else if (strcmp(optimization, "do_copy_propagation_elements") == 0) {
      return do_copy_propagation_elements(ir);
   } else if (strcmp(optimization, "do_constant_propagation") == 0) {
      return do_constant_propagation(ir);
   } else if (strcmp(optimization, "do_dead_code") == 0) {
      return do_dead_code(ir, false);
   } else if (strcmp(optimization, "do_dead_code_local") == 0) {
      return do_dead_code_local(ir);
   } else if (strcmp(optimization, "do_dead_code_unlinked") == 0) {
      return do_dead_code_unlinked(ir);
   } else if (strcmp(optimization, "do_dead_functions") == 0) {
      return do_dead_functions(ir);
   } else if (strcmp(optimization, "do_function_inlining") == 0) {
      return do_function_inlining(ir);
   } else if (sscanf(optimization,
                     "do_lower_jumps ( %d , %d , %d , %d , %d ) ",
                     &int_0, &int_1, &int_2, &int_3, &int_4) == 5) {
      return do_lower_jumps(ir, int_0 != 0, int_1 != 0, int_2 != 0,
                            int_3 != 0, int_4 != 0);
   } else if (strcmp(optimization, "do_lower_texture_projection") == 0) {
      return do_lower_texture_projection(ir);
   } else if (strcmp(optimization, "do_if_simplification") == 0) {
      return do_if_simplification(ir);
   } else if (sscanf(optimization, "lower_if_to_cond_assign ( %d ) ",
                     &int_0) == 1) {
      return lower_if_to_cond_assign(MESA_SHADER_VERTEX, ir, int_0);
   } else if (strcmp(optimization, "do_mat_op_to_vec") == 0) {
      return do_mat_op_to_vec(ir);
   } else if (strcmp(optimization, "optimize_swizzles") == 0) {
      return optimize_swizzles(ir);
   } else if (strcmp(optimization, "do_structure_splitting") == 0) {
      return do_structure_splitting(ir);
   } else if (strcmp(optimization, "do_tree_grafting") == 0) {
      return do_tree_grafting(ir);
   } else if (strcmp(optimization, "do_vec_index_to_cond_assign") == 0) {
      return do_vec_index_to_cond_assign(ir);
   } else if (strcmp(optimization, "do_vec_index_to_swizzle") == 0) {
      return do_vec_index_to_swizzle(ir);
   } else if (strcmp(optimization, "lower_discard") == 0) {
      return lower_discard(ir);
   } else if (sscanf(optimization, "lower_instructions ( %d ) ",
                     &int_0) == 1) {
      return lower_instructions(ir, int_0);
   } else if (strcmp(optimization, "lower_noise") == 0) {
      return lower_noise(ir);
   } else if (sscanf(optimization, "lower_variable_index_to_cond_assign "
                     "( %d , %d , %d , %d ) ", &int_0, &int_1, &int_2,
                     &int_3) == 4) {
      return lower_variable_index_to_cond_assign(MESA_SHADER_VERTEX, ir,
                                                 int_0 != 0, int_1 != 0,
                                                 int_2 != 0, int_3 != 0);
   } else if (sscanf(optimization, "lower_quadop_vector ( %d ) ",
                     &int_0) == 1) {
      return lower_quadop_vector(ir, int_0 != 0);
   } else if (strcmp(optimization, "optimize_redundant_jumps") == 0) {
      return optimize_redundant_jumps(ir);
   } else {
      printf("Unrecognized optimization %s\n", optimization);
      exit(EXIT_FAILURE);
      return false;
   }
}

static GLboolean
do_optimization_passes(struct exec_list *ir, char **optimizations,
                       int num_optimizations, bool quiet,
                       const struct gl_shader_compiler_options *options)
{
   GLboolean overall_progress = false;

   for (int i = 0; i < num_optimizations; ++i) {
      const char *optimization = optimizations[i];
      if (!quiet) {
         printf("*** Running optimization %s...", optimization);
      }
      GLboolean progress = do_optimization(ir, optimization, options);
      if (!quiet) {
         printf("%s\n", progress ? "progress" : "no progress");
      }
      validate_ir_tree(ir);

      overall_progress = overall_progress || progress;
   }

   return overall_progress;
}

int test_optpass(int argc, char **argv)
{
   int input_format_ir = 0; /* 0=glsl, 1=ir */
   int loop = 0;
   int shader_type = GL_VERTEX_SHADER;
   int quiet = 0;
   int error;

   const struct option optpass_opts[] = {
      { "input-ir", no_argument, &input_format_ir, 1 },
      { "input-glsl", no_argument, &input_format_ir, 0 },
      { "loop", no_argument, &loop, 1 },
      { "vertex-shader", no_argument, &shader_type, GL_VERTEX_SHADER },
      { "fragment-shader", no_argument, &shader_type, GL_FRAGMENT_SHADER },
      { "quiet", no_argument, &quiet, 1 },
      { NULL, 0, NULL, 0 }
   };

   int idx = 0;
   int c;
   while ((c = getopt_long(argc, argv, "", optpass_opts, &idx)) != -1) {
      if (c != 0) {
         printf("*** usage: %s optpass <optimizations> <options>\n", argv[0]);
         printf("\n");
         printf("Possible options are:\n");
         printf("  --input-ir: input format is IR\n");
         printf("  --input-glsl: input format is GLSL (the default)\n");
         printf("  --loop: run optimizations repeatedly until no progress\n");
         printf("  --vertex-shader: test with a vertex shader (the default)\n");
         printf("  --fragment-shader: test with a fragment shader\n");
         exit(EXIT_FAILURE);
      }
   }

   struct gl_context local_ctx;
   struct gl_context *ctx = &local_ctx;
   initialize_context_to_defaults(ctx, API_OPENGL_COMPAT);

   ir_variable::temporaries_allocate_names = true;

   struct gl_shader *shader = rzalloc(NULL, struct gl_shader);
   shader->Type = shader_type;
   shader->Stage = _mesa_shader_enum_to_shader_stage(shader_type);

   string input = read_stdin_to_eof();

   struct _mesa_glsl_parse_state *state
      = new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader);

   if (input_format_ir) {
      shader->ir = new(shader) exec_list;
      _mesa_glsl_initialize_types(state);
      _mesa_glsl_read_ir(state, shader->ir, input.c_str(), true);
   } else {
      shader->Source = input.c_str();
      const char *source = shader->Source;
      state->error = glcpp_preprocess(state, &source, &state->info_log,
                                      NULL, NULL, ctx) != 0;

      if (!state->error) {
         _mesa_glsl_lexer_ctor(state, source);
         _mesa_glsl_parse(state);
         _mesa_glsl_lexer_dtor(state);
      }

      shader->ir = new(shader) exec_list;
      if (!state->error && !state->translation_unit.is_empty())
         _mesa_ast_to_hir(shader->ir, state);
   }

   /* Print out the initial IR */
   if (!state->error && !quiet) {
      printf("*** pre-optimization IR:\n");
      _mesa_print_ir(stdout, shader->ir, state);
      printf("\n--\n");
   }

   /* Optimization passes */
   if (!state->error) {
      GLboolean progress;
      const struct gl_shader_compiler_options *options =
         &ctx->Const.ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(shader_type)];
      do {
         progress = do_optimization_passes(shader->ir, &argv[optind],
                                           argc - optind, quiet != 0, options);
      } while (loop && progress);
   }

   /* Print out the resulting IR */
   if (!state->error) {
      if (!quiet) {
         printf("*** resulting IR:\n");
      }
      _mesa_print_ir(stdout, shader->ir, state);
      if (!quiet) {
         printf("\n--\n");
      }
   }

   if (state->error) {
      printf("*** error(s) occurred:\n");
      printf("%s\n", state->info_log);
      printf("--\n");
   }

   error = state->error;

   ralloc_free(state);
   ralloc_free(shader);

   return error;
}

