* * *

Author Topic: Statement as memory barrier for globals ("volatile")  (Read 3802 times)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 4415
    • wiki
Re: Statement as memory barrier for globals ("volatile")
« Reply #45 on: December 06, 2017, 04:32:56 am »
Using the generated asm is really meaningless.

Just because current FPC does not apply a specific optimization, does not mean that future FPC wont either.

If it isn't documented, then it can not be relied upon.

The doc for typed constant https://www.freepascal.org/docs-html/3.0.2/ref/refse10.html sets them equal to initialized global variables.

That doc does not guarantee that not in future -O5 may optimize those variables to a register. (A variable cached in a register is still writeable)

So either their is no volatile, or (if all globals are meant to be volatile) the doc for that is missing.

engkin

  • Hero Member
  • *****
  • Posts: 1758
Re: Statement as memory barrier for globals ("volatile")
« Reply #46 on: December 06, 2017, 06:43:13 am »
Code: Pascal  [Select]
  1. program project1;
  2.  
  3. var
  4.   t: byte absolute 1;
  5.   temp: byte;
  6.  
  7. begin
  8.   t := 255;
  9.   temp := t;
  10.   WriteLn(temp);
  11. end.
Thank you for this example. I took your code and recompiled it using your options and adding {$Optimization REGVAR+}. Here is the emitted assembly:
Code: ASM  [Select]
  1. _main:
  2. ; [project1.lpr]
  3. ; [9] begin
  4.                 push    ebx
  5.                 push    esi
  6. ; Var temp located in register bl
  7.                 call    FPC_INITIALIZEUNITS
  8.                 mov     al,0
  9. ; [10] t := 255;
  10.                 mov     bl,255
  11. ; Var temp located in register bl
  12.                 mov     byte ptr [+1],bl
  13. ; [12] WriteLn(temp);
  14. ...
You ask the compiler to emit code for:
Code: Pascal  [Select]
  1.   t := 255;
  2.   temp := t;
and the result -remember temp is in bl-:
Code: ASM  [Select]
  1.                 mov     bl,255
  2.                 mov     byte ptr [+1],bl
which is more like:
Code: Pascal  [Select]
  1.   temp := 255;
  2.   t := temp;

There are TWO problems with the emitted assembly:
  • For temp := t the compiler did *NOT* read the value from the memory location. Instead it used an immediate value mov   bl,255
  • It assigned the value 255 to temp (bl) *BEFORE* writing it to t, unlike the order of instructions in your code
Both problems should not exist when dealing with volatile variables.

