/* IPA predicates.
   Copyright (C) 2003-2022 Free Software Foundation, Inc.
   Contributed by Jan Hubicka

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 "tree.h"
#include "cgraph.h"
#include "tree-vrp.h"
#include "alloc-pool.h"
#include "symbol-summary.h"
#include "ipa-prop.h"
#include "ipa-fnsummary.h"
#include "real.h"
#include "fold-const.h"
#include "tree-pretty-print.h"
#include "gimple.h"
#include "gimplify.h"
#include "data-streamer.h"


/* Check whether two set of operations have same effects.  */
static bool
expr_eval_ops_equal_p (expr_eval_ops ops1, expr_eval_ops ops2)
{
  if (ops1)
    {
      if (!ops2 || ops1->length () != ops2->length ())
	return false;

      for (unsigned i = 0; i < ops1->length (); i++)
	{
	  expr_eval_op &op1 = (*ops1)[i];
	  expr_eval_op &op2 = (*ops2)[i];

	  if (op1.code != op2.code
	      || op1.index != op2.index
	      || !vrp_operand_equal_p (op1.val[0], op2.val[0])
	      || !vrp_operand_equal_p (op1.val[1], op2.val[1])
	      || !types_compatible_p (op1.type, op2.type))
	    return false;
	}
      return true;
    }
  return !ops2;
}

/* Add clause CLAUSE into the predicate P.
   When CONDITIONS is NULL do not perform checking whether NEW_CLAUSE
   is obviously true.  This is useful only when NEW_CLAUSE is known to be
   sane.  */

void
ipa_predicate::add_clause (conditions conditions, clause_t new_clause)
{
  int i;
  int i2;
  int insert_here = -1;
  int c1, c2;

  /* True clause.  */
  if (!new_clause)
    return;

  /* False clause makes the whole predicate false.  Kill the other variants.  */
  if (new_clause == (1 << ipa_predicate::false_condition))
    {
      *this = false;
      return;
    }
  if (*this == false)
    return;

  /* No one should be silly enough to add false into nontrivial clauses.  */
  gcc_checking_assert (!(new_clause & (1 << ipa_predicate::false_condition)));

  /* Look where to insert the new_clause.  At the same time prune out
     new_clauses of P that are implied by the new new_clause and thus
     redundant.  */
  for (i = 0, i2 = 0; i <= max_clauses; i++)
    {
      m_clause[i2] = m_clause[i];

      if (!m_clause[i])
	break;

      /* If m_clause[i] implies new_clause, there is nothing to add.  */
      if ((m_clause[i] & new_clause) == m_clause[i])
	{
	  /* We had nothing to add, none of clauses should've become
	     redundant.  */
	  gcc_checking_assert (i == i2);
	  return;
	}

      if (m_clause[i] < new_clause && insert_here < 0)
	insert_here = i2;

      /* If new_clause implies clause[i], then clause[i] becomes redundant.
         Otherwise the clause[i] has to stay.  */
      if ((m_clause[i] & new_clause) != new_clause)
	i2++;
    }

  /* Look for clauses that are obviously true.  I.e.
     op0 == 5 || op0 != 5.  */
  if (conditions)
    for (c1 = ipa_predicate::first_dynamic_condition;
	 c1 < num_conditions; c1++)
      {
	condition *cc1;
	if (!(new_clause & (1 << c1)))
	  continue;
	cc1 = &(*conditions)[c1 - ipa_predicate::first_dynamic_condition];
	/* We have no way to represent !changed and !is_not_constant
	   and thus there is no point for looking for them.  */
	if (cc1->code == changed || cc1->code == is_not_constant)
	  continue;
	for (c2 = c1 + 1; c2 < num_conditions; c2++)
	  if (new_clause & (1 << c2))
	    {
	      condition *cc2 =
		&(*conditions)[c2 - ipa_predicate::first_dynamic_condition];
	      if (cc1->operand_num == cc2->operand_num
		  && vrp_operand_equal_p (cc1->val, cc2->val)
		  && cc2->code != is_not_constant
		  && cc2->code != changed
		  && expr_eval_ops_equal_p (cc1->param_ops, cc2->param_ops)
		  && cc2->agg_contents == cc1->agg_contents
		  && cc2->by_ref == cc1->by_ref
		  && types_compatible_p (cc2->type, cc1->type)
		  && cc1->code == invert_tree_comparison (cc2->code,
							  HONOR_NANS (cc1->val)))
		return;
	    }
      }


  /* We run out of variants.  Be conservative in positive direction.  */
  if (i2 == max_clauses)
    return;
  /* Keep clauses in decreasing order. This makes equivalence testing easy.  */
  m_clause[i2 + 1] = 0;
  if (insert_here >= 0)
    for (; i2 > insert_here; i2--)
      m_clause[i2] = m_clause[i2 - 1];
  else
    insert_here = i2;
  m_clause[insert_here] = new_clause;
}


