This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [tree-ssa] Lowering of VLA's
- From: Jason Merrill <jason at redhat dot com>
- To: Zdenek Dvorak <rakdver at atrey dot karlin dot mff dot cuni dot cz>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 25 Aug 2003 00:26:18 -0400
- Subject: Re: [tree-ssa] Lowering of VLA's
- References: <20030822180000.GA6927@atrey.karlin.mff.cuni.cz>
On Fri, 22 Aug 2003 20:00:00 +0200, Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz> wrote:
> It makes the place on stack for them to be allocated explicitely. There
> are little technical problems with this step -- it turned out to be
> necessary to replace all references to the object with a pointer (since
> dynamic stack allocation really is a set to pointer).
I looked at this problem a bit a few months back; indeed, this sort of
thing is another aspect of the problem with referring directly to variables
that live in memory rather than by explicit pointer (as in LLVM).
I was reluctant to make this sort of change because of the impact on
debugging information--I want the type of the decl to remain the same for
the benefit of gdb.
One possibility would be to create a separate pointer decl, replace uses
of the vla with uses of the pointer, and associate the two decls at RTL
expansion time.
However, if you're going to introduce a whole new tree code anyway, I don't
think you need to bother with switching to a pointer representation. When
I was looking at this before, I generated the following incomplete patch,
which seems like a simpler approach.
> This change does not yet make VLA's fully independent on enclosing BIND_EXPR,
> since there is the stack deallocation part that is still carried by
> BIND_EXPR; changes to make this explicit should follow.
Hmm. I suppose that means introducing some concept of stack management
into tree-ssa?
Jason
*** c-simplify.c.~1~ 2003-02-05 17:23:57.000000000 -0500
--- c-simplify.c 2003-02-05 17:18:30.000000000 -0500
*************** simplify_decl_stmt (stmt_p, next_p)
*** 753,791 ****
if (!TREE_CONSTANT (DECL_SIZE (decl)))
{
! /* This is a variable-sized decl. We need to wrap it in a new
! block so that we can simplify the expressions for calculating
! its size, and so that any other local variables used in those
! expressions will have been initialized. */
!
! /* FIXME break the allocation out into a separate statement. */
!
! tree size = DECL_SIZE (decl);
! tree usize = DECL_SIZE_UNIT (decl);
! tree bind;
! tree *p;
!
! size = get_initialized_tmp_var (size, &pre);
! usize = get_initialized_tmp_var (usize, &pre);
!
! /* FIXME also simplify field sizes. */
! DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (decl)) = size;
! DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (TREE_TYPE (decl)) = usize;
!
! /* Prune this decl and any others after it out of the enclosing block. */
! for (p = &BIND_EXPR_VARS (gimple_current_bind_expr ());
! *p != decl; p = &TREE_CHAIN (*p))
! /* search */;
! *p = NULL_TREE;
! if (BLOCK_VARS (BIND_EXPR_BLOCK (gimple_current_bind_expr ())) == decl)
! BLOCK_VARS (BIND_EXPR_BLOCK (gimple_current_bind_expr ())) = NULL_TREE;
! bind = c_build_bind_expr (decl, TREE_CHAIN (stmt));
!
! add_tree (bind, &pre);
!
! if (next_p)
! *next_p = NULL_TREE;
}
if (init && init != error_mark_node)
--- 753,765 ----
if (!TREE_CONSTANT (DECL_SIZE (decl)))
{
! /* This is a variable-sized decl. Simplify its size and mark it
! for deferred expansion. */
! DECL_SIZE_UNIT (decl)
! = get_initialized_tmp_var (DECL_SIZE_UNIT (decl), &pre);
! DECL_DEFER_OUTPUT (decl) = 1;
! add_tree (build1 (EXPAND_DECL_EXPR, void_type_node, decl), &pre);
}
if (init && init != error_mark_node)
*** expr.c.~1~ 2003-02-05 17:23:57.000000000 -0500
--- expr.c 2003-02-05 17:18:48.000000000 -0500
*************** expand_expr (exp, target, tmode, modifie
*** 7021,7027 ****
{
tree var = vars;
! if (DECL_EXTERNAL (var))
continue;
if (TREE_STATIC (var))
--- 7021,7027 ----
{
tree var = vars;
! if (DECL_EXTERNAL (var) || DECL_DEFER_OUTPUT (var))
continue;
if (TREE_STATIC (var))
*************** expand_expr (exp, target, tmode, modifie
*** 9440,9445 ****
--- 9440,9449 ----
expand_asm_expr (exp);
return const0_rtx;
+ case EXPAND_DECL_EXPR:
+ expand_decl (TREE_OPERAND (exp, 0));
+ return const0_rtx;
+
default:
return (*lang_hooks.expand_expr) (exp, original_target, tmode, modifier);
}
*** gimplify.c.~1~ 2003-02-05 17:23:57.000000000 -0500
--- gimplify.c 2003-02-05 17:19:01.000000000 -0500
*************** simplify_expr (expr_p, pre_p, post_p, si
*** 474,479 ****
--- 474,480 ----
case LABEL_EXPR:
case CASE_LABEL_EXPR:
+ case EXPAND_DECL_EXPR:
break;
case RETURN_EXPR:
*** tree.def.~1~ 2003-02-05 17:23:57.000000000 -0500
--- tree.def 2003-02-05 17:19:24.000000000 -0500
*************** DEFTREECODE (CATCH_EXPR, "catch_expr", '
*** 885,890 ****
--- 885,894 ----
expanding. */
DEFTREECODE (EH_FILTER_EXPR, "eh_filter_expr", 's', 2)
+ /* Used to represent allocation of space for a variable of variable-size
+ type. Basically just a placeholder for a call to expand_decl. */
+ DEFTREECODE (EXPAND_DECL_EXPR, "expand_decl_expr", 's', 2)
+
/*
Local variables:
mode:c
*** tree-dfa.c.~1~ 2003-02-05 17:23:57.000000000 -0500
--- tree-dfa.c 2003-02-05 17:19:21.000000000 -0500
*************** get_expr_operands (stmt, expr_p, is_def,
*** 456,461 ****
--- 456,469 ----
return;
}
+ /* Allocation of VLAs. */
+ if (code == EXPAND_DECL_EXPR)
+ {
+ get_expr_operands (stmt, &DECL_SIZE_UNIT (TREE_OPERAND (expr, 0)),
+ false, prev_vops);
+ return;
+ }
+
/* Unary expressions. */
if (class == '1'
|| code == BIT_FIELD_REF)
*** tree-pretty-print.c.~1~ 2003-02-05 17:23:57.000000000 -0500
--- tree-pretty-print.c 2003-02-05 17:19:22.000000000 -0500
*************** dump_generic_node (buffer, node, spc, fl
*** 1272,1277 ****
--- 1272,1283 ----
output_add_newline (buffer);
break;
+ case EXPAND_DECL_EXPR:
+ output_add_string (buffer, "<EXPAND ");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags);
+ output_add_character (buffer, '>');
+ break;
+
default:
NIY;
}