Dear all,

A few days ago I posted the following to <news://comp.lang.pl1>, addressed specifically to Peter Elderon:

Given part of a compiler listing (V5.2.2) below (and this is the code generated for the current source, which has been updated a bit over the weekend)

0038E8  D204  3AC0  BA0E  004142 |
0038EE  D209  7000  6564  004142 |
0038F4  E350  DF14  0771  004142 |
0038FA  D100  3AC7  BA12  004142 |
003900  D407  3AC0  2397  004142 |
003906  E310  D168  0258  004142 |
00390C  E360  DEA0  0771  004143 |
003912  D207  3A98  3AC0  004142 |
003918  E380  D10C  0958  004143 |
00391E  D707  3A90  3A90  004142 |
003924  FDF1  3A90  238D  004142 |
00392A  E390  D110  0958  004143 |
003930  F87D  EF60  3A90  004142 |
003936  D204  EF84  EF63  004142 |
00393C  E300  DF14  0773  004142 |
003942  C00B  0000  000F  004142 |
003948  E300  DF14  0772  004142 |
00394E  DE09  7000  5000  004142 |
003954  E300  DF1E  0795  004142 |
00395A  4000  1044        004142 |
00395E  E310  D168  0258  004143 |
003964  D204  EF84  BA0E  004143 |
00396A  F854  3AC8  BA0E  004143 |
003970  E350  D0F8  0958  004143 |
003976  D205  3A9A  3AC8  004143 |
00397C  D709  3A90  3A90  004143 |
003982  4110  1047        004143 |
003986  E370  D108  0958  004143 |
00398C  FDF1  3A90  238D  004143 |
003992  D201  EF7F  3A9E  004143 |
003998  D201  3ACE  EF7F  004143 |
00399E  F910  EF7F  238B  004143 |
0039A4  E3A0  D114  0958  004143 |
0039AA  A7B4  001A        004143 |
0039AE  D201  3AD1  3ACE  004143 |
0039B4  9200  3AD0        004143 |
0039B8  FA21  3AD0  238F  004143 |
0039BE  F812  3AD4  3AD0  004143 |
0039C4  91F0  3AD4        004143 |
0039C8  A784  0008        004143 |
0039CC  F010  3AD4  0001  004143 |
0039D2  F010  3AD4  0FFF  004143 |
0039D8                    004143 |
0039D8  D201  EF7F  3AD4  004143 |
0039DE                    004143 |
0039DE  E320  DF0F  0771  004143 |

compiled with OPT(3) are the 004142 and 004143 actually really exclusively referring to statements 4142 and 4143? Because if they do...

And, maybe not surprisingly, only one person replied with a

"And the corresponding PL/I source is ?"

Note for what follows: PL/I has a truckload of builtin functions to work with dates and times, but none of them seem to cater for times in just minutes, as opposed to seconds or even micro-seconds.

The reason for asking the question? The two statements in question

min_max_line.t_max_hh = dtot.t_max / 60;
min_max_line.t_max_mm = mod(dtot.t_max, 60);

copy a time (in minutes, in packed format) to a print-line, in hh:mm format, which means splitting up said time into hh & mm by a division and a remainder, which, given that times can not be negative, can use PL/I's "MOD(ulo)" builtin function although obviously(!) that is not the best thing to do, as modulo and remainder may not have the same sign, given that modulo is defined as

"the smallest ***nonnegative*** value, R, such that (x - R)/y = n"

which immediately would suggest that IBM could/should add an optional third parameter to the "MOD" builtin function that can have the value 'U' to indicate that both other parameters should be treated as "U(nsigned)" (and no post-processing is required on the remainder to turn it into modulo), or add a new "UMOD" builtin function to do the same.

That's my first issue out of the way...

However, we're living AD 2020, Enterprise PL/I is an optimizing compiler, and so it should make use of everything that the underlying hardware offers, and opening the PoP and the description of the "DP Divide Decimal" instruction tells us that, emphasis (***) added:

"The first operand (the dividend) is divided by the second operand (the
divisor). The resulting quotient ***and*** remainder are placed at the first-
operand location. The operands and results are in the signed-packed decimal 
format."

Which is just what we need, and similar to what the x86 and AMD64 architectures do (RAX/EAX/AX/AH: quotient, RDX/EDX/DX/AH: remainder), so only one DP should be required, but obviously that's something Enterprise PL/I misses, and, for what it's worth, I've got no clue as to what modern C compilers on the white-box platform might be doing, but this immediately suggests another new PL/I builtin function, "QUOTREM()", that might be invoked as

