/* Top-level LTO routines.
   Copyright (C) 2009-2022 Free Software Foundation, Inc.
   Contributed by CodeSourcery, 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/>.  */

#define INCLUDE_STRING
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "function.h"
#include "bitmap.h"
#include "basic-block.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "tree-streamer.h"
#include "cgraph.h"
#include "opts.h"
#include "toplev.h"
#include "stor-layout.h"
#include "symbol-summary.h"
#include "tree-vrp.h"
#include "ipa-prop.h"
#include "debug.h"
#include "lto.h"
#include "lto-section-names.h"
#include "splay-tree.h"
#include "lto-partition.h"
#include "context.h"
#include "pass_manager.h"
#include "ipa-fnsummary.h"
#include "ipa-utils.h"
#include "gomp-constants.h"
#include "lto-symtab.h"
#include "stringpool.h"
#include "fold-const.h"
#include "attribs.h"
#include "builtins.h"
#include "lto-common.h"
#include "opts-jobserver.h"

/* Number of parallel tasks to run.  */
static int lto_parallelism;

/* Number of active WPA streaming processes.  */
static int nruns = 0;

/* GNU make's jobserver info.  */
static jobserver_info *jinfo = NULL;

/* Return true when NODE has a clone that is analyzed (i.e. we need
   to load its body even if the node itself is not needed).  */

static bool
has_analyzed_clone_p (struct cgraph_node *node)
{
  struct cgraph_node *orig = node;
  node = node->clones;
  if (node)
    while (node != orig)
      {
	if (node->analyzed)
	  return true;
	if (node->clones)
	  node = node->clones;
	else if (node->next_sibling_clone)
	  node = node->next_sibling_clone;
	else
	  {
	    while (node != orig && !node->next_sibling_clone)
	      node = node->clone_of;
	    if (node != orig)
	      node = node->next_sibling_clone;
	  }
      }
  return false;
}

/* Read the function body for the function associated with NODE.  */

static void
lto_materialize_function (struct cgraph_node *node)
{
  tree decl;

  decl = node->decl;
  /* Read in functions with body (analyzed nodes)
     and also functions that are needed to produce virtual clones.  */
  if ((node->has_gimple_body_p () && node->analyzed)
      || node->used_as_abstract_origin
      || has_analyzed_clone_p (node))
    {
      /* Clones don't need to be read.  */
      if (node->clone_of)
	return;
      if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl)
	first_personality_decl = DECL_FUNCTION_PERSONALITY (decl);
      /* If the file contains a function with a language specific EH
	 personality set or with EH enabled initialize the backend EH
	 machinery.  */
      if (DECL_FUNCTION_PERSONALITY (decl)
	  || opt_for_fn (decl, flag_exceptions))
	lto_init_eh ();
    }

  /* Let the middle end know about the function.  */
  rest_of_decl_compilation (decl, 1, 0);
}

/* Materialize all the bodies for all the nodes in the callgraph.  */

static void
materialize_cgraph (void)
{
  struct cgraph_node *node;
  timevar_id_t lto_timer;

  if (!quiet_flag)
    fprintf (stderr,
	     flag_wpa ? "Materializing decls:" : "Reading function bodies:");


  FOR_EACH_FUNCTION (node)
    {
      if (node->lto_file_data)
	{
	  lto_materialize_function (node);
	  lto_stats.num_input_cgraph_nodes++;
	}
    }


  /* Start the appropriate timer depending on the mode that we are
     operating in.  */
  lto_timer = (flag_wpa) ? TV_WHOPR_WPA
	      : (flag_ltrans) ? TV_WHOPR_LTRANS
	      : TV_LTO;
  timevar_push (lto_timer);

  current_function_decl = NULL;
  set_cfun (NULL);

  if (!quiet_flag)
    fprintf (stderr, "\n");

  timevar_pop (lto_timer);
}

/* Actually stream out ENCODER into TEMP_FILENAME.  */

static void
stream_out (char *temp_filename, lto_symtab_encoder_t encoder, int part)
{
  lto_file *file = lto_obj_file_open (temp_filename, true);
  if (!file)
    fatal_error (input_location, "%<lto_obj_file_open()%> failed");
  lto_set_current_out_file (file);

  gcc_assert (!dump_file);
  streamer_dump_file = dump_begin (TDI_lto_stream_out, NULL, part);
  ipa_write_optimization_summaries (encoder);

  free (CONST_CAST (char *, file->filename));

  lto_set_current_out_file (NULL);
  lto_obj_file_close (file);
  free (file);
  if (streamer_dump_file)
    {
      dump_end (TDI_lto_stream_out, streamer_dump_file);
      streamer_dump_file = NULL;
    }
}

