libgomp: Fix "intelmic" offloading in build-tree testing.
[gcc.git] / libgomp / splay-tree.h
1 /* A splay-tree datatype.
2 Copyright (C) 1998-2015 Free Software Foundation, Inc.
3 Contributed by Mark Mitchell (mark@markmitchell.com).
4
5 This file is part of the GNU OpenMP Library (libgomp).
6
7 Libgomp is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 more details.
16
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
25
26 /* The splay tree code copied from include/splay-tree.h and adjusted,
27 so that all the data lives directly in splay_tree_node_s structure
28 and no extra allocations are needed.
29
30 Files including this header should before including it add:
31 typedef struct splay_tree_node_s *splay_tree_node;
32 typedef struct splay_tree_s *splay_tree;
33 typedef struct splay_tree_key_s *splay_tree_key;
34 define splay_tree_key_s structure, and define
35 splay_compare inline function. */
36
37 /* For an easily readable description of splay-trees, see:
38
39 Lewis, Harry R. and Denenberg, Larry. Data Structures and Their
40 Algorithms. Harper-Collins, Inc. 1991.
41
42 The major feature of splay trees is that all basic tree operations
43 are amortized O(log n) time for a tree with n nodes. */
44
45 /* The nodes in the splay tree. */
46 struct splay_tree_node_s {
47 struct splay_tree_key_s key;
48 /* The left and right children, respectively. */
49 splay_tree_node left;
50 splay_tree_node right;
51 };
52
53 /* The splay tree. */
54 struct splay_tree_s {
55 splay_tree_node root;
56 };
57
58 /* Rotate the edge joining the left child N with its parent P. PP is the
59 grandparents' pointer to P. */
60
61 static inline void
62 rotate_left (splay_tree_node *pp, splay_tree_node p, splay_tree_node n)
63 {
64 splay_tree_node tmp;
65 tmp = n->right;
66 n->right = p;
67 p->left = tmp;
68 *pp = n;
69 }
70
71 /* Rotate the edge joining the right child N with its parent P. PP is the
72 grandparents' pointer to P. */
73
74 static inline void
75 rotate_right (splay_tree_node *pp, splay_tree_node p, splay_tree_node n)
76 {
77 splay_tree_node tmp;
78 tmp = n->left;
79 n->left = p;
80 p->right = tmp;
81 *pp = n;
82 }
83
84 /* Bottom up splay of KEY. */
85
86 static void
87 splay_tree_splay (splay_tree sp, splay_tree_key key)
88 {
89 if (sp->root == NULL)
90 return;
91
92 do {
93 int cmp1, cmp2;
94 splay_tree_node n, c;
95
96 n = sp->root;
97 cmp1 = splay_compare (key, &n->key);
98
99 /* Found. */
100 if (cmp1 == 0)
101 return;
102
103 /* Left or right? If no child, then we're done. */
104 if (cmp1 < 0)
105 c = n->left;
106 else
107 c = n->right;
108 if (!c)
109 return;
110
111 /* Next one left or right? If found or no child, we're done
112 after one rotation. */
113 cmp2 = splay_compare (key, &c->key);
114 if (cmp2 == 0
115 || (cmp2 < 0 && !c->left)
116 || (cmp2 > 0 && !c->right))
117 {
118 if (cmp1 < 0)
119 rotate_left (&sp->root, n, c);
120 else
121 rotate_right (&sp->root, n, c);
122 return;
123 }
124
125 /* Now we have the four cases of double-rotation. */
126 if (cmp1 < 0 && cmp2 < 0)
127 {
128 rotate_left (&n->left, c, c->left);
129 rotate_left (&sp->root, n, n->left);
130 }
131 else if (cmp1 > 0 && cmp2 > 0)
132 {
133 rotate_right (&n->right, c, c->right);
134 rotate_right (&sp->root, n, n->right);
135 }
136 else if (cmp1 < 0 && cmp2 > 0)
137 {
138 rotate_right (&n->left, c, c->right);
139 rotate_left (&sp->root, n, n->left);
140 }
141 else if (cmp1 > 0 && cmp2 < 0)
142 {
143 rotate_left (&n->right, c, c->left);
144 rotate_right (&sp->root, n, n->right);
145 }
146 } while (1);
147 }
148
149 /* Insert a new NODE into SP. The NODE shouldn't exist in the tree. */
150
151 static void
152 splay_tree_insert (splay_tree sp, splay_tree_node node)
153 {
154 int comparison = 0;
155
156 splay_tree_splay (sp, &node->key);
157
158 if (sp->root)
159 comparison = splay_compare (&sp->root->key, &node->key);
160
161 if (sp->root && comparison == 0)
162 abort ();
163 else
164 {
165 /* Insert it at the root. */
166 if (sp->root == NULL)
167 node->left = node->right = NULL;
168 else if (comparison < 0)
169 {
170 node->left = sp->root;
171 node->right = node->left->right;
172 node->left->right = NULL;
173 }
174 else
175 {
176 node->right = sp->root;
177 node->left = node->right->left;
178 node->right->left = NULL;
179 }
180
181 sp->root = node;
182 }
183 }
184
185 /* Remove node with KEY from SP. It is not an error if it did not exist. */
186
187 static void
188 splay_tree_remove (splay_tree sp, splay_tree_key key)
189 {
190 splay_tree_splay (sp, key);
191
192 if (sp->root && splay_compare (&sp->root->key, key) == 0)
193 {
194 splay_tree_node left, right;
195
196 left = sp->root->left;
197 right = sp->root->right;
198
199 /* One of the children is now the root. Doesn't matter much
200 which, so long as we preserve the properties of the tree. */
201 if (left)
202 {
203 sp->root = left;
204
205 /* If there was a right child as well, hang it off the
206 right-most leaf of the left child. */
207 if (right)
208 {
209 while (left->right)
210 left = left->right;
211 left->right = right;
212 }
213 }
214 else
215 sp->root = right;
216 }
217 }
218
219 /* Lookup KEY in SP, returning NODE if present, and NULL
220 otherwise. */
221
222 static splay_tree_key
223 splay_tree_lookup (splay_tree sp, splay_tree_key key)
224 {
225 splay_tree_splay (sp, key);
226
227 if (sp->root && splay_compare (&sp->root->key, key) == 0)
228 return &sp->root->key;
229 else
230 return NULL;
231 }