"quotient = QUOTREM(dividend, divisor], remainder]);",

where "remainder" is optional, although that's admittedly (more than) a bit 
silly.

That's issue two out of the way...

However, now we go for the real issue, the generated code, which seems to be a bit long-winded. Or rather more than that! A hell of a lot more!

I'm fortunate enough, don't ask, to still have access to the old

"5668-910 IBM OS PL/I OPTIMIZING COMPILER  VER 2 REL 3 MOD 0"

and here's what it generates for those two statements. I've cut the relevant lines to 79 chars to hopefully avoid wrapping:

5668-910 IBM OS PL/I OPTIMIZING COMPILER  VER 2 REL 3 MOD 0
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
                       2 MIN_MAX_INIT    CHAR     (121)
                 INIT ((' |      |      |       |       |       |        ' ||
                                '|        |        |   :   |   :   |   :   |')),
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
      21   1  0  DCL 1 MIN_MAX_LINE BASED(LINE_PTR),
                       2 Z00069          CHAR       (3),
                       2 MODE            CHAR       (4),
                       2 Z00070          CHAR       (3),
                       2 #MIMA           PIC     'zzz9',
                       2 Z00071          CHAR       (3),
                       2 V_MAXR          PIC   'zz9v.9',
                       2 Z00072          CHAR       (3),
                       2 V_MINR          PIC   'zz9v.9',
                       2 Z00073          CHAR       (3),
                       2 V_AVG           PIC   'zz9v.9',
                       2 Z00074          CHAR       (3),
                       2 L_MAX           PIC  'zzz9v.9',
                       2 Z00075          CHAR       (3),
                       2 L_MIN           PIC  'zzz9v.9',
                       2 Z00076          CHAR       (3),
                       2 L_AVG           PIC  'zzz9v.9',
                       2 Z00077          CHAR       (3),
                       2 T_MAX_HH        PIC       'z9',
                       2 Z00078          CHAR       (1),
                       2 T_MAX_MM        PIC       '99',
                       2 Z00079          CHAR       (3),
                       2 T_MIN_HH        PIC       'z9',
                       2 Z00080          CHAR       (1),
                       2 T_MIN_MM        PIC       '99',
                       2 Z00081          CHAR       (3),
                       2 T_AVG_HH        PIC       'z9',
                       2 Z00082          CHAR       (1),
                       2 T_AVG_MM        PIC       '99';
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
      27   1  0  DCL 1 LIFT_WORK,
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
                       2 LINE_PTR        PTR            INIT (ADDR(LINE)),
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
                       2 LINE            CHAR     (121) INIT ((121)' '),
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
     369   1  0  LINE                  = MIN_MAX_INIT;
     370   1  0  MIN_MAX_LINE.MODE     = 'Tot ';
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
     378   1  0  MIN_MAX_LINE.T_MAX_HH = DTOT.T_MAX / 60;
     379   1  0  MIN_MAX_LINE.T_MAX_MM = MOD(DTOT.T_MAX, 60);
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
* STATEMENT NUMBER  369        (1)
002D68  58 B0 3 818               L     11,2072(0,3)
002D6C  58 70 D 0CC               L     7,204(0,13)
002D70 D2 78 7 91B B 794 MVC LIFT_WORK.LINE(121),LIFT_STATIC.MIN_MAX_INIT (a wrapped line, sorry)

* STATEMENT NUMBER  370        (1)
002D76  58 F0 9 2C8               L     15,LIFT_WORK.LINE_PTR
002D7A  58 E0 3 810               L     14,2064(0,3)
002D7E  D2 03 F 003 E A49         MVC   MIN_MAX_LINE.MODE(4),2633(14)
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
* STATEMENT NUMBER  378        (1)
002E94  D7 09 D 098 D 098         XC    WKSP.1+32(10),WKSP.1+32
002E9A  D2 04 D 09A 7 B2E         MVC   WKSP.1+34(5),LIFT_WORK.DTOT.T_MAX
002EA0  94 F0 D 09E               NI    WKSP.1+38,X'F0'
002EA4  D1 00 D 0A1 7 B32         MVN   WKSP.1+41(1),LIFT_WORK.DTOT.T_MAX+4
002EAA  FD 91 D 098 E 9E5         DP    WKSP.1+32(10),2533(2,14)
002EB0  D2 07 4 308 D 098         MVC   776(8,4),WKSP.1+32
002EB6  D2 03 4 310 8 130         MVC   784(4,4),304(8)
002EBC  DE 03 4 310 4 30B         ED    784(4,4),779(4)
002EC2  D2 01 F 044 4 312         MVC   MIN_MAX_LINE.T_MAX_HH(2),786(4)

