summaryrefslogtreecommitdiff
path: root/gcc/tree-call-cdce.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-call-cdce.c')
-rw-r--r--gcc/tree-call-cdce.c205
1 files changed, 97 insertions, 108 deletions
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index 8f7041bbf09..ce9572ca142 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -35,7 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "diagnostic.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-dump.h"
#include "tree-pass.h"
#include "timevar.h"
@@ -99,7 +99,7 @@ typedef struct input_domain
bool is_ub_inclusive;
} inp_domain;
-static VEC (tree, heap) *cond_dead_built_in_calls;
+static VEC (gimple, heap) *cond_dead_built_in_calls;
/* A helper function to construct and return an input
domain object. LB is the lower bound, HAS_LB is
@@ -174,16 +174,16 @@ check_target_format (tree arg)
#define MAX_BASE_INT_BIT_SIZE 32
static bool
-check_pow (tree pow_call)
+check_pow (gimple pow_call)
{
tree base, expn;
enum tree_code bc, ec;
- if (call_expr_nargs (pow_call) != 2)
+ if (gimple_call_num_args (pow_call) != 2)
return false;
- base = CALL_EXPR_ARG (pow_call, 0);
- expn = CALL_EXPR_ARG (pow_call, 1);
+ base = gimple_call_arg (pow_call, 0);
+ expn = gimple_call_arg (pow_call, 1);
if (!check_target_format (expn))
return false;
@@ -212,20 +212,19 @@ check_pow (tree pow_call)
}
else if (bc == SSA_NAME)
{
- tree base_def, base_val, base_val0, base_var, type;
+ tree base_val0, base_var, type;
+ gimple base_def;
int bit_sz;
/* Only handles cases where base value is converted
from integer values. */
base_def = SSA_NAME_DEF_STMT (base);
- if (TREE_CODE (base_def) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (base_def) != GIMPLE_ASSIGN)
return false;
- base_val = GIMPLE_STMT_OPERAND (base_def, 1);
-
- if (TREE_CODE (base_val) != FLOAT_EXPR)
+ if (gimple_assign_rhs_code (base_def) != FLOAT_EXPR)
return false;
- base_val0 = TREE_OPERAND (base_val, 0);
+ base_val0 = gimple_assign_rhs1 (base_def);
base_var = SSA_NAME_VAR (base_val0);
if (!DECL_P (base_var))
@@ -253,11 +252,11 @@ check_pow (tree pow_call)
Returns true if the function call is a candidate. */
static bool
-check_builtin_call (tree bcall)
+check_builtin_call (gimple bcall)
{
tree arg;
- arg = CALL_EXPR_ARG (bcall, 0);
+ arg = gimple_call_arg (bcall, 0);
return check_target_format (arg);
}
@@ -266,18 +265,18 @@ check_builtin_call (tree bcall)
is a candidate. */
static bool
-is_call_dce_candidate (tree call)
+is_call_dce_candidate (gimple call)
{
tree fn;
enum built_in_function fnc;
- if (!flag_tree_builtin_call_dce)
+ /* Only potentially dead calls are considered. */
+ if (gimple_call_lhs (call))
return false;
- gcc_assert (call && TREE_CODE (call) == CALL_EXPR);
-
- fn = get_callee_fndecl (call);
- if (!fn || !DECL_BUILT_IN (fn)
+ fn = gimple_call_fndecl (call);
+ if (!fn
+ || !DECL_BUILT_IN (fn)
|| (DECL_BUILT_IN_CLASS (fn) != BUILT_IN_NORMAL))
return false;
@@ -331,38 +330,35 @@ static void
gen_one_condition (tree arg, int lbub,
enum tree_code tcode,
const char *temp_name1,
- const char *temp_name2,
- VEC (tree, heap) *conds,
+ const char *temp_name2,
+ VEC (gimple, heap) *conds,
unsigned *nconds)
{
tree lbub_real_cst, lbub_cst, float_type;
tree temp, tempn, tempc, tempcn;
- tree stmt1, stmt2, stmt3;
+ gimple stmt1, stmt2, stmt3;
float_type = TREE_TYPE (arg);
lbub_cst = build_int_cst (integer_type_node, lbub);
lbub_real_cst = build_real_from_int_cst (float_type, lbub_cst);
temp = create_tmp_var (float_type, temp_name1);
- stmt1 = build_gimple_modify_stmt (temp, arg);
+ stmt1 = gimple_build_assign (temp, arg);
tempn = make_ssa_name (temp, stmt1);
- GIMPLE_STMT_OPERAND (stmt1, 0) = tempn;
+ gimple_assign_set_lhs (stmt1, tempn);
tempc = create_tmp_var (boolean_type_node, temp_name2);
- stmt2 = build_gimple_modify_stmt (tempc,
- fold_build2 (tcode,
- boolean_type_node,
- tempn, lbub_real_cst));
+ stmt2 = gimple_build_assign (tempc,
+ fold_build2 (tcode,
+ boolean_type_node,
+ tempn, lbub_real_cst));
tempcn = make_ssa_name (tempc, stmt2);
- GIMPLE_STMT_OPERAND (stmt2, 0) = tempcn;
-
- /* fold_built3 not used for gimple statement here,
- as it will hit assertion. */
- stmt3 = build3 (COND_EXPR, void_type_node,
- tempcn, NULL_TREE, NULL_TREE);
- VEC_quick_push (tree, conds, stmt1);
- VEC_quick_push (tree, conds, stmt2);
- VEC_quick_push (tree, conds, stmt3);
+ gimple_assign_set_lhs (stmt2, tempcn);
+
+ stmt3 = gimple_build_cond_from_tree (tempcn, NULL_TREE, NULL_TREE);
+ VEC_quick_push (gimple, conds, stmt1);
+ VEC_quick_push (gimple, conds, stmt2);
+ VEC_quick_push (gimple, conds, stmt3);
(*nconds)++;
}
@@ -377,7 +373,7 @@ gen_one_condition (tree arg, int lbub,
static void
gen_conditions_for_domain (tree arg, inp_domain domain,
- VEC (tree, heap) *conds,
+ VEC (gimple, heap) *conds,
unsigned *nconds)
{
if (domain.has_lb)
@@ -391,7 +387,7 @@ gen_conditions_for_domain (tree arg, inp_domain domain,
{
/* Now push a separator. */
if (domain.has_lb)
- VEC_quick_push (tree, conds, NULL);
+ VEC_quick_push (gimple, conds, NULL);
gen_one_condition (arg, domain.ub,
(domain.is_ub_inclusive
@@ -420,7 +416,7 @@ gen_conditions_for_domain (tree arg, inp_domain domain,
static void
gen_conditions_for_pow_cst_base (tree base, tree expn,
- VEC (tree, heap) *conds,
+ VEC (gimple, heap) *conds,
unsigned *nconds)
{
inp_domain exp_domain;
@@ -456,20 +452,21 @@ gen_conditions_for_pow_cst_base (tree base, tree expn,
static void
gen_conditions_for_pow_int_base (tree base, tree expn,
- VEC (tree, heap) *conds,
+ VEC (gimple, heap) *conds,
unsigned *nconds)
{
- tree base_def, base_nm, base_val, base_val0;
+ gimple base_def;
+ tree base_nm, base_val0;
tree base_var, int_type;
tree temp, tempn;
- tree cst0, stmt1, stmt2;
+ tree cst0;
+ gimple stmt1, stmt2;
int bit_sz, max_exp;
inp_domain exp_domain;
base_def = SSA_NAME_DEF_STMT (base);
- base_nm = GIMPLE_STMT_OPERAND (base_def, 0);
- base_val = GIMPLE_STMT_OPERAND (base_def, 1);
- base_val0 = TREE_OPERAND (base_val, 0);
+ base_nm = gimple_assign_lhs (base_def);
+ base_val0 = gimple_assign_rhs1 (base_def);
base_var = SSA_NAME_VAR (base_val0);
int_type = TREE_TYPE (base_var);
bit_sz = TYPE_PRECISION (int_type);
@@ -514,19 +511,17 @@ gen_conditions_for_pow_int_base (tree base, tree expn,
type is integer. */
/* Push a separator. */
- VEC_quick_push (tree, conds, NULL);
+ VEC_quick_push (gimple, conds, NULL);
temp = create_tmp_var (int_type, "DCE_COND1");
cst0 = build_int_cst (int_type, 0);
- stmt1 = build_gimple_modify_stmt (temp, base_val0);
+ stmt1 = gimple_build_assign (temp, base_val0);
tempn = make_ssa_name (temp, stmt1);
- GIMPLE_STMT_OPERAND (stmt1, 0) = tempn;
- stmt2 = build3 (COND_EXPR, void_type_node,
- fold_build2 (LE_EXPR, boolean_type_node, tempn, cst0),
- NULL_TREE, NULL_TREE);
+ gimple_assign_set_lhs (stmt1, tempn);
+ stmt2 = gimple_build_cond (LE_EXPR, tempn, cst0, NULL_TREE, NULL_TREE);
- VEC_quick_push (tree, conds, stmt1);
- VEC_quick_push (tree, conds, stmt2);
+ VEC_quick_push (gimple, conds, stmt1);
+ VEC_quick_push (gimple, conds, stmt2);
(*nconds)++;
}
@@ -548,7 +543,7 @@ gen_conditions_for_pow_int_base (tree base, tree expn,
and *NCONDS is the number of logical conditions. */
static void
-gen_conditions_for_pow (tree pow_call, VEC (tree, heap) *conds,
+gen_conditions_for_pow (gimple pow_call, VEC (gimple, heap) *conds,
unsigned *nconds)
{
tree base, expn;
@@ -560,18 +555,16 @@ gen_conditions_for_pow (tree pow_call, VEC (tree, heap) *conds,
*nconds = 0;
- base = CALL_EXPR_ARG (pow_call, 0);
- expn = CALL_EXPR_ARG (pow_call, 1);
+ base = gimple_call_arg (pow_call, 0);
+ expn = gimple_call_arg (pow_call, 1);
bc = TREE_CODE (base);
ec = TREE_CODE (expn);
if (bc == REAL_CST)
- gen_conditions_for_pow_cst_base (base, expn,
- conds, nconds);
+ gen_conditions_for_pow_cst_base (base, expn, conds, nconds);
else if (bc == SSA_NAME)
- gen_conditions_for_pow_int_base (base, expn,
- conds, nconds);
+ gen_conditions_for_pow_int_base (base, expn, conds, nconds);
else
gcc_unreachable ();
}
@@ -689,22 +682,19 @@ get_no_error_domain (enum built_in_function fnc)
condition are separated by NULL tree in the vector. */
static void
-gen_shrink_wrap_conditions (tree bi_call, VEC (tree, heap) *conds,
+gen_shrink_wrap_conditions (gimple bi_call, VEC (gimple, heap) *conds,
unsigned int *nconds)
{
- tree call, fn;
+ gimple call;
+ tree fn;
enum built_in_function fnc;
gcc_assert (nconds && conds);
- gcc_assert (VEC_length (tree, conds) == 0);
- gcc_assert (TREE_CODE (bi_call) == GIMPLE_MODIFY_STMT
- || TREE_CODE (bi_call) == CALL_EXPR);
+ gcc_assert (VEC_length (gimple, conds) == 0);
+ gcc_assert (is_gimple_call (bi_call));
call = bi_call;
- if (TREE_CODE (call) == GIMPLE_MODIFY_STMT)
- call = get_call_expr_in (bi_call);
-
- fn = get_callee_fndecl (call);
+ fn = gimple_call_fndecl (call);
gcc_assert (fn && DECL_BUILT_IN (fn));
fnc = DECL_FUNCTION_CODE (fn);
*nconds = 0;
@@ -716,7 +706,7 @@ gen_shrink_wrap_conditions (tree bi_call, VEC (tree, heap) *conds,
tree arg;
inp_domain domain = get_no_error_domain (fnc);
*nconds = 0;
- arg = CALL_EXPR_ARG (bi_call, 0);
+ arg = gimple_call_arg (bi_call, 0);
gen_conditions_for_domain (arg, domain, conds, nconds);
}
@@ -733,21 +723,21 @@ gen_shrink_wrap_conditions (tree bi_call, VEC (tree, heap) *conds,
transformation actually happens. */
static bool
-shrink_wrap_one_built_in_call (tree bi_call)
+shrink_wrap_one_built_in_call (gimple bi_call)
{
- block_stmt_iterator bi_call_bsi;
+ gimple_stmt_iterator bi_call_bsi;
basic_block bi_call_bb, join_tgt_bb, guard_bb, guard_bb0;
edge join_tgt_in_edge_from_call, join_tgt_in_edge_fall_thru;
edge bi_call_in_edge0, guard_bb_in_edge;
- VEC (tree, heap) *conds;
+ VEC (gimple, heap) *conds;
unsigned tn_cond_stmts, nconds;
unsigned ci;
- tree cond_expr = NULL;
- tree cond_expr_start;
+ gimple cond_expr = NULL;
+ gimple cond_expr_start;
tree bi_call_label_decl;
- tree bi_call_label;
+ gimple bi_call_label;
- conds = VEC_alloc (tree, heap, 12);
+ conds = VEC_alloc (gimple, heap, 12);
gen_shrink_wrap_conditions (bi_call, conds, &nconds);
/* This can happen if the condition generator decides
@@ -757,40 +747,40 @@ shrink_wrap_one_built_in_call (tree bi_call)
if (nconds == 0)
return false;
- bi_call_bb = bb_for_stmt (bi_call);
+ bi_call_bb = gimple_bb (bi_call);
/* Now find the join target bb -- split
bi_call_bb if needed. */
- bi_call_bsi = bsi_for_stmt (bi_call);
+ bi_call_bsi = gsi_for_stmt (bi_call);
join_tgt_in_edge_from_call = split_block (bi_call_bb, bi_call);
- bi_call_bsi = bsi_for_stmt (bi_call);
+ bi_call_bsi = gsi_for_stmt (bi_call);
join_tgt_bb = join_tgt_in_edge_from_call->dest;
/* Now it is time to insert the first conditional expression
into bi_call_bb and split this bb so that bi_call is
shrink-wrapped. */
- tn_cond_stmts = VEC_length (tree, conds);
+ tn_cond_stmts = VEC_length (gimple, conds);
cond_expr = NULL;
- cond_expr_start = VEC_index (tree, conds, 0);
+ cond_expr_start = VEC_index (gimple, conds, 0);
for (ci = 0; ci < tn_cond_stmts; ci++)
{
- tree c = VEC_index (tree, conds, ci);
+ gimple c = VEC_index (gimple, conds, ci);
gcc_assert (c || ci != 0);
if (!c)
break;
- bsi_insert_before (&bi_call_bsi, c, BSI_SAME_STMT);
+ gsi_insert_before (&bi_call_bsi, c, GSI_SAME_STMT);
cond_expr = c;
}
nconds--;
ci++;
- gcc_assert (cond_expr && TREE_CODE (cond_expr) == COND_EXPR);
+ gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
/* Now the label. */
bi_call_label_decl = create_artificial_label ();
- bi_call_label = build1 (LABEL_EXPR, void_type_node, bi_call_label_decl);
- bsi_insert_before (&bi_call_bsi, bi_call_label, BSI_SAME_STMT);
+ bi_call_label = gimple_build_label (bi_call_label_decl);
+ gsi_insert_before (&bi_call_bsi, bi_call_label, GSI_SAME_STMT);
bi_call_in_edge0 = split_block (bi_call_bb, cond_expr);
bi_call_in_edge0->flags &= ~EDGE_FALLTHRU;
@@ -810,21 +800,21 @@ shrink_wrap_one_built_in_call (tree bi_call)
{
unsigned ci0;
edge bi_call_in_edge;
- block_stmt_iterator guard_bsi = bsi_for_stmt (cond_expr_start);
+ gimple_stmt_iterator guard_bsi = gsi_for_stmt (cond_expr_start);
ci0 = ci;
- cond_expr_start = VEC_index (tree, conds, ci0);
+ cond_expr_start = VEC_index (gimple, conds, ci0);
for (; ci < tn_cond_stmts; ci++)
{
- tree c = VEC_index (tree, conds, ci);
+ gimple c = VEC_index (gimple, conds, ci);
gcc_assert (c || ci != ci0);
if (!c)
break;
- bsi_insert_before (&guard_bsi, c, BSI_SAME_STMT);
+ gsi_insert_before (&guard_bsi, c, GSI_SAME_STMT);
cond_expr = c;
}
nconds--;
ci++;
- gcc_assert (cond_expr && TREE_CODE (cond_expr) == COND_EXPR);
+ gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
guard_bb_in_edge = split_block (guard_bb, cond_expr);
guard_bb_in_edge->flags &= ~EDGE_FALLTHRU;
guard_bb_in_edge->flags |= EDGE_FALSE_VALUE;
@@ -836,11 +826,11 @@ shrink_wrap_one_built_in_call (tree bi_call)
REG_BR_PROB_BASE - bi_call_in_edge->probability;
}
- VEC_free (tree, heap, conds);
+ VEC_free (gimple, heap, conds);
if (dump_file && (dump_flags & TDF_DETAILS))
{
location_t loc;
- loc = EXPR_LOCATION (bi_call);
+ loc = gimple_location (bi_call);
fprintf (dump_file,
"%s:%d: note: function call is shrink-wrapped"
" into error conditions.\n",
@@ -859,13 +849,13 @@ shrink_wrap_conditional_dead_built_in_calls (void)
bool changed = false;
unsigned i = 0;
- unsigned n = VEC_length (tree, cond_dead_built_in_calls);
+ unsigned n = VEC_length (gimple, cond_dead_built_in_calls);
if (n == 0)
return false;
for (; i < n ; i++)
{
- tree bi_call = VEC_index (tree, cond_dead_built_in_calls, i);
+ gimple bi_call = VEC_index (gimple, cond_dead_built_in_calls, i);
changed |= shrink_wrap_one_built_in_call (bi_call);
}
@@ -878,34 +868,33 @@ static unsigned int
tree_call_cdce (void)
{
basic_block bb;
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
bool something_changed = false;
- cond_dead_built_in_calls = VEC_alloc (tree, heap, 64);
+ cond_dead_built_in_calls = VEC_alloc (gimple, heap, 64);
FOR_EACH_BB (bb)
{
/* Collect dead call candidates. */
- for (i = bsi_start (bb); ! bsi_end_p (i); bsi_next (&i))
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
- tree stmt = bsi_stmt (i);
- if (TREE_CODE (stmt) == CALL_EXPR
+ gimple stmt = gsi_stmt (i);
+ if (is_gimple_call (stmt)
&& is_call_dce_candidate (stmt))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Found conditional dead call: ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
- VEC_quick_push (tree, cond_dead_built_in_calls, stmt);
+ VEC_quick_push (gimple, cond_dead_built_in_calls, stmt);
}
}
}
- something_changed =
- shrink_wrap_conditional_dead_built_in_calls ();
+ something_changed = shrink_wrap_conditional_dead_built_in_calls ();
- VEC_free (tree, heap, cond_dead_built_in_calls);
+ VEC_free (gimple, heap, cond_dead_built_in_calls);
if (something_changed)
{