* gnu/regexp/CharIndexedReader.java: Removed.
[official-gcc.git] / gcc / tree-ssa-live.h
blob30c33cfb84ba21768237800a68af32d96e5c6e5d
1 /* Routines for liveness in SSA trees.
2 Copyright (C) 2003, 2004 Free Software Foundation, Inc.
3 Contributed by Andrew MacLeod <amacleod@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
23 #ifndef _TREE_SSA_LIVE_H
24 #define _TREE_SSA_LIVE_H 1
26 /* Used to create the variable mapping when we go out of SSA form. */
27 typedef struct _var_map
29 /* The partition of all variables. */
30 partition var_partition;
32 /* Vector for compacting partitions. */
33 int *partition_to_compact;
34 int *compact_to_partition;
36 /* Mapping of partition numbers to vars. */
37 tree *partition_to_var;
39 /* Current number of partitions. */
40 unsigned int num_partitions;
42 /* Original partition size. */
43 unsigned int partition_size;
45 /* Reference count, if required. */
46 int *ref_count;
47 } *var_map;
49 #define VAR_ANN_PARTITION(ann) (ann->partition)
50 #define VAR_ANN_ROOT_INDEX(ann) (ann->root_index)
52 #define NO_PARTITION -1
54 /* Flags to pass to compact_var_map */
56 #define VARMAP_NORMAL 0
57 #define VARMAP_NO_SINGLE_DEFS 1
59 /* Flags to pass to remove_ssa_form. */
61 #define SSANORM_PERFORM_TER 0x1
62 #define SSANORM_COMBINE_TEMPS 0x2
63 #define SSANORM_REMOVE_ALL_PHIS 0x4
64 #define SSANORM_COALESCE_PARTITIONS 0x8
65 #define SSANORM_USE_COALESCE_LIST 0x10
67 extern var_map init_var_map (int);
68 extern void delete_var_map (var_map);
69 extern void dump_var_map (FILE *, var_map);
70 extern int var_union (var_map, tree, tree);
71 extern void change_partition_var (var_map, tree, int);
72 extern void compact_var_map (var_map, int);
73 extern void remove_ssa_form (FILE *, var_map, int);
74 extern void register_ssa_partitions_for_vars (bitmap vars, var_map map);
75 extern tree make_ssa_temp (tree);
77 static inline int num_var_partitions (var_map);
78 static inline tree var_to_partition_to_var (var_map, tree);
79 static inline tree partition_to_var (var_map, int);
80 static inline int var_to_partition (var_map, tree);
81 static inline tree version_to_var (var_map, int);
82 static inline int version_ref_count (var_map, tree);
83 static inline void register_ssa_partition (var_map, tree, bool);
85 #define SSA_VAR_MAP_REF_COUNT 0x01
86 extern var_map create_ssa_var_map (int);
89 /* Number of partitions in MAP. */
91 static inline int
92 num_var_partitions (var_map map)
94 return map->num_partitions;
98 /* Return the reference count for SSA_VAR's partition in MAP. */
100 static inline int
101 version_ref_count (var_map map, tree ssa_var)
103 int version = SSA_NAME_VERSION (ssa_var);
104 #ifdef ENABLE_CHECKING
105 if (!map->ref_count)
106 abort ();
107 #endif
108 return map->ref_count[version];
112 /* Given partition index I from MAP, return the variable which represents that
113 partition. */
115 static inline tree
116 partition_to_var (var_map map, int i)
118 if (map->compact_to_partition)
119 i = map->compact_to_partition[i];
120 i = partition_find (map->var_partition, i);
121 return map->partition_to_var[i];
125 /* Given ssa_name VERSION, if it has a partition in MAP, return the var it
126 is associated with. Otherwise return NULL. */
128 static inline tree version_to_var (var_map map, int version)
130 int part;
131 part = partition_find (map->var_partition, version);
132 if (map->partition_to_compact)
133 part = map->partition_to_compact[part];
134 if (part == NO_PARTITION)
135 return NULL_TREE;
137 return partition_to_var (map, part);
141 /* Given VAR, return the partition number in MAP which contains it.
142 NO_PARTITION is returned if its not in any partition. */
144 static inline int
145 var_to_partition (var_map map, tree var)
147 var_ann_t ann;
148 int part;
150 if (TREE_CODE (var) == SSA_NAME)
152 part = partition_find (map->var_partition, SSA_NAME_VERSION (var));
153 if (map->partition_to_compact)
154 part = map->partition_to_compact[part];
156 else
158 ann = var_ann (var);
159 if (ann->out_of_ssa_tag)
160 part = VAR_ANN_PARTITION (ann);
161 else
162 part = NO_PARTITION;
164 return part;
168 /* Given VAR, return the variable which represents the entire partition
169 it is a member of in MAP. NULL is returned if it is not in a partition. */
171 static inline tree
172 var_to_partition_to_var (var_map map, tree var)
174 int part;
176 part = var_to_partition (map, var);
177 if (part == NO_PARTITION)
178 return NULL_TREE;
179 return partition_to_var (map, part);
183 /* This routine registers a partition for SSA_VAR with MAP. IS_USE is used
184 to count references. Any unregistered partitions may be compacted out
185 later. */
187 static inline void
188 register_ssa_partition (var_map map, tree ssa_var, bool is_use)
190 int version;
192 #if defined ENABLE_CHECKING
193 if (TREE_CODE (ssa_var) != SSA_NAME)
194 abort ();
196 if (!is_gimple_reg (SSA_NAME_VAR (ssa_var)))
198 fprintf (stderr, "Illegally registering a virtual SSA name :");
199 print_generic_expr (stderr, ssa_var, TDF_SLIM);
200 fprintf (stderr, " in the SSA->Normal phase.\n");
201 abort();
203 #endif
205 version = SSA_NAME_VERSION (ssa_var);
206 if (is_use && map->ref_count)
207 map->ref_count[version]++;
209 if (map->partition_to_var[version] == NULL_TREE)
210 map->partition_to_var[SSA_NAME_VERSION (ssa_var)] = ssa_var;
214 /* ---------------- live on entry/exit info ------------------------------
216 This structure is used to represent live range information on SSA based
217 trees. A partition map must be provided, and based on the active partitions,
218 live-on-entry information and live-on-exit information can be calculated.
219 As well, partitions are marked as to whether they are global (live
220 outside the basic block they are defined in).
222 The live-on-entry information is per variable. It provide a bitmap for
223 each variable which has a bit set for each basic block that the variable
224 is live on entry to that block.
226 The live-on-exit information is per block. It provides a bitmap for each
227 block indicating which partitions are live on exit from the block.
229 For the purposes of this implementation, we treat the elements of a PHI
230 as follows:
232 Uses in a PHI are considered LIVE-ON-EXIT to the block from which they
233 originate. They are *NOT* considered live on entry to the block
234 containing the PHI node.
236 The Def of a PHI node is *not* considered live on entry to the block.
237 It is considered to be "define early" in the block. Picture it as each
238 block having a stmt (or block-preheader) before the first real stmt in
239 the block which defines all the variables that are defined by PHIs.
241 ----------------------------------------------------------------------- */
244 typedef struct tree_live_info_d
246 /* Var map this relates to. */
247 var_map map;
249 /* Bitmap indicating which partitions are global. */
250 bitmap global;
252 /* Bitmap of live on entry blocks for partition elements. */
253 bitmap *livein;
255 /* Number of basic blocks when live on exit calculated. */
256 int num_blocks;
258 /* Bitmap of what variables are live on exit for a basic blocks. */
259 bitmap *liveout;
260 } *tree_live_info_p;
263 extern tree_live_info_p calculate_live_on_entry (var_map);
264 extern void calculate_live_on_exit (tree_live_info_p);
265 extern void delete_tree_live_info (tree_live_info_p);
267 #define LIVEDUMP_ENTRY 0x01
268 #define LIVEDUMP_EXIT 0x02
269 #define LIVEDUMP_ALL (LIVEDUMP_ENTRY | LIVEDUMP_EXIT)
270 extern void dump_live_info (FILE *, tree_live_info_p, int);
272 static inline int partition_is_global (tree_live_info_p, int);
273 static inline bitmap live_entry_blocks (tree_live_info_p, int);
274 static inline bitmap live_on_exit (tree_live_info_p, basic_block);
275 static inline var_map live_var_map (tree_live_info_p);
276 static inline void live_merge_and_clear (tree_live_info_p, int, int);
277 static inline void make_live_on_entry (tree_live_info_p, basic_block, int);
280 /* Return TRUE if P is marked as a global in LIVE. */
282 static inline int
283 partition_is_global (tree_live_info_p live, int p)
285 if (!live->global)
286 abort ();
288 return bitmap_bit_p (live->global, p);
292 /* Return the bitmap from LIVE representing the live on entry blocks for
293 partition P. */
295 static inline bitmap
296 live_entry_blocks (tree_live_info_p live, int p)
298 if (!live->livein)
299 abort ();
301 return live->livein[p];
305 /* Return the bitmap from LIVE representing the live on exit partitions from
306 block BB. */
308 static inline bitmap
309 live_on_exit (tree_live_info_p live, basic_block bb)
311 if (!live->liveout)
312 abort();
314 if (bb == ENTRY_BLOCK_PTR || bb == EXIT_BLOCK_PTR)
315 abort ();
317 return live->liveout[bb->index];
321 /* Return the partition map which the information in LIVE utilizes. */
323 static inline var_map
324 live_var_map (tree_live_info_p live)
326 return live->map;
330 /* Merge the live on entry information in LIVE for partitions P1 and P2. Place
331 the result into P1. Clear P2. */
333 static inline void
334 live_merge_and_clear (tree_live_info_p live, int p1, int p2)
336 bitmap_a_or_b (live->livein[p1], live->livein[p1], live->livein[p2]);
337 bitmap_zero (live->livein[p2]);
341 /* Mark partition P as live on entry to basic block BB in LIVE. */
343 static inline void
344 make_live_on_entry (tree_live_info_p live, basic_block bb , int p)
346 bitmap_set_bit (live->livein[p], bb->index);
347 bitmap_set_bit (live->global, p);
351 /* A tree_partition_associator (TPA)object is a base structure which allows
352 partitions to be associated with a tree object.
354 A varray of tree elements represent each distinct tree item.
355 A parallel int array represents the first partition number associated with
356 the tree.
357 This partition number is then used as in index into the next_partition
358 array, which returns the index of the next partition which is associated
359 with the tree. TPA_NONE indicates the end of the list.
360 A varray paralleling the partition list 'partition_to_tree_map' is used
361 to indicate which tree index the partition is in. */
363 typedef struct tree_partition_associator_d
365 varray_type trees;
366 varray_type first_partition;
367 int *next_partition;
368 int *partition_to_tree_map;
369 int num_trees;
370 int uncompressed_num;
371 var_map map;
372 } *tpa_p;
374 /* Value returned when there are no more partitions associated with a tree. */
375 #define TPA_NONE -1
377 static inline tree tpa_tree (tpa_p, int);
378 static inline int tpa_first_partition (tpa_p, int);
379 static inline int tpa_next_partition (tpa_p, int);
380 static inline int tpa_num_trees (tpa_p);
381 static inline int tpa_find_tree (tpa_p, int);
382 static inline void tpa_decompact (tpa_p);
383 extern tpa_p tpa_init (var_map);
384 extern void tpa_delete (tpa_p);
385 extern void tpa_dump (FILE *, tpa_p);
386 extern void tpa_remove_partition (tpa_p, int, int);
387 extern int tpa_compact (tpa_p);
390 /* Return the number of distinct tree nodes in TPA. */
392 static inline int
393 tpa_num_trees (tpa_p tpa)
395 return tpa->num_trees;
399 /* Return the tree node for index I in TPA. */
401 static inline tree
402 tpa_tree (tpa_p tpa, int i)
404 return VARRAY_TREE (tpa->trees, i);
408 /* Return the first partition associated with tree list I in TPA. */
410 static inline int
411 tpa_first_partition (tpa_p tpa, int i)
413 return VARRAY_INT (tpa->first_partition, i);
417 /* Return the next partition after partition I in TPA's list. */
419 static inline int
420 tpa_next_partition (tpa_p tpa, int i)
422 return tpa->next_partition[i];
426 /* Return the tree index from TPA whose list contains partition I.
427 TPA_NONE is returned if I is not associated with any list. */
429 static inline int
430 tpa_find_tree (tpa_p tpa, int i)
432 int index;
434 index = tpa->partition_to_tree_map[i];
435 /* When compressed, any index higher than the number of tree elements is
436 a compressed element, so return TPA_NONE. */
437 if (index != TPA_NONE && index >= tpa_num_trees (tpa))
439 #ifdef ENABLE_CHECKING
440 if (tpa->uncompressed_num == -1)
441 abort ();
442 #endif
443 index = TPA_NONE;
446 return index;
450 /* This function removes any compaction which was performed on TPA. */
452 static inline void
453 tpa_decompact(tpa_p tpa)
455 #ifdef ENABLE_CHECKING
456 if (tpa->uncompressed_num == -1)
457 abort ();
458 #endif
459 tpa->num_trees = tpa->uncompressed_num;
463 /* Once a var_map has been created and compressed, a complimentary root_var
464 object can be built. This creates a list of all the root variables from
465 which ssa version names are derived. Each root variable has a list of
466 which partitions are versions of that root.
468 This is implemented using the tree_partition_associator.
470 The tree vector is used to represent the root variable.
471 The list of partitions represent SSA versions of the root variable. */
473 typedef tpa_p root_var_p;
475 static inline tree root_var (root_var_p, int);
476 static inline int root_var_first_partition (root_var_p, int);
477 static inline int root_var_next_partition (root_var_p, int);
478 static inline int root_var_num (root_var_p);
479 static inline void root_var_dump (FILE *, root_var_p);
480 static inline void root_var_remove_partition (root_var_p, int, int);
481 static inline void root_var_delete (root_var_p);
482 static inline int root_var_find (root_var_p, int);
483 static inline int root_var_compact (root_var_p);
484 static inline void root_var_decompact (tpa_p);
486 extern root_var_p root_var_init (var_map);
488 /* Value returned when there are no more partitions associated with a root
489 variable. */
490 #define ROOT_VAR_NONE TPA_NONE
493 /* Return the number of distinct root variables in RV. */
495 static inline int
496 root_var_num (root_var_p rv)
498 return tpa_num_trees (rv);
502 /* Return root variable I from RV. */
504 static inline tree
505 root_var (root_var_p rv, int i)
507 return tpa_tree (rv, i);
511 /* Return the first partition in RV belonging to root variable list I. */
513 static inline int
514 root_var_first_partition (root_var_p rv, int i)
516 return tpa_first_partition (rv, i);
520 /* Return the next partition after partition I in a root list from RV. */
522 static inline int
523 root_var_next_partition (root_var_p rv, int i)
525 return tpa_next_partition (rv, i);
529 /* Send debug info for root_var list RV to file F. */
531 static inline void
532 root_var_dump (FILE *f, root_var_p rv)
534 fprintf (f, "\nRoot Var dump\n");
535 tpa_dump (f, rv);
536 fprintf (f, "\n");
540 /* Destroy root_var object RV. */
542 static inline void
543 root_var_delete (root_var_p rv)
545 tpa_delete (rv);
549 /* Remove partition PARTITION_INDEX from root_var list ROOT_INDEX in RV. */
551 static inline void
552 root_var_remove_partition (root_var_p rv, int root_index, int partition_index)
554 tpa_remove_partition (rv, root_index, partition_index);
558 /* Return the root_var list index for partition I in RV. */
560 static inline int
561 root_var_find (root_var_p rv, int i)
563 return tpa_find_tree (rv, i);
567 /* Hide single element lists in RV. */
569 static inline int
570 root_var_compact (root_var_p rv)
572 return tpa_compact (rv);
576 /* Expose the single element lists in RV. */
578 static inline void
579 root_var_decompact (root_var_p rv)
581 tpa_decompact (rv);
585 /* A TYPE_VAR object is similar to a root_var object, except this associates
586 partitions with their type rather than their root variable. This is used to
587 coalesce memory locations based on type. */
589 typedef tpa_p type_var_p;
591 static inline tree type_var (type_var_p, int);
592 static inline int type_var_first_partition (type_var_p, int);
593 static inline int type_var_next_partition (type_var_p, int);
594 static inline int type_var_num (type_var_p);
595 static inline void type_var_dump (FILE *, type_var_p);
596 static inline void type_var_remove_partition (type_var_p, int, int);
597 static inline void type_var_delete (type_var_p);
598 static inline int type_var_find (type_var_p, int);
599 static inline int type_var_compact (type_var_p);
600 static inline void type_var_decompact (type_var_p);
602 extern type_var_p type_var_init (var_map);
604 /* Value returned when there is no partitions associated with a list. */
605 #define TYPE_VAR_NONE TPA_NONE
608 /* Return the number of distinct type lists in TV. */
610 static inline int
611 type_var_num (type_var_p tv)
613 return tpa_num_trees (tv);
617 /* Return the type of list I in TV. */
619 static inline tree
620 type_var (type_var_p tv, int i)
622 return tpa_tree (tv, i);
626 /* Return the first partition belonging to type list I in TV. */
628 static inline int
629 type_var_first_partition (type_var_p tv, int i)
631 return tpa_first_partition (tv, i);
635 /* Return the next partition after partition I in a type list within TV. */
637 static inline int
638 type_var_next_partition (type_var_p tv, int i)
640 return tpa_next_partition (tv, i);
644 /* Send debug info for type_var object TV to file F. */
646 static inline void
647 type_var_dump (FILE *f, type_var_p tv)
649 fprintf (f, "\nType Var dump\n");
650 tpa_dump (f, tv);
651 fprintf (f, "\n");
655 /* Delete type_var object TV. */
657 static inline void
658 type_var_delete (type_var_p tv)
660 tpa_delete (tv);
664 /* Remove partition PARTITION_INDEX from type list TYPE_INDEX in TV. */
666 static inline void
667 type_var_remove_partition (type_var_p tv, int type_index, int partition_index)
669 tpa_remove_partition (tv, type_index, partition_index);
673 /* Return the type index in TV for the list partition I is in. */
675 static inline int
676 type_var_find (type_var_p tv, int i)
678 return tpa_find_tree (tv, i);
682 /* Hide single element lists in TV. */
684 static inline int
685 type_var_compact (type_var_p tv)
687 return tpa_compact (tv);
691 /* Expose single element lists in TV. */
693 static inline void
694 type_var_decompact (type_var_p tv)
696 tpa_decompact (tv);
699 /* This set of routines implements a coalesce_list. This is an object which
700 is used to track pairs of partitions which are desirable to coalesce
701 together at some point. Costs are associated with each pair, and when
702 all desired information has been collected, the object can be used to
703 order the pairs for processing. */
705 /* This structure defines a pair for coalescing. */
707 typedef struct partition_pair_d
709 int first_partition;
710 int second_partition;
711 int cost;
712 struct partition_pair_d *next;
713 } *partition_pair_p;
715 /* This structure maintains the list of coalesce pairs.
716 When add_mode is true, list is a triangular shaped list of coalesce pairs.
717 The smaller partition number is used to index the list, and the larger is
718 index is located in a partition_pair_p object. These lists are sorted from
719 smallest to largest by 'second_partition'. New coalesce pairs are allowed
720 to be added in this mode.
721 When add_mode is false, the lists have all been merged into list[0]. The
722 rest of the lists are not used. list[0] is ordered from most desirable
723 coalesce to least desirable. pop_best_coalesce() retrieves the pairs
724 one at a time. */
726 typedef struct coalesce_list_d
728 var_map map;
729 partition_pair_p *list;
730 bool add_mode;
731 } *coalesce_list_p;
733 extern coalesce_list_p create_coalesce_list (var_map);
734 extern void add_coalesce (coalesce_list_p, int, int, int);
735 extern void sort_coalesce_list (coalesce_list_p);
736 extern void dump_coalesce_list (FILE *, coalesce_list_p);
737 extern void delete_coalesce_list (coalesce_list_p);
739 #define NO_BEST_COALESCE -1
740 extern int pop_best_coalesce (coalesce_list_p, int *, int *);
742 extern conflict_graph build_tree_conflict_graph (tree_live_info_p, tpa_p,
743 coalesce_list_p);
744 extern void coalesce_tpa_members (tpa_p tpa, conflict_graph graph, var_map map,
745 coalesce_list_p cl, FILE *);
748 #endif /* _TREE_SSA_LIVE_H */