/* Do THIS &= P.  */

ipa_predicate &
ipa_predicate::operator &= (const ipa_predicate &p)
{
  /* Avoid busy work.  */
  if (p == false || *this == true)
    {
      *this = p;
      return *this;
    }
  if (*this == false || p == true || this == &p)
    return *this;

  int i;

  /* See how far ipa_predicates match.  */
  for (i = 0; m_clause[i] && m_clause[i] == p.m_clause[i]; i++)
    {
      gcc_checking_assert (i < max_clauses);
    }

  /* Combine the ipa_predicates rest.  */
  for (; p.m_clause[i]; i++)
    {
      gcc_checking_assert (i < max_clauses);
      add_clause (NULL, p.m_clause[i]);
    }
  return *this;
}



/* Return THIS | P2.  */

ipa_predicate
ipa_predicate::or_with (conditions conditions,
			const ipa_predicate &p) const
{
  /* Avoid busy work.  */
  if (p == false || *this == true || *this == p)
    return *this;
  if (*this == false || p == true)
    return p;

  /* OK, combine the predicates.  */
  ipa_predicate out = true;

  for (int i = 0; m_clause[i]; i++)
    for (int j = 0; p.m_clause[j]; j++)
      {
	gcc_checking_assert (i < max_clauses && j < max_clauses);
	out.add_clause (conditions, m_clause[i] | p.m_clause[j]);
      }
  return out;
}


/* Having partial truth assignment in POSSIBLE_TRUTHS, return false
   if predicate P is known to be false.  */

bool
ipa_predicate::evaluate (clause_t possible_truths) const
{
  int i;

  /* True remains true.  */
  if (*this == true)
    return true;

  gcc_assert (!(possible_truths & (1 << ipa_predicate::false_condition)));

  /* See if we can find clause we can disprove.  */
  for (i = 0; m_clause[i]; i++)
    {
      gcc_checking_assert (i < max_clauses);
      if (!(m_clause[i] & possible_truths))
	return false;
    }
  return true;
}

/* Return the probability in range 0...REG_BR_PROB_BASE that the predicated
   instruction will be recomputed per invocation of the inlined call.  */

int
ipa_predicate::probability (conditions conds,
	                clause_t possible_truths,
	                vec<inline_param_summary> inline_param_summary) const
{
  int i;
  int combined_prob = REG_BR_PROB_BASE;

  /* True remains true.  */
  if (*this == true)
    return REG_BR_PROB_BASE;

  if (*this == false)
    return 0;

  gcc_assert (!(possible_truths & (1 << ipa_predicate::false_condition)));

  /* See if we can find clause we can disprove.  */
  for (i = 0; m_clause[i]; i++)
    {
      gcc_checking_assert (i < max_clauses);
      if (!(m_clause[i] & possible_truths))
	return 0;
      else
	{
	  int this_prob = 0;
	  int i2;
	  if (!inline_param_summary.exists ())
	    return REG_BR_PROB_BASE;
	  for (i2 = 0; i2 < num_conditions; i2++)
	    if ((m_clause[i] & possible_truths) & (1 << i2))
	      {
		if (i2 >= ipa_predicate::first_dynamic_condition)
		  {
		    condition *c =
		      &(*conds)[i2 - ipa_predicate::first_dynamic_condition];
		    if (c->code == ipa_predicate::changed
			&& (c->operand_num <
			    (int) inline_param_summary.length ()))
		      {
			int iprob =
			  inline_param_summary[c->operand_num].change_prob;
			this_prob = MAX (this_prob, iprob);
		      }
		    else
		      this_prob = REG_BR_PROB_BASE;
		  }
		else
		  this_prob = REG_BR_PROB_BASE;
	      }
	  combined_prob = MIN (this_prob, combined_prob);
	  if (!combined_prob)
	    return 0;
	}
    }
  return combined_prob;
}


