[cfe-commits] Patch to change how const arrays/structs are handled

Douglas Gregor dgregor at apple.com
Mon Oct 26 15:34:20 PDT 2009


On Oct 26, 2009, at 2:37 PM, Chris Lattner wrote:

> On Oct 26, 2009, at 2:34 PM, Douglas Gregor wrote:
>> On Oct 22, 2009, at 8:46 PM, Eli Friedman wrote:
>> On Thu, Oct 22, 2009 at 3:08 PM, Tanya Lattner <lattner at apple.com>
>>> wrote:
>>>> Ok, I don't understand why address taken should matter if it is
>>>> declared
>>>> const. Am I missing something?
>>>
>>> It's sort of an edge case, but it's something like gcc's
>>> -fmerge-all-constants, which isn't completely standard-compliant.   
>>> In
>>> essence, if there are multiple instances of the given function on  
>>> the
>>> stack, the addresses of each version of the constant are supposed to
>>> be distinct, and this is broken by making the variable a global.
>>
>>
>> Right. If the address of the constant was never taken (even  
>> implicitly
>> via a reference binding), I think we would be free to perform this
>> optimization. Otherwise, we'll probably have to put it behind - 
>> fmerge-
>> all-constants, like GCC does, so that we don't break conforming
>> programs with this optimization.
>>
>> If this code is only enabled with -fmerge-all-constants, the patch
>> looks fine to me, but please also add some tests that make sure we
>> only perform the optimization when it's safe.
>
> GCC does this optimization by default, e.g. in this testcase:
>
> void foo() {
>  const int x[] = { 1, 2,3,4,5,6,7,8 };
>  bar(x);
> }

I believe that GCC is non-conforming in this regard, because recursive  
calls to "foo" would not have distinct "x" pointers. Note that this  
was fixed in GCC 4.3.4, so that they no longer promote the automatic  
variable to a constant if its address has been taken, as described in  
this bug report:

	http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38615

> My understanding is that -fmerge-all-constants doesn't default to  
> being on.  I don't think this should be tied to it.


There are 3 levels of "merge-constants" in GCC:

   -fno-merge-constants: default at -O0, merges nothing
   -fmerge-constants: default at -O, -O2, -O3, -Os. merges "x" in your  
example with GCC < 4.3.4, but shouldn't (according to the bug report)  
with GCC >= 4.3.4.
   -fmerge-all-constants: must be explicitly-specified; merges "x" in  
your example (always), which is non-conforming behavior

So, we either need to tie this patch to -fmerge-all-constants (where  
we allow such non-conforming behavior) or we need to keep track of  
whether declarations have had their address taken (to implement the  
equivalent of -fmerge-constants).

	- Doug



More information about the cfe-commits mailing list