📄 cfg.texi
字号:
@findex EDGE_ABNORMAL, EDGE_ABNORMAL_CALLGCC allows nested functions to return into caller using a @code{goto}to a label passed to as an argument to the callee. The labels passedto nested functions contain special code to cleanup after functioncall. Such sections of code are referred to as ``nonlocal gotoreceivers''. If a function contains such nonlocal goto receivers, anedge from the call to the label is created with the@code{EDGE_ABNORMAL} and @code{EDGE_ABNORMAL_CALL} flags set.@item function entry points@cindex function entry point, alternate function entry point@findex LABEL_ALTERNATE_NAMEBy definition, execution of function starts at basic block 0, so thereis always an edge from the @code{ENTRY_BLOCK_PTR} to basic block 0.There is no @code{tree} representation for alternate entry points atthis moment. In RTL, alternate entry points are specified by@code{CODE_LABEL} with @code{LABEL_ALTERNATE_NAME} defined. Thisfeature is currently used for multiple entry point prologues and islimited to post-reload passes only. This can be used by back-ends toemit alternate prologues for functions called from different contexts.In future full support for multiple entry functions defined by Fortran90 needs to be implemented.@item function exitsIn the pre-reload representation a function terminates after the lastinstruction in the insn chain and no explicit return instructions areused. This corresponds to the fall-thru edge into exit block. Afterreload, optimal RTL epilogues are used that use explicit (conditional)return instructions that are represented by edges with no flags set.@end table@node Profile information@section Profile information@cindex profile representationIn many cases a compiler must make a choice whether to trade speed inone part of code for speed in another, or to trade code size for codespeed. In such cases it is useful to know information about how oftensome given block will be executed. That is the purpose formaintaining profile within the flow graph.GCC can handle profile information obtained through @dfn{profilefeedback}, but it can also estimate branch probabilities based onstatics and heuristics.@cindex profile feedbackThe feedback based profile is produced by compiling the program withinstrumentation, executing it on a train run and reading the numbersof executions of basic blocks and edges back to the compiler whilere-compiling the program to produce the final executable. This methodprovides very accurate information about where a program spends mostof its time on the train run. Whether it matches the average run ofcourse depends on the choice of train data set, but several studieshave shown that the behavior of a program usually changes justmarginally over different data sets.@cindex Static profile estimation@cindex branch prediction@findex predict.defWhen profile feedback is not available, the compiler may be asked toattempt to predict the behavior of each branch in the program using aset of heuristics (see @file{predict.def} for details) and computeestimated frequencies of each basic block by propagating theprobabilities over the graph.@findex frequency, count, BB_FREQ_BASEEach @code{basic_block} contains two integer fields to representprofile information: @code{frequency} and @code{count}. The@code{frequency} is an estimation how often is basic block executedwithin a function. It is represented as an integer scaled in therange from 0 to @code{BB_FREQ_BASE}. The most frequently executedbasic block in function is initially set to @code{BB_FREQ_BASE} andthe rest of frequencies are scaled accordingly. During optimization,the frequency of the most frequent basic block can both decrease (forinstance by loop unrolling) or grow (for instance by cross-jumpingoptimization), so scaling sometimes has to be performed multipletimes.@findex gcov_typeThe @code{count} contains hard-counted numbers of execution measuredduring training runs and is nonzero only when profile feedback isavailable. This value is represented as the host's widest integer(typically a 64 bit integer) of the special type @code{gcov_type}.Most optimization passes can use only the frequency information of abasic block, but a few passes may want to know hard execution counts.The frequencies should always match the counts after scaling, howeverduring updating of the profile information numerical error mayaccumulate into quite large errors.@findex REG_BR_PROB_BASE, EDGE_FREQUENCYEach edge also contains a branch probability field: an integer in therange from 0 to @code{REG_BR_PROB_BASE}. It represents probability ofpassing control from the end of the @code{src} basic block to the@code{dest} basic block, i.e.@: the probability that control will flowalong this edge. The @code{EDGE_FREQUENCY} macro is available tocompute how frequently a given edge is taken. There is a @code{count}field for each edge as well, representing same information as for abasic block.The basic block frequencies are not represented in the instructionstream, but in the RTL representation the edge frequencies arerepresented for conditional jumps (via the @code{REG_BR_PROB}macro) since they are used when instructions are output to theassembly file and the flow graph is no longer maintained.@cindex reverse probabilityThe probability that control flow arrives via a given edge to itsdestination basic block is called @dfn{reverse probability} and is notdirectly represented, but it may be easily computed from frequenciesof basic blocks.@findex redirect_edge_and_branchUpdating profile information is a delicate task that can unfortunatelynot be easily integrated with the CFG manipulation API@. Many of thefunctions and hooks to modify the CFG, such as@code{redirect_edge_and_branch}, do not have enough information toeasily update the profile, so updating it is in the majority of casesleft up to the caller. It is difficult to uncover bugs in the profileupdating code, because they manifest themselves only by producingworse code, and checking profile consistency is not possible becauseof numeric error accumulation. Hence special attention needs to begiven to this issue in each pass that modifies the CFG@.@findex REG_BR_PROB_BASE, BB_FREQ_BASE, countIt is important to point out that @code{REG_BR_PROB_BASE} and@code{BB_FREQ_BASE} are both set low enough to be possible to computesecond power of any frequency or probability in the flow graph, it isnot possible to even square the @code{count} field, as modern CPUs arefast enough to execute $2^32$ operations quickly.@node Maintaining the CFG@section Maintaining the CFG@findex cfghooks.hAn important task of each compiler pass is to keep both the controlflow graph and all profile information up-to-date. Reconstruction ofthe control flow graph after each pass is not an option, since it may bevery expensive and lost profile information cannot be reconstructed atall.GCC has two major intermediate representations, and both use the@code{basic_block} and @code{edge} data types to represent controlflow. Both representations share as much of the CFG maintenance codeas possible. For each representation, a set of @dfn{hooks} is definedso that each representation can provide its own implementation of CFGmanipulation routines when necessary. These hooks are defined in@file{cfghooks.h}. There are hooks for almost all common CFGmanipulations, including block splitting and merging, edge redirectionand creating and deleting basic blocks. These hooks should provideeverything you need to maintain and manipulate the CFG in both the RTLand @code{tree} representation.At the moment, the basic block boundaries are maintained transparentlywhen modifying instructions, so there rarely is a need to move themmanually (such as in case someone wants to output instruction outsidebasic block explicitly).Often the CFG may be better viewed as integral part of instructionchain, than structure built on the top of it. However, in principlethe control flow graph for the @code{tree} representation is@emph{not} an integral part of the representation, in that a functiontree may be expanded without first building a flow graph for the@code{tree} representation at all. This happens when compilingwithout any @code{tree} optimization enabled. When the @code{tree}optimizations are enabled and the instruction stream is rewritten inSSA form, the CFG is very tightly coupled with the instruction stream.In particular, statement insertion and removal has to be done withcare. In fact, the whole @code{tree} representation can not be easilyused or maintained without proper maintenance of the CFGsimultaneously.@findex BLOCK_FOR_INSN, bb_for_stmtIn the RTL representation, each instruction has a@code{BLOCK_FOR_INSN} value that represents pointer to the basic blockthat contains the instruction. In the @code{tree} representation, thefunction @code{bb_for_stmt} returns a pointer to the basic blockcontaining the queried statement.@cindex block statement iteratorsWhen changes need to be applied to a function in its @code{tree}representation, @dfn{block statement iterators} should be used. Theseiterators provide an integrated abstraction of the flow graph and theinstruction stream. Block statement iterators iterators areconstructed using the @code{block_stmt_iterator} data structure andseveral modifier are available, including the following:@ftable @code@item bsi_startThis function initializes a @code{block_stmt_iterator} that points tothe first non-empty statement in a basic block.@item bsi_lastThis function initializes a @code{block_stmt_iterator} that points tothe last statement in a basic block.@item bsi_end_pThis predicate is @code{true} if a @code{block_stmt_iterator}represents the end of a basic block.@item bsi_nextThis function takes a @code{block_stmt_iterator} and makes it point toits successor.@item bsi_prevThis function takes a @code{block_stmt_iterator} and makes it point toits predecessor.@item bsi_insert_afterThis function inserts a statement after the @code{block_stmt_iterator}passed in. The final parameter determines whether the statementiterator is updated to point to the newly inserted statement, or leftpointing to the original statement.@item bsi_insert_beforeThis function inserts a statement before the @code{block_stmt_iterator}passed in. The final parameter determines whether the statementiterator is updated to point to the newly inserted statement, or leftpointing to the original statement.@item bsi_removeThis function removes the @code{block_stmt_iterator} passed in andrechains the remaining statements in a basic block, if any.@end ftable@findex BB_HEAD, BB_ENDIn the RTL representation, the macros @code{BB_HEAD} and @code{BB_END}may be used to get the head and end @code{rtx} of a basic block. Noabstract iterators are defined for traversing the insn chain, but youcan just use @code{NEXT_INSN} and @code{PREV_INSN} instead. See@xref{Insns}.@findex purge_dead_edgesUsually a code manipulating pass simplifies the instruction stream andthe flow of control, possibly eliminating some edges. This may forexample happen when a conditional jump is replaced with anunconditional jump, but also when simplifying possibly trappinginstruction to non-trapping while compiling Java. Updating of edgesis not transparent and each optimization pass is required to do somanually. However only few cases occur in practice. The pass maycall @code{purge_dead_edges} on a given basic block to removesuperfluous edges, if any.@findex redirect_edge_and_branch, redirect_jumpAnother common scenario is redirection of branch instructions, butthis is best modeled as redirection of edges in the control flow graphand thus use of @code{redirect_edge_and_branch} is preferred over morelow level functions, such as @code{redirect_jump} that operate on RTLchain only. The CFG hooks defined in @file{cfghooks.h} should providethe complete API required for manipulating and maintaining the CFG@.@findex split_blockIt is also possible that a pass has to insert control flow instructioninto the middle of a basic block, thus creating an entry point in themiddle of the basic block, which is impossible by definition: Theblock must be split to make sure it only has one entry point, i.e.@: thehead of the basic block. The CFG hook @code{split_block} may be usedwhen an instruction in the middle of a basic block has to become thetarget of a jump or branch instruction.@findex insert_insn_on_edge@findex commit_edge_insertions@findex bsi_insert_on_edge@findex bsi_commit_edge_inserts@cindex edge splittingFor a global optimizer, a common operation is to split edges in theflow graph and insert instructions on them. In the RTLrepresentation, this can be easily done using the@code{insert_insn_on_edge} function that emits an instruction``on the edge'', caching it for a later @code{commit_edge_insertions}call that will take care of moving the inserted instructions off theedge into the instruction stream contained in a basic block. Thisincludes the creation of new basic blocks where needed. In the@code{tree} representation, the equivalent functions are@code{bsi_insert_on_edge} which inserts a block statementiterator on an edge, and @code{bsi_commit_edge_inserts} which flushesthe instruction to actual instruction stream.While debugging the optimization pass, an @code{verify_flow_info}function may be useful to find bugs in the control flow graph updatingcode.Note that at present, the representation of control flow in the@code{tree} representation is discarded before expanding to RTL@.Long term the CFG should be maintained and ``expanded'' to theRTL representation along with the function @code{tree} itself.@node Liveness information@section Liveness information@cindex Liveness representationLiveness information is useful to determine whether some register is``live'' at given point of program, i.e.@: that it contains a value thatmay be used at a later point in the program. This information isused, for instance, during register allocation, as the pseudoregisters only need to be assigned to a unique hard register or to astack slot if they are live. The hard registers and stack slots maybe freely reused for other values when a register is dead. Liveness information is available in the back end starting with@code{pass_df_initialize} and ending with @code{pass_df_finish}. Threeflavors of live analysis are available: With @code{LR}, it is possibleto determine at any point @code{P} in the function if the register may beused on some path from @code{P} to the end of the function. With@code{UR}, it is possible to determine if there is a path from thebeginning of the function to @code{P} that defines the variable. @code{LIVE} is the intersection of the @code{LR} and @code{UR} and avariable is live at @code{P} if there is both an assignment that reachesit from the beginning of the function and a uses that can be reached onsome path from @code{P} to the end of the function.In general @code{LIVE} is the most useful of the three. The macros@code{DF_[LR,UR,LIVE]_[IN,OUT]} can be used to access this information.The macros take a basic block number and return a bitmap that is indexedby the register number. This information is only guaranteed to be up todate after calls are made to @code{df_analyze}. See the file@code{df-core.c} for details on using the dataflow. @findex REG_DEAD, REG_UNUSEDThe liveness information is stored partly in the RTL instruction streamand partly in the flow graph. Local information is stored in theinstruction stream: Each instruction may contain @code{REG_DEAD} notesrepresenting that the value of a given register is no longer needed, or@code{REG_UNUSED} notes representing that the value computed by theinstruction is never used. The second is useful for instructionscomputing multiple values at once.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -