00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027 #include "system.h"
00028 #include "coretypes.h"
00029 #include "tm.h"
00030 #include "et-forest.h"
00031 #include "alloc-pool.h"
00032
00033
00034 #undef DEBUG_ET
00035
00036 #ifdef DEBUG_ET
00037 #include "basic-block.h"
00038 #endif
00039
00040
00041 struct et_occ
00042 {
00043 struct et_node *of;
00044
00045 struct et_occ *parent;
00046 struct et_occ *prev;
00047 struct et_occ *next;
00048
00049 int depth;
00050
00051 int min;
00052
00053
00054 struct et_occ *min_occ;
00055
00056 };
00057
00058 static alloc_pool et_nodes;
00059 static alloc_pool et_occurrences;
00060
00061
00062
00063 static inline void
00064 set_depth (struct et_occ *occ, int d)
00065 {
00066 if (!occ)
00067 return;
00068
00069 occ->min += d - occ->depth;
00070 occ->depth = d;
00071 }
00072
00073
00074
00075 static inline void
00076 set_depth_add (struct et_occ *occ, int d)
00077 {
00078 if (!occ)
00079 return;
00080
00081 occ->min += d;
00082 occ->depth += d;
00083 }
00084
00085
00086
00087 static inline void
00088 set_prev (struct et_occ *occ, struct et_occ *t)
00089 {
00090 #ifdef DEBUG_ET
00091 gcc_assert (occ != t);
00092 #endif
00093
00094 occ->prev = t;
00095 if (t)
00096 t->parent = occ;
00097 }
00098
00099
00100
00101 static inline void
00102 set_next (struct et_occ *occ, struct et_occ *t)
00103 {
00104 #ifdef DEBUG_ET
00105 gcc_assert (occ != t);
00106 #endif
00107
00108 occ->next = t;
00109 if (t)
00110 t->parent = occ;
00111 }
00112
00113
00114
00115 static inline void
00116 et_recomp_min (struct et_occ *occ)
00117 {
00118 struct et_occ *mson = occ->prev;
00119
00120 if (!mson
00121 || (occ->next
00122 && mson->min > occ->next->min))
00123 mson = occ->next;
00124
00125 if (mson && mson->min < 0)
00126 {
00127 occ->min = mson->min + occ->depth;
00128 occ->min_occ = mson->min_occ;
00129 }
00130 else
00131 {
00132 occ->min = occ->depth;
00133 occ->min_occ = occ;
00134 }
00135 }
00136
00137 #ifdef DEBUG_ET
00138
00139
00140 static void
00141 et_check_occ_sanity (struct et_occ *occ)
00142 {
00143 if (!occ)
00144 return;
00145
00146 gcc_assert (occ->parent != occ);
00147 gcc_assert (occ->prev != occ);
00148 gcc_assert (occ->next != occ);
00149 gcc_assert (!occ->next || occ->next != occ->prev);
00150
00151 if (occ->next)
00152 {
00153 gcc_assert (occ->next != occ->parent);
00154 gcc_assert (occ->next->parent == occ);
00155 }
00156
00157 if (occ->prev)
00158 {
00159 gcc_assert (occ->prev != occ->parent);
00160 gcc_assert (occ->prev->parent == occ);
00161 }
00162
00163 gcc_assert (!occ->parent
00164 || occ->parent->prev == occ
00165 || occ->parent->next == occ);
00166 }
00167
00168
00169
00170 static void
00171 et_check_sanity (struct et_occ *occ)
00172 {
00173 et_check_occ_sanity (occ);
00174 if (occ->prev)
00175 et_check_sanity (occ->prev);
00176 if (occ->next)
00177 et_check_sanity (occ->next);
00178 }
00179
00180
00181
00182 static void
00183 et_check_tree_sanity (struct et_occ *occ)
00184 {
00185 while (occ->parent)
00186 occ = occ->parent;
00187
00188 et_check_sanity (occ);
00189 }
00190
00191
00192
00193
00194
00195 #define MAX_NODES 100000
00196
00197 static int len;
00198 static void *datas[MAX_NODES];
00199 static int depths[MAX_NODES];
00200
00201
00202
00203 static int
00204 record_path_before_1 (struct et_occ *occ, int depth)
00205 {
00206 int mn, m;
00207
00208 depth += occ->depth;
00209 mn = depth;
00210
00211 if (occ->prev)
00212 {
00213 m = record_path_before_1 (occ->prev, depth);
00214 if (m < mn)
00215 mn = m;
00216 }
00217
00218 fprintf (stderr, "%d (%d); ", ((basic_block) occ->of->data)->index, depth);
00219
00220 gcc_assert (len < MAX_NODES);
00221
00222 depths[len] = depth;
00223 datas[len] = occ->of;
00224 len++;
00225
00226 if (occ->next)
00227 {
00228 m = record_path_before_1 (occ->next, depth);
00229 if (m < mn)
00230 mn = m;
00231 }
00232
00233 gcc_assert (mn == occ->min + depth - occ->depth);
00234
00235 return mn;
00236 }
00237
00238
00239
00240 static void
00241 record_path_before (struct et_occ *occ)
00242 {
00243 while (occ->parent)
00244 occ = occ->parent;
00245
00246 len = 0;
00247 record_path_before_1 (occ, 0);
00248 fprintf (stderr, "\n");
00249 }
00250
00251
00252
00253
00254 static int
00255 check_path_after_1 (struct et_occ *occ, int depth)
00256 {
00257 int mn, m;
00258
00259 depth += occ->depth;
00260 mn = depth;
00261
00262 if (occ->next)
00263 {
00264 m = check_path_after_1 (occ->next, depth);
00265 if (m < mn)
00266 mn = m;
00267 }
00268
00269 len--;
00270 gcc_assert (depths[len] == depth && datas[len] == occ->of);
00271
00272 if (occ->prev)
00273 {
00274 m = check_path_after_1 (occ->prev, depth);
00275 if (m < mn)
00276 mn = m;
00277 }
00278
00279 gcc_assert (mn == occ->min + depth - occ->depth);
00280
00281 return mn;
00282 }
00283
00284
00285
00286
00287 static void
00288 check_path_after (struct et_occ *occ)
00289 {
00290 while (occ->parent)
00291 occ = occ->parent;
00292
00293 check_path_after_1 (occ, 0);
00294 gcc_assert (!len);
00295 }
00296
00297 #endif
00298
00299
00300
00301 static void
00302 et_splay (struct et_occ *occ)
00303 {
00304 struct et_occ *f, *gf, *ggf;
00305 int occ_depth, f_depth, gf_depth;
00306
00307 #ifdef DEBUG_ET
00308 record_path_before (occ);
00309 et_check_tree_sanity (occ);
00310 #endif
00311
00312 while (occ->parent)
00313 {
00314 occ_depth = occ->depth;
00315
00316 f = occ->parent;
00317 f_depth = f->depth;
00318
00319 gf = f->parent;
00320
00321 if (!gf)
00322 {
00323 set_depth_add (occ, f_depth);
00324 occ->min_occ = f->min_occ;
00325 occ->min = f->min;
00326
00327 if (f->prev == occ)
00328 {
00329
00330 set_prev (f, occ->next);
00331 set_next (occ, f);
00332 set_depth_add (f->prev, occ_depth);
00333 }
00334 else
00335 {
00336
00337 set_next (f, occ->prev);
00338 set_prev (occ, f);
00339 set_depth_add (f->next, occ_depth);
00340 }
00341 set_depth (f, -occ_depth);
00342 occ->parent = NULL;
00343
00344 et_recomp_min (f);
00345 #ifdef DEBUG_ET
00346 et_check_tree_sanity (occ);
00347 check_path_after (occ);
00348 #endif
00349 return;
00350 }
00351
00352 gf_depth = gf->depth;
00353
00354 set_depth_add (occ, f_depth + gf_depth);
00355 occ->min_occ = gf->min_occ;
00356 occ->min = gf->min;
00357
00358 ggf = gf->parent;
00359
00360 if (gf->prev == f)
00361 {
00362 if (f->prev == occ)
00363 {
00364
00365 set_prev (gf, f->next);
00366 set_prev (f, occ->next);
00367 set_next (occ, f);
00368 set_next (f, gf);
00369
00370 set_depth (f, -occ_depth);
00371 set_depth_add (f->prev, occ_depth);
00372 set_depth (gf, -f_depth);
00373 set_depth_add (gf->prev, f_depth);
00374 }
00375 else
00376 {
00377
00378 set_prev (gf, occ->next);
00379 set_next (f, occ->prev);
00380 set_prev (occ, f);
00381 set_next (occ, gf);
00382
00383 set_depth (f, -occ_depth);
00384 set_depth_add (f->next, occ_depth);
00385 set_depth (gf, -occ_depth - f_depth);
00386 set_depth_add (gf->prev, occ_depth + f_depth);
00387 }
00388 }
00389 else
00390 {
00391 if (f->prev == occ)
00392 {
00393
00394 set_next (gf, occ->prev);
00395 set_prev (f, occ->next);
00396 set_prev (occ, gf);
00397 set_next (occ, f);
00398
00399 set_depth (f, -occ_depth);
00400 set_depth_add (f->prev, occ_depth);
00401 set_depth (gf, -occ_depth - f_depth);
00402 set_depth_add (gf->next, occ_depth + f_depth);
00403 }
00404 else
00405 {
00406
00407 set_next (gf, f->prev);
00408 set_next (f, occ->prev);
00409 set_prev (occ, f);
00410 set_prev (f, gf);
00411
00412 set_depth (f, -occ_depth);
00413 set_depth_add (f->next, occ_depth);
00414 set_depth (gf, -f_depth);
00415 set_depth_add (gf->next, f_depth);
00416 }
00417 }
00418
00419 occ->parent = ggf;
00420 if (ggf)
00421 {
00422 if (ggf->prev == gf)
00423 ggf->prev = occ;
00424 else
00425 ggf->next = occ;
00426 }
00427
00428 et_recomp_min (gf);
00429 et_recomp_min (f);
00430 #ifdef DEBUG_ET
00431 et_check_tree_sanity (occ);
00432 #endif
00433 }
00434
00435 #ifdef DEBUG_ET
00436 et_check_sanity (occ);
00437 check_path_after (occ);
00438 #endif
00439 }
00440
00441
00442
00443 static struct et_occ *
00444 et_new_occ (struct et_node *node)
00445 {
00446 struct et_occ *nw;
00447
00448 if (!et_occurrences)
00449 et_occurrences = create_alloc_pool ("et_occ pool", sizeof (struct et_occ), 300);
00450 nw = pool_alloc (et_occurrences);
00451
00452 nw->of = node;
00453 nw->parent = NULL;
00454 nw->prev = NULL;
00455 nw->next = NULL;
00456
00457 nw->depth = 0;
00458 nw->min_occ = nw;
00459 nw->min = 0;
00460
00461 return nw;
00462 }
00463
00464
00465
00466 struct et_node *
00467 et_new_tree (void *data)
00468 {
00469 struct et_node *nw;
00470
00471 if (!et_nodes)
00472 et_nodes = create_alloc_pool ("et_node pool", sizeof (struct et_node), 300);
00473 nw = pool_alloc (et_nodes);
00474
00475 nw->data = data;
00476 nw->father = NULL;
00477 nw->left = NULL;
00478 nw->right = NULL;
00479 nw->son = NULL;
00480
00481 nw->rightmost_occ = et_new_occ (nw);
00482 nw->parent_occ = NULL;
00483
00484 return nw;
00485 }
00486
00487
00488
00489 void
00490 et_free_tree (struct et_node *t)
00491 {
00492 while (t->son)
00493 et_split (t->son);
00494
00495 if (t->father)
00496 et_split (t);
00497
00498 pool_free (et_occurrences, t->rightmost_occ);
00499 pool_free (et_nodes, t);
00500 }
00501
00502
00503
00504 void
00505 et_set_father (struct et_node *t, struct et_node *father)
00506 {
00507 struct et_node *left, *right;
00508 struct et_occ *rmost, *left_part, *new_f_occ, *p;
00509
00510
00511 new_f_occ = et_new_occ (father);
00512
00513 rmost = father->rightmost_occ;
00514 et_splay (rmost);
00515
00516 left_part = rmost->prev;
00517
00518 p = t->rightmost_occ;
00519 et_splay (p);
00520
00521 set_prev (new_f_occ, left_part);
00522 set_next (new_f_occ, p);
00523
00524 p->depth++;
00525 p->min++;
00526 et_recomp_min (new_f_occ);
00527
00528 set_prev (rmost, new_f_occ);
00529
00530 if (new_f_occ->min + rmost->depth < rmost->min)
00531 {
00532 rmost->min = new_f_occ->min + rmost->depth;
00533 rmost->min_occ = new_f_occ->min_occ;
00534 }
00535
00536 t->parent_occ = new_f_occ;
00537
00538
00539 t->father = father;
00540 right = father->son;
00541 if (right)
00542 left = right->left;
00543 else
00544 left = right = t;
00545
00546 left->right = t;
00547 right->left = t;
00548 t->left = left;
00549 t->right = right;
00550
00551 father->son = t;
00552
00553 #ifdef DEBUG_ET
00554 et_check_tree_sanity (rmost);
00555 record_path_before (rmost);
00556 #endif
00557 }
00558
00559
00560
00561 void
00562 et_split (struct et_node *t)
00563 {
00564 struct et_node *father = t->father;
00565 struct et_occ *r, *l, *rmost, *p_occ;
00566
00567
00568 rmost = t->rightmost_occ;
00569 et_splay (rmost);
00570
00571 for (r = rmost->next; r->prev; r = r->prev)
00572 continue;
00573 et_splay (r);
00574
00575 r->prev->parent = NULL;
00576 p_occ = t->parent_occ;
00577 et_splay (p_occ);
00578 t->parent_occ = NULL;
00579
00580 l = p_occ->prev;
00581 p_occ->next->parent = NULL;
00582
00583 set_prev (r, l);
00584
00585 et_recomp_min (r);
00586
00587 et_splay (rmost);
00588 rmost->depth = 0;
00589 rmost->min = 0;
00590
00591 pool_free (et_occurrences, p_occ);
00592
00593
00594 if (father->son == t)
00595 father->son = t->right;
00596 if (father->son == t)
00597 father->son = NULL;
00598 else
00599 {
00600 t->left->right = t->right;
00601 t->right->left = t->left;
00602 }
00603 t->left = t->right = NULL;
00604 t->father = NULL;
00605
00606 #ifdef DEBUG_ET
00607 et_check_tree_sanity (rmost);
00608 record_path_before (rmost);
00609
00610 et_check_tree_sanity (r);
00611 record_path_before (r);
00612 #endif
00613 }
00614
00615
00616
00617 struct et_node *
00618 et_nca (struct et_node *n1, struct et_node *n2)
00619 {
00620 struct et_occ *o1 = n1->rightmost_occ, *o2 = n2->rightmost_occ, *om;
00621 struct et_occ *l, *r, *ret;
00622 int mn;
00623
00624 if (n1 == n2)
00625 return n1;
00626
00627 et_splay (o1);
00628 l = o1->prev;
00629 r = o1->next;
00630 if (l)
00631 l->parent = NULL;
00632 if (r)
00633 r->parent = NULL;
00634 et_splay (o2);
00635
00636 if (l == o2 || (l && l->parent != NULL))
00637 {
00638 ret = o2->next;
00639
00640 set_prev (o1, o2);
00641 if (r)
00642 r->parent = o1;
00643 }
00644 else
00645 {
00646 ret = o2->prev;
00647
00648 set_next (o1, o2);
00649 if (l)
00650 l->parent = o1;
00651 }
00652
00653 if (0 < o2->depth)
00654 {
00655 om = o1;
00656 mn = o1->depth;
00657 }
00658 else
00659 {
00660 om = o2;
00661 mn = o2->depth + o1->depth;
00662 }
00663
00664 #ifdef DEBUG_ET
00665 et_check_tree_sanity (o2);
00666 #endif
00667
00668 if (ret && ret->min + o1->depth + o2->depth < mn)
00669 return ret->min_occ->of;
00670 else
00671 return om->of;
00672 }
00673
00674
00675
00676 bool
00677 et_below (struct et_node *down, struct et_node *up)
00678 {
00679 struct et_occ *u = up->rightmost_occ, *d = down->rightmost_occ;
00680 struct et_occ *l, *r;
00681
00682 if (up == down)
00683 return true;
00684
00685 et_splay (u);
00686 l = u->prev;
00687 r = u->next;
00688
00689 if (!l)
00690 return false;
00691
00692 l->parent = NULL;
00693
00694 if (r)
00695 r->parent = NULL;
00696
00697 et_splay (d);
00698
00699 if (l == d || l->parent != NULL)
00700 {
00701 if (r)
00702 r->parent = u;
00703 set_prev (u, d);
00704 #ifdef DEBUG_ET
00705 et_check_tree_sanity (u);
00706 #endif
00707 }
00708 else
00709 {
00710 l->parent = u;
00711
00712
00713
00714 if (r && r->parent != NULL)
00715 set_next (u, d);
00716 else
00717 set_next (u, r);
00718
00719 #ifdef DEBUG_ET
00720 et_check_tree_sanity (u);
00721 #endif
00722 return false;
00723 }
00724
00725 if (0 >= d->depth)
00726 return false;
00727
00728 return !d->next || d->next->min + d->depth >= 0;
00729 }