gimplify.c (gimplify_compound_lval): Take fallback argument instead of want_lvalue.

* gimplify.c (gimplify_compound_lval): Take fallback argument
        instead of want_lvalue.
        (gimplify_call_expr): Take want_value argument instead of test
        function.  Gimplify arguments to val only if reg_type; otherwise
        allow lvalue forms.
        (gimplify_expr): Update gimplify_compound_lval and gimplify_call_expr
        calls.
        * tree-gimple.c: Update GIMPLE grammer.  Use true/false not 1/0.
        Tidy commentary globally.
        (get_call_expr_in): Remove RETURN_EXPR handling.  Tidy.
        * tree-gimple.h (is_gimple_call_addr): Mark extern.

        * gimplify.c (gimplify_modify_expr_to_memcpy): Fix typo.

From-SVN: r83941
This commit is contained in:
Richard Henderson 2004-06-30 17:14:43 -07:00 committed by Richard Henderson
parent 2b9ef4fa61
commit 90051e16b4
4 changed files with 188 additions and 236 deletions

View File

@ -1,3 +1,19 @@
2004-06-30 Richard Henderson <rth@redhat.com>
* gimplify.c (gimplify_compound_lval): Take fallback argument
instead of want_lvalue.
(gimplify_call_expr): Take want_value argument instead of test
function. Gimplify arguments to val only if reg_type; otherwise
allow lvalue forms.
(gimplify_expr): Update gimplify_compound_lval and gimplify_call_expr
calls.
* tree-gimple.c: Update GIMPLE grammer. Use true/false not 1/0.
Tidy commentary globally.
(get_call_expr_in): Remove RETURN_EXPR handling. Tidy.
* tree-gimple.h (is_gimple_call_addr): Mark extern.
* gimplify.c (gimplify_modify_expr_to_memcpy): Fix typo.
2004-06-30 Richard Henderson <rth@redhat.com>
* tree-gimple.c (right_assocify_expr): Kill

View File