/* Dump conditional COND.  */

void
dump_condition (FILE *f, conditions conditions, int cond)
{
  condition *c;
  if (cond == ipa_predicate::false_condition)
    fprintf (f, "false");
  else if (cond == ipa_predicate::not_inlined_condition)
    fprintf (f, "not inlined");
  else
    {
      c = &(*conditions)[cond - ipa_predicate::first_dynamic_condition];
      fprintf (f, "op%i", c->operand_num);
      if (c->agg_contents)
	fprintf (f, "[%soffset: " HOST_WIDE_INT_PRINT_DEC "]",
		 c->by_ref ? "ref " : "", c->offset);

      for (unsigned i = 0; i < vec_safe_length (c->param_ops); i++)
	{
	  expr_eval_op &op = (*(c->param_ops))[i];
	  const char *op_name = op_symbol_code (op.code);

	  if (op_name == op_symbol_code (ERROR_MARK))
	    op_name = get_tree_code_name (op.code);

	  fprintf (f, ",(");

	  if (!op.val[0])
	    {
	      switch (op.code)
		{
		case FLOAT_EXPR:
		case FIX_TRUNC_EXPR:
		case FIXED_CONVERT_EXPR:
		case VIEW_CONVERT_EXPR:
		CASE_CONVERT:
		  if (op.code == VIEW_CONVERT_EXPR)
		    fprintf (f, "VCE");
		  fprintf (f, "(");
		  print_generic_expr (f, op.type);
		  fprintf (f, ")" );
		  break;

		default:
		  fprintf (f, "%s", op_name);
		}
	      fprintf (f, " #");
	    }
	  else if (!op.val[1])
	    {
	      if (op.index)
		{
		  print_generic_expr (f, op.val[0]);
		  fprintf (f, " %s #", op_name);
		}
	      else
		{
		  fprintf (f, "# %s ", op_name);
		  print_generic_expr (f, op.val[0]);
		}
	    }
	  else
	    {
	      fprintf (f, "%s ", op_name);
	      switch (op.index)
		{
		case 0:
		  fprintf (f, "#, ");
		  print_generic_expr (f, op.val[0]);
		  fprintf (f, ", ");
		  print_generic_expr (f, op.val[1]);
		  break;

		case 1:
		  print_generic_expr (f, op.val[0]);
		  fprintf (f, ", #, ");
		  print_generic_expr (f, op.val[1]);
		  break;

		case 2:
		  print_generic_expr (f, op.val[0]);
		  fprintf (f, ", ");
		  print_generic_expr (f, op.val[1]);
		  fprintf (f, ", #");
		  break;

		default:
		  fprintf (f, "*, *, *");
		}
	    }
	  fprintf (f, ")");
	}

      if (c->code == ipa_predicate::is_not_constant)
	{
	  fprintf (f, " not constant");
	  return;
	}
      if (c->code == ipa_predicate::changed)
	{
	  fprintf (f, " changed");
	  return;
	}
      fprintf (f, " %s ", op_symbol_code (c->code));
      print_generic_expr (f, c->val);
    }
}


/* Dump clause CLAUSE.  */

static void
dump_clause (FILE *f, conditions conds, clause_t clause)
{
  int i;
  bool found = false;
  fprintf (f, "(");
  if (!clause)
    fprintf (f, "true");
  for (i = 0; i < ipa_predicate::num_conditions; i++)
    if (clause & (1 << i))
      {
	if (found)
	  fprintf (f, " || ");
	found = true;
	dump_condition (f, conds, i);
      }
  fprintf (f, ")");
}


/* Dump THIS to F.  CONDS a vector of conditions used when evaluating
   ipa_predicates.  When NL is true new line is output at the end of dump.  */

void
ipa_predicate::dump (FILE *f, conditions conds, bool nl) const
{
  int i;
  if (*this == true)
    dump_clause (f, conds, 0);
  else
    for (i = 0; m_clause[i]; i++)
      {
	if (i)
	  fprintf (f, " && ");
	dump_clause (f, conds, m_clause[i]);
      }
  if (nl)
    fprintf (f, "\n");
}


void
ipa_predicate::debug (conditions conds) const
{
  dump (stderr, conds);
}


/* Remap predicate THIS of former function to be predicate of duplicated function.
   POSSIBLE_TRUTHS is clause of possible truths in the duplicated node,
   INFO is inline summary of the duplicated node.  */

ipa_predicate
ipa_predicate::remap_after_duplication (clause_t possible_truths)
{
  int j;
  ipa_predicate out = true;
  for (j = 0; m_clause[j]; j++)
    if (!(possible_truths & m_clause[j]))
      return false;
    else
      out.add_clause (NULL, possible_truths & m_clause[j]);
  return out;
}


/* Translate all conditions from callee representation into caller
   representation and symbolically evaluate predicate THIS into new predicate.

   INFO is ipa_fn_summary of function we are adding predicate into, CALLEE_INFO
   is summary of function predicate P is from. OPERAND_MAP is array giving
   callee formal IDs the caller formal IDs. POSSSIBLE_TRUTHS is clause of all
   callee conditions that may be true in caller context.  TOPLEV_PREDICATE is
   predicate under which callee is executed.  OFFSET_MAP is an array of
   offsets that need to be added to conditions, negative offset means that
   conditions relying on values passed by reference have to be discarded
   because they might not be preserved (and should be considered offset zero
   for other purposes).  */

ipa_predicate
ipa_predicate::remap_after_inlining (class ipa_fn_summary *info,
				 class ipa_node_params *params_summary,
				 class ipa_fn_summary *callee_info,
				 const vec<int> &operand_map,
				 const vec<HOST_WIDE_INT> &offset_map,
				 clause_t possible_truths,
				 const ipa_predicate &toplev_predicate)
{
  int i;
  ipa_predicate out = true;

  /* True ipa_predicate is easy.  */
  if (*this == true)
    return toplev_predicate;
  for (i = 0; m_clause[i]; i++)
    {
      clause_t clause = m_clause[i];
      int cond;
      ipa_predicate clause_predicate = false;

      gcc_assert (i < max_clauses);

      for (cond = 0; cond < num_conditions; cond++)
	/* Do we have condition we can't disprove?   */
	if (clause & possible_truths & (1 << cond))
	  {
	    ipa_predicate cond_predicate;
	    /* Work out if the condition can translate to predicate in the
	       inlined function.  */
	    if (cond >= ipa_predicate::first_dynamic_condition)
	      {
		struct condition *c;

		int index = cond - ipa_predicate::first_dynamic_condition;
		c = &(*callee_info->conds)[index];
		/* See if we can remap condition operand to caller's operand.
		   Otherwise give up.  */
		if (!operand_map.exists ()
		    || (int) operand_map.length () <= c->operand_num
		    || operand_map[c->operand_num] == -1
		    /* TODO: For non-aggregate conditions, adding an offset is
		       basically an arithmetic jump function processing which
		       we should support in future.  */
		    || ((!c->agg_contents || !c->by_ref)
			&& offset_map[c->operand_num] > 0)
		    || (c->agg_contents && c->by_ref
			&& offset_map[c->operand_num] < 0))
		  cond_predicate = true;
		else
		  {
		    struct agg_position_info ap;
		    HOST_WIDE_INT offset_delta = offset_map[c->operand_num];
		    if (offset_delta < 0)
		      {
			gcc_checking_assert (!c->agg_contents || !c->by_ref);
			offset_delta = 0;
		      }
		    gcc_assert (!c->agg_contents
				|| c->by_ref || offset_delta == 0);
		    ap.offset = c->offset + offset_delta;
		    ap.agg_contents = c->agg_contents;
		    ap.by_ref = c->by_ref;
		    cond_predicate = add_condition (info, params_summary,
						    operand_map[c->operand_num],
						    c->type, &ap, c->code,
						    c->val, c->param_ops);
		  }
	      }
	    /* Fixed conditions remains same, construct single
	       condition predicate.  */
	    else
	      cond_predicate = ipa_predicate::predicate_testing_cond (cond);
	    clause_predicate = clause_predicate.or_with (info->conds,
					                 cond_predicate);
	  }
      out &= clause_predicate;
    }
  out &= toplev_predicate;
  return out;
}


/* Read predicate from IB.  */

void
ipa_predicate::stream_in (class lto_input_block *ib)
{
  clause_t clause;
  int k = 0;

  do
    {
      gcc_assert (k <= max_clauses);
      clause = m_clause[k++] = streamer_read_uhwi (ib);
    }
  while (clause);

  /* Zero-initialize the remaining clauses in OUT.  */
  while (k <= max_clauses)
    m_clause[k++] = 0;
}


/* Write predicate P to OB.  */

void
ipa_predicate::stream_out (struct output_block *ob)
{
  int j;
  for (j = 0; m_clause[j]; j++)
    {
      gcc_assert (j < max_clauses);
      streamer_write_uhwi (ob, m_clause[j]);
    }
  streamer_write_uhwi (ob, 0);
}


/* Add condition to condition list SUMMARY.  OPERAND_NUM, TYPE, CODE, VAL and
   PARAM_OPS correspond to fields of condition structure.  AGGPOS describes
   whether the used operand is loaded from an aggregate and where in the
   aggregate it is.  It can be NULL, which means this not a load from an
   aggregate.  */

ipa_predicate
add_condition (class ipa_fn_summary *summary,
	       class ipa_node_params *params_summary,
	       int operand_num,
	       tree type, struct agg_position_info *aggpos,
	       enum tree_code code, tree val, expr_eval_ops param_ops)
{
  int i, j;
  struct condition *c;
  struct condition new_cond;
  HOST_WIDE_INT offset;
  bool agg_contents, by_ref;
  expr_eval_op *op;

  if (params_summary)
    ipa_set_param_used_by_ipa_predicates (params_summary, operand_num, true);

  if (aggpos)
    {
      offset = aggpos->offset;
      agg_contents = aggpos->agg_contents;
      by_ref = aggpos->by_ref;
    }
  else
    {
      offset = 0;
      agg_contents = false;
      by_ref = false;
    }

  gcc_checking_assert (operand_num >= 0);
  for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++)
    {
      if (c->operand_num == operand_num
	  && c->code == code
	  && types_compatible_p (c->type, type)
	  && vrp_operand_equal_p (c->val, val)
	  && c->agg_contents == agg_contents
	  && expr_eval_ops_equal_p (c->param_ops, param_ops)
	  && (!agg_contents || (c->offset == offset && c->by_ref == by_ref)))
	return ipa_predicate::predicate_testing_cond (i);
    }
  /* Too many conditions.  Give up and return constant true.  */
  if (i == ipa_predicate::num_conditions - ipa_predicate::first_dynamic_condition)
    return true;

  new_cond.operand_num = operand_num;
  new_cond.code = code;
  new_cond.type = unshare_expr_without_location (type);
  new_cond.val = val ? unshare_expr_without_location (val) : val;
  new_cond.agg_contents = agg_contents;
  new_cond.by_ref = by_ref;
  new_cond.offset = offset;
  new_cond.param_ops = vec_safe_copy (param_ops);

  for (j = 0; vec_safe_iterate (new_cond.param_ops, j, &op); j++)
    {
      if (op->val[0])
	op->val[0] = unshare_expr_without_location (op->val[0]);
      if (op->val[1])
	op->val[1] = unshare_expr_without_location (op->val[1]);
    }

  vec_safe_push (summary->conds, new_cond);

  return ipa_predicate::predicate_testing_cond (i);
}
