| /* Functions for high level gimple building routines. |
| Copyright (C) 2013-2017 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); |
| } |
| |
| |
| |