Add VEC_ORDERED_REMOVE_IF
authorTom de Vries <tom@codesourcery.com>
Tue, 1 May 2018 19:16:43 +0000 (19:16 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Tue, 1 May 2018 19:16:43 +0000 (19:16 +0000)
2018-05-01  Tom de Vries  <tom@codesourcery.com>

PR other/83786
* vec.h (VEC_ORDERED_REMOVE_IF, VEC_ORDERED_REMOVE_IF_FROM_TO): Define.
* vec.c (test_ordered_remove_if): New function.
(vec_c_tests): Call test_ordered_remove_if.
* dwarf2cfi.c (connect_traces): Use VEC_ORDERED_REMOVE_IF_FROM_TO.
* lto-streamer-out.c (prune_offload_funcs): Use VEC_ORDERED_REMOVE_IF.
* tree-vect-patterns.c (vect_pattern_recog_1): Use
VEC_ORDERED_REMOVE_IF.

From-SVN: r259808

gcc/ChangeLog
gcc/dwarf2cfi.c
gcc/lto-streamer-out.c
gcc/tree-vect-patterns.c
gcc/vec.c
gcc/vec.h

index 2afdd79b158429555c21946c7b02f18607a457d4..5d319c8d588dbb715ead96506ec88cb9cb8e2c78 100644 (file)
@@ -1,3 +1,14 @@
+2018-05-01  Tom de Vries  <tom@codesourcery.com>
+
+       PR other/83786
+       * vec.h (VEC_ORDERED_REMOVE_IF, VEC_ORDERED_REMOVE_IF_FROM_TO): Define.
+       * vec.c (test_ordered_remove_if): New function.
+       (vec_c_tests): Call test_ordered_remove_if.
+       * dwarf2cfi.c (connect_traces): Use VEC_ORDERED_REMOVE_IF_FROM_TO.
+       * lto-streamer-out.c (prune_offload_funcs): Use VEC_ORDERED_REMOVE_IF.
+       * tree-vect-patterns.c (vect_pattern_recog_1): Use
+       VEC_ORDERED_REMOVE_IF.
+
 2018-05-01  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>
 
        PR tree-optimization/82665
index 07e6a5a2887f6014b01aae0a2f69bfe92f371f3e..4cfb91b8d40810ffb1331a1e084a917e0ed7f9c2 100644 (file)
@@ -2719,7 +2719,7 @@ before_next_cfi_note (rtx_insn *start)
 static void
 connect_traces (void)
 {
-  unsigned i, n = trace_info.length ();
+  unsigned i, n;
   dw_trace_info *prev_ti, *ti;
 
   /* ??? Ideally, we should have both queued and processed every trace.
@@ -2730,20 +2730,15 @@ connect_traces (void)
      these are not "real" instructions, and should not be considered.
      This could be generically useful for tablejump data as well.  */
   /* Remove all unprocessed traces from the list.  */
-  for (i = n - 1; i > 0; --i)
-    {
-      ti = &trace_info[i];
-      if (ti->beg_row == NULL)
-       {
-         trace_info.ordered_remove (i);
-         n -= 1;
-       }
-      else
-       gcc_assert (ti->end_row != NULL);
-    }
+  unsigned ix, ix2;
+  VEC_ORDERED_REMOVE_IF_FROM_TO (trace_info, ix, ix2, ti, 1,
+                                trace_info.length (), ti->beg_row == NULL);
+  FOR_EACH_VEC_ELT (trace_info, ix, ti)
+    gcc_assert (ti->end_row != NULL);
 
   /* Work from the end back to the beginning.  This lets us easily insert
      remember/restore_state notes in the correct order wrt other notes.  */
+  n = trace_info.length ();
   prev_ti = &trace_info[n - 1];
   for (i = n - 1; i > 0; --i)
     {
index 70476dc6da8630b6de00152e8fbb151a0b02a326..f614aef201f416736c4d19c48c1e2ad737c57676 100644 (file)
@@ -2360,24 +2360,14 @@ prune_offload_funcs (void)
   if (!offload_funcs)
     return;
 
-  unsigned int write_index = 0;
-  for (unsigned read_index = 0; read_index < vec_safe_length (offload_funcs);
-       read_index++)
-    {
-      tree fn_decl = (*offload_funcs)[read_index];
-      bool remove_p = cgraph_node::get (fn_decl) == NULL;
-      if (remove_p)
-       continue;
-
-      DECL_PRESERVE_P (fn_decl) = 1;
-
-      if (write_index != read_index)
-       (*offload_funcs)[write_index] = (*offload_funcs)[read_index];
-
-      write_index++;
-    }
-
-  offload_funcs->truncate (write_index);
+  unsigned ix, ix2;
+  tree *elem_ptr;
+  VEC_ORDERED_REMOVE_IF (*offload_funcs, ix, ix2, elem_ptr,
+                        cgraph_node::get (*elem_ptr) == NULL);
+
+  tree fn_decl;
+  FOR_EACH_VEC_ELT (*offload_funcs, ix, fn_decl)
+    DECL_PRESERVE_P (fn_decl) = 1;
 }
 
 /* Main entry point from the pass manager.  */
index 621ed07758ff587d3fe6fca0c4ee1a4579a7b6fe..5c2578f046591b8955a8b2d5a3691c82d04e789e 100644 (file)
@@ -4483,7 +4483,6 @@ vect_pattern_recog_1 (vect_recog_func *recog_func,
   tree type_in, type_out;
   enum tree_code code;
   int i;
-  gimple *next;
 
   stmts_to_replace->truncate (0);
   stmts_to_replace->quick_push (stmt);
@@ -4545,9 +4544,12 @@ vect_pattern_recog_1 (vect_recog_func *recog_func,
   /* Patterns cannot be vectorized using SLP, because they change the order of
      computation.  */
   if (loop_vinfo)
-    FOR_EACH_VEC_ELT (LOOP_VINFO_REDUCTIONS (loop_vinfo), i, next)
-      if (next == stmt)
-        LOOP_VINFO_REDUCTIONS (loop_vinfo).ordered_remove (i);
+    {
+      unsigned ix, ix2;
+      gimple **elem_ptr;
+      VEC_ORDERED_REMOVE_IF (LOOP_VINFO_REDUCTIONS (loop_vinfo), ix, ix2,
+                            elem_ptr, *elem_ptr == stmt);
+    }
 
   /* It is possible that additional pattern stmts are created and inserted in
      STMTS_TO_REPLACE.  We create a stmt_info for each of them, and mark the
index 695cd1eba5ad436d02fe7f29ab923907b6e482d7..11924a80a2d244b7cd52d5d86305f89d1798c90c 100644 (file)
--- a/gcc/vec.c
+++ b/gcc/vec.c
@@ -382,6 +382,51 @@ test_ordered_remove ()
   ASSERT_EQ (9, v.length ());
 }
 
+/* Verify that vec::ordered_remove_if works correctly.  */
+
+static void
+test_ordered_remove_if (void)
+{
+  auto_vec <int> v;
+  safe_push_range (v, 0, 10);
+  unsigned ix, ix2;
+  int *elem_ptr;
+  VEC_ORDERED_REMOVE_IF (v, ix, ix2, elem_ptr,
+                        *elem_ptr == 5 || *elem_ptr == 7);
+  ASSERT_EQ (4, v[4]);
+  ASSERT_EQ (6, v[5]);
+  ASSERT_EQ (8, v[6]);
+  ASSERT_EQ (8, v.length ());
+
+  v.truncate (0);
+  safe_push_range (v, 0, 10);
+  VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 0, 6,
+                                *elem_ptr == 5 || *elem_ptr == 7);
+  ASSERT_EQ (4, v[4]);
+  ASSERT_EQ (6, v[5]);
+  ASSERT_EQ (7, v[6]);
+  ASSERT_EQ (9, v.length ());
+
+  v.truncate (0);
+  safe_push_range (v, 0, 10);
+  VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 0, 5,
+                                *elem_ptr == 5 || *elem_ptr == 7);
+  VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 8, 10,
+                                *elem_ptr == 5 || *elem_ptr == 7);
+  ASSERT_EQ (4, v[4]);
+  ASSERT_EQ (5, v[5]);
+  ASSERT_EQ (6, v[6]);
+  ASSERT_EQ (10, v.length ());
+
+  v.truncate (0);
+  safe_push_range (v, 0, 10);
+  VEC_ORDERED_REMOVE_IF (v, ix, ix2, elem_ptr, *elem_ptr == 5);
+  ASSERT_EQ (4, v[4]);
+  ASSERT_EQ (6, v[5]);
+  ASSERT_EQ (7, v[6]);
+  ASSERT_EQ (9, v.length ());
+}
+
 /* Verify that vec::unordered_remove works correctly.  */
 
 static void
@@ -443,6 +488,7 @@ vec_c_tests ()
   test_pop ();
   test_safe_insert ();
   test_ordered_remove ();
+  test_ordered_remove_if ();
   test_unordered_remove ();
   test_block_remove ();
   test_qsort ();
index 4d2046c04af562b06b8a3dbc4d056d7c0dadd8bb..2d1f468ca1c6f47232522bb55ef25a274b4eee67 100644 (file)
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -1028,6 +1028,40 @@ vec<T, A, vl_embed>::ordered_remove (unsigned ix)
 }
 
 