In your example the compiler failed to read the first temperature sensor.  :(



@Martin, thank you.
« Last Edit: December 06, 2017, 06:49:09 am by engkin »

ccrause

  • Jr. Member
  • **
  • Posts: 77
Re: Statement as memory barrier for globals ("volatile")
« Reply #47 on: December 07, 2017, 01:17:34 pm »
If it isn't documented, then it can not be relied upon.
Agreed, my interest in this discussion is finding out what is currently possible even though it isn't documented.

I took your code and recompiled it using your options and adding {$Optimization REGVAR+}.
Indeed this shows the problem of not having an explicit modifier for volatile.

In your example the compiler failed to read the first temperature sensor.  :(
I guess you have to indicate what constitutes "reading a sensor".  My interpretation was that a specific memory location is read and assigned to a different variable for further processing.

engkin

  • Hero Member
  • *****
  • Posts: 1758
Re: Statement as memory barrier for globals ("volatile")
« Reply #48 on: December 07, 2017, 05:55:32 pm »
In your example the compiler failed to read the first temperature sensor.  :(
I guess you have to indicate what constitutes "reading a sensor".  My interpretation was that a specific memory location is read and assigned to a different variable for further processing.
Your interpretation is correct. The problem the compiler did *not* emit any code to read the location you specified in your example.

ccrause

  • Jr. Member
  • **
  • Posts: 77
Re: Statement as memory barrier for globals ("volatile")
« Reply #49 on: December 07, 2017, 08:35:11 pm »
In your example the compiler failed to read the first temperature sensor.  :(
I guess you have to indicate what constitutes "reading a sensor".  My interpretation was that a specific memory location is read and assigned to a different variable for further processing.
Your interpretation is correct. The problem the compiler did *not* emit any code to read the location you specified in your example.
I thought the assembler code generated for my example did exactly that:
Code: Pascal  [Select]
  1. # [9] temp := t;
  2.         movq    $1,%rax
  3.         movb    (%rax),%al
  4.         movb    %al,U_$P$PROJECT1_$$_TEMP(%rip)
My interpretation of the instruction sequence is: move value 1 into register RAX (variable t was specified at address 1 in the example), then move the byte value at the address pointed to by RAX into register AL (so AL now contain the content of memory location 1), then move the content of register AL into memory location for variable temp.  I had to reference this page to decode the syntax, so I may be wrong.

engkin

  • Hero Member
  • *****
  • Posts: 1758
Re: Statement as memory barrier for globals ("volatile")
« Reply #50 on: December 07, 2017, 08:44:11 pm »
In your example the compiler failed to read the first temperature sensor.  :(
I guess you have to indicate what constitutes "reading a sensor".  My interpretation was that a specific memory location is read and assigned to a different variable for further processing.
Your interpretation is correct. The problem the compiler did *not* emit any code to read the location you specified in your example.
I thought the assembler code generated for my example did exactly that:
Not when I used {$Optimization REGVAR+}.

Thaddy

  • Hero Member
  • *****
  • Posts: 4777
Re: Statement as memory barrier for globals ("volatile")
« Reply #51 on: December 07, 2017, 09:00:07 pm »
In your example the compiler failed to read the first temperature sensor.  :(
I guess you have to indicate what constitutes "reading a sensor".  My interpretation was that a specific memory location is read and assigned to a different variable for further processing.
Your interpretation is correct. The problem the compiler did *not* emit any code to read the location you specified in your example.
I thought the assembler code generated for my example did exactly that:
Not when I used {$Optimization REGVAR+}.

Should not happen when:
Code: Pascal  [Select]
  1. program project1;
  2. {$WRITEABLECONST ON}
  3. var
  4.  t:byte absolute 1;
  5. const  
  6.   temp: byte = 0;
  7.  
  8. begin
  9.   t := 255;
  10.   temp := t;
  11.   WriteLn(temp);
  12. end.
  13.  
Because- as I explained before - they are memory locations.
« Last Edit: December 07, 2017, 09:08:28 pm by Thaddy »
"Logically, no number of positive outcomes at the level of experimental testing can confirm a scientific theory, but a single counterexample is logically decisive."

engkin

  • Hero Member
  • *****
  • Posts: 1758
Re: Statement as memory barrier for globals ("volatile")
« Reply #52 on: December 07, 2017, 09:06:06 pm »
In your example the compiler failed to read the first temperature sensor.  :(
I guess you have to indicate what constitutes "reading a sensor".  My interpretation was that a specific memory location is read and assigned to a different variable for further processing.
Your interpretation is correct. The problem the compiler did *not* emit any code to read the location you specified in your example.
I thought the assembler code generated for my example did exactly that:
Not when I used {$Optimization REGVAR+}.

Should not happen when:
Code: Pascal  [Select]
  1. program project1;
  2. {$WRITEABLECONST ON}
  3. const
  4.   t: byte absolute 1;
  5.   temp: byte;
  6.  
  7. begin
  8.   t := 255;
  9.   temp := t;
  10.   WriteLn(temp);
  11. end.
Because- as I explained before - they are memory locations.

You might be right. Let me try.

Thaddy

  • Hero Member
  • *****
  • Posts: 4777
Re: Statement as memory barrier for globals ("volatile")
« Reply #53 on: December 07, 2017, 09:09:15 pm »
I tried and had to change the example a bit.
Code: Pascal  [Select]
  1. program project1;
  2. {$WRITEABLECONST ON}
  3. var
  4.  t:byte absolute 1; //forced memory location
  5. const  
  6.   temp: byte = 0; // memory location because of J+
  7.  
  8. begin
  9.   t := 255;
  10.   temp := t;
  11.   WriteLn(temp);
  12. end.

{$OPTIMIZATION REGVAR+} has a bug if it does not work..... BUT it works on arm:
Code: Text  [Select]
  1. main:
  2.         stmfd   r13!,{r4,r14}
  3.         bl      fpc_initializeunits
  4.         ldr     r1,.Lj3   ; address 1
  5.         mov     r0,#255   ; load the var value
  6.         ldr     r2,.Lj3   ; address 1
  7.         strb    r0,[r1]   ; store value at address 1
  8. .......
  9. .Lj3:
  10.         .long   1
  11. .....
  12.  
« Last Edit: December 07, 2017, 09:34:28 pm by Thaddy »
"Logically, no number of positive outcomes at the level of experimental testing can confirm a scientific theory, but a single counterexample is logically decisive."

engkin

  • Hero Member
  • *****
  • Posts: 1758
Re: Statement as memory barrier for globals ("volatile")
« Reply #54 on: December 07, 2017, 09:31:32 pm »
Well, it turned out that absolute can not be used with constants. IOW, this does not compile:
Code: Pascal  [Select]
  1. const
  2.   t: byte absolute 1;
  3. or
  4.   t: byte = 2 absolute 1;

Meaning you can not give a constant a specific address.


I tried and had to change the example a bit.
Code: Pascal  [Select]
  1. program project1;
  2. {$WRITEABLECONST ON}
  3. var
  4.  t:byte absolute 1; //forced memory location
  5. const  
  6.   temp: byte = 0; // memory location because of J+
  7.  
  8. begin
  9.   t := 255;
  10.   temp := t;
  11.   WriteLn(temp);
  12. end.

{$OPTIMIZATION REGVAR+} has a bug if it does not work.....
Let me assume that it works. What are the rules?
Are you saying that if you give a variable a specific address using absolute then:

  • You can write to it and it will be written to the memory always no matter what.
  • But to read from that memory location you have to use a writable typed constant?

Thaddy

  • Hero Member
  • *****
  • Posts: 4777
Re: Statement as memory barrier for globals ("volatile")
« Reply #55 on: December 07, 2017, 09:41:16 pm »
- If the memory is not ROM or EEPROM but any form of RAM that is mapped in by the OS..
- If sufficient rights
Then, yes, the absolute guarantees a fixed location and - at least on arm - the compiler obeys this even with regvar+.
To prevent the compiler from optimizing the second , I used the trick of J+ which *guarantees* a memory location.
Now what I see on arm is that it works like planned.
Any assignment is done on the register level, but the result is written back.

(Note of course this example will crash (loc 1 is not safe!) and just meant to examine its assembler output, but it works for e.g. the GPIO addresses on the Raspberry Pi.)
« Last Edit: December 07, 2017, 09:49:17 pm by Thaddy »
"Logically, no number of positive outcomes at the level of experimental testing can confirm a scientific theory, but a single counterexample is logically decisive."

kupferstecher

  • Full Member
  • ***
  • Posts: 142
Re: Statement as memory barrier for globals ("volatile")
« Reply #56 on: December 08, 2017, 12:39:11 am »
BUT it works on arm:
If I read the assembly correctly then temp is not stored to memory, but handled in a register, isn't? Then why would you use a writable typed constant instead of a variable?

Quote
I tried and had to change the example a bit.
The only difference I saw in your code is the initialisation of the typed constant, right? Why was that necessary?

molly

  • Hero Member
  • *****
  • Posts: 2037
Re: Statement as memory barrier for globals ("volatile")
« Reply #57 on: December 08, 2017, 12:51:26 am »
Why was that necessary?
Code: [Select]
Fatal: Syntax error, "=" expected but ";" foundIt is how constants work, also typed constants.

engkin

  • Hero Member
  • *****
  • Posts: 1758
Re: Statement as memory barrier for globals ("volatile")
« Reply #58 on: December 08, 2017, 05:31:15 am »
For i386:
Code: ASM  [Select]
  1. ; [10] t := 255;
  2.                 mov     al,255
  3.                 mov     byte ptr [+1],al
  4. ; [11] temp := t;
  5.                 mov     byte ptr [TC_$P$PROJECT1_$$_TEMP],al
  6.  

Notice how it did *not* read anything from the memory location specified by absolute . The optimizer is doing a good job for usual variables, but not what is needed here for volatile variables.

Let's try AVR:
Code: ASM  [Select]
  1. # [10] t := 255;
  2.         ldi     r26,-1
  3.         mov     r18,r26
  4.         sts     (+1),r18
  5. # [11] temp := t;
  6.         lds     r0,(+1)
  7.         sts     (TC_sPsPROJECT1_ss_TEMP),r0

At first it seems like it is doing what we need, but in fact there seem to be no optimization. See the highlighted line?

Again, no equivalent to volatile.

As Martin said:
Quote
If it isn't documented, then it can not be relied upon.

kupferstecher

  • Full Member
  • ***
  • Posts: 142
Re: Statement as memory barrier for globals ("volatile")
« Reply #59 on: December 08, 2017, 10:23:52 am »
It is how constants work, also typed constants.
Of course. Stupid me :)

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus