/* Rich information on why an optimization wasn't possible.
   Copyright (C) 2018-2021 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_OPT_PROBLEM_H
#define GCC_OPT_PROBLEM_H

#include "diagnostic-core.h" /* for ATTRIBUTE_GCC_DIAG.  */
#include "optinfo.h" /* for optinfo.  */

/* This header declares a family of wrapper classes for tracking a
   success/failure value, while optionally supporting propagating an
   opt_problem * describing any failure back up the call stack.

   For instance, at the deepest point of the callstack where the failure
   happens, rather than:

     if (!check_something ())
       {
         if (dump_enabled_p ())
           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
                            "foo is unsupported.\n");
         return false;
       }
     // [...more checks...]

     // All checks passed:
     return true;

   we can capture the cause of the failure via:

     if (!check_something ())
       return opt_result::failure_at (stmt, "foo is unsupported");
     // [...more checks...]

     // All checks passed:
     return opt_result::success ();

   which effectively returns true or false, whilst recording any problem.

   opt_result::success and opt_result::failure return opt_result values
   which "looks like" true/false respectively, via operator bool().
   If dump_enabled_p, then opt_result::failure also creates an opt_problem *,
   capturing the pertinent data (here, "foo is unsupported " and "stmt").
   If dumps are disabled, then opt_problem instances aren't
   created, and it's equivalent to just returning a bool.

   The opt_problem can be propagated via opt_result values back up
   the call stack to where it makes most sense to the user.
   For instance, rather than:

     bool ok = try_something_that_might_fail ();
     if (!ok)
       {
         if (dump_enabled_p ())
           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
                            "some message.\n");
         return false;
       }

   we can replace the bool with an opt_result, so if dump_enabled_p, we
   assume that if try_something_that_might_fail, an opt_problem * will be
   created, and we can propagate it up the call chain:

     opt_result ok = try_something_that_might_fail ();
     if (!ok)
       {
         if (dump_enabled_p ())
           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
                            "some message.\n");
         return ok; // propagating the opt_result
       }

   opt_result is an opt_wrapper<bool>, where opt_wrapper<T> is a base
   class for wrapping a T, optionally propagating an opt_problem in
   case of failure_at (when dumps are enabled).  Similarly,
   opt_pointer_wrapper<T> can be used to wrap pointer types (where non-NULL
   signifies success, NULL signifies failure).

   In all cases, opt_wrapper<T> acts as if the opt_problem were one of its
   fields, but the opt_problem is actually stored in a global, so that when
   compiled, an opt_wrapper<T> is effectively just a T, so that we're
   still just passing e.g. a bool around; the opt_wrapper<T> classes
   simply provide type-checking and an API to ensure that we provide
   error-messages deep in the callstack at the places where problems
   occur, and that we propagate them.  This also avoids having
   to manage the ownership of the opt_problem instances.

   Using opt_result and opt_wrapper<T> documents the intent of the code
   for the places where we represent success values, and allows the C++ type
   system to track where the deepest points in the callstack are where we
   need to emit the failure messages from.  */

/* A bundle of information about why an optimization failed (e.g.
   vectorization), and the location in both the user's code and
   in GCC itself where the problem occurred.

   Instances are created by static member functions in opt_wrapper
   subclasses, such as opt_result::failure.

   Instances are only created when dump_enabled_p ().  */

class opt_problem
{
 public:
  static opt_problem *get_singleton () { return s_the_problem; }

  opt_problem (const dump_location_t &loc,
	       const char *fmt, va_list *ap)
    ATTRIBUTE_GCC_DUMP_PRINTF (3, 0);

  const dump_location_t &
  get_dump_location () const { return m_optinfo.get_dump_location (); }

  const optinfo & get_optinfo () const { return m_optinfo; }

  void emit_and_clear ();

 private:
  optinfo m_optinfo;

  static opt_problem *s_the_problem;
};

/* A base class for wrapper classes that track a success/failure value, while
   optionally supporting propagating an opt_problem * describing any
   failure back up the call stack.  */

template <typename T>
class opt_wrapper
{
 public:
  typedef T wrapped_t;

  /* Be accessible as the wrapped type.  */
  operator wrapped_t () const { return m_result; }

  /* No public ctor.  */

