[M3devel] m3cg.i3 reduction?

Jay K jay.krell at cornell.edu
Mon Mar 8 17:17:24 CET 2010


 > Front-ends should not be worried about optimising.

 

 

But it does so much already.

It unrolls comparisons of "solid" types to a certain extent.

  It took me a while to track that down.

 

It converts divides by powers of two into shift/extract.

 

 

m3front (or m3middle?) could act as "shared code" for multiple backends.

Computing the reciprocal is something that would be common

to various backends. The computation itself is portable.

The backend could chose to use it or not

(maybe some processor has a fast divide instruction..or equally

slow divide and mutiply...).

 

 

How about TInt.Reciprocal or somesuch?

 


 > doesn't mean that all upstream clients of m3middle will do so


 

What other clients of m3middle could possibly exist?

  And that really need more functionality than m3front needs?

 

 

What does insert/extract with negative numbers mean?

 I'll see if the .i3 files describes it in comments.

 

 

Please let's not just invent general generalities, that we don't use, and can't test.

What m3front needs, we should do.

What m3front doesn't need, we should not do.

m3middle serves m3front.

If/when m3front needs it, do it then.

 

 

Generalities produce dead untestable buggy code and wasted time.

There was definitely some in m3back, e.g. sign extended

extract seemed wrong for count = 0.

 

 

I forgot another suggestion:

 set_eq and set_ne are implemented the same by the two backends,

  by calling memcmp. All the other comparisons are the same too, via

  calling functions. Maybe the frontend should just know about this

  and call the functions? These are unusually high level operations

  in the backends, that neither one implements in an at all clever way.

 

 

 - Jay

 

From: hosking at cs.purdue.edu
Date: Mon, 8 Mar 2010 09:59:41 -0500
To: jay.krell at cornell.edu
CC: m3devel at elegosoft.com
Subject: Re: [M3devel] m3cg.i3 reduction?




On 8 Mar 2010, at 04:15, Jay K wrote:


The backend interface has a few aspects that the frontend does not use.
Implementations of these are therefore extremely difficult to test and therefore probably don't work. 



This is inevitable.  Your backend is not implementing an interface that the front-end defines.  It is implementing an interface defined in m3middle which is much wider than that used by m3front.  For good reason, we should not dumb down m3middle just because m3front doesn't make use of all its operations.  Similarly, you should not assume that m3front will not make use of some operations in future.  This is good practice for separation of concerns in support of modularity.


I propose:
 
 
extract and extract_n should not take a sign_extend:BOOLEAN parameter.
It is always false.



Only as currently generated by m3front.


 extract_mn shall retain its sign_extend:BOOLEAN parameter.



For consistency and generality we should retain it for all extract operators.


Though really, it could go too.
The front end could just issue divide and the backends could probably
figure it out. I like the frontend doing the work though.



The front-end should not be concerned with optimisation.  It's job is semantics, and having extract/insert is important for some targets.


 (Really, if it going to optimize divide by a power of 2, it might be nice
to compute reciprocals too...on my list for m3back..)



Same.  Front-ends should not be worried about optimising.


 The integer parameters to extract*/insert* should be CARDINAL instead of INTEGER.
Or [0..63], with the "63" abstracted out somehow and comments that clarify it is
really sometimes only 0..31.



That is not a general interface.  Just because m3front filters the operands it provides doesn't mean that all upstream clients of m3middle will do so.


The front end already issues range checks for these parameters.

The backend shouldn't worry about such wide ranges.



The backend should be prepared for them.


 Arguably remove insert_m/n and extract_m/n and just have insert/extract.



That is a possibility.  But again, some backends might find it convenient to know about constant operands.  Let's not constrain things.


The NT386 backend already notices when parameters on the stack are constants,
and the gcc backend probably does too, at least when optimizing.
The "specializations" do make it easier for a hypothetical backend simpler
than the NT386 to optimize a bit.



Precisely!


So I'm on the fence there.



We should retain them.


 Zero_n should be removed.



I've considered using it for some initialisation support.  We don't want to throw something out that may later be useful.  M3CG was designed for generality, and actually even predates the Modula-3 language itself.  It is derived from code generators at DEC SRC from the 1980s.


It isn't used.



Yet...


Far more radically, I'm suspicious that the use of a stack is a good idea.
It'd probably be just as easy or easier, and lead to better code, to
have a *sort* of union that encapsulates constants and variables,
and pass each "operation" (add/multiply/subtract/insert/extract/etc.) its
parameters with the function all.



Stack models versus "registers" have always been argued about in compiling.  Witness the Java VM spec's use of a stack as compared to the fact that most Java VMs convert the stack to registers for specific targets.


 
 
 - Jay


 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20100308/93bb1c70/attachment-0002.html>


More information about the M3devel mailing list