This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Problem with recompute_tree_invarant_for_addr_expr


Hello,

I have run into the following problem:

recompute_tree_invarant_for_addr_expr says that address of a decl
is invariant if it is a decl in the current function:

if (decl_function_context (node) == current_function_decl)
  ... /* set TREE_INVARIANT  */

This has a small flaw -- in case NODE has variable size, it gets
allocated on stack dynamically, it may be allocated and deallocated
several times, and its address is no longer an invariant.

So I tried to fix the code as follows:

if (decl_function_context (node) == current_function_decl
    && TREE_CONSTANT (DECL_SIZE (node))
  ... /* set TREE_INVARIANT  */

The problem is that tree-nested.c builds frame_decl, adds fields to
it one by one, sometimes takes its address, and only in the end lays it
out.  This means that at the point the address is taken, DECL_SIZE is
not yet known and it is NULL.  In fact, in the moment the address is
taken, there seems to be no way how to tell whether the size of
frame_decl will be variable or not.

So I tried a conservative variant:

if (decl_function_context (node) == current_function_decl
    && DECL_SIZE (node)
    && TREE_CONSTANT (DECL_SIZE (node))
  ... /* set TREE_INVARIANT  */

This works up to moment verify_stmts is called, which ends with
"invariant not recomputed when ADDR_EXPR changed" (because now
frame_decl is laid out, and we know its size is constant, and that the
address is invariant).

Other possibility would be to be "optimistic":

if (decl_function_context (node) == current_function_decl
    && (!DECL_SIZE (node)
        || TREE_CONSTANT (DECL_SIZE (node)))
  ... /* set TREE_INVARIANT  */

which would probably work for frame_decl, as it should be allocated just
once (I hope), but is not very safe and still would ICE in
"invariant not recomputed when ADDR_EXPR changed", this time in case
if frame_decl were variable-sized.

It might be possible to special-case frame_decl in
recompute_tree_invarant_for_addr_expr, but it would be quite ugly hack,
and it is not somehow terribly simple to do anyway.

The other possibility is to somehow remember the list of places where
we take address of something based on frame_decl, and recompute
TREE_INVARIANT for them once frame_decl is laid out.

Any simpler idea how to solve this problem?

Zdenek


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]