[comp.lang.misc] 'register' variables and other goodies

jlg@lambda.UUCP (Jim Giles) (02/06/90)

From article <PCG.90Feb5163252@rupert.cs.aber.ac.uk>, by pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi):
> [... 'register' is only a 'noalias' substitute - I said ...]
>
> Well, there is also actually a strong *hint* that the variable will
> be heavily *dynamically* used across statement boundaries, in the
> current scope. The compiler can use this hint very effectively.

Such a hint is only useful to an exceptionally dumb compiler.  Most
modern compilers do better data flow analysis than human programmers
are willing to do. Studies have shown that compilers can consistently
do a _very_ good job of register allocation without such hints.  In fact,
most C compilers simply ignore the 'register' attribute except to verify
that the variable is never used with an 'address-of' (&) operator.

In the overwhelming majority of programming environments, the only way
to beat the compiler's code is to switch to assembly.  The use of
'register' or other such tricks is insignificant (sometimes even
damaging).

> [...]
> A careful programmer will never declare a variable for a scope larger
> than that in which it is used, [...]

I disagree.  A careful programmer will neither write extremely monolithic
code, nor write code which is fragmented into lots of little scopes.  If
I have a 50 line function which uses XYZ in only the middle third, I'm
not likekly to make a new scope just for XYZ.  I _may_ split out the
middle third _if_ it seems to be a distinct and nearly independent
segment (but, then I would ask myself whether the code should actually
all be in the same function at all).

> [...]                          will never reuse a variable with the same
> name for two different roles.

Now, I agree with that.  However, I make one caveat: in most languages
including C, the idiom for the use of index variables in loops is single
letter variables.  Such variables are often used in separate loops (with
non-overlapping scopes of course) without any sign of confusion that I've
ever noticed.  Of course, you _could_ argue that the variable _isn't_ being
used in separate roles - it's always an index variable.

It is interesting that you consider using the same name for two different
things to be very evil and yet you consider having two names for a single
object (aliasing) to be acceptable.  For most people, the degree of evil
is the other way 'round.

> [...]
> 	Of course this is because I am eccentric enough to think
> 	that the performance characterization of a program is
> 	part of its design and pragmatics should be as obvious
> 	as semantics.

One should only degrade the readibility of code with performance enhancing
transformations when absolutely necessary: that is, when the performance
of the code would otherwise be unsatisfactory.  This usually applies only
to a very small part of the code for any given project.  Most of the code
is under another sort of optimization pressure altogether: the pressure
to work correctly, to get written quickly, to be maintainable, to be
easy to enhance when new demands are made on the program, etc..  Even
the code that needs to work _FAST_ should first be written as clearly
as possible and only _then_ optimized.

