On 12/5/23 07:53, Richard Biener via Gcc wrote:
On Tue, Dec 5, 2023 at 3:54 PM Alexander Monakov via Gcc
<gcc@gcc.gnu.org> wrote:
Greetings,
the definitions for NOP_EXPR and CONVERT_EXPR in tree.def, having survived
all the way from 1992, currently say:
/* Represents a conversion of type of a value.
All conversions, including implicit ones, must be
represented by CONVERT_EXPR or NOP_EXPR nodes. */
DEFTREECODE (CONVERT_EXPR, "convert_expr", tcc_unary, 1)
/* Represents a conversion expected to require no code to be generated. */
DEFTREECODE (NOP_EXPR, "nop_expr", tcc_unary, 1)
Unfortunately, they are confusing, as in
float f(double d)
{
return d;
}
the narrowing conversion is represented with NOP_EXPR, and it is definitely
not a no-op.
Does some clear distinction remain, and is it possible to clarify the
definitions?
{NOP,CONVERT}_EXPR are interchangeable in the middle-end but
frontends (IIRC the C++ FE mainly) distinguishes them. So a uniform
documentation might be difficult - in the end we could eventually
drop NOP_EXPR from the middle-end (during gimplification?) and
only use CONVERT_EXPR. All uses should use CASE_CONVERT
or CONVERT_EXPR_CODE_P which globs both.
I thought someone looked at this a while ago (measured in years) and
concluded it wasn't actually feasible. Perhaps because the middle end
still hands things off to routines that are also used by the FE.
I could see dropping/converting during gimplification with a checker
that verifies they don't sneak back in. Then we can start to expunge
them from gimple passes. Feels like a gcc-15+ problem to me.
jeff