+2012-04-05 Richard Guenther <rguenther@suse.de>
+
+ * gimple.c (walk_gimple_op): Compute val_only for the LHS
+ of an assigment in the canonical way, avoiding is_gimple_mem_rhs.
+ (is_gimple_mem_rhs, is_gimple_reg_rhs, is_gimple_stmt): Move ...
+ * gimplify.c (is_gimple_mem_rhs, is_gimple_reg_rhs, is_gimple_stmt):
+ ... here and make static.
+ * gimple.h (is_gimple_mem_rhs, is_gimple_reg_rhs, is_gimple_stmt):
+ Remove.
+
2012-04-05 Richard Guenther <rguenther@suse.de>
* tree-ssa-dse.c (dse_optimize_stmt): Remember the stmt
may use a COMPONENT_REF on the LHS. */
if (wi)
{
- /* If the RHS has more than 1 operand, it is not appropriate
- for the memory.
- ??? A lhs always requires an lvalue, checking the val_only flag
- does not make any sense, so we should be able to avoid computing
- it here. */
+ /* If the RHS is of a non-renamable type or is a register variable,
+ we may use a COMPONENT_REF on the LHS. */
tree rhs1 = gimple_assign_rhs1 (stmt);
- wi->val_only = !(is_gimple_mem_rhs (rhs1)
- || TREE_CODE (rhs1) == CONSTRUCTOR)
- || gimple_assign_rhs_class (stmt) != GIMPLE_SINGLE_RHS;
+ wi->val_only
+ = (is_gimple_reg_type (TREE_TYPE (rhs1)) && !is_gimple_reg (rhs1))
+ || gimple_assign_rhs_class (stmt) != GIMPLE_SINGLE_RHS;
wi->is_lhs = true;
}
/* Validation of GIMPLE expressions. */
-/* 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)
-{
- return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
-}
-
-/* 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_val (t) || is_gimple_lvalue (t);
-}
-
/* Return true if T is a valid LHS for a GIMPLE assignment expression. */
bool
return is_gimple_constant (t);
}
-/* Return true if T looks like a valid GIMPLE statement. */
-
-bool
-is_gimple_stmt (tree t)
-{
- const enum tree_code code = TREE_CODE (t);
-
- switch (code)
- {
- case NOP_EXPR:
- /* The only valid NOP_EXPR is the empty statement. */
- return IS_EMPTY_STMT (t);
-
- case BIND_EXPR:
- case COND_EXPR:
- /* These are only valid if they're void. */
- return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
-
- case SWITCH_EXPR:
- case GOTO_EXPR:
- case RETURN_EXPR:
- case LABEL_EXPR:
- case CASE_LABEL_EXPR:
- case TRY_CATCH_EXPR:
- case TRY_FINALLY_EXPR:
- case EH_FILTER_EXPR:
- case CATCH_EXPR:
- case ASM_EXPR:
- case STATEMENT_LIST:
- case OMP_PARALLEL:
- case OMP_FOR:
- case OMP_SECTIONS:
- case OMP_SECTION:
- case OMP_SINGLE:
- case OMP_MASTER:
- case OMP_ORDERED:
- case OMP_CRITICAL:
- case OMP_TASK:
- /* These are always void. */
- return true;
-
- case CALL_EXPR:
- case MODIFY_EXPR:
- case PREDICT_EXPR:
- /* These are valid regardless of their type. */
- return true;
-
- default:
- return false;
- }
-}
-
/* Return true if T is a variable. */
bool
const char *gimple_decl_printable_name (tree, int);
tree gimple_get_virt_method_for_binfo (HOST_WIDE_INT, tree);
tree gimple_extract_devirt_binfo_from_cst (tree);
-/* Returns true iff T is a valid GIMPLE statement. */
-extern bool is_gimple_stmt (tree);
/* Returns true iff T is a scalar register variable. */
extern bool is_gimple_reg (tree);
extern bool is_gimple_asm_val (tree);
/* Returns true iff T is a valid address operand of a MEM_REF. */
bool is_gimple_mem_ref_addr (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_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);
return ret;
}
+/* 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)
+{
+ return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
+}
+
+/* Returns true iff T is a valid RHS for an assignment to an un-renamed
+ LHS, or for a call argument. */
+
+static 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_val (t) || is_gimple_lvalue (t);
+}
+
/* Return true if T is a CALL_EXPR or an expression that can be
assigned to a temporary. Note that this predicate should only be
used during gimplification. See the rationale for this in
return ret;
}
+
+/* Return true if T looks like a valid GIMPLE statement. */
+
+static bool
+is_gimple_stmt (tree t)
+{
+ const enum tree_code code = TREE_CODE (t);
+
+ switch (code)
+ {
+ case NOP_EXPR:
+ /* The only valid NOP_EXPR is the empty statement. */
+ return IS_EMPTY_STMT (t);
+
+ case BIND_EXPR:
+ case COND_EXPR:
+ /* These are only valid if they're void. */
+ return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
+
+ case SWITCH_EXPR:
+ case GOTO_EXPR:
+ case RETURN_EXPR:
+ case LABEL_EXPR:
+ case CASE_LABEL_EXPR:
+ case TRY_CATCH_EXPR:
+ case TRY_FINALLY_EXPR:
+ case EH_FILTER_EXPR:
+ case CATCH_EXPR:
+ case ASM_EXPR:
+ case STATEMENT_LIST:
+ case OMP_PARALLEL:
+ case OMP_FOR:
+ case OMP_SECTIONS:
+ case OMP_SECTION:
+ case OMP_SINGLE:
+ case OMP_MASTER:
+ case OMP_ORDERED:
+ case OMP_CRITICAL:
+ case OMP_TASK:
+ /* These are always void. */
+ return true;
+
+ case CALL_EXPR:
+ case MODIFY_EXPR:
+ case PREDICT_EXPR:
+ /* These are valid regardless of their type. */
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+
/* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
DECL_GIMPLE_REG_P set.