  wrapped_t get_result () const { return m_result; }
  opt_problem *get_problem () const { return opt_problem::get_singleton (); }

 protected:
  opt_wrapper (wrapped_t result, opt_problem */*problem*/)
  : m_result (result)
  {
    /* "problem" is ignored: although it looks like a field, we
       actually just use the opt_problem singleton, so that
       opt_wrapper<T> in memory is just a T.  */
  }

 private:
  wrapped_t m_result;
};

/* Subclass of opt_wrapper<T> for bool, where
   - true signifies "success", and
   - false signifies "failure"
   whilst effectively propagating an opt_problem * describing any failure
   back up the call stack.  */

class opt_result : public opt_wrapper <bool>
{
 public:
  /* Generate a "success" value: a wrapper around "true".  */

  static opt_result success () { return opt_result (true, NULL); }

  /* Generate a "failure" value: a wrapper around "false", and,
     if dump_enabled_p, an opt_problem.  */

  static opt_result failure_at (const dump_location_t &loc,
				const char *fmt, ...)
	  ATTRIBUTE_GCC_DUMP_PRINTF (2, 3)
  {
    opt_problem *problem = NULL;
    if (dump_enabled_p ())
      {
	va_list ap;
	va_start (ap, fmt);
	problem = new opt_problem (loc, fmt, &ap);
	va_end (ap);
      }
    return opt_result (false, problem);
  }

  /* Given a failure wrapper of some other kind, make an opt_result failure
     object, for propagating the opt_problem up the call stack.  */

  template <typename S>
  static opt_result
  propagate_failure (opt_wrapper <S> other)
  {
    return opt_result (false, other.get_problem ());
  }

 private:
  /* Private ctor.  Instances should be created by the success and failure
     static member functions.  */
  opt_result (wrapped_t result, opt_problem *problem)
  : opt_wrapper <bool> (result, problem)
  {}
};

/* Subclass of opt_wrapper<T> where T is a pointer type, for tracking
   success/failure, where:
   - a non-NULL value signifies "success", and
   - a NULL value signifies "failure",
   whilst effectively propagating an opt_problem * describing any failure
   back up the call stack.  */

template <typename PtrType_t>
class opt_pointer_wrapper : public opt_wrapper <PtrType_t>
{
 public:
  typedef PtrType_t wrapped_pointer_t;

  /* Given a non-NULL pointer, make a success object wrapping it.  */

  static opt_pointer_wrapper <wrapped_pointer_t>
  success (wrapped_pointer_t ptr)
  {
    return opt_pointer_wrapper <wrapped_pointer_t> (ptr, NULL);
  }

  /* Make a NULL pointer failure object, with the given message
     (if dump_enabled_p).  */

  static opt_pointer_wrapper <wrapped_pointer_t>
  failure_at (const dump_location_t &loc,
	      const char *fmt, ...)
    ATTRIBUTE_GCC_DUMP_PRINTF (2, 3)
  {
    opt_problem *problem = NULL;
    if (dump_enabled_p ())
      {
	va_list ap;
	va_start (ap, fmt);
	problem = new opt_problem (loc, fmt, &ap);
	va_end (ap);
      }
    return opt_pointer_wrapper <wrapped_pointer_t> (NULL, problem);
  }

  /* Given a failure wrapper of some other kind, make a NULL pointer
     failure object, propagating the problem.  */

  template <typename S>
  static opt_pointer_wrapper <wrapped_pointer_t>
  propagate_failure (opt_wrapper <S> other)
  {
    return opt_pointer_wrapper <wrapped_pointer_t> (NULL,
						    other.get_problem ());
  }

  /* Support accessing the underlying pointer via ->.  */

  wrapped_pointer_t operator-> () const { return this->get_result (); }

 private:
  /* Private ctor.  Instances should be built using the static member
     functions "success" and "failure".  */
  opt_pointer_wrapper (wrapped_pointer_t result, opt_problem *problem)
  : opt_wrapper<PtrType_t> (result, problem)
  {}
};

/* A typedef for wrapping "tree" so that NULL_TREE can carry an
   opt_problem describing the failure (if dump_enabled_p).  */

typedef opt_pointer_wrapper<tree> opt_tree;

#endif /* #ifndef GCC_OPT_PROBLEM_H */
