This is the mail archive of the gcc-patches@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]

Re: [PATCH][RFC] Add gimple_fold


On 03/18/2011 10:11 AM, Richard Guenther wrote:

This tries to extend the previously posted CCP folding patch by introducing a generic interface for non-tree-building, GIMPLE SSA aware folding. The low-level interface for folding regular operations is

/* Fold the expression composed by *CODEP, TYPE and valueized operands
*OP0P,
    *OP1P and *OP2P (as required), using the VALUEIZE callback to valueize
    SSA names that turn up during statement lookup and producing a result
    of at most KIND.  The folding result will be stored in the operands.
    GF_KIND_FAIL is returned if no folding was done.
    If GF_KIND_CONST or GF_KIND_VAL is returned the folding result is
    stored in *OP0P and is a is_gimple_min_invariant or a is_gimple_val.
    If GF_KIND_STMT is returned the folding result is stored in *CODEP,
    *OP0P, *OP1P and *OP2P (as required) and will compose a valid set of
    operands for a gimple assignment.
    If GF_KIND_COMPLEX is returned the folding result is stored in *OP0P
    and will be an arbitrarily complex tree.  */

enum gf_kind
gimple_fold (enum tree_code *codep, tree type,
              tree *op0p, tree *op1p, tree *op2p,
              tree (*valueize)(tree), enum gf_kind kind)

which would allow existing gimple-level foldings to build ontop of this
(including fold_stmt and friends and the special CCP foldings).

The current implementation is quite lame, just dispatching to fold,
but I plan to integrate it with the CCP and fold_stmt foldings before
considering to merge it (eventually producing some sort of statistics
of what the fold path catches that the gimple path does not).

The low-level interface needs to be amended by one for builtin calls
where I'm not sure if it is going to take decomposed operands
or just a gimple statement (I think we have at most 3 operands to
any builtin we can fold in some way).

This again is just a RFC (even though the patch "works" as far as
plugging into the SCCVN binary operation simplification).


I like this. In terms of the interface, what do you think about this always returning an SSA name or (may be) the statement that defines it. Although, if this is just the low-level interface, then we can build a wrapper that calls it and returns a statement.


Some questions and nits below:

+ enum gf_kind {
+     GF_KIND_FAIL = 0,
+     GF_KIND_CONST,
+     GF_KIND_VAL,
+     GF_KIND_STMT,
+     GF_KIND_COMPLEX
+ };

These will need documentation. The values are also sorted by level of complexity, right?


Should we not bother with GF_KIND_COMPLEX? If we are going to return an arbitrarily complex tree, we might as well return GF_KIND_FAIL, I think. Are you implementing GF_KIND_COMPLEX as a workaround or is this the expected behaviour?

For instance, if folding ends up producing a complex tree, would it need to be gimplified? Maybe we could generate the gimplified statement and return the SSA name on the LHS? Though I'm not sure I like even this.

+
+
+ static tree
+ build_valueized_tree_from_def (tree name, tree (*valueize)(tree))
+ {

Needs comment.


+   gimple def_stmt = SSA_NAME_DEF_STMT (name);
+   tree op0, op1, op2;
+
+   if (!is_gimple_assign (def_stmt)
+       || gimple_vuse (def_stmt))
+     return name;
+
+   switch (gimple_assign_rhs_class (def_stmt))
+     {
+     case GIMPLE_SINGLE_RHS:
+       return gimple_assign_rhs1 (def_stmt);
+
+     case GIMPLE_TERNARY_RHS:
+       op2 = gimple_assign_rhs3 (def_stmt);
+       if (TREE_CODE (op2) == SSA_NAME
+ 	&&  valueize)
+ 	op2 = (*valueize) (op2);
+
+     case GIMPLE_BINARY_RHS:
+       op1 = gimple_assign_rhs2 (def_stmt);
+       if (TREE_CODE (op1) == SSA_NAME
+ 	&&  valueize)
+ 	op1 = (*valueize) (op1);
+

/* Fallthru */


+     case GIMPLE_UNARY_RHS:
+       op0 = gimple_assign_rhs1 (def_stmt);
+       if (TREE_CODE (op0) == SSA_NAME
+ 	&&  valueize)
+ 	op0 = (*valueize) (op0);
+       break;
+
+     default:;
+     }
+
+   switch (gimple_assign_rhs_class (def_stmt))
+     {
+     case GIMPLE_UNARY_RHS:
+       return fold_build1 (gimple_assign_rhs_code (def_stmt),
+ 			  TREE_TYPE (name), op0);
+     case GIMPLE_BINARY_RHS:
+       return fold_build2 (gimple_assign_rhs_code (def_stmt),
+ 			  TREE_TYPE (name), op0, op1);
+     case GIMPLE_TERNARY_RHS:
+       return fold_build3 (gimple_assign_rhs_code (def_stmt),
+ 			  TREE_TYPE (name), op0, op1, op2);
+     default:;
+     }
+
+   return name;
+ }
+
+ static enum gf_kind
+ const_or_val (tree res, enum gf_kind kind)
+ {

Needs comment.



Diego.



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