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

Sven Barth pascaldragon at googlemail.com
Mon Apr 15 09:48:27 CEST 2019


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



More information about the fpc-pascal mailing list