// Copyright (c) 2016 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <algorithm>
#include <cassert>
#include <cstring>
#include <fstream>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

#include "source/opt/log.h"
#include "source/spirv_target_env.h"
#include "source/util/string_utils.h"
#include "spirv-tools/libspirv.hpp"
#include "spirv-tools/optimizer.hpp"
#include "tools/io.h"
#include "tools/util/cli_consumer.h"

namespace {

// Status and actions to perform after parsing command-line arguments.
enum OptActions { OPT_CONTINUE, OPT_STOP };

struct OptStatus {
  OptActions action;
  int code;
};

// Message consumer for this tool.  Used to emit diagnostics during
// initialization and setup. Note that |source| and |position| are irrelevant
// here because we are still not processing a SPIR-V input file.
void opt_diagnostic(spv_message_level_t level, const char* /*source*/,
                    const spv_position_t& /*positon*/, const char* message) {
  if (level == SPV_MSG_ERROR) {
    fprintf(stderr, "error: ");
  }
  fprintf(stderr, "%s\n", message);
}

std::string GetListOfPassesAsString(const spvtools::Optimizer& optimizer) {
  std::stringstream ss;
  for (const auto& name : optimizer.GetPassNames()) {
    ss << "\n\t\t" << name;
  }
  return ss.str();
}

const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_3;

std::string GetLegalizationPasses() {
  spvtools::Optimizer optimizer(kDefaultEnvironment);
  optimizer.RegisterLegalizationPasses();
  return GetListOfPassesAsString(optimizer);
}

std::string GetOptimizationPasses() {
  spvtools::Optimizer optimizer(kDefaultEnvironment);
  optimizer.RegisterPerformancePasses();
  return GetListOfPassesAsString(optimizer);
}

std::string GetSizePasses() {
  spvtools::Optimizer optimizer(kDefaultEnvironment);
  optimizer.RegisterSizePasses();
  return GetListOfPassesAsString(optimizer);
}

std::string GetWebGPUPasses() {
  spvtools::Optimizer optimizer(SPV_ENV_WEBGPU_0);
  optimizer.RegisterWebGPUPasses();
  return GetListOfPassesAsString(optimizer);
}

void PrintUsage(const char* program) {
  // NOTE: Please maintain flags in lexicographical order.
  printf(
      R"(%s - Optimize a SPIR-V binary file.

USAGE: %s [options] [<input>] -o <output>

The SPIR-V binary is read from <input>. If no file is specified,
or if <input> is "-", then the binary is read from standard input.
if <output> is "-", then the optimized output is written to
standard output.

NOTE: The optimizer is a work in progress.

Options (in lexicographical order):
  --ccp
               Apply the conditional constant propagation transform.  This will
               propagate constant values throughout the program, and simplify
               expressions and conditional jumps with known predicate
               values.  Performed on entry point call tree functions and
               exported functions.
  --cfg-cleanup
               Cleanup the control flow graph. This will remove any unnecessary
               code from the CFG like unreachable code. Performed on entry
               point call tree functions and exported functions.
  --combine-access-chains
               Combines chained access chains to produce a single instruction
               where possible.
  --compact-ids
               Remap result ids to a compact range starting from %%1 and without
               any gaps.
  --convert-local-access-chains
               Convert constant index access chain loads/stores into
               equivalent load/stores with inserts and extracts. Performed
               on function scope variables referenced only with load, store,
               and constant index access chains in entry point call tree
               functions.
  --copy-propagate-arrays
               Does propagation of memory references when an array is a copy of
               another.  It will only propagate an array if the source is never
               written to, and the only store to the target is the copy.
  --eliminate-common-uniform
               Perform load/load elimination for duplicate uniform values.
               Converts any constant index access chain uniform loads into
               its equivalent load and extract. Some loads will be moved
               to facilitate sharing. Performed only on entry point
               call tree functions.
  --eliminate-dead-branches
               Convert conditional branches with constant condition to the
               indicated unconditional brranch. Delete all resulting dead
               code. Performed only on entry point call tree functions.
  --eliminate-dead-code-aggressive
               Delete instructions which do not contribute to a function's
               output. Performed only on entry point call tree functions.
  --eliminate-dead-const
               Eliminate dead constants.
  --eliminate-dead-functions
               Deletes functions that cannot be reached from entry points or
               exported functions.
  --eliminate-dead-inserts
               Deletes unreferenced inserts into composites, most notably
               unused stores to vector components, that are not removed by
               aggressive dead code elimination.
  --eliminate-dead-variables
               Deletes module scope variables that are not referenced.
  --eliminate-insert-extract
               DEPRECATED.  This pass has been replaced by the simplification
               pass, and that pass will be run instead.
               See --simplify-instructions.
  --eliminate-local-multi-store
               Replace stores and loads of function scope variables that are
               stored multiple times. Performed on variables referenceed only
               with loads and stores. Performed only on entry point call tree
               functions.
  --eliminate-local-single-block
               Perform single-block store/load and load/load elimination.
               Performed only on function scope variables in entry point
               call tree functions.
  --eliminate-local-single-store
               Replace stores and loads of function scope variables that are
               only stored once. Performed on variables referenceed only with
               loads and stores. Performed only on entry point call tree
               functions.
  --flatten-decorations
               Replace decoration groups with repeated OpDecorate and
               OpMemberDecorate instructions.
  --fold-spec-const-op-composite
               Fold the spec constants defined by OpSpecConstantOp or
               OpSpecConstantComposite instructions to front-end constants
               when possible.
  --freeze-spec-const
               Freeze the values of specialization constants to their default
               values.
  --generate-webgpu-initializers
               Adds initial values to OpVariable instructions that are missing
               them, due to their storage type requiring them for WebGPU.
  --if-conversion
               Convert if-then-else like assignments into OpSelect.
  --inline-entry-points-exhaustive
               Exhaustively inline all function calls in entry point call tree
               functions. Currently does not inline calls to functions with
               early return in a loop.
  --legalize-hlsl
               Runs a series of optimizations that attempts to take SPIR-V
               generated by an HLSL front-end and generates legal Vulkan SPIR-V.
               The optimizations are:
               %s

               Note this does not guarantee legal code. This option passes the
               option --relax-logical-pointer to the validator.
  --local-redundancy-elimination
               Looks for instructions in the same basic block that compute the
               same value, and deletes the redundant ones.
  --loop-fission
               Splits any top level loops in which the register pressure has
               exceeded a given threshold. The threshold must follow the use of
               this flag and must be a positive integer value.
  --loop-fusion
               Identifies adjacent loops with the same lower and upper bound.
               If this is legal, then merge the loops into a single loop.
               Includes heuristics to ensure it does not increase number of
               registers too much, while reducing the number of loads from
               memory. Takes an additional positive integer argument to set
               the maximum number of registers.
  --loop-invariant-code-motion
               Identifies code in loops that has the same value for every
               iteration of the loop, and move it to the loop pre-header.
  --loop-unroll
               Fully unrolls loops marked with the Unroll flag
  --loop-unroll-partial
               Partially unrolls loops marked with the Unroll flag. Takes an
               additional non-0 integer argument to set the unroll factor, or
               how many times a loop body should be duplicated
  --loop-peeling
               Execute few first (respectively last) iterations before
               (respectively after) the loop if it can elide some branches.
  --loop-peeling-threshold
               Takes a non-0 integer argument to set the loop peeling code size
               growth threshold. The threshold prevents the loop peeling
               from happening if the code size increase created by
               the optimization is above the threshold.
  --max-id-bound=<n>
               Sets the maximum value for the id bound for the moudle.  The
               default is the minimum value for this limit, 0x3FFFFF.  See
               section 2.17 of the Spir-V specification.
  --merge-blocks
               Join two blocks into a single block if the second has the
               first as its only predecessor. Performed only on entry point
               call tree functions.
  --merge-return
               Changes functions that have multiple return statements so they
               have a single return statement.

               For structured control flow it is assumed that the only
               unreachable blocks in the function are trivial merge and continue
               blocks.

               A trivial merge block contains the label and an OpUnreachable
               instructions, nothing else.  A trivial continue block contain a
               label and an OpBranch to the header, nothing else.

               These conditions are guaranteed to be met after running
               dead-branch elimination.
  --loop-unswitch
               Hoists loop-invariant conditionals out of loops by duplicating
               the loop on each branch of the conditional and adjusting each
               copy of the loop.
  -O
               Optimize for performance. Apply a sequence of transformations
               in an attempt to improve the performance of the generated
               code. For this version of the optimizer, this flag is equivalent
               to specifying the following optimization code names:
               %s
  -Os
               Optimize for size. Apply a sequence of transformations in an
               attempt to minimize the size of the generated code. For this
               version of the optimizer, this flag is equivalent to specifying
               the following optimization code names:
               %s

               NOTE: The specific transformations done by -O and -Os change
                     from release to release.
  -Oconfig=<file>
               Apply the sequence of transformations indicated in <file>.
               This file contains a sequence of strings separated by whitespace
               (tabs, newlines or blanks). Each string is one of the flags
               accepted by spirv-opt. Optimizations will be applied in the
               sequence they appear in the file. This is equivalent to
               specifying all the flags on the command line. For example,
               given the file opts.cfg with the content:

                --inline-entry-points-exhaustive
                --eliminate-dead-code-aggressive

               The following two invocations to spirv-opt are equivalent:

               $ spirv-opt -Oconfig=opts.cfg program.spv

               $ spirv-opt --inline-entry-points-exhaustive \
                    --eliminate-dead-code-aggressive program.spv

               Lines starting with the character '#' in the configuration
               file indicate a comment and will be ignored.

               The -O, -Os, and -Oconfig flags act as macros. Using one of them
               is equivalent to explicitly inserting the underlying flags at
               that position in the command line. For example, the invocation
               'spirv-opt --merge-blocks -O ...' applies the transformation
               --merge-blocks followed by all the transformations implied by
               -O.
  --print-all
               Print SPIR-V assembly to standard error output before each pass
               and after the last pass.
  --private-to-local
               Change the scope of private variables that are used in a single
               function to that function.
  --reduce-load-size
               Replaces loads of composite objects where not every component is
               used by loads of just the elements that are used.
  --redundancy-elimination
               Looks for instructions in the same function that compute the
               same value, and deletes the redundant ones.
  --relax-struct-store
               Allow store from one struct type to a different type with
               compatible layout and members. This option is forwarded to the
               validator.
  --remove-duplicates
               Removes duplicate types, decorations, capabilities and extension
               instructions.
  --replace-invalid-opcode
               Replaces instructions whose opcode is valid for shader modules,
               but not for the current shader stage.  To have an effect, all
               entry points must have the same execution model.
  --ssa-rewrite
               Replace loads and stores to function local variables with
               operations on SSA IDs.
  --scalar-replacement[=<n>]
               Replace aggregate function scope variables that are only accessed
               via their elements with new function variables representing each
               element.  <n> is a limit on the size of the aggragates that will
               be replaced.  0 means there is no limit.  The default value is
               100.
  --set-spec-const-default-value "<spec id>:<default value> ..."
               Set the default values of the specialization constants with
               <spec id>:<default value> pairs specified in a double-quoted
               string. <spec id>:<default value> pairs must be separated by
               blank spaces, and in each pair, spec id and default value must
               be separated with colon ':' without any blank spaces in between.
               e.g.: --set-spec-const-default-value "1:100 2:400"
  --simplify-instructions
               Will simplify all instructions in the function as much as
               possible.
  --skip-validation
               Will not validate the SPIR-V before optimizing.  If the SPIR-V
               is invalid, the optimizer may fail or generate incorrect code.
               This options should be used rarely, and with caution.
  --strength-reduction
               Replaces instructions with equivalent and less expensive ones.
  --strip-atomic-counter-memory
               Removes AtomicCountMemory bit from memory semantics values.
  --strip-debug
               Remove all debug instructions.
  --strip-reflect
               Remove all reflection information.  For now, this covers
               reflection information defined by SPV_GOOGLE_hlsl_functionality1.
  --target-env=<env>
               Set the target environment. Without this flag the target
               enviroment defaults to spv1.3.
               <env> must be one of vulkan1.0, vulkan1.1, opencl2.2, spv1.0,
               spv1.1, spv1.2, spv1.3, or webgpu0.
  --time-report
               Print the resource utilization of each pass (e.g., CPU time,
               RSS) to standard error output. Currently it supports only Unix
               systems. This option is the same as -ftime-report in GCC. It
               prints CPU/WALL/USR/SYS time (and RSS if possible), but note that
               USR/SYS time are returned by getrusage() and can have a small
               error.
  --upgrade-memory-model
               Upgrades the Logical GLSL450 memory model to Logical VulkanKHR.
               Transforms memory, image, atomic and barrier operations to conform
               to that model's requirements.
  --vector-dce
               This pass looks for components of vectors that are unused, and
               removes them from the vector.  Note this would still leave around
               lots of dead code that a pass of ADCE will be able to remove.
  --webgpu-mode
               Turns on the prescribed passes for WebGPU and sets the target
               environmet to webgpu0. Other passes may be turned on via
               additional flags, but such combinations are not tested.
               Using --target-env with this flag is not allowed.

               This flag is the equivalent of passing in --target-env=webgpu0
               and specifying the following optimization code names:
               %s

               NOTE: This flag is a WIP and its behaviour is subject to change.
  --workaround-1209
               Rewrites instructions for which there are known driver bugs to
               avoid triggering those bugs.
               Current workarounds: Avoid OpUnreachable in loops.
  --unify-const
               Remove the duplicated constants.
  --validate-after-all
               Validate the module after each pass is performed.
  -h, --help
               Print this help.
  --version
               Display optimizer version information.
)",
      program, program, GetLegalizationPasses().c_str(),
      GetOptimizationPasses().c_str(), GetSizePasses().c_str(),
      GetWebGPUPasses().c_str());
}

