introduce gcc_stablesort
authorAlexander Monakov <amonakov@ispras.ru>
Mon, 3 Sep 2018 16:51:24 +0000 (19:51 +0300)
committerAlexander Monakov <amonakov@gcc.gnu.org>
Mon, 3 Sep 2018 16:51:24 +0000 (19:51 +0300)
* sort.cc (struct sort_ctx): New field 'nlim'.  Use it...
(mergesort): ... here as maximum count for using netsort.
(gcc_qsort): Set nlim to 3 if stable sort is requested.
(gcc_stablesort): New.
* system.h (gcc_stablesort): Declare.

From-SVN: r264066

gcc/ChangeLog
gcc/sort.cc
gcc/system.h

index bfa9ce6a76e297c248c013a4af22f53459a92ad8..99c5ca75fa18b84fb9f66536a5aadb63cef9a1ef 100644 (file)
@@ -1,3 +1,11 @@
+2018-09-03  Alexander Monakov  <amonakov@ispras.ru>
+
+       * sort.cc (struct sort_ctx): New field 'nlim'.  Use it...
+       (mergesort): ... here as maximum count for using netsort.
+       (gcc_qsort): Set nlim to 3 if stable sort is requested.
+       (gcc_stablesort): New.
+       * system.h (gcc_stablesort): Declare.
+
 2018-09-03  Alexander Monakov  <amonakov@ispras.ru>
 
        * sort.cc (gcc_qsort) [CHECKING_P]: Call qsort_chk.
index 9f8ee12e13b323c2a6d33216360a41f7490d8c31..b3be1eac72bfb07b11b3c8fffeb3cfc645eea445 100644 (file)
@@ -55,6 +55,7 @@ struct sort_ctx
   char   *out; // output buffer
   size_t n;    // number of elements
   size_t size; // element size
+  size_t nlim; // limit for network sort
 };
 
 /* Helper for netsort. Permute, possibly in-place, 2 or 3 elements,
@@ -178,7 +179,7 @@ do {                                  \
 static void
 mergesort (char *in, sort_ctx *c, size_t n, char *out, char *tmp)
 {
-  if (likely (n <= 5))
+  if (likely (n <= c->nlim))
     {
       c->out = out;
       c->n = n;
@@ -221,8 +222,12 @@ gcc_qsort (void *vbase, size_t n, size_t size, cmp_fn *cmp)
 {
   if (n < 2)
     return;
+  size_t nlim = 5;
+  bool stable = (ssize_t) size < 0;
+  if (stable)
+    nlim = 3, size = ~size;
   char *base = (char *)vbase;
-  sort_ctx c = {cmp, base, n, size};
+  sort_ctx c = {cmp, base, n, size, nlim};
   long long scratch[32];
   size_t bufsz = (n / 2) * size;
   void *buf = bufsz <= sizeof scratch ? scratch : xmalloc (bufsz);
@@ -233,3 +238,9 @@ gcc_qsort (void *vbase, size_t n, size_t size, cmp_fn *cmp)
   qsort_chk (vbase, n, size, cmp);
 #endif
 }
+
+void
+gcc_stablesort (void *vbase, size_t n, size_t size, cmp_fn *cmp)
+{
+  gcc_qsort (vbase, n, ~size, cmp);
+}
index 203c6a4f0cfc0b6e8fea8e2522f27727f54d66dc..100feb567c9854508c2d1d15b8164ba33964681b 100644 (file)
@@ -1202,6 +1202,8 @@ helper_const_non_const_cast (const char *p)
    corresponding to vec::qsort (cmp): they use C qsort internally anyway.  */
 void qsort_chk (void *, size_t, size_t, int (*)(const void *, const void *));
 void gcc_qsort (void *, size_t, size_t, int (*)(const void *, const void *));
+void gcc_stablesort (void *, size_t, size_t,
+                    int (*)(const void *, const void *));
 #define PP_5th(a1, a2, a3, a4, a5, ...) a5
 #undef qsort
 #define qsort(...) PP_5th (__VA_ARGS__, gcc_qsort, 3, 2, qsort, 0) (__VA_ARGS__)