Re: gcc 4.5.1 -fstrict-aliasing and store removal

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> It's pretty hard to say anything conclusive about an incomplete example,

Unfortunately I failed to create a small example illustrating this
optimization.

> but the use of reinterpret_cast and -fstrict-aliasing obviously suggests
> an aliasing violation.
>
> Perhaps you could explain why this is not an aliasing violation?
>

I am pretty sure that this cast violate strict aliasing rules because
we try to treat value of type GlobalObject* as a value of type byte*.
And then we treat a value of type byte* as a value of type Object**.
Neither of this types are compatible as far as I understand.

The question is why this conversions between incompatible pointer
types allows GCC to remove memory stores to some random memory
location it does not know anything about?

In some article about strict aliasing I've read that compiler can
remove the following stores:

inline void init (uint64_t* value, uint32_t hi, uint32_t lo) {
  uint32_t* p = reinterpret_cast<uint32_t>(value);
  p[0] = lo;  // can be optimized out when inlined to mk
  p[1] = hi;  // can be optimized out when inlined to mk
}

uint64_t mk(uint32_t hi, uint32_t lo) {
  uint64_t result;
  init(&result, hi, lo);
}

But I cannot clearly see why compiler can do that nor I can understand
why it would be beneficial to do so. And the main mystery for me here
is how to prevent compiler from doing such optimizations.

> (When your program has an aliasing violation, gcc does unpredictable
> things.  There is little benefit to speculating about precisely why it
> did what it did.)

Any optimization done by a compiler is always predictable [unless it
is bug in optimizer], because compiler has to prove that his
transformation is correct.

I would like to understand what exactly compiler proved in this case.

--
Vyacheslav Egorov


On Fri, Oct 1, 2010 at 5:45 PM, Ian Lance Taylor <iant@xxxxxxxxxx> wrote:
> Vyacheslav Egorov <vegorov@xxxxxxxxxxxx> writes:
>
>> I am experiencing the following problem when compiling V8[1] with gcc
>> 4.5.1 with -O1 -fstrict-aliasing enabled: for some reason GCC removes
>> one of the stores to memory.
>>
>> Store removal happens in the method Genesis::HookUpGlobalProxy [2]
>>
>> void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global,
>> Handle<JSGlobalProxy> global_proxy) {
>>   // ...
>>   inner_global->set_global_context(*global_context());
>>   // ...
>> }
>>
>>  GCC inlines method GlobalObject::set_global_context, which is defined
>> through macroses ACCESSORS[3] and WRITE_FIELD[4]
>>
>>   void GlobalObject::set_global_context(Context* value, WriteBarrierMode mode) {
>>     WRITE_FIELD(this, offset, value);
>>     CONDITIONAL_WRITE_BARRIER(this, offset, mode);
>>   }
>>
>> #define FIELD_ADDR(p, offset) \
>>   (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
>>
>> #define WRITE_FIELD(p, offset, value) \
>>   (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
>>
>> and removes memory store which should be generated from WRITE_FIELD.
>>
>> I am trying to figure out why GCC decides that this memory store can
>> be safely removed.
>
> It's pretty hard to say anything conclusive about an incomplete example,
> but the use of reinterpret_cast and -fstrict-aliasing obviously suggests
> an aliasing violation.
>
> Perhaps you could explain why this is not an aliasing violation?
>
> (When your program has an aliasing violation, gcc does unpredictable
> things.  There is little benefit to speculating about precisely why it
> did what it did.)
>
> Ian
>



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux