[Info-vax] LLVM, volatile and async VMS I/O and system calls
Dave Froble
davef at tsoft-inc.com
Sun Oct 3 14:18:18 EDT 2021
On 10/3/2021 11:29 AM, Bill Gunshannon wrote:
> 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
>
What I find a bit funny is all an optimizer does is corrects poorly
written code. People get into habits, and it can be hard to break some
habits.
As an example, back in the day, the RSTS Basic+ interpreter had an
interesting quirk. For example:
A = "abc"
B = A
One would expect the value in A to be placed in the location where the
pointer to B points. However, Basic+ would change the pointer to B to
the value of the pointer to A, thus losing the old location of B. I
think this happened with strings, don't really remember, it has been a
very long time.
Now consider that the pointer to B was in an I/O buffer. After the
operation, B would no longer be pointing into the I/O buffer. Perhaps
not such a good thing. (Actually a horrible thing!)
What people learned to do is:
B = A + ""
That would insure moving of the data, not the pointer. With BP2 and
later, this odd operation was not an issue. But, even today, I find
people still using that old habit of appending the null string to an
operation.
Bad habits are hard to kill.
--
David Froble Tel: 724-529-0450
Dave Froble Enterprises, Inc. E-Mail: davef at tsoft-inc.com
DFE Ultralights, Inc.
170 Grimplin Road
Vanderbilt, PA 15486
More information about the Info-vax
mailing list