@ -1563,7 +1563,7 @@ gimplify_array_ref_to_plus (tree *expr_p, tree *pre_p, tree *post_p)
static enum gimplify_status
gimplify_compound_lval (tree *expr_p, tree *pre_p,
tree *post_p, bool want_lvalue)
tree *post_p, fallback_t fallback)
{
tree *p;
varray_type stack;
@ -1669,8 +1669,7 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
}
/* Step 2 is to gimplify the base expression. */
tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
want_lvalue ? fb_lvalue : fb_rvalue);
tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback);
ret = MIN (ret, tret);
/* And finally, the indices and operands to BIT_FIELD_REF. */
@ -1713,12 +1712,11 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
VARRAY_POP (stack);
}
tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
want_lvalue ? fb_lvalue : fb_rvalue);
tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback);
ret = MIN (ret, tret);
/* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
if (!want_lvalue && TREE_CODE (*expr_p) == COMPONENT_REF)
if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
{
canonicalize_component_ref (expr_p);
ret = MIN (ret, GS_OK);
@ -1806,20 +1804,12 @@ gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
}
}
/* Gimplify the CALL_EXPR node pointed by EXPR_P.
call_expr
: ID '(' arglist ')'
arglist
: arglist ',' val
| val
PRE_P points to the list where side effects that must happen before
*EXPR_P should be stored. */
/* Gimplify the CALL_EXPR node pointed by EXPR_P. PRE_P points to the
list where side effects that must happen before *EXPR_P should be stored.
WANT_VALUE is true if the result of the call is desired. */
static enum gimplify_status
gimplify_call_expr (tree *expr_p, tree *pre_p, bool (*gimple_test_f) (tree))
gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
{
tree decl;
tree arglist;
@ -1863,7 +1853,7 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool (*gimple_test_f) (tree))
if (DECL_FUNCTION_CODE (decl) == BUILT_IN_STACK_RESTORE)
gimplify_ctxp->save_stack = false;
new = simplify_builtin (*expr_p, gimple_test_f == is_gimple_stmt);
new = simplify_builtin (*expr_p, !want_value);
if (new && new != *expr_p)
{
@ -1887,13 +1877,24 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool (*gimple_test_f) (tree))
arglist = TREE_CHAIN (arglist))
{
enum gimplify_status t;
bool (*test) (tree);
fallback_t fb;
/* In general, we allow lvalues for function arguments to avoid
extra overhead of copying large aggregates out of even larger
aggregates into temporaries only to copy the temporaries to
the argument list. Make optimizers happy by pulling out to
temporaries those types that fit in registers. */
if (is_gimple_reg_type (TREE_TYPE (TREE_VALUE (arglist))))
test = is_gimple_val, fb = fb_rvalue;
else
test = is_gimple_lvalue, fb = fb_either;
/* There is a sequence point before a function call. Side effects in
the argument list must occur before the actual call. So, when
gimplifying arguments, force gimplify_expr to use an internal
post queue which is then appended to the end of PRE_P. */
t = gimplify_expr (&TREE_VALUE (arglist), pre_p, NULL, is_gimple_val,
fb_rvalue);
t = gimplify_expr (&TREE_VALUE (arglist), pre_p, NULL, test, fb);
if (t == GS_ERROR)
ret = GS_ERROR;
@ -1904,7 +1905,7 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool (*gimple_test_f) (tree))
/* Try this again in case gimplification exposed something. */
if (ret != GS_ERROR && decl && DECL_BUILT_IN (decl))
{
tree new = simplify_builtin (*expr_p, gimple_test_f == is_gimple_stmt);
tree new = simplify_builtin (*expr_p, !want_value);
if (new && new != *expr_p)
{
@ -2334,7 +2335,7 @@ gimplify_modify_expr_to_memcpy (tree *expr_p, bool want_value)
args = tree_cons (NULL, t, args);
to_ptr = build_fold_addr_expr (to);
args = tree_cons (NULL, to, args);
args = tree_cons (NULL, to_ptr, args);
t = implicit_built_in_decls[BUILT_IN_MEMCPY];
t = build_function_call_expr (t, args);
@ -3508,7 +3509,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
case IMAGPART_EXPR:
case COMPONENT_REF:
ret = gimplify_compound_lval (expr_p, pre_p, post_p,
fallback & fb_lvalue);
fallback ? fallback : fb_rvalue);
break;
case COND_EXPR:
@ -3516,7 +3517,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
break;
case CALL_EXPR:
ret = gimplify_call_expr (expr_p, pre_p, gimple_test_f);
ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
break;
case TREE_LIST:
@ -3717,7 +3718,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
enum gimplify_status r0, r1, r2;
r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
is_gimple_min_lval, fb_either);
is_gimple_lvalue, fb_either);
r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
is_gimple_val, fb_rvalue);
r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p, post_p,

View File

