/* Loop optimizer initialization routines and RTL loop optimization passes.
   Copyright (C) 2002-2025 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 plus the number of removed 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.  */
  unsigned n_deleted = 0;
  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);
	n_deleted++;
      }

  /* If we deleted loops then the cached scalar evolutions refering to
     those loops become invalid.  */
  if (n_deleted > 0 && 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 + n_deleted;
}

/* 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: */
  bool gate (function *) final override;

}; // 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: */
  unsigned int execute (function *) final override { 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: */
  unsigned int execute (function *) final override;

}; // 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: */
  bool gate (function *) final override { return flag_move_loop_invariants; }
  unsigned int execute (function *fun) final override
    {
      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: */
  bool gate (function *) final override
    {
      return (flag_unroll_loops || flag_unroll_all_loops
	      || cfun->has_unroll);
    }

  unsigned int execute (function *) final override;

}; // 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: */
  bool gate (function *) final override;
  unsigned int execute (function *) final override;

}; // 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);
}
