Re: NOP_EXPR vs. CONVERT_EXPR
On Fri, Dec 8, 2023 at 1:24 AM Jeff Law wrote: > > > > On 12/5/23 07:53, Richard Biener via Gcc wrote: > > On Tue, Dec 5, 2023 at 3:54 PM Alexander Monakov via Gcc > > 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. It's not so long that I tried this (but really by removing NOP_EXPR) when I figured the C++ FE at least won't be happy. The gimplification route and IL checking so NOP_EXPR doesn't creep back in could work though. Richard. > jeff
Re: NOP_EXPR vs. CONVERT_EXPR
On 12/5/23 07:53, Richard Biener via Gcc wrote: On Tue, Dec 5, 2023 at 3:54 PM Alexander Monakov via Gcc 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
Re: NOP_EXPR vs. CONVERT_EXPR
On Tue, Dec 5, 2023 at 3:54 PM Alexander Monakov via Gcc 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. Richard. > > Thanks. > Alexander
NOP_EXPR vs. CONVERT_EXPR
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? Thanks. Alexander