/* Wait for forked process and signal errors.  */
#ifdef HAVE_WORKING_FORK
static void
wait_for_child ()
{
  int status;
  do
    {
#ifndef WCONTINUED
#define WCONTINUED 0
#endif
      int w = waitpid (0, &status, WUNTRACED | WCONTINUED);
      if (w == -1)
	fatal_error (input_location, "waitpid failed");

      if (WIFEXITED (status) && WEXITSTATUS (status))
	fatal_error (input_location, "streaming subprocess failed");
      else if (WIFSIGNALED (status))
	fatal_error (input_location,
		     "streaming subprocess was killed by signal");
    }
  while (!WIFEXITED (status) && !WIFSIGNALED (status));

  --nruns;

  /* Return token to the jobserver if active.  */
  if (jinfo != NULL && jinfo->is_connected)
    jinfo->return_token ();
}
#endif

static void
stream_out_partitions_1 (char *temp_filename, int blen, int min, int max)
{
   /* Write all the nodes in SET.  */
   for (int p = min; p < max; p ++)
     {
       sprintf (temp_filename + blen, "%u.o", p);
       stream_out (temp_filename, ltrans_partitions[p]->encoder, p);
       ltrans_partitions[p]->encoder = NULL;
     }
}

/* Stream out ENCODER into TEMP_FILENAME
   Fork if that seems to help.  */

static void
stream_out_partitions (char *temp_filename, int blen, int min, int max,
		       bool ARG_UNUSED (last))
{
#ifdef HAVE_WORKING_FORK
  if (lto_parallelism <= 1)
    {
      stream_out_partitions_1 (temp_filename, blen, min, max);
      return;
    }

  if (lto_parallelism > 0 && nruns >= lto_parallelism)
    wait_for_child ();

  /* If this is not the last parallel partition, execute new
     streaming process.  */
  if (!last)
    {
      if (jinfo != NULL && jinfo->is_connected)
	while (true)
	  {
	    if (jinfo->get_token ())
	      break;
	    if (nruns > 0)
	      wait_for_child ();
	    else
	      {
		/* There are no free tokens, lets do the job outselves.  */
		stream_out_partitions_1 (temp_filename, blen, min, max);
		asm_nodes_output = true;
		return;
	      }
	  }

      pid_t cpid = fork ();

      if (!cpid)
	{
	  setproctitle ("lto1-wpa-streaming");
          stream_out_partitions_1 (temp_filename, blen, min, max);
	  exit (0);
	}
      /* Fork failed; lets do the job ourseleves.  */
      else if (cpid == -1)
	stream_out_partitions_1 (temp_filename, blen, min, max);
      else
	nruns++;
    }
  /* Last partition; stream it and wait for all children to die.  */
  else
    {
      stream_out_partitions_1 (temp_filename, blen, min, max);
      while (nruns > 0)
	wait_for_child ();

      if (jinfo != NULL && jinfo->is_connected)
	jinfo->disconnect ();
    }
  asm_nodes_output = true;
#else
  stream_out_partitions_1 (temp_filename, blen, min, max);
#endif
}

/* Write all output files in WPA mode and the file with the list of
   LTRANS units.  */

static void
lto_wpa_write_files (void)
{
  unsigned i, n_sets;
  ltrans_partition part;
  FILE *ltrans_output_list_stream;
  char *temp_filename;
  auto_vec <char *>temp_filenames;
  auto_vec <int>temp_priority;
  size_t blen;

  /* Open the LTRANS output list.  */
  if (!ltrans_output_list)
    fatal_error (input_location, "no LTRANS output list filename provided");

  timevar_push (TV_WHOPR_WPA);

  FOR_EACH_VEC_ELT (ltrans_partitions, i, part)
    lto_stats.num_output_symtab_nodes
    += lto_symtab_encoder_size (part->encoder);

  timevar_pop (TV_WHOPR_WPA);

  timevar_push (TV_WHOPR_WPA_IO);

  cgraph_node *node;
  /* Do body modifications needed for streaming before we fork out
     worker processes.  */
  FOR_EACH_FUNCTION (node)
    if (!node->clone_of && gimple_has_body_p (node->decl))
      lto_prepare_function_for_streaming (node);

  ggc_trim ();
  report_heap_memory_use ();

  /* Generate a prefix for the LTRANS unit files.  */
  blen = strlen (ltrans_output_list);
  temp_filename = (char *) xmalloc (blen + sizeof ("2147483648.o"));
  strcpy (temp_filename, ltrans_output_list);
  if (blen > sizeof (".out")
      && strcmp (temp_filename + blen - sizeof (".out") + 1,
		 ".out") == 0)
    temp_filename[blen - sizeof (".out") + 1] = '\0';
  blen = strlen (temp_filename);

  n_sets = ltrans_partitions.length ();
  unsigned sets_per_worker = n_sets;
  if (lto_parallelism > 1)
    {
      if (lto_parallelism > (int)n_sets)
	lto_parallelism = n_sets;
      sets_per_worker = (n_sets + lto_parallelism - 1) / lto_parallelism;
    }

  for (i = 0; i < n_sets; i++)
    {
      ltrans_partition part = ltrans_partitions[i];

      /* Write all the nodes in SET.  */
      sprintf (temp_filename + blen, "%u.o", i);

      if (!quiet_flag)
	fprintf (stderr, " %s (%s %i insns)", temp_filename, part->name,
		 part->insns);
      if (symtab->dump_file)
	{
	  lto_symtab_encoder_iterator lsei;

	  fprintf (symtab->dump_file,
		   "Writing partition %s to file %s, %i insns\n",
		   part->name, temp_filename, part->insns);
	  fprintf (symtab->dump_file, "  Symbols in partition: ");
	  for (lsei = lsei_start_in_partition (part->encoder);
	       !lsei_end_p (lsei);
	       lsei_next_in_partition (&lsei))
	    {
	      symtab_node *node = lsei_node (lsei);
	      fprintf (symtab->dump_file, "%s ", node->dump_asm_name ());
	    }
	  fprintf (symtab->dump_file, "\n  Symbols in boundary: ");
	  for (lsei = lsei_start (part->encoder); !lsei_end_p (lsei);
	       lsei_next (&lsei))
	    {
	      symtab_node *node = lsei_node (lsei);
	      if (!lto_symtab_encoder_in_partition_p (part->encoder, node))
		{
		  fprintf (symtab->dump_file, "%s ", node->dump_asm_name ());
		  cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
		  if (cnode
		      && lto_symtab_encoder_encode_body_p (part->encoder,
							   cnode))
		    fprintf (symtab->dump_file, "(body included)");
		  else
		    {
		      varpool_node *vnode = dyn_cast <varpool_node *> (node);
		      if (vnode
			  && lto_symtab_encoder_encode_initializer_p (part->encoder,
								      vnode))
			fprintf (symtab->dump_file, "(initializer included)");
		    }
		}
	    }
	  fprintf (symtab->dump_file, "\n");
	}
      gcc_checking_assert (lto_symtab_encoder_size (part->encoder) || !i);

      temp_priority.safe_push (part->insns);
      temp_filenames.safe_push (xstrdup (temp_filename));
    }
  memory_block_pool::trim (0);

  for (int set = 0; set < MAX (lto_parallelism, 1); set++)
    {
      stream_out_partitions (temp_filename, blen, set * sets_per_worker,
			     MIN ((set + 1) * sets_per_worker, n_sets),
			     set == MAX (lto_parallelism, 1) - 1);
    }

  ltrans_output_list_stream = fopen (ltrans_output_list, "w");
  if (ltrans_output_list_stream == NULL)
    fatal_error (input_location,
		 "opening LTRANS output list %s: %m", ltrans_output_list);
  for (i = 0; i < n_sets; i++)
    {
      unsigned int len = strlen (temp_filenames[i]);
      if (fprintf (ltrans_output_list_stream, "%i\n", temp_priority[i]) < 0
	  || fwrite (temp_filenames[i], 1, len, ltrans_output_list_stream) < len
	  || fwrite ("\n", 1, 1, ltrans_output_list_stream) < 1)
	fatal_error (input_location, "writing to LTRANS output list %s: %m",
		     ltrans_output_list);
     free (temp_filenames[i]);
    }

  lto_stats.num_output_files += n_sets;

  /* Close the LTRANS output list.  */
  if (fclose (ltrans_output_list_stream))
    fatal_error (input_location,
		 "closing LTRANS output list %s: %m", ltrans_output_list);

  free_ltrans_partitions ();
  free (temp_filename);

  timevar_pop (TV_WHOPR_WPA_IO);
}

