Mercurial > hg > CbC > CbC_gcc
diff gcc/domwalk.h @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | 77e2b8dfacca |
children | 84e7813d76e9 |
line wrap: on
line diff
--- a/gcc/domwalk.h Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/domwalk.h Fri Oct 27 22:46:09 2017 +0900 @@ -1,5 +1,5 @@ /* Generic dominator tree walker - Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2003-2017 Free Software Foundation, Inc. Contributed by Diego Novillo <dnovillo@redhat.com> This file is part of GCC. @@ -18,59 +18,73 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ -typedef void *void_p; -DEF_VEC_P(void_p); -DEF_VEC_ALLOC_P(void_p,heap); +#ifndef GCC_DOM_WALK_H +#define GCC_DOM_WALK_H + +/** + * This is the main class for the dominator walker. It is expected that + * consumers will have a custom class inheriting from it, which will over ride + * at least one of before_dom_children and after_dom_children to implement the + * custom behavior. + */ +class dom_walker +{ +public: + static const edge STOP; + + /* Use SKIP_UNREACHBLE_BLOCKS = true when your client can discover + that some edges are not executable. -/* This is the main data structure for the dominator walker. It provides - the callback hooks as well as a convenient place to hang block local - data and pass-global data. */ + If a client can discover that a COND, SWITCH or GOTO has a static + target in the before_dom_children callback, the taken edge should + be returned. The generic walker will clear EDGE_EXECUTABLE on all + edges it can determine are not executable. + + You can provide a mapping of basic-block index to RPO if you + have that readily available or you do multiple walks. */ + dom_walker (cdi_direction direction, bool skip_unreachable_blocks = false, + int *bb_index_to_rpo = NULL); + + ~dom_walker (); + + /* Walk the dominator tree. */ + void walk (basic_block); -struct dom_walk_data -{ + /* Function to call before the recursive walk of the dominator children. + + Return value is the always taken edge if the block has multiple outgoing + edges, NULL otherwise. When skipping unreachable blocks, the walker + uses the taken edge information to clear EDGE_EXECUTABLE on the other + edges, exposing unreachable blocks. A NULL return value means all + outgoing edges should still be considered executable. A return value + of STOP means to stop the domwalk from processing dominated blocks from + here. This can be used to process a SEME region only (note domwalk + will still do work linear in function size). */ + virtual edge before_dom_children (basic_block) { return NULL; } + + /* Function to call after the recursive walk of the dominator children. */ + virtual void after_dom_children (basic_block) {} + +private: /* This is the direction of the dominator tree we want to walk. i.e., if it is set to CDI_DOMINATORS, then we walk the dominator tree, if it is set to CDI_POST_DOMINATORS, then we walk the post dominator tree. */ - ENUM_BITFIELD (cdi_direction) dom_direction : 2; - - /* Function to initialize block local data. - - Note that the dominator walker infrastructure may provide a new - fresh, and zero'd block local data structure, or it may re-use an - existing block local data structure. - - If the block local structure has items such as virtual arrays, then - that allows your optimizer to re-use those arrays rather than - creating new ones. */ - void (*initialize_block_local_data) (struct dom_walk_data *, - basic_block, bool); - - /* Function to call before the recursive walk of the dominator children. */ - void (*before_dom_children) (struct dom_walk_data *, basic_block); + const ENUM_BITFIELD (cdi_direction) m_dom_direction : 2; + bool m_skip_unreachable_blocks; + bool m_user_bb_to_rpo; + basic_block m_unreachable_dom; + int *m_bb_to_rpo; - /* Function to call after the recursive walk of the dominator children. */ - void (*after_dom_children) (struct dom_walk_data *, basic_block); - - /* Global data for a walk through the dominator tree. */ - void *global_data; - - /* Stack of any data we need to keep on a per-block basis. + /* Query whether or not the given block is reachable or not. */ + bool bb_reachable (struct function *, basic_block); - If you have no local data, then BLOCK_DATA_STACK will be NULL. */ - VEC(void_p,heap) *block_data_stack; + /* Given an unreachable block, propagate that property to outgoing + and possibly incoming edges for the block. Typically called after + determining a block is unreachable in the before_dom_children + callback. */ + void propagate_unreachable_to_edges (basic_block, FILE *, dump_flags_t); - /* Size of the block local data. If this is zero, then it is assumed - you have no local data and thus no BLOCK_DATA_STACK as well. */ - size_t block_local_data_size; - - /* From here below are private data. Please do not use this - information/data outside domwalk.c. */ - - /* Stack of available block local structures. */ - VEC(void_p,heap) *free_block_data; }; -void walk_dominator_tree (struct dom_walk_data *, basic_block); -void init_walk_dominator_tree (struct dom_walk_data *); -void fini_walk_dominator_tree (struct dom_walk_data *); +#endif