From: Jason Merrill Date: Wed, 18 Dec 2002 16:27:56 +0000 (-0500) Subject: unwind-dw2-fde.c (frame_downheap): Split out from... X-Git-Tag: releases/gcc-3.4.0~9926 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=80d83b160fb4d8426d7e8625a99157f778daedeb;p=thirdparty%2Fgcc.git unwind-dw2-fde.c (frame_downheap): Split out from... * unwind-dw2-fde.c (frame_downheap): Split out from... (frame_heapsort): Here. From-SVN: r60253 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dca13eff81a4..ed8a64d3a06d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2002-12-18 Jason Merrill + + * unwind-dw2-fde.c (frame_downheap): Split out from... + (frame_heapsort): Here. + 2002-12-17 Jason Merrill * tree.c (make_node): Don't set TREE_TYPE on 's' class nodes. diff --git a/gcc/unwind-dw2-fde.c b/gcc/unwind-dw2-fde.c index 7f3aeaf3e162..b1bd8c031115 100644 --- a/gcc/unwind-dw2-fde.c +++ b/gcc/unwind-dw2-fde.c @@ -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 }