// Reads command-line flags  the file specified in |oconfig_flag|. This string
// is assumed to have the form "-Oconfig=FILENAME". This function parses the
// string and extracts the file name after the '=' sign.
//
// Flags found in |FILENAME| are pushed at the end of the vector |file_flags|.
//
// This function returns true on success, false on failure.
bool ReadFlagsFromFile(const char* oconfig_flag,
                       std::vector<std::string>* file_flags) {
  const char* fname = strchr(oconfig_flag, '=');
  if (fname == nullptr || fname[0] != '=') {
    spvtools::Errorf(opt_diagnostic, nullptr, {}, "Invalid -Oconfig flag %s",
                     oconfig_flag);
    return false;
  }
  fname++;

  std::ifstream input_file;
  input_file.open(fname);
  if (input_file.fail()) {
    spvtools::Errorf(opt_diagnostic, nullptr, {}, "Could not open file '%s'",
                     fname);
    return false;
  }

  std::string line;
  while (std::getline(input_file, line)) {
    // Ignore empty lines and lines starting with the comment marker '#'.
    if (line.length() == 0 || line[0] == '#') {
      continue;
    }

    // Tokenize the line.  Add all found tokens to the list of found flags. This
    // mimics the way the shell will parse whitespace on the command line. NOTE:
    // This does not support quoting and it is not intended to.
    std::istringstream iss(line);
    while (!iss.eof()) {
      std::string flag;
      iss >> flag;
      file_flags->push_back(flag);
    }
  }

  return true;
}

