Mercurial > hg > CbC > CbC_gcc
diff gcc/loop-iv.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/loop-iv.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/loop-iv.c Thu Feb 13 11:34:05 2020 +0900 @@ -1,5 +1,5 @@ /* Rtl-level induction variable analysis. - Copyright (C) 2004-2018 Free Software Foundation, Inc. + Copyright (C) 2004-2020 Free Software Foundation, Inc. This file is part of GCC. @@ -61,6 +61,9 @@ #include "intl.h" #include "dumpfile.h" #include "rtl-iter.h" +#include "tree-ssa-loop-niter.h" +#include "regs.h" +#include "function-abi.h" /* Possible return values of iv_get_reaching_def. */ @@ -84,10 +87,11 @@ /* Information about a biv. */ -struct biv_entry +class biv_entry { +public: unsigned regno; /* The register of the biv. */ - struct rtx_iv iv; /* Value of the biv. */ + class rtx_iv iv; /* Value of the biv. */ }; static bool clean_slate = true; @@ -95,7 +99,7 @@ static unsigned int iv_ref_table_size = 0; /* Table of rtx_ivs indexed by the df_ref uid field. */ -static struct rtx_iv ** iv_ref_table; +static class rtx_iv ** iv_ref_table; /* Induction variable stored at the reference. */ #define DF_REF_IV(REF) iv_ref_table[DF_REF_ID (REF)] @@ -103,7 +107,7 @@ /* The current loop. */ -static struct loop *current_loop; +static class loop *current_loop; /* Hashtable helper. */ @@ -134,7 +138,7 @@ static hash_table<biv_entry_hasher> *bivs; -static bool iv_analyze_op (rtx_insn *, scalar_int_mode, rtx, struct rtx_iv *); +static bool iv_analyze_op (rtx_insn *, scalar_int_mode, rtx, class rtx_iv *); /* Return the RTX code corresponding to the IV extend code EXTEND. */ static inline enum rtx_code @@ -154,9 +158,9 @@ /* Dumps information about IV to FILE. */ -extern void dump_iv_info (FILE *, struct rtx_iv *); +extern void dump_iv_info (FILE *, class rtx_iv *); void -dump_iv_info (FILE *file, struct rtx_iv *iv) +dump_iv_info (FILE *file, class rtx_iv *iv) { if (!iv->base) { @@ -202,9 +206,9 @@ if (iv_ref_table_size < DF_DEFS_TABLE_SIZE ()) { unsigned int new_size = DF_DEFS_TABLE_SIZE () + (DF_DEFS_TABLE_SIZE () / 4); - iv_ref_table = XRESIZEVEC (struct rtx_iv *, iv_ref_table, new_size); + iv_ref_table = XRESIZEVEC (class rtx_iv *, iv_ref_table, new_size); memset (&iv_ref_table[iv_ref_table_size], 0, - (new_size - iv_ref_table_size) * sizeof (struct rtx_iv *)); + (new_size - iv_ref_table_size) * sizeof (class rtx_iv *)); iv_ref_table_size = new_size; } } @@ -243,7 +247,7 @@ clear_iv_info (void) { unsigned i, n_defs = DF_DEFS_TABLE_SIZE (); - struct rtx_iv *iv; + class rtx_iv *iv; check_iv_ref_table_size (); for (i = 0; i < n_defs; i++) @@ -263,7 +267,7 @@ /* Prepare the data for an induction variable analysis of a LOOP. */ void -iv_analysis_loop_init (struct loop *loop) +iv_analysis_loop_init (class loop *loop) { current_loop = loop; @@ -301,7 +305,7 @@ { df_ref single_rd = NULL, adef; unsigned regno = REGNO (reg); - struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (current_loop->latch); + class df_rd_bb_info *bb_info = DF_RD_BB_INFO (current_loop->latch); for (adef = DF_REG_DEF_CHAIN (regno); adef; adef = DF_REF_NEXT_REG (adef)) { @@ -384,7 +388,7 @@ consistency with other iv manipulation functions that may fail). */ static bool -iv_constant (struct rtx_iv *iv, scalar_int_mode mode, rtx cst) +iv_constant (class rtx_iv *iv, scalar_int_mode mode, rtx cst) { iv->mode = mode; iv->base = cst; @@ -401,7 +405,7 @@ /* Evaluates application of subreg to MODE on IV. */ static bool -iv_subreg (struct rtx_iv *iv, scalar_int_mode mode) +iv_subreg (class rtx_iv *iv, scalar_int_mode mode) { /* If iv is invariant, just calculate the new value. */ if (iv->step == const0_rtx @@ -443,7 +447,7 @@ /* Evaluates application of EXTEND to MODE on IV. */ static bool -iv_extend (struct rtx_iv *iv, enum iv_extend_code extend, scalar_int_mode mode) +iv_extend (class rtx_iv *iv, enum iv_extend_code extend, scalar_int_mode mode) { /* If iv is invariant, just calculate the new value. */ if (iv->step == const0_rtx @@ -481,7 +485,7 @@ /* Evaluates negation of IV. */ static bool -iv_neg (struct rtx_iv *iv) +iv_neg (class rtx_iv *iv) { if (iv->extend == IV_UNKNOWN_EXTEND) { @@ -504,7 +508,7 @@ /* Evaluates addition or subtraction (according to OP) of IV1 to IV0. */ static bool -iv_add (struct rtx_iv *iv0, struct rtx_iv *iv1, enum rtx_code op) +iv_add (class rtx_iv *iv0, class rtx_iv *iv1, enum rtx_code op) { scalar_int_mode mode; rtx arg; @@ -574,7 +578,7 @@ /* Evaluates multiplication of IV by constant CST. */ static bool -iv_mult (struct rtx_iv *iv, rtx mby) +iv_mult (class rtx_iv *iv, rtx mby) { scalar_int_mode mode = iv->extend_mode; @@ -599,7 +603,7 @@ /* Evaluates shift of IV by constant CST. */ static bool -iv_shift (struct rtx_iv *iv, rtx mby) +iv_shift (class rtx_iv *iv, rtx mby) { scalar_int_mode mode = iv->extend_mode; @@ -809,9 +813,9 @@ /* Records information that DEF is induction variable IV. */ static void -record_iv (df_ref def, struct rtx_iv *iv) +record_iv (df_ref def, class rtx_iv *iv) { - struct rtx_iv *recorded_iv = XNEW (struct rtx_iv); + class rtx_iv *recorded_iv = XNEW (class rtx_iv); *recorded_iv = *iv; check_iv_ref_table_size (); @@ -822,9 +826,9 @@ IV and return true. Otherwise return false. */ static bool -analyzed_for_bivness_p (rtx def, struct rtx_iv *iv) +analyzed_for_bivness_p (rtx def, class rtx_iv *iv) { - struct biv_entry *biv = bivs->find_with_hash (def, REGNO (def)); + class biv_entry *biv = bivs->find_with_hash (def, REGNO (def)); if (!biv) return false; @@ -834,9 +838,9 @@ } static void -record_biv (rtx def, struct rtx_iv *iv) +record_biv (rtx def, class rtx_iv *iv) { - struct biv_entry *biv = XNEW (struct biv_entry); + class biv_entry *biv = XNEW (class biv_entry); biv_entry **slot = bivs->find_slot_with_hash (def, REGNO (def), INSERT); biv->regno = REGNO (def); @@ -849,7 +853,7 @@ to *IV. OUTER_MODE is the mode of DEF. */ static bool -iv_analyze_biv (scalar_int_mode outer_mode, rtx def, struct rtx_iv *iv) +iv_analyze_biv (scalar_int_mode outer_mode, rtx def, class rtx_iv *iv) { rtx inner_step, outer_step; scalar_int_mode inner_mode; @@ -927,11 +931,11 @@ bool iv_analyze_expr (rtx_insn *insn, scalar_int_mode mode, rtx rhs, - struct rtx_iv *iv) + class rtx_iv *iv) { rtx mby = NULL_RTX; rtx op0 = NULL_RTX, op1 = NULL_RTX; - struct rtx_iv iv0, iv1; + class rtx_iv iv0, iv1; enum rtx_code code = GET_CODE (rhs); scalar_int_mode omode = mode; @@ -1038,7 +1042,7 @@ /* Analyzes iv DEF and stores the result to *IV. */ static bool -iv_analyze_def (df_ref def, struct rtx_iv *iv) +iv_analyze_def (df_ref def, class rtx_iv *iv) { rtx_insn *insn = DF_REF_INSN (def); rtx reg = DF_REF_REG (def); @@ -1102,7 +1106,7 @@ mode of OP. */ static bool -iv_analyze_op (rtx_insn *insn, scalar_int_mode mode, rtx op, struct rtx_iv *iv) +iv_analyze_op (rtx_insn *insn, scalar_int_mode mode, rtx op, class rtx_iv *iv) { df_ref def = NULL; enum iv_grd_result res; @@ -1163,7 +1167,7 @@ mode of VAL. */ bool -iv_analyze (rtx_insn *insn, scalar_int_mode mode, rtx val, struct rtx_iv *iv) +iv_analyze (rtx_insn *insn, scalar_int_mode mode, rtx val, class rtx_iv *iv) { rtx reg; @@ -1188,7 +1192,7 @@ /* Analyzes definition of DEF in INSN and stores the result to IV. */ bool -iv_analyze_result (rtx_insn *insn, rtx def, struct rtx_iv *iv) +iv_analyze_result (rtx_insn *insn, rtx def, class rtx_iv *iv) { df_ref adef; @@ -1208,7 +1212,7 @@ bool biv_p (rtx_insn *insn, scalar_int_mode mode, rtx reg) { - struct rtx_iv iv; + class rtx_iv iv; df_ref def, last_def; if (!simple_reg_p (reg)) @@ -1230,7 +1234,7 @@ /* Calculates value of IV at ITERATION-th iteration. */ rtx -get_iv_value (struct rtx_iv *iv, rtx iteration) +get_iv_value (class rtx_iv *iv, rtx iteration) { rtx val; @@ -1380,24 +1384,23 @@ static rtx find_single_def_src (unsigned int regno) { - df_ref adef; - rtx set, src; - - for (;;) + rtx src = NULL_RTX; + + /* Don't look through unbounded number of single definition REG copies, + there might be loops for sources with uninitialized variables. */ + for (int cnt = 0; cnt < 128; cnt++) { - rtx note; - adef = DF_REG_DEF_CHAIN (regno); + df_ref adef = DF_REG_DEF_CHAIN (regno); if (adef == NULL || DF_REF_NEXT_REG (adef) != NULL || DF_REF_IS_ARTIFICIAL (adef)) return NULL_RTX; - set = single_set (DF_REF_INSN (adef)); + rtx set = single_set (DF_REF_INSN (adef)); if (set == NULL || !REG_P (SET_DEST (set)) || REGNO (SET_DEST (set)) != regno) return NULL_RTX; - note = find_reg_equal_equiv_note (DF_REF_INSN (adef)); - + rtx note = find_reg_equal_equiv_note (DF_REF_INSN (adef)); if (note && function_invariant_p (XEXP (note, 0))) { src = XEXP (note, 0); @@ -1849,7 +1852,7 @@ is a list, its elements are assumed to be combined using OP. */ static void -simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) +simplify_using_initial_values (class loop *loop, enum rtx_code op, rtx *expr) { bool expression_valid; rtx head, tail, last_valid_expr; @@ -1968,15 +1971,15 @@ continue; CLEAR_REG_SET (this_altered); - note_stores (PATTERN (insn), mark_altered, this_altered); + note_stores (insn, mark_altered, this_altered); if (CALL_P (insn)) { - /* Kill all call clobbered registers. */ - unsigned int i; - hard_reg_set_iterator hrsi; - EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, - 0, i, hrsi) - SET_REGNO_REG_SET (this_altered, i); + /* Kill all registers that might be clobbered by the call. + We don't track modes of hard registers, so we need to be + conservative and assume that partial kills are full kills. */ + function_abi callee_abi = insn_callee_abi (insn); + IOR_REG_SET_HRS (this_altered, + callee_abi.full_and_partial_reg_clobbers ()); } if (suitable_set_for_replacement (insn, &dest, &src)) @@ -2070,8 +2073,8 @@ is SIGNED_P to DESC. */ static void -shorten_into_mode (struct rtx_iv *iv, scalar_int_mode mode, - enum rtx_code cond, bool signed_p, struct niter_desc *desc) +shorten_into_mode (class rtx_iv *iv, scalar_int_mode mode, + enum rtx_code cond, bool signed_p, class niter_desc *desc) { rtx mmin, mmax, cond_over, cond_under; @@ -2129,8 +2132,8 @@ some assumptions to DESC). */ static bool -canonicalize_iv_subregs (struct rtx_iv *iv0, struct rtx_iv *iv1, - enum rtx_code cond, struct niter_desc *desc) +canonicalize_iv_subregs (class rtx_iv *iv0, class rtx_iv *iv1, + enum rtx_code cond, class niter_desc *desc) { scalar_int_mode comp_mode; bool signed_p; @@ -2245,7 +2248,7 @@ expression for the number of iterations, before we tried to simplify it. */ static uint64_t -determine_max_iter (struct loop *loop, struct niter_desc *desc, rtx old_niter) +determine_max_iter (class loop *loop, class niter_desc *desc, rtx old_niter) { rtx niter = desc->niter_expr; rtx mmin, mmax, cmp; @@ -2303,11 +2306,11 @@ (basically its rtl version), complicated by things like subregs. */ static void -iv_number_of_iterations (struct loop *loop, rtx_insn *insn, rtx condition, - struct niter_desc *desc) +iv_number_of_iterations (class loop *loop, rtx_insn *insn, rtx condition, + class niter_desc *desc) { rtx op0, op1, delta, step, bound, may_xform, tmp, tmp0, tmp1; - struct rtx_iv iv0, iv1; + class rtx_iv iv0, iv1; rtx assumption, may_not_xform; enum rtx_code cond; machine_mode nonvoid_mode; @@ -2865,7 +2868,7 @@ into DESC. */ static void -check_simple_exit (struct loop *loop, edge e, struct niter_desc *desc) +check_simple_exit (class loop *loop, edge e, class niter_desc *desc) { basic_block exit_bb; rtx condition; @@ -2913,12 +2916,12 @@ /* Finds a simple exit of LOOP and stores its description into DESC. */ void -find_simple_exit (struct loop *loop, struct niter_desc *desc) +find_simple_exit (class loop *loop, class niter_desc *desc) { unsigned i; basic_block *body; edge e; - struct niter_desc act; + class niter_desc act; bool any = false; edge_iterator ei; @@ -2997,16 +3000,29 @@ fprintf (dump_file, "Loop %d is not simple.\n", loop->num); } + /* Fix up the finiteness if possible. We can only do it for single exit, + since the loop is finite, but it's possible that we predicate one loop + exit to be finite which can not be determined as finite in middle-end as + well. It results in incorrect predicate information on the exit condition + expression. For example, if says [(int) _1 + -8, + , -8] != 0 finite, + it means _1 can exactly divide -8. */ + if (desc->infinite && single_exit (loop) && finite_loop_p (loop)) + { + desc->infinite = NULL_RTX; + if (dump_file) + fprintf (dump_file, " infinite updated to finite.\n"); + } + free (body); } /* Creates a simple loop description of LOOP if it was not computed already. */ -struct niter_desc * -get_simple_loop_desc (struct loop *loop) +class niter_desc * +get_simple_loop_desc (class loop *loop) { - struct niter_desc *desc = simple_loop_desc (loop); + class niter_desc *desc = simple_loop_desc (loop); if (desc) return desc; @@ -3023,9 +3039,9 @@ /* Releases simple loop description for LOOP. */ void -free_simple_loop_desc (struct loop *loop) +free_simple_loop_desc (class loop *loop) { - struct niter_desc *desc = simple_loop_desc (loop); + class niter_desc *desc = simple_loop_desc (loop); if (!desc) return;