X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=gcc%2Fvar-tracking.c;h=ce1d92027c452d503c33108db2e90b69403ad7f9;hb=7adcbafe45f8001b698967defe682687b52c0007;hp=a9ca16b0f04d4330f74d65dbbe0b46f363b8887f;hpb=9708ca2be40399d6266bc85c99e085e3fe27a809;p=thirdparty%2Fgcc.git diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index a9ca16b0f04d..ce1d92027c45 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -1,5 +1,5 @@ /* Variable tracking routines for the GNU compiler. - Copyright (C) 2002-2020 Free Software Foundation, Inc. + Copyright (C) 2002-2022 Free Software Foundation, Inc. This file is part of GCC. @@ -118,7 +118,6 @@ #include "function-abi.h" typedef fibonacci_heap bb_heap_t; -typedef fibonacci_node bb_heap_node_t; /* var-tracking.c assumes that tree code with the same value as VALUE rtx code has no chance to appear in REG_EXPR/MEM_EXPRs and isn't a decl. @@ -305,6 +304,9 @@ struct expand_depth int entryvals; }; +/* Type for dependencies actively used when expand FROM into cur_loc. */ +typedef vec deps_vec; + /* This data structure is allocated for one-part variables at the time of emitting notes. */ struct onepart_aux @@ -325,7 +327,7 @@ struct onepart_aux /* The depth of the cur_loc expression. */ expand_depth depth; /* Dependencies actively used when expand FROM into cur_loc. */ - vec deps; + deps_vec deps; }; /* Structure describing one part of variable. */ @@ -434,10 +436,16 @@ int_mem_offset (const_rtx mem) : NULL) #define VAR_LOC_FROM(var) (VAR_LOC_1PAUX (var)->from) #define VAR_LOC_DEPTH(var) (VAR_LOC_1PAUX (var)->depth) -#define VAR_LOC_DEP_VEC(var) (VAR_LOC_1PAUX (var) \ - ? &VAR_LOC_1PAUX (var)->deps \ - : NULL) +#define VAR_LOC_DEP_VEC(var) var_loc_dep_vec (var) + +/* Implements the VAR_LOC_DEP_VEC above as a function to work around + a bogus -Wnonnull (PR c/95554). */ +static inline deps_vec* +var_loc_dep_vec (variable *var) +{ + return VAR_LOC_1PAUX (var) ? &VAR_LOC_1PAUX (var)->deps : NULL; +} typedef unsigned int dvuid; @@ -2442,7 +2450,6 @@ unsuitable_loc (rtx loc) { case PC: case SCRATCH: - case CC0: case ASM_INPUT: case ASM_OPERANDS: return true; @@ -5653,7 +5660,6 @@ non_suitable_const (const_rtx x) case DEBUG_EXPR: case PC: case SCRATCH: - case CC0: case ASM_INPUT: case ASM_OPERANDS: return true; @@ -6117,6 +6123,20 @@ add_stores (rtx loc, const_rtx expr, void *cuip) && preserve) cselib_set_value_sp_based (v); + /* Don't record MO_VAL_SET for VALUEs that can be described using + cfa_base_rtx or cfa_base_rtx + CONST_INT, cselib already knows + all the needed equivalences and they shouldn't change depending + on which register holds that VALUE in some instruction. */ + if (!frame_pointer_needed + && cfa_base_rtx + && cselib_sp_derived_value_p (v) + && loc == stack_pointer_rtx) + { + if (preserve) + preserve_value (v); + return; + } + nloc = replace_expr_with_values (oloc); if (nloc) oloc = nloc; @@ -7056,54 +7076,68 @@ vt_find_locations (void) int htabsz = 0; int htabmax = param_max_vartrack_size; bool success = true; + unsigned int n_blocks_processed = 0; timevar_push (TV_VAR_TRACKING_DATAFLOW); /* Compute reverse completion order of depth first search of the CFG so that the data-flow runs faster. */ rc_order = XNEWVEC (int, n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS); bb_order = XNEWVEC (int, last_basic_block_for_fn (cfun)); - pre_and_rev_post_order_compute (NULL, rc_order, false); - for (i = 0; i < n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS; i++) + auto_bitmap exit_bbs; + bitmap_set_bit (exit_bbs, EXIT_BLOCK); + auto_vec > toplevel_scc_extents; + int n = rev_post_order_and_mark_dfs_back_seme + (cfun, single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), exit_bbs, true, + rc_order, &toplevel_scc_extents); + for (i = 0; i < n; i++) bb_order[rc_order[i]] = i; - free (rc_order); - auto_sbitmap visited (last_basic_block_for_fn (cfun)); in_worklist = sbitmap_alloc (last_basic_block_for_fn (cfun)); in_pending = sbitmap_alloc (last_basic_block_for_fn (cfun)); bitmap_clear (in_worklist); + bitmap_clear (in_pending); + + /* We're performing the dataflow iteration independently over the + toplevel SCCs plus leading non-cyclic entry blocks and separately + over the tail. That ensures best memory locality and the least + number of visited blocks. */ + unsigned extent = 0; + int curr_start = -1; + int curr_end = -1; + do + { + curr_start = curr_end + 1; + if (toplevel_scc_extents.length () <= extent) + curr_end = n - 1; + else + curr_end = toplevel_scc_extents[extent++].second; - FOR_EACH_BB_FN (bb, cfun) - pending->insert (bb_order[bb->index], bb); - bitmap_ones (in_pending); - - while (success && !pending->empty ()) - { - std::swap (worklist, pending); - std::swap (in_worklist, in_pending); - - bitmap_clear (visited); + for (int i = curr_start; i <= curr_end; ++i) + { + pending->insert (i, BASIC_BLOCK_FOR_FN (cfun, rc_order[i])); + bitmap_set_bit (in_pending, rc_order[i]); + } - while (!worklist->empty ()) + while (success && !pending->empty ()) { - bb = worklist->extract_min (); - bitmap_clear_bit (in_worklist, bb->index); - gcc_assert (!bitmap_bit_p (visited, bb->index)); - if (!bitmap_bit_p (visited, bb->index)) + std::swap (worklist, pending); + std::swap (in_worklist, in_pending); + + while (!worklist->empty ()) { bool changed; edge_iterator ei; int oldinsz, oldoutsz; - bitmap_set_bit (visited, bb->index); + bb = worklist->extract_min (); + bitmap_clear_bit (in_worklist, bb->index); if (VTI (bb)->in.vars) { - htabsz - -= shared_hash_htab (VTI (bb)->in.vars)->size () - + shared_hash_htab (VTI (bb)->out.vars)->size (); + htabsz -= (shared_hash_htab (VTI (bb)->in.vars)->size () + + shared_hash_htab (VTI (bb)->out.vars)->size ()); oldinsz = shared_hash_htab (VTI (bb)->in.vars)->elements (); - oldoutsz - = shared_hash_htab (VTI (bb)->out.vars)->elements (); + oldoutsz = shared_hash_htab (VTI (bb)->out.vars)->elements (); } else oldinsz = oldoutsz = 0; @@ -7164,8 +7198,9 @@ vt_find_locations (void) } changed = compute_bb_dataflow (bb); - htabsz += shared_hash_htab (VTI (bb)->in.vars)->size () - + shared_hash_htab (VTI (bb)->out.vars)->size (); + n_blocks_processed++; + htabsz += (shared_hash_htab (VTI (bb)->in.vars)->size () + + shared_hash_htab (VTI (bb)->out.vars)->size ()); if (htabmax && htabsz > htabmax) { @@ -7187,8 +7222,11 @@ vt_find_locations (void) if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun)) continue; - if (bitmap_bit_p (visited, e->dest->index)) + /* Iterate to an earlier block in RPO in the next + round, iterate to the same block immediately. */ + if (bb_order[e->dest->index] < bb_order[bb->index]) { + gcc_assert (bb_order[e->dest->index] >= curr_start); if (!bitmap_bit_p (in_pending, e->dest->index)) { /* Send E->DEST to next round. */ @@ -7197,9 +7235,11 @@ vt_find_locations (void) e->dest); } } - else if (!bitmap_bit_p (in_worklist, e->dest->index)) + else if (bb_order[e->dest->index] <= curr_end + && !bitmap_bit_p (in_worklist, e->dest->index)) { - /* Add E->DEST to current round. */ + /* Add E->DEST to current round or delay + processing if it is in the next SCC. */ bitmap_set_bit (in_worklist, e->dest->index); worklist->insert (bb_order[e->dest->index], e->dest); @@ -7209,8 +7249,8 @@ vt_find_locations (void) if (dump_file) fprintf (dump_file, - "BB %i: in %i (was %i), out %i (was %i), rem %i + %i, tsz %i\n", - bb->index, + "BB %i: in %i (was %i), out %i (was %i), rem %i + %i, " + "tsz %i\n", bb->index, (int)shared_hash_htab (VTI (bb)->in.vars)->size (), oldinsz, (int)shared_hash_htab (VTI (bb)->out.vars)->size (), @@ -7228,11 +7268,16 @@ vt_find_locations (void) } } } + while (curr_end != n - 1); + + statistics_counter_event (cfun, "compute_bb_dataflow times", + n_blocks_processed); if (success && MAY_HAVE_DEBUG_BIND_INSNS) FOR_EACH_BB_FN (bb, cfun) gcc_assert (VTI (bb)->flooded); + free (rc_order); free (bb_order); delete worklist; delete pending; @@ -8099,7 +8144,7 @@ loc_exp_dep_alloc (variable *var, int count) return; allocsize = offsetof (struct onepart_aux, deps) - + vec::embedded_size (count); + + deps_vec::embedded_size (count); if (VAR_LOC_1PAUX (var)) { @@ -10045,19 +10090,25 @@ vt_initialize (void) preserve_value (val); if (reg != hard_frame_pointer_rtx && fixed_regs[REGNO (reg)]) cselib_preserve_cfa_base_value (val, REGNO (reg)); - expr = plus_constant (GET_MODE (stack_pointer_rtx), - stack_pointer_rtx, -ofst); - cselib_add_permanent_equiv (val, expr, get_insns ()); - if (ofst) { - val = cselib_lookup_from_insn (stack_pointer_rtx, - GET_MODE (stack_pointer_rtx), 1, - VOIDmode, get_insns ()); - preserve_value (val); + cselib_val *valsp + = cselib_lookup_from_insn (stack_pointer_rtx, + GET_MODE (stack_pointer_rtx), 1, + VOIDmode, get_insns ()); + preserve_value (valsp); expr = plus_constant (GET_MODE (reg), reg, ofst); - cselib_add_permanent_equiv (val, expr, get_insns ()); + /* This cselib_add_permanent_equiv call needs to be done before + the other cselib_add_permanent_equiv a few lines later, + because after that one is done, cselib_lookup on this expr + will due to the cselib SP_DERIVED_VALUE_P optimizations + return valsp and so no permanent equivalency will be added. */ + cselib_add_permanent_equiv (valsp, expr, get_insns ()); } + + expr = plus_constant (GET_MODE (stack_pointer_rtx), + stack_pointer_rtx, -ofst); + cselib_add_permanent_equiv (val, expr, get_insns ()); } /* In order to factor out the adjustments made to the stack pointer or to @@ -10148,10 +10199,10 @@ vt_initialize (void) vt_add_function_parameters (); + bool record_sp_value = false; FOR_EACH_BB_FN (bb, cfun) { rtx_insn *insn; - HOST_WIDE_INT pre, post = 0; basic_block first_bb, last_bb; if (MAY_HAVE_DEBUG_BIND_INSNS) @@ -10162,6 +10213,15 @@ vt_initialize (void) cselib_get_next_uid ()); } + if (MAY_HAVE_DEBUG_BIND_INSNS + && cfa_base_rtx + && !frame_pointer_needed + && record_sp_value) + cselib_record_sp_cfa_base_equiv (-cfa_base_offset + - VTI (bb)->in.stack_adjust, + BB_HEAD (bb)); + record_sp_value = true; + first_bb = bb; for (;;) { @@ -10187,6 +10247,8 @@ vt_initialize (void) { if (INSN_P (insn)) { + HOST_WIDE_INT pre = 0, post = 0; + if (!frame_pointer_needed) { insn_stack_adjust_offset_pre_post (insn, &pre, &post); @@ -10206,7 +10268,7 @@ vt_initialize (void) cselib_hook_called = false; adjust_insn (bb, insn); - if (!frame_pointer_needed && pre) + if (pre) VTI (bb)->out.stack_adjust += pre; if (DEBUG_MARKER_INSN_P (insn)) @@ -10233,7 +10295,7 @@ vt_initialize (void) add_with_sets (insn, 0, 0); cancel_changes (0); - if (!frame_pointer_needed && post) + if (post) { micro_operation mo; mo.type = MO_ADJUST; @@ -10447,7 +10509,6 @@ variable_tracking_main_1 (void) return 0; } - mark_dfs_back_edges (); if (!vt_initialize ()) { vt_finalize ();