This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Add LVAL argument to c_fully_fold* and propagate it through (PR c/66618, PR c/69960)
- From: Marek Polacek <polacek at redhat dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: "Joseph S. Myers" <joseph at codesourcery dot com>, gcc-patches at gcc dot gnu dot org
- Date: Wed, 8 Nov 2017 17:42:07 +0100
- Subject: Re: [PATCH] Add LVAL argument to c_fully_fold* and propagate it through (PR c/66618, PR c/69960)
- Authentication-results: sourceware.org; auth=none
- References: <20171108162245.GV14653@tucnak>
On Wed, Nov 08, 2017 at 05:22:45PM +0100, Jakub Jelinek wrote:
> Hi!
>
> Here is an attempt to fix these two PRs. The C++ FE already has an LVAL
Nice!
> bool that it propagates through constexpr.c functions, or in
> cp-gimplify.c through calling cp_fold_{maybe_,}rvalue where appropriate.
> The C c_fully_fold was instead just calling decl_constant_value_for_optimization
> in some spots where we've previously called c_fully_fold{_internal,} on
> some rvalue.
> decl_constant_value_for_optimization wasn't doing anything when -O0,
> so we got different behavior between -O0 and -O1+ on what is accepted
> in static initializers. Furthermore, we needed the hack to ignore
> vars with ARRAY_TYPE or BLKmode, so that we actually wouldn't fold lvalues
> to rvalues.
>
> This patch adds LVAL to c_fully_fold{_internal,} and does what
> decl_constant_value_for_optimization did inside of it (without the hacks,
> furthermore, and additionally for -O0 when in initializers for consistency),
> of course only if LVAL is false. Additionally, I've added folding of
> "foo"[2] into 'o'. We have it in gimple-fold.c or so, so that one
> isn't performed when not in_init.
>
> Not sure about the COND_EXPR/VEC_COND_EXPR cases, right now I'm passing
> false as LVAL for the first operand (condition) and lval as LVAL for the
> other two (i.e. if called with lval == true on the whole *_COND_EXPR
> decl_constant_value_for_optimization etc. isn't performed on op1/op2, while
> without it it is). Can one take address of the whole COND_EXPR, or
> have it on LHS of anything in C?
I don't think so, the ?: operator does not yield an lvalue.
> @@ -218,12 +235,51 @@ c_fully_fold_internal (tree expr, bool i
> op2 = TREE_OPERAND (expr, 2);
> op3 = TREE_OPERAND (expr, 3);
> op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
> - maybe_const_itself, for_int_const);
> + maybe_const_itself, for_int_const, lval);
> STRIP_TYPE_NOPS (op0);
> op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
> - maybe_const_itself, for_int_const);
> + maybe_const_itself, for_int_const, false);
> STRIP_TYPE_NOPS (op1);
> - op1 = decl_constant_value_for_optimization (op1);
> + /* Fold "foo"[2] in initializers. */
> + if (!lval
> + && in_init
> + && TREE_CODE (op0) == STRING_CST
> + && TREE_CODE (op1) == INTEGER_CST
> + && TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE
Does this also handle 2["foobar"]?
> + && tree_fits_uhwi_p (op1))
> + {
> + tree ary = op0;
> + tree index = op1;
> + unsigned len = 0;
> + tree elem_type = TREE_TYPE (TREE_TYPE (ary));
> + unsigned elem_nchars = (TYPE_PRECISION (elem_type)
> + / TYPE_PRECISION (char_type_node));
> + len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
> +
> + tree nelts = array_type_nelts (TREE_TYPE (ary));
> + bool dummy1 = true, dummy2 = true;
> + nelts = c_fully_fold_internal (nelts, in_init, &dummy1, &dummy2,
> + for_int_const, false);
> + unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
> + if (tree_int_cst_le (index, nelts)
> + && i < len
> + && i + elem_nchars <= len)
> + {
> + tree type = TREE_TYPE (expr);
> + if (elem_nchars == 1)
> + ret = build_int_cst (type,
> + TREE_STRING_POINTER (ary)[i]);
> + else
> + {
> + const unsigned char *ptr
> + = ((const unsigned char *)TREE_STRING_POINTER (ary)
> + + i * elem_nchars);
> + ret = native_interpret_expr (type, ptr, elem_nchars);
> + }
> + if (ret)
> + goto out;
> + }
> + }
So this code comes from gimple-fold.c? I would probably move it to a new
function.
Marek