[Info-vax] LLVM, volatile and async VMS I/O and system calls
Bill Gunshannon
bill.gunshannon at gmail.com
Sun Oct 3 11:29:49 EDT 2021
On 10/3/21 11:16 AM, Jan-Erik Söderholm wrote:
> Den 2021-10-03 kl. 16:21, skrev Bill Gunshannon:
>> On 10/3/21 8:29 AM, chris wrote:
>>> On 10/03/21 10:21, Jan-Erik Söderholm wrote:
>>>> Den 2021-10-03 kl. 01:06, skrev chris:
>>>>>
>>>>> So, it really comes down to optimiser choice of instruction, depending
>>>>> on the use of the volatile keyword. Perhaps optimisers might optimise
>>>>> such reads out, but that common ?.
>>>>
>>>> Optimizing out code not needed is one of the most common things that
>>>> optimizers does. A very short example.
>>>>
>>>> int a;
>>>> int b;
>>>> void main() {
>>>> a = 10;
>>>> b = a;
>>>> b = a;
>>>> }
>>>>
>>>> The second assignment to b will simply be removed since it is
>>>> a duplicate of the first and the value of a has not changed, at
>>>> least not as far as the compiler can see.
>>>>
>>>> Compare with:
>>>>
>>>> int volatile a;
>>>> int b;
>>>> void main() {
>>>> a = 10;
>>>> b = a;
>>>> b = a;
>>>> }
>>>>
>>>> This tells the compiler that the value of a can change outside of
>>>> the current compile unit and both assignments will be left to be
>>>> done and the value of b could be different after each assignment.
>>>>
>>>> The first generates 7 Alpha instructions and the second 9 instructions.
>>>
>>> Would be interesting to see instructions generated, so we can see what
>>> is happening. Instruction count alone doesn't say much.
>>
>> More interesting than you might thnk. Here's an x86 version.
>>
>> .text
>> .globl main
>> .type main, @function
>> main:
>> .LFB0:
>> .cfi_startproc
>> movl $10, a(%rip)
>> movl $10, b(%rip)
>> ret
>> .cfi_endproc
>> .LFE0:
>> .size main, .-main
>> .comm b,4,4
>> .comm a,4,4
>> .ident "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
>> .section .note.GNU-stack,"", at progbits
>>
>> ---------------------------------------
>>
>> .text
>> .globl main
>> .type main, @function
>> main:
>> .LFB0:
>> .cfi_startproc
>> movl $10, a(%rip)
>> movl a(%rip), %eax
>> movl a(%rip), %eax
>> movl %eax, b(%rip)
>> ret
>> .cfi_endproc
>> .LFE0:
>> .size main, .-main
>> .comm b,4,4
>> .comm a,4,4
>> .ident "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
>> .section .note.GNU-stack,"", at progbits
>>
>> ------------------------------------------
>>
>> And the diff:
>>
>> < movl $10, b(%rip)
>> ---
>> > movl a(%rip), %eax
>> > movl a(%rip), %eax
>> > movl %eax, b(%rip)
>>
>>
>> Most interesting.
>>
>> bill
>
> OK. since b isn't used for anything between the two assignments,
> the first movl is removed. But the final value is still frmo the
> second read of a, anyway.
>
> Try with using b for something in between the assignments.
>
> int a;
> int b;
> int c, d;
> void main() {
> a = 10;
> b = a;
> c = b;
> b = a; (Probably removed by the optimizer...)
> d = b;
> }
>
> int volatile a;
> int b;
> int c, d;
> void main() {
> a = 10;
> b = a;
> c = b;
> b = a;
> d = b;
> }
>
> Anyway, it is obvious that "volatile" does change the way the
> compiler/optimizer builds the code. As expected, of course.
>
>
I thought the funnier part was in the first one where the
optimizer decided that moving a to b was not necessary and
it merely assigned the constant value 10 to both of them.
bill
More information about the Info-vax
mailing list