From 131db6b8b25c6cb2349045f8c8196be6e376f454 Mon Sep 17 00:00:00 2001 From: Steven Bosscher Date: Wed, 22 Aug 2012 21:38:03 +0000 Subject: tracer.c (mark_bb_seen): Use SBITMAP_SIZE. * tracer.c (mark_bb_seen): Use SBITMAP_SIZE. * alias.c (MAX_ALIAS_LOOP_PASSES): Update comment with rationale, or rather a lack thereof. (init_alias_analysis): Propagate the latest information across the CFG in topological order to propagate as far as possible in each iteration. Ignore debug insns. From-SVN: r190602 --- gcc/ChangeLog | 10 +++++ gcc/alias.c | 140 ++++++++++++++++++++++++++++++++-------------------------- gcc/tracer.c | 2 +- 3 files changed, 89 insertions(+), 63 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f67c4ac..527f822a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2012-08-22 Steven Bosscher + + * tracer.c (mark_bb_seen): Use SBITMAP_SIZE. + + * alias.c (MAX_ALIAS_LOOP_PASSES): Update comment with rationale, + or rather a lack thereof. + (init_alias_analysis): Propagate the latest information across + the CFG in topological order to propagate as far as possible in + each iteration. Ignore debug insns. + 2012-08-22 H.J. Lu * doc/invoke.texi: Document -mlong-double-64/-mlong-double-80. diff --git a/gcc/alias.c b/gcc/alias.c index de7640f..a26c299 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -168,7 +168,10 @@ static void memory_modified_1 (rtx, const_rtx, void *); #define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X))) /* Cap the number of passes we make over the insns propagating alias - information through set chains. 10 is a completely arbitrary choice. */ + information through set chains. + ??? 10 is a completely arbitrary choice. This should be based on the + maximum loop depth in the CFG, but we do not have this information + available (even if current_loops _is_ available). */ #define MAX_ALIAS_LOOP_PASSES 10 /* reg_base_value[N] gives an address to which register N is related. @@ -2764,6 +2767,8 @@ init_alias_analysis (void) int i; unsigned int ui; rtx insn, val; + int rpo_cnt; + int *rpo; timevar_push (TV_ALIAS_ANALYSIS); @@ -2786,6 +2791,9 @@ init_alias_analysis (void) "constant" information from the previous pass to propagate alias information through another level of assignments. + The propagation is done on the CFG in reverse post-order, to propagate + things forward as far as possible in each iteration. + This could get expensive if the assignment chains are long. Maybe we should throttle the number of iterations, possibly based on the optimization level or flag_expensive_optimizations. @@ -2801,6 +2809,9 @@ init_alias_analysis (void) The state of the arrays for the set chain in question does not matter since the program has undefined behavior. */ + rpo = XNEWVEC (int, n_basic_blocks); + rpo_cnt = pre_and_rev_post_order_compute (NULL, rpo, false); + pass = 0; do { @@ -2833,80 +2844,84 @@ init_alias_analysis (void) FIRST_PSEUDO_REGISTER * sizeof (rtx)); /* Walk the insns adding values to the new_reg_base_value array. */ - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + for (i = 0; i < rpo_cnt; i++) { - if (INSN_P (insn)) + basic_block bb = BASIC_BLOCK (rpo[i]); + FOR_BB_INSNS (bb, insn) { - rtx note, set; + if (NONDEBUG_INSN_P (insn)) + { + rtx note, set; #if defined (HAVE_prologue) || defined (HAVE_epilogue) - /* The prologue/epilogue insns are not threaded onto the - insn chain until after reload has completed. Thus, - there is no sense wasting time checking if INSN is in - the prologue/epilogue until after reload has completed. */ - if (reload_completed - && prologue_epilogue_contains (insn)) - continue; + /* The prologue/epilogue insns are not threaded onto the + insn chain until after reload has completed. Thus, + there is no sense wasting time checking if INSN is in + the prologue/epilogue until after reload has completed. */ + if (reload_completed + && prologue_epilogue_contains (insn)) + continue; #endif - /* If this insn has a noalias note, process it, Otherwise, - scan for sets. A simple set will have no side effects - which could change the base value of any other register. */ + /* If this insn has a noalias note, process it, Otherwise, + scan for sets. A simple set will have no side effects + which could change the base value of any other register. */ - if (GET_CODE (PATTERN (insn)) == SET - && REG_NOTES (insn) != 0 - && find_reg_note (insn, REG_NOALIAS, NULL_RTX)) - record_set (SET_DEST (PATTERN (insn)), NULL_RTX, NULL); - else - note_stores (PATTERN (insn), record_set, NULL); + if (GET_CODE (PATTERN (insn)) == SET + && REG_NOTES (insn) != 0 + && find_reg_note (insn, REG_NOALIAS, NULL_RTX)) + record_set (SET_DEST (PATTERN (insn)), NULL_RTX, NULL); + else + note_stores (PATTERN (insn), record_set, NULL); - set = single_set (insn); + set = single_set (insn); - if (set != 0 - && REG_P (SET_DEST (set)) - && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER) - { - unsigned int regno = REGNO (SET_DEST (set)); - rtx src = SET_SRC (set); - rtx t; - - note = find_reg_equal_equiv_note (insn); - if (note && REG_NOTE_KIND (note) == REG_EQUAL - && DF_REG_DEF_COUNT (regno) != 1) - note = NULL_RTX; - - if (note != NULL_RTX - && GET_CODE (XEXP (note, 0)) != EXPR_LIST - && ! rtx_varies_p (XEXP (note, 0), 1) - && ! reg_overlap_mentioned_p (SET_DEST (set), - XEXP (note, 0))) - { - set_reg_known_value (regno, XEXP (note, 0)); - set_reg_known_equiv_p (regno, - REG_NOTE_KIND (note) == REG_EQUIV); - } - else if (DF_REG_DEF_COUNT (regno) == 1 - && GET_CODE (src) == PLUS - && REG_P (XEXP (src, 0)) - && (t = get_reg_known_value (REGNO (XEXP (src, 0)))) - && CONST_INT_P (XEXP (src, 1))) - { - t = plus_constant (GET_MODE (src), t, - INTVAL (XEXP (src, 1))); - set_reg_known_value (regno, t); - set_reg_known_equiv_p (regno, false); - } - else if (DF_REG_DEF_COUNT (regno) == 1 - && ! rtx_varies_p (src, 1)) + if (set != 0 + && REG_P (SET_DEST (set)) + && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER) { - set_reg_known_value (regno, src); - set_reg_known_equiv_p (regno, false); + unsigned int regno = REGNO (SET_DEST (set)); + rtx src = SET_SRC (set); + rtx t; + + note = find_reg_equal_equiv_note (insn); + if (note && REG_NOTE_KIND (note) == REG_EQUAL + && DF_REG_DEF_COUNT (regno) != 1) + note = NULL_RTX; + + if (note != NULL_RTX + && GET_CODE (XEXP (note, 0)) != EXPR_LIST + && ! rtx_varies_p (XEXP (note, 0), 1) + && ! reg_overlap_mentioned_p (SET_DEST (set), + XEXP (note, 0))) + { + set_reg_known_value (regno, XEXP (note, 0)); + set_reg_known_equiv_p (regno, + REG_NOTE_KIND (note) == REG_EQUIV); + } + else if (DF_REG_DEF_COUNT (regno) == 1 + && GET_CODE (src) == PLUS + && REG_P (XEXP (src, 0)) + && (t = get_reg_known_value (REGNO (XEXP (src, 0)))) + && CONST_INT_P (XEXP (src, 1))) + { + t = plus_constant (GET_MODE (src), t, + INTVAL (XEXP (src, 1))); + set_reg_known_value (regno, t); + set_reg_known_equiv_p (regno, false); + } + else if (DF_REG_DEF_COUNT (regno) == 1 + && ! rtx_varies_p (src, 1)) + { + set_reg_known_value (regno, src); + set_reg_known_equiv_p (regno, false); + } } } + else if (NOTE_P (insn) + && NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG) + copying_arguments = false; } - else if (NOTE_P (insn) - && NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG) - copying_arguments = false; } /* Now propagate values from new_reg_base_value to reg_base_value. */ @@ -2925,6 +2940,7 @@ init_alias_analysis (void) } } while (changed && ++pass < MAX_ALIAS_LOOP_PASSES); + XDELETEVEC (rpo); /* Fill in the remaining entries. */ FOR_EACH_VEC_ELT (rtx, reg_known_value, i, val) diff --git a/gcc/tracer.c b/gcc/tracer.c index f60f348..9b1d724 100644 --- a/gcc/tracer.c +++ b/gcc/tracer.c @@ -69,7 +69,7 @@ sbitmap bb_seen; static inline void mark_bb_seen (basic_block bb) { - unsigned int size = SBITMAP_SIZE_BYTES (bb_seen) * 8; + unsigned int size = SBITMAP_SIZE (bb_seen); if ((unsigned int)bb->index >= size) bb_seen = sbitmap_resize (bb_seen, size * 2, 0); -- cgit v1.1