+/* Remove elements in [START, END) from VEC for which COND holds.  Ordering of
+   remaining elements is preserved.  This is an O(N) operation.  */
+
+#define VEC_ORDERED_REMOVE_IF_FROM_TO(vec, read_index, write_index,    \
+                                     elem_ptr, start, end, cond)       \
+  {                                                                    \
+    gcc_assert ((end) <= (vec).length ());                             \
+    for (read_index = write_index = (start); read_index < (end);       \
+        ++read_index)                                                  \
+      {                                                                        \
+       elem_ptr = &(vec)[read_index];                                  \
+       bool remove_p = (cond);                                         \
+       if (remove_p)                                                   \
+         continue;                                                     \
+                                                                       \
+       if (read_index != write_index)                                  \
+         (vec)[write_index] = (vec)[read_index];                       \
+                                                                       \
+       write_index++;                                                  \
+      }                                                                        \
+                                                                       \
+    if (read_index - write_index > 0)                                  \
+      (vec).block_remove (write_index, read_index - write_index);      \
+  }
+
+
+/* Remove elements from VEC for which COND holds.  Ordering of remaining
+   elements is preserved.  This is an O(N) operation.  */
+
+#define VEC_ORDERED_REMOVE_IF(vec, read_index, write_index, elem_ptr,  \
+                             cond)                                     \
+  VEC_ORDERED_REMOVE_IF_FROM_TO ((vec), read_index, write_index,       \
+                                elem_ptr, 0, (vec).length (), (cond))
+
 /* Remove an element from the IXth position of this vector.  Ordering of
    remaining elements is destroyed.  This is an O(1) operation.  */