OptStatus ParseFlags(int argc, const char** argv,
                     spvtools::Optimizer* optimizer, const char** in_file,
                     const char** out_file,
                     spvtools::ValidatorOptions* validator_options,
                     spvtools::OptimizerOptions* optimizer_options);

// Parses and handles the -Oconfig flag. |prog_name| contains the name of
// the spirv-opt binary (used to build a new argv vector for the recursive
// invocation to ParseFlags). |opt_flag| contains the -Oconfig=FILENAME flag.
// |optimizer|, |in_file|, |out_file|, |validator_options|, and
// |optimizer_options| are as in ParseFlags.
//
// This returns the same OptStatus instance returned by ParseFlags.
OptStatus ParseOconfigFlag(const char* prog_name, const char* opt_flag,
                           spvtools::Optimizer* optimizer, const char** in_file,
                           const char** out_file,
                           spvtools::ValidatorOptions* validator_options,
                           spvtools::OptimizerOptions* optimizer_options) {
  std::vector<std::string> flags;
  flags.push_back(prog_name);

  std::vector<std::string> file_flags;
  if (!ReadFlagsFromFile(opt_flag, &file_flags)) {
    spvtools::Error(opt_diagnostic, nullptr, {},
                    "Could not read optimizer flags from configuration file");
    return {OPT_STOP, 1};
  }
  flags.insert(flags.end(), file_flags.begin(), file_flags.end());

  const char** new_argv = new const char*[flags.size()];
  for (size_t i = 0; i < flags.size(); i++) {
    if (flags[i].find("-Oconfig=") != std::string::npos) {
      spvtools::Error(
          opt_diagnostic, nullptr, {},
          "Flag -Oconfig= may not be used inside the configuration file");
      return {OPT_STOP, 1};
    }
    new_argv[i] = flags[i].c_str();
  }

  auto ret_val =
      ParseFlags(static_cast<int>(flags.size()), new_argv, optimizer, in_file,
                 out_file, validator_options, optimizer_options);
  delete[] new_argv;
  return ret_val;
}

// Canonicalize the flag in |argv[argi]| of the form '--pass arg' into
// '--pass=arg'. The optimizer only accepts arguments to pass names that use the
// form '--pass_name=arg'.  Since spirv-opt also accepts the other form, this
// function makes the necessary conversion.
//
// Pass flags that require additional arguments should be handled here.  Note
// that additional arguments should be given as a single string.  If the flag
// requires more than one argument, the pass creator in
// Optimizer::GetPassFromFlag() should parse it accordingly (e.g., see the
// handler for --set-spec-const-default-value).
//
// If the argument requests one of the passes that need an additional argument,
// |argi| is modified to point past the current argument, and the string
// "argv[argi]=argv[argi + 1]" is returned. Otherwise, |argi| is unmodified and
// the string "|argv[argi]|" is returned.
std::string CanonicalizeFlag(const char** argv, int argc, int* argi) {
  const char* cur_arg = argv[*argi];
  const char* next_arg = (*argi + 1 < argc) ? argv[*argi + 1] : nullptr;
  std::ostringstream canonical_arg;
  canonical_arg << cur_arg;

  // NOTE: DO NOT ADD NEW FLAGS HERE.
  //
  // These flags are supported for backwards compatibility.  When adding new
  // passes that need extra arguments in its command-line flag, please make them
  // use the syntax "--pass_name[=pass_arg].
  if (0 == strcmp(cur_arg, "--set-spec-const-default-value") ||
      0 == strcmp(cur_arg, "--loop-fission") ||
      0 == strcmp(cur_arg, "--loop-fusion") ||
      0 == strcmp(cur_arg, "--loop-unroll-partial") ||
      0 == strcmp(cur_arg, "--loop-peeling-threshold")) {
    if (next_arg) {
      canonical_arg << "=" << next_arg;
      ++(*argi);
    }
  }

  return canonical_arg.str();
}

