This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: TREE_ADDRESSABLE problem
- From: Jan Hubicka <jh at suse dot cz>
- To: Jan Hubicka <hubicka at ucw dot cz>, gcc-patches at gcc dot gnu dot org
- Cc: Richard Henderson <rth at redhat dot com>, Jan Hubicka <jh at suse dot cz>,gcc at gcc dot gnu dot org, law at redhat dot com
- Date: Fri, 21 Nov 2003 01:57:36 +0100
- Subject: Re: TREE_ADDRESSABLE problem
- References: <20031119230256.GS11681@kam.mff.cuni.cz> <20031119232009.GF1138@redhat.com> <20031119232927.GX11681@kam.mff.cuni.cz> <20031119234619.GA1635@redhat.com> <20031120224311.GB341@atrey.karlin.mff.cuni.cz> <20031120231758.GC6106@redhat.com> <20031120232402.GC16923@atrey.karlin.mff.cuni.cz> <20031120155216.A1706@redhat.com> <20031121000037.GE16923@atrey.karlin.mff.cuni.cz>
> > On Fri, Nov 21, 2003 at 12:24:02AM +0100, Jan Hubicka wrote:
> > > However we need to ensure that VAR_DECLs won't be modified in some other
> > > ways by the optimizers?
> >
> > No idea.
> >
> > > Perhaps we want do both - duplicate var_decls and compute addressable
> > > flag as part of remove_useless_* or rewrite_into_ssa?
> >
> > I don't think so.
> >
> > It doesn't seem like it ought to be that difficult to just delay
> > compilation of any inline candidate until we've decided that we're
> > done with all inlining.
> >
> > Which is *much* more robust than copying things around.
>
> Actually copying things around would help me to implement the recursive
> inlining (ie inlinine recursive calls up to given depth so function
> growth to specified size).
>
> But I will definitly update the sorting routines to try first compile
> all functions we inlined into and then the inline candidate.
> However if we want to maintain the constraint that for non-recursive
> graphs we compile callees before caller, we end up needing copies from
> time to time.
>
> OK, for start I will implement the tracking of ADDR_EXPRs so we won't
> get tons of checking errors.
> find_referenced_vars looks like most plausible place to hook into.
Hi,
here is the patch, bootstrapped/regtested i386-linux together with
verify_stmts added past find_referenced_vars.
OK?
Honza
2003-11-21 Jan Hubicka <jh@suse.cz>
* tree-dfa.c (add_referenced_var): Add new argument in_addr_expr_p;
recompute TREE_ADDRESSABLE.
(find_referenced_vars): Update call.
(find_vars_r): Likewise.
(add_referenced_tmp_var): Likewise.
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.181
diff -c -3 -p -r1.1.4.181 tree-dfa.c
*** tree-dfa.c 19 Nov 2003 20:10:00 -0000 1.1.4.181
--- tree-dfa.c 21 Nov 2003 00:51:19 -0000
*************** static void add_call_read_ops (tree, vop
*** 133,139 ****
static void add_stmt_operand (tree *, tree, int, voperands_t);
static void add_immediate_use (tree, tree);
static tree find_vars_r (tree *, int *, void *);
! static void add_referenced_var (tree, struct walk_state *);
static tree get_memory_tag_for (tree);
static void compute_immediate_uses_for_phi (tree, bool (*)(tree));
static void compute_immediate_uses_for_stmt (tree, int, bool (*)(tree));
--- 133,139 ----
static void add_stmt_operand (tree *, tree, int, voperands_t);
static void add_immediate_use (tree, tree);
static tree find_vars_r (tree *, int *, void *);
! static void add_referenced_var (tree, struct walk_state *, bool);
static tree get_memory_tag_for (tree);
static void compute_immediate_uses_for_phi (tree, bool (*)(tree));
static void compute_immediate_uses_for_stmt (tree, int, bool (*)(tree));
*************** find_referenced_vars (tree fndecl)
*** 1977,1983 ****
if (walk_state.num_calls * num_call_clobbered_vars < n_calls * n_clobbers)
global_var = NULL_TREE;
else if (global_var)
! add_referenced_var (global_var, &walk_state);
}
htab_delete (vars_found);
--- 1977,1983 ----
if (walk_state.num_calls * num_call_clobbered_vars < n_calls * n_clobbers)
global_var = NULL_TREE;
else if (global_var)
! add_referenced_var (global_var, &walk_state, true);
}
htab_delete (vars_found);
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2464,2469 ****
--- 2464,2483 ----
return t;
}
+ else if (TREE_CODE (t) == ADDR_EXPR)
+ {
+ t = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) == ARRAY_REF
+ || TREE_CODE (t) == COMPONENT_REF
+ || TREE_CODE (t) == REALPART_EXPR
+ || TREE_CODE (t) == IMAGPART_EXPR)
+ t = TREE_OPERAND (t, 0);
+ if (SSA_VAR_P (t))
+ {
+ add_referenced_var (t, walk_state, true);
+ }
+ return NULL_TREE;
+ }
else if (TREE_CODE (t) == ASM_EXPR)
{
walk_state->is_asm_expr = 1;
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2491,2497 ****
if (SSA_VAR_P (t))
{
! add_referenced_var (t, walk_state);
return NULL_TREE;
}
--- 2506,2512 ----
if (SSA_VAR_P (t))
{
! add_referenced_var (t, walk_state, false);
return NULL_TREE;
}
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2512,2518 ****
&& !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (arg))))
{
walk_state->is_indirect_ref = 1;
! add_referenced_var (arg, walk_state);
walk_state->is_indirect_ref = 0;
}
}
--- 2527,2533 ----
&& !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (arg))))
{
walk_state->is_indirect_ref = 1;
! add_referenced_var (arg, walk_state, false);
walk_state->is_indirect_ref = 0;
}
}
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2538,2544 ****
assumes that VAR is a valid SSA variable. */
static void
! add_referenced_var (tree var, struct walk_state *walk_state)
{
void **slot;
var_ann_t v_ann;
--- 2553,2559 ----
assumes that VAR is a valid SSA variable. */
static void
! add_referenced_var (tree var, struct walk_state *walk_state, bool in_addr_expr_p)
{
void **slot;
var_ann_t v_ann;
*************** add_referenced_var (tree var, struct wal
*** 2562,2567 ****
--- 2577,2588 ----
v_ann->uid = num_referenced_vars;
VARRAY_PUSH_TREE (referenced_vars, var);
+ /* FIXME: For aggregates we must keep addresable bit set to keep front-end happy.
+ Honza will track this next! */
+ if (!AGGREGATE_TYPE_P (TREE_TYPE (var))
+ && decl_function_context (var) == current_function_decl)
+ TREE_ADDRESSABLE (var) = 0;
+
/* Arguments or global variable pointers may point to memory outside
the current function. */
if (POINTER_TYPE_P (TREE_TYPE (var))
*************** add_referenced_var (tree var, struct wal
*** 2608,2613 ****
--- 2629,2661 ----
if (DECL_NONLOCAL (var))
set_is_used (var);
}
+ if (in_addr_expr_p && !TREE_ADDRESSABLE (var)
+ && decl_function_context (var) == current_function_decl)
+ {
+ struct alias_map_d *alias_map;
+
+ /* In our simplistics view taking address makes variable call clobbered. */
+ if (!is_gimple_call_clobbered (var))
+ {
+ add_call_clobbered_var (var);
+ v_ann->is_call_clobbered = 1;
+ if (POINTER_TYPE_P (TREE_TYPE (var)))
+ v_ann->may_point_to_global_mem = 1;
+ }
+ TREE_ADDRESSABLE (var) = 1;
+ /* Verify that we are still stupid this way. */
+ if (!is_gimple_call_clobbered (var))
+ abort ();
+ /* Create a new alias set entry for VAR. */
+ alias_map = ggc_alloc (sizeof (*alias_map));
+ alias_map->var = var;
+
+ if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
+ alias_map->set = get_alias_set (TREE_TYPE (TREE_TYPE (var)));
+ else
+ alias_map->set = get_alias_set (var);
+ VARRAY_PUSH_GENERIC_PTR (addressable_vars, alias_map);
+ }
/* Now, set attributes that depend on WALK_STATE. */
if (walk_state == NULL)
*************** add_referenced_var (tree var, struct wal
*** 2654,2660 ****
the memory tag that depend on WALK_STATE (e.g., whether this
variable is being stored-to). */
walk_state->is_indirect_ref = 0;
! add_referenced_var (tag, walk_state);
/* If pointer VAR may point to global mem, then TAG may alias
global memory. */
--- 2702,2708 ----
the memory tag that depend on WALK_STATE (e.g., whether this
variable is being stored-to). */
walk_state->is_indirect_ref = 0;
! add_referenced_var (tag, walk_state, false);
/* If pointer VAR may point to global mem, then TAG may alias
global memory. */
*************** create_global_var (void)
*** 2857,2863 ****
void
add_referenced_tmp_var (tree var)
{
! add_referenced_var (var, NULL);
}
/* Return true if VDEFS_AFTER contains fewer entries than VDEFS_BEFORE.
--- 2905,2911 ----
void
add_referenced_tmp_var (tree var)
{
! add_referenced_var (var, NULL, false);
}
/* Return true if VDEFS_AFTER contains fewer entries than VDEFS_BEFORE.