This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] More fixes
- From: Diego Novillo <dnovillo at redhat dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 07 Aug 2003 20:41:15 -0400
- Subject: [tree-ssa] More fixes
- Organization: Red Hat Canada
Another collection of minor fixes. This one does two main things:
* Variables that are hidden in the IL (VLA initialization,
non-gimple builtin calls) are never exposed to the optimizers.
* Variables that are used in VA_ARG_EXPR are never used in real
operands. This is necessary because VA_ARG_EXPR both modifies
and reads from its argument. This is not something we can
easily support in real operands. Perhaps if VA_ARG_EXPR had two
operands, instead of one.
* In tree-ssa.c we were creating varrays of data structures that
were not GC allocated, this was creating random failures on
ia64.
* Similarly, in tree-ssa-ccp.c, we were using a varray of edges,
which are not GC allocated. I created a new VARRAY for edges
that use xmalloc instead.
* I also moved the code to find variables outside of
compute_may_aliases. It doesn't make sense to have them both in
the same place.
Bootstrapped and tested on x86, ia64, ppc and amd64.
Diego.
* Makefile.in (GTFILES): Add tree-ssa.c, tree-dfa.c and
tree-ssa-ccp.c.
(gt-tree-ssa.h, gt-tree-dfa.h, gt-tree-ssa-ccp.h): Depend on
s-gtype.
* tree-dfa.c (struct clobber_data_d): Remove. Update all users.
(struct alias_map_d): Mark for garbage collection.
(struct walk_state): Add fields 'is_not_gimple' and
'is_va_arg_expr'.
(clobber_vars_r): Remove. Update all users.
(get_stmt_operands): Abort if attempting to get operands from a
non-GIMPLE statement.
(get_expr_operands): Likewise.
Do not force a virtual operand when scanning VA_ARG_EXPR.
(add_stmt_operand): If the variable has hidden uses, mark the
statement as having volatile operands and return.
If the variable occurs inside a VA_ARG_EXPR, add it as a virtual
operand.
(add_immediate_use): Call VARRAY_TREE_INIT instead of
VARRAY_GENERIC_PTR_INIT.
(dump_variable): Check is_in_va_arg_expr flag.
(compute_may_aliases): Move code to find variables ...
(find_referenced_vars): ... here.
(find_vars_r): Abort if we find a non-GIMPLE expression
unexpectedly.
Mark variables found inside a VA_ARG_EXPR.
Do not scan arguments for non-GIMPLE CALL_EXPRs.
Remove local variable saved_is_store.
Reformat some code for readability.
(add_referenced_var): If the variable is already marked as having
hidden uses, ignore it.
If the variable is found inside a non-GIMPLE expression, mark it.
If the variable is found inside a VA_ARG_EXPR, mark it.
* tree-flow.h (struct var_ann_d): Add field is_in_va_arg_expr.
(find_referenced_vars): Declare.
* tree-optimize.c (optimize_function_tree): Call
find_referenced_vars before computing may aliases.
* tree-ssa-dce.c (need_to_preserve_store): Do not check if the
variable has hidden uses.
* tree-ssa-live.c (type_var_init): Likewise.
* tree-ssa-ccp.c (ssa_edges): Mark for garbage collection.
(tree_ssa_ccp): Use VARRAY_.*_EDGE calls to manipulate the varray
of CFG edges.
(add_control_edge): Likewise.
(initialize): Likewise.
* tree-ssa.c (struct def_blocks_d): Mark for garbage collection.
(struct var_value_d): Likewise.
(def_blocks_free): Remove. Update all users.
(rewrite_into_ssa): Do not specify free function when creating
def_blocks and currdefs.
Call sbitmap_free instead of free.
(mark_def_sites): Call sbitmap_free instead of free.
(set_def_block): Use GC allocation.
(set_livein_block): Likewise.
(insert_phi_nodes): Adjust name of varray def_maps when creating it.
(insert_phis_for_deferred_variables): Remove call to BITMAP_XFREE.
(insert_phi_nodes_for): Use GC allocation for phi_insertion_points.
(init_tree_ssa): Remove typecast in call to memset.
(set_value_for): Use GC allocation.
(get_def_blocks_for): Remove typecast in call to htab_find.
* varray.c (element): Add entry for struct edge_def *.
* varray.h (enum varray_data_enum): Add VARRAY_DATA_EDGE.
(union varray_data_tag): Add field of type struct edge_def *.
(VARRAY_EDGE_INIT): Define.
(VARRAY_EDGE): Define.
(VARRAY_PUSH_EDGE): Define.
(VARRAY_TOP_EDGE): Define.
testsuite/ChangeLog.tree-ssa:
* gcc.c-torture/execute/20030801-1.c: New test.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.903.2.107
diff -d -u -p -c -r1.903.2.107 Makefile.in
*** Makefile.in 4 Aug 2003 17:22:41 -0000 1.903.2.107
--- Makefile.in 7 Aug 2003 18:51:15 -0000
*************** GTFILES = $(srcdir)/input.h $(srcdir)/co
*** 2147,2152 ****
--- 2147,2153 ----
$(srcdir)/tree-mudflap.c $(srcdir)/tree-flow.h \
$(srcdir)/c-objc-common.c $(srcdir)/c-common.c $(srcdir)/c-parse.in \
$(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \
+ $(srcdir)/tree-ssa.c $(srcdir)/tree-dfa.c $(srcdir)/tree-ssa-ccp.c \
$(out_file) \
@all_gtfiles@
*************** gt-dwarf2out.h gt-ra-build.h gt-reg-stac
*** 2164,2170 ****
gt-dbxout.h gt-c-common.h gt-c-decl.h gt-c-parse.h \
gt-c-pragma.h gt-c-objc-common.h gtype-c.h gt-input.h gt-cfglayout.h \
gt-stringpool.h gt-langhooks.h \
! gt-tree-alias-common.h gt-tree-mudflap.h gt-dependence.h: s-gtype ; @true
gtyp-gen.h: Makefile
echo "/* This file is machine generated. Do not edit. */" > tmp-gtyp.h
--- 2165,2172 ----
gt-dbxout.h gt-c-common.h gt-c-decl.h gt-c-parse.h \
gt-c-pragma.h gt-c-objc-common.h gtype-c.h gt-input.h gt-cfglayout.h \
gt-stringpool.h gt-langhooks.h \
! gt-tree-alias-common.h gt-tree-mudflap.h gt-dependence.h \
! gt-tree-ssa.h gt-tree-dfa.h gt-tree-ssa-ccp.h: s-gtype ; @true
gtyp-gen.h: Makefile
echo "/* This file is machine generated. Do not edit. */" > tmp-gtyp.h
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.142
diff -d -u -p -c -r1.1.4.142 tree-dfa.c
*** tree-dfa.c 6 Aug 2003 19:55:38 -0000 1.1.4.142
--- tree-dfa.c 7 Aug 2003 18:51:16 -0000
*************** struct dfa_stats_d
*** 60,74 ****
long num_vuses;
};
- struct clobber_data_d
- {
- tree stmt;
- voperands_t prev_vops;
- };
-
/* Tuple to map a variable to its alias set. Used to cache the results of
calls to get_alias_set(). */
! struct alias_map_d
{
tree var;
HOST_WIDE_INT set;
--- 60,68 ----
long num_vuses;
};
/* Tuple to map a variable to its alias set. Used to cache the results of
calls to get_alias_set(). */
! struct GTY(()) alias_map_d
{
tree var;
HOST_WIDE_INT set;
*************** static GTY(()) varray_type pointers;
*** 85,93 ****
/* State information for find_vars_r. */
struct walk_state
{
- /* Hash table used to avoid adding the same variable more than once. */
- htab_t vars_found;
-
/* Nonzero if the variables found under the current tree are written to. */
int is_store : 1;
--- 79,84 ----
*************** struct walk_state
*** 96,101 ****
--- 87,101 ----
/* Nonzero if the walker is inside an ASM_EXPR node. */
int is_asm_expr : 1;
+
+ /* Nonzero if the walker is inside a non-GIMPLE expression. */
+ int is_not_gimple : 1;
+
+ /* Nonzero if the walker is inside a VA_ARG_EXPR node. */
+ int is_va_arg_expr : 1;
+
+ /* Hash table used to avoid adding the same variable more than once. */
+ htab_t vars_found;
};
*************** static void cleanup_operand_arrays (stmt
*** 123,129 ****
static void get_expr_operands (tree, tree *, int, voperands_t);
static void collect_dfa_stats (struct dfa_stats_d *);
static tree collect_dfa_stats_r (tree *, int *, void *);
- static tree clobber_vars_r (tree *, int *, void *);
static void compute_alias_sets (void);
static bool may_alias_p (tree, HOST_WIDE_INT, tree, HOST_WIDE_INT);
static bool may_access_global_mem_p (tree);
--- 123,128 ----
*************** static void add_may_alias (tree, tree);
*** 140,146 ****
static int get_call_flags (tree);
static void find_hidden_use_vars (tree);
static tree find_hidden_use_vars_r (tree *, int *, void *);
!
/* Global declarations. */
--- 139,147 ----
static int get_call_flags (tree);
static void find_hidden_use_vars (tree);
static tree find_hidden_use_vars_r (tree *, int *, void *);
! #if 0
! static void remove_hidden_vars_from (varray_type, bool);
! #endif
/* Global declarations. */
*************** get_stmt_operands (tree stmt)
*** 176,188 ****
abort ();
#endif
! if (IS_EMPTY_STMT (stmt) || stmt == error_mark_node)
return;
/* If the statement has not been modified, the operands are still valid. */
if (!stmt_modified_p (stmt))
return;
ann = get_stmt_ann (stmt);
/* Remove any existing operands as they will be scanned again. */
--- 177,196 ----
abort ();
#endif
! /* Ignore empty and error statements. */
! if (IS_EMPTY_STMT (stmt) || TREE_CODE (stmt) == ERROR_MARK)
return;
/* If the statement has not been modified, the operands are still valid. */
if (!stmt_modified_p (stmt))
return;
+ #if defined ENABLE_CHECKING
+ /* non-GIMPLE statements should not appear here. */
+ if (TREE_NOT_GIMPLE (stmt))
+ abort ();
+ #endif
+
ann = get_stmt_ann (stmt);
/* Remove any existing operands as they will be scanned again. */
*************** get_expr_operands (tree stmt, tree *expr
*** 272,277 ****
--- 280,291 ----
if (expr == NULL || expr == error_mark_node)
return;
+ #if defined ENABLE_CHECKING
+ /* non-GIMPLE expressions should not appear here. */
+ if (TREE_NOT_GIMPLE (expr))
+ abort ();
+ #endif
+
code = TREE_CODE (expr);
class = TREE_CODE_CLASS (code);
*************** get_expr_operands (tree stmt, tree *expr
*** 314,339 ****
expr = *expr_p;
}
- /* If this reference is associated with a non GIMPLE expression, then we
- mark the statement non GIMPLE and recursively clobber every
- variable referenced by STMT. FIXME: TREE_NOT_GIMPLE must die. */
- if (stmt && TREE_NOT_GIMPLE (expr))
- {
- struct clobber_data_d cd;
- mark_not_gimple (&stmt);
- cd.stmt = stmt;
- cd.prev_vops = prev_vops;
- walk_tree (&stmt, clobber_vars_r, (void *) &cd, NULL);
- return;
- }
-
- /* If the parent statement is marked not-gimple, don't do anything. This
- means that in a previous iteration we encountered a non-gimple
- sub-expression which already clobbered all the variables in the
- statement. FIXME: TREE_NOT_GIMPLE must die. */
- if (stmt && TREE_NOT_GIMPLE (stmt))
- return;
-
/* If we found a variable, add it to DEFS or USES depending on the
operand flags. */
if (SSA_VAR_P (expr))
--- 328,333 ----
*************** get_expr_operands (tree stmt, tree *expr
*** 491,498 ****
VOPS to avoid optimizations messing it up. */
if (code == VA_ARG_EXPR)
{
! add_stmt_operand (&TREE_OPERAND (expr, 0), stmt, opf_is_def|opf_force_vop,
! prev_vops);
return;
}
--- 485,491 ----
VOPS to avoid optimizations messing it up. */
if (code == VA_ARG_EXPR)
{
! add_stmt_operand (&TREE_OPERAND (expr, 0), stmt, opf_is_def, prev_vops);
return;
}
*************** static void
*** 546,552 ****
add_stmt_operand (tree *var_p, tree stmt, int flags, voperands_t prev_vops)
{
bool is_scalar;
! tree var;
varray_type aliases;
size_t i;
stmt_ann_t s_ann;
--- 539,545 ----
add_stmt_operand (tree *var_p, tree stmt, int flags, voperands_t prev_vops)
{
bool is_scalar;
! tree var, sym;
varray_type aliases;
size_t i;
stmt_ann_t s_ann;
*************** add_stmt_operand (tree *var_p, tree stmt
*** 580,595 ****
if (!is_scalar && !DECL_P (var))
var = get_virtual_var (var);
! /* If VAR is not a variable, do nothing. */
if (var == NULL_TREE || !SSA_VAR_P (var))
return;
! v_ann = var_ann (TREE_CODE (var) == SSA_NAME ? SSA_NAME_VAR (var) : var);
! /* FIXME: Currently, objects in static storage are always treated as
! virtual operands. */
! if (decl_function_context (!DECL_P (var) ? get_base_symbol (var) : var) == 0
! || TREE_STATIC ((!DECL_P (var) ? get_base_symbol (var) : var)))
flags |= opf_force_vop;
/* If the variable is an alias tag, it means that its address has been
--- 573,602 ----
if (!is_scalar && !DECL_P (var))
var = get_virtual_var (var);
! /* If VAR is not a variable that we care to optimize, do nothing. */
if (var == NULL_TREE || !SSA_VAR_P (var))
return;
! sym = get_base_symbol (var);
! v_ann = var_ann (sym);
! /* FIXME: We currently refuse to optimize variables that have hidden uses
! (variables used in VLA declarations, MD builtin calls and variables
! from the parent function in nested functions). This is because not
! all uses of these variables are exposed in the IL or the statements
! that reference them are not in GIMPLE form. If that's the case, mark
! the statement as having volatile operands and return. */
! if (v_ann->has_hidden_use)
! {
! s_ann->has_volatile_ops = 1;
! return;
! }
!
! /* Globals, local statics and variables referenced in VA_ARG_EXPR are
! always accessed using virtual operands. */
! if (decl_function_context (sym) == 0
! || TREE_STATIC (sym)
! || v_ann->is_in_va_arg_expr)
flags |= opf_force_vop;
/* If the variable is an alias tag, it means that its address has been
*************** add_immediate_use (tree stmt, tree use_s
*** 1159,1165 ****
}
if (ann->df->immediate_uses == NULL)
! VARRAY_GENERIC_PTR_INIT (ann->df->immediate_uses, 10, "immediate_uses");
VARRAY_PUSH_TREE (ann->df->immediate_uses, use_stmt);
}
--- 1166,1172 ----
}
if (ann->df->immediate_uses == NULL)
! VARRAY_TREE_INIT (ann->df->immediate_uses, 10, "immediate_uses");
VARRAY_PUSH_TREE (ann->df->immediate_uses, use_stmt);
}
*************** dump_variable (FILE *file, tree var)
*** 1381,1386 ****
--- 1388,1396 ----
if (ann->is_stored)
fprintf (file, ", is stored");
+ if (ann->is_in_va_arg_expr)
+ fprintf (file, ", is used in va_arg");
+
if (ann->may_aliases)
{
fprintf (file, ", may aliases: ");
*************** collect_dfa_stats_r (tree *tp, int *walk
*** 1697,1733 ****
}
! /* Callback for walk_tree, create may-def/may-use references for every
! declaration node and compound reference found under a given tree node
! TP. */
! static tree
! clobber_vars_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
! void *data)
{
! enum tree_code code = TREE_CODE (*tp);
! /* Add every *_DECL node to VDEFS and VUSES. */
! if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
{
! struct clobber_data_d *cd = (struct clobber_data_d *) data;
! add_vuse (*tp, cd->stmt, cd->prev_vops);
! add_vdef (*tp, cd->stmt, cd->prev_vops);
}
! return NULL;
}
! /*---------------------------------------------------------------------------
! Aliasing
! ---------------------------------------------------------------------------*/
! /* Compute may-alias information for every variable referenced in the
! program. Note that in the absence of points-to analysis
! (-ftree-points-to), this may compute a much bigger set than necessary. */
void
! compute_may_aliases (tree fndecl)
{
static htab_t vars_found;
basic_block bb;
--- 1707,1761 ----
}
! /*---------------------------------------------------------------------------
! Aliasing
! ---------------------------------------------------------------------------*/
! /* Compute may-alias information for every variable referenced in function
! FNDECL. Note that in the absence of points-to analysis
! (-ftree-points-to), this may compute a much bigger set than necessary. */
! void
! compute_may_aliases (tree fndecl ATTRIBUTE_UNUSED)
{
! timevar_push (TV_TREE_MAY_ALIAS);
! if (flag_tree_points_to != PTA_NONE)
{
! timevar_push (TV_TREE_PTA);
! create_alias_vars (fndecl);
! timevar_pop (TV_TREE_PTA);
}
! /* Compute alias sets. */
! compute_alias_sets ();
!
! if (flag_tree_points_to != PTA_NONE)
! {
! timevar_push (TV_TREE_PTA);
! delete_alias_vars ();
! timevar_pop (TV_TREE_PTA);
! }
!
! /* Deallocate memory used by aliasing data structures. */
! addressable_vars = NULL;
! pointers = NULL;
!
! timevar_pop (TV_TREE_MAY_ALIAS);
}
! /* Find all the variables referenced in function FNDECL. This function
! builds the global arrays REFERENCED_VARS and CALL_CLOBBERED_VARS. It
! also builds the local arrays ADDRESSABLE_VARS and POINTERS used for
! alias analysis.
!
! Note that this function does not look for statement operands, it simply
! determines what variables are referenced in the program and detects
! various attributes for each variable used by alias analysis and the
! optimizer. */
void
! find_referenced_vars (tree fndecl)
{
static htab_t vars_found;
basic_block bb;
*************** compute_may_aliases (tree fndecl)
*** 1735,1741 ****
struct walk_state walk_state;
tree block;
! timevar_push (TV_TREE_MAY_ALIAS);
/* Walk the lexical blocks in the function looking for variables that may
have been used to declare VLAs and for nested functions. Both
--- 1763,1770 ----
struct walk_state walk_state;
tree block;
! VARRAY_GENERIC_PTR_INIT (addressable_vars, 20, "addressable_vars");
! VARRAY_GENERIC_PTR_INIT (pointers, 20, "pointers");
/* Walk the lexical blocks in the function looking for variables that may
have been used to declare VLAs and for nested functions. Both
*************** compute_may_aliases (tree fndecl)
*** 1751,1795 ****
block = BLOCK_CHAIN (block);
}
- VARRAY_GENERIC_PTR_INIT (addressable_vars, 20, "addressable_vars");
- VARRAY_GENERIC_PTR_INIT (pointers, 20, "pointers");
-
- /* Hash table of all the objects the SSA builder needs to be aware of. */
vars_found = htab_create (50, htab_hash_pointer, htab_eq_pointer, NULL);
!
! if (flag_tree_points_to != PTA_NONE)
! {
! timevar_push (TV_TREE_PTA);
! create_alias_vars (fndecl);
! timevar_pop (TV_TREE_PTA);
! }
!
walk_state.vars_found = vars_found;
- walk_state.is_store = 0;
- walk_state.is_indirect_ref = 0;
- walk_state.is_asm_expr = 0;
- /* Find all the variables referenced in the function. */
FOR_EACH_BB (bb)
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
! walk_tree (bsi_stmt_ptr (si), find_vars_r, &walk_state, NULL);
! htab_delete (vars_found);
! compute_alias_sets ();
!
! if (flag_tree_points_to != PTA_NONE)
! {
! timevar_push (TV_TREE_PTA);
! delete_alias_vars ();
! timevar_pop (TV_TREE_PTA);
! }
! /* Deallocate memory used by aliasing data structures. */
! addressable_vars = NULL;
! pointers = NULL;
! timevar_pop (TV_TREE_MAY_ALIAS);
}
--- 1780,1844 ----
block = BLOCK_CHAIN (block);
}
vars_found = htab_create (50, htab_hash_pointer, htab_eq_pointer, NULL);
! memset (&walk_state, 0, sizeof (walk_state));
walk_state.vars_found = vars_found;
FOR_EACH_BB (bb)
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
! {
! tree *stmt_p = bsi_stmt_ptr (si);
! /* Propagate non-GIMPLE attribute into the statement. FIXME:
! The only statements that are not in GIMPLE form are calls to MD
! builtins. Propagate the non-GIMPLE attribute from the RHS of
! assignments into the statement, if needed. */
! if (TREE_CODE (*stmt_p) == MODIFY_EXPR
! && TREE_CODE (TREE_OPERAND (*stmt_p, 1)) == CALL_EXPR
! && TREE_NOT_GIMPLE (TREE_OPERAND (*stmt_p, 1)))
! {
! mark_not_gimple (stmt_p);
! /* Prevent get_stmt_operands() from ever dealing with this
! statement. */
! unmodify_stmt (*stmt_p);
! }
! /* A CALL_EXPR may also appear inside a RETURN_EXPR. */
! if (TREE_CODE (*stmt_p) == RETURN_EXPR)
! {
! tree expr = TREE_OPERAND (*stmt_p, 0);
! if (expr
! && TREE_CODE (expr) == MODIFY_EXPR
! && TREE_CODE (TREE_OPERAND (expr, 1)) == CALL_EXPR
! && TREE_NOT_GIMPLE (TREE_OPERAND (expr, 1)))
! {
! mark_not_gimple (stmt_p);
! /* Prevent get_stmt_operands() from ever dealing with this
! statement. */
! unmodify_stmt (*stmt_p);
! }
! }
! if (TREE_NOT_GIMPLE (*stmt_p))
! walk_state.is_not_gimple = 1;
! walk_tree (stmt_p, find_vars_r, &walk_state, NULL);
! walk_state.is_not_gimple = 0;
! }
!
! htab_delete (vars_found);
!
! #if 0
! /* Purge the arrays of variables. Variables that have hidden uses must
! be removed so that the optimizers don't do anything with them. Note
! that this can't be done while looking for variables because it may not
! be obvious that a variable has hidden uses until it's found inside a
! VLA declaration or an MD built-in call. */
! remove_hidden_vars_from (referenced_vars, false);
! remove_hidden_vars_from (call_clobbered_vars, false);
! remove_hidden_vars_from (addressable_vars, true);
! remove_hidden_vars_from (pointers, true);
! #endif
}
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2216,2222 ****
{
tree t = *tp;
struct walk_state *walk_state = (struct walk_state *)data;
! int saved_is_store = walk_state->is_store;
/* Type and constant nodes have no interesting children. Ignore them. */
if (TYPE_P (t) || TREE_CODE_CLASS (TREE_CODE (t)) == 'c')
--- 2265,2275 ----
{
tree t = *tp;
struct walk_state *walk_state = (struct walk_state *)data;
!
! #if defined ENABLE_CHECKING
! if (TREE_NOT_GIMPLE (*tp) && walk_state->is_not_gimple == 0)
! abort ();
! #endif
/* Type and constant nodes have no interesting children. Ignore them. */
if (TYPE_P (t) || TREE_CODE_CLASS (TREE_CODE (t)) == 'c')
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2238,2261 ****
if (TREE_CODE (t) == MODIFY_EXPR)
{
walk_state->is_store = 1;
! walk_tree (&TREE_OPERAND (t, 0), find_vars_r, data, NULL);
walk_state->is_store = 0;
! walk_tree (&TREE_OPERAND (t, 1), find_vars_r, data, NULL);
! walk_state->is_store = saved_is_store;
/* If this is an assignment to a pointer and the RHS may point to
! global memory, mark the pointer on the LHS. FIXME: This causes a
! second traversal of the RHS of the assignment, we should set a bit
! in WALK_STATE as we walk the RHS. */
! if (SSA_VAR_P (TREE_OPERAND (t, 0))
! && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0)))
! && may_access_global_mem_p (TREE_OPERAND (t, 1)))
! set_may_point_to_global_mem (TREE_OPERAND (t, 0));
/* If either side makes volatile references, mark the statement. */
! if (TREE_THIS_VOLATILE (TREE_OPERAND (t, 0))
! || TREE_THIS_VOLATILE (TREE_OPERAND (t, 1)))
get_stmt_ann (t)->has_volatile_ops = 1;
return t;
--- 2291,2314 ----
if (TREE_CODE (t) == MODIFY_EXPR)
{
+ tree *lhs_p = &TREE_OPERAND (t, 0);
+ tree *rhs_p = &TREE_OPERAND (t, 1);
+
walk_state->is_store = 1;
! walk_tree (lhs_p, find_vars_r, walk_state, NULL);
walk_state->is_store = 0;
! walk_tree (rhs_p, find_vars_r, walk_state, NULL);
/* If this is an assignment to a pointer and the RHS may point to
! global memory, mark the pointer on the LHS. */
! if (SSA_VAR_P (*lhs_p)
! && POINTER_TYPE_P (TREE_TYPE (*lhs_p))
! && may_access_global_mem_p (*rhs_p))
! set_may_point_to_global_mem (*lhs_p);
/* If either side makes volatile references, mark the statement. */
! if (TREE_THIS_VOLATILE (*lhs_p)
! || TREE_THIS_VOLATILE (*rhs_p))
get_stmt_ann (t)->has_volatile_ops = 1;
return t;
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2264,2302 ****
{
walk_state->is_asm_expr = 1;
walk_state->is_store = 1;
! walk_tree (&ASM_OUTPUTS (t), find_vars_r, data, NULL);
! walk_tree (&ASM_CLOBBERS (t), find_vars_r, data, NULL);
walk_state->is_store = 0;
! walk_tree (&ASM_INPUTS (t), find_vars_r, data, NULL);
! walk_state->is_store = saved_is_store;
walk_state->is_asm_expr = 0;
return t;
}
else if (TREE_CODE (t) == INDIRECT_REF)
{
walk_state->is_indirect_ref = 1;
! walk_tree (&TREE_OPERAND (t, 0), find_vars_r, data, NULL);
/* INDIRECT_REF nodes cannot be nested in GIMPLE, so there is no need
of saving/restoring the state. */
walk_state->is_indirect_ref = 0;
return NULL_TREE;
}
! if (SSA_VAR_P (*tp))
{
! add_referenced_var (*tp, walk_state);
return NULL_TREE;
}
/* A function call that receives pointer arguments may dereference them.
For every pointer 'p' in the argument to the function call, add a
reference to '*p'. */
! if (TREE_CODE (*tp) == CALL_EXPR)
{
tree op;
! int call_flags = get_call_flags (*tp);
! for (op = TREE_OPERAND (*tp, 1); op; op = TREE_CHAIN (op))
{
tree arg = TREE_VALUE (op);
if (SSA_VAR_P (arg) && POINTER_TYPE_P (TREE_TYPE (arg)))
--- 2317,2365 ----
{
walk_state->is_asm_expr = 1;
walk_state->is_store = 1;
! walk_tree (&ASM_OUTPUTS (t), find_vars_r, walk_state, NULL);
! walk_tree (&ASM_CLOBBERS (t), find_vars_r, walk_state, NULL);
walk_state->is_store = 0;
! walk_tree (&ASM_INPUTS (t), find_vars_r, walk_state, NULL);
walk_state->is_asm_expr = 0;
return t;
}
else if (TREE_CODE (t) == INDIRECT_REF)
{
walk_state->is_indirect_ref = 1;
! walk_tree (&TREE_OPERAND (t, 0), find_vars_r, walk_state, NULL);
!
/* INDIRECT_REF nodes cannot be nested in GIMPLE, so there is no need
of saving/restoring the state. */
walk_state->is_indirect_ref = 0;
+
+ /* Keep iterating, because an INDIRECT_REF node may have more
+ references inside (structures and arrays). */
return NULL_TREE;
}
+ else if (TREE_CODE (t) == VA_ARG_EXPR)
+ {
+ walk_state->is_va_arg_expr = 1;
+ walk_tree (&TREE_OPERAND (t, 0), find_vars_r, walk_state, NULL);
+ walk_state->is_va_arg_expr = 0;
+ return t;
+ }
! if (SSA_VAR_P (t))
{
! add_referenced_var (t, walk_state);
return NULL_TREE;
}
/* A function call that receives pointer arguments may dereference them.
For every pointer 'p' in the argument to the function call, add a
reference to '*p'. */
! if (TREE_CODE (t) == CALL_EXPR && walk_state->is_not_gimple == 0)
{
tree op;
! int call_flags = get_call_flags (t);
! for (op = TREE_OPERAND (t, 1); op; op = TREE_CHAIN (op))
{
tree arg = TREE_VALUE (op);
if (SSA_VAR_P (arg) && POINTER_TYPE_P (TREE_TYPE (arg)))
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2314,2322 ****
consider this call as a store operation to .GLOBAL_VAR. */
if (!(call_flags & (ECF_CONST | ECF_PURE | ECF_NORETURN)))
walk_state->is_store = 1;
-
add_referenced_var (global_var, walk_state);
! walk_state->is_store = saved_is_store;
}
return NULL_TREE;
--- 2377,2384 ----
consider this call as a store operation to .GLOBAL_VAR. */
if (!(call_flags & (ECF_CONST | ECF_PURE | ECF_NORETURN)))
walk_state->is_store = 1;
add_referenced_var (global_var, walk_state);
! walk_state->is_store = 0;
}
return NULL_TREE;
*************** add_referenced_var (tree var, struct wal
*** 2342,2347 ****
--- 2404,2414 ----
v_ann = get_var_ann (var);
+ /* If the variable has already been flagged as having hidden uses,
+ ignore it. */
+ if (v_ann->has_hidden_use)
+ return;
+
slot = htab_find_slot (vars_found, (void *) var, INSERT);
if (*slot == NULL)
{
*************** add_referenced_var (tree var, struct wal
*** 2378,2384 ****
alias_map = ggc_alloc (sizeof (*alias_map));
alias_map->var = var;
alias_map->set = get_alias_set (var);
! VARRAY_PUSH_GENERIC_PTR (addressable_vars, (void *) alias_map);
}
/* Addressable variables, memory tags and static locals may be used
--- 2445,2451 ----
alias_map = ggc_alloc (sizeof (*alias_map));
alias_map->var = var;
alias_map->set = get_alias_set (var);
! VARRAY_PUSH_GENERIC_PTR (addressable_vars, alias_map);
}
/* Addressable variables, memory tags and static locals may be used
*************** add_referenced_var (tree var, struct wal
*** 2401,2406 ****
--- 2468,2485 ----
if (walk_state->is_store)
v_ann->is_stored = 1;
+ /* If VAR is being referenced inside a non-GIMPLE tree, mark it as having
+ hidden uses. Currently, this is used for MD built-ins, which are not
+ gimplified and cannot be optimized. FIXME: long term all trees must
+ be in GIMPLE form. */
+ if (walk_state->is_not_gimple)
+ v_ann->has_hidden_use = 1;
+
+ /* If VAR is being referenced inside a VA_ARG_EXPR, mark it so that all
+ operands to VAR are always virtual. */
+ if (walk_state->is_va_arg_expr)
+ v_ann->is_in_va_arg_expr = 1;
+
/* If the variable is a pointer being clobbered by an ASM_EXPR, the
pointer may end up pointing to global memory. */
if (POINTER_TYPE_P (TREE_TYPE (var))
*************** get_memory_tag_for (tree ptr)
*** 2483,2489 ****
alias_map = ggc_alloc (sizeof (*alias_map));
alias_map->var = ptr;
alias_map->set = tag_set;
! VARRAY_PUSH_GENERIC_PTR (pointers, (void *) alias_map);
}
return tag;
--- 2562,2568 ----
alias_map = ggc_alloc (sizeof (*alias_map));
alias_map->var = ptr;
alias_map->set = tag_set;
! VARRAY_PUSH_GENERIC_PTR (pointers, alias_map);
}
return tag;
*************** create_global_var (void)
*** 2623,2625 ****
--- 2702,2746 ----
TREE_THIS_VOLATILE (global_var) = 1;
TREE_ADDRESSABLE (global_var) = 0;
}
+
+ #if 0
+ /* Remove all the variables marked with the has_hidden_use attribute from
+ ARRAY. IS_ALIAS_MAP is true when ARRAY is an array of struct
+ alias_map_d objects. */
+
+ static void
+ remove_hidden_vars_from (varray_type array, bool is_alias_map)
+ {
+ size_t i;
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (array); i++)
+ {
+ tree var = (is_alias_map)
+ ? ((struct alias_map_d *) VARRAY_GENERIC_PTR (array, i))->var
+ : VARRAY_TREE (array, i);
+
+ if (0)
+ {
+ size_t len = VARRAY_ACTIVE_SIZE (array);
+ if (i < len - 1)
+ {
+ if (is_alias_map)
+ VARRAY_GENERIC_PTR (array, i) = VARRAY_GENERIC_PTR (array,
+ len - 1);
+ else
+ VARRAY_TREE (array, i) = VARRAY_TREE (array, len - 1);
+
+ /* Make sure we visit the element we just moved from the end
+ of the array. */
+ i--;
+ }
+
+ fprintf (stderr, "%s(%d): Removed variable %s from array %s\n",
+ input_filename, input_line, get_name (var), array->name);
+ VARRAY_POP (array);
+ }
+ }
+ }
+ #endif
+
+ #include "gt-tree-dfa.h"
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.100
diff -d -u -p -c -r1.1.4.100 tree-flow.h
*** tree-flow.h 5 Aug 2003 15:17:57 -0000 1.1.4.100
--- tree-flow.h 7 Aug 2003 18:51:16 -0000
*************** struct var_ann_d GTY(())
*** 95,100 ****
--- 95,106 ----
applied. We set this when translating out of SSA form. */
unsigned used : 1;
+ /* Nonzero if this variable is used as the argument to VA_ARG_EXPR. This
+ forces all operands to this variable to always be virtual, because
+ VA_ARG_EXPR both reads and modifies its argument and it can't be
+ modified by optimizations. */
+ unsigned is_in_va_arg_expr;
+
/* A VAR_DECL used to associated pointers with the memory location that
they are pointing to. If IS_MEM_TAG is nonzero, then MEM_TAG is the
pointer associated to this memory tag. If IS_MEM_TAG is zero, then
*************** extern int could_trap_p (tree);
*** 412,417 ****
--- 418,424 ----
extern basic_block tree_split_edge (edge);
/* In tree-dfa.c */
+ void find_referenced_vars (tree);
extern void get_stmt_operands (tree);
extern var_ann_t create_var_ann (tree);
extern stmt_ann_t create_stmt_ann (tree);
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-optimize.c,v
retrieving revision 1.1.4.42
diff -d -u -p -c -r1.1.4.42 tree-optimize.c
*** tree-optimize.c 5 Aug 2003 16:10:53 -0000 1.1.4.42
--- tree-optimize.c 7 Aug 2003 18:51:16 -0000
*************** optimize_function_tree (tree fndecl)
*** 69,74 ****
--- 69,77 ----
/* Initialize common SSA structures. */
init_tree_ssa ();
+ /* Find all the variables referenced in the function. */
+ find_referenced_vars (fndecl);
+
/* Compute aliasing information for all the variables referenced in
the function. */
compute_may_aliases (fndecl);
Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-ccp.c,v
retrieving revision 1.1.2.82
diff -d -u -p -c -r1.1.2.82 tree-ssa-ccp.c
*** tree-ssa-ccp.c 5 Aug 2003 13:14:30 -0000 1.1.2.82
--- tree-ssa-ccp.c 7 Aug 2003 18:51:17 -0000
*************** static varray_type cfg_edges;
*** 98,104 ****
has changed. SSA edges are def-use edges in the SSA web. For each
edge, we store the definition statement or PHI node D. The destination
nodes that need to be visited are accessed using immediate_uses (D). */
! static varray_type ssa_edges;
static void initialize (void);
static void finalize (void);
--- 98,104 ----
has changed. SSA edges are def-use edges in the SSA web. For each
edge, we store the definition statement or PHI node D. The destination
nodes that need to be visited are accessed using immediate_uses (D). */
! static GTY(()) varray_type ssa_edges;
static void initialize (void);
static void finalize (void);
*************** tree_ssa_ccp (tree fndecl)
*** 154,161 ****
if (VARRAY_ACTIVE_SIZE (cfg_edges) > 0)
{
/* Pull the next block to simulate off the worklist. */
! basic_block dest_block;
! dest_block = ((edge)VARRAY_TOP_GENERIC_PTR (cfg_edges))->dest;
VARRAY_POP (cfg_edges);
simulate_block (dest_block);
}
--- 154,160 ----
if (VARRAY_ACTIVE_SIZE (cfg_edges) > 0)
{
/* Pull the next block to simulate off the worklist. */
! basic_block dest_block = VARRAY_TOP_EDGE (cfg_edges)->dest;
VARRAY_POP (cfg_edges);
simulate_block (dest_block);
}
*************** add_control_edge (edge e)
*** 697,703 ****
return;
e->flags |= EDGE_EXECUTABLE;
! VARRAY_PUSH_GENERIC_PTR (cfg_edges, e);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Adding edge (%d -> %d) to worklist\n\n",
--- 696,702 ----
return;
e->flags |= EDGE_EXECUTABLE;
! VARRAY_PUSH_EDGE (cfg_edges, e);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Adding edge (%d -> %d) to worklist\n\n",
*************** initialize (void)
*** 1032,1045 ****
}
! VARRAY_GENERIC_PTR_INIT (cfg_edges, 20, "cfg_edges");
/* Seed the algorithm by adding the successors of the entry block to the
edge worklist. */
for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
{
e->flags |= EDGE_EXECUTABLE;
! VARRAY_PUSH_GENERIC_PTR (cfg_edges, e);
}
}
--- 1031,1044 ----
}
! VARRAY_EDGE_INIT (cfg_edges, 20, "cfg_edges");
/* Seed the algorithm by adding the successors of the entry block to the
edge worklist. */
for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
{
e->flags |= EDGE_EXECUTABLE;
! VARRAY_PUSH_EDGE (cfg_edges, e);
}
}
*************** get_strlen (tree arg)
*** 1585,1587 ****
--- 1584,1588 ----
return NULL_TREE;
}
+
+ #include "gt-tree-ssa-ccp.h"
Index: tree-ssa-dce.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dce.c,v
retrieving revision 1.1.2.51
diff -d -u -p -c -r1.1.2.51 tree-ssa-dce.c
*** tree-ssa-dce.c 5 Aug 2003 19:20:49 -0000 1.1.2.51
--- tree-ssa-dce.c 7 Aug 2003 18:51:17 -0000
*************** need_to_preserve_store (tree var)
*** 201,210 ****
if (may_alias_global_mem_p (sym))
return true;
/* If SYM is used in some way that we can not readily see in the IL, then
we need to preserve it. FIXME: Long term this needs to go away. */
if (has_hidden_use (sym))
! return true;
return false;
}
--- 201,212 ----
if (may_alias_global_mem_p (sym))
return true;
+ #if 1
/* If SYM is used in some way that we can not readily see in the IL, then
we need to preserve it. FIXME: Long term this needs to go away. */
if (has_hidden_use (sym))
! abort ();
! #endif
return false;
}
Index: tree-ssa-live.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-live.c,v
retrieving revision 1.1.2.14
diff -d -u -p -c -r1.1.2.14 tree-ssa-live.c
*** tree-ssa-live.c 31 Jul 2003 12:10:46 -0000 1.1.2.14
--- tree-ssa-live.c 7 Aug 2003 18:51:17 -0000
*************** type_var_init (var_map map)
*** 878,888 ****
for (x = num_partitions - 1; x >= 0; x--)
{
t = partition_to_var (map, x);
/* Disallow coalescing of these types of variables. */
! if (!t || TREE_THIS_VOLATILE (t) || TREE_CODE (t) == RESULT_DECL
|| TREE_CODE (t) == PARM_DECL
! || (DECL_P (t) && (DECL_REGISTER (t) || !DECL_ARTIFICIAL (t)
! || DECL_RTL_SET_P (t) || has_hidden_use (t))))
continue;
p = var_to_partition (map, t);
--- 878,895 ----
for (x = num_partitions - 1; x >= 0; x--)
{
t = partition_to_var (map, x);
+ if (has_hidden_use (t))
+ abort ();
+
/* Disallow coalescing of these types of variables. */
! if (!t
! || TREE_THIS_VOLATILE (t)
! || TREE_CODE (t) == RESULT_DECL
|| TREE_CODE (t) == PARM_DECL
! || (DECL_P (t)
! && (DECL_REGISTER (t)
! || !DECL_ARTIFICIAL (t)
! || DECL_RTL_SET_P (t))))
continue;
p = var_to_partition (map, t);
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.114
diff -d -u -p -c -r1.1.4.114 tree-ssa.c
*** tree-ssa.c 5 Aug 2003 15:17:58 -0000 1.1.4.114
--- tree-ssa.c 7 Aug 2003 18:51:17 -0000
*************** static htab_t def_blocks;
*** 77,83 ****
/* Structure to map a variable VAR to the set of blocks that contain
definitions for VAR. */
! struct def_blocks_d
{
tree var;
bitmap def_blocks;
--- 77,83 ----
/* Structure to map a variable VAR to the set of blocks that contain
definitions for VAR. */
! struct GTY(()) def_blocks_d
{
tree var;
bitmap def_blocks;
*************** static htab_t currdefs;
*** 93,99 ****
/* Structure to map variables to values. It's used to keep track of the
current reaching definition, constant values and variable copies while
renaming. */
! struct var_value_d
{
tree var;
tree value;
--- 93,99 ----
/* Structure to map variables to values. It's used to keep track of the
current reaching definition, constant values and variable copies while
renaming. */
! struct GTY(()) var_value_d
{
tree var;
tree value;
*************** static hashval_t def_blocks_hash (const
*** 161,167 ****
static int def_blocks_eq (const void *, const void *);
static hashval_t var_value_hash (const void *);
static int var_value_eq (const void *, const void *);
- static void def_blocks_free (void *);
static int debug_def_blocks_r (void **, void *);
static struct def_blocks_d *get_def_blocks_for (tree);
static void htab_statistics (FILE *, htab_t);
--- 161,166 ----
*************** rewrite_into_ssa (tree fndecl, sbitmap v
*** 297,307 ****
/* Allocate memory for the DEF_BLOCKS hash table. */
def_blocks = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars),
! def_blocks_hash, def_blocks_eq, def_blocks_free);
/* Allocate memory for the CURRDEFS hash table. */
currdefs = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars),
! var_value_hash, var_value_eq, free);
/* Allocate memory for the GLOBALS bitmap which will indicate which
variables are live across basic block boundaries. Note that this
--- 296,306 ----
/* Allocate memory for the DEF_BLOCKS hash table. */
def_blocks = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars),
! def_blocks_hash, def_blocks_eq, NULL);
/* Allocate memory for the CURRDEFS hash table. */
currdefs = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars),
! var_value_hash, var_value_eq, NULL);
/* Allocate memory for the GLOBALS bitmap which will indicate which
variables are live across basic block boundaries. Note that this
*************** rewrite_into_ssa (tree fndecl, sbitmap v
*** 393,399 ****
for (i = 0; i < n_basic_blocks; i++)
BITMAP_XFREE (dfs[i]);
free (dfs);
! free (globals);
htab_delete (def_blocks);
htab_delete (currdefs);
if (vars == NULL)
--- 392,398 ----
for (i = 0; i < n_basic_blocks; i++)
BITMAP_XFREE (dfs[i]);
free (dfs);
! sbitmap_free (globals);
htab_delete (def_blocks);
htab_delete (currdefs);
if (vars == NULL)
*************** mark_def_sites (sbitmap globals)
*** 626,632 ****
}
}
! free (kills);
}
/* Mark block BB as the definition site for variable VAR. */
--- 625,631 ----
}
}
! sbitmap_free (kills);
}
/* Mark block BB as the definition site for variable VAR. */
*************** set_def_block (tree var, basic_block bb)
*** 642,651 ****
slot = htab_find_slot (def_blocks, (void *) &db, INSERT);
if (*slot == NULL)
{
! db_p = xmalloc (sizeof (*db_p));
db_p->var = var;
! db_p->def_blocks = BITMAP_XMALLOC ();
! db_p->livein_blocks = BITMAP_XMALLOC ();
*slot = (void *) db_p;
}
else
--- 641,650 ----
slot = htab_find_slot (def_blocks, (void *) &db, INSERT);
if (*slot == NULL)
{
! db_p = ggc_alloc (sizeof (*db_p));
db_p->var = var;
! db_p->def_blocks = BITMAP_GGC_ALLOC ();
! db_p->livein_blocks = BITMAP_GGC_ALLOC ();
*slot = (void *) db_p;
}
else
*************** set_livein_block (tree var, basic_block
*** 668,677 ****
slot = htab_find_slot (def_blocks, (void *) &db, INSERT);
if (*slot == NULL)
{
! db_p = xmalloc (sizeof (*db_p));
db_p->var = var;
! db_p->def_blocks = BITMAP_XMALLOC ();
! db_p->livein_blocks = BITMAP_XMALLOC ();
*slot = (void *) db_p;
}
else
--- 667,676 ----
slot = htab_find_slot (def_blocks, (void *) &db, INSERT);
if (*slot == NULL)
{
! db_p = ggc_alloc (sizeof (*db_p));
db_p->var = var;
! db_p->def_blocks = BITMAP_GGC_ALLOC ();
! db_p->livein_blocks = BITMAP_GGC_ALLOC ();
*slot = (void *) db_p;
}
else
*************** insert_phi_nodes (bitmap *dfs, sbitmap g
*** 698,704 ****
timevar_push (TV_TREE_INSERT_PHI_NODES);
! VARRAY_GENERIC_PTR_INIT (def_maps, HOST_BITS_PER_WIDE_INT, "deferred_vars");
/* Array WORK_STACK is a stack of CFG blocks. Each block that contains
an assignment or PHI node will be pushed to this stack. */
--- 697,703 ----
timevar_push (TV_TREE_INSERT_PHI_NODES);
! VARRAY_GENERIC_PTR_INIT (def_maps, HOST_BITS_PER_WIDE_INT, "def_maps");
/* Array WORK_STACK is a stack of CFG blocks. Each block that contains
an assignment or PHI node will be pushed to this stack. */
*************** insert_phis_for_deferred_variables (varr
*** 1889,1895 ****
create_phi_node (var, BASIC_BLOCK (bb_index));
});
- BITMAP_XFREE (phi_insertion_points);
def_map->phi_insertion_points = NULL;
}
}
--- 1888,1893 ----
*************** insert_phi_nodes_for (tree var, bitmap *
*** 1908,1914 ****
if (def_map == NULL)
return;
! phi_insertion_points = BITMAP_XMALLOC ();
EXECUTE_IF_SET_IN_BITMAP (def_map->def_blocks, 0, bb_index,
{
--- 1906,1912 ----
if (def_map == NULL)
return;
! phi_insertion_points = BITMAP_GGC_ALLOC ();
EXECUTE_IF_SET_IN_BITMAP (def_map->def_blocks, 0, bb_index,
{
*************** insert_phi_nodes_for (tree var, bitmap *
*** 1981,1987 ****
create_phi_node (var, BASIC_BLOCK (bb_index));
});
! BITMAP_XFREE (phi_insertion_points);
}
/* Scan all the statements looking for symbols not in SSA form. If any are
--- 1979,1985 ----
create_phi_node (var, BASIC_BLOCK (bb_index));
});
! phi_insertion_points = NULL;
}
/* Scan all the statements looking for symbols not in SSA form. If any are
*************** register_new_def (tree var, tree def, va
*** 2181,2187 ****
/*---------------------------------------------------------------------------
Various helpers.
---------------------------------------------------------------------------*/
! /* Initialize DFA/SSA structures. */
void
init_tree_ssa (void)
--- 2179,2185 ----
/*---------------------------------------------------------------------------
Various helpers.
---------------------------------------------------------------------------*/
! /* Initialize global DFA and SSA structures. */
void
init_tree_ssa (void)
*************** init_tree_ssa (void)
*** 2189,2195 ****
next_ssa_version = 1;
VARRAY_TREE_INIT (referenced_vars, 20, "referenced_vars");
VARRAY_TREE_INIT (call_clobbered_vars, 20, "call_clobbered_vars");
! memset ((void *) &ssa_stats, 0, sizeof (ssa_stats));
global_var = NULL_TREE;
}
--- 2187,2193 ----
next_ssa_version = 1;
VARRAY_TREE_INIT (referenced_vars, 20, "referenced_vars");
VARRAY_TREE_INIT (call_clobbered_vars, 20, "call_clobbered_vars");
! memset (&ssa_stats, 0, sizeof (ssa_stats));
global_var = NULL_TREE;
}
*************** get_reaching_def (tree var)
*** 2273,2290 ****
}
- /* Free memory allocated for a <def, def_blocks> tuple. */
-
- static void
- def_blocks_free (void *p)
- {
- struct def_blocks_d *db_p = (struct def_blocks_d *) p;
- BITMAP_XFREE (db_p->def_blocks);
- BITMAP_XFREE (db_p->livein_blocks);
- free (p);
- }
-
-
/* Hashing and equality functions for DEF_BLOCKS. */
static hashval_t
--- 2271,2276 ----
*************** set_value_for (tree var, tree value, hta
*** 2385,2391 ****
slot = htab_find_slot (table, (void *) &vm, INSERT);
if (*slot == NULL)
{
! vm_p = xmalloc (sizeof *vm_p);
vm_p->var = var;
*slot = (void *) vm_p;
}
--- 2371,2377 ----
slot = htab_find_slot (table, (void *) &vm, INSERT);
if (*slot == NULL)
{
! vm_p = ggc_alloc (sizeof *vm_p);
vm_p->var = var;
*slot = (void *) vm_p;
}
*************** get_def_blocks_for (tree var)
*** 2404,2408 ****
struct def_blocks_d dm;
dm.var = var;
! return (struct def_blocks_d *) htab_find (def_blocks, (void *) &dm);
}
--- 2390,2396 ----
struct def_blocks_d dm;
dm.var = var;
! return (struct def_blocks_d *) htab_find (def_blocks, &dm);
}
+
+ #include "gt-tree-ssa.h"
Index: varray.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varray.c,v
retrieving revision 1.15.2.4
diff -d -u -p -c -r1.15.2.4 varray.c
*** varray.c 23 Jul 2003 17:00:02 -0000 1.15.2.4
--- varray.c 7 Aug 2003 18:51:17 -0000
*************** static const struct {
*** 57,62 ****
--- 57,63 ----
{ sizeof (struct const_equiv_data), 0 },
{ sizeof (struct basic_block_def *), 0 },
{ sizeof (struct elt_list *), 1 },
+ { sizeof (struct edge_def *), 0 },
};
/* Allocate a virtual array with NUM_ELEMENT elements, each of which is
Index: varray.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varray.h,v
retrieving revision 1.28.2.3
diff -d -u -p -c -r1.28.2.3 varray.h
*** varray.h 23 Jul 2003 17:00:02 -0000 1.28.2.3
--- varray.h 7 Aug 2003 18:51:17 -0000
*************** enum varray_data_enum {
*** 81,86 ****
--- 81,87 ----
VARRAY_DATA_CONST_EQUIV,
VARRAY_DATA_BB,
VARRAY_DATA_TE,
+ VARRAY_DATA_EDGE,
NUM_VARRAY_DATA
};
*************** typedef union varray_data_tag GTY (()) {
*** 126,131 ****
--- 127,134 ----
tag ("VARRAY_DATA_BB"))) bb[1];
struct elt_list *GTY ((length ("%0.num_elements"),
tag ("VARRAY_DATA_TE"))) te[1];
+ struct edge_def *GTY ((length ("%0.num_elements"), skip (""),
+ tag ("VARRAY_DATA_EDGE"))) e[1];
} varray_data;
/* Virtual array of pointers header. */
*************** extern varray_type varray_init (size_t,
*** 204,209 ****
--- 207,215 ----
#define VARRAY_ELT_LIST_INIT(va, num, name) \
va = varray_init (num, VARRAY_DATA_TE, name)
+ #define VARRAY_EDGE_INIT(va, num, name) \
+ va = varray_init (num, VARRAY_DATA_EDGE, name)
+
/* Free up memory allocated by the virtual array, but do not free any of the
elements involved. */
#define VARRAY_FREE(vp) \
*************** extern void varray_check_failed (varray_
*** 276,281 ****
--- 282,288 ----
#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)
+ #define VARRAY_EDGE(VA, N) VARRAY_CHECK (VA, N, e)
/* Push a new element on the end of VA, extending it if necessary. */
#define VARRAY_PUSH_CHAR(VA, X) VARRAY_PUSH (VA, c, X)
*************** extern void varray_check_failed (varray_
*** 297,302 ****
--- 304,310 ----
#define VARRAY_PUSH_REG(VA, X) VARRAY_PUSH (VA, reg, X)
#define VARRAY_PUSH_CONST_EQUIV(VA, X) VARRAY_PUSH (VA, const_equiv, X)
#define VARRAY_PUSH_BB(VA, X) VARRAY_PUSH (VA, bb, X)
+ #define VARRAY_PUSH_EDGE(VA, X) VARRAY_PUSH (VA, e, X)
/* Return the last element of VA. */
#define VARRAY_TOP_CHAR(VA) VARRAY_TOP (VA, c)
*************** extern void varray_check_failed (varray_
*** 318,322 ****
--- 326,331 ----
#define VARRAY_TOP_REG(VA) VARRAY_TOP (VA, reg)
#define VARRAY_TOP_CONST_EQUIV(VA) VARRAY_TOP (VA, const_equiv)
#define VARRAY_TOP_BB(VA) VARRAY_TOP (VA, bb)
+ #define VARRAY_TOP_EDGE(VA) VARRAY_TOP (VA, e)
#endif /* ! GCC_VARRAY_H */