This separates out a loop finding new_edges from edges in copy_bbs,
making its complexity cheaper overall from total number of succs in
copied bbs times num_edges to num_edges times the complexity of
find_edge.

Bootstrapped / tested on x86_64-unknown-linux-gnu, pushed.

2020-10-21  Richard Biener  <rguent...@suse.de>

        * cfghooks.c (copy_bbs): Split out loop computing new_edges.
---
 gcc/cfghooks.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index 71c6b63ad3b..14c006df6e1 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -1391,8 +1391,6 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block 
*new_bbs,
     }
 
   /* Redirect edges.  */
-  for (j = 0; j < num_edges; j++)
-    new_edges[j] = NULL;
   for (i = 0; i < n; i++)
     {
       edge_iterator ei;
@@ -1401,15 +1399,26 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block 
*new_bbs,
 
       FOR_EACH_EDGE (e, ei, new_bb->succs)
        {
-         for (j = 0; j < num_edges; j++)
-           if (edges[j] && edges[j]->src == bb && edges[j]->dest == e->dest)
-             new_edges[j] = e;
-
          if (!(e->dest->flags & BB_DUPLICATED))
            continue;
          redirect_edge_and_branch_force (e, get_bb_copy (e->dest));
        }
     }
+  for (j = 0; j < num_edges; j++)
+    {
+      if (!edges[j])
+       new_edges[j] = NULL;
+      else
+       {
+         basic_block src = edges[j]->src;
+         basic_block dest = edges[j]->dest;
+         if (src->flags & BB_DUPLICATED)
+           src = get_bb_copy (src);
+         if (dest->flags & BB_DUPLICATED)
+           dest = get_bb_copy (dest);
+         new_edges[j] = find_edge (src, dest);
+       }
+    }
 
   /* Clear information about duplicates.  */
   for (i = 0; i < n; i++)
-- 
2.26.2

Reply via email to