This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/86318] const local aggregates can be assumed not to be modified even when escaped
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 26 Jun 2018 07:53:56 +0000
- Subject: [Bug tree-optimization/86318] const local aggregates can be assumed not to be modified even when escaped
- Auto-submitted: auto-generated
- References: <bug-86318-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86318
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Last reconfirmed| |2018-06-26
CC| |rguenth at gcc dot gnu.org
Ever confirmed|0 |1
--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
Confirmed. It is the frontend doing the optimization likely during its
folding.
The middle-end doesn't in any way honor 'const' since
const S s = { .... };
can be expanded (gimplified) to a automatic variable initialized by
one or multiple assignments (so that automatic variable isn't "constant"):
For example g1:
g1 ()
{
const int a[1];
int _1;
<bb 2> :
a[0] = 1;
f (&a);
_1 = a[0];
if (_1 != 1)
so here a[0] is assigned to.
If we'd always place such constants in .rodata (use a CONST_DECL) things
might work but then optimization cannot elide (parts of) such initializer.
Previously RTL had a thing like RTX_UNCHANGING which meant values do not
change once set. But that was a recipie for desaster (wrong-code).
For simple cases like g1 the FE could fold the read from *a but I could
see the following case as difficult for the FE to "fold" (unless you
want to "constexpr" evaluate all stmts).
void g3 (void)
{
const struct S s = { 1 };
f (&s);
struct S q = s;
if (q.i != 1)
abort ();
}
A solution on the optimizer side is difficult, it would likely need to
separate "initialization" from "modification" somehow. Like wrapping
the "const" a's in the accesses:
g1 ()
{
const int a[1];
int _1;
<bb 2> :
a[0] = 1;
f (&CONST<a>);
_1 = CONST<a>[0];
either by a bit on the reference trees or by an explicit handled-component.
The address-taking context is somewhat awkward to deal with I think.
In the end it would be the FEs responsibility to "wrap" stuff or the
gimplifier could wrap all but the initialization stmts.
Or we could do it the other way around, wrap the initialization refs.