📄 toplev.c
字号:
if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) TIMEVAR (symout_time, { dbxout_finish (asm_out_file, main_input_filename); });#endif#ifdef DWARF_DEBUGGING_INFO if (write_symbols == DWARF_DEBUG) TIMEVAR (symout_time, { dwarfout_finish (); });#endif /* Output some stuff at end of file if nec. */ end_final (main_input_filename);#ifdef ASM_FILE_END ASM_FILE_END (asm_out_file);#endif after_finish_compilation: /* Language-specific end of compilation actions. */ lang_finish (); /* Close the dump files. */ if (flag_gen_aux_info) { fclose (aux_info_file); if (errorcount) unlink (aux_info_file_name); } if (rtl_dump) fclose (rtl_dump_file); if (jump_opt_dump) fclose (jump_opt_dump_file); if (cse_dump) fclose (cse_dump_file); if (loop_dump) fclose (loop_dump_file); if (cse2_dump) fclose (cse2_dump_file); if (flow_dump) fclose (flow_dump_file); if (combine_dump) { dump_combine_total_stats (combine_dump_file); fclose (combine_dump_file); } if (sched_dump) fclose (sched_dump_file); if (local_reg_dump) fclose (local_reg_dump_file); if (global_reg_dump) fclose (global_reg_dump_file); if (sched2_dump) fclose (sched2_dump_file); if (jump2_opt_dump) fclose (jump2_opt_dump_file); if (dbr_sched_dump) fclose (dbr_sched_dump_file);#ifdef STACK_REGS if (stack_reg_dump) fclose (stack_reg_dump_file);#endif /* Close non-debugging input and output files. Take special care to note whether fclose returns an error, since the pages might still be on the buffer chain while the file is open. */ fclose (finput); if (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0) fatal_io_error (asm_file_name); /* Print the times. */ if (! quiet_flag) { fprintf (stderr,"\n"); print_time ("parse", parse_time); print_time ("integration", integration_time); print_time ("jump", jump_time); print_time ("cse", cse_time); print_time ("loop", loop_time); print_time ("cse2", cse2_time); print_time ("flow", flow_time); print_time ("combine", combine_time); print_time ("sched", sched_time); print_time ("local-alloc", local_alloc_time); print_time ("global-alloc", global_alloc_time); print_time ("sched2", sched2_time); print_time ("dbranch", dbr_sched_time); print_time ("shorten-branch", shorten_branch_time); print_time ("stack-reg", stack_reg_time); print_time ("final", final_time); print_time ("varconst", varconst_time); print_time ("symout", symout_time); print_time ("dump", dump_time); }}/* This is called from various places for FUNCTION_DECL, VAR_DECL, and TYPE_DECL nodes. This does nothing for local (non-static) variables. Otherwise, it sets up the RTL and outputs any assembler code (label definition, storage allocation and initialization). DECL is the declaration. If ASMSPEC is nonzero, it specifies the assembler symbol name to be used. TOP_LEVEL is nonzero if this declaration is not within a function. */voidrest_of_decl_compilation (decl, asmspec, top_level, at_end) tree decl; char *asmspec; int top_level; int at_end;{ /* Declarations of variables, and of functions defined elsewhere. */ /* Forward declarations for nested functions are not "external", but we need to treat them as if they were. */ if (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || TREE_CODE (decl) == FUNCTION_DECL) TIMEVAR (varconst_time, { make_decl_rtl (decl, asmspec, top_level); /* For a user-invisible decl that should be replaced by its value when used, don't output anything. */ if (! (TREE_CODE (decl) == VAR_DECL && DECL_IGNORED_P (decl) && TREE_READONLY (decl) && DECL_INITIAL (decl) != 0)) /* Don't output anything when a tentative file-scope definition is seen. But at end of compilation, do output code for them. */ if (! (! at_end && top_level && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node || DECL_IGNORED_P (decl)))) assemble_variable (decl, top_level, at_end); }); else if (DECL_REGISTER (decl) && asmspec != 0) { if (decode_reg_name (asmspec) >= 0) { DECL_RTL (decl) = 0; make_decl_rtl (decl, asmspec, top_level); } else error ("invalid register name `%s' for register variable", asmspec); }#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) && TREE_CODE (decl) == TYPE_DECL) TIMEVAR (symout_time, dbxout_symbol (decl, 0));#endif#ifdef SDB_DEBUGGING_INFO else if (write_symbols == SDB_DEBUG && top_level && TREE_CODE (decl) == TYPE_DECL) TIMEVAR (symout_time, sdbout_symbol (decl, 0));#endif}/* Called after finishing a record, union or enumeral type. */voidrest_of_type_compilation (type, toplev) tree type; int toplev;{#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev));#endif#ifdef SDB_DEBUGGING_INFO if (write_symbols == SDB_DEBUG) TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev));#endif}/* This is called from finish_function (within yyparse) after each top-level definition is parsed. It is supposed to compile that function or variable and output the assembler code for it. After we return, the tree storage is freed. */voidrest_of_compilation (decl) tree decl;{ register rtx insns; int start_time = get_run_time (); int tem; /* Nonzero if we have saved the original DECL_INITIAL of the function, to be restored after we finish compiling the function (for use when compiling inline calls to this function). */ tree saved_block_tree = 0; /* Likewise, for DECL_ARGUMENTS. */ tree saved_arguments = 0; int failure = 0; /* If we are reconsidering an inline function at the end of compilation, skip the stuff for making it inline. */ if (DECL_SAVED_INSNS (decl) == 0) { int specd = DECL_INLINE (decl); char *lose; /* If requested, consider whether to make this function inline. */ if (specd || flag_inline_functions) TIMEVAR (integration_time, { lose = function_cannot_inline_p (decl); if (lose) { if (warn_inline && specd) warning_with_decl (decl, lose); DECL_INLINE (decl) = 0; } else DECL_INLINE (decl) = 1; }); insns = get_insns (); /* Dump the rtl code if we are dumping rtl. */ if (rtl_dump) TIMEVAR (dump_time, { fprintf (rtl_dump_file, "\n;; Function %s\n\n", IDENTIFIER_POINTER (DECL_NAME (decl))); if (DECL_SAVED_INSNS (decl)) fprintf (rtl_dump_file, ";; (integrable)\n\n"); print_rtl (rtl_dump_file, insns); fflush (rtl_dump_file); }); /* If function is inline, and we don't yet know whether to compile it by itself, defer decision till end of compilation. finish_compilation will call rest_of_compilation again for those functions that need to be output. */ if (DECL_INLINE (decl) && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl) && ! flag_keep_inline_functions) || DECL_EXTERNAL (decl))) {#ifdef DWARF_DEBUGGING_INFO /* Generate the DWARF info for the "abstract" instance of a function which we may later generate inlined and/or out-of-line instances of. */ if (write_symbols == DWARF_DEBUG) { set_decl_abstract_flags (decl, 1); TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); set_decl_abstract_flags (decl, 0); }#endif TIMEVAR (integration_time, save_for_inline_nocopy (decl)); goto exit_rest_of_compilation; } /* If we have to compile the function now, save its rtl and subdecls so that its compilation will not affect what others get. */ if (DECL_INLINE (decl)) {#ifdef DWARF_DEBUGGING_INFO /* Generate the DWARF info for the "abstract" instance of a function which we will generate an out-of-line instance of almost immediately (and which we may also later generate various inlined instances of). */ if (write_symbols == DWARF_DEBUG) { set_decl_abstract_flags (decl, 1); TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); set_decl_abstract_flags (decl, 0); }#endif saved_block_tree = DECL_INITIAL (decl); saved_arguments = DECL_ARGUMENTS (decl); TIMEVAR (integration_time, save_for_inline_copying (decl)); } } TREE_ASM_WRITTEN (decl) = 1; /* Now that integrate will no longer see our rtl, we need not distinguish between the return value of this function and the return value of called functions. */ rtx_equal_function_value_matters = 0; /* Don't return yet if -Wreturn-type; we need to do jump_optimize. */ if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type) { goto exit_rest_of_compilation; } /* From now on, allocate rtl in current_obstack, not in saveable_obstack. Note that that may have been done above, in save_for_inline_copying. The call to resume_temporary_allocation near the end of this function goes back to the usual state of affairs. */ rtl_in_current_obstack ();#ifdef FINALIZE_PIC /* If we are doing position-independent code generation, now is the time to output special prologues and epilogues. We do not want to do this earlier, because it just clutters up inline functions with meaningless insns. */ if (flag_pic) FINALIZE_PIC;#endif insns = get_insns (); /* Copy any shared structure that should not be shared. */ unshare_all_rtl (insns); /* Instantiate all virtual registers. */ instantiate_virtual_regs (current_function_decl, get_insns ()); /* See if we have allocated stack slots that are not directly addressable. If so, scan all the insns and create explicit address computation for all references to such slots. *//* fixup_stack_slots (); */ /* Do jump optimization the first time, if -opt. Also do it if -W, but in that case it doesn't change the rtl code, it only computes whether control can drop off the end of the function. */ if (optimize > 0 || extra_warnings || warn_return_type /* If function is `volatile', we should warn if it tries to return. */ || TREE_THIS_VOLATILE (decl)) { TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0)); TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 1)); } /* Now is when we stop if -fsyntax-only and -Wreturn-type. */ if (rtl_dump_and_exit || flag_syntax_only) goto exit_rest_of_compilation; /* Dump rtl code after jump, if we are doing that. */ if (jump_opt_dump) TIMEVAR (dump_time, { fprintf (jump_opt_dump_file, "\n;; Function %s\n\n", IDENTIFIER_POINTER (DECL_NAME (decl))); print_rtl (jump_opt_dump_file, insns); fflush (jump_opt_dump_file); }); /* Perform common subexpression elimination. Nonzero value from `cse_main' means that jumps were simplified and some code may now be unreachable, so do jump optimization again. */ if (cse_dump) TIMEVAR (dump_time, { fprintf (cse_dump_file, "\n;; Function %s\n\n", IDENTIFIER_POINTER (DECL_NAME (decl))); }); if (optimize > 0) { TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1)); if (flag_thread_jumps) /* Hacks by tiemann & kenner. */ TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0)); TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (), 0, cse_dump_file)); TIMEVAR (cse_time, delete_dead_from_cse (insns, max_reg_num ())); if (tem) TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 0)); } /* Dump rtl code after cse, if we are doing that. */ if (cse_dump) TIMEVAR (dump_time, { print_rtl (cse_dump_file, insns); fflush (cse_dump_file); }); if (loop_dump) TIMEVAR (dump_time, { fprintf (loop_dump_file, "\n;; Function %s\n\n", IDENTIFIER_POINTER (DECL_NAME (decl))); }); /* Move constant computations out of loops. */ if (optimize > 0) { TIMEVAR (loop_time, { loop_optimize (insns, loop_dump_file); }); } /* Dump rtl code after loop opt, if we are doing that. */ if (loop_dump) TIMEVAR (dump_time, { print_rtl (loop_dump_file, insns); fflush (loop_dump_file); }); if (cse2_dump) TIMEVAR (dump_time, { fprintf (cse2_dump_file, "\n;; Function %s\n\n", IDENTIFIER_POINTER (DECL_NAME (decl))); }); if (optimize > 0 && flag_rerun_cse_after_loop) { TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0)); TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (), 1, cse2_dump_file)); if (tem) TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 0)); } if (optimize > 0 && flag_thread_jumps) /* This pass of jump threading straightens out code that was kinked by loop optimization. */ TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0)); /* Dump rtl code after cse, if we are doing that. */ if (cse2_dump) TIMEVAR (dump_time, { print_rtl (cse2_dump_file, insns); fflush (cse2_dump_file); }); /* We are no longer anticipating cse in this function, at least. */ cse_not_expected = 1; /* Now we choose between stupid (pcc-like) register allocation (if we got the -noreg switch and not -opt) and smart register allocation. */ if
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -