📄 passes.texi
字号:
@c markers: CROSSREF BUG TODO@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,@c 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software@c Foundation, Inc.@c This is part of the GCC manual.@c For copying conditions, see the file gcc.texi.@node Passes@chapter Passes and Files of the Compiler@cindex passes and files of the compiler@cindex files and passes of the compiler@cindex compiler passes and filesThis chapter is dedicated to giving an overview of the optimization andcode generation passes of the compiler. In the process, it describessome of the language front end interface, though this description is nowhere near complete.@menu* Parsing pass:: The language front end turns text into bits.* Gimplification pass:: The bits are turned into something we can optimize.* Pass manager:: Sequencing the optimization passes.* Tree-SSA passes:: Optimizations on a high-level representation.* RTL passes:: Optimizations on a low-level representation.@end menu@node Parsing pass@section Parsing pass@cindex GENERIC@findex lang_hooks.parse_fileThe language front end is invoked only once, via@code{lang_hooks.parse_file}, to parse the entire input. The languagefront end may use any intermediate language representation deemedappropriate. The C front end uses GENERIC trees (CROSSREF), plusa double handful of language specific tree codes defined in@file{c-common.def}. The Fortran front end uses a completely differentprivate representation.@cindex GIMPLE@cindex gimplification@cindex gimplifier@cindex language-independent intermediate representation@cindex intermediate representation lowering@cindex lowering, language-dependent intermediate representationAt some point the front end must translate the representation used in thefront end to a representation understood by the language-independentportions of the compiler. Current practice takes one of two forms.The C front end manually invokes the gimplifier (CROSSREF) on each function,and uses the gimplifier callbacks to convert the language-specific treenodes directly to GIMPLE (CROSSREF) before passing the function off tobe compiled.The Fortran front end converts from a private representation to GENERIC,which is later lowered to GIMPLE when the function is compiled. Whichroute to choose probably depends on how well GENERIC (plus extensions)can be made to match up with the source language and necessary parsingdata structures.BUG: Gimplification must occur before nested function lowering,and nested function lowering must be done by the front end beforepassing the data off to cgraph.TODO: Cgraph should control nested function lowering. It wouldonly be invoked when it is certain that the outer-most functionis used.TODO: Cgraph needs a gimplify_function callback. It should beinvoked when (1) it is certain that the function is used, (2)warning flags specified by the user require some amount ofcompilation in order to honor, (3) the language indicates thatsemantic analysis is not complete until gimplification occurs.Hum@dots{} this sounds overly complicated. Perhaps we should justhave the front end gimplify always; in most cases it's only onefunction call.The front end needs to pass all function definitions and top leveldeclarations off to the middle-end so that they can be compiled andemitted to the object file. For a simple procedural language, it isusually most convenient to do this as each top level declaration ordefinition is seen. There is also a distinction to be made betweengenerating functional code and generating complete debug information.The only thing that is absolutely required for functional code is thatfunction and data @emph{definitions} be passed to the middle-end. Forcomplete debug information, function, data and type declarationsshould all be passed as well.@findex rest_of_decl_compilation@findex rest_of_type_compilation@findex cgraph_finalize_functionIn any case, the front end needs each complete top-level function ordata declaration, and each data definition should be passed to@code{rest_of_decl_compilation}. Each complete type definition shouldbe passed to @code{rest_of_type_compilation}. Each function definitionshould be passed to @code{cgraph_finalize_function}.TODO: I know rest_of_compilation currently has all sorts ofrtl-generation semantics. I plan to move all code generationbits (both tree and rtl) to compile_function. Should we hidecgraph from the front ends and move back to rest_of_compilationas the official interface? Possibly we should rename all threeinterfaces such that the names match in some meaningful way andthat is more descriptive than "rest_of".The middle-end will, at its option, emit the function and datadefinitions immediately or queue them for later processing.@node Gimplification pass@section Gimplification pass@cindex gimplification@cindex GIMPLE@dfn{Gimplification} is a whimsical term for the process of convertingthe intermediate representation of a function into the GIMPLE language(CROSSREF). The term stuck, and so words like ``gimplification'',``gimplify'', ``gimplifier'' and the like are sprinkled throughout thissection of code.@cindex GENERICWhile a front end may certainly choose to generate GIMPLE directly ifit chooses, this can be a moderately complex process unless theintermediate language used by the front end is already fairly simple.Usually it is easier to generate GENERIC trees plus extensionsand let the language-independent gimplifier do most of the work.@findex gimplify_function_tree@findex gimplify_expr@findex lang_hooks.gimplify_exprThe main entry point to this pass is @code{gimplify_function_tree}located in @file{gimplify.c}. From here we process the entirefunction gimplifying each statement in turn. The main workhorsefor this pass is @code{gimplify_expr}. Approximately everythingpasses through here at least once, and it is from here that weinvoke the @code{lang_hooks.gimplify_expr} callback.The callback should examine the expression in question and return@code{GS_UNHANDLED} if the expression is not a language specificconstruct that requires attention. Otherwise it should alter theexpression in some way to such that forward progress is made towardproducing valid GIMPLE@. If the callback is certain that thetransformation is complete and the expression is valid GIMPLE, itshould return @code{GS_ALL_DONE}. Otherwise it should return@code{GS_OK}, which will cause the expression to be processed again.If the callback encounters an error during the transformation (becausethe front end is relying on the gimplification process to finishsemantic checks), it should return @code{GS_ERROR}.@node Pass manager@section Pass managerThe pass manager is located in @file{passes.c}, @file{tree-optimize.c}and @file{tree-pass.h}.Its job is to run all of the individual passes in the correct order,and take care of standard bookkeeping that applies to every pass.The theory of operation is that each pass defines a structure thatrepresents everything we need to know about that pass---when itshould be run, how it should be run, what intermediate languageform or on-the-side data structures it needs. We register the passto be run in some particular order, and the pass manager arrangesfor everything to happen in the correct order.The actuality doesn't completely live up to the theory at present.Command-line switches and @code{timevar_id_t} enumerations must stillbe defined elsewhere. The pass manager validates constraints but doesnot attempt to (re-)generate data structures or lower intermediatelanguage form based on the requirements of the next pass. Nevertheless,what is present is useful, and a far sight better than nothing at all.TODO: describe the global variables set up by the pass manager,and a brief description of how a new pass should use it.I need to look at what info rtl passes use first@enddots{}@node Tree-SSA passes@section Tree-SSA passesThe following briefly describes the tree optimization passes that arerun after gimplification and what source files they are located in.@itemize @bullet@item Remove useless statementsThis pass is an extremely simple sweep across the gimple code in whichwe identify obviously dead code and remove it. Here we do things likesimplify @code{if} statements with constant conditions, removeexception handling constructs surrounding code that obviously cannotthrow, remove lexical bindings that contain no variables, and otherassorted simplistic cleanups. The idea is to get rid of the obviousstuff quickly rather than wait until later when it's more work to getrid of it. This pass is located in @file{tree-cfg.c} and described by@code{pass_remove_useless_stmts}.@item Mudflap declaration registrationIf mudflap (@pxref{Optimize Options,,-fmudflap -fmudflapth-fmudflapir,gcc,Using the GNU Compiler Collection (GCC)}) isenabled, we generate code to register some variable declarations withthe mudflap runtime. Specifically, the runtime tracks the lifetimes ofthose variable declarations that have their addresses taken, or whosebounds are unknown at compile time (@code{extern}). This pass generatesnew exception handling constructs (@code{try}/@code{finally}), and somust run before those are lowered. In addition, the pass enqueuesdeclarations of static variables whose lifetimes extend to the entireprogram. The pass is located in @file{tree-mudflap.c} and is describedby @code{pass_mudflap_1}.@item OpenMP loweringIf OpenMP generation (@option{-fopenmp}) is enabled, this pass lowersOpenMP constructs into GIMPLE.Lowering of OpenMP constructs involves creating replacementexpressions for local variables that have been mapped using datasharing clauses, exposing the control flow of most synchronizationdirectives and adding region markers to facilitate the creation of thecontrol flow graph. The pass is located in @file{omp-low.c} and isdescribed by @code{pass_lower_omp}.@item OpenMP expansionIf OpenMP generation (@option{-fopenmp}) is enabled, this pass expandsparallel regions into their own functions to be invoked by the threadlibrary. The pass is located in @file{omp-low.c} and is described by@code{pass_expand_omp}.@item Lower control flowThis pass flattens @code{if} statements (@code{COND_EXPR})and moves lexical bindings (@code{BIND_EXPR}) out of line. Afterthis pass, all @code{if} statements will have exactly two @code{goto}statements in its @code{then} and @code{else} arms. Lexical bindinginformation for each statement will be found in @code{TREE_BLOCK} ratherthan being inferred from its position under a @code{BIND_EXPR}. Thispass is found in @file{gimple-low.c} and is described by@code{pass_lower_cf}.@item Lower exception handling control flowThis pass decomposes high-level exception handling constructs(@code{TRY_FINALLY_EXPR} and @code{TRY_CATCH_EXPR}) into a formthat explicitly represents the control flow involved. After thispass, @code{lookup_stmt_eh_region} will return a non-negativenumber for any statement that may have EH control flow semantics;examine @code{tree_can_throw_internal} or @code{tree_can_throw_external}for exact semantics. Exact control flow may be extracted from@code{foreach_reachable_handler}. The EH region nesting tree is definedin @file{except.h} and built in @file{except.c}. The lowering passitself is in @file{tree-eh.c} and is described by @code{pass_lower_eh}.@item Build the control flow graphThis pass decomposes a function into basic blocks and creates all ofthe edges that connect them. It is located in @file{tree-cfg.c} andis described by @code{pass_build_cfg}.@item Find all referenced variablesThis pass walks the entire function and collects an array of allvariables referenced in the function, @code{referenced_vars}. Theindex at which a variable is found in the array is used as a UIDfor the variable within this function. This data is needed by theSSA rewriting routines. The pass is located in @file{tree-dfa.c}and is described by @code{pass_referenced_vars}.@item Enter static single assignment formThis pass rewrites the function such that it is in SSA form. Afterthis pass, all @code{is_gimple_reg} variables will be referenced by@code{SSA_NAME}, and all occurrences of other variables will beannotated with @code{VDEFS} and @code{VUSES}; PHI nodes will havebeen inserted as necessary for each basic block. This pass islocated in @file{tree-ssa.c} and is described by @code{pass_build_ssa}.@item Warn for uninitialized variablesThis pass scans the function for uses of @code{SSA_NAME}s thatare fed by default definition. For non-parameter variables, suchuses are uninitialized. The pass is run twice, before and afteroptimization. In the first pass we only warn for uses that arepositively uninitialized; in the second pass we warn for uses thatare possibly uninitialized. The pass is located in @file{tree-ssa.c}and is defined by @code{pass_early_warn_uninitialized} and@code{pass_late_warn_uninitialized}.@item Dead code eliminationThis pass scans the function for statements without side effects whoseresult is unused. It does not do memory life analysis, so any valuethat is stored in memory is considered used. The pass is run multipletimes throughout the optimization process. It is located in@file{tree-ssa-dce.c} and is described by @code{pass_dce}.@item Dominator optimizationsThis pass performs trivial dominator-based copy and constant propagation,expression simplification, and jump threading. It is run multiple timesthroughout the optimization process. It it located in @file{tree-ssa-dom.c}and is described by @code{pass_dominator}.@item Forward propagation of single-use variablesThis pass attempts to remove redundant computation by substitutingvariables that are used once into the expression that uses them andseeing if the result can be simplified. It is located in@file{tree-ssa-forwprop.c} and is described by @code{pass_forwprop}.@item Copy Renaming
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -