/* Loop optimizer initialization routines and RTL loop optimization passes.
   Copyright (C) 2002-2022 Free Software Foundation, Inc.

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 "target.h"
#include "rtl.h"
#include "tree.h"
#include "cfghooks.h"
#include "df.h"
#include "regs.h"
#include "cfgcleanup.h"
#include "cfgloop.h"
#include "tree-pass.h"
#include "tree-ssa-loop-niter.h"
#include "loop-unroll.h"
#include "tree-scalar-evolution.h"
#include "tree-cfgcleanup.h"


/* Apply FLAGS to the loop state.  */

static void
apply_loop_flags (unsigned flags)
{
  if (flags & LOOPS_MAY_HAVE_MULTIPLE_LATCHES)
    {
      /* If the loops may have multiple latches, we cannot canonicalize
	 them further (and most of the loop manipulation functions will
	 not work).  However, we avoid modifying cfg, which some
	 passes may want.  */
      gcc_assert ((flags & ~(LOOPS_MAY_HAVE_MULTIPLE_LATCHES
			     | LOOPS_HAVE_RECORDED_EXITS
			     | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)) == 0);
      loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
    }
  else
    disambiguate_loops_with_multiple_latches ();

  /* Create pre-headers.  */
  if (flags & LOOPS_HAVE_PREHEADERS)
    {
      int cp_flags = CP_SIMPLE_PREHEADERS;

      if (flags & LOOPS_HAVE_FALLTHRU_PREHEADERS)
        cp_flags |= CP_FALLTHRU_PREHEADERS;

      create_preheaders (cp_flags);
    }

  /* Force all latches to have only single successor.  */
  if (flags & LOOPS_HAVE_SIMPLE_LATCHES)
    force_single_succ_latches ();

  /* Mark irreducible loops.  */
  if (flags & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
    mark_irreducible_loops ();

  if (flags & LOOPS_HAVE_RECORDED_EXITS)
    record_loop_exits ();
}

/* Initialize loop structures.  This is used by the tree and RTL loop
   optimizers.  FLAGS specify what properties to compute and/or ensure for
   loops.  */

void
loop_optimizer_init (unsigned flags)
{
  timevar_push (TV_LOOP_INIT);

  if (!current_loops)
    {
      gcc_assert (!(cfun->curr_properties & PROP_loops));

      /* Find the loops.  */
      current_loops = flow_loops_find (NULL);
    }
  else
    {
      bool recorded_exits = loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS);
      bool needs_fixup = loops_state_satisfies_p (LOOPS_NEED_FIXUP);

      gcc_assert (cfun->curr_properties & PROP_loops);

      /* Ensure that the dominators are computed, like flow_loops_find does.  */
      calculate_dominance_info (CDI_DOMINATORS);

      if (!needs_fixup)
	checking_verify_loop_structure ();

      /* Clear all flags.  */
      if (recorded_exits)
	release_recorded_exits (cfun);
      loops_state_clear (~0U);

      if (needs_fixup)
	{
	  /* Apply LOOPS_MAY_HAVE_MULTIPLE_LATCHES early as fix_loop_structure
	     re-applies flags.  */
	  loops_state_set (flags & LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
	  fix_loop_structure (NULL);
	}
    }

  /* Apply flags to loops.  */
  apply_loop_flags (flags);

  /* Dump loops.  */
  flow_loops_dump (dump_file, NULL, 1);

  checking_verify_loop_structure ();

  timevar_pop (TV_LOOP_INIT);
}

/* Finalize loop structures.  */

void
loop_optimizer_finalize (struct function *fn, bool clean_loop_closed_phi)
{
  basic_block bb;

  timevar_push (TV_LOOP_FINI);

  if (clean_loop_closed_phi && loops_state_satisfies_p (fn, LOOP_CLOSED_SSA))
    {
      clean_up_loop_closed_phi (fn);
      loops_state_clear (fn, LOOP_CLOSED_SSA);
    }

  if (loops_state_satisfies_p (fn, LOOPS_HAVE_RECORDED_EXITS))
    release_recorded_exits (fn);

  free_numbers_of_iterations_estimates (fn);

  /* If we should preserve loop structure, do not free it but clear
     flags that advanced properties are there as we are not preserving
     that in full.  */
  if (fn->curr_properties & PROP_loops)
    {
      loops_state_clear (fn, LOOP_CLOSED_SSA
			 | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
			 | LOOPS_HAVE_PREHEADERS
			 | LOOPS_HAVE_SIMPLE_LATCHES
			 | LOOPS_HAVE_FALLTHRU_PREHEADERS);
      loops_state_set (fn, LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
      goto loop_fini_done;
    }

  for (auto loop : loops_list (fn, 0))
    free_simple_loop_desc (loop);

  /* Clean up.  */
  flow_loops_free (loops_for_fn (fn));
  ggc_free (loops_for_fn (fn));
  set_loops_for_fn (fn, NULL);

  FOR_ALL_BB_FN (bb, fn)
    {
      bb->loop_father = NULL;
    }

loop_fini_done:
  timevar_pop (TV_LOOP_FINI);
}

/* The structure of loops might have changed.  Some loops might get removed
   (and their headers and latches were set to NULL), loop exists might get
   removed (thus the loop nesting may be wrong), and some blocks and edges
   were changed (so the information about bb --> loop mapping does not have
   to be correct).  But still for the remaining loops the header dominates
   the latch, and loops did not get new subloops (new loops might possibly
   get created, but we are not interested in them).  Fix up the mess.

   If CHANGED_BBS is not NULL, basic blocks whose loop depth has changed are
   marked in it.

   Returns the number of new discovered loops.  */

unsigned
fix_loop_structure (bitmap changed_bbs)
{
  basic_block bb;
  int record_exits = 0;
  unsigned old_nloops, i;

  timevar_push (TV_LOOP_INIT);

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "fix_loop_structure: fixing up loops for function\n");

  /* We need exact and fast dominance info to be available.  */
  gcc_assert (dom_info_state (CDI_DOMINATORS) == DOM_OK);

  if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
    {
      release_recorded_exits (cfun);
      record_exits = LOOPS_HAVE_RECORDED_EXITS;
    }

  /* Remember the depth of the blocks in the loop hierarchy, so that we can
     recognize blocks whose loop nesting relationship has changed.  */
  if (changed_bbs)
    FOR_EACH_BB_FN (bb, cfun)
      bb->aux = (void *) (size_t) loop_depth (bb->loop_father);

  /* Remove the dead loops from structures.  We start from the innermost
     loops, so that when we remove the loops, we know that the loops inside
     are preserved, and do not waste time relinking loops that will be
     removed later.  */
  for (auto loop : loops_list (cfun, LI_FROM_INNERMOST))
    {
      /* Detect the case that the loop is no longer present even though
         it wasn't marked for removal.
	 ???  If we do that we can get away with not marking loops for
	 removal at all.  And possibly avoid some spurious removals.  */
      if (loop->header
	  && bb_loop_header_p (loop->header))
	continue;

      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "fix_loop_structure: removing loop %d\n",
		 loop->num);

      while (loop->inner)
	{
	  class loop *ploop = loop->inner;
	  flow_loop_tree_node_remove (ploop);
	  flow_loop_tree_node_add (loop_outer (loop), ploop);
	}

      /* Remove the loop.  */
      if (loop->header)
	loop->former_header = loop->header;
      else
	gcc_assert (loop->former_header != NULL);
      loop->header = NULL;
      flow_loop_tree_node_remove (loop);
    }

  /* Remember the number of loops so we can return how many new loops
     flow_loops_find discovered.  */
  old_nloops = number_of_loops (cfun);

  /* Re-compute loop structure in-place.  */
  flow_loops_find (current_loops);

  /* Mark the blocks whose loop has changed.  */
  if (changed_bbs)
    {
      FOR_EACH_BB_FN (bb, cfun)
	{
	  if ((void *) (size_t) loop_depth (bb->loop_father) != bb->aux)
	    bitmap_set_bit (changed_bbs, bb->index);

    	  bb->aux = NULL;
	}
    }

  /* Finally free deleted loops.  */
  bool any_deleted = false;
  class loop *loop;
  FOR_EACH_VEC_ELT (*get_loops (cfun), i, loop)
    if (loop && loop->header == NULL)
      {
	if (dump_file
	    && ((unsigned) loop->former_header->index
		< basic_block_info_for_fn (cfun)->length ()))
	  {
	    basic_block former_header
	      = BASIC_BLOCK_FOR_FN (cfun, loop->former_header->index);
	    /* If the old header still exists we want to check if the
	       original loop is re-discovered or the old header is now
	       part of a newly discovered loop.
	       In both cases we should have avoided removing the loop.  */
	    if (former_header == loop->former_header)
	      {
		if (former_header->loop_father->header == former_header)
		  fprintf (dump_file, "fix_loop_structure: rediscovered "
			   "removed loop %d as loop %d with old header %d\n",
			   loop->num, former_header->loop_father->num,
			   former_header->index);
		else if ((unsigned) former_header->loop_father->num
			 >= old_nloops)
		  fprintf (dump_file, "fix_loop_structure: header %d of "
			   "removed loop %d is part of the newly "
			   "discovered loop %d with header %d\n",
			   former_header->index, loop->num,
			   former_header->loop_father->num,
			   former_header->loop_father->header->index);
	      }
	  }
	(*get_loops (cfun))[i] = NULL;
	flow_loop_free (loop);
	any_deleted = true;
      }

  /* If we deleted loops then the cached scalar evolutions refering to
     those loops become invalid.  */
  if (any_deleted && scev_initialized_p ())
    scev_reset_htab ();

  loops_state_clear (LOOPS_NEED_FIXUP);

  /* Apply flags to loops.  */
  apply_loop_flags (current_loops->state | record_exits);

  checking_verify_loop_structure ();

  timevar_pop (TV_LOOP_INIT);

  return number_of_loops (cfun) - old_nloops;
}

/* The RTL loop superpass.  The actual passes are subpasses.  See passes.cc for
   more on that.  */

namespace {

const pass_data pass_data_loop2 =
{
  RTL_PASS, /* type */
  "loop2", /* name */
  OPTGROUP_LOOP, /* optinfo_flags */
  TV_LOOP, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_loop2 : public rtl_opt_pass
{
public:
  pass_loop2 (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_loop2, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *);

}; // class pass_loop2

bool
pass_loop2::gate (function *fun)
{
  if (optimize > 0
      && (flag_move_loop_invariants
	  || flag_unswitch_loops
	  || flag_unroll_loops
	  || (flag_branch_on_count_reg && targetm.have_doloop_end ())
	  || cfun->has_unroll))
    return true;
  else
    {
      /* No longer preserve loops, remove them now.  */
      fun->curr_properties &= ~PROP_loops;
      if (current_loops)
	loop_optimizer_finalize ();
      return false;
    } 
}

} // anon namespace

rtl_opt_pass *
make_pass_loop2 (gcc::context *ctxt)
{
  return new pass_loop2 (ctxt);
}


/* Initialization of the RTL loop passes.  */
static unsigned int
rtl_loop_init (void)
{
  gcc_assert (current_ir_type () == IR_RTL_CFGLAYOUT);

  if (dump_file)
    {
      dump_reg_info (dump_file);
      dump_flow_info (dump_file, dump_flags);
    }

  loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
  return 0;
}

namespace {

const pass_data pass_data_rtl_loop_init =
{
  RTL_PASS, /* type */
  "loop2_init", /* name */
  OPTGROUP_LOOP, /* optinfo_flags */
  TV_LOOP, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_rtl_loop_init : public rtl_opt_pass
{
public:
  pass_rtl_loop_init (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_rtl_loop_init, ctxt)
  {}

  /* opt_pass methods: */
  virtual unsigned int execute (function *) { return rtl_loop_init (); }

}; // class pass_rtl_loop_init

} // anon namespace

rtl_opt_pass *
make_pass_rtl_loop_init (gcc::context *ctxt)
{
  return new pass_rtl_loop_init (ctxt);
}


/* Finalization of the RTL loop passes.  */

namespace {

const pass_data pass_data_rtl_loop_done =
{
  RTL_PASS, /* type */
  "loop2_done", /* name */
  OPTGROUP_LOOP, /* optinfo_flags */
  TV_LOOP, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  PROP_loops, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_rtl_loop_done : public rtl_opt_pass
{
public:
  pass_rtl_loop_done (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_rtl_loop_done, ctxt)
  {}

  /* opt_pass methods: */
  virtual unsigned int execute (function *);

}; // class pass_rtl_loop_done

unsigned int
pass_rtl_loop_done::execute (function *fun)
{
  /* No longer preserve loops, remove them now.  */
  fun->curr_properties &= ~PROP_loops;
  loop_optimizer_finalize ();
  free_dominance_info (CDI_DOMINATORS);

  cleanup_cfg (0);
  if (dump_file)
    {
      dump_reg_info (dump_file);
      dump_flow_info (dump_file, dump_flags);
    }

  return 0;
}

} // anon namespace

rtl_opt_pass *
make_pass_rtl_loop_done (gcc::context *ctxt)
{
  return new pass_rtl_loop_done (ctxt);
}


/* Loop invariant code motion.  */

namespace {

const pass_data pass_data_rtl_move_loop_invariants =
{
  RTL_PASS, /* type */
  "loop2_invariant", /* name */
  OPTGROUP_LOOP, /* optinfo_flags */
  TV_LOOP_MOVE_INVARIANTS, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  ( TODO_df_verify | TODO_df_finish ), /* todo_flags_finish */
};

class pass_rtl_move_loop_invariants : public rtl_opt_pass
{
public:
  pass_rtl_move_loop_invariants (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_rtl_move_loop_invariants, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *) { return flag_move_loop_invariants; }
  virtual unsigned int execute (function *fun)
    {
      if (number_of_loops (fun) > 1)
	move_loop_invariants ();
      return 0;
    }

}; // class pass_rtl_move_loop_invariants

} // anon namespace

rtl_opt_pass *
make_pass_rtl_move_loop_invariants (gcc::context *ctxt)
{
  return new pass_rtl_move_loop_invariants (ctxt);
}


namespace {

const pass_data pass_data_rtl_unroll_loops =
{
  RTL_PASS, /* type */
  "loop2_unroll", /* name */
  OPTGROUP_LOOP, /* optinfo_flags */
  TV_LOOP_UNROLL, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_rtl_unroll_loops : public rtl_opt_pass
{
public:
  pass_rtl_unroll_loops (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_rtl_unroll_loops, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *)
    {
      return (flag_unroll_loops || flag_unroll_all_loops || cfun->has_unroll);
    }

  virtual unsigned int execute (function *);

}; // class pass_rtl_unroll_loops

unsigned int
pass_rtl_unroll_loops::execute (function *fun)
{
  if (number_of_loops (fun) > 1)
    {
      int flags = 0;
      if (dump_file)
	df_dump (dump_file);

      if (flag_unroll_loops)
	flags |= UAP_UNROLL;
      if (flag_unroll_all_loops)
	flags |= UAP_UNROLL_ALL;

      unroll_loops (flags);
    }
  return 0;
}

} // anon namespace

rtl_opt_pass *
make_pass_rtl_unroll_loops (gcc::context *ctxt)
{
  return new pass_rtl_unroll_loops (ctxt);
}


namespace {

const pass_data pass_data_rtl_doloop =
{
  RTL_PASS, /* type */
  "loop2_doloop", /* name */
  OPTGROUP_LOOP, /* optinfo_flags */
  TV_LOOP_DOLOOP, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_rtl_doloop : public rtl_opt_pass
{
public:
  pass_rtl_doloop (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_rtl_doloop, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *);
  virtual unsigned int execute (function *);

}; // class pass_rtl_doloop

bool
pass_rtl_doloop::gate (function *)
{
  return (flag_branch_on_count_reg && targetm.have_doloop_end ());
}

unsigned int
pass_rtl_doloop::execute (function *fun)
{
  if (number_of_loops (fun) > 1)
    doloop_optimize_loops ();
  return 0;
}

} // anon namespace

rtl_opt_pass *
make_pass_rtl_doloop (gcc::context *ctxt)
{
  return new pass_rtl_doloop (ctxt);
}
