Minor cleanups
Richard Kenner
kenner@vlsi1.ultra.nyu.edu
Tue Apr 18 11:18:00 GMT 2000
I committed the following:
Tue Apr 18 14:16:47 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* c-decl.c (mark_binding_level): Use 'for' instead of `while'.
* conflict.c: Minor cleanups.
* optabs.c: Add blank line
* simplify-rtx.c:
*** c-decl.c 2000/03/27 01:26:16 1.105
--- c-decl.c 2000/04/18 17:42:25
*************** lookup_name_current_level (name)
*** 2861,2864 ****
--- 2861,2865 ----
/* Mark ARG for GC. */
+
static void
mark_binding_level (arg)
*************** mark_binding_level (arg)
*** 2867,2871 ****
struct binding_level *level = *(struct binding_level **) arg;
! while (level)
{
ggc_mark_tree (level->names);
--- 2868,2872 ----
struct binding_level *level = *(struct binding_level **) arg;
! for (; level != 0; level = level->level_chain)
{
ggc_mark_tree (level->names);
*************** mark_binding_level (arg)
*** 2875,2879 ****
ggc_mark_tree (level->this_block);
ggc_mark_tree (level->parm_order);
- level = level->level_chain;
}
}
--- 2876,2879 ----
*** conflict.c 2000/04/07 08:16:31 1.2
--- conflict.c 2000/04/18 17:44:33
***************
*** 3,22 ****
Contributed by CodeSourcery, LLC
! 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. */
/* References:
--- 3,22 ----
Contributed by CodeSourcery, LLC
! 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. */
/* References:
***************
*** 28,32 ****
#include "config.h"
#include "system.h"
-
#include "obstack.h"
#include "hashtab.h"
--- 28,31 ----
*************** struct conflict_graph_def
*** 109,129 ****
/* The initial capacity (number of conflict arcs) for newly-created
conflict graphs. */
! #define INITIAL_ARC_CAPACITY (64)
/* Computes the hash value of the conflict graph arc connecting regs
! R1__ and R2__. R1__ is assumed to be smaller or equal to R2__. */
! #define CONFLICT_HASH_FN(r1__, r2__) ((r2__) * ((r2__) - 1) / 2 + (r1__))
!
! static unsigned arc_hash
! PARAMS ((const void *arcp));
! static int arc_eq
! PARAMS ((const void *arcp1, const void *arcp2));
! static int print_conflict
! PARAMS ((int reg1, int reg2, void *contextp));
! static void mark_reg
! PARAMS ((rtx reg, rtx setter, void *data));
!
/* Callback function to compute the hash value of an arc. Uses
current_graph to locate the graph to which the arc belongs. */
--- 108,123 ----
/* The initial capacity (number of conflict arcs) for newly-created
conflict graphs. */
! #define INITIAL_ARC_CAPACITY 64
/* Computes the hash value of the conflict graph arc connecting regs
! R1 and R2. R1 is assumed to be smaller or equal to R2. */
! #define CONFLICT_HASH_FN(R1, R2) ((R2) * ((R2) - 1) / 2 + (R1))
! static unsigned arc_hash PARAMS ((const void *));
! static int arc_eq PARAMS ((const void *, const void *));
! static int print_conflict PARAMS ((int, int, void *));
! static void mark_reg PARAMS ((rtx, rtx, void *));
!
/* Callback function to compute the hash value of an arc. Uses
current_graph to locate the graph to which the arc belongs. */
*************** arc_hash (arcp)
*** 134,137 ****
--- 128,132 ----
{
conflict_graph_arc arc = (conflict_graph_arc) arcp;
+
return CONFLICT_HASH_FN (arc->smaller, arc->larger);
}
*************** arc_eq (arcp1, arcp2)
*** 147,150 ****
--- 142,146 ----
conflict_graph_arc arc1 = (conflict_graph_arc) arcp1;
conflict_graph_arc arc2 = (conflict_graph_arc) arcp2;
+
return arc1->smaller == arc2->smaller && arc1->larger == arc2->larger;
}
*************** conflict_graph_new (num_regs)
*** 157,178 ****
int num_regs;
{
! conflict_graph graph =
! (conflict_graph) xmalloc (sizeof (struct conflict_graph_def));
graph->num_regs = num_regs;
/* Set up the hash table. No delete action is specified; memory
management of arcs is through the obstack. */
! graph->arc_hash_table =
! htab_create (INITIAL_ARC_CAPACITY, &arc_hash, &arc_eq, NULL);
/* Create an obstack for allocating arcs. */
! obstack_init (&(graph->arc_obstack));
/* Create and zero the lookup table by register number. */
! graph->neighbor_heads = (conflict_graph_arc *)
! xmalloc (num_regs * sizeof (conflict_graph_arc));
! memset (graph->neighbor_heads, 0,
! num_regs * sizeof (conflict_graph_arc));
return graph;
}
--- 153,173 ----
int num_regs;
{
! conflict_graph graph
! = (conflict_graph) xmalloc (sizeof (struct conflict_graph_def));
graph->num_regs = num_regs;
/* Set up the hash table. No delete action is specified; memory
management of arcs is through the obstack. */
! graph->arc_hash_table
! = htab_create (INITIAL_ARC_CAPACITY, &arc_hash, &arc_eq, NULL);
/* Create an obstack for allocating arcs. */
! obstack_init (&graph->arc_obstack);
/* Create and zero the lookup table by register number. */
! graph->neighbor_heads
! = (conflict_graph_arc *) xmalloc (num_regs * sizeof (conflict_graph_arc));
+ memset (graph->neighbor_heads, 0, num_regs * sizeof (conflict_graph_arc));
return graph;
}
*************** conflict_graph_delete (graph)
*** 184,188 ****
conflict_graph graph;
{
! obstack_free (&(graph->arc_obstack), NULL);
htab_delete (graph->arc_hash_table);
free (graph->neighbor_heads);
--- 179,183 ----
conflict_graph graph;
{
! obstack_free (&graph->arc_obstack, NULL);
htab_delete (graph->arc_hash_table);
free (graph->neighbor_heads);
*************** conflict_graph_add (graph, reg1, reg2)
*** 219,226 ****
/* Allocate an arc. */
! arc = (conflict_graph_arc)
! obstack_alloc (&(graph->arc_obstack),
! sizeof (struct conflict_graph_arc_def));
!
/* Record the reg numbers. */
arc->smaller = smaller;
--- 214,222 ----
/* Allocate an arc. */
! arc
! = (conflict_graph_arc)
! obstack_alloc (&graph->arc_obstack,
! sizeof (struct conflict_graph_arc_def));
!
/* Record the reg numbers. */
arc->smaller = smaller;
*************** conflict_graph_merge_regs (graph, target
*** 300,303 ****
--- 296,300 ----
{
int other = arc->smaller;
+
if (other == src)
other = arc->larger;
*************** conflict_graph_print (graph, fp)
*** 373,379 ****
int reg;
struct print_context context;
- context.fp = fp;
fprintf (fp, "Conflicts:\n");
/* Loop over registers supported in this graph. */
for (reg = 0; reg < graph->num_regs; ++reg)
--- 370,377 ----
int reg;
struct print_context context;
+ context.fp = fp;
fprintf (fp, "Conflicts:\n");
+
/* Loop over registers supported in this graph. */
for (reg = 0; reg < graph->num_regs; ++reg)
*************** conflict_graph_print (graph, fp)
*** 381,384 ****
--- 379,383 ----
context.reg = reg;
context.started = 0;
+
/* Scan the conflicts for reg, printing as we go. A label for
this line will be printed the first time a conflict is
*************** conflict_graph_print (graph, fp)
*** 386,389 ****
--- 385,389 ----
has no conflicts. */
conflict_graph_enum (graph, reg, &print_conflict, &context);
+
/* If this reg does have conflicts, end the line. */
if (context.started)
*************** conflict_graph_compute (regs, p)
*** 470,476 ****
head = bb->head;
insn = bb->end;
! for (insn = bb->end;
! insn != head;
! insn = PREV_INSN (insn))
{
int born_reg;
--- 470,474 ----
head = bb->head;
insn = bb->end;
! for (insn = bb->end; insn != head; insn = PREV_INSN (insn))
{
int born_reg;
*************** conflict_graph_compute (regs, p)
*** 498,515 ****
/* For every reg born here, add a conflict with every other
reg live coming into this insn. */
! EXECUTE_IF_SET_IN_REG_SET (born,
! FIRST_PSEUDO_REGISTER,
! born_reg, {
! EXECUTE_IF_SET_IN_REG_SET (live,
! FIRST_PSEUDO_REGISTER,
! live_reg, {
! /* Build the conflict graph in terms of canonical
! regnos. */
! int b = partition_find (p, born_reg);
! int l = partition_find (p, live_reg);
! if (b != l)
! conflict_graph_add (graph, b, l);
! });
! });
/* Morgan's algorithm checks the operands of the insn
--- 496,514 ----
/* For every reg born here, add a conflict with every other
reg live coming into this insn. */
! EXECUTE_IF_SET_IN_REG_SET
! (born, FIRST_PSEUDO_REGISTER, born_reg,
! {
! EXECUTE_IF_SET_IN_REG_SET
! (live, FIRST_PSEUDO_REGISTER, live_reg,
! {
! /* Build the conflict graph in terms of canonical
! regnos. */
! int b = partition_find (p, born_reg);
! int l = partition_find (p, live_reg);
!
! if (b != l)
! conflict_graph_add (graph, b, l);
! });
! });
/* Morgan's algorithm checks the operands of the insn
*************** conflict_graph_compute (regs, p)
*** 520,524 ****
if (REG_NOTE_KIND (link) == REG_DEAD)
{
! int regno = REGNO (XEXP (link, 0));
if (REGNO_REG_SET_P (regs, regno))
SET_REGNO_REG_SET (live, regno);
--- 519,524 ----
if (REG_NOTE_KIND (link) == REG_DEAD)
{
! unsigned int regno = REGNO (XEXP (link, 0));
!
if (REGNO_REG_SET_P (regs, regno))
SET_REGNO_REG_SET (live, regno);
*** optabs.c 2000/04/15 15:20:58 1.69
--- optabs.c 2000/04/18 17:47:11
*************** prepare_cmp_insn (px, py, pcomparison, s
*** 3099,3102 ****
--- 3099,3103 ----
WIDER_MODE (UNSIGNEDP determines whether it is a unsigned conversion), and
that it is accepted by the operand predicate. Return the new value. */
+
rtx
prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
*** simplify-rtx.c 2000/04/04 02:24:49 1.11
--- simplify-rtx.c 2000/04/18 17:47:33
***************
*** 1,3 ****
! /* Common subexpression elimination for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000 Free Software Foundation, Inc.
--- 1,3 ----
! /* RTL simplification functions for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000 Free Software Foundation, Inc.
*************** Boston, MA 02111-1307, USA. */
*** 22,26 ****
#include "config.h"
- /* stdio.h must precede rtl.h for FFS. */
#include "system.h"
#include <setjmp.h>
--- 22,25 ----
*************** Boston, MA 02111-1307, USA. */
*** 95,102 ****
! static rtx simplify_plus_minus PARAMS ((enum rtx_code, enum machine_mode,
! rtx, rtx));
! static void check_fold_consts PARAMS ((PTR));
/* Make a binary operation by properly ordering the operands and
seeing if the expression folds. */
--- 94,185 ----
! static rtx simplify_plus_minus PARAMS ((enum rtx_code,
! enum machine_mode, rtx, rtx));
! static void check_fold_consts PARAMS ((PTR));
! static int entry_and_rtx_equal_p PARAMS ((const void *, const void *));
! static unsigned int get_value_hash PARAMS ((const void *));
! static struct elt_list *new_elt_list PARAMS ((struct elt_list *,
! cselib_val *));
! static struct elt_loc_list *new_elt_loc_list PARAMS ((struct elt_loc_list *,
! rtx));
! static void unchain_one_value PARAMS ((cselib_val *));
! static void unchain_one_elt_list PARAMS ((struct elt_list **));
! static void unchain_one_elt_loc_list PARAMS ((struct elt_loc_list **));
! static void clear_table PARAMS ((void));
! static int check_value_useless PARAMS ((cselib_val *));
! static int discard_useless_locs PARAMS ((void **, void *));
! static int discard_useless_values PARAMS ((void **, void *));
! static void remove_useless_values PARAMS ((void));
! static unsigned int hash_rtx PARAMS ((rtx, enum machine_mode, int));
! static cselib_val *new_cselib_val PARAMS ((unsigned int,
! enum machine_mode));
! static void add_mem_for_addr PARAMS ((cselib_val *, cselib_val *,
! rtx));
! static cselib_val *cselib_lookup_mem PARAMS ((rtx, int));
! static rtx cselib_subst_to_values PARAMS ((rtx));
! static void cselib_invalidate_regno PARAMS ((unsigned int,
! enum machine_mode));
! static int cselib_mem_conflict_p PARAMS ((rtx, rtx));
! static int cselib_invalidate_mem_1 PARAMS ((void **, void *));
! static void cselib_invalidate_mem PARAMS ((rtx));
! static void cselib_invalidate_rtx PARAMS ((rtx, rtx, void *));
! static void cselib_record_set PARAMS ((rtx, cselib_val *,
! cselib_val *));
! static void cselib_record_sets PARAMS ((rtx));
!
! /* There are three ways in which cselib can look up an rtx:
! - for a REG, the reg_values table (which is indexed by regno) is used
! - for a MEM, we recursively look up its address and then follow the
! addr_list of that value
! - for everything else, we compute a hash value and go through the hash
! table. Since different rtx's can still have the same hash value,
! this involves walking the table entries for a given value and comparing
! the locations of the entries with the rtx we are looking up. */
!
! /* A table that enables us to look up elts by their value. */
! static htab_t hash_table;
!
! /* This is a global so we don't have to pass this through every function.
! It is used in new_elt_loc_list to set SETTING_INSN. */
! static rtx cselib_current_insn;
!
! /* Every new unknown value gets a unique number. */
! static unsigned int next_unknown_value;
+ /* The number of registers we had when the varrays were last resized. */
+ static unsigned int cselib_nregs;
+
+ /* Count values without known locations. Whenever this grows too big, we
+ remove these useless values from the table. */
+ static int n_useless_values;
+
+ /* Number of useless values before we remove them from the hash table. */
+ #define MAX_USELESS_VALUES 32
+
+ /* This table maps from register number to values. It does not contain
+ pointers to cselib_val structures, but rather elt_lists. The purpose is
+ to be able to refer to the same register in different modes. */
+ static varray_type reg_values;
+ #define REG_VALUES(I) VARRAY_ELT_LIST (reg_values, (I))
+
+ /* We pass this to cselib_invalidate_mem to invalidate all of
+ memory for a non-const call instruction. */
+ static rtx callmem;
+
+ /* Memory for our structures is allocated from this obstack. */
+ static struct obstack cselib_obstack;
+
+ /* Used to quickly free all memory. */
+ static char *cselib_startobj;
+
+ /* Caches for unused structures. */
+ static cselib_val *empty_vals;
+ static struct elt_list *empty_elt_lists;
+ static struct elt_loc_list *empty_elt_loc_lists;
+
+ /* Set by discard_useless_locs if it deleted the last location of any
+ value. */
+ static int values_became_useless;
+
/* Make a binary operation by properly ordering the operands and
seeing if the expression folds. */
*************** simplify_ternary_operation (code, mode,
*** 1810,1814 ****
rtx op0, op1, op2;
{
! int width = GET_MODE_BITSIZE (mode);
/* VOIDmode means "infinite" precision. */
--- 1893,1897 ----
rtx op0, op1, op2;
{
! unsigned int width = GET_MODE_BITSIZE (mode);
/* VOIDmode means "infinite" precision. */
*************** simplify_ternary_operation (code, mode,
*** 1873,1879 ****
else if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && ! side_effects_p (op0))
{
! rtx temp;
! temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
! XEXP (op0, 0), XEXP (op0, 1));
/* See if any simplifications were possible. */
if (temp == const0_rtx)
--- 1956,1963 ----
else if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && ! side_effects_p (op0))
{
! rtx temp
! = simplify_relational_operation (GET_CODE (op0), op0_mode,
! XEXP (op0, 0), XEXP (op0, 1));
!
/* See if any simplifications were possible. */
if (temp == const0_rtx)
*************** simplify_rtx (x)
*** 1963,2047 ****
}
- static int entry_and_rtx_equal_p PARAMS ((const void *, const void *));
- static unsigned int get_value_hash PARAMS ((const void *));
- static struct elt_list *new_elt_list PARAMS ((struct elt_list *, cselib_val *));
- static struct elt_loc_list *new_elt_loc_list PARAMS ((struct elt_loc_list *, rtx));
- static void unchain_one_value PARAMS ((cselib_val *));
- static void unchain_one_elt_list PARAMS ((struct elt_list **));
- static void unchain_one_elt_loc_list PARAMS ((struct elt_loc_list **));
- static void clear_table PARAMS ((void));
- static int check_value_useless PARAMS ((cselib_val *));
- static int discard_useless_locs PARAMS ((void **, void *));
- static int discard_useless_values PARAMS ((void **, void *));
- static void remove_useless_values PARAMS ((void));
- static unsigned int hash_rtx PARAMS ((rtx, enum machine_mode, int));
- static cselib_val *new_cselib_val PARAMS ((unsigned int,
- enum machine_mode));
- static void add_mem_for_addr PARAMS ((cselib_val *, cselib_val *,
- rtx));
- static cselib_val *cselib_lookup_mem PARAMS ((rtx, int));
- static rtx cselib_subst_to_values PARAMS ((rtx));
- static void cselib_invalidate_regno PARAMS ((unsigned int,
- enum machine_mode));
- static int cselib_mem_conflict_p PARAMS ((rtx, rtx));
- static int cselib_invalidate_mem_1 PARAMS ((void **, void *));
- static void cselib_invalidate_mem PARAMS ((rtx));
- static void cselib_invalidate_rtx PARAMS ((rtx, rtx, void *));
- static void cselib_record_set PARAMS ((rtx, cselib_val *,
- cselib_val *));
- static void cselib_record_sets PARAMS ((rtx));
-
- /* There are three ways in which cselib can look up an rtx:
- - for a REG, the reg_values table (which is indexed by regno) is used
- - for a MEM, we recursively look up its address and then follow the
- addr_list of that value
- - for everything else, we compute a hash value and go through the hash
- table. Since different rtx's can still have the same hash value,
- this involves walking the table entries for a given value and comparing
- the locations of the entries with the rtx we are looking up. */
-
- /* A table that enables us to look up elts by their value. */
- static htab_t hash_table;
-
- /* This is a global so we don't have to pass this through every function.
- It is used in new_elt_loc_list to set SETTING_INSN. */
- static rtx cselib_current_insn;
-
- /* Every new unknown value gets a unique number. */
- static unsigned int next_unknown_value;
- /* The number of registers we had when the varrays were last resized. */
- static int cselib_nregs;
-
- /* Count values without known locations. Whenever this grows too big, we
- remove these useless values from the table. */
- static int n_useless_values;
-
- /* Number of useless values before we remove them from the hash table. */
- #define MAX_USELESS_VALUES 32
-
- /* This table maps from register number to values. It does not contain
- pointers to cselib_val structures, but rather elt_lists. The purpose is
- to be able to refer to the same register in different modes. */
- static varray_type reg_values;
- #define REG_VALUES(I) VARRAY_ELT_LIST (reg_values, (I))
-
- /* We pass this to cselib_invalidate_mem to invalidate all of
- memory for a non-const call instruction. */
- static rtx callmem;
-
- /* Memory for our structures is allocated from this obstack. */
- static struct obstack cselib_obstack;
-
- /* Used to quickly free all memory. */
- static char *cselib_startobj;
-
- /* Caches for unused structures. */
- static cselib_val *empty_vals;
- static struct elt_list *empty_elt_lists;
- static struct elt_loc_list *empty_elt_loc_lists;
-
/* Allocate a struct elt_list and fill in its two elements with the
arguments. */
static struct elt_list *
new_elt_list (next, elt)
--- 2047,2054 ----
}
/* Allocate a struct elt_list and fill in its two elements with the
arguments. */
+
static struct elt_list *
new_elt_list (next, elt)
*************** new_elt_list (next, elt)
*** 2050,2053 ****
--- 2057,2061 ----
{
struct elt_list *el = empty_elt_lists;
+
if (el)
empty_elt_lists = el->next;
*************** new_elt_list (next, elt)
*** 2062,2065 ****
--- 2070,2074 ----
/* Allocate a struct elt_loc_list and fill in its two elements with the
arguments. */
+
static struct elt_loc_list *
new_elt_loc_list (next, loc)
*************** new_elt_loc_list (next, loc)
*** 2068,2071 ****
--- 2077,2081 ----
{
struct elt_loc_list *el = empty_elt_loc_lists;
+
if (el)
empty_elt_loc_lists = el->next;
*************** new_elt_loc_list (next, loc)
*** 2081,2084 ****
--- 2091,2095 ----
/* The elt_list at *PL is no longer needed. Unchain it and free its
storage. */
+
static void
unchain_one_elt_list (pl)
*************** unchain_one_elt_list (pl)
*** 2086,2089 ****
--- 2097,2101 ----
{
struct elt_list *l = *pl;
+
*pl = l->next;
l->next = empty_elt_lists;
*************** unchain_one_elt_list (pl)
*** 2092,2095 ****
--- 2104,2108 ----
/* Likewise for elt_loc_lists. */
+
static void
unchain_one_elt_loc_list (pl)
*************** unchain_one_elt_loc_list (pl)
*** 2097,2100 ****
--- 2110,2114 ----
{
struct elt_loc_list *l = *pl;
+
*pl = l->next;
l->next = empty_elt_loc_lists;
*************** unchain_one_elt_loc_list (pl)
*** 2104,2107 ****
--- 2118,2122 ----
/* Likewise for cselib_vals. This also frees the addr_list associated with
V. */
+
static void
unchain_one_value (v)
*************** unchain_one_value (v)
*** 2117,2124 ****
/* Remove all entries from the hash table. Also used during
initialization. */
static void
clear_table ()
{
! int i;
for (i = 0; i < cselib_nregs; i++)
REG_VALUES (i) = 0;
--- 2132,2141 ----
/* Remove all entries from the hash table. Also used during
initialization. */
+
static void
clear_table ()
{
! unsigned int i;
!
for (i = 0; i < cselib_nregs; i++)
REG_VALUES (i) = 0;
*************** clear_table ()
*** 2137,2140 ****
--- 2154,2158 ----
/* The equality test for our hash table. The first argument ENTRY is a table
element (i.e. a cselib_val), while the second arg X is an rtx. */
+
static int
entry_and_rtx_equal_p (entry, x_arg)
*************** entry_and_rtx_equal_p (entry, x_arg)
*** 2142,2147 ****
{
struct elt_loc_list *l;
! const cselib_val *v = (const cselib_val *)entry;
! rtx x = (rtx)x_arg;
/* We don't guarantee that distinct rtx's have different hash values,
--- 2160,2165 ----
{
struct elt_loc_list *l;
! const cselib_val *v = (const cselib_val *) entry;
! rtx x = (rtx) x_arg;
/* We don't guarantee that distinct rtx's have different hash values,
*************** entry_and_rtx_equal_p (entry, x_arg)
*** 2150,2153 ****
--- 2168,2172 ----
if (rtx_equal_for_cselib_p (l->loc, x))
return 1;
+
return 0;
}
*************** entry_and_rtx_equal_p (entry, x_arg)
*** 2156,2159 ****
--- 2175,2179 ----
hash_rtx when adding an element; this function just extracts the hash
value from a cselib_val structure. */
+
static unsigned int
get_value_hash (entry)
*************** get_value_hash (entry)
*** 2167,2170 ****
--- 2187,2191 ----
useless. See whether that is the case for V. Return 1 if this has
just become useless. */
+
static int
check_value_useless (v)
*************** check_value_useless (v)
*** 2187,2190 ****
--- 2208,2212 ----
element has been set to zero, which implies the cselib_val will be
removed. */
+
int
references_value_p (x, only_useless)
*************** references_value_p (x, only_useless)
*** 2194,2198 ****
enum rtx_code code = GET_CODE (x);
const char *fmt = GET_RTX_FORMAT (code);
! int i;
if (GET_CODE (x) == VALUE
--- 2216,2220 ----
enum rtx_code code = GET_CODE (x);
const char *fmt = GET_RTX_FORMAT (code);
! int i, j;
if (GET_CODE (x) == VALUE
*************** references_value_p (x, only_useless)
*** 2202,2218 ****
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
! if (fmt[i] == 'e')
! {
! if (references_value_p (XEXP (x, i), only_useless))
! return 1;
! }
else if (fmt[i] == 'E')
! {
! int j;
!
! for (j = 0; j < XVECLEN (x, i); j++)
! if (references_value_p (XVECEXP (x, i, j), only_useless))
! return 1;
! }
}
--- 2224,2233 ----
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
! if (fmt[i] == 'e' && references_value_p (XEXP (x, i), only_useless))
! return 1;
else if (fmt[i] == 'E')
! for (j = 0; j < XVECLEN (x, i); j++)
! if (references_value_p (XVECEXP (x, i, j), only_useless))
! return 1;
}
*************** references_value_p (x, only_useless)
*** 2220,2230 ****
}
- /* Set by discard_useless_locs if it deleted the last location of any
- value. */
- static int values_became_useless;
-
/* For all locations found in X, delete locations that reference useless
values (i.e. values without any location). Called through
htab_traverse. */
static int
discard_useless_locs (x, info)
--- 2235,2242 ----
}
/* For all locations found in X, delete locations that reference useless
values (i.e. values without any location). Called through
htab_traverse. */
+
static int
discard_useless_locs (x, info)
*************** discard_useless_locs (x, info)
*** 2242,2245 ****
--- 2254,2258 ----
p = &(*p)->next;
}
+
if (check_value_useless (v))
values_became_useless = 1;
*************** discard_useless_values (x, info)
*** 2263,2266 ****
--- 2276,2280 ----
n_useless_values--;
}
+
return 1;
}
*************** discard_useless_values (x, info)
*** 2268,2271 ****
--- 2282,2286 ----
/* Clean out useless values (i.e. those which no longer have locations
associated with them) from the hash table. */
+
static void
remove_useless_values ()
*************** remove_useless_values ()
*** 2289,2292 ****
--- 2304,2308 ----
/* Return nonzero if we can prove that X and Y contain the same value, taking
our gathered information into account. */
+
int
rtx_equal_for_cselib_p (x, y)
*************** rtx_equal_for_cselib_p (x, y)
*** 2300,2309 ****
--- 2316,2328 ----
{
cselib_val *e = cselib_lookup (x, VOIDmode, 0);
+
if (e)
x = e->u.val_rtx;
}
+
if (GET_CODE (y) == REG || GET_CODE (y) == MEM)
{
cselib_val *e = cselib_lookup (y, VOIDmode, 0);
+
if (e)
y = e->u.val_rtx;
*************** rtx_equal_for_cselib_p (x, y)
*** 2328,2333 ****
if (GET_CODE (t) == REG || GET_CODE (t) == MEM)
continue;
!
! if (rtx_equal_for_cselib_p (t, y))
return 1;
}
--- 2347,2351 ----
if (GET_CODE (t) == REG || GET_CODE (t) == MEM)
continue;
! else if (rtx_equal_for_cselib_p (t, y))
return 1;
}
*************** rtx_equal_for_cselib_p (x, y)
*** 2347,2352 ****
if (GET_CODE (t) == REG || GET_CODE (t) == MEM)
continue;
!
! if (rtx_equal_for_cselib_p (x, t))
return 1;
}
--- 2365,2369 ----
if (GET_CODE (t) == REG || GET_CODE (t) == MEM)
continue;
! else if (rtx_equal_for_cselib_p (x, t))
return 1;
}
*************** rtx_equal_for_cselib_p (x, y)
*** 2355,2360 ****
}
! if (GET_CODE (x) != GET_CODE (y)
! || GET_MODE (x) != GET_MODE (y))
return 0;
--- 2372,2376 ----
}
! if (GET_CODE (x) != GET_CODE (y) || GET_MODE (x) != GET_MODE (y))
return 0;
*************** rtx_equal_for_cselib_p (x, y)
*** 2369,2372 ****
--- 2385,2389 ----
{
int j;
+
switch (fmt[i])
{
*************** rtx_equal_for_cselib_p (x, y)
*** 2432,2435 ****
--- 2449,2453 ----
MODE is used in hashing for CONST_INTs only;
otherwise the mode of X is used. */
+
static unsigned int
hash_rtx (x, mode, create)
*************** hash_rtx (x, mode, create)
*** 2456,2468 ****
if (! e)
return 0;
hash += e->value;
return hash;
case CONST_INT:
! {
! unsigned HOST_WIDE_INT tem = INTVAL (x);
! hash += ((unsigned) CONST_INT << 7) + (unsigned) mode + tem;
! return hash ? hash : CONST_INT;
! }
case CONST_DOUBLE:
--- 2474,2484 ----
if (! e)
return 0;
+
hash += e->value;
return hash;
case CONST_INT:
! hash += ((unsigned) CONST_INT << 7) + (unsigned) mode + INTVAL (x);
! return hash ? hash : CONST_INT;
case CONST_DOUBLE:
*************** hash_rtx (x, mode, create)
*** 2472,2479 ****
if (GET_MODE (x) != VOIDmode)
for (i = 2; i < GET_RTX_LENGTH (CONST_DOUBLE); i++)
! {
! unsigned HOST_WIDE_INT tem = XWINT (x, i);
! hash += tem;
! }
else
hash += ((unsigned) CONST_DOUBLE_LOW (x)
--- 2488,2492 ----
if (GET_MODE (x) != VOIDmode)
for (i = 2; i < GET_RTX_LENGTH (CONST_DOUBLE); i++)
! hash += XWINT (x, i);
else
hash += ((unsigned) CONST_DOUBLE_LOW (x)
*************** hash_rtx (x, mode, create)
*** 2518,2523 ****
if (fmt[i] == 'e')
{
- unsigned int tem_hash;
rtx tem = XEXP (x, i);
/* If we are about to do the last recursive call
--- 2531,2536 ----
if (fmt[i] == 'e')
{
rtx tem = XEXP (x, i);
+ unsigned int tem_hash;
/* If we are about to do the last recursive call
*************** hash_rtx (x, mode, create)
*** 2529,2535 ****
--- 2542,2550 ----
goto repeat;
}
+
tem_hash = hash_rtx (tem, 0, create);
if (tem_hash == 0)
return 0;
+
hash += tem_hash;
}
*************** hash_rtx (x, mode, create)
*** 2538,2543 ****
--- 2553,2560 ----
{
unsigned int tem_hash = hash_rtx (XVECEXP (x, i, j), 0, create);
+
if (tem_hash == 0)
return 0;
+
hash += tem_hash;
}
*************** hash_rtx (x, mode, create)
*** 2545,2548 ****
--- 2562,2566 ----
{
const unsigned char *p = (const unsigned char *) XSTR (x, i);
+
if (p)
while (*p)
*************** hash_rtx (x, mode, create)
*** 2550,2557 ****
}
else if (fmt[i] == 'i')
! {
! unsigned int tem = XINT (x, i);
! hash += tem;
! }
else if (fmt[i] == '0' || fmt[i] == 't')
/* unused */;
--- 2568,2572 ----
}
else if (fmt[i] == 'i')
! hash += XINT (x, i);
else if (fmt[i] == '0' || fmt[i] == 't')
/* unused */;
*************** hash_rtx (x, mode, create)
*** 2559,2562 ****
--- 2574,2578 ----
abort ();
}
+
return hash ? hash : 1 + GET_CODE (x);
}
*************** hash_rtx (x, mode, create)
*** 2564,2567 ****
--- 2580,2584 ----
/* Create a new value structure for VALUE and initialize it. The mode of the
value is MODE. */
+
static cselib_val *
new_cselib_val (value, mode)
*************** new_cselib_val (value, mode)
*** 2570,2583 ****
{
cselib_val *e = empty_vals;
if (e)
empty_vals = e->u.next_free;
else
e = (cselib_val *) obstack_alloc (&cselib_obstack, sizeof (cselib_val));
if (value == 0)
abort ();
e->value = value;
e->u.val_rtx = gen_rtx_VALUE (mode);
CSELIB_VAL_PTR (e->u.val_rtx) = e;
-
e->addr_list = 0;
e->locs = 0;
--- 2587,2602 ----
{
cselib_val *e = empty_vals;
+
if (e)
empty_vals = e->u.next_free;
else
e = (cselib_val *) obstack_alloc (&cselib_obstack, sizeof (cselib_val));
+
if (value == 0)
abort ();
+
e->value = value;
e->u.val_rtx = gen_rtx_VALUE (mode);
CSELIB_VAL_PTR (e->u.val_rtx) = e;
e->addr_list = 0;
e->locs = 0;
*************** new_cselib_val (value, mode)
*** 2588,2591 ****
--- 2607,2611 ----
contains the data at this address. X is a MEM that represents the
value. Update the two value structures to represent this situation. */
+
static void
add_mem_for_addr (addr_elt, mem_elt, x)
*************** add_mem_for_addr (addr_elt, mem_elt, x)
*** 2613,2616 ****
--- 2633,2637 ----
/* Subroutine of cselib_lookup. Return a value for X, which is a MEM rtx.
If CREATE, make a new one if we haven't seen it before. */
+
static cselib_val *
cselib_lookup_mem (x, create)
*************** cselib_lookup_mem (x, create)
*** 2623,2629 ****
struct elt_list *l;
! if (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode)
! return 0;
! if (FLOAT_MODE_P (GET_MODE (x)) && flag_float_store)
return 0;
--- 2644,2649 ----
struct elt_list *l;
! if (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode
! || (FLOAT_MODE_P (GET_MODE (x)) && flag_float_store))
return 0;
*************** cselib_lookup_mem (x, create)
*** 2637,2645 ****
if (GET_MODE (l->elt->u.val_rtx) == GET_MODE (x))
return l->elt;
if (! create)
return 0;
mem_elt = new_cselib_val (++next_unknown_value, GET_MODE (x));
add_mem_for_addr (addr, mem_elt, x);
slot = htab_find_slot_with_hash (hash_table, x, mem_elt->value, 1);
*slot = mem_elt;
return mem_elt;
--- 2657,2667 ----
if (GET_MODE (l->elt->u.val_rtx) == GET_MODE (x))
return l->elt;
+
if (! create)
return 0;
+
mem_elt = new_cselib_val (++next_unknown_value, GET_MODE (x));
add_mem_for_addr (addr, mem_elt, x);
slot = htab_find_slot_with_hash (hash_table, x, mem_elt->value, 1);
*slot = mem_elt;
return mem_elt;
*************** cselib_lookup_mem (x, create)
*** 2651,2654 ****
--- 2673,2677 ----
X isn't actually modified; if modifications are needed, new rtl is
allocated. However, the return value can share rtl with X. */
+
static rtx
cselib_subst_to_values (x)
*************** cselib_subst_to_values (x)
*** 2665,2672 ****
{
case REG:
! i = REGNO (x);
! for (l = REG_VALUES (i); l; l = l->next)
if (GET_MODE (l->elt->u.val_rtx) == GET_MODE (x))
return l->elt->u.val_rtx;
abort ();
--- 2688,2695 ----
{
case REG:
! for (l = REG_VALUES (REGNO (x)); l; l = l->next)
if (GET_MODE (l->elt->u.val_rtx) == GET_MODE (x))
return l->elt->u.val_rtx;
+
abort ();
*************** cselib_subst_to_values (x)
*** 2692,2697 ****
--- 2715,2722 ----
{
rtx t = cselib_subst_to_values (XEXP (x, i));
+
if (t != XEXP (x, i) && x == copy)
copy = shallow_copy_rtx (x);
+
XEXP (copy, i) = t;
}
*************** cselib_subst_to_values (x)
*** 2703,2718 ****
--- 2728,2747 ----
{
rtx t = cselib_subst_to_values (XVECEXP (x, i, j));
+
if (t != XVECEXP (x, i, j) && XVEC (x, i) == XVEC (copy, i))
{
if (x == copy)
copy = shallow_copy_rtx (x);
+
XVEC (copy, i) = rtvec_alloc (XVECLEN (x, i));
for (k = 0; k < j; k++)
XVECEXP (copy, i, k) = XVECEXP (x, i, k);
}
+
XVECEXP (copy, i, j) = t;
}
}
}
+
return copy;
}
*************** cselib_subst_to_values (x)
*** 2722,2725 ****
--- 2751,2755 ----
we create a new one if possible, using mode MODE if X doesn't have a mode
(i.e. because it's a constant). */
+
cselib_val *
cselib_lookup (x, mode, create)
*************** cselib_lookup (x, mode, create)
*** 2741,2750 ****
{
struct elt_list *l;
! int i = REGNO (x);
for (l = REG_VALUES (i); l; l = l->next)
if (mode == GET_MODE (l->elt->u.val_rtx))
return l->elt;
if (! create)
return 0;
e = new_cselib_val (++next_unknown_value, GET_MODE (x));
e->locs = new_elt_loc_list (e->locs, x);
--- 2771,2783 ----
{
struct elt_list *l;
! unsigned int i = REGNO (x);
!
for (l = REG_VALUES (i); l; l = l->next)
if (mode == GET_MODE (l->elt->u.val_rtx))
return l->elt;
+
if (! create)
return 0;
+
e = new_cselib_val (++next_unknown_value, GET_MODE (x));
e->locs = new_elt_loc_list (e->locs, x);
*************** cselib_lookup (x, mode, create)
*** 2771,2774 ****
--- 2806,2810 ----
e = new_cselib_val (hashval, mode);
+
/* We have to fill the slot before calling cselib_subst_to_values:
the hash table is inconsistent until we do so, and
*************** cselib_invalidate_regno (regno, mode)
*** 2842,2845 ****
--- 2878,2882 ----
}
}
+
check_value_useless (v);
}
*************** cselib_invalidate_regno (regno, mode)
*** 2849,2852 ****
--- 2886,2890 ----
/* The memory at address MEM_BASE is being changed.
Return whether this change will invalidate VAL. */
+
static int
cselib_mem_conflict_p (mem_base, val)
*************** cselib_mem_conflict_p (mem_base, val)
*** 2856,2860 ****
enum rtx_code code;
const char *fmt;
! int i;
code = GET_CODE (val);
--- 2894,2898 ----
enum rtx_code code;
const char *fmt;
! int i, j;
code = GET_CODE (val);
*************** cselib_mem_conflict_p (mem_base, val)
*** 2875,2882 ****
case MEM:
if (GET_MODE (mem_base) == BLKmode
! || GET_MODE (val) == BLKmode)
! return 1;
! if (anti_dependence (val, mem_base))
return 1;
/* The address may contain nested MEMs. */
break;
--- 2913,2920 ----
case MEM:
if (GET_MODE (mem_base) == BLKmode
! || GET_MODE (val) == BLKmode
! || anti_dependence (val, mem_base))
return 1;
+
/* The address may contain nested MEMs. */
break;
*************** cselib_mem_conflict_p (mem_base, val)
*** 2887,2891 ****
fmt = GET_RTX_FORMAT (code);
-
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
--- 2925,2928 ----
*************** cselib_mem_conflict_p (mem_base, val)
*** 2896,2906 ****
}
else if (fmt[i] == 'E')
! {
! int j;
!
! for (j = 0; j < XVECLEN (val, i); j++)
! if (cselib_mem_conflict_p (mem_base, XVECEXP (val, i, j)))
! return 1;
! }
}
--- 2933,2939 ----
}
else if (fmt[i] == 'E')
! for (j = 0; j < XVECLEN (val, i); j++)
! if (cselib_mem_conflict_p (mem_base, XVECEXP (val, i, j)))
! return 1;
}
*************** cselib_mem_conflict_p (mem_base, val)
*** 2910,2913 ****
--- 2943,2947 ----
/* For the value found in SLOT, walk its locations to determine if any overlap
INFO (which is a MEM rtx). */
+
static int
cselib_invalidate_mem_1 (slot, info)
*************** cselib_invalidate_mem_1 (slot, info)
*** 2921,2927 ****
while (*p)
{
cselib_val *addr;
struct elt_list **mem_chain;
- rtx x = (*p)->loc;
/* MEMs may occur in locations only at the top level; below
--- 2955,2961 ----
while (*p)
{
+ rtx x = (*p)->loc;
cselib_val *addr;
struct elt_list **mem_chain;
/* MEMs may occur in locations only at the top level; below
*************** cselib_invalidate_mem_1 (slot, info)
*** 2946,2953 ****
--- 2980,2990 ----
break;
}
+
mem_chain = &(*mem_chain)->next;
}
+
unchain_one_elt_loc_list (p);
}
+
check_value_useless (v);
return 1;
*************** cselib_invalidate_mem_1 (slot, info)
*** 2957,2960 ****
--- 2994,2998 ----
store to MEM_RTX. If this is called because of a non-const call
instruction, MEM_RTX is (mem:BLK const0_rtx). */
+
static void
cselib_invalidate_mem (mem_rtx)
*************** cselib_invalidate_mem (mem_rtx)
*** 2967,2970 ****
--- 3005,3009 ----
the third parameter exist so that this function can be passed to
note_stores; they are ignored. */
+
static void
cselib_invalidate_rtx (dest, ignore, data)
*************** cselib_invalidate_rtx (dest, ignore, dat
*** 2973,2980 ****
void *data ATTRIBUTE_UNUSED;
{
! while (GET_CODE (dest) == STRICT_LOW_PART
! || GET_CODE (dest) == SIGN_EXTRACT
! || GET_CODE (dest) == ZERO_EXTRACT
! || GET_CODE (dest) == SUBREG)
dest = XEXP (dest, 0);
--- 3012,3017 ----
void *data ATTRIBUTE_UNUSED;
{
! while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SIGN_EXTRACT
! || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SUBREG)
dest = XEXP (dest, 0);
*************** cselib_record_sets (insn)
*** 3087,3090 ****
--- 3124,3128 ----
/* Record the effects of INSN. */
+
void
cselib_process_insn (insn)
*************** cselib_process_insn (insn)
*** 3092,3095 ****
--- 3130,3134 ----
{
int i;
+ rtx x;
cselib_current_insn = insn;
*************** cselib_process_insn (insn)
*** 3112,3115 ****
--- 3151,3155 ----
return;
}
+
/* If this is a call instruction, forget anything stored in a
call clobbered register, or, if this is not a const call, in
*************** cselib_process_insn (insn)
*** 3131,3141 ****
could keep track of the changes to their values, but it is
unlikely to help. */
! {
! rtx x;
!
! for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
! if (REG_NOTE_KIND (x) == REG_INC)
! cselib_invalidate_rtx (XEXP (x, 0), NULL_RTX, NULL);
! }
#endif
--- 3171,3177 ----
could keep track of the changes to their values, but it is
unlikely to help. */
! for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
! if (REG_NOTE_KIND (x) == REG_INC)
! cselib_invalidate_rtx (XEXP (x, 0), NULL_RTX, NULL);
#endif
*************** cselib_process_insn (insn)
*** 3143,3155 ****
after we have processed the insn. */
if (GET_CODE (insn) == CALL_INSN)
! {
! rtx x;
- for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1))
- if (GET_CODE (XEXP (x, 0)) == CLOBBER)
- cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0), NULL_RTX,
- NULL);
- }
-
cselib_current_insn = 0;
--- 3179,3186 ----
after we have processed the insn. */
if (GET_CODE (insn) == CALL_INSN)
! for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1))
! if (GET_CODE (XEXP (x, 0)) == CLOBBER)
! cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0), NULL_RTX, NULL);
cselib_current_insn = 0;
*************** cselib_process_insn (insn)
*** 3160,3169 ****
/* Make sure our varrays are big enough. Not called from any cselib routines;
it must be called by the user if it allocated new registers. */
void
cselib_update_varray_sizes ()
{
! int nregs = max_reg_num ();
if (nregs == cselib_nregs)
return;
cselib_nregs = nregs;
VARRAY_GROW (reg_values, nregs);
--- 3191,3203 ----
/* Make sure our varrays are big enough. Not called from any cselib routines;
it must be called by the user if it allocated new registers. */
+
void
cselib_update_varray_sizes ()
{
! unsigned int nregs = max_reg_num ();
!
if (nregs == cselib_nregs)
return;
+
cselib_nregs = nregs;
VARRAY_GROW (reg_values, nregs);
*************** cselib_update_varray_sizes ()
*** 3172,3175 ****
--- 3206,3210 ----
/* Initialize cselib for one pass. The caller must also call
init_alias_analysis. */
+
void
cselib_init ()
*************** cselib_init ()
*** 3179,3182 ****
--- 3214,3218 ----
{
extern struct obstack permanent_obstack;
+
gcc_obstack_init (&cselib_obstack);
cselib_startobj = obstack_alloc (&cselib_obstack, 0);
*************** cselib_init ()
*** 3195,3198 ****
--- 3231,3235 ----
/* Called when the current user is done with cselib. */
+
void
cselib_finish ()
*** tree.h 2000/04/17 03:20:48 1.159
--- tree.h 2000/04/18 17:49:30
*************** struct tree_type
*** 1110,1114 ****
/* Holds the alignment required for the datum. */
#define DECL_ALIGN(NODE) (DECL_CHECK (NODE)->decl.u1.a.align)
! /* For FIELD_DECLs, holds the alignment that DECL_FEILD_OFFSET has. */
#define DECL_OFFSET_ALIGN(NODE) (FIELD_DECL_CHECK (NODE)->decl.u1.a.off_align)
/* Holds the machine mode corresponding to the declaration of a variable or
--- 1110,1114 ----
/* Holds the alignment required for the datum. */
#define DECL_ALIGN(NODE) (DECL_CHECK (NODE)->decl.u1.a.align)
! /* For FIELD_DECLs, holds the alignment that DECL_FIELD_OFFSET has. */
#define DECL_OFFSET_ALIGN(NODE) (FIELD_DECL_CHECK (NODE)->decl.u1.a.off_align)
/* Holds the machine mode corresponding to the declaration of a variable or
More information about the Gcc-patches
mailing list