|
|
1.1 root 1: /* Top level of GNU C compiler
2: Copyright (C) 1987, 1988 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is distributed in the hope that it will be useful,
7: but WITHOUT ANY WARRANTY. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing. Refer to the GNU CC General Public
11: License for full details.
12:
13: Everyone is granted permission to copy, modify and redistribute
14: GNU CC, but only under the conditions described in the
15: GNU CC General Public License. A copy of this license is
16: supposed to have been given to you along with GNU CC so you
17: can know your rights and responsibilities. It should be in a
18: file named COPYING. Among other things, the copyright notice
19: and this notice must be preserved on all copies. */
20:
21:
22: /* This is the top level of cc1.
23: It parses command args, opens files, invokes the various passes
24: in the proper order, and counts the time used by each.
25: Error messages and low-level interface to malloc also handled here. */
26:
27: #include "config.h"
28: #include <stdio.h>
29: #include <signal.h>
30:
31: #ifdef USG
32: #include <sys/param.h>
33: #include <sys/times.h>
34: #include <time.h> /* Correct for hpux at least. Is it good on other USG? */
35: #else
36: #ifndef VMS
37: #include <sys/time.h>
38: #include <sys/resource.h>
39: #endif
40: #endif
41:
42: #ifndef _TYPES_
43: #include <sys/types.h>
44: #endif
45: #include <sys/stat.h>
46:
47: #include "tree.h"
48: #include "c-tree.h"
49: #include "rtl.h"
50: #include "flags.h"
51:
52: extern int yydebug;
53:
54: extern FILE *finput;
55:
56: extern void init_lex ();
57: extern void init_decl_processing ();
58: extern void init_tree ();
59: extern void init_rtl ();
60: extern void init_optabs ();
61: extern void init_reg_sets ();
62: extern void dump_flow_info ();
63: extern void dump_local_alloc ();
64:
65: void rest_of_decl_compilation ();
66: void error ();
67: void error_with_file_and_line ();
68: void set_target_switch ();
69:
70: /* Bit flags that specify the machine subtype we are compiling for.
71: Bits are tested using macros TARGET_... defined in the tm-...h file
72: and set by `-m...' switches. */
73:
74: int target_flags;
75:
76: /* Name of current original source file (what was input to cpp).
77: This comes from each #-command in the actual input. */
78:
79: char *input_filename;
80:
81: /* Name of top-level original source file (what was input to cpp).
82: This comes from the first #-command in the actual input. */
83:
84: char *main_input_filename;
85:
86: /* Current line number in real source file. */
87:
88: extern int lineno;
89:
90: /* FUNCTION_DECL for function now being parsed or compiled. */
91:
92: extern tree current_function_decl;
93:
94: /* Name to use as base of names for dump output files. */
95:
96: char *dump_base_name;
97:
98: /* Flags saying which kinds of debugging dump have been requested. */
99:
100: int rtl_dump = 0;
101: int rtl_dump_and_exit = 0;
102: int jump_opt_dump = 0;
103: int cse_dump = 0;
104: int loop_dump = 0;
105: int flow_dump = 0;
106: int combine_dump = 0;
107: int local_reg_dump = 0;
108: int global_reg_dump = 0;
109: int jump2_opt_dump = 0;
110:
111: /* 1 => write gdb debugging output (using symout.c). -g
112: 2 => write dbx debugging output (using dbxout.c). -G */
113:
114: int write_symbols = 0;
115:
116: /* Nonzero means do optimizations. -opt. */
117:
118: int optimize = 0;
119:
120: /* Nonzero for -fforce-mem: load memory value into a register
121: before arithmetic on it. This makes better cse but slower compilation. */
122:
123: int flag_force_mem = 0;
124:
125: /* Nonzero for -fforce-addr: load memory address into a register before
126: reference to memory. This makes better cse but slower compilation. */
127:
128: int flag_force_addr = 0;
129:
130: /* Nonzero for -fdefer-pop: don't pop args after each function call;
131: instead save them up to pop many calls' args with one insns. */
132:
133: int flag_defer_pop = 1;
134:
135: /* Nonzero for -ffloat-store: don't allocate floats and doubles
136: in extended-precision registers. */
137:
138: int flag_float_store = 0;
139:
140: /* Nonzero for -fcombine-regs:
141: allow instruction combiner to combine an insn
142: that just copies one reg to another. */
143:
144: int flag_combine_regs = 0;
145:
146: /* Nonzero for -fwritable-strings:
147: store string constants in data segment and don't uniquize them. */
148:
149: int flag_writable_strings = 0;
150:
151: /* Nonzero means don't put addresses of constant functions in registers.
152: Used for compiling the Unix kernel, where strange substitutions are
153: done on the assembly output. */
154:
155: int flag_no_function_cse = 0;
156:
157: /* Nonzero for -fomit-frame-pointer:
158: don't make a frame pointer in simple functions that don't require one. */
159:
160: int flag_omit_frame_pointer = 0;
161:
162: /* Nonzero to inhibit use of define_optimization peephole opts. */
163:
164: int flag_no_peephole = 0;
165:
166: /* Nonzero means `char' should be signed. */
167:
168: int flag_signed_char;
169:
170: /* Nonzero means allow type mismatches in conditional expressions;
171: just make their values `void'. */
172:
173: int flag_cond_mismatch;
174:
175: /* Nonzero means don't recognize the keyword `asm'. */
176:
177: int flag_no_asm;
178:
179: /* Nonzero means warn about implicit declarations. */
180:
181: int warn_implicit;
182:
183: /* Nonzero means warn about function definitions that default the return type
184: or that use a null return and have a return-type other than void. */
185:
186: int warn_return_type;
187:
188: /* Nonzero means do some things the same way PCC does. */
189:
190: int flag_traditional;
191:
192: /* Nonzero means all references through pointers are volatile. */
193:
194: int flag_volatile;
195:
196: /* Nonzero means do stupid register allocation. -noreg.
197: This and `optimize' are controlled by different switches in cc1,
198: but normally cc controls them both with the -O switch. */
199:
200: int obey_regdecls = 0;
201:
202: /* Don't print functions as they are compiled and don't print
203: times taken by the various passes. -quiet. */
204:
205: int quiet_flag = 0;
206:
207: /* Don't print warning messages. -w. */
208:
209: int inhibit_warnings = 0;
210:
211: /* Do print extra warnings (such as for uninitialized variables). -W. */
212:
213: int extra_warnings = 0;
214:
215: /* Number of error messages and warning messages so far. */
216:
217: int errorcount = 0;
218: int warningcount = 0;
219:
220: /* Nonzero if generating code to do profiling. */
221:
222: int profile_flag = 0;
223:
224: /* Nonzero for -pedantic switch: warn about anything
225: that standard C forbids. */
226:
227: int pedantic = 0;
228:
229: /* Nonzero for -finline-functions: ok to inline functions that look like
230: good inline candidates. */
231:
232: int flag_inline_functions;
233:
234: /* Nonzero for -fkeep-inline-functions: even if we make a function
235: go inline everywhere, keep its defintion around for debugging
236: purposes. */
237:
238: int flag_keep_inline_functions;
239:
240: /* Name for output file of assembly code, specified with -o. */
241:
242: char *asm_file_name;
243:
244: /* Name for output file of GDB symbol segment, specified with -symout. */
245:
246: char *sym_file_name;
247:
248: /* Output files for assembler code (real compiler output)
249: and debugging dumps. */
250:
251: FILE *asm_out_file;
252: FILE *rtl_dump_file;
253: FILE *jump_opt_dump_file;
254: FILE *cse_dump_file;
255: FILE *loop_dump_file;
256: FILE *flow_dump_file;
257: FILE *combine_dump_file;
258: FILE *local_reg_dump_file;
259: FILE *global_reg_dump_file;
260: FILE *jump2_opt_dump_file;
261:
262: /* Time accumulators, to count the total time spent in various passes. */
263:
264: int parse_time;
265: int varconst_time;
266: int integration_time;
267: int jump_time;
268: int cse_time;
269: int loop_time;
270: int flow_time;
271: int combine_time;
272: int local_alloc_time;
273: int global_alloc_time;
274: int final_time;
275: int symout_time;
276: int dump_time;
277:
278: /* Return time used so far, in microseconds. */
279:
280: int
281: gettime ()
282: {
283: #ifdef USG
284: struct tms tms;
285: #else
286: #ifndef VMS
287: struct rusage rusage;
288: #else /* VMS */
289: struct
290: {
291: int proc_user_time;
292: int proc_system_time;
293: int child_user_time;
294: int child_system_time;
295: } vms_times;
296: #endif
297: #endif
298:
299: if (quiet_flag)
300: return 0;
301:
302: #ifdef USG
303: times (&tms);
304: return (tms.tms_utime + tms.tms_stime) * (1000000 / HZ);
305: #else
306: #ifndef VMS
307: getrusage (0, &rusage);
308: return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
309: + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
310: #else /* VMS */
311: times (&vms_times);
312: return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000;
313: #endif
314: #endif
315: }
316:
317: #define TIMEVAR(VAR, BODY) \
318: do { int otime = gettime (); BODY; VAR += gettime () - otime; } while (0)
319:
320: void
321: print_time (str, total)
322: char *str;
323: int total;
324: {
325: fprintf (stderr,
326: "time in %s: %d.%06d\n",
327: str, total / 1000000, total % 1000000);
328: }
329:
330: /* Count an error or warning. Return 1 if the message should be printed. */
331:
332: int
333: count_error (warningp)
334: int warningp;
335: {
336: if (warningp && inhibit_warnings)
337: return 0;
338:
339: if (warningp)
340: warningcount++;
341: else
342: errorcount++;
343:
344: return 1;
345: }
346:
347: /* Print a fatal error message. NAME is the text.
348: Also include a system error message based on `errno'. */
349:
350: void
351: pfatal_with_name (name)
352: char *name;
353: {
354: fprintf (stderr, "cc1: ");
355: perror (name);
356: exit (35);
357: }
358:
359: void
360: fatal_io_error (name)
361: char *name;
362: {
363: fprintf (stderr, "cc1:%s: I/O error\n", name);
364: exit (35);
365: }
366:
367: void
368: fatal (s)
369: char *s;
370: {
371: error (s, 0);
372: exit (34);
373: }
374:
375: /* Called when the start of a function definition is parsed,
376: this function prints on stderr the name of the function. */
377:
378: void
379: announce_function (decl)
380: tree decl;
381: {
382: if (! quiet_flag)
383: {
384: fprintf (stderr, " %s", IDENTIFIER_POINTER (DECL_NAME (decl)));
385: fflush (stderr);
386: }
387: }
388:
389: /* Prints out, if necessary, the name of the current function
390: which caused an error. Called from all error and warning functions. */
391:
392: void
393: report_error_function()
394: {
395: static tree last_error_function = NULL;
396:
397: if (last_error_function != current_function_decl)
398: {
399: if (current_function_decl == NULL)
400: {
401: if (!quiet_flag)
402: fprintf (stderr, "\n");
403: fprintf (stderr, "At top level:\n");
404: }
405: else
406: {
407: if (!quiet_flag)
408: /* We already know this info. Don't print it twice.
409: But make sure we are at the beginning of a line. */
410: fprintf (stderr, "\n");
411: else
412: fprintf (stderr, "In function %s:\n",
413: IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
414: }
415: last_error_function = current_function_decl;
416: }
417: }
418:
419: /* Report an error at the current line number.
420: S and V are a string and an arg for `printf'. */
421:
422: void
423: error (s, v)
424: char *s;
425: int v; /* @@also used as pointer */
426: {
427: error_with_file_and_line (input_filename, lineno, s, v);
428: }
429:
430: /* Report an error at line LINE of file FILE.
431: S and V are a string and an arg for `printf'. */
432:
433: void
434: error_with_file_and_line (file, line, s, v)
435: char *file;
436: int line;
437: char *s;
438: int v;
439: {
440: count_error (0);
441:
442: report_error_function ();
443:
444: if (file)
445: fprintf (stderr, "%s:%d: ", file, line);
446: else
447: fprintf (stderr, "cc1: ");
448: fprintf (stderr, s, v);
449: fprintf (stderr, "\n");
450: }
451:
452: /* Report an error at the declaration DECL.
453: S is string which uses %s to substitute the declaration name. */
454:
455: void
456: error_with_decl (decl, s)
457: tree decl;
458: char *s;
459: {
460: count_error (0);
461:
462: report_error_function ();
463:
464: fprintf (stderr, "%s:%d: ",
465: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
466:
467: if (DECL_NAME (decl))
468: fprintf (stderr, s, IDENTIFIER_POINTER (DECL_NAME (decl)));
469: else
470: fprintf (stderr, s, "((anonymous))");
471: fprintf (stderr, "\n");
472: }
473:
474: /* Report a warning at line LINE.
475: S and V are a string and an arg for `printf'. */
476:
477: void
478: warning_with_line (line, s, v)
479: int line;
480: char *s;
481: int v;
482: {
483: if (count_error (1) == 0)
484: return;
485:
486: report_error_function ();
487:
488: if (input_filename)
489: fprintf (stderr, "%s:%d: ", input_filename, line);
490: else
491: fprintf (stderr, "cc1: ");
492:
493: fprintf (stderr, "warning: ");
494: fprintf (stderr, s, v);
495: fprintf (stderr, "\n");
496: }
497:
498: /* Report a warning at the current line number.
499: S and V are a string and an arg for `printf'. */
500:
501: void
502: warning (s, v)
503: char *s;
504: int v; /* @@also used as pointer */
505: {
506: warning_with_line (lineno, s, v);
507: }
508:
509: /* Report a warning at the declaration DECL.
510: S is string which uses %s to substitute the declaration name. */
511:
512: void
513: warning_with_decl (decl, s)
514: tree decl;
515: char *s;
516: {
517: if (count_error (1) == 0)
518: return;
519:
520: report_error_function ();
521:
522: fprintf (stderr, "%s:%d: ",
523: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
524:
525: fprintf (stderr, "warning: ");
526: if (DECL_NAME (decl))
527: fprintf (stderr, s, IDENTIFIER_POINTER (DECL_NAME (decl)));
528: else
529: fprintf (stderr, s, "((anonymous))");
530: fprintf (stderr, "\n");
531: }
532:
533: /* When `malloc.c' is compiled with `rcheck' defined,
534: it calls this function to report clobberage. */
535:
536: void
537: botch (s)
538: {
539: abort ();
540: }
541:
542: /* Same as `malloc' but report error if no memory available. */
543:
544: int
545: xmalloc (size)
546: unsigned size;
547: {
548: register int value = (int) malloc (size);
549: if (value == 0)
550: fatal ("Virtual memory exhausted.");
551: return value;
552: }
553:
554: /* Same as `realloc' but report error if no memory available. */
555:
556: int
557: xrealloc (ptr, size)
558: char *ptr;
559: int size;
560: {
561: int result = realloc (ptr, size);
562: if (!result)
563: fatal ("Virtual memory exhausted.");
564: return result;
565: }
566:
567: /* Return the logarithm of X, base 2, considering X unsigned,
568: if X is a power of 2. Otherwise, returns -1. */
569:
570: int
571: exact_log2 (x)
572: register unsigned int x;
573: {
574: register int log = 0;
575: for (log = 0; log < HOST_BITS_PER_INT; log++)
576: if (x == (1 << log))
577: return log;
578: return -1;
579: }
580:
581: /* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
582: If X is 0, return -1. */
583:
584: int
585: floor_log2 (x)
586: register unsigned int x;
587: {
588: register int log = 0;
589: for (log = 0; log < HOST_BITS_PER_INT; log++)
590: if ((x & ((-1) << log)) == 0)
591: return log - 1;
592: return HOST_BITS_PER_INT - 1;
593: }
594:
595: /* Compile an entire file of output from cpp, named NAME.
596: Write a file of assembly output and various debugging dumps. */
597:
598: static void
599: compile_file (name)
600: char *name;
601: {
602: tree globals;
603: int start_time;
604: int dump_base_name_length = strlen (dump_base_name);
605:
606: parse_time = 0;
607: varconst_time = 0;
608: integration_time = 0;
609: jump_time = 0;
610: cse_time = 0;
611: loop_time = 0;
612: flow_time = 0;
613: combine_time = 0;
614: local_alloc_time = 0;
615: global_alloc_time = 0;
616: final_time = 0;
617: symout_time = 0;
618: dump_time = 0;
619:
620: /* Open input file. */
621:
622: finput = fopen (name, "r");
623: if (finput == 0)
624: pfatal_with_name (name);
625:
626: /* Initialize data in various passes. */
627:
628: init_tree ();
629: init_lex ();
630: init_rtl ();
631: init_emit_once ();
632: init_decl_processing ();
633: init_optabs ();
634:
635: /* If rtl dump desired, open the output file. */
636: if (rtl_dump)
637: {
638: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
639: strcpy (dumpname, dump_base_name);
640: strcat (dumpname, ".rtl");
641: rtl_dump_file = fopen (dumpname, "w");
642: if (rtl_dump_file == 0)
643: pfatal_with_name (dumpname);
644: }
645:
646: /* If jump_opt dump desired, open the output file. */
647: if (jump_opt_dump)
648: {
649: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
650: strcpy (dumpname, dump_base_name);
651: strcat (dumpname, ".jump");
652: jump_opt_dump_file = fopen (dumpname, "w");
653: if (jump_opt_dump_file == 0)
654: pfatal_with_name (dumpname);
655: }
656:
657: /* If cse dump desired, open the output file. */
658: if (cse_dump)
659: {
660: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
661: strcpy (dumpname, dump_base_name);
662: strcat (dumpname, ".cse");
663: cse_dump_file = fopen (dumpname, "w");
664: if (cse_dump_file == 0)
665: pfatal_with_name (dumpname);
666: }
667:
668: /* If loop dump desired, open the output file. */
669: if (loop_dump)
670: {
671: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
672: strcpy (dumpname, dump_base_name);
673: strcat (dumpname, ".loop");
674: loop_dump_file = fopen (dumpname, "w");
675: if (loop_dump_file == 0)
676: pfatal_with_name (dumpname);
677: }
678:
679: /* If flow dump desired, open the output file. */
680: if (flow_dump)
681: {
682: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
683: strcpy (dumpname, dump_base_name);
684: strcat (dumpname, ".flow");
685: flow_dump_file = fopen (dumpname, "w");
686: if (flow_dump_file == 0)
687: pfatal_with_name (dumpname);
688: }
689:
690: /* If combine dump desired, open the output file. */
691: if (combine_dump)
692: {
693: register char *dumpname = (char *) xmalloc (dump_base_name_length + 10);
694: strcpy (dumpname, dump_base_name);
695: strcat (dumpname, ".combine");
696: combine_dump_file = fopen (dumpname, "w");
697: if (combine_dump_file == 0)
698: pfatal_with_name (dumpname);
699: }
700:
701: /* If local_reg dump desired, open the output file. */
702: if (local_reg_dump)
703: {
704: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
705: strcpy (dumpname, dump_base_name);
706: strcat (dumpname, ".lreg");
707: local_reg_dump_file = fopen (dumpname, "w");
708: if (local_reg_dump_file == 0)
709: pfatal_with_name (dumpname);
710: }
711:
712: /* If global_reg dump desired, open the output file. */
713: if (global_reg_dump)
714: {
715: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
716: strcpy (dumpname, dump_base_name);
717: strcat (dumpname, ".greg");
718: global_reg_dump_file = fopen (dumpname, "w");
719: if (global_reg_dump_file == 0)
720: pfatal_with_name (dumpname);
721: }
722:
723: /* If jump2_opt dump desired, open the output file. */
724: if (jump2_opt_dump)
725: {
726: register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
727: strcpy (dumpname, dump_base_name);
728: strcat (dumpname, ".jump2");
729: jump2_opt_dump_file = fopen (dumpname, "w");
730: if (jump2_opt_dump_file == 0)
731: pfatal_with_name (dumpname);
732: }
733:
734: /* Open assembler code output file. */
735:
736: {
737: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
738: int len = strlen (dump_base_name);
739: strcpy (dumpname, dump_base_name);
740: if (len > 2 && ! strcmp (".c", dumpname + len - 2))
741: dumpname[len - 2] = 0;
742: else if (len > 3 && ! strcmp (".co", dumpname + len - 3))
743: dumpname[len - 3] = 0;
744: strcat (dumpname, ".s");
745: if (asm_file_name == 0)
746: {
747: asm_file_name = (char *) malloc (strlen (dumpname) + 1);
748: strcpy (asm_file_name, dumpname);
749: }
750: asm_out_file = fopen (asm_file_name, "w");
751: if (asm_out_file == 0)
752: pfatal_with_name (asm_file_name ? asm_file_name : dumpname);
753: fprintf (asm_out_file, ASM_FILE_START);
754: }
755:
756: input_filename = name;
757:
758: /* the beginning of the file is a new line; check for # */
759: /* With luck, we discover the real source file's name from that
760: and put it in input_filename. */
761: check_newline ();
762:
763: /* If GDB symbol table desired, open the GDB symbol output file. */
764: if (write_symbols == 1)
765: {
766: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
767: int len = strlen (dump_base_name);
768: strcpy (dumpname, dump_base_name);
769: if (len > 2 && ! strcmp (".c", dumpname + len - 2))
770: dumpname[len - 2] = 0;
771: else if (len > 3 && ! strcmp (".co", dumpname + len - 3))
772: dumpname[len - 3] = 0;
773: strcat (dumpname, ".sym");
774: if (sym_file_name == 0)
775: sym_file_name = dumpname;
776: symout_init (sym_file_name, asm_out_file, input_filename);
777: }
778:
779: /* If dbx symbol table desired, initialize writing it
780: and output the predefined types. */
781: if (write_symbols == 2)
782: dbxout_init (asm_out_file, main_input_filename);
783:
784: /* Initialize yet another pass. */
785:
786: init_final (main_input_filename);
787:
788: start_time = gettime ();
789:
790: /* Call the parser, which parses the entire file
791: (calling rest_of_compilation for each function). */
792:
793: yyparse ();
794:
795: /* Compilation is now finished except for writing
796: what's left of the symbol table output. */
797:
798: parse_time += gettime () - start_time;
799:
800: parse_time -= varconst_time;
801:
802: globals = getdecls ();
803:
804: /* Really define vars that have had only a tentative definition.
805: Really output inline functions that must actually be callable
806: and have not been output so far. */
807:
808: {
809: tree decl;
810: for (decl = globals; decl; decl = TREE_CHAIN (decl))
811: {
812: if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
813: && ! TREE_ASM_WRITTEN (decl))
814: rest_of_decl_compilation (decl, 0, 1, 1);
815: if (TREE_CODE (decl) == FUNCTION_DECL
816: && ! TREE_ASM_WRITTEN (decl)
817: && DECL_INITIAL (decl) != 0
818: && TREE_ADDRESSABLE (decl))
819: output_inline_function (decl);
820: }
821: }
822:
823: /* Do dbx symbols */
824: if (write_symbols == 2)
825: TIMEVAR (symout_time,
826: {
827: dbxout_tags (gettags ());
828: dbxout_types (get_permanent_types ());
829: });
830:
831: /* Do gdb symbols */
832: if (write_symbols == 1)
833: TIMEVAR (symout_time,
834: {
835: struct stat statbuf;
836: fstat (fileno (finput), &statbuf);
837: symout_types (get_permanent_types ());
838: symout_top_blocks (globals, gettags ());
839: symout_finish (name, statbuf.st_ctime);
840: });
841:
842: /* Close the dump files. */
843:
844: if (rtl_dump)
845: fclose (rtl_dump_file);
846:
847: if (jump_opt_dump)
848: fclose (jump_opt_dump_file);
849:
850: if (cse_dump)
851: fclose (cse_dump_file);
852:
853: if (loop_dump)
854: fclose (loop_dump_file);
855:
856: if (flow_dump)
857: fclose (flow_dump_file);
858:
859: if (combine_dump)
860: {
861: dump_combine_total_stats (combine_dump_file);
862: fclose (combine_dump_file);
863: }
864:
865: if (local_reg_dump)
866: fclose (local_reg_dump_file);
867:
868: if (global_reg_dump)
869: fclose (global_reg_dump_file);
870:
871: if (jump2_opt_dump)
872: fclose (jump2_opt_dump_file);
873:
874: /* Close non-debugging input and output files. */
875:
876: fclose (finput);
877: if (ferror (asm_out_file) != 0)
878: fatal_io_error (asm_file_name);
879: fclose (asm_out_file);
880:
881: /* Print the times. */
882:
883: if (! quiet_flag)
884: {
885: fprintf (stderr,"\n");
886: print_time ("parse", parse_time);
887: print_time ("integration", integration_time);
888: print_time ("jump", jump_time);
889: print_time ("cse", cse_time);
890: print_time ("loop", loop_time);
891: print_time ("flow", flow_time);
892: print_time ("combine", combine_time);
893: print_time ("local-alloc", local_alloc_time);
894: print_time ("global-alloc", global_alloc_time);
895: print_time ("final", final_time);
896: print_time ("varconst", varconst_time);
897: print_time ("symout", symout_time);
898: print_time ("dump", dump_time);
899: }
900: }
901:
902: /* This is called from finish_decl (within yyparse)
903: for each declaration of a function or variable.
904: This does nothing for automatic variables.
905: Otherwise, it sets up the RTL and outputs any assembler code
906: (label definition, storage allocation and initialization).
907:
908: DECL is the declaration. If ASMSPEC is nonzero, it specifies
909: the assembler symbol name to be used. TOP_LEVEL is nonzero
910: if this declaration is not within a function. */
911:
912: void
913: rest_of_decl_compilation (decl, asmspec, top_level, at_end)
914: tree decl;
915: tree asmspec;
916: int top_level;
917: int at_end;
918: {
919: /* Declarations of variables, and of functions defined elsewhere. */
920:
921: if (TREE_STATIC (decl) || TREE_EXTERNAL (decl))
922: TIMEVAR (varconst_time,
923: {
924: assemble_variable (decl, asmspec, top_level, write_symbols, at_end);
925: });
926: else if (write_symbols == 2 && TREE_CODE (decl) == TYPE_DECL)
927: TIMEVAR (varconst_time, dbxout_symbol (decl, 0));
928:
929: if (top_level)
930: {
931: if (write_symbols == 1)
932: {
933: TIMEVAR (symout_time,
934: {
935: /* The initizations make types when they contain
936: string constants. The types are on the temporary
937: obstack, so output them now before they go away. */
938: symout_types (get_temporary_types ());
939: });
940: }
941: else
942: /* Clean out the temporary type list, since the types will go away. */
943: get_temporary_types ();
944: }
945: }
946:
947: /* This is called from finish_function (within yyparse)
948: after each top-level definition is parsed.
949: It is supposed to compile that function or variable
950: and output the assembler code for it.
951: After we return, the tree storage is freed. */
952:
953: void
954: rest_of_compilation (decl)
955: tree decl;
956: {
957: register rtx insns;
958: int start_time = gettime ();
959: int tem;
960:
961: /* If we are reconsidering an inline function
962: at the end of compilation, skip the stuff for making it inline. */
963:
964: if (DECL_SAVED_INSNS (decl) == 0)
965: {
966:
967: /* If requested, consider whether to make this function inline. */
968: if (flag_inline_functions || TREE_INLINE (decl))
969: {
970: TIMEVAR (integration_time,
971: {
972: int specd = TREE_INLINE (decl);
973: char *lose = function_cannot_inline_p (decl);
974: if (lose != 0 && specd)
975: warning_with_decl (decl, lose);
976: if (lose == 0)
977: save_for_inline (decl);
978: else
979: TREE_INLINE (decl) = 0;
980: });
981: }
982:
983: insns = get_insns ();
984:
985: /* Dump the rtl code if we are dumping rtl. */
986:
987: if (rtl_dump)
988: TIMEVAR (dump_time,
989: {
990: fprintf (rtl_dump_file, "\n;; Function %s\n\n",
991: IDENTIFIER_POINTER (DECL_NAME (decl)));
992: if (DECL_SAVED_INSNS (decl))
993: fprintf (rtl_dump_file, ";; (integrable)\n\n");
994: print_rtl (rtl_dump_file, insns);
995: fflush (rtl_dump_file);
996: });
997:
998: /* If function is inline, and we don't yet know whether to
999: compile it by itself, defer decision till end of compilation.
1000: finish_compilation will call rest_of_compilation again
1001: for those functions that need to be output. */
1002:
1003: if (TREE_PUBLIC (decl) == 0
1004: && TREE_INLINE (decl)
1005: && ! flag_keep_inline_functions)
1006: goto exit_rest_of_compilation;
1007: }
1008:
1009: if (rtl_dump_and_exit)
1010: goto exit_rest_of_compilation;
1011:
1012: TREE_ASM_WRITTEN (decl) = 1;
1013:
1014: insns = get_insns ();
1015:
1016: /* Copy any shared structure that should not be shared. */
1017:
1018: unshare_all_rtl (insns);
1019:
1020: /* See if we have allocated stack slots that are not directly addressable.
1021: If so, scan all the insns and create explicit address computation
1022: for all references to such slots. */
1023: /* fixup_stack_slots (); */
1024:
1025: /* Do jump optimization the first time, if -opt.
1026: Also do it if -W, but in that case it doesn't change the rtl code,
1027: it only computes whether control can drop off the end of the function. */
1028:
1029: if (optimize || extra_warnings || warn_return_type)
1030: TIMEVAR (jump_time, jump_optimize (insns, 0, 0));
1031:
1032: /* Dump rtl code after jump, if we are doing that. */
1033:
1034: if (jump_opt_dump)
1035: TIMEVAR (dump_time,
1036: {
1037: fprintf (jump_opt_dump_file, "\n;; Function %s\n\n",
1038: IDENTIFIER_POINTER (DECL_NAME (decl)));
1039: print_rtl (jump_opt_dump_file, insns);
1040: fflush (jump_opt_dump_file);
1041: });
1042:
1043: /* Perform common subexpression elimination.
1044: Nonzero value from `cse_main' means that jumps were simplified
1045: and some code may now be unreachable, so do
1046: jump optimization again. */
1047:
1048: if (optimize)
1049: {
1050: TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 0));
1051:
1052: TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num ()));
1053:
1054: if (tem)
1055: TIMEVAR (jump_time, jump_optimize (insns, 0, 0));
1056: }
1057:
1058: /* Dump rtl code after cse, if we are doing that. */
1059:
1060: if (cse_dump)
1061: TIMEVAR (dump_time,
1062: {
1063: fprintf (cse_dump_file, "\n;; Function %s\n\n",
1064: IDENTIFIER_POINTER (DECL_NAME (decl)));
1065: print_rtl (cse_dump_file, insns);
1066: fflush (cse_dump_file);
1067: });
1068:
1069: if (loop_dump)
1070: TIMEVAR (dump_time,
1071: {
1072: fprintf (loop_dump_file, "\n;; Function %s\n\n",
1073: IDENTIFIER_POINTER (DECL_NAME (decl)));
1074: });
1075:
1076: /* Move constant computations out of loops. */
1077:
1078: if (optimize)
1079: {
1080: TIMEVAR (loop_time,
1081: {
1082: reg_scan (insns, max_reg_num (), 1);
1083: loop_optimize (insns, max_reg_num (),
1084: loop_dump ? loop_dump_file : 0);
1085: });
1086: }
1087:
1088: /* Dump rtl code after loop opt, if we are doing that. */
1089:
1090: if (loop_dump)
1091: TIMEVAR (dump_time,
1092: {
1093: print_rtl (loop_dump_file, insns);
1094: fflush (loop_dump_file);
1095: });
1096:
1097: /* Now we choose between stupid (pcc-like) register allocation
1098: (if we got the -noreg switch and not -opt)
1099: and smart register allocation. */
1100:
1101: if (optimize) /* Stupid allocation probably won't work */
1102: obey_regdecls = 0; /* if optimizations being done. */
1103:
1104: regclass_init ();
1105:
1106: /* Print function header into flow dump now
1107: because doing the flow analysis makes some of the dump. */
1108:
1109: if (flow_dump)
1110: TIMEVAR (dump_time,
1111: {
1112: fprintf (flow_dump_file, "\n;; Function %s\n\n",
1113: IDENTIFIER_POINTER (DECL_NAME (decl)));
1114: });
1115:
1116: if (obey_regdecls)
1117: {
1118: TIMEVAR (flow_time,
1119: {
1120: regclass (insns, max_reg_num ());
1121: stupid_life_analysis (insns, max_reg_num (),
1122: flow_dump_file);
1123: });
1124: }
1125: else
1126: {
1127: /* Do control and data flow analysis,
1128: and write some of the results to dump file. */
1129:
1130: TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (),
1131: flow_dump_file));
1132: if (extra_warnings)
1133: uninitialized_vars_warning (DECL_INITIAL (decl));
1134: }
1135:
1136: /* Dump rtl after flow analysis. */
1137:
1138: if (flow_dump)
1139: TIMEVAR (dump_time,
1140: {
1141: print_rtl (flow_dump_file, insns);
1142: fflush (flow_dump_file);
1143: });
1144:
1145: /* If -opt, try combining insns through substitution. */
1146:
1147: if (optimize)
1148: TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
1149:
1150: /* Dump rtl code after insn combination. */
1151:
1152: if (combine_dump)
1153: TIMEVAR (dump_time,
1154: {
1155: fprintf (combine_dump_file, "\n;; Function %s\n\n",
1156: IDENTIFIER_POINTER (DECL_NAME (decl)));
1157: dump_combine_stats (combine_dump_file);
1158: print_rtl (combine_dump_file, insns);
1159: fflush (combine_dump_file);
1160: });
1161:
1162: /* Unless we did stupid register allocation,
1163: allocate pseudo-regs that are used only within 1 basic block. */
1164:
1165: if (!obey_regdecls)
1166: TIMEVAR (local_alloc_time,
1167: {
1168: regclass (insns, max_reg_num ());
1169: local_alloc ();
1170: });
1171:
1172: /* Dump rtl code after allocating regs within basic blocks. */
1173:
1174: if (local_reg_dump)
1175: TIMEVAR (dump_time,
1176: {
1177: fprintf (local_reg_dump_file, "\n;; Function %s\n\n",
1178: IDENTIFIER_POINTER (DECL_NAME (decl)));
1179: dump_flow_info (local_reg_dump_file);
1180: dump_local_alloc (local_reg_dump_file);
1181: print_rtl (local_reg_dump_file, insns);
1182: fflush (local_reg_dump_file);
1183: });
1184:
1185: if (global_reg_dump)
1186: TIMEVAR (dump_time,
1187: fprintf (global_reg_dump_file, "\n;; Function %s\n\n",
1188: IDENTIFIER_POINTER (DECL_NAME (decl))));
1189:
1190: /* Unless we did stupid register allocation,
1191: allocate remaining pseudo-regs, then do the reload pass
1192: fixing up any insns that are invalid. */
1193:
1194: TIMEVAR (global_alloc_time,
1195: {
1196: if (!obey_regdecls)
1197: global_alloc (global_reg_dump ? global_reg_dump_file : 0);
1198: else
1199: reload (insns, 0,
1200: global_reg_dump ? global_reg_dump_file : 0);
1201: });
1202:
1203: if (global_reg_dump)
1204: TIMEVAR (dump_time,
1205: {
1206: dump_global_regs (global_reg_dump_file);
1207: print_rtl (global_reg_dump_file, insns);
1208: fflush (global_reg_dump_file);
1209: });
1210:
1211: /* One more attempt to remove jumps to .+1
1212: left by dead-store-elimination.
1213: Also do cross-jumping this time
1214: and delete no-op move insns. */
1215:
1216: if (optimize)
1217: {
1218: TIMEVAR (jump_time, jump_optimize (insns, 1, 1));
1219: }
1220:
1221: /* Dump rtl code after jump, if we are doing that. */
1222:
1223: if (jump2_opt_dump)
1224: TIMEVAR (dump_time,
1225: {
1226: fprintf (jump2_opt_dump_file, "\n;; Function %s\n\n",
1227: IDENTIFIER_POINTER (DECL_NAME (decl)));
1228: print_rtl (jump2_opt_dump_file, insns);
1229: fflush (jump2_opt_dump_file);
1230: });
1231:
1232: /* Now turn the rtl into assembler code. */
1233:
1234: TIMEVAR (final_time,
1235: {
1236: assemble_function (decl);
1237: final_start_function (insns, asm_out_file,
1238: write_symbols, optimize);
1239: final (insns, asm_out_file,
1240: write_symbols, optimize);
1241: final_end_function (insns, asm_out_file,
1242: write_symbols, optimize);
1243: fflush (asm_out_file);
1244: });
1245:
1246: /* Write GDB symbols if requested */
1247:
1248: if (write_symbols == 1)
1249: {
1250: TIMEVAR (symout_time,
1251: {
1252: symout_types (get_permanent_types ());
1253: symout_types (get_temporary_types ());
1254:
1255: DECL_BLOCK_SYMTAB_ADDRESS (decl)
1256: = symout_function (DECL_INITIAL (decl),
1257: DECL_ARGUMENTS (decl), 0);
1258: });
1259: }
1260: else
1261: get_temporary_types ();
1262:
1263: /* Write DBX symbols if requested */
1264:
1265: if (write_symbols == 2)
1266: TIMEVAR (symout_time, dbxout_function (decl));
1267:
1268: exit_rest_of_compilation:
1269:
1270: /* The parsing time is all the time spent in yyparse
1271: *except* what is spent in this function. */
1272:
1273: parse_time -= gettime () - start_time;
1274: }
1275:
1276: /* Entry point of cc1. Decode command args, then call compile_file.
1277: Exit code is 35 if can't open files, 34 if fatal error,
1278: 33 if had nonfatal errors, else success. */
1279:
1280: int
1281: main (argc, argv, envp)
1282: int argc;
1283: char **argv;
1284: char **envp;
1285: {
1286: register int i;
1287: char *filename = 0;
1288: int print_mem_flag = 0;
1289:
1290: #ifdef RLIMIT_STACK
1291: /* Get rid of any avoidable limit on stack size. */
1292: {
1293: struct rlimit rlim;
1294:
1295: /* Set the stack limit huge so that alloca does not fail. */
1296: getrlimit (RLIMIT_STACK, &rlim);
1297: rlim.rlim_cur = rlim.rlim_max;
1298: setrlimit (RLIMIT_STACK, &rlim);
1299: }
1300: #endif /* RLIMIT_STACK */
1301:
1302: /* Initialize whether `char' is signed. */
1303: flag_signed_char = DEFAULT_SIGNED_CHAR;
1304:
1305: /* Initialize reg-sets now so switches may override. */
1306: init_reg_sets ();
1307:
1308: target_flags = 0;
1309: set_target_switch ("");
1310:
1311: for (i = 1; i < argc; i++)
1312: if (argv[i][0] == '-')
1313: {
1314: register char *str = argv[i] + 1;
1315: if (str[0] == 'Y')
1316: str++;
1317:
1318: if (str[0] == 'm')
1319: set_target_switch (&str[1]);
1320: else if (!strcmp (str, "dumpbase"))
1321: {
1322: dump_base_name = argv[++i];
1323: }
1324: else if (str[0] == 'd')
1325: {
1326: register char *p = &str[1];
1327: while (*p)
1328: switch (*p++)
1329: {
1330: case 'c':
1331: combine_dump = 1;
1332: break;
1333: case 'f':
1334: flow_dump = 1;
1335: break;
1336: case 'g':
1337: global_reg_dump = 1;
1338: break;
1339: case 'j':
1340: jump_opt_dump = 1;
1341: break;
1342: case 'J':
1343: jump2_opt_dump = 1;
1344: break;
1345: case 'l':
1346: local_reg_dump = 1;
1347: break;
1348: case 'L':
1349: loop_dump = 1;
1350: break;
1351: case 'm':
1352: print_mem_flag = 1;
1353: break;
1354: case 'r':
1355: rtl_dump = 1;
1356: break;
1357: case 's':
1358: cse_dump = 1;
1359: break;
1360: case 'y':
1361: yydebug = 1;
1362: break;
1363: }
1364: }
1365: else if (str[0] == 'f')
1366: {
1367: register char *p = &str[1];
1368: if (!strcmp (p, "float-store"))
1369: flag_float_store = 1;
1370: else if (!strcmp (p, "traditional"))
1371: flag_traditional = 1;
1372: else if (!strcmp (p, "volatile"))
1373: flag_volatile = 1;
1374: else if (!strcmp (p, "defer-pop"))
1375: flag_defer_pop = 1;
1376: else if (!strcmp (p, "no-defer-pop"))
1377: flag_defer_pop = 0;
1378: else if (!strcmp (p, "omit-frame-pointer"))
1379: flag_omit_frame_pointer = 1;
1380: else if (!strcmp (p, "no-omit-frame-pointer"))
1381: flag_omit_frame_pointer = 0;
1382: else if (!strcmp (p, "no-peephole"))
1383: flag_no_peephole = 1;
1384: else if (!strcmp (p, "signed-char"))
1385: flag_signed_char = 1;
1386: else if (!strcmp (p, "unsigned-char"))
1387: flag_signed_char = 0;
1388: else if (!strcmp (p, "force-mem"))
1389: flag_force_mem = 1;
1390: else if (!strcmp (p, "force-addr"))
1391: flag_force_addr = 1;
1392: else if (!strcmp (p, "combine-regs"))
1393: flag_combine_regs = 1;
1394: else if (!strcmp (p, "writable-strings"))
1395: flag_writable_strings = 1;
1396: else if (!strcmp (p, "no-function-cse"))
1397: flag_no_function_cse = 1;
1398: else if (!strcmp (p, "cond-mismatch"))
1399: flag_cond_mismatch = 1;
1400: else if (!strcmp (p, "no-asm"))
1401: flag_no_asm = 1;
1402: else if (!strncmp (p, "fixed-", 6))
1403: fix_register (&p[6], 1, 1);
1404: else if (!strncmp (p, "call-used-", 10))
1405: fix_register (&p[10], 0, 1);
1406: else if (!strncmp (p, "call-saved-", 11))
1407: fix_register (&p[11], 0, 0);
1408: else if (!strcmp (p, "inline-functions"))
1409: flag_inline_functions = 1;
1410: else if (!strcmp (p, "keep-inline-functions"))
1411: flag_keep_inline_functions = 1;
1412: else
1413: error ("Invalid option, `%s'", argv[i]);
1414: }
1415: else if (!strcmp (str, "noreg"))
1416: obey_regdecls = 1;
1417: else if (!strcmp (str, "opt"))
1418: optimize = 1;
1419: else if (!strcmp (str, "pedantic"))
1420: pedantic = 1;
1421: else if (!strcmp (str, "traditional"))
1422: flag_traditional = 1;
1423: else if (!strcmp (str, "ansi"))
1424: flag_no_asm = 1;
1425: else if (!strcmp (str, "quiet"))
1426: quiet_flag = 1;
1427: else if (!strcmp (str, "version"))
1428: {
1429: extern char version_string[];
1430: printf ("GNU C version %s", version_string);
1431: #ifdef TARGET_VERSION
1432: TARGET_VERSION;
1433: #endif
1434: #ifdef __GNUC__
1435: #ifndef __VERSION__
1436: #define __VERSION__ "[unknown]"
1437: #endif
1438: printf (" compiled by GNU C version %s.\n", __VERSION__);
1439: #else
1440: printf (" compiled by CC.\n");
1441: #endif
1442: }
1443: else if (!strcmp (str, "w"))
1444: inhibit_warnings = 1;
1445: else if (!strcmp (str, "W"))
1446: extra_warnings = 1;
1447: else if (!strcmp (str, "Wimplicit"))
1448: warn_implicit = 1;
1449: else if (!strcmp (str, "Wreturn-type"))
1450: warn_return_type = 1;
1451: else if (!strcmp (str, "Wcomment"))
1452: ; /* cpp handles this one. */
1453: else if (!strcmp (str, "Wall"))
1454: {
1455: extra_warnings = 1;
1456: warn_implicit = 1;
1457: warn_return_type = 1;
1458: }
1459: else if (!strcmp (str, "p"))
1460: profile_flag = 1;
1461: else if (!strcmp (str, "g"))
1462: write_symbols = 1;
1463: else if (!strcmp (str, "G"))
1464: write_symbols = 2;
1465: else if (!strcmp (str, "symout"))
1466: {
1467: if (write_symbols == 0)
1468: write_symbols = 1;
1469: sym_file_name = argv[++i];
1470: }
1471: else if (!strcmp (str, "o"))
1472: {
1473: asm_file_name = argv[++i];
1474: }
1475: else
1476: error ("Invalid switch, %s.", argv[i]);
1477: }
1478: else
1479: filename = argv[i];
1480:
1481: if (filename == 0)
1482: fatal ("no input file specified");
1483:
1484: if (dump_base_name == 0)
1485: dump_base_name = filename;
1486:
1487: #ifdef OVERRIDE_OPTIONS
1488: /* Some machines may reject certain combinations of options. */
1489: OVERRIDE_OPTIONS;
1490: #endif
1491:
1492: compile_file (filename);
1493:
1494: #ifndef USG
1495: #ifndef VMS
1496: if (print_mem_flag)
1497: {
1498: extern char **environ;
1499: caddr_t lim = (caddr_t) sbrk (0);
1500:
1501: fprintf (stderr, "Data size %d.\n",
1502: (int) lim - (int) &environ);
1503: fflush (stderr);
1504:
1505: system ("ps v");
1506: }
1507: #endif /* not VMS */
1508: #endif /* not USG */
1509:
1510: if (errorcount)
1511: exit (FATAL_EXIT_CODE);
1512: exit (SUCCESS_EXIT_CODE);
1513: return 34;
1514: }
1515:
1516: /* Decode -m switches. */
1517:
1518: /* Here is a table, controlled by the tm-...h file, listing each -m switch
1519: and which bits in `target_switches' it should set or clear.
1520: If VALUE is positive, it is bits to set.
1521: If VALUE is negative, -VALUE is bits to clear.
1522: (The sign bit is not used so there is no confusion.) */
1523:
1524: struct {char *name; int value;} target_switches []
1525: = TARGET_SWITCHES;
1526:
1527: /* Decode the switch -mNAME. */
1528:
1529: void
1530: set_target_switch (name)
1531: char *name;
1532: {
1533: register int j;
1534: for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
1535: if (!strcmp (target_switches[j].name, name))
1536: {
1537: if (target_switches[j].value < 0)
1538: target_flags &= ~-target_switches[j].value;
1539: else
1540: target_flags |= target_switches[j].value;
1541: break;
1542: }
1543: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.