/* Create artificial pointers for "omp declare target link" vars.  */

static void
offload_handle_link_vars (void)
{
#ifdef ACCEL_COMPILER
  varpool_node *var;
  FOR_EACH_VARIABLE (var)
    if (lookup_attribute ("omp declare target link",
			  DECL_ATTRIBUTES (var->decl)))
      {
	tree type = build_pointer_type (TREE_TYPE (var->decl));
	tree link_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
					clone_function_name (var->decl,
							     "linkptr"), type);
	TREE_USED (link_ptr_var) = 1;
	TREE_STATIC (link_ptr_var) = 1;
	TREE_PUBLIC (link_ptr_var) = TREE_PUBLIC (var->decl);
	DECL_ARTIFICIAL (link_ptr_var) = 1;
	SET_DECL_ASSEMBLER_NAME (link_ptr_var, DECL_NAME (link_ptr_var));
	SET_DECL_VALUE_EXPR (var->decl, build_simple_mem_ref (link_ptr_var));
	DECL_HAS_VALUE_EXPR_P (var->decl) = 1;
      }
#endif
}

/* Perform whole program analysis (WPA) on the callgraph and write out the
   optimization plan.  */

static void
do_whole_program_analysis (void)
{
  symtab_node *node;

  lto_parallelism = 1;

  if (!strcmp (flag_wpa, "jobserver"))
    {
      jinfo = new jobserver_info ();
      if (jinfo->is_active)
	jinfo->connect ();

      lto_parallelism = param_max_lto_streaming_parallelism;
    }
  else
    {
      lto_parallelism = atoi (flag_wpa);
      if (lto_parallelism <= 0)
	lto_parallelism = 0;
      if (lto_parallelism >= param_max_lto_streaming_parallelism)
	lto_parallelism = param_max_lto_streaming_parallelism;
    }

  timevar_start (TV_PHASE_OPT_GEN);

  /* Note that since we are in WPA mode, materialize_cgraph will not
     actually read in all the function bodies.  It only materializes
     the decls and cgraph nodes so that analysis can be performed.  */
  materialize_cgraph ();

  /* Reading in the cgraph uses different timers, start timing WPA now.  */
  timevar_push (TV_WHOPR_WPA);

  if (pre_ipa_mem_report)
    dump_memory_report ("Memory consumption before IPA");

  symtab->function_flags_ready = true;

  if (symtab->dump_file)
    symtab->dump (symtab->dump_file);
  bitmap_obstack_initialize (NULL);
  symtab->state = IPA_SSA;

  execute_ipa_pass_list (g->get_passes ()->all_regular_ipa_passes);

  /* When WPA analysis raises errors, do not bother to output anything.  */
  if (seen_error ())
    return;

  /* We are about to launch the final LTRANS phase, stop the WPA timer.  */
  timevar_pop (TV_WHOPR_WPA);

  /* We are no longer going to stream in anything.  Free some memory.  */
  lto_free_file_name_hash ();


  timevar_push (TV_WHOPR_PARTITIONING);

  gcc_assert (!dump_file);
  dump_file = dump_begin (partition_dump_id, NULL);

  if (dump_file)
    symtab->dump (dump_file);

  symtab_node::checking_verify_symtab_nodes ();
  bitmap_obstack_release (NULL);
  if (flag_lto_partition == LTO_PARTITION_1TO1)
    lto_1_to_1_map ();
  else if (flag_lto_partition == LTO_PARTITION_MAX)
    lto_max_map ();
  else if (flag_lto_partition == LTO_PARTITION_ONE)
    lto_balanced_map (1, INT_MAX);
  else if (flag_lto_partition == LTO_PARTITION_BALANCED)
    lto_balanced_map (param_lto_partitions,
		      param_max_partition_size);
  else
    gcc_unreachable ();

  /* Size summaries are needed for balanced partitioning.  Free them now so
     the memory can be used for streamer caches.  */
  ipa_free_size_summary ();

  /* AUX pointers are used by partitioning code to bookkeep number of
     partitions symbol is in.  This is no longer needed.  */
  FOR_EACH_SYMBOL (node)
    node->aux = NULL;

  lto_stats.num_cgraph_partitions += ltrans_partitions.length ();

  /* Find out statics that need to be promoted
     to globals with hidden visibility because they are accessed from multiple
     partitions.  */
  lto_promote_cross_file_statics ();
  offload_handle_link_vars ();
  if (dump_file)
     dump_end (partition_dump_id, dump_file);
  dump_file = NULL;
  timevar_pop (TV_WHOPR_PARTITIONING);

  timevar_stop (TV_PHASE_OPT_GEN);

  /* Collect a last time - in lto_wpa_write_files we may end up forking
     with the idea that this doesn't increase memory usage.  So we
     absoultely do not want to collect after that.  */
  ggc_collect ();

  timevar_start (TV_PHASE_STREAM_OUT);
  if (!quiet_flag)
    {
      fprintf (stderr, "\nStreaming out");
      fflush (stderr);
    }
  lto_wpa_write_files ();
  if (!quiet_flag)
    fprintf (stderr, "\n");
  timevar_stop (TV_PHASE_STREAM_OUT);

  if (post_ipa_mem_report)
    dump_memory_report ("Memory consumption after IPA");

  /* Show the LTO report before launching LTRANS.  */
  if (flag_lto_report || (flag_wpa && flag_lto_report_wpa))
    print_lto_report_1 ();
  if (mem_report_wpa)
    dump_memory_report ("Final");
}

unsigned int
lto_option_lang_mask (void)
{
  return CL_LTO;
}

/* Main entry point for the GIMPLE front end.  This front end has
   three main personalities:

   - LTO (-flto).  All the object files on the command line are
     loaded in memory and processed as a single translation unit.
     This is the traditional link-time optimization behavior.

   - WPA (-fwpa).  Only the callgraph and summary information for
     files in the command file are loaded.  A single callgraph
     (without function bodies) is instantiated for the whole set of
     files.  IPA passes are only allowed to analyze the call graph
     and make transformation decisions.  The callgraph is
     partitioned, each partition is written to a new object file
     together with the transformation decisions.

   - LTRANS (-fltrans).  Similar to -flto but it prevents the IPA
     summary files from running again.  Since WPA computed summary
     information and decided what transformations to apply, LTRANS
     simply applies them.  */

void
lto_main (void)
{
  /* LTO is called as a front end, even though it is not a front end.
     Because it is called as a front end, TV_PHASE_PARSING and
     TV_PARSE_GLOBAL are active, and we need to turn them off while
     doing LTO.  Later we turn them back on so they are active up in
     toplev.cc.  */
  timevar_pop (TV_PARSE_GLOBAL);
  timevar_stop (TV_PHASE_PARSING);

  timevar_start (TV_PHASE_SETUP);

  /* Initialize the LTO front end.  */
  lto_fe_init ();

  timevar_stop (TV_PHASE_SETUP);
  timevar_start (TV_PHASE_STREAM_IN);

  /* Read all the symbols and call graph from all the files in the
     command line.  */
  read_cgraph_and_symbols (num_in_fnames, in_fnames);

  timevar_stop (TV_PHASE_STREAM_IN);

  if (!seen_error ())
    {
      offload_handle_link_vars ();

      /* If WPA is enabled analyze the whole call graph and create an
	 optimization plan.  Otherwise, read in all the function
	 bodies and continue with optimization.  */
      if (flag_wpa)
	do_whole_program_analysis ();
      else
	{
	  timevar_start (TV_PHASE_OPT_GEN);

	  materialize_cgraph ();
	  if (!flag_ltrans)
	    {
	      lto_promote_statics_nonwpa ();
	      offload_handle_link_vars ();
	    }

	  /* Annotate the CU DIE and mark the early debug phase as finished.  */
	  debuginfo_early_start ();
	  debug_hooks->early_finish ("<artificial>");
	  debuginfo_early_stop ();

	  /* Let the middle end know that we have read and merged all of
	     the input files.  */
	  symtab->compile ();

	  timevar_stop (TV_PHASE_OPT_GEN);

	  /* FIXME lto, if the processes spawned by WPA fail, we miss
	     the chance to print WPA's report, so WPA will call
	     print_lto_report before launching LTRANS.  If LTRANS was
	     launched directly by the driver we would not need to do
	     this.  */
	  if (flag_lto_report || (flag_wpa && flag_lto_report_wpa))
	    print_lto_report_1 ();
	}
    }

  /* Here we make LTO pretend to be a parser.  */
  timevar_start (TV_PHASE_PARSING);
  timevar_push (TV_PARSE_GLOBAL);
}
