/* D-specific tree lowering bits; see also gimple.c.
   Copyright (C) 2020-2021 Free Software Foundation, Inc.

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 "dmd/globals.h"

#include "tree.h"
#include "gimple-expr.h"
#include "gimplify.h"

#include "d-tree.h"


/* Return TRUE if an operand OP of a given TYPE being copied has no data.
   The middle-end does a similar check with zero sized types.  */

static bool
empty_modify_p (tree type, tree op)
{
  tree_code code = TREE_CODE (op);
  switch (code)
    {
    case COMPOUND_EXPR:
      return empty_modify_p (type, TREE_OPERAND (op, 1));

    case CONSTRUCTOR:
      /* Non-empty construcors are valid.  */
      if (CONSTRUCTOR_NELTS (op) != 0 || TREE_CLOBBER_P (op))
	return false;
      break;

    case CALL_EXPR:
      /* Leave nrvo alone because it isn't a copy.  */
      if (CALL_EXPR_RETURN_SLOT_OPT (op))
	return false;
      break;

    default:
      /* If the operand doesn't have a simple form.  */
      if (!is_gimple_lvalue (op) && !INDIRECT_REF_P (op))
	return false;
      break;
    }

  return empty_aggregate_p (type);
}

/* Gimplify assignment from an INIT_EXPR or MODIFY_EXPR.  */

static gimplify_status
d_gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
  tree op0 = TREE_OPERAND (*expr_p, 0);
  tree op1 = TREE_OPERAND (*expr_p, 1);

  if (error_operand_p (op0) || error_operand_p (op1))
    return GS_UNHANDLED;

  /* Remove any copies of empty aggregates.  */
  if (empty_modify_p (TREE_TYPE (op0), op1))
    {
      gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
		     is_gimple_lvalue, fb_lvalue);

      if (TREE_SIDE_EFFECTS (op1))
	gimplify_and_add (op1, pre_p);

      *expr_p = TREE_OPERAND (*expr_p, 0);
      return GS_OK;
    }

  /* If the back end isn't clever enough to know that the lhs and rhs
     types are the same, add an explicit conversion.  */
  if ((AGGREGATE_TYPE_P (TREE_TYPE (op0)) || AGGREGATE_TYPE_P (TREE_TYPE (op1)))
      && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
    {
      TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
					  TREE_TYPE (op0), op1);
      return GS_OK;
    }

  return GS_UNHANDLED;
}

/* Gimplify an ADDR_EXPR node.  */

static gimplify_status
d_gimplify_addr_expr (tree *expr_p)
{
  tree op0 = TREE_OPERAND (*expr_p, 0);
  /* Constructors are not lvalues, so make them one.  */
  if (TREE_CODE (op0) == CONSTRUCTOR)
    {
      TREE_OPERAND (*expr_p, 0) = force_target_expr (op0);
      return GS_OK;
    }

  return GS_UNHANDLED;
}

/* Gimplify a CALL_EXPR node.  */

static gimplify_status
d_gimplify_call_expr (tree *expr_p, gimple_seq *pre_p)
{
  if (CALL_EXPR_ARGS_ORDERED (*expr_p))
    {
      /* Strictly evaluate all arguments from left to right.  */
      int nargs = call_expr_nargs (*expr_p);
      location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location);

      /* No need to enforce evaluation order if only one argument.  */
      if (nargs < 2)
	return GS_UNHANDLED;

      /* Or if all arguments are already free of side-effects.  */
      bool has_side_effects = false;
      for (int i = 0; i < nargs; i++)
	{
	  if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
	    {
	      has_side_effects = true;
	      break;
	    }
	}

      if (!has_side_effects)
	return GS_UNHANDLED;

      /* Leave the last argument for gimplify_call_expr.  */
      for (int i = 0; i < nargs - 1; i++)
	{
	  tree new_arg = CALL_EXPR_ARG (*expr_p, i);

	  /* If argument has a side-effect, gimplify_arg will handle it.  */
	  if (gimplify_arg (&new_arg, pre_p, loc) == GS_ERROR)
	    return GS_ERROR;

	  /* Even if an argument itself doesn't have any side-effects, it
	     might be altered by another argument in the list.  */
	  if (new_arg == CALL_EXPR_ARG (*expr_p, i)
	      && !really_constant_p (new_arg))
	    new_arg = get_formal_tmp_var (new_arg, pre_p);

	  CALL_EXPR_ARG (*expr_p, i) = new_arg;
	}

      return GS_OK;
    }

  return GS_UNHANDLED;
}

/* Gimplify an UNSIGNED_RSHIFT_EXPR node.  */

static gimplify_status
d_gimplify_unsigned_rshift_expr (tree *expr_p)
{
  /* Convert op0 to an unsigned type.  */
  tree op0 = TREE_OPERAND (*expr_p, 0);
  tree op1 = TREE_OPERAND (*expr_p, 1);
  tree type = d_unsigned_type (TREE_TYPE (op0));

  *expr_p = convert (TREE_TYPE (*expr_p),
		     build2 (RSHIFT_EXPR, type, convert (type, op0), op1));
  return GS_OK;
}

/* Implements the lang_hooks.gimplify_expr routine for language D.
   Do gimplification of D specific expression trees in EXPR_P.  */

int
d_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
  switch (TREE_CODE (*expr_p))
    {
    case INIT_EXPR:
    case MODIFY_EXPR:
      return d_gimplify_modify_expr (expr_p, pre_p, post_p);

    case ADDR_EXPR:
      return d_gimplify_addr_expr (expr_p);

    case CALL_EXPR:
      return d_gimplify_call_expr (expr_p, pre_p);

    case UNSIGNED_RSHIFT_EXPR:
      return d_gimplify_unsigned_rshift_expr (expr_p);

    case FLOAT_MOD_EXPR:
      gcc_unreachable ();

    default:
      break;
    }

  return GS_UNHANDLED;
}
