aboutsummaryrefslogtreecommitdiff
path: root/gcc/gcse.c
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2015-03-22 23:21:04 -0600
committerJeff Law <law@gcc.gnu.org>2015-03-22 23:21:04 -0600
commitaf3eb1106883dffe6b1164070a00ad0c14df1146 (patch)
treeff31c846a2349895a68d8feecadffa34bf433a27 /gcc/gcse.c
parent4460b2dc61de31c84b9a25464eea06be0567c0db (diff)
downloadgcc-af3eb1106883dffe6b1164070a00ad0c14df1146.zip
gcc-af3eb1106883dffe6b1164070a00ad0c14df1146.tar.gz
gcc-af3eb1106883dffe6b1164070a00ad0c14df1146.tar.bz2
re PR rtl-optimization/64317 (Ineffective allocation of PIC base register)
PR rtl-optimization/64317 * Makefile.in (OBJS): Add gcse-common.c * gcse.c: Include gcse-common.h (struct modify_pair_s): Move structure definition to gcse-common.h (compute_transp): Move function to gcse-common.c. (canon_list_insert): Similarly. (record_last_mem_set_info): Break out some code and put it into gcse-common.c. Call into the new common code. (compute_local_properties): Pass additional arguments to compute_transp. * postreload-gcse.c: Include gcse-common.h and df.h (modify_mem_list_set, blocks_with_calls): New variables. (modify_mem_list, canon_modify_mem_list, transp): Likewise. (get_bb_avail_insn): Pass in the expression index too. (alloc_mem): Allocate memory for the new bitmaps and lists. (free_mem): Free memory for the new bitmaps and lists. (insert_expr_in_table): Record a bitmap index for each entry we add to the table. (record_last_mem_set_info): Call into common code in gcse-common.c. (get_bb_avail_insn): If no available insn was found in the requested BB. If BB has a single predecessor, see if the expression is transparent in BB and available in that single predecessor. (compute_expr_transp): New wrapper for compute_transp. (eliminate_partially_redundant_load): Pass expression's bitmap_index to get_bb_avail_insn. Compute next_pred_bb_end a bit later. (gcse_after_reload_main): If there are elements in the hash table, then compute transparency for all the elements in the hash table. * gcse-common.h: New file. * gcse-common.c: New file. From-SVN: r221585
Diffstat (limited to 'gcc/gcse.c')
-rw-r--r--gcc/gcse.c179
1 files changed, 9 insertions, 170 deletions
diff --git a/gcc/gcse.c b/gcc/gcse.c
index e03b36c..37aac6a 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -189,6 +189,7 @@ along with GCC; see the file COPYING3. If not see
#include "dbgcnt.h"
#include "target.h"
#include "gcse.h"
+#include "gcse-common.h"
/* We support GCSE via Partial Redundancy Elimination. PRE optimizations
are a superset of those done by classic GCSE.
@@ -424,13 +425,6 @@ static regset reg_set_bitmap;
static vec<rtx_insn *> *modify_mem_list;
static bitmap modify_mem_list_set;
-typedef struct modify_pair_s
-{
- rtx dest; /* A MEM. */
- rtx dest_addr; /* The canonical address of `dest'. */
-} modify_pair;
-
-
/* This array parallels modify_mem_list, except that it stores MEMs
being set and their canonicalized memory addresses. */
static vec<modify_pair> *canon_modify_mem_list;
@@ -507,12 +501,10 @@ static void alloc_hash_table (struct gcse_hash_table_d *);
static void free_hash_table (struct gcse_hash_table_d *);
static void compute_hash_table_work (struct gcse_hash_table_d *);
static void dump_hash_table (FILE *, const char *, struct gcse_hash_table_d *);
-static void compute_transp (const_rtx, int, sbitmap *);
static void compute_local_properties (sbitmap *, sbitmap *, sbitmap *,
struct gcse_hash_table_d *);
static void mems_conflict_for_gcse_p (rtx, const_rtx, void *);
static int load_killed_in_block_p (const_basic_block, int, const_rtx, int);
-static void canon_list_insert (rtx, const_rtx, void *);
static void alloc_pre_mem (int, int);
static void free_pre_mem (void);
static struct edge_list *compute_pre_data (void);
@@ -733,7 +725,10 @@ compute_local_properties (sbitmap *transp, sbitmap *comp, sbitmap *antloc,
We start by assuming all are transparent [none are killed], and
then reset the bits for those that are. */
if (transp)
- compute_transp (expr->expr, indx, transp);
+ compute_transp (expr->expr, indx, transp,
+ blocks_with_calls,
+ modify_mem_list_set,
+ canon_modify_mem_list);
/* The occurrences recorded in antic_occr are exactly those that
we want to set to nonzero in ANTLOC. */
@@ -1489,40 +1484,6 @@ record_last_reg_set_info (rtx insn, int regno)
}
}
-/* Record all of the canonicalized MEMs of record_last_mem_set_info's insn.
- Note we store a pair of elements in the list, so they have to be
- taken off pairwise. */
-
-static void
-canon_list_insert (rtx dest ATTRIBUTE_UNUSED, const_rtx x ATTRIBUTE_UNUSED,
- void * v_insn)
-{
- rtx dest_addr, insn;
- int bb;
- modify_pair pair;
-
- while (GET_CODE (dest) == SUBREG
- || GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == STRICT_LOW_PART)
- dest = XEXP (dest, 0);
-
- /* If DEST is not a MEM, then it will not conflict with a load. Note
- that function calls are assumed to clobber memory, but are handled
- elsewhere. */
-
- if (! MEM_P (dest))
- return;
-
- dest_addr = get_addr (XEXP (dest, 0));
- dest_addr = canon_rtx (dest_addr);
- insn = (rtx) v_insn;
- bb = BLOCK_FOR_INSN (insn)->index;
-
- pair.dest = dest;
- pair.dest_addr = dest_addr;
- canon_modify_mem_list[bb].safe_push (pair);
-}
-
/* Record memory modification information for INSN. We do not actually care
about the memory location(s) that are set, or even how they are set (consider
a CALL_INSN). We merely need to record which insns modify memory. */
@@ -1530,21 +1491,13 @@ canon_list_insert (rtx dest ATTRIBUTE_UNUSED, const_rtx x ATTRIBUTE_UNUSED,
static void
record_last_mem_set_info (rtx_insn *insn)
{
- int bb;
-
if (! flag_gcse_lm)
return;
- /* load_killed_in_block_p will handle the case of calls clobbering
- everything. */
- bb = BLOCK_FOR_INSN (insn)->index;
- modify_mem_list[bb].safe_push (insn);
- bitmap_set_bit (modify_mem_list_set, bb);
-
- if (CALL_P (insn))
- bitmap_set_bit (blocks_with_calls, bb);
- else
- note_stores (PATTERN (insn), canon_list_insert, (void*) insn);
+ record_last_mem_set_info_common (insn, modify_mem_list,
+ canon_modify_mem_list,
+ modify_mem_list_set,
+ blocks_with_calls);
}
/* Called from compute_hash_table via note_stores to handle one
@@ -1699,120 +1652,6 @@ free_modify_mem_tables (void)
canon_modify_mem_list = 0;
}
-/* For each block, compute whether X is transparent. X is either an
- expression or an assignment [though we don't care which, for this context
- an assignment is treated as an expression]. For each block where an
- element of X is modified, reset the INDX bit in BMAP. */
-
-static void
-compute_transp (const_rtx x, int indx, sbitmap *bmap)
-{
- int i, j;
- enum rtx_code code;
- const char *fmt;
-
- /* repeat is used to turn tail-recursion into iteration since GCC
- can't do it when there's no return value. */
- repeat:
-
- if (x == 0)
- return;
-
- code = GET_CODE (x);
- switch (code)
- {
- case REG:
- {
- df_ref def;
- for (def = DF_REG_DEF_CHAIN (REGNO (x));
- def;
- def = DF_REF_NEXT_REG (def))
- bitmap_clear_bit (bmap[DF_REF_BB (def)->index], indx);
- }
-
- return;
-
- case MEM:
- if (! MEM_READONLY_P (x))
- {
- bitmap_iterator bi;
- unsigned bb_index;
- rtx x_addr;
-
- x_addr = get_addr (XEXP (x, 0));
- x_addr = canon_rtx (x_addr);
-
- /* First handle all the blocks with calls. We don't need to
- do any list walking for them. */
- EXECUTE_IF_SET_IN_BITMAP (blocks_with_calls, 0, bb_index, bi)
- {
- bitmap_clear_bit (bmap[bb_index], indx);
- }
-
- /* Now iterate over the blocks which have memory modifications
- but which do not have any calls. */
- EXECUTE_IF_AND_COMPL_IN_BITMAP (modify_mem_list_set,
- blocks_with_calls,
- 0, bb_index, bi)
- {
- vec<modify_pair> list
- = canon_modify_mem_list[bb_index];
- modify_pair *pair;
- unsigned ix;
-
- FOR_EACH_VEC_ELT_REVERSE (list, ix, pair)
- {
- rtx dest = pair->dest;
- rtx dest_addr = pair->dest_addr;
-
- if (canon_true_dependence (dest, GET_MODE (dest),
- dest_addr, x, x_addr))
- {
- bitmap_clear_bit (bmap[bb_index], indx);
- break;
- }
- }
- }
- }
-
- x = XEXP (x, 0);
- goto repeat;
-
- case PC:
- case CC0: /*FIXME*/
- case CONST:
- CASE_CONST_ANY:
- case SYMBOL_REF:
- case LABEL_REF:
- case ADDR_VEC:
- case ADDR_DIFF_VEC:
- return;
-
- default:
- break;
- }
-
- for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
- {
- if (fmt[i] == 'e')
- {
- /* If we are about to do the last recursive call
- needed at this level, change it into iteration.
- This function is called enough to be worth it. */
- if (i == 0)
- {
- x = XEXP (x, i);
- goto repeat;
- }
-
- compute_transp (XEXP (x, i), indx, bmap);
- }
- else if (fmt[i] == 'E')
- for (j = 0; j < XVECLEN (x, i); j++)
- compute_transp (XVECEXP (x, i, j), indx, bmap);
- }
-}
-
/* Compute PRE+LCM working variables. */
/* Local properties of expressions. */