> [... Other languages don't usually _need_ 'register' ...]
> Let me differ. Fortran has had equivalence and common forever,
> and even if dirty tricks are prohibited in theory, most compilers
> cannot assume users are well behaved [...]

There is a difference between aliasing and storage association.  Common
blocks can cause storage association between different objects - but _NOT_
within the same scope.  The only type of aliasing possible with common
is passing common variables through the argument list.  But this is illegal!
And most compilers _DO_ assume that such aliasing has not occurred.

As for equivalence: that is a _LOCAL_ declaration.  The compiler can clearly
see what variables are aliased and what variables aren't.  There is no need
for a 'register' attribute to declare this information, the compiler is
already explicitly aware of it.

Fortran 90, on the other hand, has introduced pointers which can point
to other (non-dynamic) objects.  In this language, something analogous
to the 'register' attribute is needed.  The method chosen by the
committee was symmetric to the C solution: Fortran 90 has the POINTEE
attribute, which tells the compiler that an object _may_ be aliased.
This means that the default attribute of most Fortran 90 objects is
effectively 'register'.

> [...]          Pascal has 'var' parameters,

Yes, but Pascal is not separately compilable.  The compiler can do a complete
interprocedural dataflow analysis to find out _unambiguously_ what arguments
might be aliased with what global variables.

> [...]                                       and, more murkly, variant
> records without discriminant.

C _also_ has variant records without discriminants!  They're called unions.
The kinds of problems caused by such things are usually type-coercion
problems and have nothing to do with 'register' attributes or aliasing
in the hidden sense.  After all, the declaration of such a union is clearly
visable in any scope that can reference any field in it - so the compiler
can already determine that overlapping fields _might_ be aliased (just like
Fortran's EQUIVALENCE in fact).

> [...]
> the absence of presence of 'noalias' (and 'volatile') does change the
> semantics of a program, while for 'register' this is not true; [...]

This is false.  The 'register' attribute should have no effect on the
_semantics_ of a correct program.  If you don't use the address-of (&)
operator on a variable, the presence or absence of 'register' on that
variable should have NO effect on the semantics of the code.  If it does,
I suspect that you have a broken compiler!

> [...]                                               'register'
> also gives a *positive* hint on usage frequency.

Yes, one that is practically useless on a good compiler.  In fact, if
the compiler makes an effort to put your 'register' vars into registers,
it may actually _inhibit_ optimal register utilization.

The fact of the matter is, usage frequency is one of the things I expect
the language environment to tell ME, not the other way around.  The
compiler and the run-time profiler are where that information comes
from - not from my gut feeling.  Now, if the profiler could feedback
information into the compiler for a subsequent compile, THAT might
be a useful feature.

> [...]
> With 'register' safety (no aliasing) is a side effect, but a
> clever one, under more than one aspect.

Actually, no aliasing is about the _only_ useful feature of the 'register'
attribute.  And it is one that is basically unneeded in other languages.
Even so, it's not all that useful - unless you like to explicitly copy-in
copy-out all your global variables that you wish to use.  And it doesn't
help with array manipulation at all (which are still pointers and are
assumed aliased to everything that's not 'register').

> [...]
> What ruins the alias show for most languages is either separate compilation
> or parameter passing, even where pointers are not present.

It's not either-or.  The problem arises only with _both_ parameter passing
and separate compilation.  Without separate compilation, the compiler can
look at the whole call tree to detect any possible aliasing.  Without call
by reference there is no problem (and this is the only parameter passing
mechanism which causes the problem).

Even so, a run-time test for aliasing would be cheap and easy to implement,
but the current lack of interest indicates to me that there really isn't
much of a problem.  Compilers _DO_ optimize as if such aliasing has not
taken place and they _DON'T_ usually test for aliasing - yet the frequency
of such errors is very small.

> [...]                                                       And even if
> this not true, the compiler still has to guess which of the safe variables
> are actually worth caching.

But, this is something that the compiler is usually _very_ good at.  Better
than most people have time to be.  (And, if you _do_ have time, you're
better off going to assembly where your register declarations aren't hints
but _orders!)  

> [...]
> 	Naturally this is a moot point on many of today's architectures,
> 	where register optimization is entirely unnecessary, as there usually
> 	far more registers available than variables [...]

Additional registers aren't a panacea.  For one thing, as the number of
registers increase, the register allocation schemes have gone 'cosmopolitan'.
There is an increasing effort to keep data in registers across procedure
calls.  The less efficiently codes use the registers, the less efficiently
the code runs - even if there are a massive number of registers.

For another thing, register utilization is not the only thing inhibited
by aliasing!  All those multi-register machines you're talking about are
also likely to be pipelined.  Pipelining is inhibited by possible aliasing
as bad (or worse) than register utilization.  And there's NO source level
control (in C or anywhere else) over code ordering optimizations on the
pipelining level.  The best thing is for the language to be designed in
such a way that aliasing is difficult and rare and is only forced upon
the user when it is actually part of the functionality he needs.

J. Giles

mjs@hpfcso.HP.COM (Marc Sabatella) (02/07/90)

>> Well, there is also actually a strong *hint* that the variable will
>> be heavily *dynamically* used across statement boundaries, in the
>> current scope. The compiler can use this hint very effectively.
>
>Such a hint is only useful to an exceptionally dumb compiler.  Most
>modern compilers do better data flow analysis than human programmers
>are willing to do. Studies have shown that compilers can consistently
>do a _very_ good job of register allocation without such hints.  In fact,
>most C compilers simply ignore the 'register' attribute except to verify
>that the variable is never used with an 'address-of' (&) operator.

Throw in profiling, and you've got a deal.  But very few compilers actually
take profiling data into account, and if you've written a routine which takes
a parameter 'n' that gives the iteration count for the loop, no amount of
static data flow analysis (even interprocedural, in many cases) is going to
tell you the dynamics of that loop.  Now say you have another loop, with a
fixed count of "10".  Which should the optimizer think is going to be more
heavily executed?  A careful programmer can hint to the optimizer with
'register' which variables he thinks are more important, which may be all the
hint the compiler needs.  And often it doesn't take a lot of work to do this,
so you are not "better off using assembly langauge".  There is also
portability to consider.

Now I agree that often, the 'register' attribute is misued by programmers.
So I would suggest a compiler pragma which says something to the effect of
"take my register declarations seriously", and ignorigin them (as usual) by
default.

>Yes, but Pascal is not separately compilable.  The compiler can do a complete
>interprocedural dataflow analysis to find out _unambiguously_ what arguments
>might be aliased with what global variables.

(scoff...)

preston@titan.rice.edu (Preston Briggs) (02/07/90)

In article <8960010@hpfcso.HP.COM> mjs@hpfcso.HP.COM (Marc Sabatella) writes:
(in response to a posting by J. Giles)

>>Yes, but Pascal is not separately compilable.  The compiler can do a complete
>>interprocedural dataflow analysis to find out _unambiguously_ what arguments
>>might be aliased with what global variables.

>(scoff...)

You doubt?

People *have* built interprocedural flow analysers for Pascal compilers.
People have even done it for Fortran, complete with separate compilation.
Even commercial people (as opposed to research).
Other people even use such compilers.

Preston Briggs
preston@titan.rice.edu

mjs@hpfcso.HP.COM (Marc Sabatella) (02/07/90)

>People *have* built interprocedural flow analysers for Pascal compilers.
>People have even done it for Fortran, complete with separate compilation.
>Even commercial people (as opposed to research).
>Other people even use such compilers.

Saying that there exist such compilers (and we all know many implementations
of Pascal *do* support separate compilation) is not the same as saying it
is "not a problem for Pascal".

jlg@lambda.UUCP (Jim Giles) (02/08/90)

From article <8960010@hpfcso.HP.COM>, by mjs@hpfcso.HP.COM (Marc Sabatella):
> [...]                             and if you've written a routine which takes
> a parameter 'n' that gives the iteration count for the loop, no amount of
> static data flow analysis (even interprocedural, in many cases) is going to
> tell you the dynamics of that loop.

Agreed.  So, in lieu of complete information, you optimize the code as
if 'n' were large.  If 'n' really _is_ large, you have a winning solution.
If 'n' is not large, you don't suffer much - the code isn't executed much
in this case.  Of course, the more that is known about 'n' the better
you can optimize the loop.  If 'n' is known to be small, you might 
_completely_ unroll the loop or perform some other modification.  But,
a better hint to the compiler in this case is _not_ to use 'register'
attributes.  Instead, the language sould provide some mechanism for
making (checkable) assertions.  For example:

      Assert(n>0 and n<=15)

The generated code can then test the assertion at run-time and the
compiler can generate the rest of the code efficiently based on the
assertion.  Of course, you might want a compiler option to turn off
the run-time checking of assertions.  Furthermore, this is _much_
more refined and clean than the methods recommended by Peter Grandi
for documenting the assumptions of the programmer.

Every time a language standard comes up for review, some recommendation
like the above 'Assert' feature is brought up (it happened for both C
and Fortran in the last few years).  I don't know what arguments have
resulted in leaving such features out.  The state-of-the-art of
compilers is gradually reaching the point where such assertions
can be used very well indeed.  Oh well....

> [...]                                Now say you have another loop, with a
> fixed count of "10".  Which should the optimizer think is going to be more
> heavily executed?

I don't see your point.  If the loops are disjoint, the registers used by
the first are free by the start of the second.  If the loops are nested,
the inner-most loop should be optimized regardless of any 'register'
declarations.  Since these are the only two possibilities, I don't see
how the lack of information about 'n' can negatively effect the loop
with constant trip-count at all.

J. Giles

meissner@osf.org (Michael Meissner) (02/10/90)

In article <8960010@hpfcso.HP.COM> mjs@hpfcso.HP.COM (Marc Sabatella) writes:

| >> Well, there is also actually a strong *hint* that the variable will
| >> be heavily *dynamically* used across statement boundaries, in the
| >> current scope. The compiler can use this hint very effectively.
| >
| >Such a hint is only useful to an exceptionally dumb compiler.  Most
| >modern compilers do better data flow analysis than human programmers
| >are willing to do. Studies have shown that compilers can consistently
| >do a _very_ good job of register allocation without such hints.  In fact,
| >most C compilers simply ignore the 'register' attribute except to verify
| >that the variable is never used with an 'address-of' (&) operator.
| 
| Throw in profiling, and you've got a deal.  But very few compilers actually
| take profiling data into account, and if you've written a routine which takes
| a parameter 'n' that gives the iteration count for the loop, no amount of
| static data flow analysis (even interprocedural, in many cases) is going to
| tell you the dynamics of that loop.  Now say you have another loop, with a
| fixed count of "10".  Which should the optimizer think is going to be more
| heavily executed?  A careful programmer can hint to the optimizer with
| 'register' which variables he thinks are more important, which may be all the
| hint the compiler needs.  And often it doesn't take a lot of work to do this,
| so you are not "better off using assembly langauge".  There is also
| portability to consider.

The MIPS compilers seem to have the ability to use profiling data when
doing full blow optimization.  Here are some sections from the online
manual (from a Dec Pmin system):

Cc(1) man page section:

     -O3            Perform all optimizations, including global
                    register allocation.  This option must pre-
                    cede all source file arguments.  With this
                    option, a ucode object file is created for
                    each C source file and left in a .u file.
                    The newly created ucode object files, the
                    ucode object files specified on the command
                    line, the runtime startup routine, and all
                    the runtime libraries are ucode linked.
                    Optimization is performed on the resulting
                    ucode linked file and then it is linked as
                    normal producing an a.out file. A resulting
                    .o file is not left from the ucode linked
                    result.  In fact -c cannot be specified with
                    -O3.

     -feedback file Use with the -cord option to specify the
                    feedback file.  This file is produced by
                    prof(1) with its -feedback option from an
                    execution of the program produced by
                    pixie(1).

     -cord          Run the procedure-rearranger on the resulting
                    file after linking.  The rearrangement is
                    performed to reduce the cache conflicts of
                    the program's text.  The output is left in
                    the file specified by the -o output option or
                    a.out by default.  At least one -feedback
                    file must be specified.

Prof(1) man page section:

     -feedback filename
               Produces a file with information that the compiler
               system can use to decide what parts of the program
               will benefit most from global optimization and
               what parts will benefit most from in-line pro-
               cedure substitution (requires basic-block count-
               ing). See cc(1).
--
Michael Meissner	email: meissner@osf.org		phone: 617-621-8861
Open Software Foundation, 11 Cambridge Center, Cambridge, MA

Catproof is an oxymoron, Childproof is nearly so

pcg@aber-cs.UUCP (Piercarlo Grandi) (02/10/90)

In article <14226@lambda.UUCP> jlg@lambda.UUCP (Jim Giles) writes:

	[ an argumetn based on the assumption that commonly available
	compilers are very good at discoverin which variables
	are frequently used, and similar interesting things ]

UNFORTUNATELY, this assumption is unproven. Commonly available
compilers are not able to do this. What happens is that
virtually every compiler out there optimizes based on *static*
frequency of usage, and even this is irrelevant on many modern
machines that have more registers than most programs can use.

Compilers that can do a good job should either use heuristics,
or profile feedback, and are exceedingly rare. In both cases
the compiler becomes more complex (becomes it has to analyze
control and data flows as a preliminary -- it is this that makes
the compiler more complex, not the optimization per se). I think
that the programmer, *by design* (aided by heuristics and
profiling, yes) should know what is going on, and tell the
compiler instead.

In any case, whether compilers can or could do this analysis is
a different issue from whether the programmer *should* document
the performance assumptions made in a piece of program, and
whether the compiler should ignore this.

I reckon the programmer should, because I reckon that programs
ought to be as precise descriptions as possible, both as to
semantics and as to pragmatics.

The issue is then whether the reader of a program be it either
human or program should not be required to second guess the
author.

Once this is demonstrated undesirable, the issue of whether
compilers should do this, taking into account the extra
complexity and ensuing unreliability of getting a much more
sophisticated compiler, and the effectiveness of doing so.

Any technology should be examined as to it cost, not just as to
its benefit. Are aggressive optimizers so effective that the
added cost in compiler complexity and reliability, in encouraging
more sloppily written programs, in resource usage, is worth it?

A completely seaprate issue is instead that of having a
'programmer assistant' that aids the programmer with writing
source code, e.g. in doing program transformations; as to this
I am in favour, as long as this is not made part of a code
generator.
-- 
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk

cks@white.toronto.edu (Chris Siebenmann) (02/13/90)

pcg@cs.aber.ac.uk (Piercarlo Grandi) writes:
| Compilers that can do a good job should either use heuristics, or
| profile feedback, and are exceedingly rare. In both cases the
| compiler becomes more complex (becomes it has to analyze control and
| data flows as a preliminary -- it is this that makes the compiler
| more complex, not the optimization per se).

 Profiling feedback compilers are becoming more and more common and at
least one set are fairly widely used: the MIPSco compilers. As people
start reading various technical reports about the gains possible and
become more aware of the usefulness of this sort of thing.

| I think that the programmer, *by design* (aided by heuristics and
| profiling, yes) should know what is going on, and tell the compiler
| instead.

 I agree that programmers should have some way of manually telling the
compiler about usage frequency. However, given that we're already
assuming a profiler at work, and the usual quality of commercial
programmers, I think it's foolish not to let the compiler/linker read
the profiling results directly. When something is simple and
mechanical, why not let the computer do the drudge work?

 I wonder how many programmers even bother running a profiler on their
programs? I suspect not many.

--
	"I shall clasp my hands together and bow to the corners of the world."
			Number Ten Ox, "Bridge of Birds"
cks@white.toronto.edu		   ...!{utgpu,utzoo,watmath}!utcsri!white!cks

pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi) (02/14/90)

In article <1990Feb12.172948.17784@jarvis.csri.toronto.edu> cks@white.toronto.edu (Chris Siebenmann) writes:

    Profiling feedback compilers are becoming more and more common and at
   least one set are fairly widely used: the MIPSco compilers.

Sure the MIPSco people would love their compilers to be widely used...
Sure DEC is contributing powerfully... :-) :-).

    I agree that programmers should have some way of manually telling the
   compiler about usage frequency.

Definitely yes! Even if the compiler uses heuristics or profiling,
the programmer may still know better in certain cases.

   However, given that we're already assuming a profiler at work, and
   the usual quality of commercial programmers, I think it's foolish
   not to let the compiler/linker read the profiling results directly.

   When something is simple and mechanical, why not let the computer
   do the drudge work?

I tend to agree in principle. In practice, things are less clear
cut.  To make use of profling and heuristic information, the
compiler has to run complex analysis and optimizing modules. This
is *bad*. The beauty of things like 'register' is that they are
absolutely safe and effective, without any analysis whatsoever.

   I wonder how many programmers even bother running a profiler on their
   programs? I suspect not many.

Very few. Actally, in most cases, profiling requires recompilation,
and this is often not very attractive, and in any case very few
programmers would understand the profile.

I think that rather than sticking complex, often unreliable and
ineffective optimizers in the bowels of code generators, the
following topics should be explored:

1) ways to make languages safer without requiring complex analysis;

2) ways to describe the semantics and pragmatics of a program, both
   to human and programmatic readers;

3) ways to make it easier to profile for time, e.g. for a coarse first
   run use statistical PC sampling, without recompilation, and then
   using flow graph based tecniques;

4) ways to make it possible to profile for space, e.g. for a coarse first
   run use statistical page reference sampling, without recompilation, then
   using flow graph based techniques, e.g. in malloc() or equivalents;

5) programmer's assistants that do a thorough analysis of the source code;

6) programmer's assistants that help make transformations of the source code;

7) training better programmers (oh well, let's dream...).

I am aware of some work in the literature about these points
(Alpeh, Euclid, lint, ....), but it is pitifully small compared
to the vast effort expended on what by comparison is an unsafe,
inefficient shortcut, "optimizers", not to mention recent
standard efforts that have worsened problems (volatile!).

If you look at things cynically, "optimizers" are a shortcut most
effective only on benchmarks, and these sell machines...
--
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk

jlg@lambda.UUCP (Jim Giles) (02/14/90)

From article <PCG.90Feb13161349@rupert.cs.aber.ac.uk>, by pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi):
> [...]
> to the vast effort expended on what by comparison is an unsafe,
> inefficient shortcut, "optimizers", [...]

You keep saying that.  However, you have yet to prove (or even make a
good case) that optimizers are either unsafe or inefficient.  To be sure,
I have no absolute objection to 'hints' that help the compiler do a
better job.  BUT - the compiler should be expected to do a reasonably
good job in the absence of such 'hints'.  Furthermore, a compiler with a
good optimizer should be expected to do _better_ than a simple compiler
even on the 'hint' filled code!

After all, the _PURPOSE_ of a compiler is to translate from source code
to semantically equivalent machine code.  Unfortunately, there are an 
infinite number of semantically equivalent translations!!!  Optimization
is a word for several compiler techniques of selecting one of these
translations which is - at least - reasonably efficient.  In fact, in
order to use the _programmer's_ time most effectively, the compiler
writer should get the compiler to produce the most efficient code he
can.

(By the way, I DO have an objection to the 'uglifying hints' that C makes
available.  It seems to me that conveying such information to the compiler
shouldn't require destroying the natural flow of the source code.)

J. Giles

steve@cs.su.oz (Stephen Russell) (02/15/90)

In article <PCG.90Feb13161349@rupert.cs.aber.ac.uk> pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi) writes:

>I tend to agree in principle. In practice, things are less clear
>cut. [...] The beauty of things like 'register' is that they are
>absolutely safe and effective, without any analysis whatsoever.
>I think that rather than sticking complex, often unreliable and
>ineffective optimizers in the bowels of code generators, ...

Complex, probably, though this depends on the target architecture and
the ambition of the compiler writers. Simple optimisers can be very
effective (eg, Powell's Modula-2 compiler's register allocation
strategy).

Unreliable, sometimes.

Ineffective, depends. There have been some very effective optimisers
around (eg, Bliss, DEC M2, MIPSCo).

A typical optimiser does much more than just register allocation.  It
may even be essential when there is a mismatch between the source and
target architectures. The match for C and the PDP-11 was very good, but
this doesn't guarantee that C will match all other architectures as
well.  Without a good optimiser, improving the match may require lots
of hand rewriting when code is ported. A well-written code generator
will do most of this rewriting automatically, and perform optimisations
that cannot be expressed (or only in an ugly manner) in the source
language.

>... the following topics should be explored:

[list of topics deleted, except for ...]

>5) programmer's assistants that do a thorough analysis of the source code;
>6) programmer's assistants that help make transformations of the source code;

What would you call an effective "programmer's assistant" that does a
thorough analysis of code (the level is mostly irrelevant) and makes
optimising (you don't want _worse_ code, right?) transformations? I'd
call it an optimiser.

>I am aware of some work in the literature about these points
>(Alpeh, Euclid, lint, ....), but it is pitifully small compared
>to the vast effort expended on what by comparison is an unsafe,
>inefficient shortcut, "optimizers"

I don't see how arguing in favour of safer HLL's is an argument against
aggressive code generators. In fact, I would have thought that further
movement away from programming the bare metal increases the need for
better optimisers to bridge the gap, particularly when RISC
architectures are also increasing the gap.

cks@white.toronto.edu (Chris Siebenmann) (02/20/90)

pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi) writes:
[I wrote]
|     Profiling feedback compilers are becoming more and more common and at
|    least one set are fairly widely used: the MIPSco compilers.
| 
| Sure the MIPSco people would love their compilers to be widely used...
| Sure DEC is contributing powerfully... :-) :-).

 Well, MIPSco-based machines seem to be the dominant thing to buy
here. I hope vendors will be paying attention to the quality of the
MIPSco compilers and implementing similar features. Maybe one of the
88K vendors will even stick this into gcc and feed the changes back to
the FSF.

