From: johnr@ee.uts.edu.au (John Reekie)
Newsgroups: comp.dsp
Subject: Re: Philosophy of DO loops (Was: 96002 Question)
Date: 5 Nov 92 04:04:23 GMT
Organization: University of Technology, Sydney
NNTP-Posting-Host: rossi.ee.uts.edu.au

mmh@mercury.analog.com (Marc M. Hoffman) writes:

>In article <johnr.719787436@ee.uts.EDU.AU> johnr@ee.uts.edu.au (John Reekie) writes:

>All my statements are based on our new compiler GCC and when I say 'we'
>that means our version of the GCC compiler.

>   Uh, well, I'm not exactly working on a compiler, but I'll have to
>   pretty soon. I'd add:

>   vi. modulo addressing

>We do this in our GCC compiler.  Althought the solution is not as
>general as we would like the solution works for most applications.

>Depending on the architecture you might be able to use the combiner of
>GCC to recognize the modulo addressing.  i>N?0:i+1 or something like
>this.  But on our architecture this doesn't work because of the b|i
>combinations. 

Isn't what's really required a pointer object? So you could go
something like:

	ModuloBuffer<float> p;		/* modulo buffer of floats */
	p = newModuloBuffer( N );	/* N is size of buffer */

	*p.current = x;			/* read from buffer */
	*p.current++ = y;		/* write and (modulo) increment */

	... p.base ...;			/* this is th base address */
	... p.size....;			/* this is the size of it */
	
	ModuloBuffer<float> q;
	q = accessModuloBuffer(p);	/* reference the same memory */

	if ( p.current >= q.current )	/* modulo comparison ? */

I know nothing about C++, but I;m sure this could be expressed
easily in it. Then all you do is say that your compiler
"knows" about certain types of object, such as ModuloBuffers.	
It can generate efficient code for calls like *p.current++
(on C30, you would get ldf *ar0++%,r0, for example). AND the
code would still be standard C++, so you could have portability
as well.

Does anyone have any comments on this idea?
		
>   vii. use of index registers

>We use index registers as much as possible.  We even generate
>postmodify code.


So if I have

	for ( i = 0; i < N; i++ ) {
		*p = *q;
		p += pinc;
		q += qinc;
	}

it will do the pointer updates using postmodify? (pinc and qinc
are not known at compile time!)

>   viii. Associative and non-associative arithmetic (I guess this
>	 is really a language feature)

>?? what does this mean

Well, I could have put it better, that's for sure. I was trying
to say that sometimes you need to be able to specify the
exact order of computation of an expression, and not have the compiler
re-arrange it, for reasons of precision. On a related note, it
may also be desirable to be able to specify numeric precision,
so that high-precision values are kept in registers, (even if
this requires extra cycles). I don't know much about this topic --
maybe someone who does could offer an example?

>   ix. smart structure return i.e. return small structures in
>       registers

>This is extreamly hard with a multi-memory architecture.  But I think
>it can be done easily if the function prototype stated where the value
>must be returned to..

I'm not sure I understand the problem. Doesn't gcc return
strctures that will fit into teh register set in registers?
This would be very important for complex numbers, for example.

>   x. Ability to inline assmebler functions (no idea how this would
>      work!)

>This is awsome and GCC provides the Best assembler interface that I
>have ever seen.  Check it out..

I will (one of these days....). What is the difference between
gcc 2.0 (which is on our machine) and gcc 2.22 (which is what
everyone talks about :-) )?

>   xi. Automatic code inlining

>Gcc does this too via a switch.

>   xii. complex number smarts (again a language feature -- I guess
>       I'm talking about not just C compilers).

>We have added this feature to our compiler.  And we like it very much
>here look:

>void fft(complex int data[], complex int coef[])
>{
>  complex int A, B, Coeff, temp;
>  int groupsPerStage = 1, BperG = 1024  >> 1;

>  for(I=10) {
>    for (J = groupsPerStage) {
>      for(K = BperG) {
>	temp = coef[I] * data[(2*J+1)*BperG+K];
>	data[ 2*J    * BperG + K] += temp;
>	data[(2*J+1) * BperG + K] -= temp;
>      } 
>    }
>    groupsPerStage <<= 1;
>    BperG >>= 1;
>  }
>}

This is pretty neat. How does the performance compare with
an assembler implementation? You use array indexing instead
of pointers -- does this adversely affect performance?

My earlier attempts to find out mroe about Numerical C
have met with no success. What document would I ask the
local rep for to find out at least about your implementation?
The DSP/C manual?

>   xiii. Preservation of dependencies between instructions so the compiler
>	 can fill in pipeline holes.

>The gcc compiler 2.0 or better does a fairly good job scheduling
>code..   


John Reekie


Newsgroups: comp.dsp