On Thu, Mar 29, 2007 at 04:16:35PM -0400, Aldy Hernandez wrote:
> * By extension, we will also need:
> 
>       typedef struct gimple_expression_d { ... } * gimple_expr;
> 
>   For example, PLUS_EXPR, etc.  These will have location, btw.
>   Something like:
> 
>                               gimple_stmt
>                                    |
>                                    =
>                                  /   \
>                                 /     \
>                                /       \
>                         gimple_expr   gimple_expr
>                              |             |
>                              tree            +
>                                |            / \
>                              decl         /     \
>                                         /         \
>                                       /             \
>                               gimple_expr    gimple_expr
>                                    |               |
>                                    tree            tree

If we really want to save space, this will not be true.  We need
to pack as much as possible down into one structure.

  GIMPLE_COPY_STMT      (a = b)
  subcode: enum tree_code MODIFY_EXPR
  op0: tree             DEST
  op1: tree             SRC
  
  GIMPLE_EXPR_STMT      (a = b + c)
  subcode: enum tree_code PLUS_EXPR
  op0: tree             A
  op1: tree             B
  op2: tree             C

  GIMPLE_CALL_STMT      (a = f(b1, ..., bn))
  count: HWI            n
  op0: tree             a or nll
  op1: tree             f
  op2: tree             b1
  ...
  op2+n: tree           bn

        Code CALL_EXPR_RETURN_SLOT_OPT, CALL_FROM_THUNK_P,
        and CALL_EXPR_TAILCALL into subcode as bits?

  etc, etc.

I think something like

  struct gimple_statment_base
  {
    enum gimple_stmt_code code : 8;
    unsigned int subcode : 24;
    source_locus locus;
    tree block;
  };

  struct gimple_statement_fixed_length
  {
    struct gimple_statment_base base;
    tree GTY ((length (...))) operands[1];
  };

  struct gimple_statment_variable_length
  {
    struct gimple_statment_base base;
    unsigned HOST_WIDE_INT length;
    tree GTY ((length ("(%h.length)"))) operands[1];
  };

might be sufficient.  The two variable length things I can think
of are CALL_EXPR and SWITCH_EXPR.  Call will have 2 mandatory
operands (return and function address), switch will also have two
mandatory operands (index and default label).  I don't know if
it's easier to hide those in the first two slots of operands or
to make them separate structures.

Of course, there's all this VL_EXP_FOO stuff in tree.h to deal with
the changed layout of calls; you might be able to re-use that in
some way.

I only suspect it'll turn out to be useful to single out GIMPLE_COPY_STMT
instead of just using GIMPLE_EXPR_STMT+MODIFY_EXPR.  Even though
we don't actually save any memory, it might result in not having
to load SUBCODE for the common case of recognizing straight copies.

> * Unfortunately, we're going to have to duplicate a lot of the functionality
>   we currently have for trees.  For example, since STATEMENT_LISTs are used
>   before gimplification, we'll have to come up with the equivalent thing
>   for tuples (say, GIMPLE_STATMENT_LISTS).

Sort of.  I think you'd want to merge tree_statement_list_node
into gimple_statement_d, to avoid the extra indirection to get
to the statement.


r~

Reply via email to