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)
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 #include "partition.h"
28 /* Used to create the variable mapping when we go out of SSA form. */
29 typedef struct _var_map
31 /* The partition of all variables. */
32 partition var_partition
;
34 /* Vector for compacting partitions. */
35 int *partition_to_compact
;
36 int *compact_to_partition
;
38 /* Mapping of partition numbers to vars. */
39 tree
*partition_to_var
;
41 /* Current number of partitions. */
42 unsigned int num_partitions
;
44 /* Original partition size. */
45 unsigned int partition_size
;
47 /* Reference count, if required. */
51 #define VAR_ANN_PARTITION(ann) (ann->partition)
52 #define VAR_ANN_ROOT_INDEX(ann) (ann->root_index)
54 #define NO_PARTITION -1
56 /* Flags to pass to compact_var_map */
58 #define VARMAP_NORMAL 0
59 #define VARMAP_NO_SINGLE_DEFS 1
61 extern var_map
init_var_map (int);
62 extern void delete_var_map (var_map
);
63 extern void dump_var_map (FILE *, var_map
);
64 extern int var_union (var_map
, tree
, tree
);
65 extern void change_partition_var (var_map
, tree
, int);
66 extern void compact_var_map (var_map
, int);
67 extern tree
make_ssa_temp (tree
);
69 static inline int num_var_partitions (var_map
);
70 static inline tree
var_to_partition_to_var (var_map
, tree
);
71 static inline tree
partition_to_var (var_map
, int);
72 static inline int var_to_partition (var_map
, tree
);
73 static inline tree
version_to_var (var_map
, int);
74 static inline int version_ref_count (var_map
, tree
);
75 static inline void register_ssa_partition (var_map
, tree
, bool);
77 #define SSA_VAR_MAP_REF_COUNT 0x01
78 extern var_map
create_ssa_var_map (int);
81 /* Number of partitions in MAP. */
84 num_var_partitions (var_map map
)
86 return map
->num_partitions
;
90 /* Return the reference count for SSA_VAR's partition in MAP. */
93 version_ref_count (var_map map
, tree ssa_var
)
95 int version
= SSA_NAME_VERSION (ssa_var
);
96 #ifdef ENABLE_CHECKING
100 return map
->ref_count
[version
];
104 /* Given partition index I from MAP, return the variable which represents that
108 partition_to_var (var_map map
, int i
)
110 if (map
->compact_to_partition
)
111 i
= map
->compact_to_partition
[i
];
112 i
= partition_find (map
->var_partition
, i
);
113 return map
->partition_to_var
[i
];
117 /* Given ssa_name VERSION, if it has a partition in MAP, return the var it
118 is associated with. Otherwise return NULL. */
120 static inline tree
version_to_var (var_map map
, int version
)
123 part
= partition_find (map
->var_partition
, version
);
124 if (map
->partition_to_compact
)
125 part
= map
->partition_to_compact
[part
];
126 if (part
== NO_PARTITION
)
129 return partition_to_var (map
, part
);
133 /* Given VAR, return the partition number in MAP which contains it.
134 NO_PARTITION is returned if its not in any partition. */
137 var_to_partition (var_map map
, tree var
)
142 if (TREE_CODE (var
) == SSA_NAME
)
144 part
= partition_find (map
->var_partition
, SSA_NAME_VERSION (var
));
145 if (map
->partition_to_compact
)
146 part
= map
->partition_to_compact
[part
];
151 if (ann
->out_of_ssa_tag
)
152 part
= VAR_ANN_PARTITION (ann
);
160 /* Given VAR, return the variable which represents the entire partition
161 it is a member of in MAP. NULL is returned if it is not in a partition. */
164 var_to_partition_to_var (var_map map
, tree var
)
168 part
= var_to_partition (map
, var
);
169 if (part
== NO_PARTITION
)
171 return partition_to_var (map
, part
);
175 /* This routine registers a partition for SSA_VAR with MAP. IS_USE is used
176 to count references. Any unregistered partitions may be compacted out
180 register_ssa_partition (var_map map
, tree ssa_var
, bool is_use
)
184 #if defined ENABLE_CHECKING
185 if (TREE_CODE (ssa_var
) != SSA_NAME
)
188 if (!is_gimple_reg (SSA_NAME_VAR (ssa_var
)))
190 fprintf (stderr
, "Illegally registering a virtual SSA name :");
191 print_generic_expr (stderr
, ssa_var
, TDF_SLIM
);
192 fprintf (stderr
, " in the SSA->Normal phase.\n");
197 version
= SSA_NAME_VERSION (ssa_var
);
198 if (is_use
&& map
->ref_count
)
199 map
->ref_count
[version
]++;
201 if (map
->partition_to_var
[version
] == NULL_TREE
)
202 map
->partition_to_var
[SSA_NAME_VERSION (ssa_var
)] = ssa_var
;
206 /* ---------------- live on entry/exit info ------------------------------
208 This structure is used to represent live range information on SSA based
209 trees. A partition map must be provided, and based on the active partitions,
210 live-on-entry information and live-on-exit information can be calculated.
211 As well, partitions are marked as to whether they are global (live
212 outside the basic block they are defined in).
214 The live-on-entry information is per variable. It provide a bitmap for
215 each variable which has a bit set for each basic block that the variable
216 is live on entry to that block.
218 The live-on-exit information is per block. It provides a bitmap for each
219 block indicating which partitions are live on exit from the block.
221 For the purposes of this implementation, we treat the elements of a PHI
224 Uses in a PHI are considered LIVE-ON-EXIT to the block from which they
225 originate. They are *NOT* considered live on entry to the block
226 containing the PHI node.
228 The Def of a PHI node is *not* considered live on entry to the block.
229 It is considered to be "define early" in the block. Picture it as each
230 block having a stmt (or block-preheader) before the first real stmt in
231 the block which defines all the variables that are defined by PHIs.
233 ----------------------------------------------------------------------- */
236 typedef struct tree_live_info_d
238 /* Var map this relates to. */
241 /* Bitmap indicating which partitions are global. */
244 /* Bitmap of live on entry blocks for partition elements. */
247 /* Number of basic blocks when live on exit calculated. */
250 /* Bitmap of what variables are live on exit for a basic blocks. */
255 extern tree_live_info_p
calculate_live_on_entry (var_map
);
256 extern void calculate_live_on_exit (tree_live_info_p
);
257 extern void delete_tree_live_info (tree_live_info_p
);
259 #define LIVEDUMP_ENTRY 0x01
260 #define LIVEDUMP_EXIT 0x02
261 #define LIVEDUMP_ALL (LIVEDUMP_ENTRY | LIVEDUMP_EXIT)
262 extern void dump_live_info (FILE *, tree_live_info_p
, int);
264 static inline int partition_is_global (tree_live_info_p
, int);
265 static inline bitmap
live_entry_blocks (tree_live_info_p
, int);
266 static inline bitmap
live_on_exit (tree_live_info_p
, basic_block
);
267 static inline var_map
live_var_map (tree_live_info_p
);
268 static inline void live_merge_and_clear (tree_live_info_p
, int, int);
269 static inline void make_live_on_entry (tree_live_info_p
, basic_block
, int);
272 /* Return TRUE if P is marked as a global in LIVE. */
275 partition_is_global (tree_live_info_p live
, int p
)
280 return bitmap_bit_p (live
->global
, p
);
284 /* Return the bitmap from LIVE representing the live on entry blocks for
288 live_entry_blocks (tree_live_info_p live
, int p
)
293 return live
->livein
[p
];
297 /* Return the bitmap from LIVE representing the live on exit partitions from
301 live_on_exit (tree_live_info_p live
, basic_block bb
)
306 if (bb
== ENTRY_BLOCK_PTR
|| bb
== EXIT_BLOCK_PTR
)
309 return live
->liveout
[bb
->index
];
313 /* Return the partition map which the information in LIVE utilizes. */
315 static inline var_map
316 live_var_map (tree_live_info_p live
)
322 /* Merge the live on entry information in LIVE for partitions P1 and P2. Place
323 the result into P1. Clear P2. */
326 live_merge_and_clear (tree_live_info_p live
, int p1
, int p2
)
328 bitmap_a_or_b (live
->livein
[p1
], live
->livein
[p1
], live
->livein
[p2
]);
329 bitmap_zero (live
->livein
[p2
]);
333 /* Mark partition P as live on entry to basic block BB in LIVE. */
336 make_live_on_entry (tree_live_info_p live
, basic_block bb
, int p
)
338 bitmap_set_bit (live
->livein
[p
], bb
->index
);
339 bitmap_set_bit (live
->global
, p
);
343 /* A tree_partition_associator (TPA)object is a base structure which allows
344 partitions to be associated with a tree object.
346 A varray of tree elements represent each distinct tree item.
347 A parallel int array represents the first partition number associated with
349 This partition number is then used as in index into the next_partition
350 array, which returns the index of the next partition which is associated
351 with the tree. TPA_NONE indicates the end of the list.
352 A varray paralleling the partition list 'partition_to_tree_map' is used
353 to indicate which tree index the partition is in. */
355 typedef struct tree_partition_associator_d
358 varray_type first_partition
;
360 int *partition_to_tree_map
;
362 int uncompressed_num
;
366 /* Value returned when there are no more partitions associated with a tree. */
369 static inline tree
tpa_tree (tpa_p
, int);
370 static inline int tpa_first_partition (tpa_p
, int);
371 static inline int tpa_next_partition (tpa_p
, int);
372 static inline int tpa_num_trees (tpa_p
);
373 static inline int tpa_find_tree (tpa_p
, int);
374 static inline void tpa_decompact (tpa_p
);
375 extern tpa_p
tpa_init (var_map
);
376 extern void tpa_delete (tpa_p
);
377 extern void tpa_dump (FILE *, tpa_p
);
378 extern void tpa_remove_partition (tpa_p
, int, int);
379 extern int tpa_compact (tpa_p
);
382 /* Return the number of distinct tree nodes in TPA. */
385 tpa_num_trees (tpa_p tpa
)
387 return tpa
->num_trees
;
391 /* Return the tree node for index I in TPA. */
394 tpa_tree (tpa_p tpa
, int i
)
396 return VARRAY_TREE (tpa
->trees
, i
);
400 /* Return the first partition associated with tree list I in TPA. */
403 tpa_first_partition (tpa_p tpa
, int i
)
405 return VARRAY_INT (tpa
->first_partition
, i
);
409 /* Return the next partition after partition I in TPA's list. */
412 tpa_next_partition (tpa_p tpa
, int i
)
414 return tpa
->next_partition
[i
];
418 /* Return the tree index from TPA whose list contains partition I.
419 TPA_NONE is returned if I is not associated with any list. */
422 tpa_find_tree (tpa_p tpa
, int i
)
426 index
= tpa
->partition_to_tree_map
[i
];
427 /* When compressed, any index higher than the number of tree elements is
428 a compressed element, so return TPA_NONE. */
429 if (index
!= TPA_NONE
&& index
>= tpa_num_trees (tpa
))
431 #ifdef ENABLE_CHECKING
432 if (tpa
->uncompressed_num
== -1)
442 /* This function removes any compaction which was performed on TPA. */
445 tpa_decompact(tpa_p tpa
)
447 #ifdef ENABLE_CHECKING
448 if (tpa
->uncompressed_num
== -1)
451 tpa
->num_trees
= tpa
->uncompressed_num
;
455 /* Once a var_map has been created and compressed, a complimentary root_var
456 object can be built. This creates a list of all the root variables from
457 which ssa version names are derived. Each root variable has a list of
458 which partitions are versions of that root.
460 This is implemented using the tree_partition_associator.
462 The tree vector is used to represent the root variable.
463 The list of partitions represent SSA versions of the root variable. */
465 typedef tpa_p root_var_p
;
467 static inline tree
root_var (root_var_p
, int);
468 static inline int root_var_first_partition (root_var_p
, int);
469 static inline int root_var_next_partition (root_var_p
, int);
470 static inline int root_var_num (root_var_p
);
471 static inline void root_var_dump (FILE *, root_var_p
);
472 static inline void root_var_remove_partition (root_var_p
, int, int);
473 static inline void root_var_delete (root_var_p
);
474 static inline int root_var_find (root_var_p
, int);
475 static inline int root_var_compact (root_var_p
);
476 static inline void root_var_decompact (tpa_p
);
478 extern root_var_p
root_var_init (var_map
);
480 /* Value returned when there are no more partitions associated with a root
482 #define ROOT_VAR_NONE TPA_NONE
485 /* Return the number of distinct root variables in RV. */
488 root_var_num (root_var_p rv
)
490 return tpa_num_trees (rv
);
494 /* Return root variable I from RV. */
497 root_var (root_var_p rv
, int i
)
499 return tpa_tree (rv
, i
);
503 /* Return the first partition in RV belonging to root variable list I. */
506 root_var_first_partition (root_var_p rv
, int i
)
508 return tpa_first_partition (rv
, i
);
512 /* Return the next partition after partition I in a root list from RV. */
515 root_var_next_partition (root_var_p rv
, int i
)
517 return tpa_next_partition (rv
, i
);
521 /* Send debug info for root_var list RV to file F. */
524 root_var_dump (FILE *f
, root_var_p rv
)
526 fprintf (f
, "\nRoot Var dump\n");
532 /* Destroy root_var object RV. */
535 root_var_delete (root_var_p rv
)
541 /* Remove partition PARTITION_INDEX from root_var list ROOT_INDEX in RV. */
544 root_var_remove_partition (root_var_p rv
, int root_index
, int partition_index
)
546 tpa_remove_partition (rv
, root_index
, partition_index
);
550 /* Return the root_var list index for partition I in RV. */
553 root_var_find (root_var_p rv
, int i
)
555 return tpa_find_tree (rv
, i
);
559 /* Hide single element lists in RV. */
562 root_var_compact (root_var_p rv
)
564 return tpa_compact (rv
);
568 /* Expose the single element lists in RV. */
571 root_var_decompact (root_var_p rv
)
577 /* A TYPE_VAR object is similar to a root_var object, except this associates
578 partitions with their type rather than their root variable. This is used to
579 coalesce memory locations based on type. */
581 typedef tpa_p type_var_p
;
583 static inline tree
type_var (type_var_p
, int);
584 static inline int type_var_first_partition (type_var_p
, int);
585 static inline int type_var_next_partition (type_var_p
, int);
586 static inline int type_var_num (type_var_p
);
587 static inline void type_var_dump (FILE *, type_var_p
);
588 static inline void type_var_remove_partition (type_var_p
, int, int);
589 static inline void type_var_delete (type_var_p
);
590 static inline int type_var_find (type_var_p
, int);
591 static inline int type_var_compact (type_var_p
);
592 static inline void type_var_decompact (type_var_p
);
594 extern type_var_p
type_var_init (var_map
);
596 /* Value returned when there is no partitions associated with a list. */
597 #define TYPE_VAR_NONE TPA_NONE
600 /* Return the number of distinct type lists in TV. */
603 type_var_num (type_var_p tv
)
605 return tpa_num_trees (tv
);
609 /* Return the type of list I in TV. */
612 type_var (type_var_p tv
, int i
)
614 return tpa_tree (tv
, i
);
618 /* Return the first partition belonging to type list I in TV. */
621 type_var_first_partition (type_var_p tv
, int i
)
623 return tpa_first_partition (tv
, i
);
627 /* Return the next partition after partition I in a type list within TV. */
630 type_var_next_partition (type_var_p tv
, int i
)
632 return tpa_next_partition (tv
, i
);
636 /* Send debug info for type_var object TV to file F. */
639 type_var_dump (FILE *f
, type_var_p tv
)
641 fprintf (f
, "\nType Var dump\n");
647 /* Delete type_var object TV. */
650 type_var_delete (type_var_p tv
)
656 /* Remove partition PARTITION_INDEX from type list TYPE_INDEX in TV. */
659 type_var_remove_partition (type_var_p tv
, int type_index
, int partition_index
)
661 tpa_remove_partition (tv
, type_index
, partition_index
);
665 /* Return the type index in TV for the list partition I is in. */
668 type_var_find (type_var_p tv
, int i
)
670 return tpa_find_tree (tv
, i
);
674 /* Hide single element lists in TV. */
677 type_var_compact (type_var_p tv
)
679 return tpa_compact (tv
);
683 /* Expose single element lists in TV. */
686 type_var_decompact (type_var_p tv
)
691 /* This set of routines implements a coalesce_list. This is an object which
692 is used to track pairs of partitions which are desirable to coalesce
693 together at some point. Costs are associated with each pair, and when
694 all desired information has been collected, the object can be used to
695 order the pairs for processing. */
697 /* This structure defines a pair for coalescing. */
699 typedef struct partition_pair_d
702 int second_partition
;
704 struct partition_pair_d
*next
;
707 /* This structure maintains the list of coalesce pairs.
708 When add_mode is true, list is a triangular shaped list of coalesce pairs.
709 The smaller partition number is used to index the list, and the larger is
710 index is located in a partition_pair_p object. These lists are sorted from
711 smallest to largest by 'second_partition'. New coalesce pairs are allowed
712 to be added in this mode.
713 When add_mode is false, the lists have all been merged into list[0]. The
714 rest of the lists are not used. list[0] is ordered from most desirable
715 coalesce to least desirable. pop_best_coalesce() retrieves the pairs
718 typedef struct coalesce_list_d
721 partition_pair_p
*list
;
725 extern coalesce_list_p
create_coalesce_list (var_map
);
726 extern void add_coalesce (coalesce_list_p
, int, int, int);
727 extern void sort_coalesce_list (coalesce_list_p
);
728 extern void dump_coalesce_list (FILE *, coalesce_list_p
);
729 extern void delete_coalesce_list (coalesce_list_p
);
731 #define NO_BEST_COALESCE -1
732 extern int pop_best_coalesce (coalesce_list_p
, int *, int *);
734 extern conflict_graph
build_tree_conflict_graph (tree_live_info_p
, tpa_p
,
736 extern void coalesce_tpa_members (tpa_p tpa
, conflict_graph graph
, var_map map
,
737 coalesce_list_p cl
, FILE *);
740 #endif /* _TREE_SSA_LIVE_H */