|    When something is simple and mechanical, why not let the computer
|    do the drudge work?
| 
| I tend to agree in principle. In practice, things are less clear
| cut.  To make use of profling and heuristic information, the
| compiler has to run complex analysis and optimizing modules. This
| is *bad*. The beauty of things like 'register' is that they are
| absolutely safe and effective, without any analysis whatsoever.

 If the compiler makes use of usage hints at all, I suspect that
getting it to take them from a profile file instead of from the source
code is fairly easy. A sophisticated compiler will want to anyways,
because its using more fine-grained granularity than a function
anyways.

 One danger of having only programmer-level hints is that quite a few
programmers will add wrong hints, or change their programs such that
hints become incorrect. The only way to make sure that the hints are
correct is to make their gathering and use automatic or nearly so.

--
	"I shall clasp my hands together and bow to the corners of the world."
			Number Ten Ox, "Bridge of Birds"
cks@white.toronto.edu		   ...!{utgpu,utzoo,watmath}!utcsri!white!cks

dhinds@portia.Stanford.EDU (David Hinds) (02/20/90)

In article <1990Feb19.155810.29127@jarvis.csri.toronto.edu>, cks@white.toronto.edu (Chris Siebenmann) writes:
> 
> |    When something is simple and mechanical, why not let the computer
> |    do the drudge work?
> | 
> | I tend to agree in principle. In practice, things are less clear
> | cut.  To make use of profling and heuristic information, the
> | compiler has to run complex analysis and optimizing modules. This
> | is *bad*. The beauty of things like 'register' is that they are
> | absolutely safe and effective, without any analysis whatsoever.
> 
>  One danger of having only programmer-level hints is that quite a few
> programmers will add wrong hints, or change their programs such that
> hints become incorrect. The only way to make sure that the hints are
> correct is to make their gathering and use automatic or nearly so.

     Not to mention that programmers are not omniscient, and a good
programmer's best hints aren't enough.  FORTRAN may not be a fashionable
language among computer scientists, but twenty years of improvement has
yielded highly optimizing mainframe compilers that generally can't be
beat by hand-coded assembly language.  And on unusual architectures, it
is often a nightmare for a programmer to figure out an efficient use of
the machine's resources.  For example, on a Cray, FORTRAN is presently
the only way to make efficient use of the machine's resources.  Cray
Unix may be "hot" now, but C brings the machines to their knees.

 -David Hinds
  dhinds@popserver.stanford.edu

sommar@enea.se (Erland Sommarskog) (02/25/90)

Piercarlo Grandi (pcg@cs.aber.ac.uk) writes:
>Any technology should be examined as to it cost, not just as to
>its benefit. Are aggressive optimizers so effective that the
>added cost in compiler complexity and reliability, in encouraging
>more sloppily written programs, in resource usage, is worth it?

It is maybe totally irrelevant, but I cannot fail to notice
that Piercarlo Grandi is posting from an academic site. In
real life, it is in many cases not a question on whether to
write as fast code as possible, but to write code as fast as
possible. There are delivery deadlines to keep. And very seldom
can you advocate from an economic point of view to polish every
part of a big program. Let a good optimizer take care of the
main bulk, and then put the efforts where the bottlenecks are. (*)
  Also, you shouldn't spend the time on the wrong issues. With
the application I currently work, optimization of the Pascal
code probably has little significance since this is a database
application where the I/O is the critical part.

>The issue is then whether the reader of a program be it either
>human or program should not be required to second guess the
>author.

If you write a program to help the compiler to produce good code,
you very often run the risk of having another human reader to
second-guess (whatever that means) what you originally meant.

(*) And when you look at those bottlenecks, what you have to do
is often not to help the compiler, but improve the algorithm. I 
had a program which the profiler told me I spend a good deal of the
time inserting elements in linked lists. So what did I do? Did
I rewrite the linked-list package? No, I changed the way of working
with the lists to keep them down in size. (They were sorted.) When 
I was ready with it the insertion routine was below 1% of the 
executed time. -- 
Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se