This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH 1/2]: Merging meaning of CONVERT_EXPR and NOP_EXPR v.2
- From: Tomas Bily <tbily at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Eric Botcazou <ebotcazou at adacore dot com>, Richard Guenther <richard dot guenther at gmail dot com>, Tomas Bily <tbily at ucw dot cz>
- Date: Mon, 7 Jul 2008 19:20:53 +0200
- Subject: Re: [PATCH 1/2]: Merging meaning of CONVERT_EXPR and NOP_EXPR v.2
- References: <20080616154618.GA9906@atrey.karlin.mff.cuni.cz> <200806221512.09643.ebotcazou@adacore.com> <84fc9c000806220722q30a4e7dcl731e9d5710911deb@mail.gmail.com> <200806221821.02841.ebotcazou@adacore.com>
Hi,
> > > IOW, the predicate must return true if there is no computation involved
> > > in the conversion.
> >
> > With my middle-end hat on I guess removing the check for AGGREGATE_TYPE_P
> > would do this.
>
> Yes, this might be sufficient.
Thanks. It was changed in new vesion below.
Bootstraped and tested on x86_64-linux, i686-linux, ia64-linux.
Ok?
Greetings
Tomas
Changelog:
2008-07-07 Tomas Bily <tbily@suse.cz>
* convert.c (convert_to_real): Use only NOP_EXPR for building conversion
to real type.
(convert_to_integer): Use only NOP_EXPR for building conversion
to int type.
* c-parser.c (c_parser_unary_expression): Handle unary plus by
NOP_EXPR.
* config/ia64/ia64.c (ia64_invalid_unary_op): Likewise.
* c-typeck.c (build_unary_op): Handle unary plus by NOP_EXPR.
(build_c_cast): Handle converion to void by NOP_EXPR. Convert
void (int (0)) that is used for empty block into void (int (1)).
* fold-const.c (fold_truth_not_expr): Merge case CONVERT_EXPR
and NOP_EPXR paths and use CASE_CONVERT.
* dojump.c (do_jump): Likewise.
* ada/trans.c (addressable_p): Likewise.
* tree-eh.c (tree_could_trap_p): Likewise.
* tree.c (get_narrower): Do not strip away real type NOP_EXPRs that has
different real mode (fixed/float) than inner operand.
* cp/cvt.c (convert_to_void): Strip conversions only for builtin calls.
* cp/typeck.c (cp_build_unary_op): Use NON_LVALUE_EXPR for unary plus
insteed of CONVERT_EXPR.
Index: gcc/tree.c
===================================================================
--- gcc/tree.c (revision 137315)
+++ gcc/tree.c (working copy)
@@ -6199,7 +6199,10 @@ get_narrower (tree op, int *unsignedp_pt
tree win = op;
bool integral_p = INTEGRAL_TYPE_P (TREE_TYPE (op));
- while (TREE_CODE (op) == NOP_EXPR)
+ while (TREE_CODE (op) == NOP_EXPR
+ && !(SCALAR_FLOAT_TYPE_P (TREE_TYPE (op)) &&
+ (TYPE_MODE (TREE_TYPE (op))
+ != TYPE_MODE (TREE_TYPE (TREE_OPERAND (op, 0))))))
{
int bitschange
= (TYPE_PRECISION (TREE_TYPE (op))
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c (revision 137315)
+++ gcc/fold-const.c (working copy)
@@ -3719,11 +3719,7 @@ fold_truth_not_expr (tree arg)
case NON_LVALUE_EXPR:
return invert_truthvalue (TREE_OPERAND (arg, 0));
- case NOP_EXPR:
- if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
- return build1 (TRUTH_NOT_EXPR, type, arg);
-
- case CONVERT_EXPR:
+ CASE_CONVERT:
case FLOAT_EXPR:
return build1 (TREE_CODE (arg), type,
invert_truthvalue (TREE_OPERAND (arg, 0)));
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c (revision 137315)
+++ gcc/cp/typeck.c (working copy)
@@ -4311,7 +4311,7 @@ cp_build_unary_op (enum tree_code code,
if ((invalid_op_diag
= targetm.invalid_unary_op ((code == UNARY_PLUS_EXPR
- ? CONVERT_EXPR
+ ? NOP_EXPR
: code),
TREE_TYPE (xarg))))
{
Index: gcc/cp/cvt.c
===================================================================
--- gcc/cp/cvt.c (revision 137315)
+++ gcc/cp/cvt.c (working copy)
@@ -949,7 +949,9 @@ convert_to_void (tree expr, const char *
conversions. Do not use STRIP_NOPs because it will
not strip conversions to "void", as that is not a
mode-preserving conversion. */
- while (TREE_CODE (e) == NOP_EXPR)
+ while (TREE_CODE (e) == NOP_EXPR
+ && ((TREE_CODE (TREE_OPERAND (e, 0)) == CALL_EXPR
+ && DECL_BUILT_IN (get_callee_fndecl (TREE_OPERAND (e, 0))))))
e = TREE_OPERAND (e, 0);
code = TREE_CODE (e);
Index: gcc/dojump.c
===================================================================
--- gcc/dojump.c (revision 137315)
+++ gcc/dojump.c (working copy)
@@ -187,13 +187,13 @@ do_jump (tree exp, rtx if_false_label, r
break;
#endif
- case NOP_EXPR:
+ CASE_CONVERT:
if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
|| TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
|| TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF
|| TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF)
goto normal;
- case CONVERT_EXPR:
+
/* If we are narrowing the operand, we have to do the compare in the
narrower mode. */
if ((TYPE_PRECISION (TREE_TYPE (exp))
Index: gcc/ada/trans.c
===================================================================
--- gcc/ada/trans.c (revision 137315)
+++ gcc/ada/trans.c (working copy)
@@ -6319,13 +6319,9 @@ addressable_p (tree gnu_expr, tree gnu_t
case ARRAY_REF: case ARRAY_RANGE_REF:
case REALPART_EXPR: case IMAGPART_EXPR:
- case NOP_EXPR:
+ CASE_CONVERT:
return addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE);
- case CONVERT_EXPR:
- return (AGGREGATE_TYPE_P (TREE_TYPE (gnu_expr))
- && addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE));
-
case VIEW_CONVERT_EXPR:
{
/* This is addressable if we can avoid a copy. */
Index: gcc/tree-eh.c
===================================================================
--- gcc/tree-eh.c (revision 137315)
+++ gcc/tree-eh.c (working copy)
@@ -1996,7 +1996,7 @@ tree_could_trap_p (tree expr)
case UNEQ_EXPR:
return honor_snans;
- case CONVERT_EXPR:
+ CASE_CONVERT:
case FIX_TRUNC_EXPR:
/* Conversion of floating point might trap. */
return honor_nans;
Index: gcc/c-typeck.c
===================================================================
--- gcc/c-typeck.c (revision 137315)
+++ gcc/c-typeck.c (working copy)
@@ -2910,7 +2910,7 @@ build_unary_op (enum tree_code code, tre
switch (code)
{
- case CONVERT_EXPR:
+ CASE_CONVERT:
/* This is used for unary plus, because a CONVERT_EXPR
is enough to prevent anybody from looking inside for
associativity, but won't generate any code. */
@@ -3653,7 +3653,11 @@ build_c_cast (tree type, tree expr)
tree otype, ovalue;
if (type == void_type_node)
- return build1 (CONVERT_EXPR, type, value);
+ {
+ if (integer_zerop (value))
+ return build1 (NOP_EXPR, type, integer_one_node);
+ return build1 (NOP_EXPR, type, value);
+ }
otype = TREE_TYPE (value);
Index: gcc/c-parser.c
===================================================================
--- gcc/c-parser.c (revision 137315)
+++ gcc/c-parser.c (working copy)
@@ -4921,7 +4921,7 @@ c_parser_unary_expression (c_parser *par
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
op = default_function_array_conversion (op);
- return parser_build_unary_op (CONVERT_EXPR, op);
+ return parser_build_unary_op (NOP_EXPR, op);
case CPP_MINUS:
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c (revision 137315)
+++ gcc/config/ia64/ia64.c (working copy)
@@ -9903,7 +9903,7 @@ ia64_invalid_unary_op (int op, const_tre
{
/* Reject operations on __fpreg other than unary + or &. */
if (TYPE_MODE (type) == RFmode
- && op != CONVERT_EXPR
+ && op != NOP_EXPR
&& op != ADDR_EXPR)
return N_("invalid operation on %<__fpreg%>");
return NULL;
Index: gcc/convert.c
===================================================================
--- gcc/convert.c (revision 137315)
+++ gcc/convert.c (working copy)
@@ -309,11 +309,7 @@ convert_to_real (tree type, tree expr)
case REAL_TYPE:
/* Ignore the conversion if we don't need to store intermediate
results and neither type is a decimal float. */
- return build1 ((flag_float_store
- || DECIMAL_FLOAT_TYPE_P (type)
- || DECIMAL_FLOAT_TYPE_P (itype))
- ? CONVERT_EXPR : NOP_EXPR, type, expr);
-
+ return build1 (NOP_EXPR, type, expr);
case INTEGER_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
@@ -489,12 +485,8 @@ convert_to_integer (tree type, tree expr
conversion necessitates an explicit sign-extension. In
the signed-to-unsigned case the high-order bits have to
be cleared. */
- if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
- && (TYPE_PRECISION (TREE_TYPE (expr))
- != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)))))
- code = CONVERT_EXPR;
- else
- code = NOP_EXPR;
+
+ code = NOP_EXPR;
tem = fold_unary (code, type, expr);
if (tem)