#!/usr/bin/env python3

"""A script to generate FileCheck statements for 'opt' analysis tests.

This script is a utility to update LLVM opt analysis test cases with new
FileCheck patterns. It can either update all of the tests in the file or
a single test function.

Example usage:
$ update_analyze_test_checks.py --opt=../bin/opt test/foo.ll

Workflow:
1. Make a compiler patch that requires updating some number of FileCheck lines
   in regression test files.
2. Save the patch and revert it from your local work area.
3. Update the RUN-lines in the affected regression tests to look canonical.
   Example: "; RUN: opt < %s -passes='print<cost-model>' -disable-output 2>&1 | FileCheck %s"
4. Refresh the FileCheck lines for either the entire file or select functions by
   running this script.
5. Commit the fresh baseline of checks.
6. Apply your patch from step 1 and rebuild your local binaries.
7. Re-run this script on affected regression tests.
8. Check the diffs to ensure the script has done something reasonable.
9. Submit a patch including the regression test diffs for review.

A common pattern is to have the script insert complete checking of every
instruction. Then, edit it down to only check the relevant instructions.
The script is designed to make adding checks to a test case fast, it is *not*
designed to be authoratitive about what constitutes a good test!
"""

from __future__ import print_function

import argparse
import os         # Used to advertise this file's name ("autogenerated_note").
import sys
import re

from UpdateTestChecks import common

def main():
  from argparse import RawTextHelpFormatter
  parser = argparse.ArgumentParser(description=__doc__, formatter_class=RawTextHelpFormatter)
  parser.add_argument('--opt-binary', default='opt',
                      help='The opt binary used to generate the test case')
  parser.add_argument(
      '--function', help='The function in the test file to update')
  parser.add_argument('tests', nargs='+')
  initial_args = common.parse_commandline_args(parser)

  script_name = os.path.basename(__file__)

  opt_basename = os.path.basename(initial_args.opt_binary)
  if (opt_basename != "opt"):
    common.error('Unexpected opt name: ' + opt_basename)
    sys.exit(1)

  for ti in common.itertests(initial_args.tests, parser,
                             script_name='utils/' + script_name):
    triple_in_ir = None
    for l in ti.input_lines:
      m = common.TRIPLE_IR_RE.match(l)
      if m:
        triple_in_ir = m.groups()[0]
        break

    prefix_list = []
    for l in ti.run_lines:
      if '|' not in l:
        common.warn('Skipping unparseable RUN line: ' + l)
        continue

      (tool_cmd, filecheck_cmd) = tuple([cmd.strip() for cmd in l.split('|', 1)])
      common.verify_filecheck_prefixes(filecheck_cmd)

      if not tool_cmd.startswith(opt_basename + ' '):
        common.warn('WSkipping non-%s RUN line: %s' % (opt_basename, l))
        continue

      if not filecheck_cmd.startswith('FileCheck '):
        common.warn('Skipping non-FileChecked RUN line: ' + l)
        continue

      tool_cmd_args = tool_cmd[len(opt_basename):].strip()
      tool_cmd_args = tool_cmd_args.replace('< %s', '').replace('%s', '').strip()

      check_prefixes = [item for m in common.CHECK_PREFIX_RE.finditer(filecheck_cmd)
                               for item in m.group(1).split(',')]
      if not check_prefixes:
        check_prefixes = ['CHECK']

      # FIXME: We should use multiple check prefixes to common check lines. For
      # now, we just ignore all but the last.
      prefix_list.append((check_prefixes, tool_cmd_args))

    builder = common.FunctionTestBuilder(
      run_list = prefix_list,
      flags = type('', (object,), {
            'verbose': ti.args.verbose,
            'filters': ti.args.filters,
            'function_signature': False,
            'check_attributes': False,
            'replace_value_regex': []}),
      scrubber_args = [],
      path=ti.path)

    for prefixes, opt_args in prefix_list:
      common.debug('Extracted opt cmd:', opt_basename, opt_args, file=sys.stderr)
      common.debug('Extracted FileCheck prefixes:', str(prefixes), file=sys.stderr)

      raw_tool_outputs = common.invoke_tool(ti.args.opt_binary, opt_args, ti.path)

      if re.search(r'Printing analysis ', raw_tool_outputs) is not None:
        # Split analysis outputs by "Printing analysis " declarations.
        for raw_tool_output in re.split(r'Printing analysis ', raw_tool_outputs):
          builder.process_run_line(common.ANALYZE_FUNCTION_RE, common.scrub_body,
                                  raw_tool_output, prefixes, False)
      elif re.search(r'LV: Checking a loop in ', raw_tool_outputs) is not None:
        # Split analysis outputs by "Printing analysis " declarations.
        for raw_tool_output in re.split(r'LV: Checking a loop in ', raw_tool_outputs):
          builder.process_run_line(common.LV_DEBUG_RE, common.scrub_body,
                                  raw_tool_output, prefixes, False)
      else:
        common.warn('Don\'t know how to deal with this output')
        continue

      builder.processed_prefixes(prefixes)

    func_dict = builder.finish_and_get_func_dict()
    is_in_function = False
    is_in_function_start = False
    prefix_set = set([prefix for prefixes, _ in prefix_list for prefix in prefixes])
    common.debug('Rewriting FileCheck prefixes:', str(prefix_set), file=sys.stderr)
    output_lines = []

    for input_info in ti.iterlines(output_lines):
      input_line = input_info.line
      args = input_info.args
      if is_in_function_start:
        if input_line == '':
          continue
        if input_line.lstrip().startswith(';'):
          m = common.CHECK_RE.match(input_line)
          if not m or m.group(1) not in prefix_set:
            output_lines.append(input_line)
            continue

        # Print out the various check lines here.
        common.add_analyze_checks(output_lines, ';', prefix_list, func_dict, func_name,
                                  is_filtered=builder.is_filtered())
        is_in_function_start = False

      if is_in_function:
        if common.should_add_line_to_output(input_line, prefix_set):
          # This input line of the function body will go as-is into the output.
          # Except make leading whitespace uniform: 2 spaces.
          input_line = common.SCRUB_LEADING_WHITESPACE_RE.sub(r'  ', input_line)
          output_lines.append(input_line)
        else:
          continue
        if input_line.strip() == '}':
          is_in_function = False
        continue

      # If it's outside a function, it just gets copied to the output.
      output_lines.append(input_line)

      m = common.IR_FUNCTION_RE.match(input_line)
      if not m:
        continue
      func_name = m.group(1)
      if ti.args.function is not None and func_name != ti.args.function:
        # When filtering on a specific function, skip all others.
        continue
      is_in_function = is_in_function_start = True

    common.debug('Writing %d lines to %s...' % (len(output_lines), ti.path))

    with open(ti.path, 'wb') as f:
      f.writelines(['{}\n'.format(l).encode('utf-8') for l in output_lines])


if __name__ == '__main__':
  main()
