Potential optimisation?

The Sherif "Matt D." dillon at ucbvax.ARPA
Wed Jan 23 03:06:44 AEST 1985


> Hi,
> 
> Please don't flame me, despite what my .signature entry may say.  This
> is in the spirit of honest enquiry.  I don't know whether the following
> is feasible in the presence of signals and the like.
> 
> I was thinking of the possible ways that C could be sped up, in a
> general fashion.  Part of the philosophy of using procedural languages
> such as C, is that the incentive is present to break up the program
> into small manageable functions.  Much of this incentive is lost if the
> function call is overly expensive.
> 
> 1) The current process of passing parameters on the stack has many
> advantages.  Primary among these are the capabilities of declaring
> routines that take a variable number of arguments (*Yes*, they are
> often necessary, and even clean).  Also, a consistent calling interface
> is desirable when linking in separately compiled, or assembly language
> routines.  Unfortunately, this adds a great deal of unnecessary
> overhead.
> 
> One way to handle this would be to handle calls to 'static' functions
> differently, based on observed usage in the rest of the file (NOTE:
> this probably would require multiple passes).  Parameterless static
> functions could be called via a 'jsr' or equivalent.  Functions with
> fewer than 'n' constant arguments could have their arguments passed in
> registers.  Static functions whose usage indicated a VARARGS usage
> would have the parameters passed in the usual fashion.  Static
> functions which are only referenced once or twice could be expanded
> inline.  Now, so far there is nothing new here.  However....
> 
> I took a look at a lot of C code on my (4.2 BSD) system.  An informal
> guess would be that over 50% of the functions in the source files could
> be declared as 'static'.  Now, let us say that we have another keyword
> 'exported' which is used to label those functions which are called from
> other source files.  All functions which were *not* declared to be
> *exported* would be considered static by default.  This would allow the
> efficient generation of code.  It would also be easier to read code
> that used this, as one would not have to sit down with a cross
> reference listing.  Furthermore, register allocation could be done on
> an inter-functional basis.  Lastly, the code could be portable through
> the use of ...
> 
> # define exported /* foobar */
> 
> in a header file, effectively stripping them in the case where they
> were not understood.
> 
> 2)  In a UNIX C compiler (to the best of my knowledge) two assembly
> procedures CSV and CRET are used to save and restore the registers in
> the *called* procedure.  I fail to see why this is desirable.  The
> *calling* procedure has full knowledge of which registers are being
> used and can save them itself.  This may not result in savings, but I
> don't see where it can result in a performance degradation.
> 
> 3)  Automatic data definitions are always allocated space on the
> stack.  This is fine in the presence of recursive functions.  However,
> in practice, recursive functions are not very heavily used.  Some means
> of data flow analysis might allow the allocation of automatic data
> statically at compile time, with each datum at a constant offset from
> the start of the object file.  The data flow analysis could enable the
> re-use of space.  This would allow processes to take up less space
> while running, as the maximum stack size would be known at compile
> time.  Of course, recursive functions would still have their local data
> allocated on the stack.
> 
> Well, what do you think.  I would appreciate some feedback on this.
> Please reply by mail.  If the responses warrant it, I will summarize to
> this group.
> 
> Regards,
> 
> -- 
> 				Binayak Banerjee
> 		{allegra | astrovax | bpa | burdvax}!sjuvax!bbanerje
> P.S.
> 	Send Flames, I love mail.

	Flame?... I wouldn't think of it.  I see a flaw in your thinking,
though.  Registers, by definition CANNOT change from original values after
a subroutine call returns.  So, the compiler pushes the registers on the
stack before a call, and pulls them back after a call.  This is nessasary
considering you can have constructs such as 'register int charlie'.  
Variables in registers go extremely fast, as you might guess.  Also, many
assembly languages such as Perkin-Elmer3230 provide a single instruction
for 'pushing' registers on the stack.

	You can't ignore registers.

	Well that's my piece of the action....Anybody else?



	



More information about the Comp.lang.c mailing list