This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][4.5] Move gimplifier predicates
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Diego Novillo <dnovillo at google dot com>, aph at redhat dot com, tromey at redhat dot com
- Date: Thu, 4 Dec 2008 18:10:31 +0100 (CET)
- Subject: [PATCH][4.5] Move gimplifier predicates
This moves gimplifier predicates to where they belong and makes them
private. Apart from the uses in walk_gimple_op for which I have no
clue what this monster-function tries to do - Diego, do you remember?
The java use seems unnecessary (as the comment hints).
Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for stage1?
Thanks,
Richard.
2008-12-04 Richard Guenther <rguenther@suse.de>
* gimple.c (walk_gimple_op): Declare is_gimple_formal_tmp_var
and is_gimple_mem_rhs.
(is_gimple_formal_tmp_rhs, is_gimple_reg_rhs, is_gimple_mem_rhs,
is_gimple_formal_tmp_var, is_gimple_formal_tmp_reg): Move ...
* gimplify.c: ... here. Make them static.
* gimple.h (is_gimple_formal_tmp_rhs, is_gimple_reg_rhs,
is_gimple_mem_rhs, is_gimple_formal_tmp_var, is_gimple_formal_tmp_reg):
Remove declarations.
* tree-mudflap.c (mf_build_check_statement_for): Use
force_gimple_operand instead of gimplify_expr.
* tree-ssa-pre.c (get_or_alloc_expr_for): Treat EXC_PTR_EXPR
and FILTER_EXPR like constants.
java/
* java-gimplify.c (java_gimplify_expr): Do not manually gimplify
the first operand of binary and comaprison expressions.
Index: trunk/gcc/gimple.c
===================================================================
*** trunk.orig/gcc/gimple.c 2008-12-04 11:18:08.000000000 +0100
--- trunk/gcc/gimple.c 2008-12-04 15:00:49.000000000 +0100
*************** walk_gimple_op (gimple stmt, walk_tree_f
*** 1373,1378 ****
--- 1373,1381 ----
struct pointer_set_t *pset = (wi) ? wi->pset : NULL;
unsigned i;
tree ret = NULL_TREE;
+ /* ??? We shouldn't be using these here. */
+ extern bool is_gimple_formal_tmp_var (tree);
+ extern bool is_gimple_mem_rhs (tree);
switch (gimple_code (stmt))
{
*************** is_gimple_operand (const_tree op)
*** 2559,2611 ****
return op && get_gimple_rhs_class (TREE_CODE (op)) == GIMPLE_SINGLE_RHS;
}
-
- /* Return true if T is a GIMPLE RHS for an assignment to a temporary. */
-
- bool
- is_gimple_formal_tmp_rhs (tree t)
- {
- if (is_gimple_lvalue (t) || is_gimple_val (t))
- return true;
-
- return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
- }
-
- /* Returns true iff T is a valid RHS for an assignment to a renamed
- user -- or front-end generated artificial -- variable. */
-
- bool
- is_gimple_reg_rhs (tree t)
- {
- /* If the RHS of the MODIFY_EXPR may throw or make a nonlocal goto
- and the LHS is a user variable, then we need to introduce a formal
- temporary. This way the optimizers can determine that the user
- variable is only modified if evaluation of the RHS does not throw.
-
- Don't force a temp of a non-renamable type; the copy could be
- arbitrarily expensive. Instead we will generate a VDEF for
- the assignment. */
-
- if (is_gimple_reg_type (TREE_TYPE (t)) && tree_could_throw_p (t))
- return false;
-
- return is_gimple_formal_tmp_rhs (t);
- }
-
- /* Returns true iff T is a valid RHS for an assignment to an un-renamed
- LHS, or for a call argument. */
-
- bool
- is_gimple_mem_rhs (tree t)
- {
- /* If we're dealing with a renamable type, either source or dest must be
- a renamed variable. */
- if (is_gimple_reg_type (TREE_TYPE (t)))
- return is_gimple_val (t);
- else
- return is_gimple_formal_tmp_rhs (t);
- }
-
/* Return true if T is a valid LHS for a GIMPLE assignment expression. */
bool
--- 2562,2567 ----
*************** is_gimple_reg (tree t)
*** 2931,2965 ****
}
- /* Returns true if T is a GIMPLE formal temporary variable. */
-
- bool
- is_gimple_formal_tmp_var (tree t)
- {
- if (TREE_CODE (t) == SSA_NAME)
- return true;
-
- return TREE_CODE (t) == VAR_DECL && DECL_GIMPLE_FORMAL_TEMP_P (t);
- }
-
- /* Returns true if T is a GIMPLE formal temporary register variable. */
-
- bool
- is_gimple_formal_tmp_reg (tree t)
- {
- /* The intent of this is to get hold of a value that won't change.
- An SSA_NAME qualifies no matter if its of a user variable or not. */
- if (TREE_CODE (t) == SSA_NAME)
- return true;
-
- /* We don't know the lifetime characteristics of user variables. */
- if (!is_gimple_formal_tmp_var (t))
- return false;
-
- /* Finally, it must be capable of being placed in a register. */
- return is_gimple_reg (t);
- }
-
/* Return true if T is a GIMPLE variable whose address is not needed. */
bool
--- 2887,2892 ----
Index: trunk/gcc/gimple.h
===================================================================
*** trunk.orig/gcc/gimple.h 2008-12-04 11:18:08.000000000 +0100
--- trunk/gcc/gimple.h 2008-12-04 15:00:49.000000000 +0100
*************** extern bool is_gimple_stmt (tree);
*** 857,866 ****
extern bool is_gimple_reg_type (tree);
/* Returns true iff T is a scalar register variable. */
extern bool is_gimple_reg (tree);
- /* Returns true if T is a GIMPLE temporary variable, false otherwise. */
- extern bool is_gimple_formal_tmp_var (tree);
- /* Returns true if T is a GIMPLE temporary register variable. */
- extern bool is_gimple_formal_tmp_reg (tree);
/* Returns true iff T is any sort of variable. */
extern bool is_gimple_variable (tree);
/* Returns true iff T is any sort of symbol. */
--- 857,862 ----
*************** extern bool is_gimple_ip_invariant (cons
*** 889,900 ****
extern bool is_gimple_val (tree);
/* Returns true iff T is a GIMPLE asm statement input. */
extern bool is_gimple_asm_val (tree);
- /* Returns true iff T is a valid rhs for a MODIFY_EXPR where the LHS is a
- GIMPLE temporary, a renamed user variable, or something else,
- respectively. */
- extern bool is_gimple_formal_tmp_rhs (tree);
- extern bool is_gimple_reg_rhs (tree);
- extern bool is_gimple_mem_rhs (tree);
/* Returns true iff T is a valid if-statement condition. */
extern bool is_gimple_condexpr (tree);
--- 885,890 ----
Index: trunk/gcc/gimplify.c
===================================================================
*** trunk.orig/gcc/gimplify.c 2008-12-04 11:18:08.000000000 +0100
--- trunk/gcc/gimplify.c 2008-12-04 16:29:42.000000000 +0100
*************** lookup_tmp_var (tree val, bool is_formal
*** 613,618 ****
--- 613,700 ----
return ret;
}
+ /* ??? This function should be private to gimplify.c, but it is used
+ by gimple.c:walk_gimple_op for unknown reasons. */
+ bool is_gimple_formal_tmp_var (tree);
+
+ /* Returns true if T is a GIMPLE formal temporary variable. */
+
+ bool
+ is_gimple_formal_tmp_var (tree t)
+ {
+ if (TREE_CODE (t) == SSA_NAME)
+ return true;
+
+ return TREE_CODE (t) == VAR_DECL && DECL_GIMPLE_FORMAL_TEMP_P (t);
+ }
+
+ /* Returns true if T is a GIMPLE formal temporary register variable. */
+
+ static bool
+ is_gimple_formal_tmp_reg (tree t)
+ {
+ /* The intent of this is to get hold of a value that won't change.
+ An SSA_NAME qualifies no matter if its of a user variable or not. */
+ if (TREE_CODE (t) == SSA_NAME)
+ return true;
+
+ /* We don't know the lifetime characteristics of user variables. */
+ if (!is_gimple_formal_tmp_var (t))
+ return false;
+
+ /* Finally, it must be capable of being placed in a register. */
+ return is_gimple_reg (t);
+ }
+
+ /* Return true if T is a GIMPLE RHS for an assignment to a temporary. */
+
+ static bool
+ is_gimple_formal_tmp_rhs (tree t)
+ {
+ if (is_gimple_lvalue (t) || is_gimple_val (t))
+ return true;
+
+ return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
+ }
+
+ /* Returns true iff T is a valid RHS for an assignment to a renamed
+ user -- or front-end generated artificial -- variable. */
+
+ static bool
+ is_gimple_reg_rhs (tree t)
+ {
+ /* If the RHS of the MODIFY_EXPR may throw or make a nonlocal goto
+ and the LHS is a user variable, then we need to introduce a formal
+ temporary. This way the optimizers can determine that the user
+ variable is only modified if evaluation of the RHS does not throw.
+
+ Don't force a temp of a non-renamable type; the copy could be
+ arbitrarily expensive. Instead we will generate a VDEF for
+ the assignment. */
+
+ if (is_gimple_reg_type (TREE_TYPE (t)) && tree_could_throw_p (t))
+ return false;
+
+ return is_gimple_formal_tmp_rhs (t);
+ }
+
+ /* ??? This function should be private to gimplify.c, but it is used
+ by gimple.c:walk_gimple_op for unknown reasons. */
+ bool is_gimple_mem_rhs (tree);
+
+ /* Returns true iff T is a valid RHS for an assignment to an un-renamed
+ LHS, or for a call argument. */
+
+ bool
+ is_gimple_mem_rhs (tree t)
+ {
+ /* If we're dealing with a renamable type, either source or dest must be
+ a renamed variable. */
+ if (is_gimple_reg_type (TREE_TYPE (t)))
+ return is_gimple_val (t);
+ else
+ return is_gimple_formal_tmp_rhs (t);
+ }
/* Return true if T is a CALL_EXPR or an expression that can be
assignmed to a temporary. Note that this predicate should only be
Index: trunk/gcc/tree-mudflap.c
===================================================================
*** trunk.orig/gcc/tree-mudflap.c 2008-12-04 11:18:08.000000000 +0100
--- trunk/gcc/tree-mudflap.c 2008-12-04 16:36:31.000000000 +0100
*************** mf_build_check_statement_for (tree base,
*** 503,509 ****
tree mf_elem;
tree mf_limit;
gimple g;
! gimple_seq seq;
/* We first need to split the current basic block, and start altering
the CFG. This allows us to insert the statements we're about to
--- 503,509 ----
tree mf_elem;
tree mf_limit;
gimple g;
! gimple_seq seq, stmts;
/* We first need to split the current basic block, and start altering
the CFG. This allows us to insert the statements we're about to
*************** mf_build_check_statement_for (tree base,
*** 553,566 ****
/* Build: __mf_base = (uintptr_t) <base address expression>. */
seq = gimple_seq_alloc ();
t = fold_convert (mf_uintptr_type, unshare_expr (base));
! gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
g = gimple_build_assign (mf_base, t);
gimple_set_location (g, location);
gimple_seq_add_stmt (&seq, g);
/* Build: __mf_limit = (uintptr_t) <limit address expression>. */
t = fold_convert (mf_uintptr_type, unshare_expr (limit));
! gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
g = gimple_build_assign (mf_limit, t);
gimple_set_location (g, location);
gimple_seq_add_stmt (&seq, g);
--- 553,568 ----
/* Build: __mf_base = (uintptr_t) <base address expression>. */
seq = gimple_seq_alloc ();
t = fold_convert (mf_uintptr_type, unshare_expr (base));
! t = force_gimple_operand (t, &stmts, false, NULL_TREE);
! gimple_seq_add_seq (&seq, stmts);
g = gimple_build_assign (mf_base, t);
gimple_set_location (g, location);
gimple_seq_add_stmt (&seq, g);
/* Build: __mf_limit = (uintptr_t) <limit address expression>. */
t = fold_convert (mf_uintptr_type, unshare_expr (limit));
! t = force_gimple_operand (t, &stmts, false, NULL_TREE);
! gimple_seq_add_seq (&seq, stmts);
g = gimple_build_assign (mf_limit, t);
gimple_set_location (g, location);
gimple_seq_add_stmt (&seq, g);
*************** mf_build_check_statement_for (tree base,
*** 577,583 ****
TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
! gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
g = gimple_build_assign (mf_elem, t);
gimple_set_location (g, location);
gimple_seq_add_stmt (&seq, g);
--- 579,586 ----
TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
! t = force_gimple_operand (t, &stmts, false, NULL_TREE);
! gimple_seq_add_seq (&seq, stmts);
g = gimple_build_assign (mf_elem, t);
gimple_set_location (g, location);
gimple_seq_add_stmt (&seq, g);
*************** mf_build_check_statement_for (tree base,
*** 622,628 ****
result of the evaluation of 't' in a temporary variable which we
can use as the condition for the conditional jump. */
t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
! gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond");
g = gimple_build_assign (cond, t);
gimple_set_location (g, location);
--- 625,632 ----
result of the evaluation of 't' in a temporary variable which we
can use as the condition for the conditional jump. */
t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
! t = force_gimple_operand (t, &stmts, false, NULL_TREE);
! gimple_seq_add_seq (&seq, stmts);
cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond");
g = gimple_build_assign (cond, t);
gimple_set_location (g, location);
*************** mf_build_check_statement_for (tree base,
*** 663,669 ****
v = fold_build2 (PLUS_EXPR, integer_type_node,
fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base),
integer_one_node);
! gimplify_expr (&v, &seq, &seq, is_gimple_mem_rhs, fb_rvalue);
g = gimple_build_call (mf_check_fndecl, 4, mf_base, v, dirflag, u);
gimple_seq_add_stmt (&seq, g);
--- 667,674 ----
v = fold_build2 (PLUS_EXPR, integer_type_node,
fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base),
integer_one_node);
! v = force_gimple_operand (v, &stmts, true, NULL_TREE);
! gimple_seq_add_seq (&seq, stmts);
g = gimple_build_call (mf_check_fndecl, 4, mf_base, v, dirflag, u);
gimple_seq_add_stmt (&seq, g);
Index: trunk/gcc/java/java-gimplify.c
===================================================================
*** trunk.orig/gcc/java/java-gimplify.c 2008-12-04 11:18:08.000000000 +0100
--- trunk/gcc/java/java-gimplify.c 2008-12-04 16:42:27.000000000 +0100
*************** java_gimplify_expr (tree *expr_p, gimple
*** 95,120 ****
gcc_unreachable ();
default:
- /* Java insists on strict left-to-right evaluation of expressions.
- A problem may arise if a variable used in the LHS of a binary
- operation is altered by an assignment to that value in the RHS
- before we've performed the operation. So, we always copy every
- LHS to a temporary variable.
-
- FIXME: Are there any other cases where we should do this?
- Parameter lists, maybe? Or perhaps that's unnecessary because
- the front end already generates SAVE_EXPRs. */
-
- if (TREE_CODE_CLASS (code) == tcc_binary
- || TREE_CODE_CLASS (code) == tcc_comparison)
- {
- enum gimplify_status stat
- = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
- is_gimple_formal_tmp_var, fb_rvalue);
- if (stat == GS_ERROR)
- return stat;
- }
-
return GS_UNHANDLED;
}
--- 95,100 ----
Index: trunk/gcc/tree-ssa-pre.c
===================================================================
*** trunk.orig/gcc/tree-ssa-pre.c 2008-12-03 16:08:04.000000000 +0100
--- trunk/gcc/tree-ssa-pre.c 2008-12-04 16:14:47.000000000 +0100
*************** get_or_alloc_expr_for (tree t)
*** 1044,1050 ****
{
if (TREE_CODE (t) == SSA_NAME)
return get_or_alloc_expr_for_name (t);
! else if (is_gimple_min_invariant (t))
return get_or_alloc_expr_for_constant (t);
else
{
--- 1044,1052 ----
{
if (TREE_CODE (t) == SSA_NAME)
return get_or_alloc_expr_for_name (t);
! else if (is_gimple_min_invariant (t)
! || TREE_CODE (t) == EXC_PTR_EXPR
! || TREE_CODE (t) == FILTER_EXPR)
return get_or_alloc_expr_for_constant (t);
else
{