// Parses command-line flags. |argc| contains the number of command-line flags.
// |argv| points to an array of strings holding the flags. |optimizer| is the
// Optimizer instance used to optimize the program.
//
// On return, this function stores the name of the input program in |in_file|.
// The name of the output file in |out_file|. The return value indicates whether
// optimization should continue and a status code indicating an error or
// success.
OptStatus ParseFlags(int argc, const char** argv,
                     spvtools::Optimizer* optimizer, const char** in_file,
                     const char** out_file,
                     spvtools::ValidatorOptions* validator_options,
                     spvtools::OptimizerOptions* optimizer_options) {
  std::vector<std::string> pass_flags;
  bool target_env_set = false;
  bool webgpu_mode_set = false;
  for (int argi = 1; argi < argc; ++argi) {
    const char* cur_arg = argv[argi];
    if ('-' == cur_arg[0]) {
      if (0 == strcmp(cur_arg, "--version")) {
        spvtools::Logf(opt_diagnostic, SPV_MSG_INFO, nullptr, {}, "%s\n",
                       spvSoftwareVersionDetailsString());
        return {OPT_STOP, 0};
      } else if (0 == strcmp(cur_arg, "--help") || 0 == strcmp(cur_arg, "-h")) {
        PrintUsage(argv[0]);
        return {OPT_STOP, 0};
      } else if (0 == strcmp(cur_arg, "-o")) {
        if (!*out_file && argi + 1 < argc) {
          *out_file = argv[++argi];
        } else {
          PrintUsage(argv[0]);
          return {OPT_STOP, 1};
        }
      } else if ('\0' == cur_arg[1]) {
        // Setting a filename of "-" to indicate stdin.
        if (!*in_file) {
          *in_file = cur_arg;
        } else {
          spvtools::Error(opt_diagnostic, nullptr, {},
                          "More than one input file specified");
          return {OPT_STOP, 1};
        }
      } else if (0 == strncmp(cur_arg, "-Oconfig=", sizeof("-Oconfig=") - 1)) {
        OptStatus status =
            ParseOconfigFlag(argv[0], cur_arg, optimizer, in_file, out_file,
                             validator_options, optimizer_options);
        if (status.action != OPT_CONTINUE) {
          return status;
        }
      } else if (0 == strcmp(cur_arg, "--skip-validation")) {
        optimizer_options->set_run_validator(false);
      } else if (0 == strcmp(cur_arg, "--print-all")) {
        optimizer->SetPrintAll(&std::cerr);
      } else if (0 == strcmp(cur_arg, "--time-report")) {
        optimizer->SetTimeReport(&std::cerr);
      } else if (0 == strcmp(cur_arg, "--relax-struct-store")) {
        validator_options->SetRelaxStructStore(true);
      } else if (0 == strncmp(cur_arg, "--max-id-bound=",
                              sizeof("--max-id-bound=") - 1)) {
        auto split_flag = spvtools::utils::SplitFlagArgs(cur_arg);
        // Will not allow values in the range [2^31,2^32).
        uint32_t max_id_bound =
            static_cast<uint32_t>(atoi(split_flag.second.c_str()));

        // That SPIR-V mandates the minimum value for max id bound but
        // implementations may allow higher minimum bounds.
        if (max_id_bound < kDefaultMaxIdBound) {
          spvtools::Error(opt_diagnostic, nullptr, {},
                          "The max id bound must be at least 0x3FFFFF");
          return {OPT_STOP, 1};
        }
        optimizer_options->set_max_id_bound(max_id_bound);
        validator_options->SetUniversalLimit(spv_validator_limit_max_id_bound,
                                             max_id_bound);
      } else if (0 == strncmp(cur_arg,
                              "--target-env=", sizeof("--target-env=") - 1)) {
        if (webgpu_mode_set) {
          spvtools::Error(opt_diagnostic, nullptr, {},
                          "Cannot use both --webgpu-mode and --target-env at "
                          "the same time");
          return {OPT_STOP, 1};
        }
        const auto split_flag = spvtools::utils::SplitFlagArgs(cur_arg);
        const auto target_env_str = split_flag.second.c_str();
        spv_target_env target_env;
        if (!spvParseTargetEnv(target_env_str, &target_env)) {
          spvtools::Error(opt_diagnostic, nullptr, {},
                          "Invalid value passed to --target-env");
          return {OPT_STOP, 1};
        }
        optimizer->SetTargetEnv(target_env);
      } else if (0 == strcmp(cur_arg, "--webgpu-mode")) {
        if (target_env_set) {
          spvtools::Error(opt_diagnostic, nullptr, {},
                          "Cannot use both --webgpu-mode and --target-env at "
                          "the same time");
          return {OPT_STOP, 1};
        }

        optimizer->SetTargetEnv(SPV_ENV_WEBGPU_0);
        optimizer->RegisterWebGPUPasses();
      } else if (0 == strcmp(cur_arg, "--validate-after-all")) {
        optimizer->SetValidateAfterAll(true);
      } else {
        // Some passes used to accept the form '--pass arg', canonicalize them
        // to '--pass=arg'.
        pass_flags.push_back(CanonicalizeFlag(argv, argc, &argi));

        // If we were requested to legalize SPIR-V generated from the HLSL
        // front-end, skip validation.
        if (0 == strcmp(cur_arg, "--legalize-hlsl")) {
          validator_options->SetRelaxLogicalPointer(true);
        }
      }
    } else {
      if (!*in_file) {
        *in_file = cur_arg;
      } else {
        spvtools::Error(opt_diagnostic, nullptr, {},
                        "More than one input file specified");
        return {OPT_STOP, 1};
      }
    }
  }

  if (!optimizer->RegisterPassesFromFlags(pass_flags)) {
    return {OPT_STOP, 1};
  }

  return {OPT_CONTINUE, 0};
}

}  // namespace

