et-forest.c 14.8 KB
Newer Older
1
/* ET-trees data structure implementation.
2
   Contributed by Pavel Nejedly
3
   Copyright (C) 2002-2013 Free Software Foundation, Inc.
4 5 6 7 8

This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
9
version 3 of the License, or (at your option) any later version.
10 11 12 13 14 15 16

Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
17 18
License along with libiberty; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.
19 20 21 22 23 24 25 26

  The ET-forest structure is described in:
    D. D. Sleator and R. E. Tarjan. A data structure for dynamic trees.
    J.  G'omput. System Sci., 26(3):362 381, 1983.
*/

#include "config.h"
#include "system.h"
27
#include "coretypes.h"
28
#include "et-forest.h"
29
#include "alloc-pool.h"
30

31 32
/* We do not enable this with ENABLE_CHECKING, since it is awfully slow.  */
#undef DEBUG_ET
33

34
#ifdef DEBUG_ET
35
#include "basic-block.h" /* To access index in record_path_before_1.  */
36
#endif
37

38
/* The occurrence of a node in the et tree.  */
39
struct et_occ
40
{
41 42 43 44 45 46 47 48 49 50 51
  struct et_node *of;		/* The node.  */

  struct et_occ *parent;	/* Parent in the splay-tree.  */
  struct et_occ *prev;		/* Left son in the splay-tree.  */
  struct et_occ *next;		/* Right son in the splay-tree.  */

  int depth;			/* The depth of the node is the sum of depth
				   fields on the path to the root.  */
  int min;			/* The minimum value of the depth in the subtree
				   is obtained by adding sum of depth fields
				   on the path to the root.  */
52
  struct et_occ *min_occ;	/* The occurrence in the subtree with the minimal
53 54
				   depth.  */
};
55

56
static alloc_pool et_nodes;
57
static alloc_pool et_occurrences;
58

59
/* Changes depth of OCC to D.  */
60

61 62 63 64 65
static inline void
set_depth (struct et_occ *occ, int d)
{
  if (!occ)
    return;
66

67 68 69
  occ->min += d - occ->depth;
  occ->depth = d;
}
70

71
/* Adds D to the depth of OCC.  */
72

73 74
static inline void
set_depth_add (struct et_occ *occ, int d)
75
{
76 77
  if (!occ)
    return;
78

79 80 81
  occ->min += d;
  occ->depth += d;
}
82

83
/* Sets prev field of OCC to P.  */
84

85 86
static inline void
set_prev (struct et_occ *occ, struct et_occ *t)
87
{
88
#ifdef DEBUG_ET
89
  gcc_assert (occ != t);
90
#endif
91

92 93 94
  occ->prev = t;
  if (t)
    t->parent = occ;
95 96
}

97 98 99 100
/* Sets next field of OCC to P.  */

static inline void
set_next (struct et_occ *occ, struct et_occ *t)
101
{
102
#ifdef DEBUG_ET
103
  gcc_assert (occ != t);
104 105 106 107 108
#endif

  occ->next = t;
  if (t)
    t->parent = occ;
109 110
}

111
/* Recompute minimum for occurrence OCC.  */
112

113 114
static inline void
et_recomp_min (struct et_occ *occ)
115
{
116
  struct et_occ *mson = occ->prev;
117

118 119 120 121
  if (!mson
      || (occ->next
	  && mson->min > occ->next->min))
      mson = occ->next;
122

123 124 125 126 127 128 129 130 131 132 133
  if (mson && mson->min < 0)
    {
      occ->min = mson->min + occ->depth;
      occ->min_occ = mson->min_occ;
    }
  else
    {
      occ->min = occ->depth;
      occ->min_occ = occ;
    }
}
134

135
#ifdef DEBUG_ET
136
/* Checks whether neighborhood of OCC seems sane.  */
137

138 139 140 141 142
static void
et_check_occ_sanity (struct et_occ *occ)
{
  if (!occ)
    return;
143

144 145 146 147
  gcc_assert (occ->parent != occ);
  gcc_assert (occ->prev != occ);
  gcc_assert (occ->next != occ);
  gcc_assert (!occ->next || occ->next != occ->prev);
148

149
  if (occ->next)
150
    {
151 152
      gcc_assert (occ->next != occ->parent);
      gcc_assert (occ->next->parent == occ);
153
    }
154 155

  if (occ->prev)
156
    {
157 158
      gcc_assert (occ->prev != occ->parent);
      gcc_assert (occ->prev->parent == occ);
159 160
    }

161 162 163
  gcc_assert (!occ->parent
	      || occ->parent->prev == occ
	      || occ->parent->next == occ);
164 165
}

166 167
/* Checks whether tree rooted at OCC is sane.  */

168
static void
169
et_check_sanity (struct et_occ *occ)
170
{
171 172 173 174 175 176
  et_check_occ_sanity (occ);
  if (occ->prev)
    et_check_sanity (occ->prev);
  if (occ->next)
    et_check_sanity (occ->next);
}
177

178
/* Checks whether tree containing OCC is sane.  */
179

180 181 182 183 184
static void
et_check_tree_sanity (struct et_occ *occ)
{
  while (occ->parent)
    occ = occ->parent;
185

186 187
  et_check_sanity (occ);
}
188

189
/* For recording the paths.  */
190

191 192 193 194
/* An ad-hoc constant; if the function has more blocks, this won't work,
   but since it is used for debugging only, it does not matter.  */
#define MAX_NODES 100000

195
static int len;
196 197
static void *datas[MAX_NODES];
static int depths[MAX_NODES];
198

199
/* Records the path represented by OCC, with depth incremented by DEPTH.  */
200

201 202 203 204
static int
record_path_before_1 (struct et_occ *occ, int depth)
{
  int mn, m;
205

206 207 208 209 210
  depth += occ->depth;
  mn = depth;

  if (occ->prev)
    {
H.J. Lu committed
211
      m = record_path_before_1 (occ->prev, depth);
212 213
      if (m < mn)
	mn = m;
214 215
    }

216
  fprintf (stderr, "%d (%d); ", ((basic_block) occ->of->data)->index, depth);
217

218
  gcc_assert (len < MAX_NODES);
219

220 221 222 223 224
  depths[len] = depth;
  datas[len] = occ->of;
  len++;

  if (occ->next)
225
    {
226 227 228 229
      m = record_path_before_1 (occ->next, depth);
      if (m < mn)
	mn = m;
    }
230

231
  gcc_assert (mn == occ->min + depth - occ->depth);
232

233 234
  return mn;
}
235

236
/* Records the path represented by a tree containing OCC.  */
237

238 239 240 241 242
static void
record_path_before (struct et_occ *occ)
{
  while (occ->parent)
    occ = occ->parent;
243

244 245 246
  len = 0;
  record_path_before_1 (occ, 0);
  fprintf (stderr, "\n");
247 248
}

249 250 251 252 253
/* Checks whether the path represented by OCC, with depth incremented by DEPTH,
   was not changed since the last recording.  */

static int
check_path_after_1 (struct et_occ *occ, int depth)
254
{
255 256 257 258
  int mn, m;

  depth += occ->depth;
  mn = depth;
259

260
  if (occ->next)
261
    {
H.J. Lu committed
262
      m = check_path_after_1 (occ->next, depth);
263 264 265
      if (m < mn)
	mn =  m;
    }
266

267
  len--;
268
  gcc_assert (depths[len] == depth && datas[len] == occ->of);
269 270 271 272 273 274

  if (occ->prev)
    {
      m = check_path_after_1 (occ->prev, depth);
      if (m < mn)
	mn =  m;
275 276
    }

277
  gcc_assert (mn == occ->min + depth - occ->depth);
278 279

  return mn;
280 281
}

282 283 284 285 286 287 288 289 290 291
/* Checks whether the path represented by a tree containing OCC was
   not changed since the last recording.  */

static void
check_path_after (struct et_occ *occ)
{
  while (occ->parent)
    occ = occ->parent;

  check_path_after_1 (occ, 0);
292
  gcc_assert (!len);
293
}
294

295
#endif
296

297
/* Splay the occurrence OCC to the root of the tree.  */
298

299
static void
300
et_splay (struct et_occ *occ)
301
{
302 303 304 305 306 307 308
  struct et_occ *f, *gf, *ggf;
  int occ_depth, f_depth, gf_depth;

#ifdef DEBUG_ET
  record_path_before (occ);
  et_check_tree_sanity (occ);
#endif
H.J. Lu committed
309

310 311 312
  while (occ->parent)
    {
      occ_depth = occ->depth;
313

314 315
      f = occ->parent;
      f_depth = f->depth;
316

317
      gf = f->parent;
318

319 320 321 322 323
      if (!gf)
	{
	  set_depth_add (occ, f_depth);
	  occ->min_occ = f->min_occ;
	  occ->min = f->min;
324

325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
	  if (f->prev == occ)
	    {
	      /* zig */
	      set_prev (f, occ->next);
	      set_next (occ, f);
	      set_depth_add (f->prev, occ_depth);
	    }
	  else
	    {
	      /* zag */
	      set_next (f, occ->prev);
	      set_prev (occ, f);
	      set_depth_add (f->next, occ_depth);
	    }
	  set_depth (f, -occ_depth);
	  occ->parent = NULL;

	  et_recomp_min (f);
#ifdef DEBUG_ET
	  et_check_tree_sanity (occ);
	  check_path_after (occ);
#endif
	  return;
	}

      gf_depth = gf->depth;

      set_depth_add (occ, f_depth + gf_depth);
      occ->min_occ = gf->min_occ;
      occ->min = gf->min;

      ggf = gf->parent;

      if (gf->prev == f)
	{
	  if (f->prev == occ)
	    {
	      /* zig zig */
	      set_prev (gf, f->next);
	      set_prev (f, occ->next);
	      set_next (occ, f);
	      set_next (f, gf);

	      set_depth (f, -occ_depth);
	      set_depth_add (f->prev, occ_depth);
	      set_depth (gf, -f_depth);
	      set_depth_add (gf->prev, f_depth);
	    }
	  else
	    {
	      /* zag zig */
	      set_prev (gf, occ->next);
	      set_next (f, occ->prev);
	      set_prev (occ, f);
	      set_next (occ, gf);

	      set_depth (f, -occ_depth);
	      set_depth_add (f->next, occ_depth);
	      set_depth (gf, -occ_depth - f_depth);
	      set_depth_add (gf->prev, occ_depth + f_depth);
	    }
	}
      else
	{
	  if (f->prev == occ)
	    {
	      /* zig zag */
	      set_next (gf, occ->prev);
	      set_prev (f, occ->next);
	      set_prev (occ, gf);
	      set_next (occ, f);

	      set_depth (f, -occ_depth);
	      set_depth_add (f->prev, occ_depth);
	      set_depth (gf, -occ_depth - f_depth);
	      set_depth_add (gf->next, occ_depth + f_depth);
	    }
	  else
	    {
	      /* zag zag */
	      set_next (gf, f->prev);
	      set_next (f, occ->prev);
	      set_prev (occ, f);
	      set_prev (f, gf);

	      set_depth (f, -occ_depth);
	      set_depth_add (f->next, occ_depth);
	      set_depth (gf, -f_depth);
	      set_depth_add (gf->next, f_depth);
	    }
	}

      occ->parent = ggf;
      if (ggf)
	{
	  if (ggf->prev == gf)
	    ggf->prev = occ;
	  else
	    ggf->next = occ;
	}

      et_recomp_min (gf);
      et_recomp_min (f);
#ifdef DEBUG_ET
      et_check_tree_sanity (occ);
#endif
    }

#ifdef DEBUG_ET
  et_check_sanity (occ);
  check_path_after (occ);
#endif
}

439
/* Create a new et tree occurrence of NODE.  */
440 441 442

static struct et_occ *
et_new_occ (struct et_node *node)
443
{
444
  struct et_occ *nw;
H.J. Lu committed
445

446 447
  if (!et_occurrences)
    et_occurrences = create_alloc_pool ("et_occ pool", sizeof (struct et_occ), 300);
448
  nw = (struct et_occ *) pool_alloc (et_occurrences);
449 450 451 452 453 454 455 456 457 458 459

  nw->of = node;
  nw->parent = NULL;
  nw->prev = NULL;
  nw->next = NULL;

  nw->depth = 0;
  nw->min_occ = nw;
  nw->min = 0;

  return nw;
460 461
}

