Re: [fpc-pascal] Can FPC optimize: if (s[i]='a') or ...

2019-04-15 Thread Rainer Stratmann
On Sonntag, 14. April 2019 21:35:43 CEST wkitt...@windstream.net wrote:
> On 4/14/19 7:28 AM, Rainer Stratmann wrote:
> > On Samstag, 13. April 2019 22:30:55 CEST Alexey Tor. wrote:
> >> E.g. i have a loop which test each s[i] char for several cases: 'a',
> >> 'b', 'c'.
> >> 
> >> for i:= 1 to length(s) do
> >> 
> >> if (s[i]='a') or (s[i]='b') or (s[i]='c') then ...
> >> 
> >> Can FPC optimize it so it only reads s[i] once (to register), not 3
> >> times?
> > 
> > You can optimise by yourself.
> > 
> > var
> > 
> >   c : char;
> >   l : longint;
> > 
> > begin
> > 
> >   l := length( s );
> >   for i := 1 to l do
> >   
> >c := s[ i ];
> >if ( c = 'a' ) or ( c = 'b' ) or ( c = 'c' ) then ...
> 
> this looks like it will read three times like the original instead of once
> like using the IN set operation... it is still stepping through each one of
> the comparison steps instead of just doing a set match...

It is at least better than reading s[ i ] at every compare operation.
Feel free to make more optimizations if there is a chance.
For example the IN operation.

if c in ['a', 'b', 'c'] then ...

You have to know the whole code to decide if it makes sense to drop the var c 
completely.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Can FPC optimize: if (s[i]='a') or ...

2019-04-15 Thread Sven Barth via fpc-pascal

Am 15.04.2019 um 09:06 schrieb Bernd Oppolzer:

Am 15.04.2019 um 08:29 schrieb Tomas Hajny:

On Mon, April 15, 2019 07:52, Bernd Oppolzer wrote:
  .
  .

On Samstag, 13. April 2019 22:30:55 CEST Alexey Tor. wrote:

  .
  .

Can FPC optimize it so it only reads s[i] once (to register), not 3
times?

  .
  .

True for New Stanford Pascal:

  .
  .

I fail to see how is this related to FPC or the question of the original
poster (who was explicitly asking about FPC). Could we stay on topic,
please?

Tomas
(one of FPC mailing list moderators)



well, I was hoping for an answer out of the FPC community
what FPC does to the different codings, so that the users can
get some guidelines out of it (for example: common subexpressions
in locigal expressions are not eliminated, so it is better to use the 
IN syntax -

or maybe the other way round). My mails were meant to motivate this :-)

but so far only suggestions how to optimize at the source code level.

(and of course: because FPC is sort of inspiration for my work,
I would like to see what FPC does in this cases and to compare it
with what I have)

Sorry about that ...
And you can't just test yourself? After all FPC is free and provides a 
"-al" option that keeps the assembly code around...


Anyway, take this code:

=== code begin ===

var
  c: Char;
begin
  c := 'A';
  if (c = 'a') or (c = 'b') or (c = 'c') then
    c := 'B';
  if c in ['a', 'b', 'c'] then
    c := 'B';
  if c in ['a', 'g', 'l'] then
    c := 'B';
end.

=== code end ===

The result on x86_64 with -O- will be this:

=== code begin ===

# [9] c := 'A';
    movb    $65,U_$P$TMW_$$_C(%rip)
# [10] if (c = 'a') or (c = 'b') or (c = 'c') then
    cmpb    $97,U_$P$TMW_$$_C(%rip)
    je    .Lj3
    jmp    .Lj4
.Lj4:
    cmpb    $98,U_$P$TMW_$$_C(%rip)
    je    .Lj3
    jmp    .Lj5
.Lj5:
    cmpb    $99,U_$P$TMW_$$_C(%rip)
    je    .Lj3
    jmp    .Lj6
.Lj3:
# [11] c := 'B';
    movb    $66,U_$P$TMW_$$_C(%rip)
.Lj6:
# [12] if c in ['a', 'b', 'c'] then
    movzbl    U_$P$TMW_$$_C(%rip),%eax
    subl    $97,%eax
    cmpl    $3,%eax
    jb    .Lj7
.Lj7:
    jc    .Lj8
    jmp    .Lj9
.Lj8:
# [13] c := 'B';
    movb    $66,U_$P$TMW_$$_C(%rip)
.Lj9:
# [14] if c in ['a', 'g', 'l'] then
    movzbl    U_$P$TMW_$$_C(%rip),%eax
    cmpl    $97,%eax
    je    .Lj10
    cmpl    $103,%eax
    je    .Lj10
    cmpl    $108,%eax
    je    .Lj10
.Lj10:
    je    .Lj11
    jmp    .Lj12
.Lj11:
# [15] c := 'B';
    movb    $66,U_$P$TMW_$$_C(%rip)

=== code end ===

With -O2 it will be this:

=== code begin ===

# Var c located in register dl
# [9] c := 'A';
    movb    $65,%dl
# [10] if (c = 'a') or (c = 'b') or (c = 'c') then
    cmpb    $97,%dl
    je    .Lj3
    cmpb    $98,%dl
    je    .Lj3
    cmpb    $99,%dl
    jne    .Lj6
.Lj3:
# [11] c := 'B';
    movb    $66,%dl
.Lj6:
# [12] if c in ['a', 'b', 'c'] then
    movzbl    %dl,%eax
    subl    $97,%eax
    cmpl    $3,%eax
    jnc    .Lj9
# [13] c := 'B';
    movb    $66,%dl
.Lj9:
# [14] if c in ['a', 'g', 'l'] then
    movzbl    %dl,%eax
    cmpl    $97,%eax
    je    .Lj11
    cmpl    $103,%eax
    je    .Lj11
    cmpl    $108,%eax
    je    .Lj11
    jne    .Lj12
.Lj11:
# [15] c := 'B';
    movb    $66,%dl

=== code end ===

So it optimized the variable access into a register, but the first 
if-condition is more like the third if-condition than the second.


Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Can FPC optimize: if (s[i]='a') or ...

2019-04-15 Thread Bernd Oppolzer

Am 15.04.2019 um 08:29 schrieb Tomas Hajny:

On Mon, April 15, 2019 07:52, Bernd Oppolzer wrote:
  .
  .

On Samstag, 13. April 2019 22:30:55 CEST Alexey Tor. wrote:

  .
  .

Can FPC optimize it so it only reads s[i] once (to register), not 3
times?

  .
  .

True for New Stanford Pascal:

  .
  .

I fail to see how is this related to FPC or the question of the original
poster (who was explicitly asking about FPC). Could we stay on topic,
please?

Tomas
(one of FPC mailing list moderators)



well, I was hoping for an answer out of the FPC community
what FPC does to the different codings, so that the users can
get some guidelines out of it (for example: common subexpressions
in locigal expressions are not eliminated, so it is better to use the IN 
syntax -

or maybe the other way round). My mails were meant to motivate this :-)

but so far only suggestions how to optimize at the source code level.

(and of course: because FPC is sort of inspiration for my work,
I would like to see what FPC does in this cases and to compare it
with what I have)

Sorry about that ...

Best regards

Bernd


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Can FPC optimize: if (s[i]='a') or ...

2019-04-15 Thread Tomas Hajny
On Mon, April 15, 2019 07:52, Bernd Oppolzer wrote:
 .
 .
>>> On Samstag, 13. April 2019 22:30:55 CEST Alexey Tor. wrote:
 .
 .
 Can FPC optimize it so it only reads s[i] once (to register), not 3
 times?
 .
 .
> True for New Stanford Pascal:
 .
 .

I fail to see how is this related to FPC or the question of the original
poster (who was explicitly asking about FPC). Could we stay on topic,
please?

Tomas
(one of FPC mailing list moderators)


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Can FPC optimize: if (s[i]='a') or ...

2019-04-14 Thread Bernd Oppolzer

Am 15.04.2019 um 03:35 schrieb wkitt...@windstream.net:

On 4/14/19 7:28 AM, Rainer Stratmann wrote:

On Samstag, 13. April 2019 22:30:55 CEST Alexey Tor. wrote:

E.g. i have a loop which test each s[i] char for several cases: 'a',
'b', 'c'.

for i:= 1 to length(s) do

if (s[i]='a') or (s[i]='b') or (s[i]='c') then ...

Can FPC optimize it so it only reads s[i] once (to register), not 3 
times?


You can optimise by yourself.

var
  c : char;
  l : longint;

begin
  l := length( s );
  for i := 1 to l do
   c := s[ i ];
   if ( c = 'a' ) or ( c = 'b' ) or ( c = 'c' ) then ...



this looks like it will read three times like the original instead of 
once like using the IN set operation... it is still stepping through 
each one of the comparison steps instead of just doing a set match...





True for New Stanford Pascal:

 23   1N   1)    for I := 1 to LENGTH ( S ) do
 24   2N   1)  begin
 25   2N   1)    C := S [ I ] ;
 26   2N   1)    if ( C = 'a' ) or ( C = 'b' ) or ( C = 'c' 
) then
 27   2N   1)  WRITELN ( I , '-tes Zeichen ist a, b 
oder c' ) ;

 28   2N   1)  end (* for *)

Lines without @@ = P-Code
Lines with @@ = IBM 370 Machine Code (Assembler notation)
as documented by Stage 2 (PASCAL2.PAS) when the A+ switch is set

 LOC  26 
 0250:   LOD  C,1,424
 0250:   LDC  C,'a'
 0250:   EQU  C
@@ 0250:   CLI   424(13),97  --- compare storage location with 'a'
 0254:   LOD  C,1,424
@@ 0254:   LA    2,1
@@ 0258:   BC    8,*+6
@@ 025C:   SR    2,2
 025E:   LDC  C,'b'
 025E:   EQU  C
@@ 025E:   CLI   424(13),98  --- compare storage location with 'b'
 0262:   IOR  B
@@ 0262:   LA    3,1
@@ 0266:   BC    8,*+6
@@ 026A:   SR    3,3
@@ 026C:   OR    2,3
 026E:   LOD  C,1,424
 026E:   LDC  C,'c'
 026E:   EQU  C
@@ 026E:   CLI   424(13),99  --- compare storage location with 'c'
 0272:   IOR  B
@@ 0272:   LA    3,1
@@ 0276:   BC    8,*+6
@@ 027A:   SR    3,3
@@ 027C:   OR    2,3
 027E:   FJP  L16
@@ 027E:   BC    8,L16


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Can FPC optimize: if (s[i]='a') or ...

2019-04-14 Thread wkitty42

On 4/14/19 7:28 AM, Rainer Stratmann wrote:

On Samstag, 13. April 2019 22:30:55 CEST Alexey Tor. wrote:

E.g. i have a loop which test each s[i] char for several cases: 'a',
'b', 'c'.

for i:= 1 to length(s) do

if (s[i]='a') or (s[i]='b') or (s[i]='c') then ...

Can FPC optimize it so it only reads s[i] once (to register), not 3 times?


You can optimise by yourself.

var
  c : char;
  l : longint;

begin
  l := length( s );
  for i := 1 to l do
   c := s[ i ];
   if ( c = 'a' ) or ( c = 'b' ) or ( c = 'c' ) then ...



this looks like it will read three times like the original instead of once like 
using the IN set operation... it is still stepping through each one of the 
comparison steps instead of just doing a set match...



--
 NOTE: No off-list assistance is given without prior approval.
   *Please keep mailing list traffic on the list unless*
   *a signed and pre-paid contract is in effect with us.*
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Can FPC optimize: if (s[i]='a') or ...

2019-04-14 Thread Bernd Oppolzer

Am 13.04.2019 um 21:55 schrieb Ralf Quint:

On 4/13/2019 12:30 PM, Alexey Tor. wrote:
E.g. i have a loop which test each s[i] char for several cases: 'a', 
'b', 'c'.


for i:= 1 to length(s) do

if (s[i]='a') or (s[i]='b') or (s[i]='c') then ...

Can FPC optimize it so it only reads s[i] once (to register), not 3 
times?



How about writing it in Pascal, something like

if s[i] in ['a'..'c'] then

or in case of no-sequential characters/values

if s[i] in ['a', 'b', 'c'] then...


Ralf



I'd like to second that ... the benefit that the optimizer may get
when IN is used ...

I would like to show you what my New Stanford Pascal compiler does;
it does not eliminate the common expressions s[i], but evaluates
them 3 times, given the original coding. But when the IN expression is used
(this coding: if s[i] in ['a', 'b', 'c'] then...)
it does a very good job. Because the three constants in the set are a
close range without holes in it, it checks in fact the range.

This is how it looks in IBM 370 ASSEMBLY language:

@@ 01AE:   SR    3,3      -- clear register 3
@@ 01B0:   IC    3,404(13,2)      -- insert character s[i] into 
register 3 (register 2 has index i, 404/13 is the address of s)
@@ 01B4:   AH    3,=H'-97'      -- subtract constant 'a' - should be 
EBCDIC 'a', but is ASCII 'a', because I tested on the PC :-)

@@ 01B8:   CL    3,=F'2'      -- check, if register 3 is between 0 and 2
@@ 01BC:   BC    2,L12      -- branch, if not

This is the result after the second step of the translation;
the first step is the translation to P-Code. The P-Code looks like this
(the Index I is on top of the stack at the beginning, the address of
S at the second position):

 01AE:   DEC  I,1  -- dec top of stack
 01AE:   IXA  1      -- use top of stack as index for 
address at second position
 01AE:   IND  C,0      -- replace top of stack (= address) 
with content of type char

 01AE:   ORD  -- convert to integer (does nothing)
 01B4:   LCA  S,C32'abc'  -- load character set constant
 01B4:   SLD  32,432  -- convert to binary set 
representation

 01B4:   INN  -- implement IN on elements on stack
 01BC:   FJP  L12  -- jump false

On the IBM mainframe, this P-Code is translated to what you see above.
On the other platforms (Windows, Linux, ...), the P-Code is interpreted -
a version of the compiler which generates native code on these platforms
has still to be done. But anyway: the language is fully portable, the 
results

are the same. (The P-Code is portable, the 370 implementation is of course
NOT portable - hence the problem when testing the 370 translation on the 
PC).


The optimization (implementing IN as a range check in this case) is
in fact done in stage 2, that is: in the P-Code to 370 translator.
The credits for this very fine compiler technology (which is about
40 years old) does not belong to me, but to many other people who
worked on this in the 1975 to 1990 era. I only did some extensions
to it in the last few years and ported the compiler to Windows and
Linux etc.

More information:

http://bernd-oppolzer.de/job9.htm
https://www.facebook.com/StanfordPascal

Kind regards

Bernd


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Can FPC optimize: if (s[i]='a') or ...

2019-04-14 Thread Rainer Stratmann
On Samstag, 13. April 2019 22:30:55 CEST Alexey Tor. wrote:
> E.g. i have a loop which test each s[i] char for several cases: 'a',
> 'b', 'c'.
> 
> for i:= 1 to length(s) do
> 
> if (s[i]='a') or (s[i]='b') or (s[i]='c') then ...
> 
> Can FPC optimize it so it only reads s[i] once (to register), not 3 times?

You can optimise by yourself.

var
 c : char;
 l : longint;

begin
 l := length( s );
 for i := 1 to l do
  c := s[ i ];
  if ( c = 'a' ) or ( c = 'b' ) or ( c = 'c' ) then ...

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Can FPC optimize: if (s[i]='a') or ...

2019-04-13 Thread Ralf Quint

On 4/13/2019 12:30 PM, Alexey Tor. wrote:
E.g. i have a loop which test each s[i] char for several cases: 'a', 
'b', 'c'.


for i:= 1 to length(s) do

if (s[i]='a') or (s[i]='b') or (s[i]='c') then ...

Can FPC optimize it so it only reads s[i] once (to register), not 3 
times?



How about writing it in Pascal, something like

if s[i] in ['a'..'c'] then

or in case of no-sequential characters/values

if s[i] in ['a', 'b', 'c'] then...


Ralf


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

[fpc-pascal] Can FPC optimize: if (s[i]='a') or ...

2019-04-13 Thread Alexey Tor.
E.g. i have a loop which test each s[i] char for several cases: 'a', 
'b', 'c'.


for i:= 1 to length(s) do

if (s[i]='a') or (s[i]='b') or (s[i]='c') then ...

Can FPC optimize it so it only reads s[i] once (to register), not 3 times?

--
Regards,
Alexey

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal