On Mon, Mar 3, 2014 at 11:41 AM, David Brown <[email protected]> wrote:
> On 28/02/14 13:19, Richard Sandiford wrote:
>> Georg-Johann Lay <[email protected]> writes:
>>> Notice that in code1, func might contain such asm-pairs to implement
>>> atomic operations, but moving costly_func across func does *not*
>>> affect the interrupt respond times in such a disastrous way.
>>>
>>> Thus you must be *very* careful w.r.t. optimizing against asm volatile
>>> + memory clobber. It's too easy to miss some side effects of *real*
>>> code.
>>
>> I understand the example, but I don't think volatile asms guarantee
>> what you want here.
>>
>>> Optimizing code to scrap and pointing to some GCC internal reasoning or some
>>> standard's wording does not help with real code.
>>
>> But how else can a compiler work? It doesn't just regurgitate canned code,
>> so it can't rely on human intuition as to what "makes sense". We have to
>> have specific rules and guarantees and say that anything outside those
>> rules and guarantees is undefined.
>>
>> It sounds like you want an asm with an extra-strong ordering guarantee.
>> I think that would need to be an extension, since it would need to consider
>> cases where the asm is used in a function. (Shades of carries_dependence
>> or whatever in the huge atomic thread.) I think anything where:
>>
>> void foo (void) { X; }
>> void bar (void) { Y1; foo (); Y2; }
>>
>> has different semantics from:
>>
>> void bar (void) { Y1; X; Y2; }
>>
>> is very dangerous. And assuming that any function call could enable
>> or disable interrupts, and therefore that nothing can be moved across
>> a non-const function call, would limit things a bit too much.
>>
>> Thanks,
>> Richard
>>
>>
>
> I think the problem stems from "volatile" being a barrier to /data flow/
> changes,
What kind of /data flow/ changes? It certainly isn't that currently,
only two volatiles always conflict but not a volatile and a non-volatile mem:
static int
true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
const_rtx x, rtx x_addr, bool mem_canonicalized)
{
...
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
return 1;
bool
refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
{
...
/* Two volatile accesses always conflict. */
if (ref1->volatile_p
&& ref2->volatile_p)
return true;
> but what is needed in this case is a barrier to /control flow/
> changes. To my knowledge, C does not provide any way of doing this, nor
> are there existing gcc extensions to guarantee the ordering. But it
> certainly is the case that control flow ordering like this is important
> - it can be critical in embedded systems (such as in the example here by
> Georg-Johann), but it can also be important for non-embedded systems
> (such as to minimise the time spend while holding a lock).
Can you elaborate on this? I have a hard time thinking of a
control flow transform that affects volatiles.
Richard.
> David
>
>