* STATEMENT NUMBER  379        (1)
002EC8  D2 01 4 308 E 9E5         MVC   776(2,4),2533(14)
002ECE  F8 94 D 098 7 B2E         ZAP   WKSP.1+32(10),LIFT_WORK.DTOT.T_MAX(5)
002ED4  FD 91 D 098 4 308         DP    WKSP.1+32(10),776(2,4)
002EDA  D2 01 4 30A D 0A0         MVC   778(2,4),WKSP.1+40
002EE0  50 F0 4 390               ST    15,912(0,4)
002EE4  F9 10 4 30A E 9B1         CP    778(2,4),2481(1,14)
002EEA  47 B0 2 754               BNL   CL.3727
002EEE  94 FE 4 309               NI    777(4),X'FE'
002EF2  FA 11 4 30A 4 308         AP    778(2,4),776(2,4)
002EF8                    CL.3727 EQU   *
002EF8  D2 01 4 308 4 30A         MVC   776(2,4),778(4)
002EFE  58 E0 4 390               L     14,912(0,4)
002F02  F3 11 E 047 4 308         UNPK  MIN_MAX_LINE.T_MAX_MM(2),776(2,4)
002F08  96 F0 E 048               OI    MIN_MAX_LINE.T_MAX_MM+1,X'F0'

Note that the listing is post-processed to merge the originally split the generated assembler and to add execution counts to the "* STATEMENT NUMBER" lines.

Count? 22 instructions for the two statements, the destination (R15) is loaded once in statement 369, for a total of 23 instructions, or let's just go for the lot, 28 assembler statements for the four PL/I statements.

Now sit back and look at what a even whiter and shinier compiler AD 2018 produces, and yes, the listing has been heavily white-space edited to avoid wrapping:

5655-PL5  IBM(R) Enterprise PL/I for z/OS       V5.R2.M2 (Built:20180530)
  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
    1178.0                    2 min_max_init    char     (121)
    1179.0      init ((' |      |      |       |       |       |        ' ||
    1180.0             '|        |        |   :   |   :   |   :   |')),
  -  -  -    -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
    2135.0   21  1      dcl 1 min_max_line based(line_ptr),
    2136.0                    2 *               char       (3),
    2137.0                    2 mode            char       (4),
    2138.0                    2 *               char       (3),
    2139.0                    2 #mima           pic     'zzz9',
    2140.0                    2 *               char       (3),
    2141.0                    2 v_maxr          pic   'zz9v.9',
    2142.0                    2 *               char       (3),
    2143.0                    2 v_minr          pic   'zz9v.9',
    2144.0                    2 *               char       (3),
    2145.0                    2 v_avg           pic   'zz9v.9',
    2146.0                    2 *               char       (3),
    2147.0                    2 l_max           pic  'zzz9v.9',
    2148.0                    2 *               char       (3),
    2149.0                    2 l_min           pic  'zzz9v.9',
    2150.0                    2 *               char       (3),
    2151.0                    2 l_avg           pic  'zzz9v.9',
    2152.0                    2 *               char       (3),
    2153.0                    2 t_max_hh        pic       'z9',
    2154.0                    2 *               char       (1),
    2155.0                    2 t_max_mm        pic       '99',
    2156.0                    2 *               char       (3),
    2157.0                    2 t_min_hh        pic       'z9',
    2158.0                    2 *               char       (1),
    2159.0                    2 t_min_mm        pic       '99',
    2160.0                    2 *               char       (3),
    2161.0                    2 t_avg_hh        pic       'z9',
    2162.0                    2 *               char       (1),
    2163.0                    2 t_avg_mm        pic       '99';
  -  -  -    -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
    2256.0   27  1      dcl 1 lift_work,
  -  -  -    -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
    2468.0                    2 line_ptr        ptr       init (addr(line)),
  -  -  -    -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
    2532.0                    2 line            char   (121) init ((121)' '),
  -  -  -    -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
    4128.0  405  1      line                  = min_max_init;
    4129.0  406  1      min_max_line.mode     = 'Tot ';
  -  -  -    -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
    4142.0  414  1      min_max_line.t_max_hh = dtot.t_max / 60;
    4143.0  415  1      min_max_line.t_max_mm = mod(dtot.t_max, 60);
  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
