* unwind-dw2-fde.c (frame_downheap): Split out from...
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 18 Dec 2002 16:27:56 +0000 (16:27 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 18 Dec 2002 16:27:56 +0000 (16:27 +0000)
        (frame_heapsort): Here.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@60253 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/unwind-dw2-fde.c

index dca13ef..ed8a64d 100644 (file)
@@ -1,3 +1,8 @@
+2002-12-18  Jason Merrill  <jason@redhat.com>
+
+       * unwind-dw2-fde.c (frame_downheap): Split out from...
+       (frame_heapsort): Here.
+
 2002-12-17  Jason Merrill  <jason@redhat.com>
 
        * tree.c (make_node): Don't set TREE_TYPE on 's' class nodes.
index 7f3aeaf..b1bd8c0 100644 (file)
@@ -467,6 +467,34 @@ fde_split (struct object *ob, fde_compare_t fde_compare,
   erratic->count = k;
 }
 
+#define SWAP(x,y) do { fde * tmp = x; x = y; y = tmp; } while (0)
+
+/* Convert a semi-heap to a heap.  A semi-heap is a heap except possibly
+   for the first (root) node; push it down to its rightful place.  */
+
+static void
+frame_downheap (struct object *ob, fde_compare_t fde_compare, fde **a,
+               int lo, int hi)
+{
+  int i, j;
+
+  for (i = lo, j = 2*i+1;
+       j < hi;
+       j = 2*i+1)
+    {
+      if (j+1 < hi && fde_compare (ob, a[j], a[j+1]) < 0)
+       ++j;
+
+      if (fde_compare (ob, a[i], a[j]) < 0)
+       {
+         SWAP (a[i], a[j]);
+         i = j;
+       }
+      else
+       break;
+    }
+}
+
 /* This is O(n log(n)).  BSD/OS defines heapsort in stdlib.h, so we must
    use a name that does not conflict.  */
 
@@ -481,55 +509,22 @@ frame_heapsort (struct object *ob, fde_compare_t fde_compare,
   /* A portion of the array is called a "heap" if for all i>=0:
      If i and 2i+1 are valid indices, then a[i] >= a[2i+1].
      If i and 2i+2 are valid indices, then a[i] >= a[2i+2].  */
-#define SWAP(x,y) do { fde * tmp = x; x = y; y = tmp; } while (0)
   size_t n = erratic->count;
-  size_t m = n;
-  size_t i;
-
-  while (m > 0)
+  int m;
+
+  /* Expand our heap incrementally from the end of the array, heapifying
+     each resulting semi-heap as we go.  After each step, a[m] is the top
+     of a heap.  */
+  for (m = n/2-1; m >= 0; --m)
+    frame_downheap (ob, fde_compare, a, m, n);
+
+  /* Shrink our heap incrementally from the end of the array, first
+     swapping out the largest element a[0] and then re-heapifying the
+     resulting semi-heap.  After each step, a[0..m) is a heap.  */
+  for (m = n-1; m >= 1; --m)
     {
-      /* Invariant: a[m..n-1] is a heap.  */
-      m--;
-      for (i = m; 2*i+1 < n; )
-       {
-         if (2*i+2 < n
-             && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
-             && fde_compare (ob, a[2*i+2], a[i]) > 0)
-           {
-             SWAP (a[i], a[2*i+2]);
-             i = 2*i+2;
-           }
-         else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
-           {
-             SWAP (a[i], a[2*i+1]);
-             i = 2*i+1;
-           }
-         else
-           break;
-       }
-    }
-  while (n > 1)
-    {
-      /* Invariant: a[0..n-1] is a heap.  */
-      n--;
-      SWAP (a[0], a[n]);
-      for (i = 0; 2*i+1 < n; )
-       {
-         if (2*i+2 < n
-             && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
-             && fde_compare (ob, a[2*i+2], a[i]) > 0)
-           {
-             SWAP (a[i], a[2*i+2]);
-             i = 2*i+2;
-           }
-         else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
-           {
-             SWAP (a[i], a[2*i+1]);
-             i = 2*i+1;
-           }
-         else
-           break;
-       }
+      SWAP (a[0], a[m]);
+      frame_downheap (ob, fde_compare, a, 0, m);
     }
 #undef SWAP
 }