Add cselib; use it in loop and reload_cse_regs
From-SVN: r32538
This commit is contained in:
parent
4bdf01f210
commit
eab5c70a03
@ -1,3 +1,67 @@
|
||||
2000-03-14 Bernd Schmidt <bernds@cygnus.co.uk>
|
||||
|
||||
* cselib.h: New file.
|
||||
* alias.c: Include "cselib.h".
|
||||
(fixed_scalar_and_varying_struct_p): Accept the addresses of the
|
||||
MEMs as two new arguments.
|
||||
(get_addr): New static function.
|
||||
(find_base_term): Handle VALUEs.
|
||||
(memrefs_conflict_p): Likewise.
|
||||
(true_dependence): Call get_addr on the addresses.
|
||||
Call fixed_scalar_and_varying_struct_p with addresses that have been
|
||||
passed through get_addr and canon_rtx.
|
||||
(write_dependence_p): Move DIFFERENT_ALIAS_SETS_P test for consistency
|
||||
with true_dependence.
|
||||
Call get_addr on the addresses; don't call canon_rtx on the MEMs.
|
||||
* loop.c: Include "cselib.h".
|
||||
(load_mems): Process extended basic block that enters the loop with
|
||||
cselib. Use that information to change initialization of the shadow
|
||||
register so that a constant equivalence is seen by later passes.
|
||||
* reload1.c: Include "cselib.h".
|
||||
(reload_cse_invalidate_regno): Delete function.
|
||||
(reload_cse_mem_conflict_p): Likewise.
|
||||
(reload_cse_invalidate_mem): Likewise.
|
||||
(reload_cse_invalidate_rtx): Likewise.
|
||||
(reload_cse_regno_equal_p): Likewise.
|
||||
(reload_cse_check_clobber): Likewise.
|
||||
(reload_cse_record_set): Likewise.
|
||||
(reg_values): Delete static variable.
|
||||
(invalidate_regno_rtx): Likewise.
|
||||
(reload_cse_delete_noop_set): New static function.
|
||||
(reload_cse_simplify): New static function, broken out of
|
||||
reload_cse_regs_1.
|
||||
(reload_cse_noop_set_p): Delete unused argument INSN.
|
||||
Just call rtx_equal_for_cselib_p on set source and destination.
|
||||
(reload_cse_regs_1): Break out some code into reload_cse_simplify and
|
||||
reload_cse_delete_noop_set. Delete code to keep track of values; use
|
||||
cselib functions instead. Delete code to push/pop obstacks.
|
||||
(reload_cse_simplify_set): Use cselib to find equivalent values.
|
||||
Delete code to push/pop obstacks.
|
||||
(reload_cse_simplify_operands): Likewise.
|
||||
* rtl.def (VALUE): New rtx code.
|
||||
* rtl.h (union rtunion_def): New elt rt_cselib.
|
||||
(X0CSELIB, CSELIB_VAL_PTR): New macros.
|
||||
* simplify_rtx.c: Include "ggc.h", "obstack.h", "cselib.h".
|
||||
(new_elt_list, new_elt_loc_list, unchain_one_value, clear_table,
|
||||
unchain_one_elt_list, unchain_one_elt_loc_list, check_useless_values,
|
||||
discard_useless_locs, discard_useless_values, entry_and_rtx_equal_p,
|
||||
hash_rtx, new_cselib_val, add_mem_for_addr, get_value_hash,
|
||||
cselib_lookup_mem, cselib_subst_to_values, cselib_invalidate_regno,
|
||||
cselib_mem_conflict_p, cselib_invalidate_mem, cselib_invalidate_rtx,
|
||||
cselib_record_set, cselib_record_sets): New static functions.
|
||||
(cselib_lookup, cselib_update_varray_sizes, cselib_init,
|
||||
cselib_finish, cselib_process_insn, rtx_equal_for_cselib_p,
|
||||
references_value_p): New functions.
|
||||
(MAX_USELESS_VALUES, REG_VALUES): New macros.
|
||||
(table, cselib_current_insn, next_unknown_value, cselib_nregs,
|
||||
n_useless_values, reg_values, callmem, cselib_obstack,
|
||||
cselib_startobj, empty_vals, empty_elt_lists, empty_elt_loc_lists):
|
||||
New static variables.
|
||||
* varray.h (union varray_data_tag): New elt te.
|
||||
(VARRAY_ELT_LIST_INIT, VARRAY_ELT_LIST): New macros.
|
||||
* Makefile.in (reload1.o, loop.o, simplify-rtx.o, alias.o): Update
|
||||
dependencies.
|
||||
|
||||
2000-03-14 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* gcc.c (do_spec_1): Catch the case where %* is used in a
|
||||
|
@ -1556,7 +1556,7 @@ jump.o : jump.c $(CONFIG_H) system.h $(RTL_H) flags.h hard-reg-set.h $(REGS_H) \
|
||||
|
||||
simplify-rtx.o : simplify-rtx.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) \
|
||||
hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
|
||||
output.h function.h
|
||||
output.h function.h cselib.h ggc.h $(srcdir)/../include/obstack.h
|
||||
cse.o : cse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
|
||||
real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h function.h ggc.h
|
||||
gcse.o : gcse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h \
|
||||
@ -1574,7 +1574,7 @@ profile.o : profile.c $(CONFIG_H) system.h $(RTL_H) flags.h insn-flags.h \
|
||||
ggc.h
|
||||
loop.o : loop.c $(CONFIG_H) system.h $(RTL_H) flags.h $(LOOP_H) insn-config.h \
|
||||
insn-flags.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) real.h \
|
||||
$(BASIC_BLOCK_H) function.h toplev.h varray.h except.h
|
||||
$(BASIC_BLOCK_H) function.h toplev.h varray.h except.h cselib.h
|
||||
unroll.o : unroll.c $(CONFIG_H) system.h $(RTL_H) insn-config.h function.h \
|
||||
$(INTEGRATE_H) $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) $(LOOP_H) toplev.h \
|
||||
varray.h
|
||||
@ -1600,7 +1600,7 @@ reload.o : reload.c $(CONFIG_H) system.h $(RTL_H) flags.h output.h $(EXPR_H) \
|
||||
function.h real.h toplev.h
|
||||
reload1.o : reload1.c $(CONFIG_H) system.h $(RTL_H) real.h flags.h $(EXPR_H) \
|
||||
reload.h $(REGS_H) hard-reg-set.h insn-config.h insn-flags.h insn-codes.h \
|
||||
$(BASIC_BLOCK_H) $(RECOG_H) output.h function.h toplev.h
|
||||
$(BASIC_BLOCK_H) $(RECOG_H) output.h function.h toplev.h cselib.h
|
||||
caller-save.o : caller-save.c $(CONFIG_H) system.h $(RTL_H) flags.h \
|
||||
$(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) function.h \
|
||||
$(RECOG_H) reload.h $(EXPR_H) toplev.h
|
||||
@ -1608,7 +1608,8 @@ reorg.o : reorg.c $(CONFIG_H) system.h $(RTL_H) conditions.h hard-reg-set.h \
|
||||
$(BASIC_BLOCK_H) $(REGS_H) insn-config.h insn-attr.h insn-flags.h \
|
||||
$(RECOG_H) function.h flags.h output.h $(EXPR_H) toplev.h
|
||||
alias.o : alias.c $(CONFIG_H) system.h $(RTL_H) flags.h hard-reg-set.h \
|
||||
$(REGS_H) toplev.h output.h $(EXPR_H) insn-flags.h ggc.h function.h
|
||||
$(REGS_H) toplev.h output.h $(EXPR_H) insn-flags.h ggc.h function.h \
|
||||
cselib.h
|
||||
regmove.o : regmove.c $(CONFIG_H) system.h $(RTL_H) insn-config.h \
|
||||
$(RECOG_H) output.h reload.h $(REGS_H) hard-reg-set.h flags.h function.h \
|
||||
$(EXPR_H) insn-flags.h $(BASIC_BLOCK_H) toplev.h
|
||||
|
97
gcc/alias.c
97
gcc/alias.c
@ -32,6 +32,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "flags.h"
|
||||
#include "output.h"
|
||||
#include "toplev.h"
|
||||
#include "cselib.h"
|
||||
#include "splay-tree.h"
|
||||
#include "ggc.h"
|
||||
|
||||
@ -81,6 +82,7 @@ typedef struct alias_set_entry
|
||||
static rtx canon_rtx PARAMS ((rtx));
|
||||
static int rtx_equal_for_memref_p PARAMS ((rtx, rtx));
|
||||
static rtx find_symbolic_term PARAMS ((rtx));
|
||||
static rtx get_addr PARAMS ((rtx));
|
||||
static int memrefs_conflict_p PARAMS ((int, rtx, int, rtx,
|
||||
HOST_WIDE_INT));
|
||||
static void record_set PARAMS ((rtx, rtx, void *));
|
||||
@ -91,7 +93,8 @@ static rtx find_base_value PARAMS ((rtx));
|
||||
static int mems_in_disjoint_alias_sets_p PARAMS ((rtx, rtx));
|
||||
static int insert_subset_children PARAMS ((splay_tree_node, void*));
|
||||
static alias_set_entry get_alias_set_entry PARAMS ((int));
|
||||
static rtx fixed_scalar_and_varying_struct_p PARAMS ((rtx, rtx, int (*)(rtx)));
|
||||
static rtx fixed_scalar_and_varying_struct_p PARAMS ((rtx, rtx, rtx, rtx,
|
||||
int (*)(rtx)));
|
||||
static int aliases_everything_p PARAMS ((rtx));
|
||||
static int write_dependence_p PARAMS ((rtx, rtx, int));
|
||||
static int nonlocal_reference_p PARAMS ((rtx));
|
||||
@ -737,6 +740,9 @@ static rtx
|
||||
find_base_term (x)
|
||||
register rtx x;
|
||||
{
|
||||
cselib_val *val;
|
||||
struct elt_loc_list *l;
|
||||
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case REG:
|
||||
@ -751,6 +757,13 @@ find_base_term (x)
|
||||
case POST_DEC:
|
||||
return find_base_term (XEXP (x, 0));
|
||||
|
||||
case VALUE:
|
||||
val = CSELIB_VAL_PTR (x);
|
||||
for (l = val->locs; l; l = l->next)
|
||||
if ((x = find_base_term (l->loc)) != 0)
|
||||
return x;
|
||||
return 0;
|
||||
|
||||
case CONST:
|
||||
x = XEXP (x, 0);
|
||||
if (GET_CODE (x) != PLUS && GET_CODE (x) != MINUS)
|
||||
@ -905,6 +918,30 @@ base_alias_check (x, y, x_mode, y_mode)
|
||||
return ! (GET_MODE (x_base) == VOIDmode && GET_MODE (y_base) == VOIDmode);
|
||||
}
|
||||
|
||||
/* Convert the address X into something we can use. This is done by returning
|
||||
it unchanged unless it is a value; in the latter case we call cselib to get
|
||||
a more useful rtx. */
|
||||
static rtx
|
||||
get_addr (x)
|
||||
rtx x;
|
||||
{
|
||||
cselib_val *v;
|
||||
struct elt_loc_list *l;
|
||||
|
||||
if (GET_CODE (x) != VALUE)
|
||||
return x;
|
||||
v = CSELIB_VAL_PTR (x);
|
||||
for (l = v->locs; l; l = l->next)
|
||||
if (CONSTANT_P (l->loc))
|
||||
return l->loc;
|
||||
for (l = v->locs; l; l = l->next)
|
||||
if (GET_CODE (l->loc) != REG && GET_CODE (l->loc) != MEM)
|
||||
return l->loc;
|
||||
if (v->locs)
|
||||
return v->locs->loc;
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Return the address of the (N_REFS + 1)th memory reference to ADDR
|
||||
where SIZE is the size in bytes of the memory reference. If ADDR
|
||||
is not modified by the memory reference then ADDR is returned. */
|
||||
@ -961,13 +998,16 @@ addr_side_effect_eval (addr, size, n_refs)
|
||||
Nice to notice that varying addresses cannot conflict with fp if no
|
||||
local variables had their addresses taken, but that's too hard now. */
|
||||
|
||||
|
||||
static int
|
||||
memrefs_conflict_p (xsize, x, ysize, y, c)
|
||||
register rtx x, y;
|
||||
int xsize, ysize;
|
||||
HOST_WIDE_INT c;
|
||||
{
|
||||
if (GET_CODE (x) == VALUE)
|
||||
x = get_addr (x);
|
||||
if (GET_CODE (y) == VALUE)
|
||||
y = get_addr (y);
|
||||
if (GET_CODE (x) == HIGH)
|
||||
x = XEXP (x, 0);
|
||||
else if (GET_CODE (x) == LO_SUM)
|
||||
@ -1185,17 +1225,15 @@ read_dependence (mem, x)
|
||||
MEM2 if vice versa. Otherwise, returns NULL_RTX. If a non-NULL
|
||||
value is returned MEM1 and MEM2 can never alias. VARIES_P is used
|
||||
to decide whether or not an address may vary; it should return
|
||||
nonzero whenever variation is possible. */
|
||||
|
||||
static rtx
|
||||
fixed_scalar_and_varying_struct_p (mem1, mem2, varies_p)
|
||||
rtx mem1;
|
||||
rtx mem2;
|
||||
int (*varies_p) PARAMS ((rtx));
|
||||
{
|
||||
rtx mem1_addr = XEXP (mem1, 0);
|
||||
rtx mem2_addr = XEXP (mem2, 0);
|
||||
nonzero whenever variation is possible.
|
||||
MEM1_ADDR and MEM2_ADDR are the addresses of MEM1 and MEM2. */
|
||||
|
||||
static rtx
|
||||
fixed_scalar_and_varying_struct_p (mem1, mem2, mem1_addr, mem2_addr, varies_p)
|
||||
rtx mem1, mem2;
|
||||
rtx mem1_addr, mem2_addr;
|
||||
int (*varies_p) PARAMS ((rtx));
|
||||
{
|
||||
if (MEM_SCALAR_P (mem1) && MEM_IN_STRUCT_P (mem2)
|
||||
&& !varies_p (mem1_addr) && varies_p (mem2_addr))
|
||||
/* MEM1 is a scalar at a fixed address; MEM2 is a struct at a
|
||||
@ -1260,11 +1298,14 @@ true_dependence (mem, mem_mode, x, varies)
|
||||
if (mem_mode == VOIDmode)
|
||||
mem_mode = GET_MODE (mem);
|
||||
|
||||
if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0), GET_MODE (x), mem_mode))
|
||||
x_addr = get_addr (XEXP (x, 0));
|
||||
mem_addr = get_addr (XEXP (mem, 0));
|
||||
|
||||
if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode))
|
||||
return 0;
|
||||
|
||||
x_addr = canon_rtx (XEXP (x, 0));
|
||||
mem_addr = canon_rtx (XEXP (mem, 0));
|
||||
x_addr = canon_rtx (x_addr);
|
||||
mem_addr = canon_rtx (mem_addr);
|
||||
|
||||
if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
|
||||
SIZE_FOR_MODE (x), x_addr, 0))
|
||||
@ -1283,7 +1324,8 @@ true_dependence (mem, mem_mode, x, varies)
|
||||
if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
|
||||
return 1;
|
||||
|
||||
return !fixed_scalar_and_varying_struct_p (mem, x, varies);
|
||||
return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
|
||||
varies);
|
||||
}
|
||||
|
||||
/* Returns non-zero if a write to X might alias a previous read from
|
||||
@ -1301,32 +1343,33 @@ write_dependence_p (mem, x, writep)
|
||||
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
|
||||
return 1;
|
||||
|
||||
if (DIFFERENT_ALIAS_SETS_P (x, mem))
|
||||
return 0;
|
||||
|
||||
/* If MEM is an unchanging read, then it can't possibly conflict with
|
||||
the store to X, because there is at most one store to MEM, and it must
|
||||
have occurred somewhere before MEM. */
|
||||
if (!writep && RTX_UNCHANGING_P (mem))
|
||||
return 0;
|
||||
|
||||
if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0), GET_MODE (x),
|
||||
x_addr = get_addr (XEXP (x, 0));
|
||||
mem_addr = get_addr (XEXP (mem, 0));
|
||||
|
||||
if (! base_alias_check (x_addr, mem_addr, GET_MODE (x),
|
||||
GET_MODE (mem)))
|
||||
return 0;
|
||||
|
||||
x = canon_rtx (x);
|
||||
mem = canon_rtx (mem);
|
||||
|
||||
if (DIFFERENT_ALIAS_SETS_P (x, mem))
|
||||
return 0;
|
||||
|
||||
x_addr = XEXP (x, 0);
|
||||
mem_addr = XEXP (mem, 0);
|
||||
x_addr = canon_rtx (x_addr);
|
||||
mem_addr = canon_rtx (mem_addr);
|
||||
|
||||
if (!memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
|
||||
SIZE_FOR_MODE (x), x_addr, 0))
|
||||
return 0;
|
||||
|
||||
fixed_scalar
|
||||
= fixed_scalar_and_varying_struct_p (mem, x, rtx_addr_varies_p);
|
||||
|
||||
= fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
|
||||
rtx_addr_varies_p);
|
||||
|
||||
return (!(fixed_scalar == mem && !aliases_everything_p (x))
|
||||
&& !(fixed_scalar == x && !aliases_everything_p (mem)));
|
||||
}
|
||||
|
66
gcc/cselib.h
Normal file
66
gcc/cselib.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* Common subexpression elimination for GNU compiler.
|
||||
Copyright (C) 1987, 88, 89, 92-7, 1998, 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
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. */
|
||||
|
||||
/* Describe a value. */
|
||||
typedef struct cselib_val_struct
|
||||
{
|
||||
/* The hash value. */
|
||||
unsigned int value;
|
||||
union
|
||||
{
|
||||
/* A VALUE rtx that points back to this structure. */
|
||||
rtx val_rtx;
|
||||
/* Used to keep a list of free cselib_val structures. */
|
||||
struct cselib_val_struct *next_free;
|
||||
} u;
|
||||
|
||||
/* All rtl expressions that hold this value at the current time during a
|
||||
scan. */
|
||||
struct elt_loc_list *locs;
|
||||
/* If this value is used as an address, points to a list of values that
|
||||
use it as an address in a MEM. */
|
||||
struct elt_list *addr_list;
|
||||
} cselib_val;
|
||||
|
||||
/* A list of rtl expressions that hold the same value. */
|
||||
struct elt_loc_list
|
||||
{
|
||||
/* Next element in the list. */
|
||||
struct elt_loc_list *next;
|
||||
/* An rtl expression that holds the value. */
|
||||
rtx loc;
|
||||
/* The insn that made the equivalence. */
|
||||
rtx setting_insn;
|
||||
};
|
||||
|
||||
/* A list of cselib_val structures. */
|
||||
struct elt_list
|
||||
{
|
||||
struct elt_list *next;
|
||||
cselib_val *elt;
|
||||
};
|
||||
|
||||
extern cselib_val *cselib_lookup PARAMS ((rtx, enum machine_mode, int));
|
||||
extern void cselib_update_varray_sizes PARAMS ((void));
|
||||
extern void cselib_init PARAMS ((void));
|
||||
extern void cselib_finish PARAMS ((void));
|
||||
extern void cselib_process_insn PARAMS ((rtx));
|
||||
extern int rtx_equal_for_cselib_p PARAMS ((rtx, rtx));
|
||||
extern int references_value_p PARAMS ((rtx, int));
|
62
gcc/loop.c
62
gcc/loop.c
@ -51,6 +51,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "flags.h"
|
||||
#include "real.h"
|
||||
#include "loop.h"
|
||||
#include "cselib.h"
|
||||
#include "except.h"
|
||||
#include "toplev.h"
|
||||
|
||||
@ -9773,6 +9774,19 @@ load_mems (loop)
|
||||
if (loop_mems_idx == 0)
|
||||
return;
|
||||
|
||||
/* Find start of the extended basic block that enters the loop. */
|
||||
for (p = loop->start;
|
||||
PREV_INSN (p) && GET_CODE (p) != CODE_LABEL;
|
||||
p = PREV_INSN (p))
|
||||
;
|
||||
|
||||
cselib_init ();
|
||||
|
||||
/* Build table of mems that get set to constant values before the
|
||||
loop. */
|
||||
for (; p != loop->start; p = NEXT_INSN (p))
|
||||
cselib_process_insn (p);
|
||||
|
||||
/* Check to see if it's possible that some instructions in the
|
||||
loop are never executed. */
|
||||
for (p = next_insn_in_loop (loop, loop->scan_start);
|
||||
@ -9924,13 +9938,49 @@ load_mems (loop)
|
||||
loop_mems[i].optimize = 0;
|
||||
else
|
||||
{
|
||||
int j;
|
||||
rtx set;
|
||||
|
||||
/* Load the memory immediately before LOOP->START, which is
|
||||
the NOTE_LOOP_BEG. */
|
||||
set = gen_move_insn (reg, mem);
|
||||
emit_insn_before (set, loop->start);
|
||||
cselib_val *e = cselib_lookup (mem, VOIDmode, 0);
|
||||
rtx set;
|
||||
rtx best = mem;
|
||||
int j;
|
||||
struct elt_loc_list *const_equiv = 0;
|
||||
|
||||
if (e)
|
||||
{
|
||||
struct elt_loc_list *equiv;
|
||||
struct elt_loc_list *best_equiv = 0;
|
||||
for (equiv = e->locs; equiv; equiv = equiv->next)
|
||||
{
|
||||
if (CONSTANT_P (equiv->loc))
|
||||
const_equiv = equiv;
|
||||
else if (GET_CODE (equiv->loc) == REG)
|
||||
best_equiv = equiv;
|
||||
}
|
||||
/* Use the constant equivalence if that is cheap enough. */
|
||||
if (! best_equiv)
|
||||
best_equiv = const_equiv;
|
||||
else if (const_equiv
|
||||
&& (rtx_cost (const_equiv->loc, SET)
|
||||
<= rtx_cost (best_equiv->loc, SET)))
|
||||
{
|
||||
best_equiv = const_equiv;
|
||||
const_equiv = 0;
|
||||
}
|
||||
|
||||
/* If best_equiv is nonzero, we know that MEM is set to a
|
||||
constant or register before the loop. We will use this
|
||||
knowledge to initialize the shadow register with that
|
||||
constant or reg rather than by loading from MEM. */
|
||||
if (best_equiv)
|
||||
best = copy_rtx (best_equiv->loc);
|
||||
}
|
||||
set = gen_move_insn (reg, best);
|
||||
set = emit_insn_before (set, loop->start);
|
||||
if (const_equiv)
|
||||
REG_NOTES (set) = gen_rtx_EXPR_LIST (REG_EQUAL,
|
||||
copy_rtx (const_equiv->loc),
|
||||
REG_NOTES (set));
|
||||
|
||||
if (written)
|
||||
{
|
||||
@ -9992,6 +10042,8 @@ load_mems (loop)
|
||||
JUMP_LABEL (p) = label;
|
||||
}
|
||||
}
|
||||
|
||||
cselib_finish ();
|
||||
}
|
||||
|
||||
/* For communication between note_reg_stored and its caller. */
|
||||
|
892
gcc/reload1.c
892
gcc/reload1.c
File diff suppressed because it is too large
Load Diff
@ -530,6 +530,9 @@ DEF_RTL_EXPR(CONST, "const", "e", 'o')
|
||||
by a SET whose first operand is (PC). */
|
||||
DEF_RTL_EXPR(PC, "pc", "", 'o')
|
||||
|
||||
/* Used in the cselib routines to describe a value. */
|
||||
DEF_RTL_EXPR(VALUE, "value", "0", 'o')
|
||||
|
||||
/* A register. The "operand" is the register number, accessed with
|
||||
the REGNO macro. If this number is less than FIRST_PSEUDO_REGISTER
|
||||
than a hardware register is being referred to. The second operand
|
||||
|
@ -92,6 +92,7 @@ typedef union rtunion_def
|
||||
struct rtvec_def *rtvec;
|
||||
enum machine_mode rttype;
|
||||
addr_diff_vec_flags rt_addr_diff_vec_flags;
|
||||
struct cselib_val_struct *rt_cselib;
|
||||
struct bitmap_head_def *rtbit;
|
||||
union tree_node *rttree;
|
||||
struct basic_block_def *bb;
|
||||
@ -330,6 +331,7 @@ extern void rtvec_check_failed_bounds PARAMS ((rtvec, int,
|
||||
#define X0TREE(RTX, N) (RTL_CHECK1(RTX, N, '0').rttree)
|
||||
#define X0BBDEF(RTX, N) (RTL_CHECK1(RTX, N, '0').bb)
|
||||
#define X0ADVFLAGS(RTX, N) (RTL_CHECK1(RTX, N, '0').rt_addr_diff_vec_flags)
|
||||
#define X0CSELIB(RTX, N) (RTL_CHECK1(RTX, N, '0').rt_cselib)
|
||||
|
||||
#define XCWINT(RTX, N, C) (RTL_CHECKC1(RTX, N, C).rtwint)
|
||||
#define XCINT(RTX, N, C) (RTL_CHECKC1(RTX, N, C).rtint)
|
||||
@ -341,6 +343,7 @@ extern void rtvec_check_failed_bounds PARAMS ((rtvec, int,
|
||||
#define XCTREE(RTX, N, C) (RTL_CHECKC1(RTX, N, C).rttree)
|
||||
#define XCBBDEF(RTX, N, C) (RTL_CHECKC1(RTX, N, C).bb)
|
||||
#define XCADVFLAGS(RTX, N, C) (RTL_CHECKC1(RTX, N, C).rt_addr_diff_vec_flags)
|
||||
#define XCCSELIB(RTX, N, C) (RTL_CHECKC1(RTX, N, C).rt_cselib)
|
||||
|
||||
#define XCVECEXP(RTX, N, M, C) RTVEC_ELT (XCVEC (RTX, N, C), M)
|
||||
#define XCVECLEN(RTX, N, C) GET_NUM_ELEM (XCVEC (RTX, N, C))
|
||||
@ -470,6 +473,8 @@ extern void rtvec_check_failed_bounds PARAMS ((rtvec, int,
|
||||
|
||||
#define ADDR_DIFF_VEC_FLAGS(RTX) X0ADVFLAGS(RTX, 4)
|
||||
|
||||
#define CSELIB_VAL_PTR(RTX) X0CSELIB(RTX, 0)
|
||||
|
||||
/* Don't forget to change reg_note_name in rtl.c. */
|
||||
enum reg_note { REG_DEAD = 1, REG_INC = 2, REG_EQUIV = 3, REG_WAS_0 = 4,
|
||||
REG_EQUAL = 5, REG_RETVAL = 6, REG_LIBCALL = 7,
|
||||
|
1230
gcc/simplify-rtx.c
1230
gcc/simplify-rtx.c
File diff suppressed because it is too large
Load Diff
@ -76,6 +76,7 @@ typedef union varray_data_tag {
|
||||
struct reg_info_def *reg[1];
|
||||
struct const_equiv_data const_equiv[1];
|
||||
struct basic_block_def *bb[1];
|
||||
struct elt_list *te[1];
|
||||
} varray_data;
|
||||
|
||||
/* Virtual array of pointers header. */
|
||||
@ -152,6 +153,9 @@ extern varray_type varray_init PARAMS ((size_t, size_t, const char *));
|
||||
#define VARRAY_BB_INIT(va, num, name) \
|
||||
va = varray_init (num, sizeof (struct basic_block_def *), name)
|
||||
|
||||
#define VARRAY_ELT_LIST_INIT(va, num, name) \
|
||||
va = varray_init (num, sizeof (struct elt_list *), name)
|
||||
|
||||
/* Free up memory allocated by the virtual array, but do not free any of the
|
||||
elements involved. */
|
||||
#define VARRAY_FREE(vp) \
|
||||
@ -219,6 +223,7 @@ extern void varray_check_failed PARAMS ((varray_type, size_t,
|
||||
#define VARRAY_REG(VA, N) VARRAY_CHECK (VA, N, reg)
|
||||
#define VARRAY_CONST_EQUIV(VA, N) VARRAY_CHECK (VA, N, const_equiv)
|
||||
#define VARRAY_BB(VA, N) VARRAY_CHECK (VA, N, bb)
|
||||
#define VARRAY_ELT_LIST(VA, N) VARRAY_CHECK (VA, N, te)
|
||||
|
||||
/* Push a new element on the end of VA, extending it if necessary. */
|
||||
#define VARRAY_PUSH_CHAR(VA, X) VARRAY_PUSH (VA, c, X)
|
||||
|
Loading…
Reference in New Issue
Block a user