0035D0  58E0  4000       4128  L    r14,=A(***LIFT2)(,r4,0)
0035D4  C0B0  0001  B58E 4129  LARL r11,F'112014'
0035DA  E3F0  D7BB  0471 4128  LAY  r15,LINE(,r13,18363)
  -  -  -  -  -  -  -  -  -  - -  - -  -  -  -  -  -  -  -  -  -  -  -  -  -
0035E6  E310  E4CC  0671 4128  LAY  r1,MIN_MAX_INIT(,r14,25804)
0035EC  E3E0  D168  0258 4129  LY   r14,<a1:d8552:l4>(,r13,8552)
0035F2  D278  F000  1000 4128  MVC  LINE(121,r15,0),MIN_MAX_INIT(r1,0)
0035F8  5800  B558       4129  L    r0,<s3864:d1368:l4>(,r11,1368)
  -  -  -  -  -  -  -  -  -  - -  - -  -  -  -  -  -  -  -  -  -  -  -  -  -
003602  5000  E003       4129  ST   r0,_shadow17(,r14,3)
  -  -  -  -  -  -  -  -  -  - -  - -  -  -  -  -  -  -  -  -  -  -  -  -  -
003802  D201  3AD8  238D 4142
                         MVC  #pd55727_1(2,r3,2776),+CONSTANT_AREA(r2,909)
  -  -  -  -  -  -  -  -  -  - -  - -  -  -  -  -  -  -  -  -  -  -  -  -  -
00382A  E370  DF1C  0771 4142  LAY  r7,_temp40(,r13,32540)
  -  -  -  -  -  -  -  -  -  - -  - -  -  -  -  -  -  -  -  -  -  -  -  -  -
0038D0  D200  3AD6  238B 4143
                         MVC  #pd55702_1(1,r3,2774),+CONSTANT_AREA(r2,907)
  -  -  -  -  -  -  -  -  -  - -  - -  -  -  -  -  -  -  -  -  -  -  -  -  -
0038E8  D204  3AC0  BA0E 4142  MVC  #pd45865_1(5,r3,2752),T_MAX(r11,2574)
0038EE  D209  7000  6564 4142  MVC  _temp40(10,r7,0),' .........'(r6,1380)
0038F4  E350  DF14  0771 4142  LAY  r5,_temp39(,r13,32532)
0038FA  D100  3AC7  BA12 4142  MVN  #pd45865_1(1,r3,2759),T_MAX(r11,2578)
003900  D407  3AC0  2397 4142
                         NC   #pd45865_1(8,r3,2752),+CONSTANT_AREA(r2,919)
003906  E310  D168  0258 4142  LY   r1,<a1:d8552:l4>(,r13,8552)
00390C  E360  DEA0  0771 4143  LAY  r6,_temp25(,r13,32416)
003912  D207  3A98  3AC0 4142  MVC  #pd46742_1(8,r3,2712),#pd45865_1(r3,2752)
003918  E380  D10C  0958 4143  LY   r8,#SPILL32(,r13,37132)
00391E  D707  3A90  3A90 4142  XC   #pd46742_1(8,r3,2704),#pd46742_1(r3,2704)
003924  FDF1  3A90  238D 4142
                         DP   #pd46742_1(16,r3,2704),+CONSTANT_AREA(2,r2,909)
00392A  E390  D110  0958 4143  LY   r9,#SPILL33(,r13,37136)
003930  F87D  EF60  3A90 4142  ZAP  _temp33(8,r14,3936),#pd46742_1(14,r3,2704)
003936  D204  EF84  EF63 4142  MVC  _temp39(5,r14,3972),_temp33(r14,3939)
00393C  E300  DF14  0773 4142  ICY  r0,<a1:d32532:l1>(,r13,32532)
003942  C00B  0000  000F 4142  NILF r0,F'15'
003948  E300  DF14  0772 4142  STCY r0,<a1:d32532:l1>(,r13,32532)
00394E  DE09  7000  5000 4142  ED   _temp40(10,r7,0),_temp39(r5,0)
003954  E300  DF1E  0795 4142  LLH  r0,<a1:d32542:l2>(,r13,32542)
00395A  4000  1044       4142  STH  r0,_shadow20(,r1,68)
00395E  E310  D168  0258 4143  LY   r1,<a1:d8552:l4>(,r13,8552)
003964  D204  EF84  BA0E 4143  MVC  _temp39(5,r14,3972),T_MAX(r11,2574)
00396A  F854  3AC8  BA0E 4143  ZAP  #pd45874_1(6,r3,2760),T_MAX(5,r11,2574)
003970  E350  D0F8  0958 4143  LY   r5,#SPILL27(,r13,37112)
003976  D205  3A9A  3AC8 4143  MVC  #pd46742_1(6,r3,2714),#pd45874_1(r3,2760)
00397C  D709  3A90  3A90 4143  XC   #pd46742_1(10,r3,2704),#pd46742_1(r3,2704)
003982  4110  1047       4143  LA   r1,#AddressShadow(,r1,71)
003986  E370  D108  0958 4143  LY   r7,#SPILL31(,r13,37128)
00398C  FDF1  3A90  238D 4143
                         DP   #pd46742_1(16,r3,2704),+CONSTANT_AREA(2,r2,909)
