Mercurial > hg > CbC > CbC_gcc
diff gcc/ipa-predicate.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
line wrap: on
line diff
--- a/gcc/ipa-predicate.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/ipa-predicate.c Thu Feb 13 11:34:05 2020 +0900 @@ -1,5 +1,5 @@ /* IPA predicates. - Copyright (C) 2003-2018 Free Software Foundation, Inc. + Copyright (C) 2003-2020 Free Software Foundation, Inc. Contributed by Jan Hubicka This file is part of GCC. @@ -25,17 +25,44 @@ #include "tree.h" #include "cgraph.h" #include "tree-vrp.h" +#include "alloc-pool.h" #include "symbol-summary.h" -#include "alloc-pool.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 @@ -110,14 +137,16 @@ for (c2 = c1 + 1; c2 < num_conditions; c2++) if (new_clause & (1 << c2)) { - condition *cc1 = - &(*conditions)[c1 - predicate::first_dynamic_condition]; condition *cc2 = &(*conditions)[c2 - predicate::first_dynamic_condition]; if (cc1->operand_num == cc2->operand_num - && cc1->val == cc2->val + && vrp_operand_equal_p (cc1->val, cc2->val) && cc2->code != is_not_constant - && cc2->code != predicate::changed + && 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; @@ -300,6 +329,83 @@ 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 == predicate::is_not_constant) { fprintf (f, " not constant"); @@ -338,8 +444,8 @@ } -/* Dump THIS to F. CONDS a vector of conditions used when evauating - predicats. When NL is true new line is output at the end of dump. */ +/* Dump THIS to F. CONDS a vector of conditions used when evaluating + predicates. When NL is true new line is output at the end of dump. */ void predicate::dump (FILE *f, conditions conds, bool nl) const @@ -389,7 +495,7 @@ 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 clausule of all + 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 of offsets that need to be added to conditions, negative offset means that @@ -398,8 +504,9 @@ for other purposes). */ predicate -predicate::remap_after_inlining (struct ipa_fn_summary *info, - struct ipa_fn_summary *callee_info, +predicate::remap_after_inlining (class ipa_fn_summary *info, + class ipa_node_params *params_summary, + class ipa_fn_summary *callee_info, vec<int> operand_map, vec<int> offset_map, clause_t possible_truths, @@ -460,10 +567,10 @@ ap.offset = c->offset + offset_delta; ap.agg_contents = c->agg_contents; ap.by_ref = c->by_ref; - cond_predicate = add_condition (info, + cond_predicate = add_condition (info, params_summary, operand_map[c->operand_num], - c->size, &ap, c->code, - c->val); + c->type, &ap, c->code, + c->val, c->param_ops); } } /* Fixed conditions remains same, construct single @@ -483,7 +590,7 @@ /* Read predicate from IB. */ void -predicate::stream_in (struct lto_input_block *ib) +predicate::stream_in (class lto_input_block *ib) { clause_t clause; int k = 0; @@ -516,21 +623,28 @@ } -/* Add condition to condition list SUMMARY. OPERAND_NUM, SIZE, CODE and VAL - 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. */ +/* 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. */ predicate -add_condition (struct ipa_fn_summary *summary, int operand_num, - HOST_WIDE_INT size, struct agg_position_info *aggpos, - enum tree_code code, tree val) +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; + 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) { @@ -549,10 +663,11 @@ for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++) { if (c->operand_num == operand_num - && c->size == size && c->code == code - && c->val == val + && 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 predicate::predicate_testing_cond (i); } @@ -562,11 +677,21 @@ new_cond.operand_num = operand_num; new_cond.code = code; - new_cond.val = val; + 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.size = size; + 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 predicate::predicate_testing_cond (i);