int main(int argc, const char** argv) {
  const char* in_file = nullptr;
  const char* out_file = nullptr;

  spv_target_env target_env = kDefaultEnvironment;

  spvtools::Optimizer optimizer(target_env);
  optimizer.SetMessageConsumer(spvtools::utils::CLIMessageConsumer);

  spvtools::ValidatorOptions validator_options;
  spvtools::OptimizerOptions optimizer_options;
  OptStatus status = ParseFlags(argc, argv, &optimizer, &in_file, &out_file,
                                &validator_options, &optimizer_options);
  optimizer_options.set_validator_options(validator_options);

  if (status.action == OPT_STOP) {
    return status.code;
  }

  if (out_file == nullptr) {
    spvtools::Error(opt_diagnostic, nullptr, {}, "-o required");
    return 1;
  }

  std::vector<uint32_t> binary;
  if (!ReadFile<uint32_t>(in_file, "rb", &binary)) {
    return 1;
  }

  // By using the same vector as input and output, we save time in the case
  // that there was no change.
  bool ok =
      optimizer.Run(binary.data(), binary.size(), &binary, optimizer_options);

  if (!WriteFile<uint32_t>(out_file, "wb", binary.data(), binary.size())) {
    return 1;
  }

  return ok ? 0 : 1;
}
