|
|
1.1 root 1: There was a bug which caused compiler errors when floating values were
2: assigned to bit fields. Some overenthusiastic optimization on my part
3: led to a float-to-int conversion on the rhs of the assignment being
4: dropped. Bit fields are now treated as a special case. [pcc.vax:
5: local2.c]
6:
7: At the instigation of Rob Pike, enums were neutered: they now behave
8: exactly like ints. The only traces of Johnson's treatment of enums are
9: warnings about clashes between one enum type and another enum type in
10: certain expressions. This fix was trickier than it looked; it would
11: have been much simpler to drop ALL warnings about enums, as Rob would
12: recommend. [mip: trees.c]
13:
14: Arthur Olsen pointed out a bug with the evaluation of constant
15: expressions -- the usual arithmetic conversions are not always
16: performed. Rather than follow Arthur's simple suggestion, I decided to
17: be safe and arranged to use the same conversion code on constants that
18: we use on variables. We short-cut the test if the operand(s) are ints,
19: which is the usual case, so the impact on compile time should be
20: small. [mip: trees.c]
21:
22: Guy Harris noted that chkpun() considered multiply dimensioned arrays
23: and multiply indirect pointers to be the same thing, which they are
24: most certainly not. His fix causes an 'illegal pointer combination'
25: warning to be emitted for code like:
26:
27: char **cpp, c2a[10][20]; cpp = c2a; cpp[5][3] = 'a';
28:
29: The new code is actually simpler than the old... [mip: trees.c]
30:
31: Another irritation of Rob Pike's is fixed -- the old-style assignment
32: ops have been ifdef'ed out. No more of those obnoxious 'ambiguous
33: assignment: assignment op taken' messages! [mip: scan.c]
34:
35: Yet another Rob Pike complaint: you couldn't refer directly to the
36: members of a structure which had been returned by a function. You may
37: now utter things like 'f().a' and get away with them. The illegal form
38: '(&f())->a' used to work; since this has the same tree representation
39: as the legal form, an ugly wart was added to the action for '&' which
40: specifically rules this form out. To be consistent, a similar
41: exception was made for expressions of the form '(a = b).c'. [mip:
42: cgram.y]
43:
44: Moved configuration flags from Makefile into macdefs.h and converted
45: some more trivial routines into macros. This cleans up the Makefile
46: considerably and consolidates assembler-dependent flags. [pcc.vax:
47: macdefs.h, code.c, order.c, Makefile; mip: onepass.h]
48:
49: More efficiency hacks: the compiler now does its best to avoid emitting
50: ANY code after an error is detected. Previously only code generation
51: through the code table was suppressed after an error. This change can
52: buy up to 25% in speed improvements if the dbx stab flag is enabled.
53: The latest 'ccom' runs twice as fast as the 4.2 BSD compiler in this
54: situation... [pcc.vax: macdefs.h, local.c, code.c; mip: cgram.y,
55: scan.c, pftn.c]
56:
57: For ANSI compatibility, we now accept void expressions in the colon
58: part of a conditional expression. Both subexpressions under the colon
59: operator must be void if one is void. The overall type of the
60: conditional expression is void in this case. [mip: trees.c]
61:
62: As long as we're doing away with old-fashioned assignment operators, we
63: might as well terminate old-fashioned initializations too. [mip: cgram.y]
64:
65: A fix from James Schoner for bitfield assignments was installed. The
66: problem was that the rhs of a bitfield assignment was used as its
67: value, an overlooked aspect of the several earlier bug fixes for
68: problems of this variety. The bug caused
69:
70: struct { unsigned a:4, b:3, c:2; } x;
71: int i;
72: i = x.b = 255;
73:
74: to store 255 in i instead of 7. [pcc.vax: table.c, local2.c]
75:
76: Scanner code was added to handle the System V/ANSI preprocessor
77: extensions #ident and #pragma. Currently #ident is ignored. #pragma
78: may be used as a substitute for lint-style comment directives; e.g. use
79: '#pragma LINTLIBRARY' for '/* LINTLIBRARY */'. The #pragma stuff
80: requires the hacked-up cpp with ANSI extensions which may eventually be
81: put into circulation here at Utah. The #line control from cpp is now
82: recognized with the same syntax by ccom. Unknown control lines elicit
83: a warning. A small bug is fixed by this new code -- previously #ident
84: and other unknown controls caused the line control mechanism to get
85: screwed up, so that bogus dbx stabs were put in the output. [mip:
86: scan.c]
87:
88: There seems to be a loophole in initializations -- apparently it is
89: legal to initialize a bitfield with a symbolic constant (i.e. the
90: address of something). No loader that I know of will handle this! The
91: compiler now emits an error when someone tries this trick; it really
92: can't do any better. [mip: pftn.c]
93:
94: Someone complained that all illegal characters were being printed as
95: octal numbers in the error message. This was changed so that printable
96: characters are printed normally, and all funny characters are printed
97: in C 'char' style. [mip: scan.c]
98:
99: Conversion of unsigned constants to floating point values was broken
100: because the requisite cast in makety() had been commented out! Argh.
101: Unsigned comparisons of constants were similarly botched. [mip: trees.c]
102:
103: Ray Butterworth made a sensible suggestion that array definitions which
104: aren't external and allocate no storage should elicit errors. I
105: modified his suggestion slightly by moving the test into nidcl(), where
106: we can be sure that an array isn't being initialized. I also adopted
107: his suggestion for a lint warning for arrays with explicit dimensions
108: that are lost by the rule that converts array types into pointer types
109: in formal arguments; the warning is contingent on lint's -h flag.
110: [mip: pftn.c]
111:
112: The structures for fpn and dpn nodes (floating point constants) were
113: changed to make them conform in shape to the other nodes. [mip: ndu.h]
114:
115: Overenthusiastic SCONV optimization code in optim2() led to functions
116: not cooperating with certain casts; e.g.
117:
118: unsigned char x(); ... y((char)x()) ...
119:
120: failed to sign-extend the result of x(). [pcc.vax: local2.c]
121:
122: A bug in outstruct() caused it to check 'stab[-1].name == NULL' for
123: unnamed structures. For some reason this didn't break until my recent
124: lint fixes tweaked the compiler in some subtle way... [pcc.vax: stab.c]
125:
126: The makefile was changed to pass C options to lint properly and to drop
127: the '-a' flag to lint in the 'lintall' entry. '-a' really ought to
128: work but unfortunately the arrangement of 'int'-like types in the
129: compiler is extremely confusing and inconsistent, so I eventually gave
130: up trying to force the issue. Sam Leffler's 'rel.c' for release
131: information was also added. [pcc.vax: Makefile, rel.c]
132:
133: I fixed defid() so that it now insists that all argument type
134: declarations must refer to names in the argument list. Previously you
135: could get away with:
136:
137: int a;
138: x()
139: int a;
140: { ... }
141:
142: Use of 'a' in the body of x() would elicit the immortal error message
143: 'warning: bad arg temp'. [mip: pftn.c]
144:
145: For some reason, mainp2() in the two-pass version of the compiler had a
146: switch statement with two 'default' cases. I zapped the obvious one.
147: [mip: reader.c]
148:
149: Botched initializations sometimes left the declarations code in a funny
150: state, so a fixinit() routine was invented to aid error recovery. For
151: example, the following illegal program forced a core dump:
152:
153: char m[] = ;
154: x() {
155: y("splat");
156: }
157:
158: The compiler tried to read "splat" into m[] and died horribly. [mip:
159: cgram.y, pftn.c]
160:
161: The compiler now warns 'can't take size of function' when asked to do
162: something amazing like '... void f(); ... if (f[10]) ...'. Previously
163: it produced a compiler error instead. [mip: pftn.c]
164:
165: If a program tried to access a value below the argument list on the
166: stack using the clever tactic of manipulating the address of an
167: argument, it drew a warning 'bad arg temp'. For the sake of these
168: clever programs, the warning has been suppressed. [pcc.vax: local2.c]
169:
170: The assembler would sometimes print 'Branch too long: try -J flag' even
171: when you used the -J flag and when there was no reason for it to be
172: making long branches. This was due to a bug in jxxxfix() which caused
173: tests for explodable branch instructions to terminate early in later
174: phases of the topological sort, because the loop termination code
175: didn't take into account the fact that not all code addresses are
176: updated by jxxxbump(). The fix is to match the pointer to the data
177: structure for the code in the sorted table rather than check for its
178: generated address. [as: asjxxx.c]
179:
180: The peephole optimizer normally compares instructions for equality
181: based on their instruction type and their operands. Unfortunately
182: several instructions are too complex for c2 to handle and are given an
183: instruction type of 0; thus all such instructions compared equal. The
184: equop() routine was changed to test the names of these '0' type
185: instructions for equality. [c2: c21.c]
186:
187: The compiler sometimes botched computations into stack temporaries by
188: treating expressions like '-40(fp)[r1]' as permissible temporaries. I
189: rewrote the shtemp() routine to make it explicit that the 'stack
190: temporary' goal in code generation means precisely that the final
191: expression must not contain any references to temporary registers (like
192: r1). I had to add a couple templates to the code table to push
193: exceedingly complex OREG expressions onto the stack when this goal is
194: attempted. [pcc.vax: local2.c, table.c]
195:
196: A bug sometimes caused a redeclaration of an array in an inner scope to
197: affect the outer array when the outer array was incompletely specified
198: (by leaving out the most significant dimension). For example:
199:
200: extern int a[];
201: x(){ int a[10]; }
202: int a[20];
203:
204: This code would elicit the error 'foo.c, line 3: redeclaration of a'.
205: The routine defid() is used to enter new definitions; for some reason
206: scope problems are not resolved in defid() until much other code has
207: been executed, including code that deals with filling out array sizes.
208: The change makes defid() notice inner scopes with auto and register
209: declarations earlier than usual. [mip: pftn.c]
210:
211: Case expressions are explicitly restricted to contain only int constants,
212: char constants and sizeof expressions (C Reference Manual section 15).
213: Previously the compiler didn't test for expressions like '(int) &foo[10]'
214: and thus it would generate some rather bogus code. Expressions which
215: resolve to names now elicit the same 'non-constant case expression'
216: warning which you receive for variables. [mip: cgram.y]
217:
218: The value of an assignment to an unsigned bitfield was signed through
219: an oversight in the code table. [pcc.vax: table.c]
220:
221: From Sam Kendall, a fix to prevent structs, unions, floats, doubles
222: and void from being cast to pointer types. [mip: trees.c]
223:
224: Some relict code in moditype() was causing void functions not to be
225: converted into pointers in some situations. [mip: trees.c]
226:
227: A minor optimization -- when the lhs of a simple assignment op (&=, |=,
228: ^=, +-, -=) is smaller than int size, we can sometimes pun the rhs and
229: avoid promoting the lhs to int, performing the operation in int width
230: and converting from int back to the lhs type. For example:
231:
232: register char *ap, *bp;
233: *ap++ |= *bp << 1;
234:
235: This used to require 7 instructions, but now needs only 3. [pcc.vax:
236: table.c]
237:
238: At some point I added code to conval() to balance types before
239: performing constant folding... While hacking on the tahoe compiler, I
240: decided that this code was too complex and replaced it with equivalent
241: code that's shorter and easier to understand. [mip: trees.c]
242:
243: Lines containing multiple statements were broken up for the sake of
244: tracing with the source debugger in tcheck() and talloc(). [mip:
245: common.c]
246:
247: I discovered that the C compiler called urem() in three different
248: places with a constant divisor... In my subsequent rampage I hacked
249: the compiler to generate inline code for all unsigned division and
250: modulus operations with constant divisors. The largest inline
251: expansion should use only 5 instructions, with most using just 3 or 4.
252: The changes touched several files but really weren't very messy.
253: [mip: pass1.h, match.c; pcc.vax: local2.c, order.c, table.c]
254:
255: A lot of new code was added to handle a really simple problem:
256:
257: unsigned char uc = 255;
258: if (uc == -1) ...
259:
260: This incorrectly tested true, because the compiler generated a test
261: that looked only at the low order byte of the constant. Not only that,
262: but the compiler didn't realize that this test could be short-
263: circuited, since -1 is equal to 4294967295 unsigned and is hence out of
264: the range of an unsigned char. Rather than add lots of cruft to the
265: code table, I shoved it into optim2() -- the compiler now picks up all
266: the absurd cases where a constant is out of the range of precision of
267: a variable it's tested against. To avoid having to write lots of code
268: templates to handle unbalanced unsigned/signed expressions, I forced
269: tymatch() to take notice of unbalanced expressions and promote the
270: signed operand to unsigned (except with assignment operators, sigh).
271: This change in turned required tweaks in autoincr() and in the code
272: table to get code quality back. I hope I can come up with a better way
273: to do this... [mip: trees.c; pcc.vax: local2.c, order.c, table.c]
274:
275: The value of TNULL was changed from 'pointer to undef' to 'pointer to
276: member of enum' so that 'void *' can be a real type. TNULL is used to
277: tag unused symbol table slots. [mip: manifest.h]
278:
279: A bug in clearst() led to problems with 'schain botch' errors. When a
280: hash collision occurs, a symbol is (linearly) rehashed; if the symbol
281: which forced the rehash is deleted, the relook() loop in clearst() will
282: cause another symbol with the same hash code to move up and replace the
283: deleted symbol. Torek's 'schain' hack for speedy identification of
284: symbols at the same block level will get screwed up by this operation
285: since it relies on a linked list of table entries -- moving an entry
286: garbles the list. How did this code ever work before? [mip: pftn.c]
287:
288: Changed putins() in ascode.c in the assembler to permit 0(pc) as a
289: write operand... Previously the assembler automatically optimized
290: this to (pc), which is an illegal operand. [as.vax: ascode.c]
291:
292: The complement of an unsigned char or unsigned short value should have
293: its high bits set, since the 'usual arithmetic conversions' widen these
294: small integers 'before' the operation. [pcc.vax: table.c]
295:
296: A minor code improvement in ccom led to problems in c2 -- c2 was able
297: to optimize sequences like 'cvtbl -4(fp),r0; bicl2 $-256,r0' but not
298: the (shorter and faster) 'cvtbl -4(fp),r0; movzbl r0,r0'. A change in
299: bflow() causes redundant conversions to be noted and removed, restoring
300: code quality. [c2: c21.c]
301:
302: A typo in the 'bitsize' array definition resulted in an unterminated
303: comment which screwed up the bit sizes for several types. I only
304: noticed this because I ran the source off with vgrind and the error
305: was exposed by comment highlighting... [c2: c21.c]
306:
307: An earlier change to conval() caused LONG and ULONG types to be hacked
308: into INT and UNSIGNED; this was fine for the (VAX) compiler, but led
309: to inconsistencies with lint. [mip: trees.c]
310:
311: When a syntax error occurs, the parser throws away tokens until it can
312: enter a known state. If a string or character constant delimiter is
313: tossed, the parser will try to interpret the contents of the constant
314: as code and can get very confused. A hack was added to yylex() to
315: detect this situation -- basically, if a delimiter is seen but the
316: string or character constant has not been processed by lxstr() at the
317: next call to yylex(), yylex() will call lxstr() itself and dispose of
318: the rest of the constant. [mip: scan.c]
319:
320: Following a suggestion by Arthur Olsen, the production for 'switch' was
321: modified to complain about constant switch expressions with 'lint -h'.
322: [mip: cgram.y]
323:
324: Another Arthur Olsen bug report pointed out a problem with increment
325: operations that don't match a code template... Two attempts at
326: rewriting the increment are made: the first tries to turn the lvalue
327: operand into an OREG, and the second applies a tree transformation to
328: convert 'x++' into '(x += sizeof x) - sizeof x'. A mistake in the
329: routine setincr() caused the lvalue operand in its entirety to be
330: generated into a register instead of just the lvalue operand's address,
331: producing something like 'r0 = x, (r0 += sizeof x) - sizeof x' instead
332: of 'r0 = &x, (*r0 += sizeof x) - sizeof x'. [pcc.vax: order.c]
333:
334: Better code for floating post-increment and -decrement can be generated
335: with a simple change to the code table and to zzzcode() so that the
336: same hack for ordinary post-increment will work for floating point too.
337: [pcc.vax: local2.c, table.c]
338:
339: I added Arthur Olsen's massive lint fixes for typechecking printf().
340: It sure would be nice if there were a way to specify new printf-like
341: commands at execute time, perhaps through lint directives embedded in
342: include files. [lint: lint.c]
343:
344: Arthur's warning about superfluous backslashes was added to lxstr().
345: Rather than adding Arthur's (expensive) code for warning about the
346: use of '$', I simply made it illegal (unless 'VMS' is defined). I
347: also took the opportunity to remove '`' gcos BCD constants. I made
348: a slight alteration to yylex() to cause it to eat unknown characters
349: rather than punt, since this seemed more useful. [mip: scan.c]
350:
351: Lint would sometimes print a bogus 'i set but not used' warning in
352: situations like this:
353:
354: static int i;
355: static int *ip = &i;
356:
357: i = 1;
358: return *ip;
359:
360: If you moved the initialization out of the declaration, the warning
361: disappeared. I installed Arthur's hack for forcing lint to examine
362: initializations. This causes lint to treat initializations of auto,
363: register and static variables as 'uses' and to ignore sizeof
364: expressions as 'uses'. Also, '&i' in a static or external
365: initialization is now a 'set' and a 'use' of 'i'. [lint: lint.c; mip:
366: cgram.y, pftn.c]
367:
368: VARARGS0 is now correctly treated differently from plain VARARGS.
369: I don't remember who originally noticed this... [lint: lint.c,
370: lpass2.c]
371:
372: The register allocation code failed to 'share' register pairs. I don't
373: know why this escaped notice for this long... I added a bit in the
374: 'busy' array to keep track of pairs and modified the code in usable()
375: to notice pairs and try to 'share' them. Some other code which treated
376: the values of busy[] elements as arithmetic values had to be changed;
377: there is now a macro which performs the proper test. [mip: allo.c,
378: match.c, pass2.h]
379:
380: Some extensive code tweaking... (1) If order() is called on to rewrite
381: a UNARY MUL node and that node has a usable index expression, we now
382: try to rewrite the base into a register so that oreg2() will produce a
383: doubly-indexed OREG. This is usually an impressive space saving. (2)
384: Instead of laboriously copying a constant 0.0 in data space to clear a
385: double or a float, we issue the proper 'clrd' or 'clrf'. This is done
386: by a trick using an alternate prtdcon() routine; I'm not sure who
387: invented it. I guess I'm still not prepared to hack in support for
388: floating literals and immediate constants. (3) The conversion code now
389: handles stack pushes directly, which often saves a spill to register.
390: With very little adjustment, this also buys us optimally small pushes
391: of constants. (4) Pointer comparisons are now unsigned; I'm not sure
392: what this really buys us, but I added it anyway. (5) AND tests against
393: constants are 'small' if both the constant and the other operand are
394: also 'small'. (6) base() now recognizes that NAME nodes can be used in
395: pc relative deferred indexed addressing, which is much more compact
396: than the equivalent code to compute the address into a register and
397: indirect through it. (7) The optimization code for ANDing with a
398: constant now tries to produce a positive mask when small types are used
399: so that literal operands are possible; a side effect is that the code
400: is more readable. (8) UCHAR/USHORT to FLOAT/DOUBLE conversions take an
401: extra step through INT type to avoid the overhead of an UNSIGNED to
402: FLOAT/DOUBLE conversion. (9) If a logical operator sits above a pair
403: of FLOAT to DOUBLE conversions, the conversions are deleted. (10) Vast
404: numbers of redundant or useless templates were deleted from the code
405: table. (11) Conversions to FLOAT in double-only arithmetic now go to
406: the trouble of clipping off excess precision from INT and DOUBLE
407: operands. (12) DOUBLE to DOUBLE conversions introduced by reclaim()
408: are now silently deleted in the table. (13) A few 'movd's were turned
409: into 'movq's -- more work needs to be done to make this consistent.
410: [mip: reader.c; pcc.vax: macdefs.h, local.c, local2.c, table.c]
411:
412: A bug which caused assignment op expressions with an unsigned char or
413: unsigned short lhs and a floating rhs to treat the lhs as signed was
414: fixed. Some conversion-related stuff which used to be done in the
415: table is now done in sconv() so that it's easier to handle and so that
416: zzzcode() and its descendants can more safely perform conversions by
417: calling zzzcode(p, 'A'). [pcc.vax: local2.c, table.c]
418:
419: The code for setting the type of a floating point constant was bogus.
420: A floating constant was float if it fit in a float without loss of
421: precision, otherwise it was double. This caused silliness like
422: unexpectedly losing low order bits of integers in mixed floating and
423: integral expressions. The fix was to adopt the ANSI proposal that all
424: floating constants are type double unless they bear an 'f' or 'F'
425: suffix, in which case they are type float. (Note that a cast to float
426: has the same effect as a 'f' suffix and is just as efficient, but I
427: conceded to the evident popularity of the 'f' suffix...) [mip: scan.c;
428: pcc.vax: local.c]
429:
430: The ASG OPSIMP templates that produce byte and word instructions for
431: byte and word destinations weren't being activated very often because
432: the constant operands weren't normalized. I added code to optim2() to
433: appropriately reduce the range of constant operands of ASG OPSIMP
434: operators and sign-extend. This blows away many useless conversions to
435: and from int. [pcc.vax: local2.c]
436:
437: The template for assignment ops with unsigned char/short lhs and
438: floating rhs indicated register sharing for the wrong operand...
439: [pcc.vax: table.c]
440:
441: The new template that handled OREG for INTEMP failed to take into
442: account the size variation in OREG objects. [pcc.vax: table.c]
443:
444: The offstar() routine tries to tweak UNARY MUL trees so that they can
445: be handled most effectively by VAX addressing modes. The code for
446: identifying index expressions was adjusted so that more indexed
447: addressing modes can be produced. [pcc.vax: order.c]
448:
449: Bogus error messages were being emitted for certain initializations
450: following an earlier legitimate error. It turns out that the
451: optimization to prevent initialization code from being emitted after
452: errors was preventing the initializer offset counter from being
453: updated, and when this occurs, the initialization code screws up -- for
454: example, string constants appear to be zero length. The initialization
455: code now always updates the offset even if errors have been detected,
456: although code generation is still suppressed. [pcc.vax: local.c]
457:
458: An assignment to a bitfield in an indexed int-width structure led to
459: code generation failure due to an indexed OREG child of FLD. This is
460: taboo because the VAX field instructions have byte-size side effects,
461: and code in clocal() arranged for indexed structs to have int width.
462: I changed clocal() to use byte width instead and it appears to work now
463: (and even uses indexed byte addressing correctly). [pcc.vax: local.c]
464:
465: For some reason the unsigned-to-floating conversion code has always
466: been long and complex when it could be short and simple. I used the
467: simple code in the Tahoe compiler but didn't think to put it in the VAX
468: compiler until prodded by Robert Firth... [pcc.vax: local2.c]
469:
470: John Gilmore noticed that the ! operator didn't work with floating
471: constants; this was pretty easy to fix. [mip: trees.c]
472:
473: For some reason, opact() put left and right shifts through tymatch().
474: The type balancing of tymatch() is wrong for shifts -- the type of the
475: shift depends only on the left operand, while the right operand is
476: converted to int. We now use the shift special case in buildtree() to
477: fix the type. [mip: trees.c]
478:
479: Following ANSI (for once) we eliminate warnings for pointer conversions
480: involving void *. [mip: trees.c]
481:
482: There were at least a couple bugs in c2 with code that converts 'ashl
483: $2,rA,rB; movab _x[rB],rC' into 'moval _x[rB],rC'; one caused the type
484: to be wrong ('movab' for 'moval'), one caused neighboring instructions
485: to get deleted. [c2.vax: c21.c]
486:
487: A branch to a redundant test sometimes resulted in c2's deleting the
488: label too, even if the label itself was not redundant. [c2.vax: c21.c]
489:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.