003992  D201  EF7F  3A9E 4143  MVC  _temp38(2,r14,3967),#pd46742_1(r3,2718)
003998  D201  3ACE  EF7F 4143  MVC  #pd1753_1(2,r3,2766),_temp38(r14,3967)
00399E  F910  EF7F  238B 4143  CP   _temp38(2,r14,3967),+CONSTANT_AREA(1,r2,907)
0039A4  E3A0  D114  0958 4143  LY   r10,#SPILL34(,r13,37140)
0039AA  A7B4  001A       4143  JNL  @1L599
0039AE  D201  3AD1  3ACE 4143  MVC  #pd1756_1(2,r3,2769),#pd1753_1(r3,2766)
0039B4  9200  3AD0       4143  MVI  #pd1756_1(r3,2768),0
0039B8  FA21  3AD0  238F 4143
                         AP   #pd1756_1(3,r3,2768),+CONSTANT_AREA(2,r2,911)
0039BE  F812  3AD4  3AD0 4143  ZAP  #pd1757_1(2,r3,2772),#pd1756_1(3,r3,2768)
0039C4  91F0  3AD4       4143  TM   #pd1757_1(r3,2772),240
0039C8  A784  0008       4143  JE   @1L18801
0039CC  F010  3AD4  0001 4143  SRP  #pd1757_1(2,r3,2772),1,0
0039D2  F010  3AD4  0FFF 4143  SRP  #pd1757_1(2,r3,2772),-1,0
0039D8                   4143 @1L18801   DS       0H
0039D8  D201  EF7F  3AD4 4143  MVC      _temp38(2,r14,3967),#pd1757_1(r3,2772)
0039DE                   4143 @1L599     DS       0H
0039DE  E320  DF0F  0771 4143  LAY r2,_temp38(,r13,32527)
  -  -  -  -  -  -  -  -  -  ---  --  -  -  -  -  -  -  -  -  -  -  -  -  -  -
0039F0  C0E0  0001  B380 4143  LARLr14,F'111488'
0039F6  E330  DF88  0771 4143  LAY r3,#PDTEMPS1(,r13,32648)
0039FC  F311  1000  2000 4143  UNPK_shadow20(2,r1,0),_temp38(2,r2,0)
003A02  96F0  1001       4143  OI  _shadow20(r1,1),240
  -  -  -  -  -  -  -  -  -  ---  --  -  -  -  -  -  -  -  -  -  -  -  -  -  -
003A12  4120  EFF1       4143  LA  r2,+CONSTANT_AREA(,r14,4081)

This time I count 60(!) assembler instructions for the four PL/I statements, and if you start deleting statements that occur in both listings, don't worry, I've done it for you, there are six statements in the "VER 2 REL 3 MOD 0" listing that do not match 38(!) statements in the "V5.R2.M2", or maybe 5/37 if I'm allowed to equate "BNL" with "JNL"

Maybe someone can explain what's happening?

For what it's worth, few years ago I gate-crashed a GSE PL/I + COBOL meeting, in Eisenach (Germany) and there one of the IBM'ers (not Peter Elderon!) told me that IBM compilers were the pinnacle, and years ahead of anything Open Source.

In fact I've read this, cannot find the source right now, about the old OS Compiler, and that is indeed a one of a kind, capable of still generating working code from code that comes close to letting a monkey use a terminal!

However, given that people pay a substantial amount of money to use Enterprise PL/I, I think that compiler could do with a bit more TLC...

Robert
--
Robert AH Prins
robert.ah.prins(a)gmail.com
The hitchhiking grandfather - https://prino.neocities.org/indez.html
Some REXX code for use on z/OS - https://prino.neocities.org/zOS/zOS-Tools.html

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN

Reply via email to