[comp.sys.amiga.tech] Lattice C 5.02 REVIEW, By Matthew Dillon

dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) (06/30/89)

	Well, here is a review of Lattice C V5.02 vs (if you insist) Manx C
	V3.6a

	First of all, I would like to say that Lattice has been much more
	responsive to reported bugs and are generally easier to reach than 
	Manx.  I had several long talks with John Toebes at DevCon and really
	like the direction Lattice is going.

	I would like to thank Jim Goodnow for kindly giving me Manx C 3.4a 
	a couple of years ago and the update to 3.6a several months ago.

	I would like to thank John Toebes for kindly giving me the most
	recent release of Lattice C, V5.02

	Please keep in mind that I am comparing the very latest Lattice C
	with a relatively old Manx C (but still the latest I've heard about).
	I do not know what will be in the next release of Manx C but I do know
	that it will make or break the company (in regard to C on the Amiga).
	
	I always keep an open mind.

			#asm, who needs #asm?

	One of my first questions was, is #asm supported in Lattice V5.02 ?
	It isn't, but John assured me that I really didn't need it and it
	turns out he was absolutely correct!

	Lattice V5.02 supports keywords that effectively remove the need to
	hack assembly tags and other things that crop up.   The keywords
	associated with this feature:

	__asm		-These allow you to specify that subroutines takes
	__d0 to __d7,	 parameters in specific registers instead of on the 
			 stack
	__a0 to __a6

			__asm blah (register __d0 int a, register __a0 int *b);

			currently you may only declare that data registers pass
			non pointers and address registers pass pointers.

	__saveds	-This automatically saves the data segment register
			 (A4) and then loads it with the proper value.  On
			 return the original contents of A4 is restored.

	The above effectively removes nearly all #asm's I had to put in 
	under Aztec C.

	Lattice conforms to using only D0-D1/A0-A1 as scratch.  Manx by
	default also uses D2-D3 as scratch with an option to save/restore
	them (but code generated using this option saves/restores D2/D3
	whether they are used or not so I try not to use it).  Since Lattice
	conforms to the Amiga spec in this regard no hacks are required to
	get it to save/restore nonconforming registers.

	This type of support allows one to write library functions and 
	interrupts directly in C without any assembly tags files.  The latter 
	is something you could not do in Manx C even *with* the #asm
	construct, at least not with any assurance.

	And for those of you who are crying about loosing 'standard C', I would
	say that using the new keywords are at least as portable as using
	#asm or .asm files.  Lattice will allow you to insert direct machine
	code into any C subroutine via the 'emit' inline function.  I will
	probably never find the need to use it.

	In anycase, the few remaining #asm's I had in my code were really so I
	could have the entire program in one file and it wasn't difficult to
	remove these to separate .asm files and assemble them with lattice's
	asm program.  They were mainly incredibly optimized subroutines I
	had written.

			OPTIMALITY, OPTIMIZATION, CODE SIZE

	Lattice now has a 'registerization of parameters' option.  If you give
	lc the -rr option, arguments to all fully prototyped functions will
	be passed in registers.  The first two data items and first two 
	pointer items to be specific (remaining arguments are passed on the
	stack).

	This is completely transparent and needs no special keywords other than
	using standard ANSI prototypes.  The prototypes themselves can be
	made compatible with non ANSI C compilers with a simple #define
	
	#ifdef LATTICE
	#define ARGS(blah) blah
	#else
	#define ARGS(blah) ()
	#endif

	extern int charlie ARGS((int, int, char *, short));

	There are a couple benign bugs with this feature that show up as
	blink errors.  Lattice in 5.02 accidently forgot to add the __stdargs
	keyword to the prototypes for AMIGA.LIB (__stdargs forces all 
	arguments to be passed on the stack even when you compile with -rr).

	Lattice C names routines differently if they expect registerized
	parameters vs. normal stacked parameters.  an '@' is used instead of
	an '_'.  THIS IS GOOD... Thus the link error.  For example, when I
	compiled under Lattice -rr and called NewList() (in Amiga.LIB) I
	got a blink error '@NewList' not found.  Of course, because the
	NewList() in AMIGA.LIB is '_NewList' as it is a normal C 
	subroutine.
		
	These minor bugs are easily fixed by fixing the #include files.
	Unfortunately the registerized library (LCR.LIB instead of LC.LIB)
	also makes this mistake and one doesn't have library source.  When
	such cases pop up you need to write your own NewList() (and other
	functions, but so far only NewList() has bit me from LCR.LIB, in
	the onbreak() call).  Since you have fully prototyped it it *will* 
	be registerized and LCR.LIB will use it.  I figure Lattice will
	fix this one real fast.

	Using registerized parameters removes a lot of overhead and reduces
	code size considerably.  No stack pushes or pops after the fact,
	and sometimes even the link #, unlk # statements are optimized out.

	Even without -rr Lattice now does defered popping of the stack.
	Manx 3.6a also has defered popping of the stack.

			REGISTER ASSIGNMENT, MANX COMPARISON, GLOBAL OPT.

	Manx still wins on short->long optimizations (only applies if you
	use 32 bit integers like I do).  Manx still does register allocation
	better but to take advantage of it you must specifically use the
	'register' keyword ala normal C.

	Lattice C will now place variables in registers by default.  You do
	not need to specify the 'register' keyword unless you really want to.
	Unfortunately, Lattice still doesn't take advantage of scope to 
	reuse registers.  The global optimizer fixes this to a degree but
	sometimes makes bad decisions.  Overall Lattice could improve on this
	quite a bit.

	Both Manx and Lattice still generate some stupid code.  With the 
	advent of the peephole optimizer (I believe this is in LC1 and
	transparent) and the global optimizer (GO, the program), Lattice
	now makes so many other optimizations that I as a programmer no 
	longer worry about writing my C code optimally.  GO is not a minor
	program, it does some pretty complex stuff.

	Comparing code generation without the global optimizer I would put
	Lattice ahead of Manx and with the global optimizer I would put Lattice
	wayyyy ahead of Manx.  Personally, both compilers still make grevious
	non-optimal mistakes but at least now Lattice has the transport layer
	into which it can insert fixes (the peephole optimizer and the global
	optimizer, which only lacks a proper register allocation scheme).

	I won't list the dozen+ things GO will optimize.  It does a good job
	for the most part and I expect it will be improved in future releases.
	It mainly optimizes for speed but I still see a code size improvment
	from it.

				ASSEMBLY OUTPUT, SORRY,
				BUT, NOT REALLY A PROBLEM. &
					LATTICE ASM

	No.  Lattice C does not output assembly.  LC1 outputs a quad file which
	LC2 digests.  Normally one just runs 'LC' which makes this two pass
	business transparent. 

	So far it hasn't been a problem.  I liked Manx C's ability to generate
	assembly but used it ONLY to checkout the quality of generated code and
	find compiler bugs.  ALSO NOTE THAT MANX NEVER PRODUCED PROPER
	ASSEMBLY.  It generated stuff that only its assembler could assemble
	and relied heavily on its assembler making certain optimizations.  It
	also relied on the assembler handling the data model.  Thus, no big
	loss.

	Lattice still has OMD and it appears to no longer barf on large object
	files.  This suffices just fine.

	Lattice now has an assembler.  ASM.  I found a few minor bugs like
	the fact that you could not have a comment after a macro which has
	no arguments.

			ENABLE		;this is a comment 

	Doesn't work (the bad english is for effect).  Remember, the assembly 
	language programmer doesn't need all the optimizations the Manx 
	Assembler did for you.  Nobody in their right mind uses MOVEM when
	they have only one register to move.

	Lattice ASM will optimize reverse branches only.  Forward branches
	default to word but you can use .S to force them to short.  This isn't
	really a problem.  Manx AS will optimize forward branches.

	Lattice ASM uses a superior method to reference A4 relative vs
	absolute location.  In fact, you can use ANY address register to
	access items relative.  You specify the addressing mode just as you
	would an address register relative addressing mode.  In Manx AS you
	would specify an absolute addressing mode and Manx AS would convert
	it depending on which model was being assembled for.  This made 
	mixing difficult and also is the cause of several bugs in Manx AS.

	You have to be a bit more on the ball and stick code and data in
	the proper SECTIONs... you need a SECTION directive before you can
	begin laying down code.  This isn't a problem either, I was just lazy
	before.

	Finally, note that Manx AS is still buggy with certain MOVEM and MOVE
	constructions (generates assembly errors when the code is perfectly
	valid).  Most such bugs are related to the small data model.

	Manx AS never implemented CNOP properly and the Manx linker does not
	place items in like-named sections together (i.e. SECTION is not
	fully implemented).

	By the way, Lattice ASM is strict on (A1,D1.x)... you need to say
	0(A1,D1.x) or Lattice ASM thinks it's a 68020 instruction and
	returns an error.

	Oh yah, one final note:  Lattice ASM and Lattice C V5.02 fully
	support code generation for 68010's 020's and 030's.  As John told me,
	"We use every 68020 instruction in the book".. well, almost
	every.  Obviously things like TAS and other atomic multiple cycle
	68020 instructions cannot be used on the Amiga.

	For example, LEA 0(A1,D7.L*4),A0 will be used on a 68020 instead of
	putting D7 into a temporary and then shifting it by 2 and *then*
	using LEA 0(A1,D7.L) .


				   PRAGMAS

	Lattice C V5.02 has the ability to call library functions directly
	without having to go through any kind of assembly tags.  This is
	a transparent feature.  You simply #include the appropriate proto/*.h
	file.  I normally just #include <proto/all.h> so I don't have to
	worry about it.

	If a library call is made inside a subroutine, A6 is automatically
	saved beforehand and restored on return.  Lattice tracks the contents
	of A6 and will not reload it unless necessary.  That means that if
	you make several system calls to a given library A6 is loaded only
	once with that library's base pointer.

				 THE MANUAL

	Comes in two IBM style binders and is much better organized than
	its predecessors and much much better than the Manx 3.4 manual
	(I got a set of pages to insert in it when I received my 3.6a
	update).  Well, it wasn't *that* bad but my comparison stands.

	The Lattice manual, like most manuals, has a neeto keen index that
	manages to list a billion topics EXCEPT the one I'm trying to look
	up.

	the Lattice manual is skimpy on the use of the __asm and associated 
	keywords but on the whole quite well done.

				COMPILER BUGS

	Manx C V3.6 has quite a few compiler bugs.  Lattice does too but at
	least they are all minor! (so far).  For example, Manx C has problems
	with constant expressions in if() statements and  ? : statements...
	it will generate bad assembly and even sometimes good assembly that
	does the wrong thing.  Manx C does not optimize out (remove) dead
	code.  Lattice does so via the global optimizer.
				
	Lattice C bugs are relatively minor.  The worst bug so far is that 
	LC2 gets confused sometimes and exits with CXERR 26 on perfectly 
	valid code... even simple C code sometimes!  I've had to munge the
	code a little to get it to compile.  This occured three times while I 
	was porting DME, SUP32.LIB, and DNET to Lattice C (that is, I fixed
	the programs to compile under both Manx and Lattice now).

	The -rrb option (generate both registerized (@) and nonregisterized (_)
	entry points) does not work.  It gets the labels mixed up (I caught
	that one *real* fast!).

	Precompiled include files don't appear to work 100%.  I couldn't pin
	it down, but apparently #pragmas would be lost from time to time, and
	maybe some prototypes too.

				   SPEED

	Unfortunately, Lattice C is still quite slow.  

	Manx C is still around 2x Lattice C under equivalent conditions
	(precompiled include file in ram and all executables rez'd or
	resident).  Poo.  Lattice C is almost 3x slower if you are forced
	not to use precompiled include files.

				FINAL OPINION

	I could find only two major faults with Lattice C (things that I
	think will not be fixed as quickly as the myrid minor problems I
	found):

	(1) precompiled include files don't work all the time (??)
	    I'll experiment more on this

	(2) Lattice C could be faster 

	Minor Faults:

	(1) CXERR 26 occurs on valid code somtimes.  minor hassle.

	(2) Lattice accidently screwed up the prototypes for AMIGA.LIB in
	    that they forgot to use the __stdargs keyword, causing undefined
	    symbols at blink time (when using the -rr option to LC).

	(3) -rrb doesn't work (so just don't use it for now, just think of
	    it as a preview to a future feature :-)).

	(4) LC+LC1+[GO]+LC2 take a bit more memory.  You really need a 1.5MB+
	    system to be able to make them all resident.  Manx has the
	    virtue of being relatively small.

	(5) Since functions are prototyped, you get many more warning 
	    messages about ptr->ptr conversion.  For ARGUMENTS to functions 
	    now.  I talked to John Toebes on this point and he already had
	    some good ideas on how to fix it.

	    Specifically, I want a function expecting a pointer to 
	    structure X as an argument to NOT display a warning message if
	    I pass a pointer to structure Y where structure Y is a superset
	    of structure X.

	*** Major Advantages ***

	(1) Registerized parameters (these are transparent)

	(2) Pragmas (these are transparent) makes overhead for system library
	    calls nearly nil.

	(3) Automatic placement of local variables into registers

	(4) Global Optimizer

	(5) *true* Support for 68010, 020, 030

	(6) Ability to specify that arguments are in specific registers (no 
	    need for assembly tags files if you are writing a library or 
	    device)

	(7) PROTOTYPES (very useful for all those 16 bit int programmers as
			well as making #(1) above possible)

	*** Minor Advantages ***

	(1) Builtin functions (inline code for common string calls)


	Overall I like Lattice C .  OK, I'll say it:  I like Lattice
	C better than I like Manx C.  There, I said it.  Sure there are
	problems, but I think Lattice is moving very quickly to fix them
	as well as thinking up lots of new features to add.

	Final note:  Note that Lattice C also comes with an object module
	librarian, object module disassembler, assembler, the latest BLink,
	grep, diff, and many other utilities including an editor (but I just
	use DME so I can't comment on their editor).  Manx C, at least the
	package I got, came with an equally prolific set of utilities.


						-Matt

giguere@aries5.uucp (Eric Giguere) (07/01/89)

Thanks for the review, Matt.  I think a lot of us have been curious
about the newest Lattice compiler.  I must admit that I, like many other
net readers, am seriously considering switching to Lattice.  After working
with ANSI compilers for so long it always pains me to have to return to K&R
style compilation on my Amiga.  

Which brings up the big question:  Does anyone have any SOLID information
on when the next release of Manx (5.0) is coming out?  I realize that 
there's only one person doing development on the compiler, but still... 
some of us can only wait so long.

Eric Giguere                                  268 Phillip St #CL-46
For the curious: it's French ("jee-gair")     Waterloo, Ontario  N2L 6G9
Bitnet  : GIGUERE at WATCSG                   (519) 746-6565
Internet: giguere@aries5.UWaterloo.ca         "Nothing but urges from HELL!!"

ddave@pnet02.cts.com (David Donley) (07/03/89)

Just some things you forgot:

Lattice takes about 3 times longer (at least) to compile than MANX, with the
global optimizer turned off.

It takes about 10 times with the global optimizer on, and the global optimizer
induces many bugs.

A program I compiled that was 160K under MANX turned out to be 155 under
lattice with the global optimizer on, but it took much much much longer to
compile, and no longer worked.

(Don't try calling the BBS below, it's down now)
 _               _
| \ _   ___ _   | \ _    | _    Call THE Bug Eyes BBS at (213) 372-4494.
|_//-\\/_|_|_)  |_/(_)/\/||_-\/ Life is too short for copy-protection-
^[33m^[41mANSI is my life!^[m/  and should be even shorter for pirates!
Send mail to: ddave@pnet02.CTS.COM or killer!gryphon!pnet02!ddave NO FLAMES!

walker@sas.UUCP (Doug Walker) (07/06/89)

In article <17314@gryphon.COM> ddave@pnet02.cts.com (David Donley) writes:
>It takes about 10 times with the global optimizer on, and the global optimizer
>induces many bugs.

Please take the time to download the latest patch release from the Lattice BBS.
It fixes most of the bugs you are complaining about.  The latest release is
5.03.22.

--Doug

new@udel.EDU (Darren New) (07/07/89)

In article <1094@sas.UUCP> walker@sas.UUCP (Doug Walker) writes:
>Please take the time to download the latest patch release from the Lattice BBS.
>It fixes most of the bugs you are complaining about.  The latest release is
>5.03.22.

Is there any way to get such patches mailed to me on a disk?
I would like them, but I don't have access to a modem line from this
machine (due to physical positioning of my machine/my telephones).
Thanks for any info...          -- Darren

sjm@well.UUCP (Stephen Moehle) (07/07/89)

In article <1094@sas.UUCP> walker@sas.UUCP (Doug Walker) writes:
>Please take the time to download the latest patch release from the Lattice
>BBS.
>It fixes most of the bugs you are complaining about.  The latest release is
>5.03.22.
>
>--Doug

I just called the Lattice BBS.  The latest patch is 5.02, and the sysops say
not to expect another patch for at least a month.  I am not holding my
breath.

Stephe
{ucbvax,pacbell,hplabs}!well!sjm     or     sjm@well.sf.ca.usa
"You heard the weirdo man.  What is truth?"

bryan@geo-works.UUCP (Bryan Ford) (07/12/89)

In article <8906300558.AA12963@postgres.Berkeley.EDU>, Matt Dillon writes:
>	__asm		-These allow you to specify that subroutines takes
>	__d0 to __d7,	 parameters in specific registers instead of on the 
>			 stack
>	__a0 to __a6
>
>			__asm blah (register __d0 int a, register __a0 int *b);
>
>			currently you may only declare that data registers pass
>			non pointers and address registers pass pointers.

Interesting fact:  I tried violating this rule both directions (data
register into pointer and address register into non-pointer), and the
compiler didn't give me any errors at all.  Data registers into pointers
worked perfectly, but if you try putting an address register into a
non-pointer, it gets it out of the corresponding data register (i.e., d1 if
you specified a1).

>	The -rrb option (generate both registerized (@) and nonregisterized (_)
>	entry points) does not work.  It gets the labels mixed up (I caught
>	that one *real* fast!).

Clarification:  It swaps the @ and _ labels when it defines functions which
can be called externally.  However, a function which calls another function
above it (Pascal style) in the same module doesn't use the labels and so
works perfectly.  When I first tried using this feature I used it on a
single-module program and it worked perfectly, but when I tried using it
on a multi-module program it crashed, which is to be expected.

Also, note that using this will increase code size slightly because of the
extra instructions to pull stack-based variables off the stack, but won't
affect speed at all.

>	Precompiled include files don't appear to work 100%.  I couldn't pin
>	it down, but apparently #pragmas would be lost from time to time, and
>	maybe some prototypes too.

I found a really interesting problem (but haven't been able to find out the
cause).  When I tried using the DateStamp structure in one of my programs
in a way in which it was necessary to have the structure actually defined
(not just pointer manipulation), it said that the structure was not defined
(although it was, in the precompiled symbol table).  I tried to kludge it
by copying the definition of the DateStamp structure out of libraries/dos.h
into my code.  It didn't tell me that the structure wasn't defined, but it
*did* tell me that the three elements (ds_Days, ds_Minute, ds_Tick) were
already defined within the structure.  So I just took the ds_ thingies off
the names just to create unique names and it worked fine.  (Although I
don't think I ever accessed the elements directly, I just defined an
instance of the structure in my program, and that's what set the whole
thing off.)

>	(5) Since functions are prototyped, you get many more warning 
>	    messages about ptr->ptr conversion.  For ARGUMENTS to functions 
>	    now.  I talked to John Toebes on this point and he already had
>	    some good ideas on how to fix it.

I'm pretty sure there are separate warning numbers (but with the same
messages attached) for argument and assignment pointer conversions, so
you should be able to disable one without affecting the other.  (#30 is for
assignments and #88 is for arguments.)

>	Final note:  Note that Lattice C also comes with an object module
>	librarian, object module disassembler, assembler, the latest BLink,
>	grep, diff, and many other utilities including an editor (but I just
>	use DME so I can't comment on their editor).  Manx C, at least the
>	package I got, came with an equally prolific set of utilities.

Their editor is pretty good, --> for an editor that comes as part of a
package <--.  It's definitely easier for beginners than DME, but a lot less
powerful and a lot bigger (because of all the menus and messages and
things).  It *does* create an integrated environment, though (resident the
compiler and stuff and compile in memory).  Of course you can do this with
ARexx anyway. :-)

				Bryan

--

     ____________________________________________
   _/ Bryan Ford - bryan@geo-works.geo-works.com \_
 _/    ..!utah-cs!caeco!i-core!geo-works!bryan     \_
/   ..!uunet!iconsys!caeco!i-core!geo-works!bryan    \

walker@sas.UUCP (Doug Walker) (07/13/89)

In article <12599@well.UUCP> sjm@well.UUCP (Stephen Moehle) writes:
>I just called the Lattice BBS.  The latest patch is 5.02, and the sysops say
>not to expect another patch for at least a month.  I am not holding my
>breath.

As I posted previously, the 5.03 patch versions are for Lattice beta testers
only.  Being new to the game, I did not realize they were not available to
the general public. 

IF YOU ARE UNABLE to work around a bug, call or write Lattice tech support
and ask for a patch that fixes your problem.

The reason the interim versions are not distributed is to avoid a
proliferation of versions of the compiler.  I am sorry for any confusion
my original posting caused, although it is a puzzle to me how so many
people read the original and apparently nobody read the followup posted
less than 24 hours later...

--Doug

mwm@eris.berkeley.edu (Mike (I'll think of something yet) Meyer) (07/14/89)

In article <1104@sas.UUCP> walker@sas.UUCP (Doug Walker) writes:
<In article <12599@well.UUCP> sjm@well.UUCP (Stephen Moehle) writes:
<>I just called the Lattice BBS.  The latest patch is 5.02, and the sysops say
<>not to expect another patch for at least a month.  I am not holding my
<>breath.
<
<As I posted previously, the 5.03 patch versions are for Lattice beta testers
<only.  Being new to the game, I did not realize they were not available to
<the general public. 

Interesting, I never saw that article.

<I am sorry for any confusion
<my original posting caused, although it is a puzzle to me how so many
<people read the original and apparently nobody read the followup posted
<less than 24 hours later...

I'd suspect that it got eaten by a news system very close to your site.
Nobody read it because it never got to them.

	<mike

--
The weather is here, I wish you were beautiful.		Mike Meyer
My thoughts aren't too clear, but don't run away.	mwm@berkeley.edu
My girlfriend's a bore, my job is too dutiful.		ucbvax!mwm
Hell nobody's perfect, would you like to play?		mwm@ucbjade.BITNET