/* Functions for high level gimple building routines.
   Copyright (C) 2013-2021 Free Software Foundation, 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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "stringpool.h"
#include "tree-vrp.h"
#include "tree-ssanames.h"


/* Return the expression type to use based on the CODE and type of
   the given operand OP.  If the expression CODE is a comparison,
   the returned type is boolean_type_node.  Otherwise, it returns
   the type of OP.  */

static tree
get_expr_type (enum tree_code code, tree op)
{
  return (TREE_CODE_CLASS (code) == tcc_comparison)
	 ? boolean_type_node
	 : TREE_TYPE (op);
}


/* Build a new gimple assignment.  The LHS of the assignment is a new
   temporary whose type matches the given expression.  MODE indicates
   whether the LHS should be an SSA or a normal temporary.  CODE is
   the expression code for the RHS.  OP1 is the first operand and VAL
   is an integer value to be used as the second operand.  */

gassign *
build_assign (enum tree_code code, tree op1, int val, tree lhs)
{
  tree op2 = build_int_cst (TREE_TYPE (op1), val);
  if (lhs == NULL_TREE)
    lhs = make_ssa_name (get_expr_type (code, op1));
  return gimple_build_assign (lhs, code, op1, op2);
}

gassign *
build_assign (enum tree_code code, gimple *g, int val, tree lhs )
{
  return build_assign (code, gimple_assign_lhs (g), val, lhs);
}


/* Build and return a new GIMPLE assignment.  The new assignment will
   have the opcode CODE and operands OP1 and OP2.  The type of the
   expression on the RHS is inferred to be the type of OP1.

   The LHS of the statement will be an SSA name or a GIMPLE temporary
   in normal form depending on the type of builder invoking this
   function.  */

gassign *
build_assign (enum tree_code code, tree op1, tree op2, tree lhs)
{
  if (lhs == NULL_TREE)
    lhs = make_ssa_name (get_expr_type (code, op1));
  return gimple_build_assign (lhs, code, op1, op2);
}

gassign *
build_assign (enum tree_code code, gimple *op1, tree op2, tree lhs)
{
  return build_assign (code, gimple_assign_lhs (op1), op2, lhs);
}

gassign *
build_assign (enum tree_code code, tree op1, gimple *op2, tree lhs)
{
  return build_assign (code, op1, gimple_assign_lhs (op2), lhs);
}

gassign *
build_assign (enum tree_code code, gimple *op1, gimple *op2, tree lhs)
{
  return build_assign (code, gimple_assign_lhs (op1), gimple_assign_lhs (op2),
                       lhs);
}


/* Create and return a type cast assignment. This creates a NOP_EXPR
   that converts OP to TO_TYPE.  */

gassign *
build_type_cast (tree to_type, tree op, tree lhs)
{
  if (lhs == NULL_TREE)
    lhs = make_ssa_name (to_type);
  return gimple_build_assign (lhs, NOP_EXPR, op);
}

gassign *
build_type_cast (tree to_type, gimple *op, tree lhs)
{
  return build_type_cast (to_type, gimple_assign_lhs (op), lhs);
}