@ -38,175 +38,141 @@ Boston, MA 02111-1307, USA. */
http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
function:
FUNCTION_DECL
DECL_SAVED_TREE -> block
block:
BIND_EXPR
BIND_EXPR_VARS -> DECL chain
BIND_EXPR_BLOCK -> BLOCK
BIND_EXPR_BODY -> compound-stmt
compound-stmt:
COMPOUND_EXPR
op0 -> non-compound-stmt
op1 -> stmt
| EXPR_VEC
(or other alternate solution)
stmt: compound-stmt | non-compound-stmt
non-compound-stmt:
block
| if-stmt
| switch-stmt
| jump-stmt
| label-stmt
| try-stmt
| modify-stmt
| call-stmt
if-stmt:
COND_EXPR
op0 -> condition
op1 -> stmt
op2 -> stmt
switch-stmt:
SWITCH_EXPR
op0 -> val
op1 -> stmt
op2 -> array of case labels (as LABEL_DECLs?)
FIXME: add case value info
The SWITCH_LABELS (op2) are sorted in ascending order, and the
last label in the vector is always the default case.
jump-stmt:
GOTO_EXPR
op0 -> LABEL_DECL | '*' ID
| RETURN_EXPR
op0 -> NULL_TREE
| RESULT_DECL
| MODIFY_EXPR -> RESULT_DECL, varname
| THROW_EXPR? do we need/want such a thing for opts, perhaps
to generate an ERT_THROW region? I think so.
Hmm...this would only work at the GIMPLE level, where we know that
the call args don't have any EH impact. Perhaps
annotation of the CALL_EXPR would work better.
| RESX_EXPR
label-stmt:
LABEL_EXPR
op0 -> LABEL_DECL
| CASE_LABEL_EXPR
CASE_LOW -> val | NULL_TREE
CASE_HIGH -> val | NULL_TREE
CASE_LABEL -> LABEL_DECL FIXME
try-stmt:
TRY_CATCH_EXPR
op0 -> stmt
op1 -> handler
| TRY_FINALLY_EXPR
op0 -> stmt
op1 -> stmt
handler:
catch-seq
| EH_FILTER_EXPR
| stmt
modify-stmt:
MODIFY_EXPR
op0 -> lhs
op1 -> rhs
call-stmt: CALL_EXPR
op0 -> ID | '&' ID | OBJ_TYPE_REF
op1 -> arglist
function : FUNCTION_DECL
DECL_SAVED_TREE -> compound-stmt
addr-expr-arg : compref | ID
lhs: addr-expr-arg | '*' ID | bitfieldref
min-lval: ID | '*' ID
bitfieldref :
BIT_FIELD_REF
op0 -> inner_compref
op1 -> CONST
op2 -> var
compref :
COMPONENT_REF
op0 -> inner_compref
| ARRAY_REF
op0 -> inner_compref
op1 -> val
op2 -> val
op3 -> val
| ARRAY_RANGE_REF
op0 -> inner_compref
op1 -> val
op2 -> val
op3 -> val
| REALPART_EXPR
op0 -> inner_compref
| IMAGPART_EXPR
op0 -> inner_compref
compound-stmt: STATEMENT_LIST
members -> stmt
inner_compref : compref | min_lval
| VIEW_CONVERT_EXPR
op0 -> inner_compref
| NOP_EXPR
op0 -> inner_compref
| CONVERT_EXPR
op0 -> inner_compref
stmt : block
| if-stmt
| switch-stmt
| goto-stmt
| return-stmt
| resx-stmt
| label-stmt
| try-stmt
| modify-stmt
| call-stmt
condition : val | val relop val
val : ID | CONST
block : BIND_EXPR
BIND_EXPR_VARS -> chain of DECLs
BIND_EXPR_BLOCK -> BLOCK
BIND_EXPR_BODY -> compound-stmt
rhs : varname | CONST
| '*' ID
| '&' addr-expr-arg
| call_expr
| unop val
| val binop val
| '(' cast ')' val
| method_ref
if-stmt : COND_EXPR
op0 -> condition
op1 -> compound-stmt
op2 -> compound-stmt
(cast here stands for all valid C typecasts)
switch-stmt : SWITCH_EXPR
op0 -> val
op1 -> NULL
op2 -> TREE_VEC of CASE_LABEL_EXPRs
The CASE_LABEL_EXPRs are sorted by CASE_LOW,
and default is last.
unop
: '+'
| '-'
| '!'
| '~'
goto-stmt : GOTO_EXPR
op0 -> LABEL_DECL | val
binop
: relop | '-'
| '+'
| '/'
| '*'
| '%'
| '&'
| '|'
| '<<'
| '>>'
| '^'
return-stmt : RETURN_EXPR
op0 -> return-value
relop
: '<'
| '<='
| '>'
| '>='
| '=='
| '!='
return-value : NULL
| RESULT_DECL
| MODIFY_EXPR
op0 -> RESULT_DECL
op1 -> lhs
resx-stmt : RESX_EXPR
label-stmt : LABEL_EXPR
op0 -> LABEL_DECL
try-stmt : TRY_CATCH_EXPR
op0 -> compound-stmt
op1 -> handler
| TRY_FINALLY_EXPR
op0 -> compound-stmt
op1 -> compound-stmt
handler : catch-seq
| EH_FILTER_EXPR
| compound-stmt
catch-seq : STATEMENT_LIST
members -> CATCH_EXPR
modify-stmt : MODIFY_EXPR
op0 -> lhs
op1 -> rhs
call-stmt : CALL_EXPR
op0 -> val | OBJ_TYPE_REF
op1 -> call-arg-list
call-arg-list: TREE_LIST
members -> lhs
addr-expr-arg: ID
| compref
lhs : addr-expr-arg
| '*' val
| bitfieldref
min-lval : ID
| '*' val
bitfieldref : BIT_FIELD_REF
op0 -> inner-compref
op1 -> CONST
op2 -> var
compref : inner-compref
| REALPART_EXPR
op0 -> inner-compref
| IMAGPART_EXPR
op0 -> inner-compref
inner-compref: min-lval
| COMPONENT_REF
op0 -> inner-compref
op1 -> FIELD_DECL
op2 -> val
| ARRAY_REF
op0 -> inner-compref
op1 -> val
op2 -> val
op3 -> val
| ARRAY_RANGE_REF
op0 -> inner-compref
op1 -> val
op2 -> val
op3 -> val
| VIEW_CONVERT_EXPR
op0 -> inner-compref
condition : val
| val RELOP val
val : ID
| CONST
rhs : lhs
| CONST
| '&' addr-expr-arg
| call_expr
| UNOP val
| val BINOP val
| val RELOP val
*/
static inline bool is_gimple_id (tree);
/* Validation of GIMPLE expressions. */
/* Return nonzero if T is a GIMPLE RHS:
rhs : varname | CONST
| '*' ID
| '&' varname_or_temp
| call_expr
| unop val
| val binop val
| '(' cast ')' val
| <CONSTRUCTOR <gimple_val ...>>
The last option is only valid GIMPLE for vector and complex types;
aggregate types should have their constructors decomposed. */
/* Return true if T is a GIMPLE RHS. */
bool
is_gimple_rhs (tree t)
@ -218,7 +184,7 @@ is_gimple_rhs (tree t)
case '1':
case '2':
case '<':
return 1;
return true;
default:
break;
@ -242,19 +208,16 @@ is_gimple_rhs (tree t)
case COMPLEX_CST:
case VECTOR_CST:
case OBJ_TYPE_REF:
return 1;
return true;
default:
break;
}
if (is_gimple_lvalue (t) || is_gimple_val (t))
return 1;
return 0;
return is_gimple_lvalue (t) || is_gimple_val (t);
}
/* Returns nonzero if T is a valid CONSTRUCTOR component in GIMPLE, either
/* Returns true if T is a valid CONSTRUCTOR component in GIMPLE, either
a val or another CONSTRUCTOR. */
bool
@ -264,7 +227,7 @@ is_gimple_constructor_elt (tree t)
|| TREE_CODE (t) == CONSTRUCTOR);
}
/* Return nonzero if T is a valid LHS for a GIMPLE assignment expression. */
/* Return true if T is a valid LHS for a GIMPLE assignment expression. */
bool
is_gimple_lvalue (tree t)
@ -276,12 +239,7 @@ is_gimple_lvalue (tree t)
|| TREE_CODE (t) == BIT_FIELD_REF);
}
/* Return nonzero if T is a GIMPLE condition:
condexpr
: val
| val relop val */
/* Return true if T is a GIMPLE condition. */
bool
is_gimple_condexpr (tree t)
@ -290,13 +248,7 @@ is_gimple_condexpr (tree t)
|| TREE_CODE_CLASS (TREE_CODE (t)) == '<');
}
/* Return nonzero if T is a valid operand for '&':
varname
: arrayref
| compref
| ID */
/* Return true if T is a valid operand for ADDR_EXPR. */
bool
is_gimple_addr_expr_arg (tree t)
@ -310,7 +262,7 @@ is_gimple_addr_expr_arg (tree t)
|| TREE_CODE (t) == INDIRECT_REF);
}
/* Return nonzero if T is function invariant. Or rather a restricted
/* Return true if T is function invariant. Or rather a restricted
form of function invariant. */
bool
@ -333,7 +285,7 @@ is_gimple_min_invariant (tree t)
}
}
/* Return nonzero if T looks like a valid GIMPLE statement. */
/* Return true if T looks like a valid GIMPLE statement. */
bool
is_gimple_stmt (tree t)
@ -364,25 +316,23 @@ is_gimple_stmt (tree t)
case PHI_NODE:
case STATEMENT_LIST:
/* These are always void. */
return 1;
return true;
case VA_ARG_EXPR:
/* FIXME this should be lowered. */
return 1;
return true;
case COMPOUND_EXPR:
/* FIXME should we work harder to make COMPOUND_EXPRs void? */
case CALL_EXPR:
case MODIFY_EXPR:
/* These are valid regardless of their type. */
return 1;
return true;
default:
return 0;
return false;
}
}
/* Return nonzero if T is a variable. */
/* Return true if T is a variable. */
bool
is_gimple_variable (tree t)
@ -393,7 +343,7 @@ is_gimple_variable (tree t)
|| TREE_CODE (t) == SSA_NAME);
}
/* Return nonzero if T is a GIMPLE identifier (something with an address). */
/* Return true if T is a GIMPLE identifier (something with an address). */
static inline bool
is_gimple_id (tree t)
@ -405,8 +355,7 @@ is_gimple_id (tree t)
|| TREE_CODE (t) == STRING_CST);
}
/* Return nonzero if TYPE is a suitable type for a scalar register
variable. */
/* Return true if TYPE is a suitable type for a scalar register variable. */
bool
is_gimple_reg_type (tree type)
@ -416,7 +365,7 @@ is_gimple_reg_type (tree type)
}
/* Return nonzero if T is a scalar register variable. */
/* Return true if T is a scalar register variable. */
bool
is_gimple_reg (tree t)
@ -433,7 +382,7 @@ is_gimple_reg (tree t)
&& ! needs_to_live_in_memory (t));
}
/* Return nonzero if T is a GIMPLE variable whose address is not needed. */
/* Return true if T is a GIMPLE variable whose address is not needed. */
bool
is_gimple_non_addressable (tree t)
@ -446,8 +395,7 @@ is_gimple_non_addressable (tree t)
&& ! needs_to_live_in_memory (t));
}
/* Return nonzero if T is a GIMPLE rvalue, i.e. an identifier or a
constant. */
/* Return true if T is a GIMPLE rvalue, i.e. an identifier or a constant. */
bool
is_gimple_val (tree t)
@ -456,7 +404,7 @@ is_gimple_val (tree t)
if (is_gimple_variable (t)
&& is_gimple_reg_type (TREE_TYPE (t))
&& !is_gimple_reg (t))
return 0;
return false;
/* FIXME make these decls. That can happen only when we expose the
entire landing-pad construct at the tree level. */
@ -467,12 +415,7 @@ is_gimple_val (tree t)
}
/* Return true if T is a GIMPLE minimal lvalue, of the form
min_lval: ID | '(' '*' ID ')'
This never actually appears in the original SIMPLE grammar, but is
repeated in several places. */
/* Return true if T is a GIMPLE minimal lvalue. */
bool
is_gimple_min_lval (tree t)
@ -481,8 +424,7 @@ is_gimple_min_lval (tree t)
|| TREE_CODE (t) == INDIRECT_REF);
}
/* Return nonzero if T is a typecast operation of the form
'(' cast ')' val. */
/* Return true if T is a typecast operation. */
bool
is_gimple_cast (tree t)
@ -510,17 +452,10 @@ is_gimple_call_addr (tree t)
tree
get_call_expr_in (tree t)
{
if (TREE_CODE (t) == MODIFY_EXPR)
t = TREE_OPERAND (t, 1);
if (TREE_CODE (t) == CALL_EXPR)
return t;
else if (TREE_CODE (t) == MODIFY_EXPR
&& TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
return TREE_OPERAND (t, 1);
else if (TREE_CODE (t) == RETURN_EXPR
&& TREE_OPERAND (t, 0)
&& TREE_CODE (TREE_OPERAND (t, 0)) == MODIFY_EXPR
&& TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 1)) == CALL_EXPR)
return TREE_OPERAND (TREE_OPERAND (t, 0), 1);
return NULL_TREE;
}

View File

@ -74,7 +74,7 @@ extern bool is_gimple_constructor_elt (tree);
extern bool is_gimple_non_addressable (tree t);
/* Returns true iff T is a valid call address expression. */
bool is_gimple_call_addr (tree);
extern bool is_gimple_call_addr (tree);
/* If T makes a function call, returns the CALL_EXPR operand. */
extern tree get_call_expr_in (tree t);