/* Code for GIMPLE range trace and debugging related routines.
   Copyright (C) 2019-2021 Free Software Foundation, Inc.
   Contributed by Andrew MacLeod <amacleod@redhat.com>
   and Aldy Hernandez <aldyh@redhat.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "fold-const.h"
#include "tree-cfg.h"
#include "cfgloop.h"
#include "tree-scalar-evolution.h"
#include "gimple-range.h"


// Breakpoint to trap at a specific index.  From GDB, this provides a simple
// place to put a breakpoint to stop at a given trace line.
// ie.  b range_tracer::breakpoint if index == 45678

void
range_tracer::breakpoint (unsigned index ATTRIBUTE_UNUSED)
{
}

// Construct a range_tracer with component NAME.

range_tracer::range_tracer (const char *name)
{
  gcc_checking_assert (strlen(name) < name_len -1);
  strcpy (component, name);
  indent = 0;
  tracing = false;
}

// This routine does the initial line spacing/indenting for a trace.
// If BLANKS is false, then IDX is printed, otherwise spaces.

void
range_tracer::print_prefix (unsigned idx, bool blanks)
{
  // Print counter index as well as INDENT spaces.
  if (!blanks)
    fprintf (dump_file, "%-7u ", idx);
  else
    fprintf (dump_file, "        ");
  fprintf (dump_file, "%s ", component);
  unsigned x;
  for (x = 0; x< indent; x++)
    fputc (' ', dump_file);

}
// If dumping, return the next call index and print the prefix for the next
// output line.  If not, retrurn 0.
// Counter is static to monotonically increase across the compilation unit.

unsigned
range_tracer::do_header (const char *str)
{
  static unsigned trace_count = 0;

  unsigned idx = ++trace_count;
  print_prefix (idx, false);
  fprintf (dump_file, "%s", str);
  indent += bump;
  breakpoint (idx);
  return idx;
}

// Print a line without starting or ending a trace.

void
range_tracer::print (unsigned counter, const char *str)
{
  print_prefix (counter, true);
  fprintf (dump_file, "%s", str);
}

// End a trace and print the CALLER, NAME, and RESULT and range R,

void
range_tracer::trailer (unsigned counter, const char *caller, bool result,
		      tree name, const irange &r)
{
  gcc_checking_assert (tracing && counter != 0);

  indent -= bump;
  print_prefix (counter, true);
  fputs(result ? "TRUE : " : "FALSE : ", dump_file);
  fprintf (dump_file, "(%u) ", counter);
  fputs (caller, dump_file);
  fputs (" (",dump_file);
  if (name)
    print_generic_expr (dump_file, name, TDF_SLIM);
  fputs (") ",dump_file);
  if (result)
    {
      r.dump (dump_file);
      fputc('\n', dump_file);
    }
  else
    fputc('\n', dump_file);
}

// =========================================
// Debugging helpers.
// =========================================

// Query all statements in the IL to precalculate computable ranges in RANGER.

DEBUG_FUNCTION void
debug_seed_ranger (gimple_ranger &ranger)
{
  // Recalculate SCEV to make sure the dump lists everything.
  if (scev_initialized_p ())
    {
      scev_finalize ();
      scev_initialize ();
    }

  basic_block bb;
  int_range_max r;
  gimple_stmt_iterator gsi;
  FOR_EACH_BB_FN (bb, cfun)
    for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
      {
	gimple *stmt = gsi_stmt (gsi);

	if (is_gimple_debug (stmt))
	  continue;

	ranger.range_of_stmt (r, stmt);
      }
}

// Change the current dump_file and dump_flags to F and FLAGS while
// saving them for later restoring.

push_dump_file::push_dump_file (FILE *f, dump_flags_t flags)
{
  old_dump_file = dump_file;
  old_dump_flags = dump_flags;
  dump_file = f;
  dump_flags = flags;
}

// Restore saved dump_file and dump_flags.

push_dump_file::~push_dump_file ()
{
  dump_file = old_dump_file;
  dump_flags = old_dump_flags;
}

// Dump all that ranger knows for the current function.

void
dump_ranger (FILE *out)
{
  push_dump_file save (out, dump_flags);
  gimple_ranger ranger;

  fprintf (out, ";; Function ");
  print_generic_expr (out, current_function_decl);
  fprintf (out, "\n");

  debug_seed_ranger (ranger);
  ranger.dump (out);
}

DEBUG_FUNCTION void
debug_ranger ()
{
  dump_ranger (stderr);
}

// Dump all that ranger knows on a path of BBs.
//
// Note that the blocks are in reverse order, thus the exit block is
// path[0].

void
dump_ranger (FILE *dump_file, const vec<basic_block> &path)
{
  if (path.length () == 0)
    {
      fprintf (dump_file, "empty\n");
      return;
    }

  gimple_ranger ranger;
  debug_seed_ranger (ranger);

  unsigned i = path.length ();
  do
    {
      i--;
      ranger.dump_bb (dump_file, path[i]);
    }
  while (i > 0);
}

DEBUG_FUNCTION void
debug_ranger (const vec<basic_block> &path)
{
  dump_ranger (stderr, path);
}

#include "gimple-range-tests.cc"
