Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.compilers > #613 > unrolled thread

Decades of compiler technology and what do we get?

Started byRobert AH Prins <robert@prino.org>
First post2012-04-22 18:57 +0000
Last post2012-09-30 10:45 +1000
Articles 17 — 4 participants

Back to article view | Back to comp.compilers


Contents

  Decades of compiler technology and what do we get? Robert AH Prins <robert@prino.org> - 2012-04-22 18:57 +0000
    Re: Decades of compiler technology and what do we get? Robert AH Prins <robert@prino.org> - 2012-04-22 22:14 +0000
    Re: PL/I nostalgia, was Decades of compiler technology and what do we get? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-04-23 00:03 +0000
      Re: PL/I nostalgia "robin" <robin51@dodo.com.au> - 2012-04-25 09:07 +1000
        Re: PL/I nostalgia glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-04-24 23:52 +0000
          Re: PL/I nostalgia "robin" <robin51@dodo.com.au> - 2012-04-28 21:30 +1000
            Re: PL/I nostalgia glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-04-28 16:11 +0000
              Re: PL/I nostalgia Robert A Duff <bobduff@shell01.TheWorld.com> - 2012-04-29 10:16 -0400
              Re: PL/I code "robin" <robin51@dodo.com.au> - 2012-05-05 00:45 +1000
                Re: PL/I code glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-05-05 05:20 +0000
                  Re: Fortran calls, was PL/I code glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-05-06 05:13 +0000
                    Re: Archaic hardware (was Fortran calls) "robin" <robin51@dodo.com.au> - 2012-05-09 10:46 +1000
            Re: PL/I nostalgia "robin" <robin51@dodo.com.au> - 2012-09-19 11:04 +1000
              Re: PL/I nostalgia glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-09-19 03:56 +0000
                Re: PL/I nostalgia "robin" <robin51@dodo.com.au> - 2012-09-21 13:53 +1000
                  Re: PL/I nostalgia glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-09-21 07:00 +0000
                    Re: PL/I nostalgia "robin" <robin51@dodo.com.au> - 2012-09-30 10:45 +1000

#613 — Decades of compiler technology and what do we get?

FromRobert AH Prins <robert@prino.org>
Date2012-04-22 18:57 +0000
SubjectDecades of compiler technology and what do we get?
Message-ID<12-04-070@comp.compilers>
On Apr 22, 12:58 pm, "HeyBub" <hey...@NOSPAMgmail.com> wrote in
bit.listserv.ibm-main:

 > > Nomen Nescio wrote:
 > >
 > > >> Then, as I said, write the damn thing in assembly language.
 > >
 > > > There isn't any need. We're fixing existing COBOL and it's easy to
 > > > fix. Just take stuff out of loops that doesn't belong there! It
 > > > works great..
 > >
 > > Is there still a compiler out there that doesn't change:
 > >
 > > PERFORM My-Many TIMES
 > >   MOVE 10 TO My-Constant
 > >   [do something else]
 > > END PERFORM.
 > >
 > > to
 > >
 > > MOVE 10 TO My-Constant
 > > PERFORM My-Many TIMES
 > >   [do something else]
 > > END-PERFORM.
 > >
 > > ???

To which yours truly replied:

 > Oh yes there is, that miracle of a compiler technology called
 > Enterprise PL/I V3R9...
 >
 > 70.0  19  1      do i = 1 to 10;
 > 71.0  20  1  1     do j = 1 to 10;
 > 72.0  21  1  2       t = 'Oops';
 > 73.0  22  1  2       put skip list(substr(t, 1, 1));
 > 74.0  23  1  2     end;
 > 75.0  24  1  1   end;
 >
 > 0000B2 4100 0001      000070 |       LA    r0,1
 > 0000B6 5000 D0CC      000070 |       ST    r0,I(,r13,204)
 > 0000BA A70E 000A      000070 |       CHI   r0,H'10'
 > 0000BE A724 0063      000070 |       JH    @1L8
 >
 > 0000C2                000070 | @1L2  DS    0H
 > 0000C2 4100 0001      000071 |       LA    r0,1
 > 0000C6 5000 D0D0      000071 |       ST    r0,J(,r13,208)
 > 0000CA A70E 000A      000071 |       CHI   r0,H'10'
 > 0000CE A724 0051      000071 |       JH    @1L10
 >
 > 0000D2                000071 | @1L5  DS    0H
 > 0000D2 D203 D0D4 700C 000072 |       MVC   T(4,r13,212),'Oops'(r7,12)
<=== Oops... (wrapped)
 > 0000D8 4110 D0D8      000072 |       LA    r1,T(,r13,216)
 > 0000DC 5010 D180      000072 |       ST    r1,#STRTEMP1(,r13,384)
 > 0000E0 9240 1000      000072 |       MVI   T(r1,0),64
 > 0000E4 D219 1001 1000 000072 |       MVC   T(26,r1,1),T(r1,0)
 > 0000EA 4100 D100      000073 |       LA    r0,_temp2(,r13,256)
 > 0000EE 5000 D170      000073 |       ST    r0,_temp3(,r13,368)
 > 0000F2 E544 D12C 4E48 000073 |       MVHHI _temp2(r13,300),H'20040'
 > 0000F8 5800 6004      000073 |       L     r0,SYSPRINT(,r6,4)
 > 0000FC 5000 D16C      000073 |       ST    r0,_temp3(,r13,364)
 > 000100 E54C D100 0001 000073 |       MVHI  _temp2(r13,256),H'1'
 > 000106 4100 D168      000073 |       LA    r0,_temp3(,r13,360)
 > 00010A 58F0 3008      000073 |       L     r15,=V(IBMQOFNT)(,r3,8)
 > 00010E 4110 D098      000073 |       LA    r1,#MX_TEMP1(,r13,152)
 > 000112 5000 D098      000073 |       ST    r0,#MX_TEMP1(,r13,152)
 > 000116 0DEF           000073 |       BASR  r14,r15
 >
 > 000118 4100 6008      000073 |       LA    r0,_Dsc_000001(,r6,8)
 > 00011C 5000 D11C      000073 |       ST    r0,_temp2(,r13,284)
 > 000120 4100 7010      000073 |       LA    r0,'..'(,r7,16)
 > 000124 5000 D118      000073 |       ST    r0,_temp2(,r13,280)
 > 000128 4100 D0D4      000073 |       LA    r0,T(,r13,212)
 > 00012C 5000 D114      000073 |       ST    r0,_temp2(,r13,276)
 > 000130 9220 D12E      000073 |       MVI   _temp2(r13,302),32
 > 000134 4100 D168      000073 |       LA    r0,_temp3(,r13,360)
 > 000138 58F0 300C      000073 |       L     r15,=V(IBMQOFPT)(,r3,12)
 > 00013C 4110 D098      000073 |       LA    r1,#MX_TEMP1(,r13,152)
 > 000140 5000 D098      000073 |       ST    r0,#MX_TEMP1(,r13,152)
 > 000144 0DEF           000073 |       BASR  r14,r15
 >
 > 000146 9201 D12E      000073 |       MVI   _temp2(r13,302),1
 > 00014A 4100 D168      000073 |       LA    r0,_temp3(,r13,360)
 > 00014E 58F0 300C      000073 |       L     r15,=V(IBMQOFPT)(,r3,12)
 > 000152 4110 D098      000073 |       LA    r1,#MX_TEMP1(,r13,152)
 > 000156 5000 D098      000073 |       ST    r0,#MX_TEMP1(,r13,152)
 > 00015A 0DEF           000073 |       BASR  r14,r15
 >
 > 00015C                000074 | @1L6  DS    0H
 > 00015C                000074 | @1L11 DS    0H
 > 00015C 5800 D0D0      000074 |       L     r0,J(,r13,208)
 > 000160 A70A 0001      000074 |       AHI   r0,H'1'
 > 000164 5000 D0D0      000074 |       ST    r0,J(,r13,208)
 > 000168 A70E 000A      000074 |       CHI   r0,H'10'
 > 00016C A7D4 FFB3      000074 |       JNH   @1L5
 >
 > 000170                000074 | @1L7  DS    0H
 > 000170                000074 | @1L10 DS    0H
 > 000170                000075 | @1L3  DS    0H
 > 000170                000075 | @1L9  DS    0H
 > 000170 5800 D0CC      000075 |       L     r0,I(,r13,204)
 > 000174 A70A 0001      000075 |       AHI   r0,H'1'
 > 000178 5000 D0CC      000075 |       ST    r0,I(,r13,204)
 > 00017C A70E 000A      000075 |       CHI   r0,H'10'
 > 000180 A7D4 FFA1      000075 |       JNH   @1L2
 >
 > 000184                000075 | @1L4  DS    0H
 > 000184                000075 | @1L8  DS    0H
 >
 > And don't let me start about IBM's PL/I for Windoze product, which in
 > many cases generates code that is as "good" as the code generated by
 > Turbo Pascal in the mid 1980'ies...  (Then again, nobody uses it, so
 > who cares)
 >
 > And yes, IBM used to have a compiler that was capable of recognizing
 > this (to a certain extent), the venerable OS PL/I V2.3.0, predating
 > Enterprise PL/I by about a decade(?)...
 >
 > You might also want to count the number of assembler statements in
 > the inner loop above and compare it with the number in the inner loop
 > below. (And then you may start to cry...)
 >
 > 17   1  0  DO I = 1 TO 10;
 > 18   1  1    DO J = 1 TO 10;
 > 19   1  2      T = 'Oops';
 > 20   1  2      PUT SKIP LIST(SUBSTR(T, 1, 1));
 > 21   1  2    END;
 > 22   1  1  END;
 >
 > * STATEMENT NUMBER  17
 > 0000C6  58 50 3 060               L     5,96(0,3)
 > 0000CA  50 50 D 0C4               ST    5,I
 > 0000CE                    CL.4    EQU   *
 >
 > * STATEMENT NUMBER  18
 > 0000CE  58 B0 3 05C               L     11,92(0,3)
 > 0000D2  58 A0 3 060               L     10,96(0,3)
 > 0000D6  18 5A                     LR    5,10
 > 0000D8  50 50 D 0C0               ST    5,J
 >
 > * INITIALIZATION CODE FOR OPTIMIZED LOOP FOLLOWS
 >
 > * CODE MOVED FROM STATEMENT NUMBER 19 <==== Yes we can^H^H^Hcould...
 > 0000DC  D2 03 D 0C8 3 08C         MVC   T(4),140(3)
 >
 > * CONTINUATION OF STATEMENT NUMBER  18
 > 0000E2  92 40 D 0CC               MVI   T+4,X'40'
 > 0000E6  D2 19 D 0CD D 0CC         MVC   T+5(26),T+4
 > 0000EC                    CL.6    EQU   *
 >
 > * STATEMENT NUMBER  19
 >
 > * STATEMENT NUMBER  20
 > 0000EC  41 70 D 110               LA    7,272(0,13)
 > 0000F0  50 70 3 07C               ST    7,124(0,3)
 > 0000F4  18 17                     LR    1,7
 > 0000F6  50 10 D 108               ST    1,264(0,13)
 > 0000FA  92 40 D 121               MVI   289(13),X'40'
 > 0000FE  41 10 3 078               LA    1,120(0,3)
 > 000102  58 F0 3 02C               L     15,A..IBMBSIOE
 > 000106  05 EF                     BALR  14,15
 > 000108  D2 07 D 138 3 048         MVC   312(8,13),72(3)
 > 00010E  41 40 D 0C8               LA    4,T
 > 000112  50 40 D 138               ST    4,312(0,13)
 > 000116  41 E0 D 138               LA    14,312(0,13)
 > 00011A  41 F0 3 040               LA    15,DED..T
 > 00011E  58 10 D 108               L     1,264(0,13)
 > 000122  90 EF 1 000               STM   14,15,0(1)
 > 000126  58 F0 3 034               L     15,A..IBMBSLOA
 > 00012A  05 EF                     BALR  14,15
 > 00012C  58 10 D 108               L     1,264(0,13)
 > 000130  58 F0 3 030               L     15,A..IBMBSIOT
 > 000134  05 EF                     BALR  14,15
 >
 > * STATEMENT NUMBER  21
 > 000136  87 5A 2 02A               BXLE  5,10,CL.6
 > 00013A  50 50 D 0C0               ST    5,J
 >
 > * CODE MOVED FROM STATEMENT NUMBER 18
 >
 > * STATEMENT NUMBER  22
 > 00013E  58 50 D 0C4               L     5,I
 > 000142  5A 50 3 060               A     5,96(0,3)
 > 000146  50 50 D 0C4               ST    5,I
 > 00014A  49 50 3 042               CH    5,66(0,3)
 > 00014E  47 C0 2 00C               BNH   CL.4
 >
 > * CODE MOVED FROM STATEMENT NUMBER 17
 >
 > * STATEMENT NUMBER  23
 >
 > Sigh...

Maybe the experts in this group would like to give their thoughts about
the why of this apparently/seemingly/obviously ridiculous(?) regression?

Robert
--
Robert AH Prins
robert(a)prino(d)org
[The conventional wisdom is that COBOL programs are all I/O bound, so
the speed of the object code is not a big deal. There are plenty of
other compilers that can optimize this kind of stuff. -John]

[toc] | [next] | [standalone]


#615

FromRobert AH Prins <robert@prino.org>
Date2012-04-22 22:14 +0000
Message-ID<12-04-072@comp.compilers>
In reply to#613
On 2012-04-22 18:57, Robert AH Prins wrote:
> On Apr 22, 12:58 pm, "HeyBub"<hey...@NOSPAMgmail.com>  wrote in
> bit.listserv.ibm-main:
>
> [The conventional wisdom is that COBOL programs are all I/O bound, so
> the speed of the object code is not a big deal. There are plenty of
> other compilers that can optimize this kind of stuff. -John]

As it turns out our test compiles add an OPT(0) after all programmer
supplied options "because that takes less CPU..." My comment that this
means that production programs are never the same as the ones that
have been tested was dismissed with a "We have done this for years
without anyone ever having a problem with it."

Submitting from SDSF with altered JCL does produce rather better code,
so I stand corrected (again, I'm losing it, rapidly...)

Apologies to all, at least for the z/OS part! However, I'm not going to
retract my remarks about the PL/I for Windows compiler.

Robert
--
Robert AH Prins
robert(a)prino(d)org

[toc] | [prev] | [next] | [standalone]


#620 — Re: PL/I nostalgia, was Decades of compiler technology and what do we get?

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-04-23 00:03 +0000
SubjectRe: PL/I nostalgia, was Decades of compiler technology and what do we get?
Message-ID<12-04-077@comp.compilers>
In reply to#613
(snip, someone wrote)
> > > > There isn't any need. We're fixing existing COBOL and it's easy to
> > > > fix. Just take stuff out of loops that doesn't belong there! It
> > > > works great..

(big snip, including generated code listing from PL/I)

> Maybe the experts in this group would like to give their thoughts about
> the why of this apparently/seemingly/obviously ridiculous(?) regression?

> [The conventional wisdom is that COBOL programs are all I/O bound, so
> the speed of the object code is not a big deal. There are plenty of
> other compilers that can optimize this kind of stuff. -John]

It has always seemed to me that PL/I would have been more successful
if the early compilers generated faster code (and ran faster, too).

It might have been that too much of the above was adopted, along with
other COBOL features, by PL/I. There are many things that other
languages, such as Fortran, traditionally didn't let you do, because
they might run too slow, but that PL/I allowed.

(Many of those have now been added to Fortran.)

Of all languages, I think I still find PL/I the most fun to write in,
though not necessarily best for the problems I actually need done.

-- glen

[toc] | [prev] | [next] | [standalone]


#624 — Re: PL/I nostalgia

From"robin" <robin51@dodo.com.au>
Date2012-04-25 09:07 +1000
SubjectRe: PL/I nostalgia
Message-ID<12-04-081@comp.compilers>
In reply to#620
From: glen herrmannsfeldt <gah@ugcs.caltech.edu>
Date: Monday, 23 April 2012 11:45

>It has always seemed to me that PL/I would have been more successful
>if the early compilers generated faster code (and ran faster, too).
>
>It might have been that too much of the above was adopted, along with
>other COBOL features, by PL/I. There are many things that other
>languages, such as Fortran, traditionally didn't let you do, because
>they might run too slow, but that PL/I allowed.

FORTRAN was developed by 1956.
PL/I was developed by 1966.
In the decade after 1956, many deficiencies had been identified in FORTRAN;
some of its statements were pretty crude.
Similar comments may be made about COBOL.
While some features of both FORTRAN and COBOL were adopted in PL/I,
many new features  were added, including (but not limited to) recursive procedures
and dynamic allocation (already in Algol).
Of those features adapted from the older languages, arbitrary restrictions
were removed, making it much easier to write programs.
One other point is that the size of machines had increased significantly
in that early decade, permitting more language features to be incorporated
in PL/I.
PL/I can be considered to be the first general-purpose language.

As to code generation of the early PL/I compilers, that code was reasonably efficient.
I would agree, however, there were certain situations where much faster code
could have been generated, but that opportunity was not taken.
I refer to operations involving whole arrays or array sections.
For instance, where an operation involved a whole array,
IBM's first compiler, PL/I-F, could have optimised a matrix statement
(trivial example, A=B;  where all elements of A and B are accessed)
to a single loop, instead of the two equivalent loops that were actually used:
do i = 1 to m;
    do j = 1 to n;
      A(i,j) = B(i,j);
   end;
end;
Four years later, IBM produced their Optimising Compiler and Checkout Compiler
(c. 1970).

>(Many of those have now been added to Fortran.)

Some have, but others have not.
For example, recent discussion in comp.lang.fortran evolved around a suitable
Fortran procedure to convert an integer to a string.
In PL/I, it requires a simple statement, s = i;
Some of the code examples offered for Fortran were as long as about 50 statements;
other shorter ones that used internal I/O failed to work when incorporated in a function procedure,
because that facility requires recursive I/O -- something that is not permitted.

Another of the same category is the Fortran list of string constants.
In Fortran, all such constants must have the same length,
as the array with which such a list is associated is not varying --
all array elements must have the same length.
[Considering what a rush job PL/I was, it's a remarkably good language.  -John]

[toc] | [prev] | [next] | [standalone]


#625 — Re: PL/I nostalgia

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-04-24 23:52 +0000
SubjectRe: PL/I nostalgia
Message-ID<12-04-082@comp.compilers>
In reply to#624
robin <robin51@dodo.com.au> wrote:

(snip, I wrote)
>>It has always seemed to me that PL/I would have been more successful
>>if the early compilers generated faster code (and ran faster, too).

(previous snip on I/O bound COBOL, and not worrying about CPU time.)

>>It might have been that too much of the above was adopted, along with
>>other COBOL features, by PL/I. There are many things that other
>>languages, such as Fortran, traditionally didn't let you do, because
>>they might run too slow, but that PL/I allowed.

> FORTRAN was developed by 1956.
> PL/I was developed by 1966.
> In the decade after 1956, many deficiencies had been identified
> in FORTRAN; some of its statements were pretty crude.

This is true, but not so important for this question.

Fortran didn't allow for recursion until 1990, and even then you had
to have the RECURSIVE attribute. Compilers could still generate
non-recursive code without the attribute.

There is overhead to the calling sequence to allow for recursion, at
least on most systems. It was usual for Fortran compilers to use
static allocation through Fortran 77. (Some rules were written
specifically to allow for it.) On machines without a call stack, there
is also overhead for that, in addition to local variable allocation.

Even more for PL/I, the ability to do multi-tasking adds more
complications that have more overhead.

> Similar comments may be made about COBOL.

As noted, this was in response to a suggestion that COBOL programs
were I/O bound, and so there was less need for CPU time optimization.

On the other hand, I/O optimizations such as locate mode I/O would
have been more important for COBOL.

> While some features of both FORTRAN and COBOL were adopted
> in PL/I, many new features  were added, including (but not
> limited to) recursive procedures and dynamic allocation
> (already in Algol).

> Of those features adapted from the older languages, arbitrary
> restrictions were removed, making it much easier to write programs.

And much easier to write slow programs. Simple PL/I expressions can
require temporary arrays. (Usually with a warning message.)

That didn't happen to Fortran until 1990, when machines were much
faster.

> One other point is that the size of machines had increased
> significantly in that early decade, permitting more language
> features to be incorporated in PL/I.

But the window was fairly small. IBM had originally expected to
replace Fortran (and maybe COBOL) with PL/I. The compiler arrived
late, ran slow, and generated much slower code.

> PL/I can be considered to be the first general-purpose language.

> As to code generation of the early PL/I compilers, that code
> was reasonably efficient.

For many scientific problems, reasonably isn't enough.

> I would agree, however, there were certain situations where much
> faster code could have been generated, but that opportunity was
> not taken.

> I refer to operations involving whole arrays or array sections.
> For instance, where an operation involved a whole array,
> IBM's first compiler, PL/I-F, could have optimised a matrix statement
> (trivial example, A=B;  where all elements of A and B are accessed)
> to a single loop, instead of the two equivalent loops that were actually used:
> do i = 1 to m;
>    do j = 1 to n;
>      A(i,j) = B(i,j);
>   end;
> end;

In some cases you can do that, but it isn't so easy in a subroutine,
when the array might not be contiguous.

Also, since array operations were added to Fortran, they are one of
the biggest causes for complaints about slow programs.

One reason is that people sometimes write array expressions that
require much more computation than they would written as loops.

PL/I only supports call-by-descriptor for arrays and strings.  That is
good, but has more overhead. For today's machines, that isn't so bad,
but on slower machines in the early days, it may have been too much.

> Four years later, IBM produced their Optimising Compiler and
> Checkout Compiler (c. 1970).

>>(Many of those have now been added to Fortran.)

> Some have, but others have not.
> For example, recent discussion in comp.lang.fortran evolved
> around a suitable Fortran procedure to convert an integer to a string.

> In PL/I, it requires a simple statement, s = i;

It is one of the fun features of PL/I, but not so often needed in
production programs.

I do remember in high-school writing a PL/I DO loop with CHAR
variables for the DO variable, and the start, end, and increment value.
(It is slightly interesting, as a string compare is used in
the loop test.)

> [Considering what a rush job PL/I was, it's a remarkably good
> language.  -John]

I didn't know about that until recently when I bought "History
of Programming Languages", edited by Richard L. Wexelblat, which
covers the timeline for the PL/I language specification. (Writing
the actual compiler was a separate timeline.)

As well as I can tell, it was October 1963 that the decision to
design a new language, instead of going to Fortran VI, was final,
and the group formed to write the specification. They were told
that it needed to be done by December 1963. In December, it was
extended to January 1964, and then slipped to February.

Then there is the comment:

  "While this can never be proven, it is clear that much of the
   long and demanding work in PL/I language development would have
   been made much easier ahd the designing committee been given
   six months or a year at the beginning to lay down a carefully
   defined language base."

I wonder how much time has now been spent by committees working
on the Fortran standard.

-- glen

[toc] | [prev] | [next] | [standalone]


#627 — Re: PL/I nostalgia

From"robin" <robin51@dodo.com.au>
Date2012-04-28 21:30 +1000
SubjectRe: PL/I nostalgia
Message-ID<12-04-084@comp.compilers>
In reply to#625
From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu>
Sent: Wednesday, 25 April 2012 9:52 AM

> robin <robin51@dodo.com.au> wrote:
>
> (snip, glen herrmannsfeldt wrote)
>>>It has always seemed to me that PL/I would have been more successful
>>>if the early compilers generated faster code (and ran faster, too).
>
> (previous snip on I/O bound COBOL, and not worrying about CPU time.)
>
>>>It might have been that too much of the above was adopted, along with
>>>other COBOL features, by PL/I. There are many things that other
>>>languages, such as Fortran, traditionally didn't let you do, because
>>>they might run too slow, but that PL/I allowed.
>
>> FORTRAN was developed by 1956.
>> PL/I was developed by 1966.
>> In the decade after 1956, many deficiencies had been identified
>> in FORTRAN; some of its statements were pretty crude.
>
> This is true, but not so important for this question.

It is fundamentally important, since you raised it 2 paras ago, as to
what was put in PL/I and why.  FORTRAN was deficient in many areas,
including I/O, its use of EQUIVALENCE and COMMON, character strings,
and DO loops.  Algol already had recursion; FORTRAN didn't, and that
deficiency made it difficult to write algorithms that were general and
which dealt with dynamic arrays that, in scientific computation, was a
pressing need.

> Fortran didn't allow for recursion until 1990, and even then you had
> to have the RECURSIVE attribute. Compilers could still generate
> non-recursive code without the attribute.

All that's irrelevant.

> There is overhead to the calling sequence to allow for recursion, at
> least on most systems. It was usual for Fortran compilers to use
> static allocation through Fortran 77. (Some rules were written
> specifically to allow for it.) On machines without a call stack, there
> is also overhead for that, in addition to local variable allocation.

The overhead is small, and in many programs, negligible.

> Even more for PL/I, the ability to do multi-tasking adds more
> complications that have more overhead.

An irrelevant consideration in this discussion.

>> Similar comments may be made about COBOL.
>
> As noted, this was in response to a suggestion that COBOL programs
> were I/O bound, and so there was less need for CPU time optimization.

Any program can be I/O bound.  There are, nevertheless, COBOL
programs that are not I/O bound.  Even in ones that are, time can be
saved through optimisation, as a reduction in the run-time of
the computational components that cannot be overlapped with I/O
reduces overall time.

> On the other hand, I/O optimizations such as locate mode I/O would
> have been more important for COBOL.

That isn't an "optimisation", it's a programming strategy.

>> While some features of both FORTRAN and COBOL were adopted
>> in PL/I, many new features  were added, including (but not
>> limited to) recursive procedures and dynamic allocation
>> (already in Algol).
>
>> Of those features adapted from the older languages, arbitrary
>> restrictions were removed, making it much easier to write programs.
>
> And much easier to write slow programs.

No, it does not.  The removal of arcane restrictions made it easier to
write error-free programs.

It's always easy to write slow programs, even in FORTRAN.
The restrictions removed from the older languages, however,
made it easier to write faster programs.

It also made it easier to write programs in shorter time than
before.

Furthermore, the necessity in FORTRAN of having all storage
as static meant that programs employing large arrays or lots of arrays
used the processor inefficiently in that the executable programs
tied up more memory than was necessary.  Compared to PL/I,
which provides dynamic arrays, considerably less run-time
memory was required.

[In case it is thought from the above that PL/I provides only dynamic arrays,
may I point out that PL/I provides dynamic and static arrays,
as well as controlled arrays.]

> Simple PL/I expressions can
> require temporary arrays. (Usually with a warning message.)
>
> That didn't happen to Fortran until 1990, when machines were much
> faster.

That's relative, and in any case irrelevant.
Machines were much faster in 1966 compared to 1956.

>> One other point is that the size of machines had increased
>> significantly in that early decade, permitting more language
>> features to be incorporated in PL/I.
>
> But the window was fairly small. IBM had originally expected to
> replace Fortran (and maybe COBOL) with PL/I. The compiler arrived
> late, ran slow, and generated much slower code.

You're wrong on both counts.  The hardware was late.  All the
compilers were late.  The code from IBM's PL/I was just as good as
from IBM's Fortran compilers on the machine that we had.  I still have
the results somewhere of test runs in FORTRAN and PL/I. It was the
link editor that took longer with PL/I than with FORTRAN.

>> PL/I can be considered to be the first general-purpose language.
>
>> As to code generation of the early PL/I compilers, that code
>> was reasonably efficient.
>
> For many scientific problems, reasonably isn't enough.

I should have been more explicit.  Code generation from IBM's
FORTRAN compilers on the machine that we had was reasonably efficient too.

What is just as important is what happens when a program runs.
FORTRAN programs often halted (division by zero, floating-point
overflow) without any indication of where or why they halted.

Even were a FORTRAN program to run faster than a PL/I program, any
such "saving" would be more than lost by having to re-run the FORTRAN
program to try to find where and why it stopped.

There was (and still is) no need to re-run the PL/I program to do
that, because the location and the reason were printed when the PL/I
program halted.  Given that it was also possible to print the values
of any variables along with the above information, the
debugging/development of the program saved a good deal of machine
time.

On the issue of whether PL/I was faster or slower than FORTRAN,
it's clear that those making timing comparisons did not know
how to write or to run PL/I programs.

One published account (D. J. Kewley, "A Comparison between
Pascal, FORTRAN, and PL/I", ACJ, Feb. 1981, pp 27-8)
claimed that Pascal was faster than PL/I,
and the author produced timing figures to "prove" it.
The author failed to specify the PL/I option "REORDER" that would
permit optimisation to take place.  Furthermore, he compared
one Pascal program performing complex arithmetic, with a PL/I
program doing the same.  Not supporting complex arithmetic,
the Pascal program simulated those operations.  When the PL/I
version was rewritten using complex arithmetic,
and with the REORDER option on the PROCEDURE statement,
a 47% increase in speed was obtained. (see my refutation, ACJ, Aug. 1981, p. 107)

In his published accounts of timing comparisons between
COBOL, PL/I, and FORTRAN, A. B. Tucker (Programming Languages",
McGraw-Hill, 1977) neglected to specify the REORDER option.
This neglect again prevented the PL/I compiler
from optimising the object programs, and therefore invalidated
his timing and code comparisons with COBOL and FORTRAN.

In P. J. Jaliks, "COBOL vs PL/I: Some Performance Comparisons",
CACM, April 1984, pp. 216-221, similar errors were made for the PL/I version.
In particular, one PL/I program ran two to three times slower
on account of inappropriate data declarations.

More recently, R. H. Prins criticized IBM's Enterprise PL/I compiler for
optimising poorly.  He subsequently retracted that criticism when
he discovered that he had been compiling the program with OPT(0) --
that is, no optimisation !

FORTRAN programmers tended to mimic FORTRAN style in
their PL/I code that was inappropriate in PL/I.
That caused PL/I programs to run slower than they should have.

>> I would agree, however, there were certain situations where much
>> faster code could have been generated, but that opportunity was
>> not taken.
>
>> I refer to operations involving whole arrays or array sections.
>> For instance, where an operation involved a whole array,
>> IBM's first compiler, PL/I-F, could have optimised a matrix statement
>> (trivial example, A=B;  where all elements of A and B are accessed)
>> to a single loop, instead of the two equivalent loops that were actually used:
>> do i = 1 to m;
>>    do j = 1 to n;
>>      A(i,j) = B(i,j);
>>   end;
>> end;
>
> In some cases you can do that, but it isn't so easy in a subroutine,
> when the array might not be contiguous.

IIRC, in IBM's F-compiler, elements in arrays were contiguous,
even in subroutines.  [Even were that not so, a single loop suffices.]

> Also, since array operations were added to Fortran, they are one of
> the biggest causes for complaints about slow programs.

Fortran 90 introduced array features (in a manner different from PL/I)
that forces temporary arrays to be created, and which results in
Fortran programs running slower than equivalent features not using
the new array features.

> One reason is that people sometimes write array expressions that
> require much more computation than they would written as loops.

That's their choice.

> PL/I only supports call-by-descriptor for arrays and strings.  That is
> good, but has more overhead.

Than what? Not having descriptors?
Descriptors are necessary to deal with dynamic arrays.
Without descriptors, it would be back to pre-Fortran 90,
where only the address of the first element of an array was typically passed.

That arrangement impeded or prevented information about
a FORTRAN array being made available to a subroutine.

> For today's machines, that isn't so bad,
> but on slower machines in the early days, it may have been too much.

The "overheads" of passing a descriptor to a subroutine
were (and still are) minimal.

>> Four years later, IBM produced their Optimising Compiler and
>> Checkout Compiler (c. 1970).
>
>>>(Many of those have now been added to Fortran.)
>
>> Some have, but others have not.
>> For example, recent discussion in comp.lang.fortran evolved
>> around a suitable Fortran procedure to convert an integer to a string.
>
>> In PL/I, it requires a simple statement, s = i;
>
> It is one of the fun features of PL/I, but not so often needed in
> production programs.

It's been a recurring chestnut in FORTRAN/Fortran for the past 40 years.
It's an important feature of any program.  It's not relevant to mention
"production" programs.  Whether a program runs once or a hundred times
is irrelevant.

Conversion to a character string is something that's used often in PL/I
in conjunction with the TRIM function to remove leading blanks.

[Irrelevant material omitted.]

>> [Considering what a rush job PL/I was, it's a remarkably good
>> language.  -John]
>
> I didn't know about that until recently when I bought "History
> of Programming Languages", edited by Richard L. Wexelblat, which
> covers the timeline for the PL/I language specification. (Writing
> the actual compiler was a separate timeline.)
>
> As well as I can tell, it was October 1963 that the decision to
> design a new language, instead of going to Fortran VI, was final,
> and the group formed to write the specification. They were told
> that it needed to be done by December 1963. In December, it was
> extended to January 1964, and then slipped to February.

That those early dates slipped is irrelevant, as the S/360 wasn't even
announced until 1964.  In any case, a slippage by a few months
was unimportant.

> Then there is the comment:
>
>  "While this can never be proven, it is clear that much of the
>   long and demanding work in PL/I language development would have
>   been made much easier ahd the designing committee been given
>   six months or a year at the beginning to lay down a carefully
>   defined language base."

Work on designs for the new language had already been in progress
prior to October 1963, so at that point much was known as to what
would be put into PL/I (or New Programming Language as it was called
before it was PL/I.)
[The code fron PL/I F was comparablw to Fortran G, but much worse than
Fortran H.  The PL/I optimizing compiler's code was better, but still
not as good as Fortran H and its descendants. -John]

[toc] | [prev] | [next] | [standalone]


#628 — Re: PL/I nostalgia

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-04-28 16:11 +0000
SubjectRe: PL/I nostalgia
Message-ID<12-04-085@comp.compilers>
In reply to#627
robin <robin51@dodo.com.au> wrote:

(big snip, then I wrote)
>> Fortran didn't allow for recursion until 1990, and even then you
>> had to have the RECURSIVE attribute. Compilers could still generate
>> non-recursive code without the attribute.

> All that's irrelevant.

There is, at least, more overhead in the procedure entry/exit
sequence for recursive routines. Now, since PL/I also has the
RECURSIVE attribute the compiler could generate different code
in the non-recursive case.

OK, to get an actual compiler question into the discussion,
are there any compilers that generate non-reentrant code for
a language that allows recursion when it isn't being used?

(snip)

> Furthermore, the necessity in FORTRAN of having all storage
> as static meant that programs employing large arrays or lots of
> arrays used the processor inefficiently in that the
> executable programs tied up more memory than was necessary.
> Compared to PL/I, which provides dynamic arrays, considerably
> less run-time memory was required.

That is true. For a single task system, like many before OS/360 and
like OS/360 PCP on smaller system, though, if it fits there isn't much
cost to the wasted memory.

> [In case it is thought from the above that PL/I provides only
> dynamic arrays, may I point out that PL/I provides dynamic
> and static arrays, as well as controlled arrays.]

I probably lost the thread that the comment was supposed to apply to.
In a called procedure, it doesn't matter how the original array was
allocated, it is referenced through the dope-vector (call by
descriptor).

In the case of a local array, the compiler can make some optimizations
that it can't make for a procedure argument.

Fortran 90 added assumed shape arrays, where the called array gets the
shape, most likely through a descriptor similar to that from PL/I. In
traversing an array through a descriptor, it isn't so easy to convert
to a single loop.

Through Fortran 77, the array passing method now called assumed size
was usually used. A common way to use assumed size in Fortran was for
the called routine to declare the argument as rank one and do all the
index calculations internally.

Now, as Robin mentioned PL/I often made it easier to write correct
programs. Processing a matrix through a rank one array is more
difficult to get right.

>> Simple PL/I expressions can require temporary arrays.
>> (Usually with a warning message.)

>> That didn't happen to Fortran until 1990, when machines were much
>> faster.

> That's relative, and in any case irrelevant.
> Machines were much faster in 1966 compared to 1956.

There is still much discussion on comp.lang.fortran on the speed
difference between array expressions and explicit DO loops.

>>> One other point is that the size of machines had increased
>>> significantly in that early decade, permitting more language
>>> features to be incorporated in PL/I.

>> But the window was fairly small. IBM had originally expected to
>> replace Fortran (and maybe COBOL) with PL/I. The compiler arrived
>> late, ran slow, and generated much slower code.

> You're wrong on both counts.  The hardware was late.  All the
> compilers were late.  The code from IBM's PL/I was just as good as
> from IBM's Fortran compilers on the machine that we had.  I still have
> the results somewhere of test runs in FORTRAN and PL/I. It was the
> link editor that took longer with PL/I than with FORTRAN.

Certainly the link editor was always slow. If one wrote the same
program in PL/I, the result might be close to that from Fortran.

If one started using many of the PL/I features, though, it was very
easy to get a much slower program. One might, for example, use FIXED
DECIMAL variables that require conversion to binary when used as array
subscripts. That is, at least, one problem that OS/360 Fortran
programmers never had.

(snip)

> I should have been more explicit.  Code generation from IBM's
> FORTRAN compilers on the machine that we had was reasonably
> efficient too.

> What is just as important is what happens when a program runs.
> FORTRAN programs often halted (division by zero, floating-point
> overflow) without any indication of where or why they halted.

OS/360 Fortran has a nice traceback feature. I don't know when it was
added, though. On the other hand, in the fairly common branch to a
non-existing address, both Fortran and PL/I left you lost.

(snip)

> One published account (D. J. Kewley, "A Comparison between
> Pascal, FORTRAN, and PL/I", ACJ, Feb. 1981, pp 27-8)
> claimed that Pascal was faster than PL/I,
> and the author produced timing figures to "prove" it.
> The author failed to specify the PL/I option "REORDER" that would
> permit optimisation to take place.  Furthermore, he compared
> one Pascal program performing complex arithmetic, with a PL/I
> program doing the same.  Not supporting complex arithmetic,
> the Pascal program simulated those operations.  When the PL/I
> version was rewritten using complex arithmetic,
> and with the REORDER option on the PROCEDURE statement,
> a 47% increase in speed was obtained. (see my refutation, ACJ,
> Aug. 1981, p. 107)

(snip)

> FORTRAN programmers tended to mimic FORTRAN style in
> their PL/I code that was inappropriate in PL/I.
> That caused PL/I programs to run slower than they should have.

(snip)
>> In some cases you can do that, but it isn't so easy in a subroutine,
>> when the array might not be contiguous.

> IIRC, in IBM's F-compiler, elements in arrays were contiguous,
> even in subroutines.  [Even were that not so, a single loop suffices.]

PL/I allows array cross sections that can be non-contiguous.

I believe some Fortran compilers now generate a test for a contiguous
array and then different code to process the two cases. As far as I
know, no PL/I compilers do that.  (Then again, I haven't looked that
carefully.)

>> Also, since array operations were added to Fortran, they are one of
>> the biggest causes for complaints about slow programs.

(snip)

>> One reason is that people sometimes write array expressions that
>> require much more computation than they would written as loops.

> That's their choice.

That is true. Still, people seem to like doing it.

>> PL/I only supports call-by-descriptor for arrays and strings.
>> That is good, but has more overhead.

> Than what? Not having descriptors?
> Descriptors are necessary to deal with dynamic arrays.
> Without descriptors, it would be back to pre-Fortran 90,
> where only the address of the first element of an array was
> typically passed.

The generated code to process assumed size arrays is often faster than
assumed shape. In many cases it is a worthwhile tradeoff on today's
machines.


(snip)

>>> [Considering what a rush job PL/I was, it's a remarkably good
>>> language.  -John]

>> I didn't know about that until recently when I bought "History
>> of Programming Languages", edited by Richard L. Wexelblat, which
>> covers the timeline for the PL/I language specification. (Writing
>> the actual compiler was a separate timeline.)

>> As well as I can tell, it was October 1963 that the decision to
>> design a new language, instead of going to Fortran VI, was final,
>> and the group formed to write the specification. They were told
>> that it needed to be done by December 1963. In December, it was
>> extended to January 1964, and then slipped to February.

> That those early dates slipped is irrelevant, as the S/360 wasn't
> even announced until 1964.  In any case, a slippage by a few months
> was unimportant.

From that description, they had four months. With the earlier
deadline, they would have had to have most of it done in two months.
For a language as complicated as PL/I, that isn't much time at all.

(snip)

> [The code fron PL/I F was comparablw to Fortran G, but much worse than
> Fortran H.  The PL/I optimizing compiler's code was better, but still
> not as good as Fortran H and its descendants. -John]

As long as you don't use too many fancy PL/I features, that should be
true. Of course you didn't have those features in Fortran IV. There is
a tendency to try out new features of a new language, though.

-- glen
[I got some astonishingly awful code when I tried to use an array of
12 bit fields.  As I recall, the code converted the fields to decimal
and back, for reasons I could not begin to guess. Also, looking at the
manuals in Bitsavers, they were still adding features and
optimizations to PL/I F at least as late as 1968. -John]

[toc] | [prev] | [next] | [standalone]


#629 — Re: PL/I nostalgia

FromRobert A Duff <bobduff@shell01.TheWorld.com>
Date2012-04-29 10:16 -0400
SubjectRe: PL/I nostalgia
Message-ID<12-04-086@comp.compilers>
In reply to#628
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:

> OK, to get an actual compiler question into the discussion,
> are there any compilers that generate non-reentrant code for
> a language that allows recursion when it isn't being used?

Yes, in the small-machine embedded systems world.  On a modern 64-bit
machine with efficient addressing based on a stack pointer and/or
frame pointer, I suspect it would be a pessimization.

Note that recursion isn't the only issue -- there's also
multi-threading.

- Bob
[I expect that on modern machines where code is generally
read-only to allow sharing between processes, there's no
advantage to non-recursive code. Back in the 1960s, S/360
code typically had a static save area per routine that it
used for all its calls, and there was a fair amount of
extra complication to save stuff in a stack. -John]

[toc] | [prev] | [next] | [standalone]


#633 — Re: PL/I code

From"robin" <robin51@dodo.com.au>
Date2012-05-05 00:45 +1000
SubjectRe: PL/I code
Message-ID<12-05-004@comp.compilers>
In reply to#628
From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu>

>
> (big snip, then I wrote)
>>> Fortran didn't allow for recursion until 1990, and even then you
>>> had to have the RECURSIVE attribute. Compilers could still generate
>>> non-recursive code without the attribute.
>
>> All that's irrelevant.
>
> There is, at least, more overhead in the procedure entry/exit
> sequence for recursive routines.

More overhead, maybe, but how much more?  Registers usually have to be
saved, a return address has to be preserved somewhere.  When the
machine has a stack, those things can go on the stack.  There appears
to be no extra overhead.  When the machine does not have a hardware
stack, one must be simulated, or, space must be made available for
saving those things, at each recursive call.  In that case, a request
from the OS may need to be made for the storage.  The request will add
to overhead.  But again, how much extra?

> Now, since PL/I also has the
> RECURSIVE attribute the compiler could generate different code
> in the non-recursive case.

And did, in the case of PL/I-F, AFIK.
BTW, the RECURSIVE attribute was required because of the possibility
of independent compilation, for it may not have been otherwise obvious
to the compiler that this particular procedure was in some sort of
recursive call chain.

> OK, to get an actual compiler question into the discussion,
> are there any compilers that generate non-reentrant code for
> a language that allows recursion when it isn't being used?

IBM PL/I for Windows generates different code for
procedures that are identical except for the attribute RECURSIVE.

Similarly for DR PL/I for DOS.

>> Furthermore, the necessity in FORTRAN of having all storage
>> as static meant that programs employing large arrays or lots of
>> arrays used the processor inefficiently in that the
>> executable programs tied up more memory than was necessary.
>> Compared to PL/I, which provides dynamic arrays, considerably
>> less run-time memory was required.
>
> That is true. For a single task system, like many before OS/360 and
> like OS/360 PCP on smaller system, though, if it fits there isn't much
> cost to the wasted memory.

Correct as far as it goes, but you've missed the point.  Such a
program may not run at all on a PCP system owing to the sum of its
static storage requirements exceeding available memory.

However, in the same system, a similar PL/I program using dynamic
memory can run because (1) there is no wasted memory, and (2) the
demand for dynamic memory generally means that all the memory is not
required at the same time, resulting in significantly less memory
requirements. (For instance, storage taken by temporary arrays created
in one procedure are given back to the system when the procedure
terminates.)  On a system like MVT, using excessive storage prevents
other programs from being loaded and (possibly) executed concurrently.

Where the run-time requirements of a program using static memory are
almost as large as available memory, once an MVT-style system decides
that the priority of the large program has become high enough, it will
stop scheduling small programs, and will permit other running programs
to terminate, until all the memory is free to run the large job.

>> [In case it is thought from the above that PL/I provides only
>> dynamic arrays, may I point out that PL/I provides dynamic
>> and static arrays, as well as controlled arrays.]
>
> I probably lost the thread that the comment was supposed to apply to.
> In a called procedure, it doesn't matter how the original array was
> allocated, it is referenced through the dope-vector (call by
> descriptor).

Correct. My remark was just by way of explanation for readers not
specially familiar with PL/I.

> In the case of a local array, the compiler can make some optimizations
> that it can't make for a procedure argument.

Like what?  I know of no such restrictions in PL/I-F.
Nor in Windows PL/I, for that matter.

> Fortran 90 added assumed shape arrays, where the called array gets the
> shape, most likely through a descriptor similar to that from PL/I. In
> traversing an array through a descriptor, it isn't so easy to convert
> to a single loop.

In Fortran (90 or later), the descriptor holds, or can hold, the stride value.
Thus, a called procedure can access non-contiguous elements in a single loop.

> Through Fortran 77, the array passing method now called assumed size
> was usually used. A common way to use assumed size in Fortran was for
> the called routine to declare the argument as rank one and do all the
> index calculations internally.

But it was also common to use "adjustable" arrays,
and to deal with a matrix argument as a matrix dummy argument.

> Now, as Robin mentioned PL/I often made it easier to write correct
> programs. Processing a matrix through a rank one array is more
> difficult to get right.

Indeed.

>>> Simple PL/I expressions can require temporary arrays.
>>> (Usually with a warning message.)
>
>>> That didn't happen to Fortran until 1990, when machines were much
>>> faster.
>
>> That's relative, and in any case irrelevant.
>> Machines were much faster in 1966 compared to 1956.
>
> There is still much discussion on comp.lang.fortran on the speed
> difference between array expressions and explicit DO loops.
>
>>>> One other point is that the size of machines had increased
>>>> significantly in that early decade, permitting more language
>>>> features to be incorporated in PL/I.
>
>>> But the window was fairly small. IBM had originally expected to
>>> replace Fortran (and maybe COBOL) with PL/I. The compiler arrived
>>> late, ran slow, and generated much slower code.
>
>> You're wrong on both counts.  The hardware was late.  All the
>> compilers were late.  The code from IBM's PL/I was just as good as
>> from IBM's Fortran compilers on the machine that we had.  I still have
>> the results somewhere of test runs in FORTRAN and PL/I. It was the
>> link editor that took longer with PL/I than with FORTRAN.
>
> Certainly the link editor was always slow. If one wrote the same
> program in PL/I, the result might be close to that from Fortran.
>
> If one started using many of the PL/I features, though, it was very
> easy to get a much slower program. One might, for example, use FIXED
> DECIMAL variables that require conversion to binary when used as array
> subscripts. That is, at least, one problem that OS/360 Fortran
> programmers never had.

Decimal variables were not designed to be used as subscripts.  Decimal
variables are typically used in holding data for general computation,
mostly, but not exclusively, for commercial work.  One application I
recall was for a large array holding values smaller than 10.  Decimal
variables were just right for that application because FIXED DECIMAL
(1) required only one byte of storage.  Compared to FORTRAN, which
used 4 bytes for an integer, the large array in PL/I used one-quarter
of the storage of its FORTRAN counterpart.  That observation also
applies to arrays whose values are -1, 0, and 1.

>> I should have been more explicit.  Code generation from IBM's
>> FORTRAN compilers on the machine that we had was reasonably
>> efficient too.
>
>> What is just as important is what happens when a program runs.
>> FORTRAN programs often halted (division by zero, floating-point
>> overflow) without any indication of where or why they halted.
>
> OS/360 Fortran has a nice traceback feature. I don't know when it was
> added, though. On the other hand, in the fairly common branch to a
> non-existing address, both Fortran and PL/I left you lost.

Branches to non-existent addresses in PL/I is something that wasn't even at all
"fairly common".

In PL/I, for any significant error, not only did you get a traceback
in English, you also got line numbers for the error location
and for the statements that called the procedure.

I think that I also mentioned in a previous post in this thread
that it was also possible to print values of PL/I variables
along with the traceback.

>> One published account (D. J. Kewley, "A Comparison between
>> Pascal, FORTRAN, and PL/I", ACJ, Feb. 1981, pp 27-8)
>> claimed that Pascal was faster than PL/I,
>> and the author produced timing figures to "prove" it.
>> The author failed to specify the PL/I option "REORDER" that would
>> permit optimisation to take place.  Furthermore, he compared
>> one Pascal program performing complex arithmetic, with a PL/I
>> program doing the same.  Not supporting complex arithmetic,
>> the Pascal program simulated those operations.  When the PL/I
>> version was rewritten using complex arithmetic,
>> and with the REORDER option on the PROCEDURE statement,
>> a 47% increase in speed was obtained. (see my refutation, ACJ,
>> Aug. 1981, p. 107)
>
> (snip)
>
>> FORTRAN programmers tended to mimic FORTRAN style in
>> their PL/I code that was inappropriate in PL/I.
>> That caused PL/I programs to run slower than they should have.
>
> (snip)
>>> In some cases you can do that, but it isn't so easy in a subroutine,
>>> when the array might not be contiguous.
>
>> IIRC, in IBM's F-compiler, elements in arrays were contiguous,
>> even in subroutines.  [Even were that not so, a single loop suffices.]
>
> PL/I allows array cross sections that can be non-contiguous.

The elements in a cross-section are contiguous for rows,
but not for columns (in a matrix).  However, the elements are
separated from each other by a constant amount, so a single loop
suffices (as you would expect, because only one subscript varies).

> I believe some Fortran compilers now generate a test for a contiguous
> array and then different code to process the two cases. As far as I
> know, no PL/I compilers do that.  (Then again, I haven't looked that
> carefully.)

>>> Also, since array operations were added to Fortran, they are one of
>>> the biggest causes for complaints about slow programs.
>
> (snip)
>
>>> One reason is that people sometimes write array expressions that
>>> require much more computation than they would written as loops.
>
>> That's their choice.
>
> That is true. Still, people seem to like doing it.
>
>>> PL/I only supports call-by-descriptor for arrays and strings.
>>> That is good, but has more overhead.
>
>> Than what? Not having descriptors?
>> Descriptors are necessary to deal with dynamic arrays.
>> Without descriptors, it would be back to pre-Fortran 90,
>> where only the address of the first element of an array was
>> typically passed.
>
> The generated code to process assumed size arrays is often faster than
> assumed shape. In many cases it is a worthwhile tradeoff on today's
> machines.

I think that you will find that there's little if any difference.

> (snip)
>
>>>> [Considering what a rush job PL/I was, it's a remarkably good
>>>> language.  -John]
>
>>> I didn't know about that until recently when I bought "History
>>> of Programming Languages", edited by Richard L. Wexelblat, which
>>> covers the timeline for the PL/I language specification. (Writing
>>> the actual compiler was a separate timeline.)
>
>>> As well as I can tell, it was October 1963 that the decision to
>>> design a new language, instead of going to Fortran VI, was final,
>>> and the group formed to write the specification. They were told
>>> that it needed to be done by December 1963. In December, it was
>>> extended to January 1964, and then slipped to February.
>
>> That those early dates slipped is irrelevant, as the S/360 wasn't
>> even announced until 1964.  In any case, a slippage by a few months
>> was unimportant.
>
> From that description, they had four months. With the earlier
> deadline, they would have had to have most of it done in two months.
> For a language as complicated as PL/I, that isn't much time at all.

Two months was probably expecting a bit much, but recall that
I said that the decisions of what to include and omit would have
already been made.  I suspect that the work required at that time
(October) would have been to decide on an appropriate syntax.

> (snip)
>
>> [The code fron PL/I F was comparable to Fortran G, but much worse than
>> Fortran H.  The PL/I optimizing compiler's code was better, but still
>> not as good as Fortran H and its descendants. -John]
>
> As long as you don't use too many fancy PL/I features, that should be
> true. Of course you didn't have those features in Fortran IV. There is
> a tendency to try out new features of a new language, though.

> [I got some astonishingly awful code when I tried to use an array of
> 12 bit fields.

BIT strings usually need to be ALIGNED for best performance.
[Didn't help -John]

>  As I recall, the code converted the fields to decimal
> and back, for reasons I could not begin to guess.

I can't imagine why that would have been done.  The usual conversion
for BIT strings is to BINARY.  In point of fact, any conversion to
arithmetic from BIT is to BINARY first, and them to any other type, if
required.

> Also, looking at the
> manuals in Bitsavers, they were still adding features and
> optimizations to PL/I F at least as late as 1968. -John]

As IBM has been doing to their current Windows PL/I compiler.

[toc] | [prev] | [next] | [standalone]


#634 — Re: PL/I code

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-05-05 05:20 +0000
SubjectRe: PL/I code
Message-ID<12-05-005@comp.compilers>
In reply to#633
robin <robin51@dodo.com.au> wrote:

(snip)
>> There is, at least, more overhead in the procedure entry/exit
>> sequence for recursive routines.

> More overhead, maybe, but how much more?  Registers usually have to be
> saved, a return address has to be preserved somewhere.  When the
> machine has a stack, those things can go on the stack.  There appears
> to be no extra overhead.  When the machine does not have a hardware
> stack, one must be simulated, or, space must be made available for
> saving those things, at each recursive call.  In that case, a request
> from the OS may need to be made for the storage.  The request will add
> to overhead.  But again, how much extra?

For the PDP-10/TOPS-10 Fortran, return addresses went on the stack,
but local variables were still static, as usual for Fortran IV.

OS/360 Fortran compilers use static storage for local variables and
save areas (including the return address). No overhead for allocation.


(snip)

>> In the case of a local array, the compiler can make some optimizations
>> that it can't make for a procedure argument.

(snip)

> In Fortran (90 or later), the descriptor holds, or can hold,
> the stride value.  Thus, a called procedure can access
> non-contiguous elements in a single loop.

(snip)

>> PL/I allows array cross sections that can be non-contiguous.

> The elements in a cross-section are contiguous for rows,
> but not for columns (in a matrix).  However, the elements are
> separated from each other by a constant amount, so a single loop
> suffices (as you would expect, because only one subscript varies).

I suppose for a 2D array the elements will have a constant stride,
but not for a higher D array.

-- glen
[That must be the new PDP-10 compiler.  The old compiler, which looked
a whole lot like OS/360 Fortran G, used JSA/JRA for subroutine calls,
which saved the return address register in the first word of the
subroutine. -John]

[toc] | [prev] | [next] | [standalone]


#635 — Re: Fortran calls, was PL/I code

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-05-06 05:13 +0000
SubjectRe: Fortran calls, was PL/I code
Message-ID<12-05-006@comp.compilers>
In reply to#634
(snip, I wrote)
> For the PDP-10/TOPS-10 Fortran, return addresses went on the stack,
> but local variables were still static, as usual for Fortran IV.

> [That must be the new PDP-10 compiler.  The old compiler, which looked
> a whole lot like OS/360 Fortran G, used JSA/JRA for subroutine calls,
> which saved the return address register in the first word of the
> subroutine. -John]

I remembered the PDP-8 using the "store the return address in the
first word" method, but, yes, there was an earlier PDP-10 compiler.
The one I used was, I believe, called Fortran-10 and the older one
Fortran-40. (I am less sure about the latter, as I don't remember ever
using it.)

I did write some Fortran callable Macro-10 programs.

-- glen
[Yup, that's the one I used. -John]

[toc] | [prev] | [next] | [standalone]


#638 — Re: Archaic hardware (was Fortran calls)

From"robin" <robin51@dodo.com.au>
Date2012-05-09 10:46 +1000
SubjectRe: Archaic hardware (was Fortran calls)
Message-ID<12-05-009@comp.compilers>
In reply to#635
From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu>
Sent: Sunday, 6 May 2012 3:13 PM

> I remembered the PDP-8 using the "store the return address in the
> first word" method, but, yes, there was an earlier PDP-10 compiler.
> The one I used was, I believe, called Fortran-10 and the older one
> Fortran-40.

The CDC machines 7600, Cyber 70 series, etc used that method to store
the return address.

Surprising that those machines should take a step backwards,
in view of around a decade of Algol (with recursion).

It meant that each subroutine/function needed to implement its own
stack should it be called recursively.

Alan Turing designed the push-down pop-up stack
for subroutines back in 1945, for his computer (later
christened Automatic Computing Engine).
That feature did not see hardware at that time.
However, the Pilot ACE (1951) included a push-down stack
(or, if you like) a queue.  That push-down stack was
continued into the DEUCE line (1955).

The stack as a means of calling and returning from subroutines/
functions was implemented in the KDF9 (1961, delivered 1963).

The S/360 and subsequent issue stored the return address in a register.
That made it somewhat easier to have a universal stack manipulated
by software.

[toc] | [prev] | [next] | [standalone]


#750 — Re: PL/I nostalgia

From"robin" <robin51@dodo.com.au>
Date2012-09-19 11:04 +1000
SubjectRe: PL/I nostalgia
Message-ID<12-09-014@comp.compilers>
In reply to#627
> [The code fron PL/I F was comparablw to Fortran G, but much worse than
> Fortran H.  The PL/I optimizing compiler's code was better, but still
> not as good as Fortran H and its descendants. -John]

Finally I have to hand Tucker's "Programming Languages".

Case study 2, matrix inversion with 20 x 20 data:

with IBM 370-145 FORTRAN (G) execution time 8.41 secs
                                                (H) execution time 5.28 secs.

With IBM 370-145 PL/I (F)            execution time 6.31 secs
                              PL/I Optimiser execution time 5.77 secs.

(refer to pages 112 and 279 for times)

However, in the case of the PL/I program, Tucker //omitted// to supply
the option (REORDER) which is necessary to obtain full optimisation.
Thus, the PL/I optimiser execution obtained was larger than it should
have been.

It is clear that the times for FORTRAN (G) and PL/I(F) are equivalent,
and that FORTRAN(H) and PL/I optimiser times are equivalent.

As well as that, FORTRAN (H) required c. 150K of memory (i.e. a 256K
machine) which was far more than the 128K that we had initially,
whereas PL/I (F) required only 64K and IIRC FORTRAN (G) a little more.

[toc] | [prev] | [next] | [standalone]


#751 — Re: PL/I nostalgia

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-09-19 03:56 +0000
SubjectRe: PL/I nostalgia
Message-ID<12-09-015@comp.compilers>
In reply to#750
robin <robin51@dodo.com.au> wrote:
>> [The code fron PL/I F was comparablw to Fortran G, but much worse than
>> Fortran H.  The PL/I optimizing compiler's code was better, but still
>> not as good as Fortran H and its descendants. -John]

Well, the dynamically allocated variables and save areas for PL/I are
naturally slower than static allocated Fortran IV.

Also, many PL/I features naturally don't optimize as well as Fortran.

> Finally I have to hand Tucker's "Programming Languages".

I have one of those. Not my favorite, but not bad.
"History of Programming Languages" is better.

> Case study 2, matrix inversion with 20 x 20 data:

What page is that on?

> with IBM 370-145 FORTRAN (G) execution time 8.41 secs
>                          (H) execution time 5.28 secs.

> With IBM 370-145 PL/I (F)       execution time 6.31 secs
>                  PL/I Optimiser execution time 5.77 secs.

> (refer to pages 112 and 279 for times)

Not in the second edition.

> However, in the case of the PL/I program, Tucker //omitted// to supply
> the option (REORDER) which is necessary to obtain full optimisation.
> Thus, the PL/I optimiser execution obtained was larger than it should
> have been.

When did that appear? I don't remember it in (F).

> It is clear that the times for FORTRAN (G) and PL/I(F) are equivalent,
> and that FORTRAN(H) and PL/I optimiser times are equivalent.

I suppose. A better test would use a larger matrix, though.

> As well as that, FORTRAN (H) required c. 150K of memory (i.e. a 256K
> machine) which was far more than the 128K that we had initially,
> whereas PL/I (F) required only 64K and IIRC FORTRAN (G) a little more.

If you really want to be fair, add the compilation time to the
run time, then see which one is faster.

-- glen

[toc] | [prev] | [next] | [standalone]


#752 — Re: PL/I nostalgia

From"robin" <robin51@dodo.com.au>
Date2012-09-21 13:53 +1000
SubjectRe: PL/I nostalgia
Message-ID<12-09-016@comp.compilers>
In reply to#751
From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu>
Sent: Wednesday, 19 September 2012 1:56 PM


> robin <robin51@dodo.com.au> wrote:
>>> [The code fron PL/I F was comparablw to Fortran G, but much worse than
>>> Fortran H.  The PL/I optimizing compiler's code was better, but still
>>> not as good as Fortran H and its descendants. -John]
>
> Well, the dynamically allocated variables and save areas for PL/I are
> naturally slower than static allocated Fortran IV.

But not where it counts.  By the time some procedure (such as INVERT)
is called, the array(s) has(have) been allocated.  Allocation is a
once-off task, probably not measurable in terms of time.  And the
FORTRAN IV code was, essentially, rigid, and required re-compilation
for larger arrays.

> Also, many PL/I features naturally don't optimize as well as Fortran.

That may be so, but to have to re-compile the FORTRAN code to deal
with larger-sized arrays counted strongly against it.  As well, PL/I
offered full roll-out of fixed-size array operations Not all arrays
needed to be dynamic.  As well as that, PL/I offered such things as
double precision complex, string-handling, and error recovery.

Error recovery more than compensated for any difference in speed that
may have existed between FORTRAN and PL/I.  Having to re-run FORTRAN
code because of some error to find out what went wrong outweighed any
speed advantage that FORTRAN might have had, because in PL/I, the
error information was already there (including values of variables),
and without necessarily a program termination.  Hence, a re-run of the
PL/I code was avoided.  That was important, not only in terms of
machine time, but also in terms of turn-around time, because
turn-around time in those days was as much as a week.

> Finally I have to hand Tucker's "Programming Languages".
>
> I have one of those. Not my favorite, but not bad.
> "History of Programming Languages" is better.
>
>> Case study 2, matrix inversion with 20 x 20 data:
>
> What page is that on?

Look in the index.

>> with IBM 370-145 FORTRAN (G) execution time 8.41 secs
>>                          (H) execution time 5.28 secs.
>
>> With IBM 370-145 PL/I (F)       execution time 6.31 secs
>>                  PL/I Optimiser execution time 5.77 secs.
>
>> (refer to pages 112 and 279 for times)
>
> Not in the second edition.

>> However, in the case of the PL/I program, Tucker //omitted// to supply
>> the option (REORDER) which is necessary to obtain full optimisation.
>> Thus, the PL/I optimiser execution obtained was larger than it should
>> have been.
>
> When did that appear? I don't remember it in (F).

It wasn't in F, but it was in the optimising compiler, where it counted.

>> It is clear that the times for FORTRAN (G) and PL/I(F) are equivalent,
>> and that FORTRAN(H) and PL/I optimiser times are equivalent.
>
> I suppose. A better test would use a larger matrix, though.

20 W 20 is more than large enough.
It's the size of a typical matrix in a typical job.

>> As well as that, FORTRAN (H) required c. 150K of memory (i.e. a 256K
>> machine) which was far more than the 128K that we had initially,
>> whereas PL/I (F) required only 64K and IIRC FORTRAN (G) a little more.
>
> If you really want to be fair, add the compilation time to the
> run time, then see which one is faster.

Compilation time is only relevant when the run-time is very short.
When speed mattered, it was in long-running executable codes,
in which case, compilation time was unimportant.

To get the entire time for a job, you'd have to add in the link time,
which Tucker didn't provide.

And if compilation time was important, such as in short jobs,
you'd have used PL/C or WATFOR.

[toc] | [prev] | [next] | [standalone]


#753 — Re: PL/I nostalgia

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-09-21 07:00 +0000
SubjectRe: PL/I nostalgia
Message-ID<12-09-017@comp.compilers>
In reply to#752
robin <robin51@dodo.com.au> wrote:
> From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu>
> Sent: Wednesday, 19 September 2012 1:56 PM

>> robin <robin51@dodo.com.au> wrote:
>>>> [The code fron PL/I F was comparablw to Fortran G, but much worse than
>>>> Fortran H.  The PL/I optimizing compiler's code was better, but still
>>>> not as good as Fortran H and its descendants. -John]

>> Well, the dynamically allocated variables and save areas for PL/I are
>> naturally slower than static allocated Fortran IV.

> But not where it counts.  By the time some procedure (such as INVERT)
> is called, the array(s) has(have) been allocated.  Allocation is a
> once-off task, probably not measurable in terms of time.

That comment was before the matrix inversion discussion,
and is meant more generally.

Yes, if you are careful with your allocations, and minimize
subroutine calls, then it isn't so bad.

Current coding practices encourage more and smaller procedures
than were usual in the early PL/I days.

> And the FORTRAN IV code was, essentially, rigid, and required
> re-compilation for larger arrays.

For single task systems, most often the memory wouldn't be used
for anything else, but, yes, it is convenient to dynamically
allocate to the appropriate size. It is especially useful
for multitasking systems.

>> Also, many PL/I features naturally don't optimize as well as Fortran.

> That may be so, but to have to re-compile the FORTRAN code to deal
> with larger-sized arrays counted strongly against it.  As well, PL/I
> offered full roll-out of fixed-size array operations Not all arrays
> needed to be dynamic.  As well as that, PL/I offered such things as
> double precision complex, string-handling, and error recovery.

IBM Fortran has had COMPLEX*16 about as far back as PL/I, but most
others didn't. (Though the most common use for COMPLEX, the FFT,
is most often written using REAL arrays.)

Compilers I know of have the overhead needed for RECURSIVE, even
when the attribute isn't used. But again, minimize the number
of procedure calls and it isn't so bad.

> Error recovery more than compensated for any difference in speed that
> may have existed between FORTRAN and PL/I.  Having to re-run FORTRAN
> code because of some error to find out what went wrong outweighed any
> speed advantage that FORTRAN might have had, because in PL/I, the
> error information was already there (including values of variables),
> and without necessarily a program termination.  Hence, a re-run of the
> PL/I code was avoided.

Pretty program dependent, but, yes, PL/I can make it easier.

On the other hand, keeping track of ON units through procedure
calls is another increase in the time needed for a call.

> That was important, not only in terms of
> machine time, but also in terms of turn-around time, because
> turn-around time in those days was as much as a week.

>> Finally I have to hand Tucker's "Programming Languages".

>> I have one of those. Not my favorite, but not bad.
>> "History of Programming Languages" is better.

>>> Case study 2, matrix inversion with 20 x 20 data:

>> What page is that on?

> Look in the index.

Might have gone away for the 2nd edition.

(snip)

> 20 W 20 is more than large enough.
> It's the size of a typical matrix in a typical job.

Pretty small for many problems, but then most bigger than
that should be done in ways other than inversion, such
as LU decomposition.

-- glen
[Even in single task systems, dynamic allocation is useful
since it means that variables only take up space when a
routine is active. The Fortran version of that was overlays,
which were a lot klunkier. -John]

[toc] | [prev] | [next] | [standalone]


#758 — Re: PL/I nostalgia

From"robin" <robin51@dodo.com.au>
Date2012-09-30 10:45 +1000
SubjectRe: PL/I nostalgia
Message-ID<12-09-022@comp.compilers>
In reply to#753
From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu>
Sent: Friday, 21 September 2012 5:00 PM

> robin <robin51@dodo.com.au> wrote:
>> From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu>
>> Sent: Wednesday, 19 September 2012 1:56 PM
>
>>> Well, the dynamically allocated variables and save areas for PL/I are
>>> naturally slower than static allocated Fortran IV.
>
>> But not where it counts.  By the time some procedure (such as INVERT)
>> is called, the array(s) has(have) been allocated.  Allocation is a
>> once-off task, probably not measurable in terms of time.
>
> That comment was before the matrix inversion discussion,
> and is meant more generally.

So was my comment (in general terms).  See "some procedure".

> Yes, if you are careful with your allocations, and minimize
> subroutine calls, then it isn't so bad.
>
> Current coding practices encourage more and smaller procedures
> than were usual in the early PL/I days.
>
>> And the FORTRAN IV code was, essentially, rigid, and required
>> re-compilation for larger arrays.
>
> For single task systems, most often the memory wouldn't be used
> for anything else, but, yes, it is convenient to dynamically
> allocate to the appropriate size. It is especially useful
> for multitasking systems.

It is essential for multitasking systems because having unused
array space in a program meant that other programs could not be loaded --
thus slowing down throughput.

As for single-task systems, it's important also, because unwanted memory
(array space) in a PL/I program could be freed during execution,
thus allowing (an)other array(s) to be allocated.

Re-compiling a FORTRAN program just to make an array size
larger was wasteful.

>>> Also, many PL/I features naturally don't optimize as well as Fortran.
>
>> That may be so, but to have to re-compile the FORTRAN code to deal
>> with larger-sized arrays counted strongly against it.  As well, PL/I
>> offered full roll-out of fixed-size array operations. Not all arrays
>> needed to be dynamic.  As well as that, PL/I offered such things as
>> double precision complex, string-handling, and error recovery.
>
> IBM Fortran has had COMPLEX*16 about as far back as PL/I, but most
> others didn't. (Though the most common use for COMPLEX, the FFT,
> is most often written using REAL arrays.)
>
> Compilers I know of have the overhead needed for RECURSIVE, even
> when the attribute isn't used. But again, minimize the number
> of procedure calls and it isn't so bad.

You wouldn't notice the time unless the procedure reference were in a loop being
ecxecuted thousands of times.

>> Error recovery more than compensated for any difference in speed that
>> may have existed between FORTRAN and PL/I.  Having to re-run FORTRAN
>> code because of some error to find out what went wrong outweighed any
>> speed advantage that FORTRAN might have had, because in PL/I, the
>> error information was already there (including values of variables),
>> and without necessarily a program termination.  Hence, a re-run of the
>> PL/I code was avoided.
>
> Pretty program dependent, but, yes, PL/I can make it easier.

It made it hugely easier, for turnaround time was around a week
in those times.

> On the other hand, keeping track of ON units through procedure
> calls is another increase in the time needed for a call.

Again, unless the procedure is in a loop that is executed thousands
of times, you wouldn't notice the time.

>> That was important, not only in terms of
>> machine time, but also in terms of turn-around time, because
>> turn-around time in those days was as much as a week.
>
>> 20 W 20 is more than large enough.
>> It's the size of a typical matrix in a typical job.
>
> Pretty small for many problems, but then most bigger than
> that should be done in ways other than inversion, such
> as LU decomposition.

It was common then to use larger array sizes with matrix inversion.
The 20 x 20 matrix was a reasonable size for the timing test.

> [Even in single task systems, dynamic allocation is useful
> since it means that variables only take up space when a
> routine is active. The Fortran version of that was overlays,
> which were a lot klunkier. -John]

Agreed.  One large job (multiple regression) was able to run in PL/I
under PCP by organising various sections as BEGIN-END blocks,
so as each section completed, the storage was freed, making it possible to
enter the following section which required additional array storage.
Without that, the program couldn't run.

And while on the topic of running large programs in small memories:
an array of small integers was easily accommodated:

Instead of using BINARY, I chose FIXED DECIMAL (1).
That used one-quarter of the space compared to a 32-bit FORTRAN integer word,
and one-half the space of a default binary integer in PL/I.

PL/I on the /360 also permitted 16-bit signed binary integers, and these
could be used for large arrays with a saving of 50% over the FORTRAN integer.
[Unless someone has something to add that is more directly
related to compiler design, here endeth the skirmishing. -John]

[toc] | [prev] | [standalone]


Back to top | Article view | comp.compilers


csiph-web