-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 05/02/11 15:18, Richard Guenther wrote:

> 
>> For (edge *)xmalloc (sizeof (edge) * 1) use XNEWVEC and friends.
>> I wonder if it makes sense to use a VEC instead (will the vector
>> be of variable size?).  Maybe wrap accesses to e->aux with
>> a macro or some inline functions.
> 
>> Ok with the allocation change.
Attached is the actual patch I checked in.  I found a minor goof in the
stats reporting which I fixed, in addition to the stuff Richard pointed out.

Bootstrapped and regression tested on x86_64-unknown-linux-gnu

Jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNwABQAAoJEBRtltQi2kC7yUkH/3RkOHjEqrTz6C/fnapNQYKx
D/Ts9p7zlIsm66+cVpbM8z2+884QOEv0TjVqd7uDo7/vg9cKw7xRMbNI6+IZTM/H
NdFweso3rC2nZZhqNn0DBkczo7RZcdMhR0DGkpd+xGZBSE4L6gw6W9+3YJ70BZZo
KLuZ0PiYmPcuJEN00O0zmypiVX7z04tvCSSLxPbXT/sHU6odNWvUAdEZhKX6nJ2r
/FljdonBdLbdwEdVoRycZ64F6TrF66zaS2EKWgtdhe9PP6hQ/ovUoyXT5LwkRxDv
VvmLRx/6D1xyDmLus9D41016k9Iog4gn4Kfb9taaX57KkiCfBgyhaQgbOoIZNVM=
=z/nF
-----END PGP SIGNATURE-----
        * tree-ssa-threadupdate.c (THREAD_TARGET): define.
        (remove_ctrl_stmt_and_useless_edges): Clear AUX field of outgoing edges.
        (craete_edge_and_update_destination_phis): Use THREAD_TARGET rather
        than accessing AUX field directly.  Free the AUX field before           
        clearing it.
        (thread_block, thread_through_loop_header): Likewise.
        (thread_single_edge, mark_threaded_blocks): Likewise.
        (redirect_edges): Delay clearing the AUX field.  Free the AUX field.
        (register_jump_thread): Do not attempt to thread to a NULL edge.
        
Index: tree-ssa-threadupdate.c
===================================================================
*** tree-ssa-threadupdate.c     (revision 173302)
--- tree-ssa-threadupdate.c     (working copy)
*************** struct local_info
*** 149,154 ****
--- 149,158 ----
     (original_edge, target_edge).  */
  static VEC(edge,heap) *threaded_edges;
  
+ /* When we start updating the CFG for threading, data necessary for jump
+    threading is attached to the AUX field for the incoming edge.  Use these
+    macros to access the underlying structure attached to the AUX field.  */
+ #define THREAD_TARGET(E) ((edge *)(E)->aux)[0]
  
  /* Jump threading statistics.  */
  
*************** remove_ctrl_stmt_and_useless_edges (basi
*** 200,209 ****
--- 204,219 ----
  static void
  create_block_for_threading (basic_block bb, struct redirection_data *rd)
  {
+   edge_iterator ei;
+   edge e;
+ 
    /* We can use the generic block duplication code and simply remove
       the stuff we do not need.  */
    rd->dup_block = duplicate_block (bb, NULL, NULL);
  
+   FOR_EACH_EDGE (e, ei, rd->dup_block->succs)
+     e->aux = NULL;
+ 
    /* Zero out the profile, since the block is unreachable for now.  */
    rd->dup_block->frequency = 0;
    rd->dup_block->count = 0;
*************** create_edge_and_update_destination_phis 
*** 314,320 ****
    rescan_loop_exit (e, true, false);
    e->probability = REG_BR_PROB_BASE;
    e->count = bb->count;
!   e->aux = rd->outgoing_edge->aux;
  
    /* If there are any PHI nodes at the destination of the outgoing edge
       from the duplicate block, then we will need to add a new argument
--- 324,339 ----
    rescan_loop_exit (e, true, false);
    e->probability = REG_BR_PROB_BASE;
    e->count = bb->count;
! 
!   if (rd->outgoing_edge->aux)
!     {
!       e->aux = (edge *) XNEWVEC (edge, 1);
!       THREAD_TARGET(e) = THREAD_TARGET (rd->outgoing_edge);
!     }
!   else
!     {
!       e->aux = NULL;
!     }
  
    /* If there are any PHI nodes at the destination of the outgoing edge
       from the duplicate block, then we will need to add a new argument
*************** redirect_edges (void **slot, void *data)
*** 406,415 ****
        next = el->next;
        free (el);
  
-       /* Go ahead and clear E->aux.  It's not needed anymore and failure
-          to clear it will cause all kinds of unpleasant problems later.  */
-       e->aux = NULL;
- 
        thread_stats.num_threaded_edges++;
  
        if (rd->dup_block)
--- 425,430 ----
*************** redirect_edges (void **slot, void *data)
*** 429,434 ****
--- 444,455 ----
          gcc_assert (e == e2);
          flush_pending_stmts (e2);
        }
+ 
+       /* Go ahead and clear E->aux.  It's not needed anymore and failure
+          to clear it will cause all kinds of unpleasant problems later.  */
+       free (e->aux);
+       e->aux = NULL;
+ 
      }
  
    /* Indicate that we actually threaded one or more jumps.  */
*************** thread_block (basic_block bb, bool noloo
*** 512,518 ****
    if (loop->header == bb)
      {
        e = loop_latch_edge (loop);
!       e2 = (edge) e->aux;
  
        if (e2 && loop_exit_edge_p (loop, e2))
        {
--- 533,543 ----
    if (loop->header == bb)
      {
        e = loop_latch_edge (loop);
! 
!       if (e->aux)
!       e2 = THREAD_TARGET (e);
!       else
!       e2 = NULL;
  
        if (e2 && loop_exit_edge_p (loop, e2))
        {
*************** thread_block (basic_block bb, bool noloo
*** 525,543 ****
       efficient lookups.  */
    FOR_EACH_EDGE (e, ei, bb->preds)
      {
!       e2 = (edge) e->aux;
  
        if (!e2
          /* If NOLOOP_ONLY is true, we only allow threading through the
             header of a loop to exit edges.  */
          || (noloop_only
              && bb == bb->loop_father->header
!             && !loop_exit_edge_p (bb->loop_father, e2)))
        continue;
  
        if (e->dest == e2->src)
        update_bb_profile_for_threading (e->dest, EDGE_FREQUENCY (e),
!                                        e->count, (edge) e->aux);
  
        /* Insert the outgoing edge into the hash table if it is not
         already in the hash table.  */
--- 550,571 ----
       efficient lookups.  */
    FOR_EACH_EDGE (e, ei, bb->preds)
      {
!       if (e->aux == NULL)
!       continue;
! 
!       e2 = THREAD_TARGET (e);
  
        if (!e2
          /* If NOLOOP_ONLY is true, we only allow threading through the
             header of a loop to exit edges.  */
          || (noloop_only
              && bb == bb->loop_father->header
!             && (!loop_exit_edge_p (bb->loop_father, e2))))
        continue;
  
        if (e->dest == e2->src)
        update_bb_profile_for_threading (e->dest, EDGE_FREQUENCY (e),
!                                        e->count, THREAD_TARGET (e));
  
        /* Insert the outgoing edge into the hash table if it is not
         already in the hash table.  */
*************** thread_block (basic_block bb, bool noloo
*** 582,598 ****
    return local_info.jumps_threaded;
  }
  
! /* Threads edge E through E->dest to the edge E->aux.  Returns the copy
!    of E->dest created during threading, or E->dest if it was not necessary
     to copy it (E is its single predecessor).  */
  
  static basic_block
  thread_single_edge (edge e)
  {
    basic_block bb = e->dest;
!   edge eto = (edge) e->aux;
    struct redirection_data rd;
  
    e->aux = NULL;
  
    thread_stats.num_threaded_edges++;
--- 610,627 ----
    return local_info.jumps_threaded;
  }
  
! /* Threads edge E through E->dest to the edge THREAD_TARGET (E).  Returns the
!    copy of E->dest created during threading, or E->dest if it was not 
necessary
     to copy it (E is its single predecessor).  */
  
  static basic_block
  thread_single_edge (edge e)
  {
    basic_block bb = e->dest;
!   edge eto = THREAD_TARGET (e);
    struct redirection_data rd;
  
+   free (e->aux);
    e->aux = NULL;
  
    thread_stats.num_threaded_edges++;
*************** thread_through_loop_header (struct loop 
*** 794,800 ****
  
    if (latch->aux)
      {
!       tgt_edge = (edge) latch->aux;
        tgt_bb = tgt_edge->dest;
      }
    else if (!may_peel_loop_headers
--- 823,829 ----
  
    if (latch->aux)
      {
!       tgt_edge = THREAD_TARGET (latch);
        tgt_bb = tgt_edge->dest;
      }
    else if (!may_peel_loop_headers
*************** thread_through_loop_header (struct loop 
*** 817,823 ****
              goto fail;
            }
  
!         tgt_edge = (edge) e->aux;
          atgt_bb = tgt_edge->dest;
          if (!tgt_bb)
            tgt_bb = atgt_bb;
--- 846,852 ----
              goto fail;
            }
  
!         tgt_edge = THREAD_TARGET (e);
          atgt_bb = tgt_edge->dest;
          if (!tgt_bb)
            tgt_bb = atgt_bb;
*************** thread_through_loop_header (struct loop 
*** 883,889 ****
  
        /* Now consider the case entry edges are redirected to the new entry
         block.  Remember one entry edge, so that we can find the new
!       preheader (its destination after threading).  */
        FOR_EACH_EDGE (e, ei, header->preds)
        {
          if (e->aux)
--- 912,918 ----
  
        /* Now consider the case entry edges are redirected to the new entry
         block.  Remember one entry edge, so that we can find the new
!        preheader (its destination after threading).  */
        FOR_EACH_EDGE (e, ei, header->preds)
        {
          if (e->aux)
*************** fail:
*** 915,920 ****
--- 944,950 ----
    /* We failed to thread anything.  Cancel the requests.  */
    FOR_EACH_EDGE (e, ei, header->preds)
      {
+       free (e->aux);
        e->aux = NULL;
      }
    return false;
*************** mark_threaded_blocks (bitmap threaded_bl
*** 946,954 ****
    for (i = 0; i < VEC_length (edge, threaded_edges); i += 2)
      {
        edge e = VEC_index (edge, threaded_edges, i);
!       edge e2 = VEC_index (edge, threaded_edges, i + 1);
  
!       e->aux = e2;
        bitmap_set_bit (tmp, e->dest->index);
      }
  
--- 976,985 ----
    for (i = 0; i < VEC_length (edge, threaded_edges); i += 2)
      {
        edge e = VEC_index (edge, threaded_edges, i);
!       edge *x = (edge *) XNEWVEC (edge, 1);
  
!       x[0] = VEC_index (edge, threaded_edges, i + 1);
!       e->aux = x;
        bitmap_set_bit (tmp, e->dest->index);
      }
  
*************** mark_threaded_blocks (bitmap threaded_bl
*** 963,969 ****
              && !redirection_block_p (bb))
            {
              FOR_EACH_EDGE (e, ei, bb->preds)
!                     e->aux = NULL;
            }
          else
            bitmap_set_bit (threaded_blocks, i);
--- 994,1003 ----
              && !redirection_block_p (bb))
            {
              FOR_EACH_EDGE (e, ei, bb->preds)
!               {
!                 free (e->aux);
!                 e->aux = NULL;
!               }
            }
          else
            bitmap_set_bit (threaded_blocks, i);
*************** thread_through_all_blocks (bool may_peel
*** 1059,1066 ****
  void
  register_jump_thread (edge e, edge e2)
  {
    if (threaded_edges == NULL)
!     threaded_edges = VEC_alloc (edge, heap, 10);
  
    if (dump_file && (dump_flags & TDF_DETAILS)
        && e->dest != e2->src)
--- 1093,1105 ----
  void
  register_jump_thread (edge e, edge e2)
  {
+   /* This can occur if we're jumping to a constant address or
+      or something similar.  Just get out now.  */
+   if (e2 == NULL)
+     return;
+ 
    if (threaded_edges == NULL)
!     threaded_edges = VEC_alloc (edge, heap, 15);
  
    if (dump_file && (dump_flags & TDF_DETAILS)
        && e->dest != e2->src)

Reply via email to