From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 3B97A3858C3A; Tue, 26 Oct 2021 08:41:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3B97A3858C3A From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/102876] GCC fails to use constant initialization even when it knows the value to initialize Date: Tue, 26 Oct 2021 08:41:25 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 11.2.0 X-Bugzilla-Keywords: missed-optimization X-Bugzilla-Severity: enhancement X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 Oct 2021 08:41:25 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D102876 --- Comment #10 from Jakub Jelinek --- (In reply to Jason Merrill from comment #9) > (In reply to Jakub Jelinek from comment #8) > > But I'm worried about larger TUs where not all dynamic initialization c= an be > > optimized into constants. E.g. if there remain any function calls wher= e the > > alias analysis could think they can read or modify the vars or their > > subobjects etc., we'd need to punt. >=20 > Would we? If the variable isn't const, it's OK for later initializers to > modify its value, I wouldn't think that would prevent us from turning its > initializer into a constant value. I'm talking about e.g. extern int b; int foo (int &); int bar (int &); int baz () { return 1; } int qux () { return b =3D 2; } int a =3D foo (b); int b =3D baz (); int c =3D bar (b); int d =3D qux (); Here, b is initialized to constant 1 and we could optimize it into .data b: .long 1 or so and similarly d can be optimized into .data d: .long 2, but after IPA we see something like: _3 =3D foo (&b); a =3D _3; b =3D 1; _4 =3D bar (&b); c =3D _4; b =3D 2; d =3D 2; where the fact that foo can only remember b's address somewhere, but can't really access it because it hasn't been constructed yet is not visible. So we'd just punt at optimizing that, we don't know if b is read or written= by foo (and, note, it doesn't have to be just the case of explicitly being pas= sed address of some var, it can get the address through other means). On the other side, we can't optimize b to b: .long 2, because bar can use t= he variable and/or modify it, so by using 2 as static initializer bar would be miscompiled. By turning the above into: .INIT_START (&a); _3 =3D foo (&b); a =3D _3; .INIT_END (&a); .INIT_START (&b); b =3D 1; .INIT_END (&b); .INIT_START (&c); _4 =3D bar (&b); c =3D _4; .INIT_END (&c); .INIT_START (&d); b =3D 2; d =3D 2; .INIT_END (&d); we can optimize it into: _3 =3D foo (&b); a =3D _3; _4 =3D bar (&b); c =3D _4; b =3D 2; with DECL_INITIAL (b) =3D 1 and DECL_INITIAL (d) =3D 2. Not showing here any aggregate initializations, there we'd need to reconstr= uct the CONSTRUCTOR for DECL_INITIAL from often more than one store. > This seems like a more general issue: after a variable declared const has > completed its initialization, it can't be modified. Would this be useful= to > mark, kind of like we use a clobber for end of life? I guess we could, but for this optimization we need it not just for const v= ars, but also non-const. And it isn't clear to me for what exactly we'd use it. > Can't you just look at the type? Probably.=