diff gcc/domwalk.h @ 16: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