/* Optimization information.
   Copyright (C) 2018 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@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/>.  */

#ifndef GCC_OPTINFO_H
#define GCC_OPTINFO_H

/* An "optinfo" is a bundle of information describing part of an
   optimization, which can be emitted to zero or more of several
   destinations, such as:

   * saved to a file as an "optimization record"

   They are generated in response to calls to the "dump_*" API in
   dumpfile.h; repeated calls to the "dump_*" API are consolidated
   into a pending optinfo instance, with a "dump_*_loc" starting a new
   optinfo instance.

   The data sent to the dump calls are captured within the pending optinfo
   instance as a sequence of optinfo_items.  For example, given:

      if (dump_enabled_p ())
        {
          dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
                           "not vectorized: live stmt not supported: ");
          dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
        }

   the "dump_printf_loc" call begins a new optinfo containing two items:
   (1) a text item containing "not vectorized: live stmt not supported: "
   (2) a gimple item for "stmt"

   Dump destinations are thus able to access rich metadata about the
   items when the optinfo is emitted to them, rather than just having plain
   text.  For example, when saving the above optinfo to a file as an
   "optimization record", the record could capture the source location of
   "stmt" above, rather than just its textual form.

   The currently pending optinfo is emitted and deleted:
   * each time a "dump_*_loc" call occurs (which starts the next optinfo), or
   * when the dump files are changed (at the end of a pass)

   Dumping to an optinfo instance is non-trivial (due to building optinfo_item
   instances), so all usage should be guarded by

     if (optinfo_enabled_p ())

   which is off by default.  */


/* Forward decls.  */
struct opt_pass;
class optinfo_item;

/* Should optinfo instances be created?
   All creation of optinfos should be guarded by this predicate.
   Return true if any optinfo destinations are active.  */

extern bool optinfo_enabled_p ();

/* Return true if any of the active optinfo destinations make use
   of inlining information.
   (if true, then the information is preserved).  */

extern bool optinfo_wants_inlining_info_p ();

/* The various kinds of optinfo.  */

enum optinfo_kind
{
  OPTINFO_KIND_SUCCESS,
  OPTINFO_KIND_FAILURE,
  OPTINFO_KIND_NOTE,
  OPTINFO_KIND_SCOPE
};

extern const char *optinfo_kind_to_string (enum optinfo_kind kind);

class dump_context;

/* A bundle of information describing part of an optimization.  */

class optinfo
{
  friend class dump_context;

 public:
  optinfo (const dump_location_t &loc,
	   enum optinfo_kind kind,
	   opt_pass *pass)
  : m_loc (loc), m_kind (kind), m_pass (pass), m_items ()
  {}
  ~optinfo ();

  const dump_location_t &
  get_dump_location () const { return m_loc; }

  const dump_user_location_t &
  get_user_location () const { return m_loc.get_user_location (); }

  const dump_impl_location_t &
  get_impl_location () const { return m_loc.get_impl_location (); }

  enum optinfo_kind get_kind () const { return m_kind; }
  opt_pass *get_pass () const { return m_pass; }
  unsigned int num_items () const { return m_items.length (); }
  const optinfo_item *get_item (unsigned int i) const { return m_items[i]; }

  location_t get_location_t () const { return m_loc.get_location_t (); }
  profile_count get_count () const { return m_loc.get_count (); }

  void add_item (optinfo_item *item);

  void emit_for_opt_problem () const;

 private:
  void emit () const;

  /* Pre-canned ways of manipulating the optinfo, for use by friend class
     dump_context.  */
  void handle_dump_file_kind (dump_flags_t);

 private:
  dump_location_t m_loc;
  enum optinfo_kind m_kind;
  opt_pass *m_pass;
  auto_vec <optinfo_item *> m_items;
};

/* An enum for discriminating between different kinds of optinfo_item.  */

enum optinfo_item_kind
{
  OPTINFO_ITEM_KIND_TEXT,
  OPTINFO_ITEM_KIND_TREE,
  OPTINFO_ITEM_KIND_GIMPLE,
  OPTINFO_ITEM_KIND_SYMTAB_NODE
};

/* An item within an optinfo.  */

class optinfo_item
{
 public:
  optinfo_item (enum optinfo_item_kind kind, location_t location,
		char *text);
  ~optinfo_item ();

  enum optinfo_item_kind get_kind () const { return m_kind; }
  location_t get_location () const { return m_location; }
  const char *get_text () const { return m_text; }

 private:
  /* Metadata (e.g. for optimization records).  */
  enum optinfo_item_kind m_kind;
  location_t m_location;

  /* The textual form of the item, owned by the item.  */
  char *m_text;
};

#endif /* #ifndef GCC_OPTINFO_H */
