Re: register variables in C.

stephen@estragon.uchicago.edu (Stephen P Spackman)
Mon, 4 May 1992 07:07:11 GMT

          From comp.compilers

Related articles
[7 earlier articles]
Re: register variables in C. Brian.Scearce@Eng.Sun.COM (1992-04-30)
Re: register variables in C. pardo@cs.washington.edu (1992-05-01)
Re: register variables in C. metaware!miker@uunet.UU.NET (1992-05-01)
Re: register variables in C. preston@dawn.cs.rice.edu (1992-05-01)
Re: register variables in C. bliss@sp64.csrd.uiuc.edu (1992-05-01)
Re: register variables in C. ressler@cs.cornell.edu (1992-05-02)
Re: register variables in C. stephen@estragon.uchicago.edu (1992-05-04)
Re: register variables in C. macrakis@osf.org (1992-05-04)
Re: register variables in C. gnb@bby.oz.au (1992-05-04)
Re: register variables in C. cliffc@cs.rice.edu (1992-05-06)
| List of all articles for this month |

Newsgroups: comp.compilers
From: stephen@estragon.uchicago.edu (Stephen P Spackman)
Keywords: registers, optimize, design
Organization: University of Chicago CILS
References: 92-04-125 92-05-020
Date: Mon, 4 May 1992 07:07:11 GMT

ressler@cs.cornell.edu (Gene Ressler) writes:
|Is it not true that good register allocators treat live ranges (even of
|the same variable) separately in the cost function? Even split live
|ranges at e.g. loop boundaries?


You bet. The more time passes, the more attractive lambda calculus looks
as an intermediate code - because we can get straight to the graphs.
Variables are all in your head anyway: the semantics has values and the
machine has bits :-).


|In this context, it seems more appropriate to have programmers tag uses of
|variables rather than declarations. With apologies for the syntax:
|
| for (i = 0; f(i); ++i) {
| a[ i:reg ] = .... < executes a million times >
| }
|[etc]


You're making a crucial and untenable assumption: that i exists. If the
compiler's worth its salt you can lay money on it not getting a value
until after loop exit in this situation - unless f is external and
compiled after the loop is frozen :-). Even in this case of unoptimisable
f, you can easily imagine an (args-in-stack, caller pops) implementation
in which a[i] is replaced by a running pointer and the "true value of i"
only exists _in the stack_, at a location where f finds it each time, with
no pushes, no pops, and the increment done in place. Then it's REALLY
faster not to enregister it. If you're going to have optimisation pragmas,
why not just:


    for (i = 0; f(i); i++)
        FAST a[i] = ....;


The idea: you can put "FAST", "DENSE" or "CAREFUL" in front of any
statement (expression, whatever), and you can put it there as many times
as you want. Each occurrence just bumps the corresponding internal
optimisation level by one (at the expense of others if necesssary) - at
about the granularity of the traditional external -O flags. (Did I once
use an Apollo compiler that got this right, or is it wishful thinking on
my part?)


Here the advantage is that the compiler knows that you are worried about
improving the time performance of the body of the loop, _however that body
may be translated_. That's better, since it knows what the final code
looks like; and you don't.


A propos....


1. This forms another nice example of why annotations (which might or
might not be comments) can use careful scoping rules; using my Now
Infamous Notation Algolishly:


.for i .from 0 .while f i
.do ?fast a i = _?"executes a million times"
.


2. Half the world considers this obvious but half the world thinks it's a
totally twisted notion (so half of you skip straight to point 3 :-): you
want to collapse assertions and assumptions. If you have a single
construct


.note <predicate> .in <statement> .


you can then generate a check-and-abort wherever it is compiled with
CAREFUL > 1; take it as an assumption in the statement (a typical case
would be when it is a nonalias pragma) when FAST > 1; and do both when
both obtain.


3. Remember that in optimisation all is not as it seems. Unless the wind
changes we're due for a ton more papers of the form "space optimisation
for better speed" and so forth (and not just the odd clever hack to do
with cache line size in some proprietary processor). Paging bandwidth is
low at the moment (the garbage collection literature is exploring
compressed swap, especially attractive now that it is known not to need
tagged data representations after all) and there seems to be a healthy
awareness going around that global optmisation requires attention to local
details :-).


For instance (and obviously) optimising once-used code for speed rather
than space is a loss because you'll never win back the paging cost of its
first use. Just as enregistering a variable that then gets eliminated in
almost all its uses is a net loss.
--
stephen p spackman Center for Information and Language Studies
stephen@estragon.uchicago.edu University of Chicago
--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.