From: Jan Hubicka Date: Thu, 16 Aug 2001 15:41:05 +0000 (+0200) Subject: Thu Aug 16 17:39:45 CEST 2001 Jan Hubicka X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=25e22dc0cb9714b9c85a057d72dc4c6a00d688ab;p=gcc.git Thu Aug 16 17:39:45 CEST 2001 Jan Hubicka * function.c (put_var_into_stack): Temporarily clear DECL_RTL. (assign_params): Avoid setting DECL_RTL to unfinished RTX. (expand_function_start): Likewise. * stmt.c (expand_decl): Likewise. * varasm.c (make_decl_rtx): Likewise. From-SVN: r44940 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 80ff580b7ec..6800290ebfe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +Thu Aug 16 17:39:45 CEST 2001 Jan Hubicka + + * function.c (put_var_into_stack): Temporarily clear DECL_RTL. + (assign_params): Avoid setting DECL_RTL to unfinished RTX. + (expand_function_start): Likewise. + * stmt.c (expand_decl): Likewise. + * varasm.c (make_decl_rtx): Likewise. + 2001-08-16 Jason Merrill * stor-layout.c (layout_decl): Don't set DECL_USER_ALIGN. diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 538888b16d4..d3e581975a9 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -7137,10 +7137,10 @@ the target supports DWARF 2 frame unwind information. This describes commands for alignment. @table @code -@findex LABEL_ALIGN_AFTER_BARRIER -@item LABEL_ALIGN_AFTER_BARRIER (@var{label}) -The alignment (log base 2) to put in front of @var{label}, which follows -a @code{BARRIER}. +@findex JUMP_ALIGN_AFTER_BARRIER +@item JUMP_ALIGN (@var{label}) +The alignment (log base 2) to put in front of @var{label}, which is +a common destination of jumps and has no fallthru incomming edge. This macro need not be defined if you don't want any special alignment to be done at such a time. Most machine descriptions do not currently @@ -7149,8 +7149,17 @@ define the macro. Unless it's necessary to inspect the @var{label} parameter, it is better to set the variable @var{align_jumps} in the target's @code{OVERRIDE_OPTIONS}. Otherwise, you should try to honour the user's -selection in @var{align_jumps} in a @code{LABEL_ALIGN_AFTER_BARRIER} -implementation. +selection in @var{align_jumps} in a @code{JUMP_ALIGN} implementation. + +@table @code +@findex LABEL_ALIGN_AFTER_BARRIER +@item LABEL_ALIGN_AFTER_BARRIER (@var{label}) +The alignment (log base 2) to put in front of @var{label}, which follows +a @code{BARRIER}. + +This macro need not be defined if you don't want any special alignment +to be done at such a time. Most machine descriptions do not currently +define the macro. @findex LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP @item LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP diff --git a/gcc/final.c b/gcc/final.c index d32248196a0..ad922915c85 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -632,11 +632,6 @@ static struct label_alignment *label_align; void init_insn_lengths () { - if (label_align) - { - free (label_align); - label_align = 0; - } if (uid_shuid) { free (uid_shuid); @@ -780,11 +775,19 @@ get_attr_length (insn) #endif #ifndef LABEL_ALIGN_AFTER_BARRIER -#define LABEL_ALIGN_AFTER_BARRIER(LABEL) align_jumps_log +#define LABEL_ALIGN_AFTER_BARRIER(LABEL) 1 #endif #ifndef LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP -#define LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP (align_jumps-1) +#define LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP 0 +#endif + +#ifndef JUMP_ALIGN +#define JUMP_ALIGN(LABEL) align_jumps_log +#endif + +#ifndef JUMP_ALIGN_MAX_SKIP +#define JUMP_ALIGN_MAX_SKIP (align_jumps-1) #endif #ifndef ADDR_VEC_ALIGN @@ -935,6 +938,85 @@ insn_current_reference_address (branch) } #endif /* HAVE_ATTR_length */ +void +compute_alignments () +{ + int i; + int log, max_skip, max_log; + + if (label_align) + { + free (label_align); + label_align = 0; + } + + max_labelno = max_label_num (); + min_labelno = get_first_label_num (); + label_align = (struct label_alignment *) xcalloc ((max_labelno - min_labelno + 1), + sizeof (struct label_alignment)); + + /* If not optimizing or optimizing for size, don't assign any alignments. */ + for (i = 0; i < n_basic_blocks; i++) + { + basic_block bb = BASIC_BLOCK (i); + rtx label = bb->head; + int fallthru_frequency = 0, branch_frequency = 0, has_fallthru = 0; + edge e; + + if (GET_CODE (label) != CODE_LABEL) + continue; + max_log = LABEL_ALIGN (label); + max_skip = LABEL_ALIGN_MAX_SKIP; + + for (e = bb->pred; e; e = e->pred_next) + { + if (e->flags & EDGE_FALLTHRU) + has_fallthru = 1, fallthru_frequency += EDGE_FREQUENCY (e); + else + branch_frequency += EDGE_FREQUENCY (e); + } + + /* There are two purposes to align block with no fallthru incomming edge: + 1) to avoid fetch stalls when branch destination is near cache boundary + 2) to improve cache effciency in case the previous block is not executed + (so it does not need to be in the cache). + + We to catch first case, we align frequently executed blocks. + To catch the second, we align blocks that are executed more frequently + than the predecesor and the predecesor is likely to not be executed + when function is called. */ + + if (!has_fallthru + && (branch_frequency > BB_FREQ_MAX / 10 + || (bb->frequency > BASIC_BLOCK (i - 1)->frequency * 10 + && (BASIC_BLOCK (i - 1)->frequency + <= ENTRY_BLOCK_PTR->frequency / 2)))) + { + log = JUMP_ALIGN (label); + if (max_log < log) + { + max_log = log; + max_skip = JUMP_ALIGN_MAX_SKIP; + } + } + /* In case block is frequent and reached mostly by non-fallthru edge, + align it. It is most likely an first block of loop. */ + if (has_fallthru + && branch_frequency + fallthru_frequency > BB_FREQ_MAX / 10 + && branch_frequency > fallthru_frequency * 5) + { + log = LOOP_ALIGN (label); + if (max_log < log) + { + max_log = log; + max_skip = LOOP_ALIGN_MAX_SKIP; + } + } + LABEL_TO_ALIGNMENT (label) = max_log; + LABEL_TO_MAX_SKIP (label) = max_skip; + } +} + /* Make a pass over all insns and compute their actual lengths by shortening any branches of variable length if possible. */ @@ -972,21 +1054,22 @@ shorten_branches (first) #endif - /* We must do some computations even when not actually shortening, in - order to get the alignment information for the labels. */ - - init_insn_lengths (); - /* Compute maximum UID and allocate label_align / uid_shuid. */ max_uid = get_max_uid (); - max_labelno = max_label_num (); - min_labelno = get_first_label_num (); - label_align = (struct label_alignment *) - xcalloc ((max_labelno - min_labelno + 1), sizeof (struct label_alignment)); - uid_shuid = (int *) xmalloc (max_uid * sizeof *uid_shuid); + if (max_labelno != max_label_num ()) + { + int old = max_labelno; + max_labelno = max_label_num (); + label_align = (struct label_alignment *) xrealloc + (label_align, + (max_labelno - min_labelno + 1) * sizeof (struct label_alignment)); + memset (label_align + old + 1 - min_labelno, 0, + sizeof (struct label_alignment) * (max_labelno - old)); + } + /* Initialize label_align and set up uid_shuid to be strictly monotonically rising with insn order. */ /* We use max_log here to keep track of the maximum alignment we want to @@ -1012,6 +1095,14 @@ shorten_branches (first) else if (GET_CODE (insn) == CODE_LABEL) { rtx next; + + /* Merge in alignments computed by compute_alignments. */ + log = LABEL_TO_ALIGNMENT (insn); + if (max_log < log) + { + max_log = log; + max_skip = LABEL_TO_MAX_SKIP (insn); + } log = LABEL_ALIGN (insn); if (max_log < log) @@ -1063,41 +1154,6 @@ shorten_branches (first) break; } } - /* Again, we allow NOTE_INSN_LOOP_BEG - INSN - CODE_LABEL - sequences in order to handle reorg output efficiently. */ - else if (GET_CODE (insn) == NOTE - && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG) - { - rtx label; - int nest = 0; - - /* Search for the label that starts the loop. - Don't skip past the end of the loop, since that could - lead to putting an alignment where it does not belong. - However, a label after a nested (non-)loop would be OK. */ - for (label = insn; label; label = NEXT_INSN (label)) - { - if (GET_CODE (label) == NOTE - && NOTE_LINE_NUMBER (label) == NOTE_INSN_LOOP_BEG) - nest++; - else if (GET_CODE (label) == NOTE - && NOTE_LINE_NUMBER (label) == NOTE_INSN_LOOP_END - && --nest == 0) - break; - else if (GET_CODE (label) == CODE_LABEL) - { - log = LOOP_ALIGN (label); - if (max_log < log) - { - max_log = log; - max_skip = LOOP_ALIGN_MAX_SKIP; - } - break; - } - } - } - else - continue; } #ifdef HAVE_ATTR_length diff --git a/gcc/output.h b/gcc/output.h index a72f80dbf31..c2cf497485d 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -20,6 +20,9 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* Compute branch alignments based on frequency information in the CFG. */ +extern void compute_alignments PARAMS ((void)); + /* Initialize data in final at the beginning of a compilation. */ extern void init_final PARAMS ((const char *));