462 463 464 465
/* Create a new et tree containing DATA.  */

struct et_node *
et_new_tree (void *data)
466
{
467
  struct et_node *nw;
H.J. Lu committed
468

469 470
  if (!et_nodes)
    et_nodes = create_alloc_pool ("et_node pool", sizeof (struct et_node), 300);
471
  nw = (struct et_node *) pool_alloc (et_nodes);
472 473 474 475 476 477 478 479 480 481 482

  nw->data = data;
  nw->father = NULL;
  nw->left = NULL;
  nw->right = NULL;
  nw->son = NULL;

  nw->rightmost_occ = et_new_occ (nw);
  nw->parent_occ = NULL;

  return nw;
483 484
}

485 486 487 488
/* Releases et tree T.  */

void
et_free_tree (struct et_node *t)
489
{
490 491
  while (t->son)
    et_split (t->son);
492

493 494
  if (t->father)
    et_split (t);
495

496
  pool_free (et_occurrences, t->rightmost_occ);
497
  pool_free (et_nodes, t);
498 499
}

500 501 502 503 504 505
/* Releases et tree T without maintaining other nodes.  */

void
et_free_tree_force (struct et_node *t)
{
  pool_free (et_occurrences, t->rightmost_occ);
506 507
  if (t->parent_occ)
    pool_free (et_occurrences, t->parent_occ);
508 509 510
  pool_free (et_nodes, t);
}

511 512 513 514 515 516 517 518 519
/* Release the alloc pools, if they are empty.  */

void
et_free_pools (void)
{
  free_alloc_pool_if_empty (&et_occurrences);
  free_alloc_pool_if_empty (&et_nodes);
}

520 521
/* Sets father of et tree T to FATHER.  */

522
void
523
et_set_father (struct et_node *t, struct et_node *father)
524
{
525 526
  struct et_node *left, *right;
  struct et_occ *rmost, *left_part, *new_f_occ, *p;
527

528 529
  /* Update the path represented in the splay tree.  */
  new_f_occ = et_new_occ (father);
530

531 532
  rmost = father->rightmost_occ;
  et_splay (rmost);
533

534
  left_part = rmost->prev;
535

536 537
  p = t->rightmost_occ;
  et_splay (p);
538

539 540 541 542 543 544
  set_prev (new_f_occ, left_part);
  set_next (new_f_occ, p);

  p->depth++;
  p->min++;
  et_recomp_min (new_f_occ);
545

546
  set_prev (rmost, new_f_occ);
547

548 549 550 551 552
  if (new_f_occ->min + rmost->depth < rmost->min)
    {
      rmost->min = new_f_occ->min + rmost->depth;
      rmost->min_occ = new_f_occ->min_occ;
    }
553

554
  t->parent_occ = new_f_occ;
555

556 557 558 559 560 561 562
  /* Update the tree.  */
  t->father = father;
  right = father->son;
  if (right)
    left = right->left;
  else
    left = right = t;
563

564 565 566 567
  left->right = t;
  right->left = t;
  t->left = left;
  t->right = right;
568

569
  father->son = t;
570

571 572 573 574
#ifdef DEBUG_ET
  et_check_tree_sanity (rmost);
  record_path_before (rmost);
#endif
575 576
}

577 578 579 580
/* Splits the edge from T to its father.  */

void
et_split (struct et_node *t)
581
{
582 583
  struct et_node *father = t->father;
  struct et_occ *r, *l, *rmost, *p_occ;
584

585 586 587
  /* Update the path represented by the splay tree.  */
  rmost = t->rightmost_occ;
  et_splay (rmost);
588

589 590
  for (r = rmost->next; r->prev; r = r->prev)
    continue;
H.J. Lu committed
591
  et_splay (r);
592

593 594 595 596
  r->prev->parent = NULL;
  p_occ = t->parent_occ;
  et_splay (p_occ);
  t->parent_occ = NULL;
597

598 599
  l = p_occ->prev;
  p_occ->next->parent = NULL;
600

601
  set_prev (r, l);
602

603
  et_recomp_min (r);
604

605 606 607
  et_splay (rmost);
  rmost->depth = 0;
  rmost->min = 0;
608

609
  pool_free (et_occurrences, p_occ);
610

611 612 613 614 615 616
  /* Update the tree.  */
  if (father->son == t)
    father->son = t->right;
  if (father->son == t)
    father->son = NULL;
  else
617
    {
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660
      t->left->right = t->right;
      t->right->left = t->left;
    }
  t->left = t->right = NULL;
  t->father = NULL;

#ifdef DEBUG_ET
  et_check_tree_sanity (rmost);
  record_path_before (rmost);

  et_check_tree_sanity (r);
  record_path_before (r);
#endif
}

/* Finds the nearest common ancestor of the nodes N1 and N2.  */

struct et_node *
et_nca (struct et_node *n1, struct et_node *n2)
{
  struct et_occ *o1 = n1->rightmost_occ, *o2 = n2->rightmost_occ, *om;
  struct et_occ *l, *r, *ret;
  int mn;

  if (n1 == n2)
    return n1;

  et_splay (o1);
  l = o1->prev;
  r = o1->next;
  if (l)
    l->parent = NULL;
  if (r)
    r->parent = NULL;
  et_splay (o2);

  if (l == o2 || (l && l->parent != NULL))
    {
      ret = o2->next;

      set_prev (o1, o2);
      if (r)
	r->parent = o1;
661
    }
662
  else if (r == o2 || (r && r->parent != NULL))
663
    {
664 665 666 667 668
      ret = o2->prev;

      set_next (o1, o2);
      if (l)
	l->parent = o1;
669
    }
670 671 672 673 674 675 676 677 678
  else
    {
      /* O1 and O2 are in different components of the forest.  */
      if (l)
	l->parent = o1;
      if (r)
	r->parent = o1;
      return NULL;
    }
679

680
  if (0 < o2->depth)
681
    {
682 683 684 685 686 687 688
      om = o1;
      mn = o1->depth;
    }
  else
    {
      om = o2;
      mn = o2->depth + o1->depth;
689 690
    }

691 692 693
#ifdef DEBUG_ET
  et_check_tree_sanity (o2);
#endif
694

695 696 697 698
  if (ret && ret->min + o1->depth + o2->depth < mn)
    return ret->min_occ->of;
  else
    return om->of;
699 700
}

701 702 703 704
/* Checks whether the node UP is an ancestor of the node DOWN.  */

bool
et_below (struct et_node *down, struct et_node *up)
705
{
706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
  struct et_occ *u = up->rightmost_occ, *d = down->rightmost_occ;
  struct et_occ *l, *r;

  if (up == down)
    return true;

  et_splay (u);
  l = u->prev;
  r = u->next;

  if (!l)
    return false;

  l->parent = NULL;

  if (r)
    r->parent = NULL;
723

724 725 726
  et_splay (d);

  if (l == d || l->parent != NULL)
727
    {
728 729 730 731 732 733
      if (r)
	r->parent = u;
      set_prev (u, d);
#ifdef DEBUG_ET
      et_check_tree_sanity (u);
#endif
734
    }
735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755
  else
    {
      l->parent = u;

      /* In case O1 and O2 are in two different trees, we must just restore the
	 original state.  */
      if (r && r->parent != NULL)
	set_next (u, d);
      else
	set_next (u, r);

#ifdef DEBUG_ET
      et_check_tree_sanity (u);
#endif
      return false;
    }

  if (0 >= d->depth)
    return false;

  return !d->next || d->next->min + d->depth >= 0;
756
}
757 758 759 760 761 762 763 764

/* Returns the root of the tree that contains NODE.  */

struct et_node *
et_root (struct et_node *node)
{
  struct et_occ *occ = node->rightmost_occ, *r;

765
  /* The root of the tree corresponds to the rightmost occurrence in the
766 767 768 769 770 771 772 773
     represented path.  */
  et_splay (occ);
  for (r = occ; r->next; r = r->next)
    continue;
  et_splay (r);

  return r->of;
}