This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Kill quadratic bottleneck in duplicate_eh_regions


> > Jan Hubicka <jh@suse.cz> wrote:
> > 
> > > *************** struct eh_status GTY(())
> > > *** 210,216 ****
> > >     struct eh_region *region_tree;
> > >
> > >     /* The same information as an indexable array.  */
> > > !   struct eh_region ** GTY ((length ("%h.last_region_number")))
> > > region_array;
> > >
> > >     /* The most recently open region.  */
> > >     struct eh_region *cur_region;
> > > --- 210,216 ----
> > >     struct eh_region *region_tree;
> > >
> > >     /* The same information as an indexable array.  */
> > > !   varray_type GTY((param_is (struct eh_region))) region_array;
> > >
> > >     /* The most recently open region.  */
> > >     struct eh_region *cur_region;
> > 
> > I think there is agreement that VEC is uniformly better than VARRAY, and we are
> > trying to move away from VARRAY replacing all occurrences with VEC. So you
> > should not probably introduce new uses.
> 
> Hmm, what is the plan here?  I tought we were using VECs for fixed size
> stuff or cases where we have very many of small sized arrays...  I can
> re-do the patch for VEC API if we are dropping VARRAYs completelly (I
> was never varray friend)...

Bootstrapped/regtested on i686-pc-gnu-linux, OK?

2005-06-11  Jan Hubicka  <jh@suse.cz>
	* except.c (struct eh_status): Turn region_array into vec.
	(expand_resx_expr, collect_eh_region_array, remove_unreachable_regions,
	convert_from_eh_region_ranges, find_exception_handler_labels, 
	current_function_has_exception_handlers, assign_filter_values, 
	build_post_landing_pads, dw2_build_landing_pads,
	sjlj_find_directly_reachable_regions, sjlj_mark_call_sites,
	sjlj_emit_dispatch_table, remove_eh_handler, for_each_eh_region,
	foreach_reachable_handler, can_throw_internal_1,
	convert_to_eh_region_ranges, verify_eh_tree): Update uses of
	region_array.
	(duplicate_eh_region_1): Update region_array.
	(duplicate_eh_regions): Resize region_array and avoid recomputing.
Index: except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.c,v
retrieving revision 1.308
diff -c -3 -p -r1.308 except.c
*** except.c	1 Jun 2005 12:07:40 -0000	1.308
--- except.c	12 Jun 2005 09:23:03 -0000
*************** struct eh_region GTY(())
*** 197,208 ****
--- 197,213 ----
    unsigned may_contain_throw : 1;
  };
  
+ typedef struct eh_region *eh_region;
+ 
  struct call_site_record GTY(())
  {
    rtx landing_pad;
    int action;
  };
  
+ DEF_VEC_P(eh_region);
+ DEF_VEC_ALLOC_P(eh_region, gc);
+ 
  /* Used to save exception status for each function.  */
  struct eh_status GTY(())
  {
*************** struct eh_status GTY(())
*** 210,216 ****
    struct eh_region *region_tree;
  
    /* The same information as an indexable array.  */
!   struct eh_region ** GTY ((length ("%h.last_region_number"))) region_array;
  
    /* The most recently open region.  */
    struct eh_region *cur_region;
--- 215,221 ----
    struct eh_region *region_tree;
  
    /* The same information as an indexable array.  */
!   VEC(eh_region,gc) *region_array;
  
    /* The most recently open region.  */
    struct eh_region *cur_region;
*************** void
*** 560,567 ****
  expand_resx_expr (tree exp)
  {
    int region_nr = TREE_INT_CST_LOW (TREE_OPERAND (exp, 0));
!   struct eh_region *reg = cfun->eh->region_array[region_nr];
  
    reg->resume = emit_jump_insn (gen_rtx_RESX (VOIDmode, region_nr));
    emit_barrier ();
  }
--- 565,574 ----
  expand_resx_expr (tree exp)
  {
    int region_nr = TREE_INT_CST_LOW (TREE_OPERAND (exp, 0));
!   struct eh_region *reg = VEC_index (eh_region,
! 				     cfun->eh->region_array, region_nr);
  
+   gcc_assert (!reg->resume);
    reg->resume = emit_jump_insn (gen_rtx_RESX (VOIDmode, region_nr));
    emit_barrier ();
  }
*************** get_exception_filter (struct function *f
*** 623,641 ****
  void
  collect_eh_region_array (void)
  {
!   struct eh_region **array, *i;
  
    i = cfun->eh->region_tree;
    if (! i)
      return;
  
!   array = ggc_alloc_cleared ((cfun->eh->last_region_number + 1)
! 			     * sizeof (*array));
!   cfun->eh->region_array = array;
  
    while (1)
      {
!       array[i->region_number] = i;
  
        /* If there are sub-regions, process them.  */
        if (i->inner)
--- 630,648 ----
  void
  collect_eh_region_array (void)
  {
!   struct eh_region *i;
  
    i = cfun->eh->region_tree;
    if (! i)
      return;
  
!   VEC_safe_grow (eh_region, gc, cfun->eh->region_array,
! 		 cfun->eh->last_region_number + 1);
!   VEC_replace (eh_region, cfun->eh->region_array, 0, 0);
  
    while (1)
      {
!       VEC_replace (eh_region, cfun->eh->region_array, i->region_number, i);
  
        /* If there are sub-regions, process them.  */
        if (i->inner)
*************** remove_unreachable_regions (rtx insns)
*** 671,677 ****
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       r = cfun->eh->region_array[i];
        if (!r || r->region_number != i)
  	continue;
  
--- 678,684 ----
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       r = VEC_index (eh_region, cfun->eh->region_array, i);
        if (!r || r->region_number != i)
  	continue;
  
*************** remove_unreachable_regions (rtx insns)
*** 692,698 ****
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       r = cfun->eh->region_array[i];
        if (r && r->region_number == i && !reachable[i])
  	{
  	  bool kill_it = true;
--- 699,705 ----
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       r = VEC_index (eh_region, cfun->eh->region_array, i);
        if (r && r->region_number == i && !reachable[i])
  	{
  	  bool kill_it = true;
*************** convert_from_eh_region_ranges (void)
*** 753,759 ****
       we allocated earlier.  */
    for (i = 1; i <= n; ++i)
      {
!       struct eh_region *region = cfun->eh->region_array[i];
        if (region && region->tree_label)
  	region->label = DECL_RTL_IF_SET (region->tree_label);
      }
--- 760,768 ----
       we allocated earlier.  */
    for (i = 1; i <= n; ++i)
      {
!       struct eh_region *region;
! 
!       region = VEC_index (eh_region, cfun->eh->region_array, i);
        if (region && region->tree_label)
  	region->label = DECL_RTL_IF_SET (region->tree_label);
      }
*************** find_exception_handler_labels (void)
*** 805,813 ****
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       struct eh_region *region = cfun->eh->region_array[i];
        rtx lab;
  
        if (! region || region->region_number != i)
  	continue;
        if (cfun->eh->built_landing_pads)
--- 814,823 ----
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       struct eh_region *region;
        rtx lab;
  
+       region = VEC_index (eh_region, cfun->eh->region_array, i);
        if (! region || region->region_number != i)
  	continue;
        if (cfun->eh->built_landing_pads)
*************** current_function_has_exception_handlers 
*** 832,839 ****
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       struct eh_region *region = cfun->eh->region_array[i];
  
        if (! region || region->region_number != i)
  	continue;
        if (region->type != ERT_THROW)
--- 842,850 ----
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       struct eh_region *region;
  
+       region = VEC_index (eh_region, cfun->eh->region_array, i);
        if (! region || region->region_number != i)
  	continue;
        if (region->type != ERT_THROW)
*************** duplicate_eh_region_1 (struct eh_region 
*** 851,856 ****
--- 862,868 ----
    *n = *o;
    
    n->region_number = o->region_number + cfun->eh->last_region_number;
+   VEC_replace (eh_region, cfun->eh->region_array, n->region_number, n);
    gcc_assert (!o->aka);
    
    return n;
*************** duplicate_eh_regions (struct function *i
*** 911,929 ****
      return 0;
    
    n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array));
!   
    /* Search for the containing ERT_TRY region to fix up
       the prev_try short-cuts for ERT_CLEANUP regions.  */
    prev_try = NULL;
    if (outer_region > 0)
!     for (prev_try = cfun->eh->region_array[outer_region];
           prev_try && prev_try->type != ERT_TRY;
  	 prev_try = prev_try->outer)
        ;
  
    for (i = 1; i <= ifun_last_region_number; ++i)
      {
!       cur = ifun->eh->region_array[i];
        if (!cur || cur->region_number != i)
  	continue;
        n_array[i] = duplicate_eh_region_1 (cur);
--- 923,950 ----
      return 0;
    
    n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array));
!   VEC_safe_grow (eh_region, gc, cfun->eh->region_array,
! 		 cfun->eh->last_region_number + 1 + ifun_last_region_number);
! 
!   /* We might've created new cfun->eh->region_array so zero out nonexisting region 0.  */
!   VEC_replace (eh_region, cfun->eh->region_array, 0, 0);
! 
!   for (i = cfun->eh->last_region_number + 1;
!        i < cfun->eh->last_region_number + 1 + ifun_last_region_number; i++)
!     VEC_replace (eh_region, cfun->eh->region_array, i, 0);
!     
    /* Search for the containing ERT_TRY region to fix up
       the prev_try short-cuts for ERT_CLEANUP regions.  */
    prev_try = NULL;
    if (outer_region > 0)
!     for (prev_try = VEC_index (eh_region, cfun->eh->region_array, outer_region);
           prev_try && prev_try->type != ERT_TRY;
  	 prev_try = prev_try->outer)
        ;
  
    for (i = 1; i <= ifun_last_region_number; ++i)
      {
!       cur = VEC_index (eh_region, ifun->eh->region_array, i);
        if (!cur || cur->region_number != i)
  	continue;
        n_array[i] = duplicate_eh_region_1 (cur);
*************** duplicate_eh_regions (struct function *i
*** 937,943 ****
      }
    for (i = 1; i <= ifun_last_region_number; ++i)
      {
!       cur = ifun->eh->region_array[i];
        if (!cur || cur->region_number != i)
  	continue;
        duplicate_eh_region_2 (cur, n_array, prev_try);
--- 958,964 ----
      }
    for (i = 1; i <= ifun_last_region_number; ++i)
      {
!       cur = VEC_index (eh_region, ifun->eh->region_array, i);
        if (!cur || cur->region_number != i)
  	continue;
        duplicate_eh_region_2 (cur, n_array, prev_try);
*************** duplicate_eh_regions (struct function *i
*** 947,953 ****
    gcc_assert (root->outer == NULL);
    if (outer_region > 0)
      {
!       struct eh_region *cur = cfun->eh->region_array[outer_region];
        struct eh_region *p = cur->inner;
  
        if (p)
--- 968,975 ----
    gcc_assert (root->outer == NULL);
    if (outer_region > 0)
      {
!       struct eh_region *cur
!          = VEC_index (eh_region, cfun->eh->region_array, outer_region);
        struct eh_region *p = cur->inner;
  
        if (p)
*************** duplicate_eh_regions (struct function *i
*** 980,987 ****
    i = cfun->eh->last_region_number;
    cfun->eh->last_region_number = i + ifun_last_region_number;
    
-   collect_eh_region_array ();
-   
    return i;
  }
  
--- 1002,1007 ----
*************** assign_filter_values (void)
*** 1161,1167 ****
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       struct eh_region *r = cfun->eh->region_array[i];
  
        /* Mind we don't process a region more than once.  */
        if (!r || r->region_number != i)
--- 1181,1189 ----
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       struct eh_region *r;
! 
!       r = VEC_index (eh_region, cfun->eh->region_array, i);
  
        /* Mind we don't process a region more than once.  */
        if (!r || r->region_number != i)
*************** build_post_landing_pads (void)
*** 1254,1262 ****
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       struct eh_region *region = cfun->eh->region_array[i];
        rtx seq;
  
        /* Mind we don't process a region more than once.  */
        if (!region || region->region_number != i)
  	continue;
--- 1276,1285 ----
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       struct eh_region *region;
        rtx seq;
  
+       region = VEC_index (eh_region, cfun->eh->region_array, i);
        /* Mind we don't process a region more than once.  */
        if (!region || region->region_number != i)
  	continue;
*************** connect_post_landing_pads (void)
*** 1373,1383 ****
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       struct eh_region *region = cfun->eh->region_array[i];
        struct eh_region *outer;
        rtx seq;
        rtx barrier;
  
        /* Mind we don't process a region more than once.  */
        if (!region || region->region_number != i)
  	continue;
--- 1396,1407 ----
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       struct eh_region *region;
        struct eh_region *outer;
        rtx seq;
        rtx barrier;
  
+       region = VEC_index (eh_region, cfun->eh->region_array, i);
        /* Mind we don't process a region more than once.  */
        if (!region || region->region_number != i)
  	continue;
*************** dw2_build_landing_pads (void)
*** 1450,1461 ****
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       struct eh_region *region = cfun->eh->region_array[i];
        rtx seq;
        basic_block bb;
        bool clobbers_hard_regs = false;
        edge e;
  
        /* Mind we don't process a region more than once.  */
        if (!region || region->region_number != i)
  	continue;
--- 1474,1486 ----
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
!       struct eh_region *region;
        rtx seq;
        basic_block bb;
        bool clobbers_hard_regs = false;
        edge e;
  
+       region = VEC_index (eh_region, cfun->eh->region_array, i);
        /* Mind we don't process a region more than once.  */
        if (!region || region->region_number != i)
  	continue;
*************** sjlj_find_directly_reachable_regions (st
*** 1551,1557 ****
        if (!note || INTVAL (XEXP (note, 0)) <= 0)
  	continue;
  
!       region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
  
        type_thrown = NULL_TREE;
        if (region->type == ERT_THROW)
--- 1576,1582 ----
        if (!note || INTVAL (XEXP (note, 0)) <= 0)
  	continue;
  
!       region = VEC_index (eh_region, cfun->eh->region_array, INTVAL (XEXP (note, 0)));
  
        type_thrown = NULL_TREE;
        if (region->type == ERT_THROW)
*************** sjlj_assign_call_site_values (rtx dispat
*** 1593,1599 ****
    for (i = cfun->eh->last_region_number; i > 0; --i)
      if (lp_info[i].directly_reachable)
        {
! 	struct eh_region *r = cfun->eh->region_array[i];
  	r->landing_pad = dispatch_label;
  	lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
  	if (lp_info[i].action_index != -1)
--- 1618,1625 ----
    for (i = cfun->eh->last_region_number; i > 0; --i)
      if (lp_info[i].directly_reachable)
        {
! 	struct eh_region *r = VEC_index (eh_region, cfun->eh->region_array, i);
! 
  	r->landing_pad = dispatch_label;
  	lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
  	if (lp_info[i].action_index != -1)
*************** sjlj_mark_call_sites (struct sjlj_lp_inf
*** 1679,1685 ****
  	  if (INTVAL (XEXP (note, 0)) <= 0)
  	    continue;
  
! 	  region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
  	  this_call_site = lp_info[region->region_number].call_site_index;
  	}
  
--- 1705,1711 ----
  	  if (INTVAL (XEXP (note, 0)) <= 0)
  	    continue;
  
! 	  region = VEC_index (eh_region, cfun->eh->region_array, INTVAL (XEXP (note, 0)));
  	  this_call_site = lp_info[region->region_number].call_site_index;
  	}
  
*************** sjlj_emit_dispatch_table (rtx dispatch_l
*** 1894,1906 ****
  
        emit_cmp_and_jump_insns (dispatch, GEN_INT (lp_info[i].dispatch_index),
  			       EQ, NULL_RTX, TYPE_MODE (integer_type_node), 0,
! 			       cfun->eh->region_array[i]->post_landing_pad);
      }
  
    seq = get_insns ();
    end_sequence ();
  
!   before = cfun->eh->region_array[first_reachable]->post_landing_pad;
  
    bb = emit_to_new_bb_before (seq, before);
    e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
--- 1920,1934 ----
  
        emit_cmp_and_jump_insns (dispatch, GEN_INT (lp_info[i].dispatch_index),
  			       EQ, NULL_RTX, TYPE_MODE (integer_type_node), 0,
! 	                       ((struct eh_region *)VEC_index (eh_region, cfun->eh->region_array, i))
! 				->post_landing_pad);
      }
  
    seq = get_insns ();
    end_sequence ();
  
!   before = (((struct eh_region *)VEC_index (eh_region, cfun->eh->region_array, first_reachable))
! 	    ->post_landing_pad);
  
    bb = emit_to_new_bb_before (seq, before);
    e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
*************** remove_eh_handler (struct eh_region *reg
*** 2052,2058 ****
       list of alternate numbers by which we are known.  */
  
    outer = region->outer;
!   cfun->eh->region_array[region->region_number] = outer;
    if (region->aka)
      {
        unsigned i;
--- 2080,2086 ----
       list of alternate numbers by which we are known.  */
  
    outer = region->outer;
!   VEC_replace (eh_region, cfun->eh->region_array, region->region_number, outer);
    if (region->aka)
      {
        unsigned i;
*************** remove_eh_handler (struct eh_region *reg
*** 2060,2066 ****
  
        EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i, bi)
  	{
! 	  cfun->eh->region_array[i] = outer;
  	}
      }
  
--- 2088,2094 ----
  
        EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i, bi)
  	{
!           VEC_replace (eh_region, cfun->eh->region_array, i, outer);
  	}
      }
  
*************** for_each_eh_region (void (*callback) (st
*** 2194,2200 ****
    int i, n = cfun->eh->last_region_number;
    for (i = 1; i <= n; ++i)
      {
!       struct eh_region *region = cfun->eh->region_array[i];
        if (region)
  	(*callback) (region);
      }
--- 2222,2230 ----
    int i, n = cfun->eh->last_region_number;
    for (i = 1; i <= n; ++i)
      {
!       struct eh_region *region;
! 
!       region = VEC_index (eh_region, cfun->eh->region_array, i);
        if (region)
  	(*callback) (region);
      }
*************** foreach_reachable_handler (int region_nu
*** 2444,2450 ****
    info.callback = callback;
    info.callback_data = callback_data;
  
!   region = cfun->eh->region_array[region_number];
  
    type_thrown = NULL_TREE;
    if (is_resx)
--- 2474,2480 ----
    info.callback = callback;
    info.callback_data = callback_data;
  
!   region = VEC_index (eh_region, cfun->eh->region_array, region_number);
  
    type_thrown = NULL_TREE;
    if (is_resx)
*************** can_throw_internal_1 (int region_number,
*** 2533,2539 ****
    struct eh_region *region;
    tree type_thrown;
  
!   region = cfun->eh->region_array[region_number];
  
    type_thrown = NULL_TREE;
    if (is_resx)
--- 2563,2569 ----
    struct eh_region *region;
    tree type_thrown;
  
!   region = VEC_index (eh_region, cfun->eh->region_array, region_number);
  
    type_thrown = NULL_TREE;
    if (is_resx)
*************** can_throw_external_1 (int region_number,
*** 2593,2599 ****
    struct eh_region *region;
    tree type_thrown;
  
!   region = cfun->eh->region_array[region_number];
  
    type_thrown = NULL_TREE;
    if (is_resx)
--- 2623,2629 ----
    struct eh_region *region;
    tree type_thrown;
  
!   region = VEC_index (eh_region, cfun->eh->region_array, region_number);
  
    type_thrown = NULL_TREE;
    if (is_resx)
*************** convert_to_eh_region_ranges (void)
*** 3124,3130 ****
  	  {
  	    if (INTVAL (XEXP (note, 0)) <= 0)
  	      continue;
! 	    region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
  	    this_action = collect_one_action_chain (ar_hash, region);
  	  }
  
--- 3154,3160 ----
  	  {
  	    if (INTVAL (XEXP (note, 0)) <= 0)
  	      continue;
! 	    region = VEC_index (eh_region, cfun->eh->region_array, INTVAL (XEXP (note, 0)));
  	    this_action = collect_one_action_chain (ar_hash, region);
  	  }
  
*************** verify_eh_tree (struct function *fun)
*** 3656,3665 ****
    if (! i)
      return;
    for (j = fun->eh->last_region_number; j > 0; --j)
!     if (fun->eh->region_array[j])
        {
  	count++;
! 	if (fun->eh->region_array[j]->region_number != j)
  	  {
  	    error ("region_array is corrupted for region %i", i->region_number);
  	    err = true;
--- 3686,3695 ----
    if (! i)
      return;
    for (j = fun->eh->last_region_number; j > 0; --j)
!     if ((i = VEC_index (eh_region, cfun->eh->region_array, j)))
        {
  	count++;
! 	if (i->region_number != j)
  	  {
  	    error ("region_array is corrupted for region %i", i->region_number);
  	    err = true;
*************** verify_eh_tree (struct function *fun)
*** 3668,3674 ****
  
    while (1)
      {
!       if (fun->eh->region_array[i->region_number] != i)
  	{
  	  error ("region_array is corrupted for region %i", i->region_number);
  	  err = true;
--- 3698,3704 ----
  
    while (1)
      {
!       if (VEC_index (eh_region, cfun->eh->region_array, i->region_number) != i)
  	{
  	  error ("region_array is corrupted for region %i", i->region_number);
  	  err = true;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]