diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-12-18 16:27:56 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-12-18 16:27:56 +0000 |
commit | ae2ff033958a853da6cd41707cb3569699a34e26 (patch) | |
tree | e24b06f1be9a92ca6df09de559af58b46545513a /gcc/unwind-dw2-fde.c | |
parent | c6ca897a9cf9b52f3d4590d899b0313d143ec09e (diff) | |
download | gcc-ae2ff033958a853da6cd41707cb3569699a34e26.tar.gz |
* unwind-dw2-fde.c (frame_downheap): Split out from...
(frame_heapsort): Here.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@60253 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/unwind-dw2-fde.c')
-rw-r--r-- | gcc/unwind-dw2-fde.c | 89 |
1 files changed, 42 insertions, 47 deletions
diff --git a/gcc/unwind-dw2-fde.c b/gcc/unwind-dw2-fde.c index 7f3aeaf3e16..b1bd8c03111 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 } |