|
|
1.1 root 1: /* Top level of GNU C compiler
2: Copyright (C) 1987 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: #include <strings.h>
31: #include <sys/time.h>
32: #include <sys/resource.h>
33: #ifndef _TYPES_
34: #include <sys/types.h>
35: #endif
36: #include <sys/stat.h>
37: #include "tree.h"
38: #include "c-tree.h"
39: #include "rtl.h"
40:
41: extern void dump_tree ();
42: extern int yydebug;
43:
44: extern FILE *finput;
45:
46: extern void init_lex ();
47: extern void init_decl_processing ();
48: extern void init_tree ();
49: extern void init_rtl ();
50: extern rtx expand_function ();
51: extern void init_optabs ();
52: extern void dump_flow_info ();
53: extern void dump_local_alloc ();
54:
55: /* Bit flags that specify the machine subtype we are compiling for.
56: Bits are tested using macros TARGET_... defined in the tm-...h file
57: and set by `-m...' switches. */
58:
59: int target_flags;
60:
61: /* Name of current real source file (what was input to cpp).
62: # commands in the input that specify file names
63: change this value. */
64:
65: extern char *input_filename;
66:
67: /* Current line number in real source file. */
68:
69: extern int lineno;
70:
71: /* FUNCTION_DECL for function now being parsed or compiled. */
72:
73: extern tree current_function_decl;
74:
75: /* Name to use as base of names for dump output files. */
76:
77: char *dump_base_name;
78:
79: /* Flags saying which kinds of debugging dump have been requested. */
80:
81: int tree_dump = 0;
82: int rtl_dump = 0;
83: int rtl_dump_and_exit = 0;
84: int jump_opt_dump = 0;
85: int cse_dump = 0;
86: int loop_dump = 0;
87: int flow_dump = 0;
88: int combine_dump = 0;
89: int local_reg_dump = 0;
90: int global_reg_dump = 0;
91:
92: /* 1 => write gdb debugging output (using symout.c). -g
93: 2 => write dbx debugging output (using dbxout.c). -G */
94:
95: int write_symbols = 0;
96:
97: /* Nonzero means do optimizations. -opt. */
98:
99: int optimize = 0;
100:
101: /* Nonzero for -optforcemem: load memory value into a register
102: before arithmetic on it. This makes better cse but slower compilation. */
103:
104: int force_mem = 0;
105:
106: /* Nonzero for -optforcemem: load memory address into a register before
107: reference to memory. This makes better cse but slower compilation. */
108:
109: int force_addr = 0;
110:
111: /* Nonzero means do stupid register allocation. -noreg.
112: This an OPTIMIZE are controlled by different switches in cc1,
113: but normally cc controls them both with the -O switch. */
114:
115: int obey_regdecls = 0;
116:
117: /* Don't print functions as they are compiled and don't print
118: times taken by the various passes. -quiet. */
119:
120: int quiet_flag = 0;
121:
122: /* Don't print warning messages. -w. */
123:
124: int inhibit_warnings = 0;
125:
126: /* Number of error messages and warning messages so far. */
127:
128: int errorcount = 0;
129: int warningcount = 0;
130:
131: /* Nonzero for -pedantic switch: warn about anything
132: that standard C forbids. */
133:
134: int pedantic = 0;
135:
136: /* Name for output file of assembly code, specified with -o. */
137:
138: char *asm_file_name;
139:
140: /* Name for output file of GDB symbol segment, specified with -symout. */
141:
142: char *sym_file_name;
143:
144: /* Output files for assembler code (real compiler output)
145: and debugging dumps. */
146:
147: FILE *asm_out_file;
148: FILE *tree_dump_file;
149: FILE *rtl_dump_file;
150: FILE *jump_opt_dump_file;
151: FILE *cse_dump_file;
152: FILE *loop_dump_file;
153: FILE *flow_dump_file;
154: FILE *combine_dump_file;
155: FILE *local_reg_dump_file;
156: FILE *global_reg_dump_file;
157:
158: /* Time accumulators, to count the total time spent in various passes. */
159:
160: int parse_time;
161: int varconst_time;
162: int expand_time;
163: int jump_time;
164: int cse_time;
165: int loop_time;
166: int flow_time;
167: int combine_time;
168: int local_alloc_time;
169: int global_alloc_time;
170: int final_time;
171: int symout_time;
172: int dump_time;
173:
174: /* Return time used so far, in microseconds. */
175:
176: gettime ()
177: {
178: struct rusage rusage;
179: if (quiet_flag)
180: return 0;
181: getrusage (0, &rusage);
182: return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
183: + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
184: }
185:
186: #define TIMEVAR(VAR, BODY) \
187: { int otime = gettime (); BODY; VAR += gettime () - otime; }
188:
189: print_time (str, total)
190: char *str;
191: int total;
192: {
193: printf ("time in %s: %d.%06d\n", str, total / 1000000, total % 1000000);
194: }
195:
196: /* Count an error or warning. Return 1 if the message should be printed. */
197:
198: int
199: count_error (warningp)
200: int warningp;
201: {
202: if (warningp && inhibit_warnings)
203: return 0;
204:
205: if (warningp)
206: warningcount++;
207: else
208: errorcount++;
209:
210: /* If we are printing function names, make sure error message
211: starts at beginning of line. */
212: if (!quiet_flag)
213: fprintf (stderr, "\n");
214:
215: return 1;
216: }
217:
218: /* Print a fatal error message. NAME is the text.
219: Also include a system error message based on `errno'. */
220:
221: int
222: pfatal_with_name (name)
223: {
224: fprintf (stderr, "cc1: ");
225: perror (name);
226: exit (35);
227: }
228:
229: void
230: fatal (s)
231: char *s;
232: {
233: yyerror (s, 0);
234: exit (34);
235: }
236:
237: /* Called when the start of a function definition is parsed,
238: this function prints on stderr the name of the function. */
239:
240: void
241: announce_function (decl)
242: tree decl;
243: {
244: if (! quiet_flag)
245: {
246: fprintf (stderr, " %s", IDENTIFIER_POINTER (DECL_NAME (decl)));
247: fflush (stderr);
248: }
249: }
250:
251: static tree last_error_function;
252:
253: /* Report an error at the current line number.
254: S and V are a string and an arg for `printf'. */
255:
256: void
257: yyerror (s, v)
258: char *s;
259: int v; /* @@also used as pointer */
260: {
261: yylineerror (lineno, s, v);
262: }
263:
264: /* Report an error at line LINE.
265: S and V are a string and an arg for `printf'. */
266:
267: yylineerror (line, s, v)
268: int line;
269: char *s;
270: int v;
271: {
272: count_error (0);
273:
274: if (last_error_function != current_function_decl)
275: {
276: fprintf (stderr, "In function %s:\n",
277: IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
278: last_error_function = current_function_decl;
279: }
280: fprintf (stderr, "%s:%d: ", input_filename, line);
281: fprintf (stderr, s, v);
282: fprintf (stderr, "\n");
283: }
284:
285: /* Report a warning at the current line number.
286: S and V are a string and an arg for `printf'. */
287:
288: void
289: warning (s, v)
290: char *s;
291: int v; /* @@also used as pointer */
292: {
293: warning_with_line (lineno, s, v);
294: }
295:
296: /* Report a warning at line LINE.
297: S and V are a string and an arg for `printf'. */
298:
299: warning_with_line (line, s, v)
300: int line;
301: char *s;
302: int v;
303: {
304: if (count_error (1) == 0)
305: return;
306:
307: if (last_error_function != current_function_decl)
308: {
309: fprintf (stderr, "In function %s:\n",
310: IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
311: last_error_function = current_function_decl;
312: }
313: fprintf (stderr, "%s:%d: ", input_filename, line);
314:
315: fprintf (stderr, "warning: ");
316: fprintf (stderr, s, v);
317: fprintf (stderr, "\n");
318: }
319:
320: /* When `malloc.c' is compiled with `rcheck' defined,
321: it calls this function to report clobberage. */
322:
323: botch (s)
324: {
325: abort ();
326: }
327:
328: /* Same as `malloc' but report error if no memory available. */
329:
330: xmalloc (size)
331: unsigned size;
332: {
333: register int value = (int) malloc (size);
334: if (value == 0)
335: fatal ("Virtual memory exhausted.");
336: return value;
337: }
338:
339: /* Same as `realloc' but report error if no memory available. */
340:
341: int
342: xrealloc (ptr, size)
343: char *ptr;
344: int size;
345: {
346: int result = realloc (ptr, size);
347: if (!result)
348: abort ();
349: return result;
350: }
351:
352: /* Return the logarithm of X, base 2, considering X unsigned,
353: if X is a power of 2. Otherwise, returns -1. */
354:
355: int
356: exact_log2 (x)
357: register unsigned int x;
358: {
359: register int log = 0;
360: for (log = 0; log < HOST_BITS_PER_INT; log++)
361: if (x == (1 << log))
362: return log;
363: return -1;
364: }
365:
366: /* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
367: If X is 0, return -1. */
368:
369: int
370: floor_log2 (x)
371: register unsigned int x;
372: {
373: register int log = 0;
374: for (log = 0; log < HOST_BITS_PER_INT; log++)
375: if ((x & ((-1) << log)) == 0)
376: return log - 1;
377: return HOST_BITS_PER_INT - 1;
378: }
379:
380: /* Compile an entire file of output from cpp, named NAME.
381: Write a file of assembly output and various debugging dumps. */
382:
383: static void
384: compile_file (name)
385: char *name;
386: {
387: tree globals;
388: int start_time;
389: int dump_base_name_length = strlen (dump_base_name);
390:
391: parse_time = 0;
392: varconst_time = 0;
393: expand_time = 0;
394: jump_time = 0;
395: cse_time = 0;
396: loop_time = 0;
397: flow_time = 0;
398: combine_time = 0;
399: local_alloc_time = 0;
400: global_alloc_time = 0;
401: final_time = 0;
402: symout_time = 0;
403: dump_time;
404:
405: /* Open input file. */
406:
407: finput = fopen (name, "r");
408: if (finput == 0)
409: pfatal_with_name (name);
410:
411: /* Initialize data in various passes. */
412:
413: init_tree ();
414: init_lex ();
415: init_rtl ();
416: init_decl_processing ();
417: init_optabs ();
418:
419: /* If tree dump desired, open the output file. */
420: if (tree_dump)
421: {
422: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
423: strcpy (dumpname, dump_base_name);
424: strcat (dumpname, ".tree");
425: tree_dump_file = fopen (dumpname, "w");
426: if (tree_dump_file == 0)
427: pfatal_with_name (dumpname);
428: }
429:
430: /* If rtl dump desired, open the output file. */
431: if (rtl_dump)
432: {
433: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
434: strcpy (dumpname, dump_base_name);
435: strcat (dumpname, ".rtl");
436: rtl_dump_file = fopen (dumpname, "w");
437: if (rtl_dump_file == 0)
438: pfatal_with_name (dumpname);
439: }
440:
441: /* If jump_opt dump desired, open the output file. */
442: if (jump_opt_dump)
443: {
444: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
445: strcpy (dumpname, dump_base_name);
446: strcat (dumpname, ".jump");
447: jump_opt_dump_file = fopen (dumpname, "w");
448: if (jump_opt_dump_file == 0)
449: pfatal_with_name (dumpname);
450: }
451:
452: /* If cse dump desired, open the output file. */
453: if (cse_dump)
454: {
455: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
456: strcpy (dumpname, dump_base_name);
457: strcat (dumpname, ".cse");
458: cse_dump_file = fopen (dumpname, "w");
459: if (cse_dump_file == 0)
460: pfatal_with_name (dumpname);
461: }
462:
463: /* If loop dump desired, open the output file. */
464: if (loop_dump)
465: {
466: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
467: strcpy (dumpname, dump_base_name);
468: strcat (dumpname, ".loop");
469: loop_dump_file = fopen (dumpname, "w");
470: if (loop_dump_file == 0)
471: pfatal_with_name (dumpname);
472: }
473:
474: /* If flow dump desired, open the output file. */
475: if (flow_dump)
476: {
477: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
478: strcpy (dumpname, dump_base_name);
479: strcat (dumpname, ".flow");
480: flow_dump_file = fopen (dumpname, "w");
481: if (flow_dump_file == 0)
482: pfatal_with_name (dumpname);
483: }
484:
485: /* If combine dump desired, open the output file. */
486: if (combine_dump)
487: {
488: register char *dumpname = (char *) xmalloc (dump_base_name_length + 10);
489: strcpy (dumpname, dump_base_name);
490: strcat (dumpname, ".combine");
491: combine_dump_file = fopen (dumpname, "w");
492: if (combine_dump_file == 0)
493: pfatal_with_name (dumpname);
494: }
495:
496: /* If local_reg dump desired, open the output file. */
497: if (local_reg_dump)
498: {
499: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
500: strcpy (dumpname, dump_base_name);
501: strcat (dumpname, ".lreg");
502: local_reg_dump_file = fopen (dumpname, "w");
503: if (local_reg_dump_file == 0)
504: pfatal_with_name (dumpname);
505: }
506:
507: /* If global_reg dump desired, open the output file. */
508: if (global_reg_dump)
509: {
510: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
511: strcpy (dumpname, dump_base_name);
512: strcat (dumpname, ".greg");
513: global_reg_dump_file = fopen (dumpname, "w");
514: if (global_reg_dump_file == 0)
515: pfatal_with_name (dumpname);
516: }
517:
518: /* Open assembler code output file. */
519:
520: {
521: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
522: strcpy (dumpname, dump_base_name);
523: strcat (dumpname, ".s");
524: asm_out_file = fopen (asm_file_name ? asm_file_name : dumpname, "w");
525: if (asm_out_file == 0)
526: pfatal_with_name (asm_file_name ? asm_file_name : dumpname);
527: }
528:
529: input_filename = name;
530:
531: /* the beginning of the file is a new line; check for # */
532: /* With luck, we discover the real source file's name from that
533: and put it in input_filename. */
534: check_newline ();
535:
536: /* If GDB symbol table desired, open the GDB symbol output file. */
537: if (write_symbols == 1)
538: {
539: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
540: strcpy (dumpname, dump_base_name);
541: strcat (dumpname, ".sym");
542: if (sym_file_name == 0)
543: sym_file_name = dumpname;
544: symout_init (sym_file_name, asm_out_file, input_filename);
545: }
546:
547: /* If dbx symbol table desired, initialize writing it
548: and output the predefined types. */
549: if (write_symbols == 2)
550: dbxout_init (asm_out_file, input_filename);
551:
552: /* Initialize yet another pass. */
553:
554: init_final (input_filename);
555:
556: start_time = gettime ();
557:
558: /* Call the parser, which parses the entire file
559: (calling rest_of_compilation for each function). */
560:
561: yyparse ();
562:
563: /* Compilation is now finished except for writing
564: what's left of the symbol table output. */
565:
566: parse_time += gettime () - start_time;
567:
568: globals = getdecls ();
569:
570: /* Do dbx symbols */
571: if (write_symbols == 2)
572: TIMEVAR (symout_time,
573: {
574: dbxout_tags (gettags ());
575: dbxout_types (get_permanent_types ());
576: });
577:
578: /* Do gdb symbols */
579: if (write_symbols == 1)
580: TIMEVAR (symout_time,
581: {
582: struct stat statbuf;
583: fstat (fileno (finput), &statbuf);
584: symout_types (get_permanent_types ());
585: symout_top_blocks (globals, gettags ());
586: symout_finish (name, statbuf.st_ctime);
587: });
588:
589: /* Close non-debugging input and output files. */
590:
591: fclose (finput);
592: fclose (asm_out_file);
593:
594: if (!quiet_flag)
595: fprintf (stderr,"\n");
596:
597: /* Dump the global nodes and close the tree dump file. */
598: if (tree_dump)
599: {
600: dump_tree (tree_dump_file, globals);
601: fclose (tree_dump_file);
602: }
603:
604: /* Close all other dump files. */
605:
606: if (rtl_dump)
607: fclose (rtl_dump_file);
608:
609: if (jump_opt_dump)
610: fclose (jump_opt_dump_file);
611:
612: if (cse_dump)
613: fclose (cse_dump_file);
614:
615: if (loop_dump)
616: fclose (loop_dump_file);
617:
618: if (flow_dump)
619: fclose (flow_dump_file);
620:
621: if (combine_dump)
622: {
623: dump_combine_total_stats (combine_dump_file);
624: fclose (combine_dump_file);
625: }
626:
627: if (local_reg_dump)
628: fclose (local_reg_dump_file);
629:
630: if (global_reg_dump)
631: fclose (global_reg_dump_file);
632:
633: /* Print the times. */
634:
635: if (! quiet_flag)
636: {
637: print_time ("parse", parse_time);
638: print_time ("expand", expand_time);
639: print_time ("jump", jump_time);
640: print_time ("cse", cse_time);
641: print_time ("loop", loop_time);
642: print_time ("flow", flow_time);
643: print_time ("combine", combine_time);
644: print_time ("local-alloc", local_alloc_time);
645: print_time ("global-alloc", global_alloc_time);
646: print_time ("final", final_time);
647: print_time ("varconst", varconst_time);
648: print_time ("symout", symout_time);
649: print_time ("dump", dump_time);
650: }
651: }
652:
653: /* This is called from finish_function (within yyparse)
654: after each top-level definition is parsed, and from
655: finish_decl (also within yyparse) for each other top-level declaration.
656: It is supposed to compile that function or variable
657: and output the assembler code for it.
658: After we return, the tree storage is freed. */
659:
660: void
661: rest_of_compilation (decl, top_level)
662: tree decl;
663: int top_level;
664: {
665: register rtx insns;
666: int start_time = gettime ();
667: int tem;
668:
669: /* Declarations of variables, and of functions defined elsewhere. */
670:
671: if ((TREE_CODE (decl) == VAR_DECL
672: || (TREE_CODE (decl) == FUNCTION_DECL
673: && DECL_INITIAL (decl) == 0))
674: && (TREE_STATIC (decl) || TREE_EXTERNAL (decl)))
675: {
676: TIMEVAR (varconst_time,
677: {
678: assemble_variable (decl, top_level);
679: if (write_symbols == 2)
680: dbxout_symbol (decl, 0);
681: });
682: }
683:
684: /* Function definitions are the real work
685: (all the rest of this function). */
686:
687: else if (TREE_CODE (decl) == FUNCTION_DECL
688: && DECL_INITIAL (decl))
689: {
690: /* Dump the function's tree if we are dumping trees. */
691:
692: if (tree_dump)
693: TIMEVAR (dump_time,
694: dump_tree (tree_dump_file, decl));
695:
696: /* Output some preliminaries for assembler. */
697:
698: TIMEVAR (varconst_time, assemble_function (decl));
699:
700: /* Generate rtl code for this function (see stmt.c, expr.c). */
701:
702: TIMEVAR (expand_time,
703: {
704: init_emit (write_symbols);
705: insns = expand_function (decl, !optimize);
706: });
707:
708: /* Dump the rtl code if we are dumping rtl. */
709:
710: if (rtl_dump)
711: TIMEVAR (dump_time,
712: {
713: fprintf (rtl_dump_file, "\n;; Function %s\n\n",
714: IDENTIFIER_POINTER (DECL_NAME (decl)));
715: print_rtl (rtl_dump_file, insns);
716: fflush (rtl_dump_file);
717: });
718:
719: if (rtl_dump_and_exit)
720: goto exit_rest_of_compilation;
721:
722: /* Do jump optimization the first time, if -opt. */
723:
724: if (optimize)
725: TIMEVAR (jump_time, jump_optimize (insns, 0));
726:
727: /* Dump rtl code after jump, if we are doing that. */
728:
729: if (jump_opt_dump)
730: TIMEVAR (dump_time,
731: {
732: fprintf (jump_opt_dump_file, "\n;; Function %s\n\n",
733: IDENTIFIER_POINTER (DECL_NAME (decl)));
734: print_rtl (jump_opt_dump_file, insns);
735: fflush (jump_opt_dump_file);
736: });
737:
738: /* Perform common subexpression elimination.
739: Nonzero value from `cse_main' means that jumps were simplified
740: and some code may now be unreachable, so do
741: jump optimization again. */
742:
743: if (optimize)
744: {
745: TIMEVAR (cse_time, reg_scan (insns, max_reg_num ()));
746:
747: TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num ()));
748:
749: if (tem)
750: TIMEVAR (jump_time, jump_optimize (insns, 0));
751: }
752:
753: /* Dump rtl code after cse, if we are doing that. */
754:
755: if (cse_dump)
756: TIMEVAR (dump_time,
757: {
758: fprintf (cse_dump_file, "\n;; Function %s\n\n",
759: IDENTIFIER_POINTER (DECL_NAME (decl)));
760: print_rtl (cse_dump_file, insns);
761: fflush (cse_dump_file);
762: });
763:
764: /* Move constant computations out of loops. */
765:
766: if (optimize)
767: {
768: TIMEVAR (loop_time, loop_optimize (insns, max_reg_num ()));
769: }
770:
771: /* Dump rtl code after loop opt, if we are doing that. */
772:
773: if (loop_dump)
774: TIMEVAR (dump_time,
775: {
776: fprintf (loop_dump_file, "\n;; Function %s\n\n",
777: IDENTIFIER_POINTER (DECL_NAME (decl)));
778: print_rtl (loop_dump_file, insns);
779: fflush (loop_dump_file);
780: });
781:
782: /* Now we choose between stupid (pcc-like) register allocation
783: (if we got the -noreg switch and not -opt)
784: and smart register allocation. */
785:
786: if (optimize) /* Stupid allocation probably won't work */
787: obey_regdecls = 0; /* if optimizations being done. */
788:
789: /* Print function header into flow dump now
790: because doing the flow analysis makes some of the dump. */
791:
792: if (flow_dump)
793: TIMEVAR (dump_time,
794: {
795: fprintf (flow_dump_file, "\n;; Function %s\n\n",
796: IDENTIFIER_POINTER (DECL_NAME (decl)));
797: });
798:
799: if (obey_regdecls)
800: {
801: TIMEVAR (flow_time,
802: {
803: regclass (insns, max_reg_num ());
804: stupid_life_analysis (insns, max_reg_num (),
805: flow_dump_file);
806: });
807: }
808: else
809: {
810: /* Do control and data flow analysis,
811: and write some of the results to dump file. */
812:
813: TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (),
814: flow_dump_file));
815: }
816:
817: /* Dump rtl after flow analysis. */
818:
819: if (flow_dump)
820: TIMEVAR (dump_time,
821: {
822: print_rtl (flow_dump_file, insns);
823: fflush (flow_dump_file);
824: });
825:
826: /* If -opt, try combining insns through substitution. */
827:
828: if (optimize)
829: TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
830:
831: /* Dump rtl code after insn combination. */
832:
833: if (combine_dump)
834: TIMEVAR (dump_time,
835: {
836: fprintf (combine_dump_file, "\n;; Function %s\n\n",
837: IDENTIFIER_POINTER (DECL_NAME (decl)));
838: dump_combine_stats (combine_dump_file);
839: print_rtl (combine_dump_file, insns);
840: fflush (combine_dump_file);
841: });
842:
843: /* Unless we did stupid register allocation,
844: allocate pseudo-regs that are used only within 1 basic block. */
845:
846: if (!obey_regdecls)
847: TIMEVAR (local_alloc_time,
848: {
849: regclass (insns, max_reg_num ());
850: local_alloc ();
851: });
852:
853: /* Dump rtl code after allocating regs within basic blocks. */
854:
855: if (local_reg_dump)
856: TIMEVAR (dump_time,
857: {
858: fprintf (local_reg_dump_file, "\n;; Function %s\n\n",
859: IDENTIFIER_POINTER (DECL_NAME (decl)));
860: dump_flow_info (local_reg_dump_file);
861: dump_local_alloc (local_reg_dump_file);
862: print_rtl (local_reg_dump_file, insns);
863: fflush (local_reg_dump_file);
864: });
865:
866: if (global_reg_dump)
867: TIMEVAR (dump_time,
868: fprintf (global_reg_dump_file, "\n;; Function %s\n\n",
869: IDENTIFIER_POINTER (DECL_NAME (decl))));
870:
871: /* Unless we did stupid register allocation,
872: allocate remaining pseudo-regs, then do the reload pass
873: fixing up any insns that are invalid. */
874:
875: TIMEVAR (global_alloc_time,
876: {
877: if (!obey_regdecls)
878: global_alloc (global_reg_dump ? global_reg_dump_file : 0);
879: else
880: reload (insns, 0,
881: global_reg_dump ? global_reg_dump_file : 0);
882: });
883:
884: if (global_reg_dump)
885: TIMEVAR (dump_time,
886: {
887: dump_global_regs (global_reg_dump_file);
888: print_rtl (global_reg_dump_file, insns);
889: fflush (global_reg_dump_file);
890: });
891:
892: /* One more attempt to remove jumps to .+1
893: left by dead-store-elimination.
894: Also do cross-jumping this time. */
895:
896: if (optimize)
897: TIMEVAR (jump_time, jump_optimize (insns, 1));
898:
899: /* Now turn the rtl into assembler code. */
900:
901: TIMEVAR (final_time,
902: {
903: final (insns, asm_out_file,
904: IDENTIFIER_POINTER (DECL_NAME (decl)),
905: write_symbols, optimize);
906: fflush (asm_out_file);
907: });
908:
909: /* Write GDB symbols if requested */
910:
911: if (write_symbols == 1)
912: TIMEVAR (symout_time,
913: {
914: symout_types (get_permanent_types ());
915: symout_types (get_temporary_types ());
916:
917: DECL_BLOCK_SYMTAB_ADDRESS (decl)
918: = symout_function (DECL_INITIAL (decl),
919: DECL_ARGUMENTS (decl), 0);
920: });
921:
922: /* Write DBX symbols if requested */
923:
924: if (write_symbols == 2)
925: TIMEVAR (symout_time, dbxout_function (decl));
926: }
927:
928: exit_rest_of_compilation:
929:
930: /* The parsing time is all the time spent in yyparse
931: *except* what is spent in this function. */
932:
933: parse_time -= gettime () - start_time;
934: }
935:
936: /* Entry point of cc1. Decode command args, then call compile_file.
937: Exit code is 34 if fatal error, else 33 if have error messages,
938: else 1 if have warnings, else 0. */
939:
940: int
941: main (argc, argv, envp)
942: int argc;
943: char **argv;
944: char **envp;
945: {
946: register int i;
947: char *filename;
948:
949: target_flags = 0;
950: set_target_switch ("");
951:
952: for (i = 1; i < argc; i++)
953: if (argv[i][0] == '-')
954: {
955: register char *str = argv[i] + 1;
956: if (str[0] == 'Y')
957: str++;
958:
959: if (str[0] == 'm')
960: set_target_switch (&str[1]);
961: else if (!strcmp (str, "dumpbase"))
962: {
963: dump_base_name = argv[++i];
964: }
965: else if (str[0] == 'd')
966: {
967: register char *p = &str[1];
968: while (*p)
969: switch (*p++)
970: {
971: case 'c':
972: combine_dump = 1;
973: break;
974: case 'f':
975: flow_dump = 1;
976: break;
977: case 'g':
978: global_reg_dump = 1;
979: break;
980: case 'j':
981: jump_opt_dump = 1;
982: break;
983: case 'l':
984: local_reg_dump = 1;
985: break;
986: case 'L':
987: loop_dump = 1;
988: break;
989: case 'r':
990: rtl_dump = 1;
991: break;
992: case 's':
993: cse_dump = 1;
994: break;
995: case 't':
996: tree_dump = 1;
997: break;
998: case 'y':
999: yydebug = 1;
1000: break;
1001: }
1002: }
1003: else if (!strcmp (str, "quiet"))
1004: quiet_flag = 1;
1005: else if (!strcmp (str, "opt"))
1006: optimize = 1;
1007: else if (!strcmp (str, "optforcemem"))
1008: force_mem = 1;
1009: else if (!strcmp (str, "optforceaddr"))
1010: force_addr = 1;
1011: else if (!strcmp (str, "noreg"))
1012: obey_regdecls = 1;
1013: else if (!strcmp (str, "w"))
1014: inhibit_warnings = 1;
1015: else if (!strcmp (str, "g"))
1016: write_symbols = 1;
1017: else if (!strcmp (str, "G"))
1018: write_symbols = 2;
1019: else if (!strcmp (str, "symout"))
1020: {
1021: if (write_symbols == 0)
1022: write_symbols = 1;
1023: sym_file_name = argv[++i];
1024: }
1025: else if (!strcmp (str, "o"))
1026: {
1027: asm_file_name = argv[++i];
1028: }
1029: else
1030: yylineerror (0, "Invalid switch, %s.", argv[i]);
1031: }
1032: else
1033: filename = argv[i];
1034:
1035: if (filename == 0)
1036: fatal ("no input file specified");
1037:
1038: if (dump_base_name == 0)
1039: dump_base_name = filename;
1040: compile_file (filename);
1041:
1042: if (errorcount)
1043: return 33;
1044: else
1045: return (warningcount > 0);
1046: }
1047:
1048: /* Decode -m switches. */
1049:
1050: /* Here is a table, controlled by the tm-...h file, listing each -m switch
1051: and which bits in `target_switches' it should set or clear.
1052: If VALUE is positive, it is bits to set.
1053: If VALUE is negative, -VALUE is bits to clear.
1054: (The sign bit is not used so there is no confusion.) */
1055:
1056: struct {char *name; int value;} target_switches []
1057: = TARGET_SWITCHES;
1058:
1059: /* Decode the switch -mNAME. */
1060:
1061: set_target_switch (name)
1062: char *name;
1063: {
1064: register int j = 0;
1065: for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
1066: if (!strcmp (target_switches[j].name, name))
1067: {
1068: if (target_switches[j].value < 0)
1069: target_flags &= ~-target_switches[j].value;
1070: else
1071: target_flags |= target_switches[j].value;
1072: break;
1073: }
1074: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.