GCC Middle and Back End API Reference
|
Data Fields | |
edge | e |
struct el * | next |
Thread edges through blocks and update the control flow and SSA graphs. Copyright (C) 2004-2013 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see http://www.gnu.org/licenses/. Given a block B, update the CFG and SSA graph to reflect redirecting one or more in-edges to B to instead reach the destination of an out-edge from B while preserving any side effects in B.
i.e., given A->B and B->C, change A->B to be A->C yet still preserve the side effects of executing B.
Change the edge A->B to A->B'.
5a. This automatically deletes any PHI arguments associated with the edge A->B in B.
5b. This automatically associates each new argument added in step 4 with the edge A->B'.
Note that block duplication can be minimized by first collecting the set of unique destination blocks that the incoming edges should be threaded to.
Block duplication can be further minimized by using B instead of creating B' for one destination if all edges into B are going to be threaded to a successor of B. We had code to do this at one time, but I'm not convinced it is correct with the changes to avoid mucking up the loop structure (which may cancel threading requests, thus a block which we thought was going to become unreachable may still be reachable). This code was also going to get ugly with the introduction of the ability for a single jump thread request to bypass multiple blocks.
We further reduce the number of edges and statements we create by not copying all the outgoing edges and the control statement in step #1. We instead create a template block without the outgoing edges and duplicate the template. Steps #5 and #6 of the above algorithm are best implemented by walking all the incoming edges which thread to the same destination edge at the same time. That avoids lots of table lookups to get information for the destination edge.
To realize that implementation we create a list of incoming edges which thread to the same outgoing edge. Thus to implement steps #5 and #6 we traverse our hash table of outgoing edge information. For each entry we walk the list of incoming edges which thread to the current outgoing edge.
edge el::e |
Referenced by lookup_redirection_data().
struct el* el::next |
Referenced by lookup_redirection_data().