Mercurial > hg > CbC > CbC_gcc
comparison gcc/ira-build.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 /* Building internal representation for IRA. | 1 /* Building internal representation for IRA. |
2 Copyright (C) 2006, 2007, 2008, 2009 | 2 Copyright (C) 2006, 2007, 2008, 2009, 2010 |
3 Free Software Foundation, Inc. | 3 Free Software Foundation, Inc. |
4 Contributed by Vladimir Makarov <vmakarov@redhat.com>. | 4 Contributed by Vladimir Makarov <vmakarov@redhat.com>. |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
30 #include "flags.h" | 30 #include "flags.h" |
31 #include "hard-reg-set.h" | 31 #include "hard-reg-set.h" |
32 #include "basic-block.h" | 32 #include "basic-block.h" |
33 #include "insn-config.h" | 33 #include "insn-config.h" |
34 #include "recog.h" | 34 #include "recog.h" |
35 #include "toplev.h" | 35 #include "diagnostic-core.h" |
36 #include "params.h" | 36 #include "params.h" |
37 #include "df.h" | 37 #include "df.h" |
38 #include "output.h" | 38 #include "output.h" |
39 #include "reload.h" | 39 #include "reload.h" |
40 #include "sparseset.h" | 40 #include "sparseset.h" |
41 #include "ira-int.h" | 41 #include "ira-int.h" |
42 #include "emit-rtl.h" /* FIXME: Can go away once crtl is moved to rtl.h. */ | |
42 | 43 |
43 static ira_copy_t find_allocno_copy (ira_allocno_t, ira_allocno_t, rtx, | 44 static ira_copy_t find_allocno_copy (ira_allocno_t, ira_allocno_t, rtx, |
44 ira_loop_tree_node_t); | 45 ira_loop_tree_node_t); |
45 | 46 |
46 /* The root of the loop tree corresponding to the all function. */ | 47 /* The root of the loop tree corresponding to the all function. */ |
68 ira_allocno_t *ira_allocnos; | 69 ira_allocno_t *ira_allocnos; |
69 | 70 |
70 /* Sizes of the previous array. */ | 71 /* Sizes of the previous array. */ |
71 int ira_allocnos_num; | 72 int ira_allocnos_num; |
72 | 73 |
73 /* Map conflict id -> allocno with given conflict id (see comments for | 74 /* Count of conflict record structures we've created, used when creating |
74 allocno member `conflict_id'). */ | 75 a new conflict id. */ |
75 ira_allocno_t *ira_conflict_id_allocno_map; | 76 int ira_objects_num; |
77 | |
78 /* Map a conflict id to its conflict record. */ | |
79 ira_object_t *ira_object_id_map; | |
76 | 80 |
77 /* Array of references to all copies. The order number of the copy | 81 /* Array of references to all copies. The order number of the copy |
78 corresponds to the index in the array. Removed copies have NULL | 82 corresponds to the index in the array. Removed copies have NULL |
79 element value. */ | 83 element value. */ |
80 ira_copy_t *ira_copies; | 84 ira_copy_t *ira_copies; |
120 } | 124 } |
121 ira_loop_nodes = ((struct ira_loop_tree_node *) | 125 ira_loop_nodes = ((struct ira_loop_tree_node *) |
122 ira_allocate (sizeof (struct ira_loop_tree_node) | 126 ira_allocate (sizeof (struct ira_loop_tree_node) |
123 * VEC_length (loop_p, ira_loops.larray))); | 127 * VEC_length (loop_p, ira_loops.larray))); |
124 max_regno = max_reg_num (); | 128 max_regno = max_reg_num (); |
125 for (i = 0; VEC_iterate (loop_p, ira_loops.larray, i, loop); i++) | 129 FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) |
126 { | 130 { |
127 if (loop != ira_loops.tree_root) | 131 if (loop != ira_loops.tree_root) |
128 { | 132 { |
129 ira_loop_nodes[i].regno_allocno_map = NULL; | 133 ira_loop_nodes[i].regno_allocno_map = NULL; |
130 if (! loops_p) | 134 if (! loops_p) |
138 break; | 142 break; |
139 } | 143 } |
140 if (skip_p) | 144 if (skip_p) |
141 continue; | 145 continue; |
142 edges = get_loop_exit_edges (loop); | 146 edges = get_loop_exit_edges (loop); |
143 for (j = 0; VEC_iterate (edge, edges, j, e); j++) | 147 FOR_EACH_VEC_ELT (edge, edges, j, e) |
144 if ((e->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (e)) | 148 if ((e->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (e)) |
145 { | 149 { |
146 skip_p = true; | 150 skip_p = true; |
147 break; | 151 break; |
148 } | 152 } |
169 more_one_region_p (void) | 173 more_one_region_p (void) |
170 { | 174 { |
171 unsigned int i; | 175 unsigned int i; |
172 loop_p loop; | 176 loop_p loop; |
173 | 177 |
174 for (i = 0; VEC_iterate (loop_p, ira_loops.larray, i, loop); i++) | 178 FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) |
175 if (ira_loop_nodes[i].regno_allocno_map != NULL | 179 if (ira_loop_nodes[i].regno_allocno_map != NULL |
176 && ira_loop_tree_root != &ira_loop_nodes[i]) | 180 && ira_loop_tree_root != &ira_loop_nodes[i]) |
177 return true; | 181 return true; |
178 return false; | 182 return false; |
179 } | 183 } |
199 finish_loop_tree_nodes (void) | 203 finish_loop_tree_nodes (void) |
200 { | 204 { |
201 unsigned int i; | 205 unsigned int i; |
202 loop_p loop; | 206 loop_p loop; |
203 | 207 |
204 for (i = 0; VEC_iterate (loop_p, ira_loops.larray, i, loop); i++) | 208 FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) |
205 finish_loop_tree_node (&ira_loop_nodes[i]); | 209 finish_loop_tree_node (&ira_loop_nodes[i]); |
206 ira_free (ira_loop_nodes); | 210 ira_free (ira_loop_nodes); |
207 for (i = 0; i < (unsigned int) last_basic_block_before_change; i++) | 211 for (i = 0; i < (unsigned int) last_basic_block_before_change; i++) |
208 { | 212 { |
209 if (ira_bb_nodes[i].local_copies != NULL) | 213 if (ira_bb_nodes[i].local_copies != NULL) |
302 loop_p loop; | 306 loop_p loop; |
303 | 307 |
304 /* We can not use loop/bb node access macros because of potential | 308 /* We can not use loop/bb node access macros because of potential |
305 checking and because the nodes are not initialized enough | 309 checking and because the nodes are not initialized enough |
306 yet. */ | 310 yet. */ |
307 for (i = 0; VEC_iterate (loop_p, ira_loops.larray, i, loop); i++) | 311 FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) |
308 if (ira_loop_nodes[i].regno_allocno_map != NULL) | 312 if (ira_loop_nodes[i].regno_allocno_map != NULL) |
309 { | 313 { |
310 ira_loop_nodes[i].children = NULL; | 314 ira_loop_nodes[i].children = NULL; |
311 ira_loop_nodes[i].subloops = NULL; | 315 ira_loop_nodes[i].subloops = NULL; |
312 } | 316 } |
348 ira_loop_tree_node_t loop_tree_node; | 352 ira_loop_tree_node_t loop_tree_node; |
349 loop_p loop; | 353 loop_p loop; |
350 ira_allocno_iterator ai; | 354 ira_allocno_iterator ai; |
351 | 355 |
352 max_regno = max_reg_num (); | 356 max_regno = max_reg_num (); |
353 for (l = 0; VEC_iterate (loop_p, ira_loops.larray, l, loop); l++) | 357 FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, l, loop) |
354 if (ira_loop_nodes[l].regno_allocno_map != NULL) | 358 if (ira_loop_nodes[l].regno_allocno_map != NULL) |
355 { | 359 { |
356 ira_free (ira_loop_nodes[l].regno_allocno_map); | 360 ira_free (ira_loop_nodes[l].regno_allocno_map); |
357 ira_loop_nodes[l].regno_allocno_map | 361 ira_loop_nodes[l].regno_allocno_map |
358 = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t) | 362 = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t) |
377 /* Remember that we can create temporary allocnos to break | 381 /* Remember that we can create temporary allocnos to break |
378 cycles in register shuffle. */ | 382 cycles in register shuffle. */ |
379 loop_tree_node->regno_allocno_map[regno] = a; | 383 loop_tree_node->regno_allocno_map[regno] = a; |
380 } | 384 } |
381 } | 385 } |
382 | |
383 | 386 |
384 | 387 |
385 /* Pools for allocnos and allocno live ranges. */ | 388 /* Pools for allocnos, allocno live ranges and objects. */ |
386 static alloc_pool allocno_pool, allocno_live_range_pool; | 389 static alloc_pool allocno_pool, live_range_pool, object_pool; |
387 | 390 |
388 /* Vec containing references to all created allocnos. It is a | 391 /* Vec containing references to all created allocnos. It is a |
389 container of array allocnos. */ | 392 container of array allocnos. */ |
390 static VEC(ira_allocno_t,heap) *allocno_vec; | 393 static VEC(ira_allocno_t,heap) *allocno_vec; |
391 | 394 |
392 /* Vec containing references to all created allocnos. It is a | 395 /* Vec containing references to all created ira_objects. It is a |
393 container of ira_conflict_id_allocno_map. */ | 396 container of ira_object_id_map. */ |
394 static VEC(ira_allocno_t,heap) *ira_conflict_id_allocno_map_vec; | 397 static VEC(ira_object_t,heap) *ira_object_id_map_vec; |
395 | 398 |
396 /* Initialize data concerning allocnos. */ | 399 /* Initialize data concerning allocnos. */ |
397 static void | 400 static void |
398 initiate_allocnos (void) | 401 initiate_allocnos (void) |
399 { | 402 { |
400 allocno_live_range_pool | 403 live_range_pool |
401 = create_alloc_pool ("allocno live ranges", | 404 = create_alloc_pool ("live ranges", |
402 sizeof (struct ira_allocno_live_range), 100); | 405 sizeof (struct live_range), 100); |
403 allocno_pool | 406 allocno_pool |
404 = create_alloc_pool ("allocnos", sizeof (struct ira_allocno), 100); | 407 = create_alloc_pool ("allocnos", sizeof (struct ira_allocno), 100); |
408 object_pool | |
409 = create_alloc_pool ("objects", sizeof (struct ira_object), 100); | |
405 allocno_vec = VEC_alloc (ira_allocno_t, heap, max_reg_num () * 2); | 410 allocno_vec = VEC_alloc (ira_allocno_t, heap, max_reg_num () * 2); |
406 ira_allocnos = NULL; | 411 ira_allocnos = NULL; |
407 ira_allocnos_num = 0; | 412 ira_allocnos_num = 0; |
408 ira_conflict_id_allocno_map_vec | 413 ira_objects_num = 0; |
409 = VEC_alloc (ira_allocno_t, heap, max_reg_num () * 2); | 414 ira_object_id_map_vec |
410 ira_conflict_id_allocno_map = NULL; | 415 = VEC_alloc (ira_object_t, heap, max_reg_num () * 2); |
416 ira_object_id_map = NULL; | |
411 ira_regno_allocno_map | 417 ira_regno_allocno_map |
412 = (ira_allocno_t *) ira_allocate (max_reg_num () * sizeof (ira_allocno_t)); | 418 = (ira_allocno_t *) ira_allocate (max_reg_num () * sizeof (ira_allocno_t)); |
413 memset (ira_regno_allocno_map, 0, max_reg_num () * sizeof (ira_allocno_t)); | 419 memset (ira_regno_allocno_map, 0, max_reg_num () * sizeof (ira_allocno_t)); |
420 } | |
421 | |
422 /* Create and return an object corresponding to a new allocno A. */ | |
423 static ira_object_t | |
424 ira_create_object (ira_allocno_t a, int subword) | |
425 { | |
426 enum reg_class cover_class = ALLOCNO_COVER_CLASS (a); | |
427 ira_object_t obj = (ira_object_t) pool_alloc (object_pool); | |
428 | |
429 OBJECT_ALLOCNO (obj) = a; | |
430 OBJECT_SUBWORD (obj) = subword; | |
431 OBJECT_CONFLICT_ID (obj) = ira_objects_num; | |
432 OBJECT_CONFLICT_VEC_P (obj) = false; | |
433 OBJECT_CONFLICT_ARRAY (obj) = NULL; | |
434 OBJECT_NUM_CONFLICTS (obj) = 0; | |
435 COPY_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), ira_no_alloc_regs); | |
436 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), ira_no_alloc_regs); | |
437 IOR_COMPL_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), | |
438 reg_class_contents[cover_class]); | |
439 IOR_COMPL_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), | |
440 reg_class_contents[cover_class]); | |
441 OBJECT_MIN (obj) = INT_MAX; | |
442 OBJECT_MAX (obj) = -1; | |
443 OBJECT_LIVE_RANGES (obj) = NULL; | |
444 | |
445 VEC_safe_push (ira_object_t, heap, ira_object_id_map_vec, obj); | |
446 ira_object_id_map | |
447 = VEC_address (ira_object_t, ira_object_id_map_vec); | |
448 ira_objects_num = VEC_length (ira_object_t, ira_object_id_map_vec); | |
449 | |
450 return obj; | |
414 } | 451 } |
415 | 452 |
416 /* Create and return the allocno corresponding to REGNO in | 453 /* Create and return the allocno corresponding to REGNO in |
417 LOOP_TREE_NODE. Add the allocno to the list of allocnos with the | 454 LOOP_TREE_NODE. Add the allocno to the list of allocnos with the |
418 same regno if CAP_P is FALSE. */ | 455 same regno if CAP_P is FALSE. */ |
436 } | 473 } |
437 ALLOCNO_CAP (a) = NULL; | 474 ALLOCNO_CAP (a) = NULL; |
438 ALLOCNO_CAP_MEMBER (a) = NULL; | 475 ALLOCNO_CAP_MEMBER (a) = NULL; |
439 ALLOCNO_NUM (a) = ira_allocnos_num; | 476 ALLOCNO_NUM (a) = ira_allocnos_num; |
440 bitmap_set_bit (loop_tree_node->all_allocnos, ALLOCNO_NUM (a)); | 477 bitmap_set_bit (loop_tree_node->all_allocnos, ALLOCNO_NUM (a)); |
441 ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) = NULL; | |
442 ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = 0; | |
443 COPY_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), ira_no_alloc_regs); | |
444 COPY_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), ira_no_alloc_regs); | |
445 ALLOCNO_NREFS (a) = 0; | 478 ALLOCNO_NREFS (a) = 0; |
446 ALLOCNO_FREQ (a) = 0; | 479 ALLOCNO_FREQ (a) = 0; |
447 ALLOCNO_HARD_REGNO (a) = -1; | 480 ALLOCNO_HARD_REGNO (a) = -1; |
448 ALLOCNO_CALL_FREQ (a) = 0; | 481 ALLOCNO_CALL_FREQ (a) = 0; |
449 ALLOCNO_CALLS_CROSSED_NUM (a) = 0; | 482 ALLOCNO_CALLS_CROSSED_NUM (a) = 0; |
459 ALLOCNO_BAD_SPILL_P (a) = false; | 492 ALLOCNO_BAD_SPILL_P (a) = false; |
460 ALLOCNO_IN_GRAPH_P (a) = false; | 493 ALLOCNO_IN_GRAPH_P (a) = false; |
461 ALLOCNO_ASSIGNED_P (a) = false; | 494 ALLOCNO_ASSIGNED_P (a) = false; |
462 ALLOCNO_MAY_BE_SPILLED_P (a) = false; | 495 ALLOCNO_MAY_BE_SPILLED_P (a) = false; |
463 ALLOCNO_SPLAY_REMOVED_P (a) = false; | 496 ALLOCNO_SPLAY_REMOVED_P (a) = false; |
464 ALLOCNO_CONFLICT_VEC_P (a) = false; | |
465 ALLOCNO_MODE (a) = (regno < 0 ? VOIDmode : PSEUDO_REGNO_MODE (regno)); | 497 ALLOCNO_MODE (a) = (regno < 0 ? VOIDmode : PSEUDO_REGNO_MODE (regno)); |
466 ALLOCNO_COPIES (a) = NULL; | 498 ALLOCNO_COPIES (a) = NULL; |
467 ALLOCNO_HARD_REG_COSTS (a) = NULL; | 499 ALLOCNO_HARD_REG_COSTS (a) = NULL; |
468 ALLOCNO_CONFLICT_HARD_REG_COSTS (a) = NULL; | 500 ALLOCNO_CONFLICT_HARD_REG_COSTS (a) = NULL; |
469 ALLOCNO_UPDATED_HARD_REG_COSTS (a) = NULL; | 501 ALLOCNO_UPDATED_HARD_REG_COSTS (a) = NULL; |
477 ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) = 0; | 509 ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) = 0; |
478 ALLOCNO_NEXT_BUCKET_ALLOCNO (a) = NULL; | 510 ALLOCNO_NEXT_BUCKET_ALLOCNO (a) = NULL; |
479 ALLOCNO_PREV_BUCKET_ALLOCNO (a) = NULL; | 511 ALLOCNO_PREV_BUCKET_ALLOCNO (a) = NULL; |
480 ALLOCNO_FIRST_COALESCED_ALLOCNO (a) = a; | 512 ALLOCNO_FIRST_COALESCED_ALLOCNO (a) = a; |
481 ALLOCNO_NEXT_COALESCED_ALLOCNO (a) = a; | 513 ALLOCNO_NEXT_COALESCED_ALLOCNO (a) = a; |
482 ALLOCNO_LIVE_RANGES (a) = NULL; | 514 ALLOCNO_NUM_OBJECTS (a) = 0; |
483 ALLOCNO_MIN (a) = INT_MAX; | 515 |
484 ALLOCNO_MAX (a) = -1; | |
485 ALLOCNO_CONFLICT_ID (a) = ira_allocnos_num; | |
486 VEC_safe_push (ira_allocno_t, heap, allocno_vec, a); | 516 VEC_safe_push (ira_allocno_t, heap, allocno_vec, a); |
487 ira_allocnos = VEC_address (ira_allocno_t, allocno_vec); | 517 ira_allocnos = VEC_address (ira_allocno_t, allocno_vec); |
488 ira_allocnos_num = VEC_length (ira_allocno_t, allocno_vec); | 518 ira_allocnos_num = VEC_length (ira_allocno_t, allocno_vec); |
489 VEC_safe_push (ira_allocno_t, heap, ira_conflict_id_allocno_map_vec, a); | 519 |
490 ira_conflict_id_allocno_map | |
491 = VEC_address (ira_allocno_t, ira_conflict_id_allocno_map_vec); | |
492 return a; | 520 return a; |
493 } | 521 } |
494 | 522 |
495 /* Set up cover class for A and update its conflict hard registers. */ | 523 /* Set up cover class for A and update its conflict hard registers. */ |
496 void | 524 void |
497 ira_set_allocno_cover_class (ira_allocno_t a, enum reg_class cover_class) | 525 ira_set_allocno_cover_class (ira_allocno_t a, enum reg_class cover_class) |
498 { | 526 { |
499 ALLOCNO_COVER_CLASS (a) = cover_class; | 527 ALLOCNO_COVER_CLASS (a) = cover_class; |
500 IOR_COMPL_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), | 528 } |
501 reg_class_contents[cover_class]); | 529 |
502 IOR_COMPL_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), | 530 /* Determine the number of objects we should associate with allocno A |
503 reg_class_contents[cover_class]); | 531 and allocate them. */ |
504 } | 532 void |
505 | 533 ira_create_allocno_objects (ira_allocno_t a) |
506 /* Return TRUE if the conflict vector with NUM elements is more | 534 { |
507 profitable than conflict bit vector for A. */ | 535 enum machine_mode mode = ALLOCNO_MODE (a); |
536 enum reg_class cover_class = ALLOCNO_COVER_CLASS (a); | |
537 int n = ira_reg_class_nregs[cover_class][mode]; | |
538 int i; | |
539 | |
540 if (GET_MODE_SIZE (mode) != 2 * UNITS_PER_WORD || n != 2) | |
541 n = 1; | |
542 | |
543 ALLOCNO_NUM_OBJECTS (a) = n; | |
544 for (i = 0; i < n; i++) | |
545 ALLOCNO_OBJECT (a, i) = ira_create_object (a, i); | |
546 } | |
547 | |
548 /* For each allocno, set ALLOCNO_NUM_OBJECTS and create the | |
549 ALLOCNO_OBJECT structures. This must be called after the cover | |
550 classes are known. */ | |
551 static void | |
552 create_allocno_objects (void) | |
553 { | |
554 ira_allocno_t a; | |
555 ira_allocno_iterator ai; | |
556 | |
557 FOR_EACH_ALLOCNO (a, ai) | |
558 ira_create_allocno_objects (a); | |
559 } | |
560 | |
561 /* Merge hard register conflict information for all objects associated with | |
562 allocno TO into the corresponding objects associated with FROM. | |
563 If TOTAL_ONLY is true, we only merge OBJECT_TOTAL_CONFLICT_HARD_REGS. */ | |
564 static void | |
565 merge_hard_reg_conflicts (ira_allocno_t from, ira_allocno_t to, | |
566 bool total_only) | |
567 { | |
568 int i; | |
569 gcc_assert (ALLOCNO_NUM_OBJECTS (to) == ALLOCNO_NUM_OBJECTS (from)); | |
570 for (i = 0; i < ALLOCNO_NUM_OBJECTS (to); i++) | |
571 { | |
572 ira_object_t from_obj = ALLOCNO_OBJECT (from, i); | |
573 ira_object_t to_obj = ALLOCNO_OBJECT (to, i); | |
574 if (!total_only) | |
575 IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (to_obj), | |
576 OBJECT_CONFLICT_HARD_REGS (from_obj)); | |
577 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (to_obj), | |
578 OBJECT_TOTAL_CONFLICT_HARD_REGS (from_obj)); | |
579 } | |
580 #ifdef STACK_REGS | |
581 if (!total_only && ALLOCNO_NO_STACK_REG_P (from)) | |
582 ALLOCNO_NO_STACK_REG_P (to) = true; | |
583 if (ALLOCNO_TOTAL_NO_STACK_REG_P (from)) | |
584 ALLOCNO_TOTAL_NO_STACK_REG_P (to) = true; | |
585 #endif | |
586 } | |
587 | |
588 /* Update hard register conflict information for all objects associated with | |
589 A to include the regs in SET. */ | |
590 void | |
591 ior_hard_reg_conflicts (ira_allocno_t a, HARD_REG_SET *set) | |
592 { | |
593 ira_allocno_object_iterator i; | |
594 ira_object_t obj; | |
595 FOR_EACH_ALLOCNO_OBJECT (a, obj, i) | |
596 { | |
597 IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), *set); | |
598 IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), *set); | |
599 } | |
600 } | |
601 | |
602 /* Return TRUE if a conflict vector with NUM elements is more | |
603 profitable than a conflict bit vector for OBJ. */ | |
508 bool | 604 bool |
509 ira_conflict_vector_profitable_p (ira_allocno_t a, int num) | 605 ira_conflict_vector_profitable_p (ira_object_t obj, int num) |
510 { | 606 { |
511 int nw; | 607 int nw; |
512 | 608 int max = OBJECT_MAX (obj); |
513 if (ALLOCNO_MAX (a) < ALLOCNO_MIN (a)) | 609 int min = OBJECT_MIN (obj); |
514 /* We prefer bit vector in such case because it does not result in | 610 |
515 allocation. */ | 611 if (max < min) |
612 /* We prefer a bit vector in such case because it does not result | |
613 in allocation. */ | |
516 return false; | 614 return false; |
517 | 615 |
518 nw = (ALLOCNO_MAX (a) - ALLOCNO_MIN (a) + IRA_INT_BITS) / IRA_INT_BITS; | 616 nw = (max - min + IRA_INT_BITS) / IRA_INT_BITS; |
519 return (2 * sizeof (ira_allocno_t) * (num + 1) | 617 return (2 * sizeof (ira_object_t) * (num + 1) |
520 < 3 * nw * sizeof (IRA_INT_TYPE)); | 618 < 3 * nw * sizeof (IRA_INT_TYPE)); |
521 } | 619 } |
522 | 620 |
523 /* Allocates and initialize the conflict vector of A for NUM | 621 /* Allocates and initialize the conflict vector of OBJ for NUM |
524 conflicting allocnos. */ | 622 conflicting objects. */ |
525 void | 623 void |
526 ira_allocate_allocno_conflict_vec (ira_allocno_t a, int num) | 624 ira_allocate_conflict_vec (ira_object_t obj, int num) |
527 { | 625 { |
528 int size; | 626 int size; |
529 ira_allocno_t *vec; | 627 ira_object_t *vec; |
530 | 628 |
531 ira_assert (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) == NULL); | 629 ira_assert (OBJECT_CONFLICT_ARRAY (obj) == NULL); |
532 num++; /* for NULL end marker */ | 630 num++; /* for NULL end marker */ |
533 size = sizeof (ira_allocno_t) * num; | 631 size = sizeof (ira_object_t) * num; |
534 ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) = ira_allocate (size); | 632 OBJECT_CONFLICT_ARRAY (obj) = ira_allocate (size); |
535 vec = (ira_allocno_t *) ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a); | 633 vec = (ira_object_t *) OBJECT_CONFLICT_ARRAY (obj); |
536 vec[0] = NULL; | 634 vec[0] = NULL; |
537 ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = 0; | 635 OBJECT_NUM_CONFLICTS (obj) = 0; |
538 ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a) = size; | 636 OBJECT_CONFLICT_ARRAY_SIZE (obj) = size; |
539 ALLOCNO_CONFLICT_VEC_P (a) = true; | 637 OBJECT_CONFLICT_VEC_P (obj) = true; |
540 } | 638 } |
541 | 639 |
542 /* Allocate and initialize the conflict bit vector of A. */ | 640 /* Allocate and initialize the conflict bit vector of OBJ. */ |
543 static void | 641 static void |
544 allocate_allocno_conflict_bit_vec (ira_allocno_t a) | 642 allocate_conflict_bit_vec (ira_object_t obj) |
545 { | 643 { |
546 unsigned int size; | 644 unsigned int size; |
547 | 645 |
548 ira_assert (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) == NULL); | 646 ira_assert (OBJECT_CONFLICT_ARRAY (obj) == NULL); |
549 size = ((ALLOCNO_MAX (a) - ALLOCNO_MIN (a) + IRA_INT_BITS) | 647 size = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS) |
550 / IRA_INT_BITS * sizeof (IRA_INT_TYPE)); | 648 / IRA_INT_BITS * sizeof (IRA_INT_TYPE)); |
551 ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) = ira_allocate (size); | 649 OBJECT_CONFLICT_ARRAY (obj) = ira_allocate (size); |
552 memset (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a), 0, size); | 650 memset (OBJECT_CONFLICT_ARRAY (obj), 0, size); |
553 ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a) = size; | 651 OBJECT_CONFLICT_ARRAY_SIZE (obj) = size; |
554 ALLOCNO_CONFLICT_VEC_P (a) = false; | 652 OBJECT_CONFLICT_VEC_P (obj) = false; |
555 } | 653 } |
556 | 654 |
557 /* Allocate and initialize the conflict vector or conflict bit vector | 655 /* Allocate and initialize the conflict vector or conflict bit vector |
558 of A for NUM conflicting allocnos whatever is more profitable. */ | 656 of OBJ for NUM conflicting allocnos whatever is more profitable. */ |
559 void | 657 void |
560 ira_allocate_allocno_conflicts (ira_allocno_t a, int num) | 658 ira_allocate_object_conflicts (ira_object_t obj, int num) |
561 { | 659 { |
562 if (ira_conflict_vector_profitable_p (a, num)) | 660 if (ira_conflict_vector_profitable_p (obj, num)) |
563 ira_allocate_allocno_conflict_vec (a, num); | 661 ira_allocate_conflict_vec (obj, num); |
564 else | 662 else |
565 allocate_allocno_conflict_bit_vec (a); | 663 allocate_conflict_bit_vec (obj); |
566 } | 664 } |
567 | 665 |
568 /* Add A2 to the conflicts of A1. */ | 666 /* Add OBJ2 to the conflicts of OBJ1. */ |
569 static void | 667 static void |
570 add_to_allocno_conflicts (ira_allocno_t a1, ira_allocno_t a2) | 668 add_to_conflicts (ira_object_t obj1, ira_object_t obj2) |
571 { | 669 { |
572 int num; | 670 int num; |
573 unsigned int size; | 671 unsigned int size; |
574 | 672 |
575 if (ALLOCNO_CONFLICT_VEC_P (a1)) | 673 if (OBJECT_CONFLICT_VEC_P (obj1)) |
576 { | 674 { |
577 ira_allocno_t *vec; | 675 ira_object_t *vec = OBJECT_CONFLICT_VEC (obj1); |
578 | 676 int curr_num = OBJECT_NUM_CONFLICTS (obj1); |
579 num = ALLOCNO_CONFLICT_ALLOCNOS_NUM (a1) + 2; | 677 num = curr_num + 2; |
580 if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) | 678 if (OBJECT_CONFLICT_ARRAY_SIZE (obj1) < num * sizeof (ira_object_t)) |
581 >= num * sizeof (ira_allocno_t)) | 679 { |
582 vec = (ira_allocno_t *) ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1); | 680 ira_object_t *newvec; |
583 else | |
584 { | |
585 size = (3 * num / 2 + 1) * sizeof (ira_allocno_t); | 681 size = (3 * num / 2 + 1) * sizeof (ira_allocno_t); |
586 vec = (ira_allocno_t *) ira_allocate (size); | 682 newvec = (ira_object_t *) ira_allocate (size); |
587 memcpy (vec, ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1), | 683 memcpy (newvec, vec, curr_num * sizeof (ira_object_t)); |
588 sizeof (ira_allocno_t) * ALLOCNO_CONFLICT_ALLOCNOS_NUM (a1)); | 684 ira_free (vec); |
589 ira_free (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1)); | 685 vec = newvec; |
590 ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1) = vec; | 686 OBJECT_CONFLICT_ARRAY (obj1) = vec; |
591 ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) = size; | 687 OBJECT_CONFLICT_ARRAY_SIZE (obj1) = size; |
592 } | 688 } |
593 vec[num - 2] = a2; | 689 vec[num - 2] = obj2; |
594 vec[num - 1] = NULL; | 690 vec[num - 1] = NULL; |
595 ALLOCNO_CONFLICT_ALLOCNOS_NUM (a1)++; | 691 OBJECT_NUM_CONFLICTS (obj1)++; |
596 } | 692 } |
597 else | 693 else |
598 { | 694 { |
599 int nw, added_head_nw, id; | 695 int nw, added_head_nw, id; |
600 IRA_INT_TYPE *vec; | 696 IRA_INT_TYPE *vec = OBJECT_CONFLICT_BITVEC (obj1); |
601 | 697 |
602 id = ALLOCNO_CONFLICT_ID (a2); | 698 id = OBJECT_CONFLICT_ID (obj2); |
603 vec = (IRA_INT_TYPE *) ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1); | 699 if (OBJECT_MIN (obj1) > id) |
604 if (ALLOCNO_MIN (a1) > id) | |
605 { | 700 { |
606 /* Expand head of the bit vector. */ | 701 /* Expand head of the bit vector. */ |
607 added_head_nw = (ALLOCNO_MIN (a1) - id - 1) / IRA_INT_BITS + 1; | 702 added_head_nw = (OBJECT_MIN (obj1) - id - 1) / IRA_INT_BITS + 1; |
608 nw = (ALLOCNO_MAX (a1) - ALLOCNO_MIN (a1)) / IRA_INT_BITS + 1; | 703 nw = (OBJECT_MAX (obj1) - OBJECT_MIN (obj1)) / IRA_INT_BITS + 1; |
609 size = (nw + added_head_nw) * sizeof (IRA_INT_TYPE); | 704 size = (nw + added_head_nw) * sizeof (IRA_INT_TYPE); |
610 if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) >= size) | 705 if (OBJECT_CONFLICT_ARRAY_SIZE (obj1) >= size) |
611 { | 706 { |
612 memmove ((char *) vec + added_head_nw * sizeof (IRA_INT_TYPE), | 707 memmove ((char *) vec + added_head_nw * sizeof (IRA_INT_TYPE), |
613 vec, nw * sizeof (IRA_INT_TYPE)); | 708 vec, nw * sizeof (IRA_INT_TYPE)); |
614 memset (vec, 0, added_head_nw * sizeof (IRA_INT_TYPE)); | 709 memset (vec, 0, added_head_nw * sizeof (IRA_INT_TYPE)); |
615 } | 710 } |
617 { | 712 { |
618 size | 713 size |
619 = (3 * (nw + added_head_nw) / 2 + 1) * sizeof (IRA_INT_TYPE); | 714 = (3 * (nw + added_head_nw) / 2 + 1) * sizeof (IRA_INT_TYPE); |
620 vec = (IRA_INT_TYPE *) ira_allocate (size); | 715 vec = (IRA_INT_TYPE *) ira_allocate (size); |
621 memcpy ((char *) vec + added_head_nw * sizeof (IRA_INT_TYPE), | 716 memcpy ((char *) vec + added_head_nw * sizeof (IRA_INT_TYPE), |
622 ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1), | 717 OBJECT_CONFLICT_ARRAY (obj1), nw * sizeof (IRA_INT_TYPE)); |
623 nw * sizeof (IRA_INT_TYPE)); | |
624 memset (vec, 0, added_head_nw * sizeof (IRA_INT_TYPE)); | 718 memset (vec, 0, added_head_nw * sizeof (IRA_INT_TYPE)); |
625 memset ((char *) vec | 719 memset ((char *) vec |
626 + (nw + added_head_nw) * sizeof (IRA_INT_TYPE), | 720 + (nw + added_head_nw) * sizeof (IRA_INT_TYPE), |
627 0, size - (nw + added_head_nw) * sizeof (IRA_INT_TYPE)); | 721 0, size - (nw + added_head_nw) * sizeof (IRA_INT_TYPE)); |
628 ira_free (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1)); | 722 ira_free (OBJECT_CONFLICT_ARRAY (obj1)); |
629 ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1) = vec; | 723 OBJECT_CONFLICT_ARRAY (obj1) = vec; |
630 ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) = size; | 724 OBJECT_CONFLICT_ARRAY_SIZE (obj1) = size; |
631 } | 725 } |
632 ALLOCNO_MIN (a1) -= added_head_nw * IRA_INT_BITS; | 726 OBJECT_MIN (obj1) -= added_head_nw * IRA_INT_BITS; |
633 } | 727 } |
634 else if (ALLOCNO_MAX (a1) < id) | 728 else if (OBJECT_MAX (obj1) < id) |
635 { | 729 { |
636 nw = (id - ALLOCNO_MIN (a1)) / IRA_INT_BITS + 1; | 730 nw = (id - OBJECT_MIN (obj1)) / IRA_INT_BITS + 1; |
637 size = nw * sizeof (IRA_INT_TYPE); | 731 size = nw * sizeof (IRA_INT_TYPE); |
638 if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) < size) | 732 if (OBJECT_CONFLICT_ARRAY_SIZE (obj1) < size) |
639 { | 733 { |
640 /* Expand tail of the bit vector. */ | 734 /* Expand tail of the bit vector. */ |
641 size = (3 * nw / 2 + 1) * sizeof (IRA_INT_TYPE); | 735 size = (3 * nw / 2 + 1) * sizeof (IRA_INT_TYPE); |
642 vec = (IRA_INT_TYPE *) ira_allocate (size); | 736 vec = (IRA_INT_TYPE *) ira_allocate (size); |
643 memcpy (vec, ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1), | 737 memcpy (vec, OBJECT_CONFLICT_ARRAY (obj1), OBJECT_CONFLICT_ARRAY_SIZE (obj1)); |
644 ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1)); | 738 memset ((char *) vec + OBJECT_CONFLICT_ARRAY_SIZE (obj1), |
645 memset ((char *) vec + ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1), | 739 0, size - OBJECT_CONFLICT_ARRAY_SIZE (obj1)); |
646 0, size - ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1)); | 740 ira_free (OBJECT_CONFLICT_ARRAY (obj1)); |
647 ira_free (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1)); | 741 OBJECT_CONFLICT_ARRAY (obj1) = vec; |
648 ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1) = vec; | 742 OBJECT_CONFLICT_ARRAY_SIZE (obj1) = size; |
649 ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) = size; | |
650 } | 743 } |
651 ALLOCNO_MAX (a1) = id; | 744 OBJECT_MAX (obj1) = id; |
652 } | 745 } |
653 SET_ALLOCNO_SET_BIT (vec, id, ALLOCNO_MIN (a1), ALLOCNO_MAX (a1)); | 746 SET_MINMAX_SET_BIT (vec, id, OBJECT_MIN (obj1), OBJECT_MAX (obj1)); |
654 } | 747 } |
655 } | 748 } |
656 | 749 |
657 /* Add A1 to the conflicts of A2 and vise versa. */ | 750 /* Add OBJ1 to the conflicts of OBJ2 and vice versa. */ |
658 void | 751 static void |
659 ira_add_allocno_conflict (ira_allocno_t a1, ira_allocno_t a2) | 752 ira_add_conflict (ira_object_t obj1, ira_object_t obj2) |
660 { | 753 { |
661 add_to_allocno_conflicts (a1, a2); | 754 add_to_conflicts (obj1, obj2); |
662 add_to_allocno_conflicts (a2, a1); | 755 add_to_conflicts (obj2, obj1); |
663 } | 756 } |
664 | 757 |
665 /* Clear all conflicts of allocno A. */ | 758 /* Clear all conflicts of OBJ. */ |
666 static void | 759 static void |
667 clear_allocno_conflicts (ira_allocno_t a) | 760 clear_conflicts (ira_object_t obj) |
668 { | 761 { |
669 if (ALLOCNO_CONFLICT_VEC_P (a)) | 762 if (OBJECT_CONFLICT_VEC_P (obj)) |
670 { | 763 { |
671 ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = 0; | 764 OBJECT_NUM_CONFLICTS (obj) = 0; |
672 ((ira_allocno_t *) ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a))[0] = NULL; | 765 OBJECT_CONFLICT_VEC (obj)[0] = NULL; |
673 } | 766 } |
674 else if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a) != 0) | 767 else if (OBJECT_CONFLICT_ARRAY_SIZE (obj) != 0) |
675 { | 768 { |
676 int nw; | 769 int nw; |
677 | 770 |
678 nw = (ALLOCNO_MAX (a) - ALLOCNO_MIN (a)) / IRA_INT_BITS + 1; | 771 nw = (OBJECT_MAX (obj) - OBJECT_MIN (obj)) / IRA_INT_BITS + 1; |
679 memset (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a), 0, | 772 memset (OBJECT_CONFLICT_BITVEC (obj), 0, nw * sizeof (IRA_INT_TYPE)); |
680 nw * sizeof (IRA_INT_TYPE)); | |
681 } | 773 } |
682 } | 774 } |
683 | 775 |
684 /* The array used to find duplications in conflict vectors of | 776 /* The array used to find duplications in conflict vectors of |
685 allocnos. */ | 777 allocnos. */ |
686 static int *allocno_conflict_check; | 778 static int *conflict_check; |
687 | 779 |
688 /* The value used to mark allocation presence in conflict vector of | 780 /* The value used to mark allocation presence in conflict vector of |
689 the current allocno. */ | 781 the current allocno. */ |
690 static int curr_allocno_conflict_check_tick; | 782 static int curr_conflict_check_tick; |
691 | 783 |
692 /* Remove duplications in conflict vector of A. */ | 784 /* Remove duplications in conflict vector of OBJ. */ |
693 static void | 785 static void |
694 compress_allocno_conflict_vec (ira_allocno_t a) | 786 compress_conflict_vec (ira_object_t obj) |
695 { | 787 { |
696 ira_allocno_t *vec, conflict_a; | 788 ira_object_t *vec, conflict_obj; |
697 int i, j; | 789 int i, j; |
698 | 790 |
699 ira_assert (ALLOCNO_CONFLICT_VEC_P (a)); | 791 ira_assert (OBJECT_CONFLICT_VEC_P (obj)); |
700 vec = (ira_allocno_t *) ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a); | 792 vec = OBJECT_CONFLICT_VEC (obj); |
701 curr_allocno_conflict_check_tick++; | 793 curr_conflict_check_tick++; |
702 for (i = j = 0; (conflict_a = vec[i]) != NULL; i++) | 794 for (i = j = 0; (conflict_obj = vec[i]) != NULL; i++) |
703 { | 795 { |
704 if (allocno_conflict_check[ALLOCNO_NUM (conflict_a)] | 796 int id = OBJECT_CONFLICT_ID (conflict_obj); |
705 != curr_allocno_conflict_check_tick) | 797 if (conflict_check[id] != curr_conflict_check_tick) |
706 { | 798 { |
707 allocno_conflict_check[ALLOCNO_NUM (conflict_a)] | 799 conflict_check[id] = curr_conflict_check_tick; |
708 = curr_allocno_conflict_check_tick; | 800 vec[j++] = conflict_obj; |
709 vec[j++] = conflict_a; | 801 } |
710 } | 802 } |
711 } | 803 OBJECT_NUM_CONFLICTS (obj) = j; |
712 ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = j; | |
713 vec[j] = NULL; | 804 vec[j] = NULL; |
714 } | 805 } |
715 | 806 |
716 /* Remove duplications in conflict vectors of all allocnos. */ | 807 /* Remove duplications in conflict vectors of all allocnos. */ |
717 static void | 808 static void |
718 compress_conflict_vecs (void) | 809 compress_conflict_vecs (void) |
719 { | 810 { |
720 ira_allocno_t a; | 811 ira_object_t obj; |
721 ira_allocno_iterator ai; | 812 ira_object_iterator oi; |
722 | 813 |
723 allocno_conflict_check | 814 conflict_check = (int *) ira_allocate (sizeof (int) * ira_objects_num); |
724 = (int *) ira_allocate (sizeof (int) * ira_allocnos_num); | 815 memset (conflict_check, 0, sizeof (int) * ira_objects_num); |
725 memset (allocno_conflict_check, 0, sizeof (int) * ira_allocnos_num); | 816 curr_conflict_check_tick = 0; |
726 curr_allocno_conflict_check_tick = 0; | 817 FOR_EACH_OBJECT (obj, oi) |
727 FOR_EACH_ALLOCNO (a, ai) | 818 { |
728 if (ALLOCNO_CONFLICT_VEC_P (a)) | 819 if (OBJECT_CONFLICT_VEC_P (obj)) |
729 compress_allocno_conflict_vec (a); | 820 compress_conflict_vec (obj); |
730 ira_free (allocno_conflict_check); | 821 } |
822 ira_free (conflict_check); | |
731 } | 823 } |
732 | 824 |
733 /* This recursive function outputs allocno A and if it is a cap the | 825 /* This recursive function outputs allocno A and if it is a cap the |
734 function outputs its members. */ | 826 function outputs its members. */ |
735 void | 827 void |
764 parent = ALLOCNO_LOOP_TREE_NODE (a)->parent; | 856 parent = ALLOCNO_LOOP_TREE_NODE (a)->parent; |
765 cap = ira_create_allocno (ALLOCNO_REGNO (a), true, parent); | 857 cap = ira_create_allocno (ALLOCNO_REGNO (a), true, parent); |
766 ALLOCNO_MODE (cap) = ALLOCNO_MODE (a); | 858 ALLOCNO_MODE (cap) = ALLOCNO_MODE (a); |
767 cover_class = ALLOCNO_COVER_CLASS (a); | 859 cover_class = ALLOCNO_COVER_CLASS (a); |
768 ira_set_allocno_cover_class (cap, cover_class); | 860 ira_set_allocno_cover_class (cap, cover_class); |
861 ira_create_allocno_objects (cap); | |
769 ALLOCNO_AVAILABLE_REGS_NUM (cap) = ALLOCNO_AVAILABLE_REGS_NUM (a); | 862 ALLOCNO_AVAILABLE_REGS_NUM (cap) = ALLOCNO_AVAILABLE_REGS_NUM (a); |
770 ALLOCNO_CAP_MEMBER (cap) = a; | 863 ALLOCNO_CAP_MEMBER (cap) = a; |
771 ALLOCNO_CAP (a) = cap; | 864 ALLOCNO_CAP (a) = cap; |
772 ALLOCNO_COVER_CLASS_COST (cap) = ALLOCNO_COVER_CLASS_COST (a); | 865 ALLOCNO_COVER_CLASS_COST (cap) = ALLOCNO_COVER_CLASS_COST (a); |
773 ALLOCNO_MEMORY_COST (cap) = ALLOCNO_MEMORY_COST (a); | 866 ALLOCNO_MEMORY_COST (cap) = ALLOCNO_MEMORY_COST (a); |
778 ALLOCNO_CONFLICT_HARD_REG_COSTS (a)); | 871 ALLOCNO_CONFLICT_HARD_REG_COSTS (a)); |
779 ALLOCNO_BAD_SPILL_P (cap) = ALLOCNO_BAD_SPILL_P (a); | 872 ALLOCNO_BAD_SPILL_P (cap) = ALLOCNO_BAD_SPILL_P (a); |
780 ALLOCNO_NREFS (cap) = ALLOCNO_NREFS (a); | 873 ALLOCNO_NREFS (cap) = ALLOCNO_NREFS (a); |
781 ALLOCNO_FREQ (cap) = ALLOCNO_FREQ (a); | 874 ALLOCNO_FREQ (cap) = ALLOCNO_FREQ (a); |
782 ALLOCNO_CALL_FREQ (cap) = ALLOCNO_CALL_FREQ (a); | 875 ALLOCNO_CALL_FREQ (cap) = ALLOCNO_CALL_FREQ (a); |
783 IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (cap), | 876 |
784 ALLOCNO_CONFLICT_HARD_REGS (a)); | 877 merge_hard_reg_conflicts (a, cap, false); |
785 IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (cap), | 878 |
786 ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a)); | |
787 ALLOCNO_CALLS_CROSSED_NUM (cap) = ALLOCNO_CALLS_CROSSED_NUM (a); | 879 ALLOCNO_CALLS_CROSSED_NUM (cap) = ALLOCNO_CALLS_CROSSED_NUM (a); |
788 #ifdef STACK_REGS | |
789 ALLOCNO_NO_STACK_REG_P (cap) = ALLOCNO_NO_STACK_REG_P (a); | |
790 ALLOCNO_TOTAL_NO_STACK_REG_P (cap) = ALLOCNO_TOTAL_NO_STACK_REG_P (a); | |
791 #endif | |
792 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) | 880 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) |
793 { | 881 { |
794 fprintf (ira_dump_file, " Creating cap "); | 882 fprintf (ira_dump_file, " Creating cap "); |
795 ira_print_expanded_allocno (cap); | 883 ira_print_expanded_allocno (cap); |
796 fprintf (ira_dump_file, "\n"); | 884 fprintf (ira_dump_file, "\n"); |
797 } | 885 } |
798 return cap; | 886 return cap; |
799 } | 887 } |
800 | 888 |
801 /* Create and return allocno live range with given attributes. */ | 889 /* Create and return a live range for OBJECT with given attributes. */ |
802 allocno_live_range_t | 890 live_range_t |
803 ira_create_allocno_live_range (ira_allocno_t a, int start, int finish, | 891 ira_create_live_range (ira_object_t obj, int start, int finish, |
804 allocno_live_range_t next) | 892 live_range_t next) |
805 { | 893 { |
806 allocno_live_range_t p; | 894 live_range_t p; |
807 | 895 |
808 p = (allocno_live_range_t) pool_alloc (allocno_live_range_pool); | 896 p = (live_range_t) pool_alloc (live_range_pool); |
809 p->allocno = a; | 897 p->object = obj; |
810 p->start = start; | 898 p->start = start; |
811 p->finish = finish; | 899 p->finish = finish; |
812 p->next = next; | 900 p->next = next; |
813 return p; | 901 return p; |
814 } | 902 } |
815 | 903 |
904 /* Create a new live range for OBJECT and queue it at the head of its | |
905 live range list. */ | |
906 void | |
907 ira_add_live_range_to_object (ira_object_t object, int start, int finish) | |
908 { | |
909 live_range_t p; | |
910 p = ira_create_live_range (object, start, finish, | |
911 OBJECT_LIVE_RANGES (object)); | |
912 OBJECT_LIVE_RANGES (object) = p; | |
913 } | |
914 | |
816 /* Copy allocno live range R and return the result. */ | 915 /* Copy allocno live range R and return the result. */ |
817 static allocno_live_range_t | 916 static live_range_t |
818 copy_allocno_live_range (allocno_live_range_t r) | 917 copy_live_range (live_range_t r) |
819 { | 918 { |
820 allocno_live_range_t p; | 919 live_range_t p; |
821 | 920 |
822 p = (allocno_live_range_t) pool_alloc (allocno_live_range_pool); | 921 p = (live_range_t) pool_alloc (live_range_pool); |
823 *p = *r; | 922 *p = *r; |
824 return p; | 923 return p; |
825 } | 924 } |
826 | 925 |
827 /* Copy allocno live range list given by its head R and return the | 926 /* Copy allocno live range list given by its head R and return the |
828 result. */ | 927 result. */ |
829 allocno_live_range_t | 928 live_range_t |
830 ira_copy_allocno_live_range_list (allocno_live_range_t r) | 929 ira_copy_live_range_list (live_range_t r) |
831 { | 930 { |
832 allocno_live_range_t p, first, last; | 931 live_range_t p, first, last; |
833 | 932 |
834 if (r == NULL) | 933 if (r == NULL) |
835 return NULL; | 934 return NULL; |
836 for (first = last = NULL; r != NULL; r = r->next) | 935 for (first = last = NULL; r != NULL; r = r->next) |
837 { | 936 { |
838 p = copy_allocno_live_range (r); | 937 p = copy_live_range (r); |
839 if (first == NULL) | 938 if (first == NULL) |
840 first = p; | 939 first = p; |
841 else | 940 else |
842 last->next = p; | 941 last->next = p; |
843 last = p; | 942 last = p; |
846 } | 945 } |
847 | 946 |
848 /* Merge ranges R1 and R2 and returns the result. The function | 947 /* Merge ranges R1 and R2 and returns the result. The function |
849 maintains the order of ranges and tries to minimize number of the | 948 maintains the order of ranges and tries to minimize number of the |
850 result ranges. */ | 949 result ranges. */ |
851 allocno_live_range_t | 950 live_range_t |
852 ira_merge_allocno_live_ranges (allocno_live_range_t r1, | 951 ira_merge_live_ranges (live_range_t r1, live_range_t r2) |
853 allocno_live_range_t r2) | 952 { |
854 { | 953 live_range_t first, last, temp; |
855 allocno_live_range_t first, last, temp; | |
856 | 954 |
857 if (r1 == NULL) | 955 if (r1 == NULL) |
858 return r2; | 956 return r2; |
859 if (r2 == NULL) | 957 if (r2 == NULL) |
860 return r1; | 958 return r1; |
872 r1->start = r2->start; | 970 r1->start = r2->start; |
873 if (r1->finish < r2->finish) | 971 if (r1->finish < r2->finish) |
874 r1->finish = r2->finish; | 972 r1->finish = r2->finish; |
875 temp = r2; | 973 temp = r2; |
876 r2 = r2->next; | 974 r2 = r2->next; |
877 ira_finish_allocno_live_range (temp); | 975 ira_finish_live_range (temp); |
878 if (r2 == NULL) | 976 if (r2 == NULL) |
879 { | 977 { |
880 /* To try to merge with subsequent ranges in r1. */ | 978 /* To try to merge with subsequent ranges in r1. */ |
881 r2 = r1->next; | 979 r2 = r1->next; |
882 r1->next = NULL; | 980 r1->next = NULL; |
924 return first; | 1022 return first; |
925 } | 1023 } |
926 | 1024 |
927 /* Return TRUE if live ranges R1 and R2 intersect. */ | 1025 /* Return TRUE if live ranges R1 and R2 intersect. */ |
928 bool | 1026 bool |
929 ira_allocno_live_ranges_intersect_p (allocno_live_range_t r1, | 1027 ira_live_ranges_intersect_p (live_range_t r1, live_range_t r2) |
930 allocno_live_range_t r2) | |
931 { | 1028 { |
932 /* Remember the live ranges are always kept ordered. */ | 1029 /* Remember the live ranges are always kept ordered. */ |
933 while (r1 != NULL && r2 != NULL) | 1030 while (r1 != NULL && r2 != NULL) |
934 { | 1031 { |
935 if (r1->start > r2->finish) | 1032 if (r1->start > r2->finish) |
942 return false; | 1039 return false; |
943 } | 1040 } |
944 | 1041 |
945 /* Free allocno live range R. */ | 1042 /* Free allocno live range R. */ |
946 void | 1043 void |
947 ira_finish_allocno_live_range (allocno_live_range_t r) | 1044 ira_finish_live_range (live_range_t r) |
948 { | 1045 { |
949 pool_free (allocno_live_range_pool, r); | 1046 pool_free (live_range_pool, r); |
950 } | 1047 } |
951 | 1048 |
952 /* Free list of allocno live ranges starting with R. */ | 1049 /* Free list of allocno live ranges starting with R. */ |
953 void | 1050 void |
954 ira_finish_allocno_live_range_list (allocno_live_range_t r) | 1051 ira_finish_live_range_list (live_range_t r) |
955 { | 1052 { |
956 allocno_live_range_t next_r; | 1053 live_range_t next_r; |
957 | 1054 |
958 for (; r != NULL; r = next_r) | 1055 for (; r != NULL; r = next_r) |
959 { | 1056 { |
960 next_r = r->next; | 1057 next_r = r->next; |
961 ira_finish_allocno_live_range (r); | 1058 ira_finish_live_range (r); |
962 } | 1059 } |
963 } | 1060 } |
964 | 1061 |
965 /* Free updated register costs of allocno A. */ | 1062 /* Free updated register costs of allocno A. */ |
966 void | 1063 void |
981 /* Free the memory allocated for allocno A. */ | 1078 /* Free the memory allocated for allocno A. */ |
982 static void | 1079 static void |
983 finish_allocno (ira_allocno_t a) | 1080 finish_allocno (ira_allocno_t a) |
984 { | 1081 { |
985 enum reg_class cover_class = ALLOCNO_COVER_CLASS (a); | 1082 enum reg_class cover_class = ALLOCNO_COVER_CLASS (a); |
1083 ira_object_t obj; | |
1084 ira_allocno_object_iterator oi; | |
1085 | |
1086 FOR_EACH_ALLOCNO_OBJECT (a, obj, oi) | |
1087 { | |
1088 ira_finish_live_range_list (OBJECT_LIVE_RANGES (obj)); | |
1089 ira_object_id_map[OBJECT_CONFLICT_ID (obj)] = NULL; | |
1090 if (OBJECT_CONFLICT_ARRAY (obj) != NULL) | |
1091 ira_free (OBJECT_CONFLICT_ARRAY (obj)); | |
1092 pool_free (object_pool, obj); | |
1093 } | |
986 | 1094 |
987 ira_allocnos[ALLOCNO_NUM (a)] = NULL; | 1095 ira_allocnos[ALLOCNO_NUM (a)] = NULL; |
988 ira_conflict_id_allocno_map[ALLOCNO_CONFLICT_ID (a)] = NULL; | |
989 if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) != NULL) | |
990 ira_free (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a)); | |
991 if (ALLOCNO_HARD_REG_COSTS (a) != NULL) | 1096 if (ALLOCNO_HARD_REG_COSTS (a) != NULL) |
992 ira_free_cost_vector (ALLOCNO_HARD_REG_COSTS (a), cover_class); | 1097 ira_free_cost_vector (ALLOCNO_HARD_REG_COSTS (a), cover_class); |
993 if (ALLOCNO_CONFLICT_HARD_REG_COSTS (a) != NULL) | 1098 if (ALLOCNO_CONFLICT_HARD_REG_COSTS (a) != NULL) |
994 ira_free_cost_vector (ALLOCNO_CONFLICT_HARD_REG_COSTS (a), cover_class); | 1099 ira_free_cost_vector (ALLOCNO_CONFLICT_HARD_REG_COSTS (a), cover_class); |
995 if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) != NULL) | 1100 if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) != NULL) |
996 ira_free_cost_vector (ALLOCNO_UPDATED_HARD_REG_COSTS (a), cover_class); | 1101 ira_free_cost_vector (ALLOCNO_UPDATED_HARD_REG_COSTS (a), cover_class); |
997 if (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) != NULL) | 1102 if (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) != NULL) |
998 ira_free_cost_vector (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a), | 1103 ira_free_cost_vector (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a), |
999 cover_class); | 1104 cover_class); |
1000 ira_finish_allocno_live_range_list (ALLOCNO_LIVE_RANGES (a)); | |
1001 pool_free (allocno_pool, a); | 1105 pool_free (allocno_pool, a); |
1002 } | 1106 } |
1003 | 1107 |
1004 /* Free the memory allocated for all allocnos. */ | 1108 /* Free the memory allocated for all allocnos. */ |
1005 static void | 1109 static void |
1009 ira_allocno_iterator ai; | 1113 ira_allocno_iterator ai; |
1010 | 1114 |
1011 FOR_EACH_ALLOCNO (a, ai) | 1115 FOR_EACH_ALLOCNO (a, ai) |
1012 finish_allocno (a); | 1116 finish_allocno (a); |
1013 ira_free (ira_regno_allocno_map); | 1117 ira_free (ira_regno_allocno_map); |
1014 VEC_free (ira_allocno_t, heap, ira_conflict_id_allocno_map_vec); | 1118 VEC_free (ira_object_t, heap, ira_object_id_map_vec); |
1015 VEC_free (ira_allocno_t, heap, allocno_vec); | 1119 VEC_free (ira_allocno_t, heap, allocno_vec); |
1016 free_alloc_pool (allocno_pool); | 1120 free_alloc_pool (allocno_pool); |
1017 free_alloc_pool (allocno_live_range_pool); | 1121 free_alloc_pool (object_pool); |
1122 free_alloc_pool (live_range_pool); | |
1018 } | 1123 } |
1019 | 1124 |
1020 | 1125 |
1021 | 1126 |
1022 /* Pools for copies. */ | 1127 /* Pools for copies. */ |
1114 else | 1219 else |
1115 cp->next_second_allocno_copy->prev_first_allocno_copy = cp; | 1220 cp->next_second_allocno_copy->prev_first_allocno_copy = cp; |
1116 } | 1221 } |
1117 ALLOCNO_COPIES (first) = cp; | 1222 ALLOCNO_COPIES (first) = cp; |
1118 ALLOCNO_COPIES (second) = cp; | 1223 ALLOCNO_COPIES (second) = cp; |
1119 } | |
1120 | |
1121 /* Detach a copy CP from allocnos involved into the copy. */ | |
1122 void | |
1123 ira_remove_allocno_copy_from_list (ira_copy_t cp) | |
1124 { | |
1125 ira_allocno_t first = cp->first, second = cp->second; | |
1126 ira_copy_t prev, next; | |
1127 | |
1128 next = cp->next_first_allocno_copy; | |
1129 prev = cp->prev_first_allocno_copy; | |
1130 if (prev == NULL) | |
1131 ALLOCNO_COPIES (first) = next; | |
1132 else if (prev->first == first) | |
1133 prev->next_first_allocno_copy = next; | |
1134 else | |
1135 prev->next_second_allocno_copy = next; | |
1136 if (next != NULL) | |
1137 { | |
1138 if (next->first == first) | |
1139 next->prev_first_allocno_copy = prev; | |
1140 else | |
1141 next->prev_second_allocno_copy = prev; | |
1142 } | |
1143 cp->prev_first_allocno_copy = cp->next_first_allocno_copy = NULL; | |
1144 | |
1145 next = cp->next_second_allocno_copy; | |
1146 prev = cp->prev_second_allocno_copy; | |
1147 if (prev == NULL) | |
1148 ALLOCNO_COPIES (second) = next; | |
1149 else if (prev->second == second) | |
1150 prev->next_second_allocno_copy = next; | |
1151 else | |
1152 prev->next_first_allocno_copy = next; | |
1153 if (next != NULL) | |
1154 { | |
1155 if (next->second == second) | |
1156 next->prev_second_allocno_copy = prev; | |
1157 else | |
1158 next->prev_first_allocno_copy = prev; | |
1159 } | |
1160 cp->prev_second_allocno_copy = cp->next_second_allocno_copy = NULL; | |
1161 } | 1224 } |
1162 | 1225 |
1163 /* Make a copy CP a canonical copy where number of the | 1226 /* Make a copy CP a canonical copy where number of the |
1164 first allocno is less than the second one. */ | 1227 first allocno is less than the second one. */ |
1165 void | 1228 void |
1549 FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds) | 1612 FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds) |
1550 if (e->src != loop_node->loop->latch) | 1613 if (e->src != loop_node->loop->latch) |
1551 create_loop_allocnos (e); | 1614 create_loop_allocnos (e); |
1552 | 1615 |
1553 edges = get_loop_exit_edges (loop_node->loop); | 1616 edges = get_loop_exit_edges (loop_node->loop); |
1554 for (i = 0; VEC_iterate (edge, edges, i, e); i++) | 1617 FOR_EACH_VEC_ELT (edge, edges, i, e) |
1555 create_loop_allocnos (e); | 1618 create_loop_allocnos (e); |
1556 VEC_free (edge, heap, edges); | 1619 VEC_free (edge, heap, edges); |
1557 } | 1620 } |
1558 } | 1621 } |
1559 | 1622 |
1600 if (! ALLOCNO_BAD_SPILL_P (a)) | 1663 if (! ALLOCNO_BAD_SPILL_P (a)) |
1601 ALLOCNO_BAD_SPILL_P (parent_a) = false; | 1664 ALLOCNO_BAD_SPILL_P (parent_a) = false; |
1602 ALLOCNO_NREFS (parent_a) += ALLOCNO_NREFS (a); | 1665 ALLOCNO_NREFS (parent_a) += ALLOCNO_NREFS (a); |
1603 ALLOCNO_FREQ (parent_a) += ALLOCNO_FREQ (a); | 1666 ALLOCNO_FREQ (parent_a) += ALLOCNO_FREQ (a); |
1604 ALLOCNO_CALL_FREQ (parent_a) += ALLOCNO_CALL_FREQ (a); | 1667 ALLOCNO_CALL_FREQ (parent_a) += ALLOCNO_CALL_FREQ (a); |
1605 #ifdef STACK_REGS | 1668 merge_hard_reg_conflicts (a, parent_a, true); |
1606 if (ALLOCNO_TOTAL_NO_STACK_REG_P (a)) | |
1607 ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a) = true; | |
1608 #endif | |
1609 IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (parent_a), | |
1610 ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a)); | |
1611 ALLOCNO_CALLS_CROSSED_NUM (parent_a) | 1669 ALLOCNO_CALLS_CROSSED_NUM (parent_a) |
1612 += ALLOCNO_CALLS_CROSSED_NUM (a); | 1670 += ALLOCNO_CALLS_CROSSED_NUM (a); |
1613 ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a) | 1671 ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a) |
1614 += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a); | 1672 += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a); |
1615 cover_class = ALLOCNO_COVER_CLASS (a); | 1673 cover_class = ALLOCNO_COVER_CLASS (a); |
1646 /* The page contains function to remove some regions from a separate | 1704 /* The page contains function to remove some regions from a separate |
1647 register allocation. We remove regions whose separate allocation | 1705 register allocation. We remove regions whose separate allocation |
1648 will hardly improve the result. As a result we speed up regional | 1706 will hardly improve the result. As a result we speed up regional |
1649 register allocation. */ | 1707 register allocation. */ |
1650 | 1708 |
1651 /* The function changes allocno in range list given by R onto A. */ | 1709 /* The function changes the object in range list given by R to OBJ. */ |
1652 static void | 1710 static void |
1653 change_allocno_in_range_list (allocno_live_range_t r, ira_allocno_t a) | 1711 change_object_in_range_list (live_range_t r, ira_object_t obj) |
1654 { | 1712 { |
1655 for (; r != NULL; r = r->next) | 1713 for (; r != NULL; r = r->next) |
1656 r->allocno = a; | 1714 r->object = obj; |
1715 } | |
1716 | |
1717 /* Move all live ranges associated with allocno FROM to allocno TO. */ | |
1718 static void | |
1719 move_allocno_live_ranges (ira_allocno_t from, ira_allocno_t to) | |
1720 { | |
1721 int i; | |
1722 int n = ALLOCNO_NUM_OBJECTS (from); | |
1723 | |
1724 gcc_assert (n == ALLOCNO_NUM_OBJECTS (to)); | |
1725 | |
1726 for (i = 0; i < n; i++) | |
1727 { | |
1728 ira_object_t from_obj = ALLOCNO_OBJECT (from, i); | |
1729 ira_object_t to_obj = ALLOCNO_OBJECT (to, i); | |
1730 live_range_t lr = OBJECT_LIVE_RANGES (from_obj); | |
1731 | |
1732 if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL) | |
1733 { | |
1734 fprintf (ira_dump_file, | |
1735 " Moving ranges of a%dr%d to a%dr%d: ", | |
1736 ALLOCNO_NUM (from), ALLOCNO_REGNO (from), | |
1737 ALLOCNO_NUM (to), ALLOCNO_REGNO (to)); | |
1738 ira_print_live_range_list (ira_dump_file, lr); | |
1739 } | |
1740 change_object_in_range_list (lr, to_obj); | |
1741 OBJECT_LIVE_RANGES (to_obj) | |
1742 = ira_merge_live_ranges (lr, OBJECT_LIVE_RANGES (to_obj)); | |
1743 OBJECT_LIVE_RANGES (from_obj) = NULL; | |
1744 } | |
1745 } | |
1746 | |
1747 static void | |
1748 copy_allocno_live_ranges (ira_allocno_t from, ira_allocno_t to) | |
1749 { | |
1750 int i; | |
1751 int n = ALLOCNO_NUM_OBJECTS (from); | |
1752 | |
1753 gcc_assert (n == ALLOCNO_NUM_OBJECTS (to)); | |
1754 | |
1755 for (i = 0; i < n; i++) | |
1756 { | |
1757 ira_object_t from_obj = ALLOCNO_OBJECT (from, i); | |
1758 ira_object_t to_obj = ALLOCNO_OBJECT (to, i); | |
1759 live_range_t lr = OBJECT_LIVE_RANGES (from_obj); | |
1760 | |
1761 if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL) | |
1762 { | |
1763 fprintf (ira_dump_file, " Copying ranges of a%dr%d to a%dr%d: ", | |
1764 ALLOCNO_NUM (from), ALLOCNO_REGNO (from), | |
1765 ALLOCNO_NUM (to), ALLOCNO_REGNO (to)); | |
1766 ira_print_live_range_list (ira_dump_file, lr); | |
1767 } | |
1768 lr = ira_copy_live_range_list (lr); | |
1769 change_object_in_range_list (lr, to_obj); | |
1770 OBJECT_LIVE_RANGES (to_obj) | |
1771 = ira_merge_live_ranges (lr, OBJECT_LIVE_RANGES (to_obj)); | |
1772 } | |
1657 } | 1773 } |
1658 | 1774 |
1659 /* Return TRUE if NODE represents a loop with low register | 1775 /* Return TRUE if NODE represents a loop with low register |
1660 pressure. */ | 1776 pressure. */ |
1661 static bool | 1777 static bool |
1756 mark_all_loops_for_removal (void) | 1872 mark_all_loops_for_removal (void) |
1757 { | 1873 { |
1758 int i; | 1874 int i; |
1759 loop_p loop; | 1875 loop_p loop; |
1760 | 1876 |
1761 for (i = 0; VEC_iterate (loop_p, ira_loops.larray, i, loop); i++) | 1877 FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) |
1762 if (ira_loop_nodes[i].regno_allocno_map != NULL) | 1878 if (ira_loop_nodes[i].regno_allocno_map != NULL) |
1763 { | 1879 { |
1764 if (ira_loop_nodes[i].parent == NULL) | 1880 if (ira_loop_nodes[i].parent == NULL) |
1765 { | 1881 { |
1766 /* Don't remove the root. */ | 1882 /* Don't remove the root. */ |
1887 static void | 2003 static void |
1888 propagate_some_info_from_allocno (ira_allocno_t a, ira_allocno_t from_a) | 2004 propagate_some_info_from_allocno (ira_allocno_t a, ira_allocno_t from_a) |
1889 { | 2005 { |
1890 enum reg_class cover_class; | 2006 enum reg_class cover_class; |
1891 | 2007 |
1892 IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), | 2008 merge_hard_reg_conflicts (from_a, a, false); |
1893 ALLOCNO_CONFLICT_HARD_REGS (from_a)); | |
1894 #ifdef STACK_REGS | |
1895 if (ALLOCNO_NO_STACK_REG_P (from_a)) | |
1896 ALLOCNO_NO_STACK_REG_P (a) = true; | |
1897 #endif | |
1898 ALLOCNO_NREFS (a) += ALLOCNO_NREFS (from_a); | 2009 ALLOCNO_NREFS (a) += ALLOCNO_NREFS (from_a); |
1899 ALLOCNO_FREQ (a) += ALLOCNO_FREQ (from_a); | 2010 ALLOCNO_FREQ (a) += ALLOCNO_FREQ (from_a); |
1900 ALLOCNO_CALL_FREQ (a) += ALLOCNO_CALL_FREQ (from_a); | 2011 ALLOCNO_CALL_FREQ (a) += ALLOCNO_CALL_FREQ (from_a); |
1901 IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), | |
1902 ALLOCNO_TOTAL_CONFLICT_HARD_REGS (from_a)); | |
1903 ALLOCNO_CALLS_CROSSED_NUM (a) += ALLOCNO_CALLS_CROSSED_NUM (from_a); | 2012 ALLOCNO_CALLS_CROSSED_NUM (a) += ALLOCNO_CALLS_CROSSED_NUM (from_a); |
1904 ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) | 2013 ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) |
1905 += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (from_a); | 2014 += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (from_a); |
1906 if (! ALLOCNO_BAD_SPILL_P (from_a)) | 2015 if (! ALLOCNO_BAD_SPILL_P (from_a)) |
1907 ALLOCNO_BAD_SPILL_P (a) = false; | 2016 ALLOCNO_BAD_SPILL_P (a) = false; |
1908 #ifdef STACK_REGS | |
1909 if (ALLOCNO_TOTAL_NO_STACK_REG_P (from_a)) | |
1910 ALLOCNO_TOTAL_NO_STACK_REG_P (a) = true; | |
1911 #endif | |
1912 cover_class = ALLOCNO_COVER_CLASS (from_a); | 2017 cover_class = ALLOCNO_COVER_CLASS (from_a); |
1913 ira_assert (cover_class == ALLOCNO_COVER_CLASS (a)); | 2018 ira_assert (cover_class == ALLOCNO_COVER_CLASS (a)); |
1914 ira_allocate_and_accumulate_costs (&ALLOCNO_HARD_REG_COSTS (a), cover_class, | 2019 ira_allocate_and_accumulate_costs (&ALLOCNO_HARD_REG_COSTS (a), cover_class, |
1915 ALLOCNO_HARD_REG_COSTS (from_a)); | 2020 ALLOCNO_HARD_REG_COSTS (from_a)); |
1916 ira_allocate_and_accumulate_costs (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), | 2021 ira_allocate_and_accumulate_costs (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), |
1927 { | 2032 { |
1928 int regno; | 2033 int regno; |
1929 bool merged_p, rebuild_p; | 2034 bool merged_p, rebuild_p; |
1930 ira_allocno_t a, prev_a, next_a, parent_a; | 2035 ira_allocno_t a, prev_a, next_a, parent_a; |
1931 ira_loop_tree_node_t a_node, parent; | 2036 ira_loop_tree_node_t a_node, parent; |
1932 allocno_live_range_t r; | |
1933 | 2037 |
1934 merged_p = false; | 2038 merged_p = false; |
1935 regno_allocnos = NULL; | 2039 regno_allocnos = NULL; |
1936 for (regno = max_reg_num () - 1; regno >= FIRST_PSEUDO_REGISTER; regno--) | 2040 for (regno = max_reg_num () - 1; regno >= FIRST_PSEUDO_REGISTER; regno--) |
1937 { | 2041 { |
1968 the upper region. */ | 2072 the upper region. */ |
1969 if (prev_a == NULL) | 2073 if (prev_a == NULL) |
1970 ira_regno_allocno_map[regno] = next_a; | 2074 ira_regno_allocno_map[regno] = next_a; |
1971 else | 2075 else |
1972 ALLOCNO_NEXT_REGNO_ALLOCNO (prev_a) = next_a; | 2076 ALLOCNO_NEXT_REGNO_ALLOCNO (prev_a) = next_a; |
1973 r = ALLOCNO_LIVE_RANGES (a); | 2077 move_allocno_live_ranges (a, parent_a); |
1974 change_allocno_in_range_list (r, parent_a); | |
1975 ALLOCNO_LIVE_RANGES (parent_a) | |
1976 = ira_merge_allocno_live_ranges | |
1977 (r, ALLOCNO_LIVE_RANGES (parent_a)); | |
1978 merged_p = true; | 2078 merged_p = true; |
1979 ALLOCNO_LIVE_RANGES (a) = NULL; | |
1980 propagate_some_info_from_allocno (parent_a, a); | 2079 propagate_some_info_from_allocno (parent_a, a); |
1981 /* Remove it from the corresponding regno allocno | 2080 /* Remove it from the corresponding regno allocno |
1982 map to avoid info propagation of subsequent | 2081 map to avoid info propagation of subsequent |
1983 allocno into this already removed allocno. */ | 2082 allocno into this already removed allocno. */ |
1984 a_node->regno_allocno_map[regno] = NULL; | 2083 a_node->regno_allocno_map[regno] = NULL; |
2008 { | 2107 { |
2009 int regno; | 2108 int regno; |
2010 bool merged_p, propagate_p; | 2109 bool merged_p, propagate_p; |
2011 ira_allocno_t a, top_a; | 2110 ira_allocno_t a, top_a; |
2012 ira_loop_tree_node_t a_node, parent; | 2111 ira_loop_tree_node_t a_node, parent; |
2013 allocno_live_range_t r; | |
2014 ira_allocno_iterator ai; | 2112 ira_allocno_iterator ai; |
2015 | 2113 |
2016 merged_p = false; | 2114 merged_p = false; |
2017 FOR_EACH_ALLOCNO (a, ai) | 2115 FOR_EACH_ALLOCNO (a, ai) |
2018 { | 2116 { |
2027 continue; | 2125 continue; |
2028 } | 2126 } |
2029 propagate_p = a_node->parent->regno_allocno_map[regno] == NULL; | 2127 propagate_p = a_node->parent->regno_allocno_map[regno] == NULL; |
2030 /* Remove the allocno and update info of allocno in the upper | 2128 /* Remove the allocno and update info of allocno in the upper |
2031 region. */ | 2129 region. */ |
2032 r = ALLOCNO_LIVE_RANGES (a); | 2130 move_allocno_live_ranges (a, top_a); |
2033 change_allocno_in_range_list (r, top_a); | |
2034 ALLOCNO_LIVE_RANGES (top_a) | |
2035 = ira_merge_allocno_live_ranges (r, ALLOCNO_LIVE_RANGES (top_a)); | |
2036 merged_p = true; | 2131 merged_p = true; |
2037 ALLOCNO_LIVE_RANGES (a) = NULL; | |
2038 if (propagate_p) | 2132 if (propagate_p) |
2039 propagate_some_info_from_allocno (top_a, a); | 2133 propagate_some_info_from_allocno (top_a, a); |
2040 } | 2134 } |
2041 FOR_EACH_ALLOCNO (a, ai) | 2135 FOR_EACH_ALLOCNO (a, ai) |
2042 { | 2136 { |
2053 FOR_EACH_ALLOCNO (a, ai) | 2147 FOR_EACH_ALLOCNO (a, ai) |
2054 { | 2148 { |
2055 regno = ALLOCNO_REGNO (a); | 2149 regno = ALLOCNO_REGNO (a); |
2056 if (ira_loop_tree_root->regno_allocno_map[regno] == a) | 2150 if (ira_loop_tree_root->regno_allocno_map[regno] == a) |
2057 { | 2151 { |
2152 ira_object_t obj; | |
2153 ira_allocno_object_iterator oi; | |
2154 | |
2058 ira_regno_allocno_map[regno] = a; | 2155 ira_regno_allocno_map[regno] = a; |
2059 ALLOCNO_NEXT_REGNO_ALLOCNO (a) = NULL; | 2156 ALLOCNO_NEXT_REGNO_ALLOCNO (a) = NULL; |
2060 ALLOCNO_CAP_MEMBER (a) = NULL; | 2157 ALLOCNO_CAP_MEMBER (a) = NULL; |
2061 COPY_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), | 2158 FOR_EACH_ALLOCNO_OBJECT (a, obj, oi) |
2062 ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a)); | 2159 COPY_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), |
2160 OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); | |
2063 #ifdef STACK_REGS | 2161 #ifdef STACK_REGS |
2064 if (ALLOCNO_TOTAL_NO_STACK_REG_P (a)) | 2162 if (ALLOCNO_TOTAL_NO_STACK_REG_P (a)) |
2065 ALLOCNO_NO_STACK_REG_P (a) = true; | 2163 ALLOCNO_NO_STACK_REG_P (a) = true; |
2066 #endif | 2164 #endif |
2067 } | 2165 } |
2120 update_bad_spill_attribute (void) | 2218 update_bad_spill_attribute (void) |
2121 { | 2219 { |
2122 int i; | 2220 int i; |
2123 ira_allocno_t a; | 2221 ira_allocno_t a; |
2124 ira_allocno_iterator ai; | 2222 ira_allocno_iterator ai; |
2125 allocno_live_range_t r; | 2223 ira_allocno_object_iterator aoi; |
2224 ira_object_t obj; | |
2225 live_range_t r; | |
2126 enum reg_class cover_class; | 2226 enum reg_class cover_class; |
2127 bitmap_head dead_points[N_REG_CLASSES]; | 2227 bitmap_head dead_points[N_REG_CLASSES]; |
2128 | 2228 |
2129 for (i = 0; i < ira_reg_class_cover_size; i++) | 2229 for (i = 0; i < ira_reg_class_cover_size; i++) |
2130 { | 2230 { |
2134 FOR_EACH_ALLOCNO (a, ai) | 2234 FOR_EACH_ALLOCNO (a, ai) |
2135 { | 2235 { |
2136 cover_class = ALLOCNO_COVER_CLASS (a); | 2236 cover_class = ALLOCNO_COVER_CLASS (a); |
2137 if (cover_class == NO_REGS) | 2237 if (cover_class == NO_REGS) |
2138 continue; | 2238 continue; |
2139 for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next) | 2239 FOR_EACH_ALLOCNO_OBJECT (a, obj, aoi) |
2140 bitmap_set_bit (&dead_points[cover_class], r->finish); | 2240 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next) |
2241 bitmap_set_bit (&dead_points[cover_class], r->finish); | |
2141 } | 2242 } |
2142 FOR_EACH_ALLOCNO (a, ai) | 2243 FOR_EACH_ALLOCNO (a, ai) |
2143 { | 2244 { |
2144 cover_class = ALLOCNO_COVER_CLASS (a); | 2245 cover_class = ALLOCNO_COVER_CLASS (a); |
2145 if (cover_class == NO_REGS) | 2246 if (cover_class == NO_REGS) |
2146 continue; | 2247 continue; |
2147 if (! ALLOCNO_BAD_SPILL_P (a)) | 2248 if (! ALLOCNO_BAD_SPILL_P (a)) |
2148 continue; | 2249 continue; |
2149 for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next) | 2250 FOR_EACH_ALLOCNO_OBJECT (a, obj, aoi) |
2150 { | 2251 { |
2151 for (i = r->start + 1; i < r->finish; i++) | 2252 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next) |
2152 if (bitmap_bit_p (&dead_points[cover_class], i)) | 2253 { |
2254 for (i = r->start + 1; i < r->finish; i++) | |
2255 if (bitmap_bit_p (&dead_points[cover_class], i)) | |
2256 break; | |
2257 if (i < r->finish) | |
2258 break; | |
2259 } | |
2260 if (r != NULL) | |
2261 { | |
2262 ALLOCNO_BAD_SPILL_P (a) = false; | |
2153 break; | 2263 break; |
2154 if (i < r->finish) | 2264 } |
2155 break; | 2265 } |
2156 } | |
2157 if (r != NULL) | |
2158 ALLOCNO_BAD_SPILL_P (a) = false; | |
2159 } | 2266 } |
2160 for (i = 0; i < ira_reg_class_cover_size; i++) | 2267 for (i = 0; i < ira_reg_class_cover_size; i++) |
2161 { | 2268 { |
2162 cover_class = ira_reg_class_cover[i]; | 2269 cover_class = ira_reg_class_cover[i]; |
2163 bitmap_clear (&dead_points[cover_class]); | 2270 bitmap_clear (&dead_points[cover_class]); |
2171 setup_min_max_allocno_live_range_point (void) | 2278 setup_min_max_allocno_live_range_point (void) |
2172 { | 2279 { |
2173 int i; | 2280 int i; |
2174 ira_allocno_t a, parent_a, cap; | 2281 ira_allocno_t a, parent_a, cap; |
2175 ira_allocno_iterator ai; | 2282 ira_allocno_iterator ai; |
2176 allocno_live_range_t r; | 2283 #ifdef ENABLE_IRA_CHECKING |
2284 ira_object_iterator oi; | |
2285 ira_object_t obj; | |
2286 #endif | |
2287 live_range_t r; | |
2177 ira_loop_tree_node_t parent; | 2288 ira_loop_tree_node_t parent; |
2178 | 2289 |
2179 FOR_EACH_ALLOCNO (a, ai) | 2290 FOR_EACH_ALLOCNO (a, ai) |
2180 { | 2291 { |
2181 r = ALLOCNO_LIVE_RANGES (a); | 2292 int n = ALLOCNO_NUM_OBJECTS (a); |
2182 if (r == NULL) | 2293 for (i = 0; i < n; i++) |
2183 continue; | 2294 { |
2184 ALLOCNO_MAX (a) = r->finish; | 2295 ira_object_t obj = ALLOCNO_OBJECT (a, i); |
2185 for (; r->next != NULL; r = r->next) | 2296 r = OBJECT_LIVE_RANGES (obj); |
2186 ; | 2297 if (r == NULL) |
2187 ALLOCNO_MIN (a) = r->start; | 2298 continue; |
2299 OBJECT_MAX (obj) = r->finish; | |
2300 for (; r->next != NULL; r = r->next) | |
2301 ; | |
2302 OBJECT_MIN (obj) = r->start; | |
2303 } | |
2188 } | 2304 } |
2189 for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--) | 2305 for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--) |
2190 for (a = ira_regno_allocno_map[i]; | 2306 for (a = ira_regno_allocno_map[i]; |
2191 a != NULL; | 2307 a != NULL; |
2192 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a)) | 2308 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a)) |
2193 { | 2309 { |
2194 if (ALLOCNO_MAX (a) < 0) | 2310 int j; |
2195 continue; | 2311 int n = ALLOCNO_NUM_OBJECTS (a); |
2196 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL); | 2312 for (j = 0; j < n; j++) |
2197 /* Accumulation of range info. */ | |
2198 if (ALLOCNO_CAP (a) != NULL) | |
2199 { | 2313 { |
2200 for (cap = ALLOCNO_CAP (a); cap != NULL; cap = ALLOCNO_CAP (cap)) | 2314 ira_object_t obj = ALLOCNO_OBJECT (a, j); |
2315 ira_object_t parent_obj; | |
2316 | |
2317 if (OBJECT_MAX (obj) < 0) | |
2318 continue; | |
2319 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL); | |
2320 /* Accumulation of range info. */ | |
2321 if (ALLOCNO_CAP (a) != NULL) | |
2201 { | 2322 { |
2202 if (ALLOCNO_MAX (cap) < ALLOCNO_MAX (a)) | 2323 for (cap = ALLOCNO_CAP (a); cap != NULL; cap = ALLOCNO_CAP (cap)) |
2203 ALLOCNO_MAX (cap) = ALLOCNO_MAX (a); | 2324 { |
2204 if (ALLOCNO_MIN (cap) > ALLOCNO_MIN (a)) | 2325 ira_object_t cap_obj = ALLOCNO_OBJECT (cap, j); |
2205 ALLOCNO_MIN (cap) = ALLOCNO_MIN (a); | 2326 if (OBJECT_MAX (cap_obj) < OBJECT_MAX (obj)) |
2327 OBJECT_MAX (cap_obj) = OBJECT_MAX (obj); | |
2328 if (OBJECT_MIN (cap_obj) > OBJECT_MIN (obj)) | |
2329 OBJECT_MIN (cap_obj) = OBJECT_MIN (obj); | |
2330 } | |
2331 continue; | |
2206 } | 2332 } |
2207 continue; | 2333 if ((parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) == NULL) |
2334 continue; | |
2335 parent_a = parent->regno_allocno_map[i]; | |
2336 parent_obj = ALLOCNO_OBJECT (parent_a, j); | |
2337 if (OBJECT_MAX (parent_obj) < OBJECT_MAX (obj)) | |
2338 OBJECT_MAX (parent_obj) = OBJECT_MAX (obj); | |
2339 if (OBJECT_MIN (parent_obj) > OBJECT_MIN (obj)) | |
2340 OBJECT_MIN (parent_obj) = OBJECT_MIN (obj); | |
2208 } | 2341 } |
2209 if ((parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) == NULL) | |
2210 continue; | |
2211 parent_a = parent->regno_allocno_map[i]; | |
2212 if (ALLOCNO_MAX (parent_a) < ALLOCNO_MAX (a)) | |
2213 ALLOCNO_MAX (parent_a) = ALLOCNO_MAX (a); | |
2214 if (ALLOCNO_MIN (parent_a) > ALLOCNO_MIN (a)) | |
2215 ALLOCNO_MIN (parent_a) = ALLOCNO_MIN (a); | |
2216 } | 2342 } |
2217 #ifdef ENABLE_IRA_CHECKING | 2343 #ifdef ENABLE_IRA_CHECKING |
2218 FOR_EACH_ALLOCNO (a, ai) | 2344 FOR_EACH_OBJECT (obj, oi) |
2219 { | 2345 { |
2220 if ((0 <= ALLOCNO_MIN (a) && ALLOCNO_MIN (a) <= ira_max_point) | 2346 if ((0 <= OBJECT_MIN (obj) && OBJECT_MIN (obj) <= ira_max_point) |
2221 && (0 <= ALLOCNO_MAX (a) && ALLOCNO_MAX (a) <= ira_max_point)) | 2347 && (0 <= OBJECT_MAX (obj) && OBJECT_MAX (obj) <= ira_max_point)) |
2222 continue; | 2348 continue; |
2223 gcc_unreachable (); | 2349 gcc_unreachable (); |
2224 } | 2350 } |
2225 #endif | 2351 #endif |
2226 } | 2352 } |
2227 | 2353 |
2228 /* Sort allocnos according to their live ranges. Allocnos with | 2354 /* Sort allocnos according to their live ranges. Allocnos with |
2229 smaller cover class are put first unless we use priority coloring. | 2355 smaller cover class are put first unless we use priority coloring. |
2230 Allocnos with the same cove class are ordered according their start | 2356 Allocnos with the same cover class are ordered according their start |
2231 (min). Allocnos with the same start are ordered according their | 2357 (min). Allocnos with the same start are ordered according their |
2232 finish (max). */ | 2358 finish (max). */ |
2233 static int | 2359 static int |
2234 allocno_range_compare_func (const void *v1p, const void *v2p) | 2360 object_range_compare_func (const void *v1p, const void *v2p) |
2235 { | 2361 { |
2236 int diff; | 2362 int diff; |
2237 ira_allocno_t a1 = *(const ira_allocno_t *) v1p; | 2363 ira_object_t obj1 = *(const ira_object_t *) v1p; |
2238 ira_allocno_t a2 = *(const ira_allocno_t *) v2p; | 2364 ira_object_t obj2 = *(const ira_object_t *) v2p; |
2365 ira_allocno_t a1 = OBJECT_ALLOCNO (obj1); | |
2366 ira_allocno_t a2 = OBJECT_ALLOCNO (obj2); | |
2239 | 2367 |
2240 if (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY | 2368 if (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY |
2241 && (diff = ALLOCNO_COVER_CLASS (a1) - ALLOCNO_COVER_CLASS (a2)) != 0) | 2369 && (diff = ALLOCNO_COVER_CLASS (a1) - ALLOCNO_COVER_CLASS (a2)) != 0) |
2242 return diff; | 2370 return diff; |
2243 if ((diff = ALLOCNO_MIN (a1) - ALLOCNO_MIN (a2)) != 0) | 2371 if ((diff = OBJECT_MIN (obj1) - OBJECT_MIN (obj2)) != 0) |
2244 return diff; | 2372 return diff; |
2245 if ((diff = ALLOCNO_MAX (a1) - ALLOCNO_MAX (a2)) != 0) | 2373 if ((diff = OBJECT_MAX (obj1) - OBJECT_MAX (obj2)) != 0) |
2246 return diff; | 2374 return diff; |
2247 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2); | 2375 return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2); |
2248 } | 2376 } |
2249 | 2377 |
2250 /* Sort ira_conflict_id_allocno_map and set up conflict id of | 2378 /* Sort ira_object_id_map and set up conflict id of allocnos. */ |
2251 allocnos. */ | 2379 static void |
2252 static void | 2380 sort_conflict_id_map (void) |
2253 sort_conflict_id_allocno_map (void) | |
2254 { | 2381 { |
2255 int i, num; | 2382 int i, num; |
2256 ira_allocno_t a; | 2383 ira_allocno_t a; |
2257 ira_allocno_iterator ai; | 2384 ira_allocno_iterator ai; |
2258 | 2385 |
2259 num = 0; | 2386 num = 0; |
2260 FOR_EACH_ALLOCNO (a, ai) | 2387 FOR_EACH_ALLOCNO (a, ai) |
2261 ira_conflict_id_allocno_map[num++] = a; | 2388 { |
2262 qsort (ira_conflict_id_allocno_map, num, sizeof (ira_allocno_t), | 2389 ira_allocno_object_iterator oi; |
2263 allocno_range_compare_func); | 2390 ira_object_t obj; |
2391 | |
2392 FOR_EACH_ALLOCNO_OBJECT (a, obj, oi) | |
2393 ira_object_id_map[num++] = obj; | |
2394 } | |
2395 qsort (ira_object_id_map, num, sizeof (ira_object_t), | |
2396 object_range_compare_func); | |
2264 for (i = 0; i < num; i++) | 2397 for (i = 0; i < num; i++) |
2265 if ((a = ira_conflict_id_allocno_map[i]) != NULL) | 2398 { |
2266 ALLOCNO_CONFLICT_ID (a) = i; | 2399 ira_object_t obj = ira_object_id_map[i]; |
2267 for (i = num; i < ira_allocnos_num; i++) | 2400 gcc_assert (obj != NULL); |
2268 ira_conflict_id_allocno_map[i] = NULL; | 2401 OBJECT_CONFLICT_ID (obj) = i; |
2402 } | |
2403 for (i = num; i < ira_objects_num; i++) | |
2404 ira_object_id_map[i] = NULL; | |
2269 } | 2405 } |
2270 | 2406 |
2271 /* Set up minimal and maximal conflict ids of allocnos with which | 2407 /* Set up minimal and maximal conflict ids of allocnos with which |
2272 given allocno can conflict. */ | 2408 given allocno can conflict. */ |
2273 static void | 2409 static void |
2274 setup_min_max_conflict_allocno_ids (void) | 2410 setup_min_max_conflict_allocno_ids (void) |
2275 { | 2411 { |
2276 int cover_class; | 2412 int cover_class; |
2277 int i, j, min, max, start, finish, first_not_finished, filled_area_start; | 2413 int i, j, min, max, start, finish, first_not_finished, filled_area_start; |
2278 int *live_range_min, *last_lived; | 2414 int *live_range_min, *last_lived; |
2415 int word0_min, word0_max; | |
2279 ira_allocno_t a; | 2416 ira_allocno_t a; |
2280 | 2417 ira_allocno_iterator ai; |
2281 live_range_min = (int *) ira_allocate (sizeof (int) * ira_allocnos_num); | 2418 |
2419 live_range_min = (int *) ira_allocate (sizeof (int) * ira_objects_num); | |
2282 cover_class = -1; | 2420 cover_class = -1; |
2283 first_not_finished = -1; | 2421 first_not_finished = -1; |
2284 for (i = 0; i < ira_allocnos_num; i++) | 2422 for (i = 0; i < ira_objects_num; i++) |
2285 { | 2423 { |
2286 a = ira_conflict_id_allocno_map[i]; | 2424 ira_object_t obj = ira_object_id_map[i]; |
2287 if (a == NULL) | 2425 if (obj == NULL) |
2288 continue; | 2426 continue; |
2427 | |
2428 a = OBJECT_ALLOCNO (obj); | |
2429 | |
2289 if (cover_class < 0 | 2430 if (cover_class < 0 |
2290 || (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY | 2431 || (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY |
2291 && cover_class != (int) ALLOCNO_COVER_CLASS (a))) | 2432 && cover_class != (int) ALLOCNO_COVER_CLASS (a))) |
2292 { | 2433 { |
2293 cover_class = ALLOCNO_COVER_CLASS (a); | 2434 cover_class = ALLOCNO_COVER_CLASS (a); |
2294 min = i; | 2435 min = i; |
2295 first_not_finished = i; | 2436 first_not_finished = i; |
2296 } | 2437 } |
2297 else | 2438 else |
2298 { | 2439 { |
2299 start = ALLOCNO_MIN (a); | 2440 start = OBJECT_MIN (obj); |
2300 /* If we skip an allocno, the allocno with smaller ids will | 2441 /* If we skip an allocno, the allocno with smaller ids will |
2301 be also skipped because of the secondary sorting the | 2442 be also skipped because of the secondary sorting the |
2302 range finishes (see function | 2443 range finishes (see function |
2303 allocno_range_compare_func). */ | 2444 object_range_compare_func). */ |
2304 while (first_not_finished < i | 2445 while (first_not_finished < i |
2305 && start > ALLOCNO_MAX (ira_conflict_id_allocno_map | 2446 && start > OBJECT_MAX (ira_object_id_map |
2306 [first_not_finished])) | 2447 [first_not_finished])) |
2307 first_not_finished++; | 2448 first_not_finished++; |
2308 min = first_not_finished; | 2449 min = first_not_finished; |
2309 } | 2450 } |
2310 if (min == i) | 2451 if (min == i) |
2311 /* We could increase min further in this case but it is good | 2452 /* We could increase min further in this case but it is good |
2312 enough. */ | 2453 enough. */ |
2313 min++; | 2454 min++; |
2314 live_range_min[i] = ALLOCNO_MIN (a); | 2455 live_range_min[i] = OBJECT_MIN (obj); |
2315 ALLOCNO_MIN (a) = min; | 2456 OBJECT_MIN (obj) = min; |
2316 } | 2457 } |
2317 last_lived = (int *) ira_allocate (sizeof (int) * ira_max_point); | 2458 last_lived = (int *) ira_allocate (sizeof (int) * ira_max_point); |
2318 cover_class = -1; | 2459 cover_class = -1; |
2319 filled_area_start = -1; | 2460 filled_area_start = -1; |
2320 for (i = ira_allocnos_num - 1; i >= 0; i--) | 2461 for (i = ira_objects_num - 1; i >= 0; i--) |
2321 { | 2462 { |
2322 a = ira_conflict_id_allocno_map[i]; | 2463 ira_object_t obj = ira_object_id_map[i]; |
2323 if (a == NULL) | 2464 if (obj == NULL) |
2324 continue; | 2465 continue; |
2466 | |
2467 a = OBJECT_ALLOCNO (obj); | |
2325 if (cover_class < 0 | 2468 if (cover_class < 0 |
2326 || (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY | 2469 || (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY |
2327 && cover_class != (int) ALLOCNO_COVER_CLASS (a))) | 2470 && cover_class != (int) ALLOCNO_COVER_CLASS (a))) |
2328 { | 2471 { |
2329 cover_class = ALLOCNO_COVER_CLASS (a); | 2472 cover_class = ALLOCNO_COVER_CLASS (a); |
2330 for (j = 0; j < ira_max_point; j++) | 2473 for (j = 0; j < ira_max_point; j++) |
2331 last_lived[j] = -1; | 2474 last_lived[j] = -1; |
2332 filled_area_start = ira_max_point; | 2475 filled_area_start = ira_max_point; |
2333 } | 2476 } |
2334 min = live_range_min[i]; | 2477 min = live_range_min[i]; |
2335 finish = ALLOCNO_MAX (a); | 2478 finish = OBJECT_MAX (obj); |
2336 max = last_lived[finish]; | 2479 max = last_lived[finish]; |
2337 if (max < 0) | 2480 if (max < 0) |
2338 /* We could decrease max further in this case but it is good | 2481 /* We could decrease max further in this case but it is good |
2339 enough. */ | 2482 enough. */ |
2340 max = ALLOCNO_CONFLICT_ID (a) - 1; | 2483 max = OBJECT_CONFLICT_ID (obj) - 1; |
2341 ALLOCNO_MAX (a) = max; | 2484 OBJECT_MAX (obj) = max; |
2342 /* In filling, we can go further A range finish to recognize | 2485 /* In filling, we can go further A range finish to recognize |
2343 intersection quickly because if the finish of subsequently | 2486 intersection quickly because if the finish of subsequently |
2344 processed allocno (it has smaller conflict id) range is | 2487 processed allocno (it has smaller conflict id) range is |
2345 further A range finish than they are definitely intersected | 2488 further A range finish than they are definitely intersected |
2346 (the reason for this is the allocnos with bigger conflict id | 2489 (the reason for this is the allocnos with bigger conflict id |
2350 last_lived[j] = i; | 2493 last_lived[j] = i; |
2351 filled_area_start = min; | 2494 filled_area_start = min; |
2352 } | 2495 } |
2353 ira_free (last_lived); | 2496 ira_free (last_lived); |
2354 ira_free (live_range_min); | 2497 ira_free (live_range_min); |
2498 | |
2499 /* For allocnos with more than one object, we may later record extra conflicts in | |
2500 subobject 0 that we cannot really know about here. | |
2501 For now, simply widen the min/max range of these subobjects. */ | |
2502 | |
2503 word0_min = INT_MAX; | |
2504 word0_max = INT_MIN; | |
2505 | |
2506 FOR_EACH_ALLOCNO (a, ai) | |
2507 { | |
2508 int n = ALLOCNO_NUM_OBJECTS (a); | |
2509 ira_object_t obj0; | |
2510 if (n < 2) | |
2511 continue; | |
2512 obj0 = ALLOCNO_OBJECT (a, 0); | |
2513 if (OBJECT_CONFLICT_ID (obj0) < word0_min) | |
2514 word0_min = OBJECT_CONFLICT_ID (obj0); | |
2515 if (OBJECT_CONFLICT_ID (obj0) > word0_max) | |
2516 word0_max = OBJECT_CONFLICT_ID (obj0); | |
2517 } | |
2518 FOR_EACH_ALLOCNO (a, ai) | |
2519 { | |
2520 int n = ALLOCNO_NUM_OBJECTS (a); | |
2521 ira_object_t obj0; | |
2522 if (n < 2) | |
2523 continue; | |
2524 obj0 = ALLOCNO_OBJECT (a, 0); | |
2525 if (OBJECT_MIN (obj0) > word0_min) | |
2526 OBJECT_MIN (obj0) = word0_min; | |
2527 if (OBJECT_MAX (obj0) < word0_max) | |
2528 OBJECT_MAX (obj0) = word0_max; | |
2529 } | |
2355 } | 2530 } |
2356 | 2531 |
2357 | 2532 |
2358 | 2533 |
2359 static void | 2534 static void |
2387 time. */ | 2562 time. */ |
2388 | 2563 |
2389 /* Map: regno -> allocnos which will finally represent the regno for | 2564 /* Map: regno -> allocnos which will finally represent the regno for |
2390 IR with one region. */ | 2565 IR with one region. */ |
2391 static ira_allocno_t *regno_top_level_allocno_map; | 2566 static ira_allocno_t *regno_top_level_allocno_map; |
2567 | |
2568 /* Find the allocno that corresponds to A at a level one higher up in the | |
2569 loop tree. Returns NULL if A is a cap, or if it has no parent. */ | |
2570 ira_allocno_t | |
2571 ira_parent_allocno (ira_allocno_t a) | |
2572 { | |
2573 ira_loop_tree_node_t parent; | |
2574 | |
2575 if (ALLOCNO_CAP (a) != NULL) | |
2576 return NULL; | |
2577 | |
2578 parent = ALLOCNO_LOOP_TREE_NODE (a)->parent; | |
2579 if (parent == NULL) | |
2580 return NULL; | |
2581 | |
2582 return parent->regno_allocno_map[ALLOCNO_REGNO (a)]; | |
2583 } | |
2584 | |
2585 /* Find the allocno that corresponds to A at a level one higher up in the | |
2586 loop tree. If ALLOCNO_CAP is set for A, return that. */ | |
2587 ira_allocno_t | |
2588 ira_parent_or_cap_allocno (ira_allocno_t a) | |
2589 { | |
2590 if (ALLOCNO_CAP (a) != NULL) | |
2591 return ALLOCNO_CAP (a); | |
2592 | |
2593 return ira_parent_allocno (a); | |
2594 } | |
2392 | 2595 |
2393 /* Process all allocnos originated from pseudo REGNO and copy live | 2596 /* Process all allocnos originated from pseudo REGNO and copy live |
2394 ranges, hard reg conflicts, and allocno stack reg attributes from | 2597 ranges, hard reg conflicts, and allocno stack reg attributes from |
2395 low level allocnos to final allocnos which are destinations of | 2598 low level allocnos to final allocnos which are destinations of |
2396 removed stores at a loop exit. Return true if we copied live | 2599 removed stores at a loop exit. Return true if we copied live |
2399 copy_info_to_removed_store_destinations (int regno) | 2602 copy_info_to_removed_store_destinations (int regno) |
2400 { | 2603 { |
2401 ira_allocno_t a; | 2604 ira_allocno_t a; |
2402 ira_allocno_t parent_a = NULL; | 2605 ira_allocno_t parent_a = NULL; |
2403 ira_loop_tree_node_t parent; | 2606 ira_loop_tree_node_t parent; |
2404 allocno_live_range_t r; | |
2405 bool merged_p; | 2607 bool merged_p; |
2406 | 2608 |
2407 merged_p = false; | 2609 merged_p = false; |
2408 for (a = ira_regno_allocno_map[regno]; | 2610 for (a = ira_regno_allocno_map[regno]; |
2409 a != NULL; | 2611 a != NULL; |
2410 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a)) | 2612 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a)) |
2411 { | 2613 { |
2412 if (a != regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))]) | 2614 if (a != regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))]) |
2413 /* This allocno will be removed. */ | 2615 /* This allocno will be removed. */ |
2414 continue; | 2616 continue; |
2617 | |
2415 /* Caps will be removed. */ | 2618 /* Caps will be removed. */ |
2416 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL); | 2619 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL); |
2417 for (parent = ALLOCNO_LOOP_TREE_NODE (a)->parent; | 2620 for (parent = ALLOCNO_LOOP_TREE_NODE (a)->parent; |
2418 parent != NULL; | 2621 parent != NULL; |
2419 parent = parent->parent) | 2622 parent = parent->parent) |
2422 (parent_a))] | 2625 (parent_a))] |
2423 && ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a))) | 2626 && ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a))) |
2424 break; | 2627 break; |
2425 if (parent == NULL || parent_a == NULL) | 2628 if (parent == NULL || parent_a == NULL) |
2426 continue; | 2629 continue; |
2427 if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL) | 2630 |
2428 { | 2631 copy_allocno_live_ranges (a, parent_a); |
2429 fprintf | 2632 merge_hard_reg_conflicts (a, parent_a, true); |
2430 (ira_dump_file, | 2633 |
2431 " Coping ranges of a%dr%d to a%dr%d: ", | |
2432 ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)), | |
2433 ALLOCNO_NUM (parent_a), REGNO (ALLOCNO_REG (parent_a))); | |
2434 ira_print_live_range_list (ira_dump_file, | |
2435 ALLOCNO_LIVE_RANGES (a)); | |
2436 } | |
2437 r = ira_copy_allocno_live_range_list (ALLOCNO_LIVE_RANGES (a)); | |
2438 change_allocno_in_range_list (r, parent_a); | |
2439 ALLOCNO_LIVE_RANGES (parent_a) | |
2440 = ira_merge_allocno_live_ranges (r, ALLOCNO_LIVE_RANGES (parent_a)); | |
2441 IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (parent_a), | |
2442 ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a)); | |
2443 #ifdef STACK_REGS | |
2444 if (ALLOCNO_TOTAL_NO_STACK_REG_P (a)) | |
2445 ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a) = true; | |
2446 #endif | |
2447 ALLOCNO_CALL_FREQ (parent_a) += ALLOCNO_CALL_FREQ (a); | 2634 ALLOCNO_CALL_FREQ (parent_a) += ALLOCNO_CALL_FREQ (a); |
2448 ALLOCNO_CALLS_CROSSED_NUM (parent_a) | 2635 ALLOCNO_CALLS_CROSSED_NUM (parent_a) |
2449 += ALLOCNO_CALLS_CROSSED_NUM (a); | 2636 += ALLOCNO_CALLS_CROSSED_NUM (a); |
2450 ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a) | 2637 ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a) |
2451 += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a); | 2638 += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a); |
2461 IRA_MAX_POINT_BEFORE_EMIT are correspondingly MAX_REG_NUM () and | 2648 IRA_MAX_POINT_BEFORE_EMIT are correspondingly MAX_REG_NUM () and |
2462 IRA_MAX_POINT before emitting insns on the loop borders. */ | 2649 IRA_MAX_POINT before emitting insns on the loop borders. */ |
2463 void | 2650 void |
2464 ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit) | 2651 ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit) |
2465 { | 2652 { |
2466 int i, j, num; | 2653 int i, j; |
2467 bool keep_p; | 2654 bool keep_p; |
2468 int hard_regs_num; | 2655 int hard_regs_num; |
2469 bool new_pseudos_p, merged_p, mem_dest_p; | 2656 bool new_pseudos_p, merged_p, mem_dest_p; |
2470 unsigned int n; | 2657 unsigned int n; |
2471 enum reg_class cover_class; | 2658 enum reg_class cover_class; |
2472 ira_allocno_t a, parent_a, first, second, node_first, node_second; | 2659 ira_allocno_t a, parent_a, first, second, node_first, node_second; |
2473 ira_copy_t cp; | 2660 ira_copy_t cp; |
2474 ira_loop_tree_node_t parent, node; | 2661 ira_loop_tree_node_t node; |
2475 allocno_live_range_t r; | 2662 live_range_t r; |
2476 ira_allocno_iterator ai; | 2663 ira_allocno_iterator ai; |
2477 ira_copy_iterator ci; | 2664 ira_copy_iterator ci; |
2478 sparseset allocnos_live; | |
2479 | 2665 |
2480 regno_top_level_allocno_map | 2666 regno_top_level_allocno_map |
2481 = (ira_allocno_t *) ira_allocate (max_reg_num () * sizeof (ira_allocno_t)); | 2667 = (ira_allocno_t *) ira_allocate (max_reg_num () * sizeof (ira_allocno_t)); |
2482 memset (regno_top_level_allocno_map, 0, | 2668 memset (regno_top_level_allocno_map, 0, |
2483 max_reg_num () * sizeof (ira_allocno_t)); | 2669 max_reg_num () * sizeof (ira_allocno_t)); |
2484 new_pseudos_p = merged_p = false; | 2670 new_pseudos_p = merged_p = false; |
2485 FOR_EACH_ALLOCNO (a, ai) | 2671 FOR_EACH_ALLOCNO (a, ai) |
2486 { | 2672 { |
2673 ira_allocno_object_iterator oi; | |
2674 ira_object_t obj; | |
2487 if (ALLOCNO_CAP_MEMBER (a) != NULL) | 2675 if (ALLOCNO_CAP_MEMBER (a) != NULL) |
2488 /* Caps are not in the regno allocno maps and they are never | 2676 /* Caps are not in the regno allocno maps and they are never |
2489 will be transformed into allocnos existing after IR | 2677 will be transformed into allocnos existing after IR |
2490 flattening. */ | 2678 flattening. */ |
2491 continue; | 2679 continue; |
2492 COPY_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), | 2680 FOR_EACH_ALLOCNO_OBJECT (a, obj, oi) |
2493 ALLOCNO_CONFLICT_HARD_REGS (a)); | 2681 COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), |
2682 OBJECT_CONFLICT_HARD_REGS (obj)); | |
2494 #ifdef STACK_REGS | 2683 #ifdef STACK_REGS |
2495 ALLOCNO_TOTAL_NO_STACK_REG_P (a) = ALLOCNO_NO_STACK_REG_P (a); | 2684 ALLOCNO_TOTAL_NO_STACK_REG_P (a) = ALLOCNO_NO_STACK_REG_P (a); |
2496 #endif | 2685 #endif |
2497 } | 2686 } |
2498 /* Fix final allocno attributes. */ | 2687 /* Fix final allocno attributes. */ |
2504 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a)) | 2693 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a)) |
2505 { | 2694 { |
2506 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL); | 2695 ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL); |
2507 if (ALLOCNO_SOMEWHERE_RENAMED_P (a)) | 2696 if (ALLOCNO_SOMEWHERE_RENAMED_P (a)) |
2508 new_pseudos_p = true; | 2697 new_pseudos_p = true; |
2509 if (ALLOCNO_CAP (a) != NULL | 2698 parent_a = ira_parent_allocno (a); |
2510 || (parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) == NULL | 2699 if (parent_a == NULL) |
2511 || ((parent_a = parent->regno_allocno_map[ALLOCNO_REGNO (a)]) | |
2512 == NULL)) | |
2513 { | 2700 { |
2514 ALLOCNO_COPIES (a) = NULL; | 2701 ALLOCNO_COPIES (a) = NULL; |
2515 regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))] = a; | 2702 regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))] = a; |
2516 continue; | 2703 continue; |
2517 } | 2704 } |
2519 | 2706 |
2520 if (ALLOCNO_MEM_OPTIMIZED_DEST (a) != NULL) | 2707 if (ALLOCNO_MEM_OPTIMIZED_DEST (a) != NULL) |
2521 mem_dest_p = true; | 2708 mem_dest_p = true; |
2522 if (REGNO (ALLOCNO_REG (a)) == REGNO (ALLOCNO_REG (parent_a))) | 2709 if (REGNO (ALLOCNO_REG (a)) == REGNO (ALLOCNO_REG (parent_a))) |
2523 { | 2710 { |
2524 IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (parent_a), | 2711 merge_hard_reg_conflicts (a, parent_a, true); |
2525 ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a)); | 2712 move_allocno_live_ranges (a, parent_a); |
2526 #ifdef STACK_REGS | |
2527 if (ALLOCNO_TOTAL_NO_STACK_REG_P (a)) | |
2528 ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a) = true; | |
2529 #endif | |
2530 if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL) | |
2531 { | |
2532 fprintf (ira_dump_file, | |
2533 " Moving ranges of a%dr%d to a%dr%d: ", | |
2534 ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)), | |
2535 ALLOCNO_NUM (parent_a), | |
2536 REGNO (ALLOCNO_REG (parent_a))); | |
2537 ira_print_live_range_list (ira_dump_file, | |
2538 ALLOCNO_LIVE_RANGES (a)); | |
2539 } | |
2540 change_allocno_in_range_list (ALLOCNO_LIVE_RANGES (a), parent_a); | |
2541 ALLOCNO_LIVE_RANGES (parent_a) | |
2542 = ira_merge_allocno_live_ranges | |
2543 (ALLOCNO_LIVE_RANGES (a), ALLOCNO_LIVE_RANGES (parent_a)); | |
2544 merged_p = true; | 2713 merged_p = true; |
2545 ALLOCNO_LIVE_RANGES (a) = NULL; | |
2546 ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a) | 2714 ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a) |
2547 = (ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a) | 2715 = (ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a) |
2548 || ALLOCNO_MEM_OPTIMIZED_DEST_P (a)); | 2716 || ALLOCNO_MEM_OPTIMIZED_DEST_P (a)); |
2549 continue; | 2717 continue; |
2550 } | 2718 } |
2574 ALLOCNO_CONFLICT_HARD_REG_COSTS (parent_a)[j] | 2742 ALLOCNO_CONFLICT_HARD_REG_COSTS (parent_a)[j] |
2575 -= ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[j]; | 2743 -= ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[j]; |
2576 ALLOCNO_COVER_CLASS_COST (parent_a) | 2744 ALLOCNO_COVER_CLASS_COST (parent_a) |
2577 -= ALLOCNO_COVER_CLASS_COST (a); | 2745 -= ALLOCNO_COVER_CLASS_COST (a); |
2578 ALLOCNO_MEMORY_COST (parent_a) -= ALLOCNO_MEMORY_COST (a); | 2746 ALLOCNO_MEMORY_COST (parent_a) -= ALLOCNO_MEMORY_COST (a); |
2579 if (ALLOCNO_CAP (parent_a) != NULL | 2747 parent_a = ira_parent_allocno (parent_a); |
2580 || (parent | 2748 if (parent_a == NULL) |
2581 = ALLOCNO_LOOP_TREE_NODE (parent_a)->parent) == NULL | |
2582 || (parent_a = (parent->regno_allocno_map | |
2583 [ALLOCNO_REGNO (parent_a)])) == NULL) | |
2584 break; | 2749 break; |
2585 } | 2750 } |
2586 ALLOCNO_COPIES (a) = NULL; | 2751 ALLOCNO_COPIES (a) = NULL; |
2587 regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))] = a; | 2752 regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))] = a; |
2588 } | 2753 } |
2592 ira_assert (new_pseudos_p || ira_max_point_before_emit == ira_max_point); | 2757 ira_assert (new_pseudos_p || ira_max_point_before_emit == ira_max_point); |
2593 if (merged_p || ira_max_point_before_emit != ira_max_point) | 2758 if (merged_p || ira_max_point_before_emit != ira_max_point) |
2594 ira_rebuild_start_finish_chains (); | 2759 ira_rebuild_start_finish_chains (); |
2595 if (new_pseudos_p) | 2760 if (new_pseudos_p) |
2596 { | 2761 { |
2762 sparseset objects_live; | |
2763 | |
2597 /* Rebuild conflicts. */ | 2764 /* Rebuild conflicts. */ |
2598 FOR_EACH_ALLOCNO (a, ai) | 2765 FOR_EACH_ALLOCNO (a, ai) |
2599 { | 2766 { |
2767 ira_allocno_object_iterator oi; | |
2768 ira_object_t obj; | |
2600 if (a != regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))] | 2769 if (a != regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))] |
2601 || ALLOCNO_CAP_MEMBER (a) != NULL) | 2770 || ALLOCNO_CAP_MEMBER (a) != NULL) |
2602 continue; | 2771 continue; |
2603 for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next) | 2772 FOR_EACH_ALLOCNO_OBJECT (a, obj, oi) |
2604 ira_assert (r->allocno == a); | 2773 { |
2605 clear_allocno_conflicts (a); | 2774 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next) |
2606 } | 2775 ira_assert (r->object == obj); |
2607 allocnos_live = sparseset_alloc (ira_allocnos_num); | 2776 clear_conflicts (obj); |
2777 } | |
2778 } | |
2779 objects_live = sparseset_alloc (ira_objects_num); | |
2608 for (i = 0; i < ira_max_point; i++) | 2780 for (i = 0; i < ira_max_point; i++) |
2609 { | 2781 { |
2610 for (r = ira_start_point_ranges[i]; r != NULL; r = r->start_next) | 2782 for (r = ira_start_point_ranges[i]; r != NULL; r = r->start_next) |
2611 { | 2783 { |
2612 a = r->allocno; | 2784 ira_object_t obj = r->object; |
2785 a = OBJECT_ALLOCNO (obj); | |
2613 if (a != regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))] | 2786 if (a != regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))] |
2614 || ALLOCNO_CAP_MEMBER (a) != NULL) | 2787 || ALLOCNO_CAP_MEMBER (a) != NULL) |
2615 continue; | 2788 continue; |
2616 num = ALLOCNO_NUM (a); | 2789 |
2617 cover_class = ALLOCNO_COVER_CLASS (a); | 2790 cover_class = ALLOCNO_COVER_CLASS (a); |
2618 sparseset_set_bit (allocnos_live, num); | 2791 sparseset_set_bit (objects_live, OBJECT_CONFLICT_ID (obj)); |
2619 EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, n) | 2792 EXECUTE_IF_SET_IN_SPARSESET (objects_live, n) |
2620 { | 2793 { |
2621 ira_allocno_t live_a = ira_allocnos[n]; | 2794 ira_object_t live_obj = ira_object_id_map[n]; |
2622 | 2795 ira_allocno_t live_a = OBJECT_ALLOCNO (live_obj); |
2623 if (ira_reg_classes_intersect_p | 2796 enum reg_class live_cover = ALLOCNO_COVER_CLASS (live_a); |
2624 [cover_class][ALLOCNO_COVER_CLASS (live_a)] | 2797 if (ira_reg_classes_intersect_p[cover_class][live_cover] |
2625 /* Don't set up conflict for the allocno with itself. */ | 2798 /* Don't set up conflict for the allocno with itself. */ |
2626 && num != (int) n) | 2799 && live_a != a) |
2627 ira_add_allocno_conflict (a, live_a); | 2800 ira_add_conflict (obj, live_obj); |
2628 } | 2801 } |
2629 } | 2802 } |
2630 | 2803 |
2631 for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next) | 2804 for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next) |
2632 sparseset_clear_bit (allocnos_live, ALLOCNO_NUM (r->allocno)); | 2805 sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (r->object)); |
2633 } | 2806 } |
2634 sparseset_free (allocnos_live); | 2807 sparseset_free (objects_live); |
2635 compress_conflict_vecs (); | 2808 compress_conflict_vecs (); |
2636 } | 2809 } |
2637 /* Mark some copies for removing and change allocnos in the rest | 2810 /* Mark some copies for removing and change allocnos in the rest |
2638 copies. */ | 2811 copies. */ |
2639 FOR_EACH_COPY (cp, ci) | 2812 FOR_EACH_COPY (cp, ci) |
2755 ALLOCNO_NUM (a))); | 2928 ALLOCNO_NUM (a))); |
2756 } | 2929 } |
2757 } | 2930 } |
2758 #endif | 2931 #endif |
2759 | 2932 |
2933 /* Identify allocnos which prefer a register class with a single hard register. | |
2934 Adjust ALLOCNO_CONFLICT_HARD_REG_COSTS so that conflicting allocnos are | |
2935 less likely to use the preferred singleton register. */ | |
2936 static void | |
2937 update_conflict_hard_reg_costs (void) | |
2938 { | |
2939 ira_allocno_t a; | |
2940 ira_allocno_iterator ai; | |
2941 int i, index, min; | |
2942 | |
2943 FOR_EACH_ALLOCNO (a, ai) | |
2944 { | |
2945 enum reg_class cover_class = ALLOCNO_COVER_CLASS (a); | |
2946 enum reg_class pref = reg_preferred_class (ALLOCNO_REGNO (a)); | |
2947 | |
2948 if (reg_class_size[pref] != 1) | |
2949 continue; | |
2950 index = (ira_class_hard_reg_index[cover_class] | |
2951 [ira_class_hard_regs[pref][0]]); | |
2952 if (index < 0) | |
2953 continue; | |
2954 if (ALLOCNO_CONFLICT_HARD_REG_COSTS (a) == NULL | |
2955 || ALLOCNO_HARD_REG_COSTS (a) == NULL) | |
2956 continue; | |
2957 min = INT_MAX; | |
2958 for (i = ira_class_hard_regs_num[cover_class] - 1; i >= 0; i--) | |
2959 if (ALLOCNO_HARD_REG_COSTS (a)[i] > ALLOCNO_COVER_CLASS_COST (a) | |
2960 && min > ALLOCNO_HARD_REG_COSTS (a)[i]) | |
2961 min = ALLOCNO_HARD_REG_COSTS (a)[i]; | |
2962 if (min == INT_MAX) | |
2963 continue; | |
2964 ira_allocate_and_set_costs (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), | |
2965 cover_class, 0); | |
2966 ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] | |
2967 -= min - ALLOCNO_COVER_CLASS_COST (a); | |
2968 } | |
2969 } | |
2970 | |
2760 /* Create a internal representation (IR) for IRA (allocnos, copies, | 2971 /* Create a internal representation (IR) for IRA (allocnos, copies, |
2761 loop tree nodes). If LOOPS_P is FALSE the nodes corresponding to | 2972 loop tree nodes). If LOOPS_P is FALSE the nodes corresponding to |
2762 the loops (except the root which corresponds the all function) and | 2973 the loops (except the root which corresponds the all function) and |
2763 correspondingly allocnos for the loops will be not created. Such | 2974 correspondingly allocnos for the loops will be not created. Such |
2764 parameter value is used for Chaitin-Briggs coloring. The function | 2975 parameter value is used for Chaitin-Briggs coloring. The function |
2776 initiate_copies (); | 2987 initiate_copies (); |
2777 create_loop_tree_nodes (loops_p); | 2988 create_loop_tree_nodes (loops_p); |
2778 form_loop_tree (); | 2989 form_loop_tree (); |
2779 create_allocnos (); | 2990 create_allocnos (); |
2780 ira_costs (); | 2991 ira_costs (); |
2992 create_allocno_objects (); | |
2781 ira_create_allocno_live_ranges (); | 2993 ira_create_allocno_live_ranges (); |
2782 remove_unnecessary_regions (false); | 2994 remove_unnecessary_regions (false); |
2783 ira_compress_allocno_live_ranges (); | 2995 ira_compress_allocno_live_ranges (); |
2784 update_bad_spill_attribute (); | 2996 update_bad_spill_attribute (); |
2785 loops_p = more_one_region_p (); | 2997 loops_p = more_one_region_p (); |
2791 ira_tune_allocno_costs_and_cover_classes (); | 3003 ira_tune_allocno_costs_and_cover_classes (); |
2792 #ifdef ENABLE_IRA_CHECKING | 3004 #ifdef ENABLE_IRA_CHECKING |
2793 check_allocno_creation (); | 3005 check_allocno_creation (); |
2794 #endif | 3006 #endif |
2795 setup_min_max_allocno_live_range_point (); | 3007 setup_min_max_allocno_live_range_point (); |
2796 sort_conflict_id_allocno_map (); | 3008 sort_conflict_id_map (); |
2797 setup_min_max_conflict_allocno_ids (); | 3009 setup_min_max_conflict_allocno_ids (); |
2798 ira_build_conflicts (); | 3010 ira_build_conflicts (); |
3011 update_conflict_hard_reg_costs (); | |
2799 if (! ira_conflicts_p) | 3012 if (! ira_conflicts_p) |
2800 { | 3013 { |
2801 ira_allocno_t a; | 3014 ira_allocno_t a; |
2802 ira_allocno_iterator ai; | 3015 ira_allocno_iterator ai; |
2803 | 3016 |
2810 /* We don't save hard registers around calls for fast allocation | 3023 /* We don't save hard registers around calls for fast allocation |
2811 -- add caller clobbered registers as conflicting ones to | 3024 -- add caller clobbered registers as conflicting ones to |
2812 allocno crossing calls. */ | 3025 allocno crossing calls. */ |
2813 FOR_EACH_ALLOCNO (a, ai) | 3026 FOR_EACH_ALLOCNO (a, ai) |
2814 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0) | 3027 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0) |
2815 { | 3028 ior_hard_reg_conflicts (a, &call_used_reg_set); |
2816 IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), | |
2817 call_used_reg_set); | |
2818 IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), | |
2819 call_used_reg_set); | |
2820 } | |
2821 } | 3029 } |
2822 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) | 3030 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) |
2823 print_copies (ira_dump_file); | 3031 print_copies (ira_dump_file); |
2824 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL) | 3032 if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL) |
2825 { | 3033 { |
2826 int n, nr; | 3034 int n, nr, nr_big; |
2827 ira_allocno_t a; | 3035 ira_allocno_t a; |
2828 allocno_live_range_t r; | 3036 live_range_t r; |
2829 ira_allocno_iterator ai; | 3037 ira_allocno_iterator ai; |
2830 | 3038 |
2831 n = 0; | 3039 n = 0; |
3040 nr = 0; | |
3041 nr_big = 0; | |
2832 FOR_EACH_ALLOCNO (a, ai) | 3042 FOR_EACH_ALLOCNO (a, ai) |
2833 n += ALLOCNO_CONFLICT_ALLOCNOS_NUM (a); | 3043 { |
2834 nr = 0; | 3044 int j, nobj = ALLOCNO_NUM_OBJECTS (a); |
2835 FOR_EACH_ALLOCNO (a, ai) | 3045 if (nobj > 1) |
2836 for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next) | 3046 nr_big++; |
2837 nr++; | 3047 for (j = 0; j < nobj; j++) |
3048 { | |
3049 ira_object_t obj = ALLOCNO_OBJECT (a, j); | |
3050 n += OBJECT_NUM_CONFLICTS (obj); | |
3051 for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next) | |
3052 nr++; | |
3053 } | |
3054 } | |
2838 fprintf (ira_dump_file, " regions=%d, blocks=%d, points=%d\n", | 3055 fprintf (ira_dump_file, " regions=%d, blocks=%d, points=%d\n", |
2839 VEC_length (loop_p, ira_loops.larray), n_basic_blocks, | 3056 VEC_length (loop_p, ira_loops.larray), n_basic_blocks, |
2840 ira_max_point); | 3057 ira_max_point); |
2841 fprintf (ira_dump_file, | 3058 fprintf (ira_dump_file, |
2842 " allocnos=%d, copies=%d, conflicts=%d, ranges=%d\n", | 3059 " allocnos=%d (big %d), copies=%d, conflicts=%d, ranges=%d\n", |
2843 ira_allocnos_num, ira_copies_num, n, nr); | 3060 ira_allocnos_num, nr_big, ira_copies_num, n, nr); |
2844 } | 3061 } |
2845 return loops_p; | 3062 return loops_p; |
2846 } | 3063 } |
2847 | 3064 |
2848 /* Release the data created by function ira_build. */ | 3065 /* Release the data created by function ira_build. */ |