138fd1498Szrj /* Coalesce SSA_NAMES together for the out-of-ssa pass.
238fd1498Szrj Copyright (C) 2004-2018 Free Software Foundation, Inc.
338fd1498Szrj Contributed by Andrew MacLeod <amacleod@redhat.com>
438fd1498Szrj
538fd1498Szrj This file is part of GCC.
638fd1498Szrj
738fd1498Szrj GCC is free software; you can redistribute it and/or modify
838fd1498Szrj it under the terms of the GNU General Public License as published by
938fd1498Szrj the Free Software Foundation; either version 3, or (at your option)
1038fd1498Szrj any later version.
1138fd1498Szrj
1238fd1498Szrj GCC is distributed in the hope that it will be useful,
1338fd1498Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
1438fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1538fd1498Szrj GNU General Public License for more details.
1638fd1498Szrj
1738fd1498Szrj You should have received a copy of the GNU General Public License
1838fd1498Szrj along with GCC; see the file COPYING3. If not see
1938fd1498Szrj <http://www.gnu.org/licenses/>. */
2038fd1498Szrj
2138fd1498Szrj #include "config.h"
2238fd1498Szrj #include "system.h"
2338fd1498Szrj #include "coretypes.h"
2438fd1498Szrj #include "backend.h"
2538fd1498Szrj #include "tree.h"
2638fd1498Szrj #include "gimple.h"
2738fd1498Szrj #include "predict.h"
2838fd1498Szrj #include "memmodel.h"
2938fd1498Szrj #include "tm_p.h"
3038fd1498Szrj #include "ssa.h"
3138fd1498Szrj #include "tree-ssa.h"
3238fd1498Szrj #include "tree-pretty-print.h"
3338fd1498Szrj #include "diagnostic-core.h"
3438fd1498Szrj #include "dumpfile.h"
3538fd1498Szrj #include "gimple-iterator.h"
3638fd1498Szrj #include "tree-ssa-live.h"
3738fd1498Szrj #include "tree-ssa-coalesce.h"
3838fd1498Szrj #include "explow.h"
3938fd1498Szrj #include "tree-dfa.h"
4038fd1498Szrj #include "stor-layout.h"
4138fd1498Szrj
4238fd1498Szrj /* This set of routines implements a coalesce_list. This is an object which
4338fd1498Szrj is used to track pairs of ssa_names which are desirable to coalesce
4438fd1498Szrj together to avoid copies. Costs are associated with each pair, and when
4538fd1498Szrj all desired information has been collected, the object can be used to
4638fd1498Szrj order the pairs for processing. */
4738fd1498Szrj
4838fd1498Szrj /* This structure defines a pair entry. */
4938fd1498Szrj
5038fd1498Szrj struct coalesce_pair
5138fd1498Szrj {
5238fd1498Szrj int first_element;
5338fd1498Szrj int second_element;
5438fd1498Szrj int cost;
5538fd1498Szrj
5638fd1498Szrj /* A count of the number of unique partitions this pair would conflict
5738fd1498Szrj with if coalescing was successful. This is the secondary sort key,
5838fd1498Szrj given two pairs with equal costs, we will prefer the pair with a smaller
5938fd1498Szrj conflict set.
6038fd1498Szrj
6138fd1498Szrj This is lazily initialized when we discover two coalescing pairs have
6238fd1498Szrj the same primary cost.
6338fd1498Szrj
6438fd1498Szrj Note this is not updated and propagated as pairs are coalesced. */
6538fd1498Szrj int conflict_count;
6638fd1498Szrj
6738fd1498Szrj /* The order in which coalescing pairs are discovered is recorded in this
6838fd1498Szrj field, which is used as the final tie breaker when sorting coalesce
6938fd1498Szrj pairs. */
7038fd1498Szrj int index;
7138fd1498Szrj };
7238fd1498Szrj
7338fd1498Szrj /* This represents a conflict graph. Implemented as an array of bitmaps.
7438fd1498Szrj A full matrix is used for conflicts rather than just upper triangular form.
7538fd1498Szrj this makes it much simpler and faster to perform conflict merges. */
7638fd1498Szrj
7738fd1498Szrj struct ssa_conflicts
7838fd1498Szrj {
7938fd1498Szrj bitmap_obstack obstack; /* A place to allocate our bitmaps. */
8038fd1498Szrj vec<bitmap> conflicts;
8138fd1498Szrj };
8238fd1498Szrj
8338fd1498Szrj /* The narrow API of the qsort comparison function doesn't allow easy
8438fd1498Szrj access to additional arguments. So we have two globals (ick) to hold
8538fd1498Szrj the data we need. They're initialized before the call to qsort and
8638fd1498Szrj wiped immediately after. */
8738fd1498Szrj static ssa_conflicts *conflicts_;
8838fd1498Szrj static var_map map_;
8938fd1498Szrj
9038fd1498Szrj /* Coalesce pair hashtable helpers. */
9138fd1498Szrj
9238fd1498Szrj struct coalesce_pair_hasher : nofree_ptr_hash <coalesce_pair>
9338fd1498Szrj {
9438fd1498Szrj static inline hashval_t hash (const coalesce_pair *);
9538fd1498Szrj static inline bool equal (const coalesce_pair *, const coalesce_pair *);
9638fd1498Szrj };
9738fd1498Szrj
9838fd1498Szrj /* Hash function for coalesce list. Calculate hash for PAIR. */
9938fd1498Szrj
10038fd1498Szrj inline hashval_t
hash(const coalesce_pair * pair)10138fd1498Szrj coalesce_pair_hasher::hash (const coalesce_pair *pair)
10238fd1498Szrj {
10338fd1498Szrj hashval_t a = (hashval_t)(pair->first_element);
10438fd1498Szrj hashval_t b = (hashval_t)(pair->second_element);
10538fd1498Szrj
10638fd1498Szrj return b * (b - 1) / 2 + a;
10738fd1498Szrj }
10838fd1498Szrj
10938fd1498Szrj /* Equality function for coalesce list hash table. Compare PAIR1 and PAIR2,
11038fd1498Szrj returning TRUE if the two pairs are equivalent. */
11138fd1498Szrj
11238fd1498Szrj inline bool
equal(const coalesce_pair * p1,const coalesce_pair * p2)11338fd1498Szrj coalesce_pair_hasher::equal (const coalesce_pair *p1, const coalesce_pair *p2)
11438fd1498Szrj {
11538fd1498Szrj return (p1->first_element == p2->first_element
11638fd1498Szrj && p1->second_element == p2->second_element);
11738fd1498Szrj }
11838fd1498Szrj
11938fd1498Szrj typedef hash_table<coalesce_pair_hasher> coalesce_table_type;
12038fd1498Szrj typedef coalesce_table_type::iterator coalesce_iterator_type;
12138fd1498Szrj
12238fd1498Szrj
12338fd1498Szrj struct cost_one_pair
12438fd1498Szrj {
12538fd1498Szrj int first_element;
12638fd1498Szrj int second_element;
12738fd1498Szrj cost_one_pair *next;
12838fd1498Szrj };
12938fd1498Szrj
13038fd1498Szrj /* This structure maintains the list of coalesce pairs. */
13138fd1498Szrj
13238fd1498Szrj struct coalesce_list
13338fd1498Szrj {
13438fd1498Szrj coalesce_table_type *list; /* Hash table. */
13538fd1498Szrj coalesce_pair **sorted; /* List when sorted. */
13638fd1498Szrj int num_sorted; /* Number in the sorted list. */
13738fd1498Szrj cost_one_pair *cost_one_list;/* Single use coalesces with cost 1. */
13838fd1498Szrj };
13938fd1498Szrj
14038fd1498Szrj #define NO_BEST_COALESCE -1
14138fd1498Szrj #define MUST_COALESCE_COST INT_MAX
14238fd1498Szrj
14338fd1498Szrj
14438fd1498Szrj /* Return cost of execution of copy instruction with FREQUENCY. */
14538fd1498Szrj
14638fd1498Szrj static inline int
coalesce_cost(int frequency,bool optimize_for_size)14738fd1498Szrj coalesce_cost (int frequency, bool optimize_for_size)
14838fd1498Szrj {
14938fd1498Szrj /* Base costs on BB frequencies bounded by 1. */
15038fd1498Szrj int cost = frequency;
15138fd1498Szrj
15238fd1498Szrj if (!cost)
15338fd1498Szrj cost = 1;
15438fd1498Szrj
15538fd1498Szrj if (optimize_for_size)
15638fd1498Szrj cost = 1;
15738fd1498Szrj
15838fd1498Szrj return cost;
15938fd1498Szrj }
16038fd1498Szrj
16138fd1498Szrj
16238fd1498Szrj /* Return the cost of executing a copy instruction in basic block BB. */
16338fd1498Szrj
16438fd1498Szrj static inline int
coalesce_cost_bb(basic_block bb)16538fd1498Szrj coalesce_cost_bb (basic_block bb)
16638fd1498Szrj {
16738fd1498Szrj return coalesce_cost (bb->count.to_frequency (cfun),
16838fd1498Szrj optimize_bb_for_size_p (bb));
16938fd1498Szrj }
17038fd1498Szrj
17138fd1498Szrj
17238fd1498Szrj /* Return the cost of executing a copy instruction on edge E. */
17338fd1498Szrj
17438fd1498Szrj static inline int
coalesce_cost_edge(edge e)17538fd1498Szrj coalesce_cost_edge (edge e)
17638fd1498Szrj {
17738fd1498Szrj int mult = 1;
17838fd1498Szrj
17938fd1498Szrj /* Inserting copy on critical edge costs more than inserting it elsewhere. */
18038fd1498Szrj if (EDGE_CRITICAL_P (e))
18138fd1498Szrj mult = 2;
18238fd1498Szrj if (e->flags & EDGE_ABNORMAL)
18338fd1498Szrj return MUST_COALESCE_COST;
18438fd1498Szrj if (e->flags & EDGE_EH)
18538fd1498Szrj {
18638fd1498Szrj edge e2;
18738fd1498Szrj edge_iterator ei;
18838fd1498Szrj FOR_EACH_EDGE (e2, ei, e->dest->preds)
18938fd1498Szrj if (e2 != e)
19038fd1498Szrj {
19138fd1498Szrj /* Putting code on EH edge that leads to BB
19238fd1498Szrj with multiple predecestors imply splitting of
19338fd1498Szrj edge too. */
19438fd1498Szrj if (mult < 2)
19538fd1498Szrj mult = 2;
19638fd1498Szrj /* If there are multiple EH predecestors, we
19738fd1498Szrj also copy EH regions and produce separate
19838fd1498Szrj landing pad. This is expensive. */
19938fd1498Szrj if (e2->flags & EDGE_EH)
20038fd1498Szrj {
20138fd1498Szrj mult = 5;
20238fd1498Szrj break;
20338fd1498Szrj }
20438fd1498Szrj }
20538fd1498Szrj }
20638fd1498Szrj
20738fd1498Szrj return coalesce_cost (EDGE_FREQUENCY (e),
20838fd1498Szrj optimize_edge_for_size_p (e)) * mult;
20938fd1498Szrj }
21038fd1498Szrj
21138fd1498Szrj
21238fd1498Szrj /* Retrieve a pair to coalesce from the cost_one_list in CL. Returns the
21338fd1498Szrj 2 elements via P1 and P2. 1 is returned by the function if there is a pair,
21438fd1498Szrj NO_BEST_COALESCE is returned if there aren't any. */
21538fd1498Szrj
21638fd1498Szrj static inline int
pop_cost_one_pair(coalesce_list * cl,int * p1,int * p2)21738fd1498Szrj pop_cost_one_pair (coalesce_list *cl, int *p1, int *p2)
21838fd1498Szrj {
21938fd1498Szrj cost_one_pair *ptr;
22038fd1498Szrj
22138fd1498Szrj ptr = cl->cost_one_list;
22238fd1498Szrj if (!ptr)
22338fd1498Szrj return NO_BEST_COALESCE;
22438fd1498Szrj
22538fd1498Szrj *p1 = ptr->first_element;
22638fd1498Szrj *p2 = ptr->second_element;
22738fd1498Szrj cl->cost_one_list = ptr->next;
22838fd1498Szrj
22938fd1498Szrj free (ptr);
23038fd1498Szrj
23138fd1498Szrj return 1;
23238fd1498Szrj }
23338fd1498Szrj
23438fd1498Szrj /* Retrieve the most expensive remaining pair to coalesce from CL. Returns the
23538fd1498Szrj 2 elements via P1 and P2. Their calculated cost is returned by the function.
23638fd1498Szrj NO_BEST_COALESCE is returned if the coalesce list is empty. */
23738fd1498Szrj
23838fd1498Szrj static inline int
pop_best_coalesce(coalesce_list * cl,int * p1,int * p2)23938fd1498Szrj pop_best_coalesce (coalesce_list *cl, int *p1, int *p2)
24038fd1498Szrj {
24138fd1498Szrj coalesce_pair *node;
24238fd1498Szrj int ret;
24338fd1498Szrj
24438fd1498Szrj if (cl->sorted == NULL)
24538fd1498Szrj return pop_cost_one_pair (cl, p1, p2);
24638fd1498Szrj
24738fd1498Szrj if (cl->num_sorted == 0)
24838fd1498Szrj return pop_cost_one_pair (cl, p1, p2);
24938fd1498Szrj
25038fd1498Szrj node = cl->sorted[--(cl->num_sorted)];
25138fd1498Szrj *p1 = node->first_element;
25238fd1498Szrj *p2 = node->second_element;
25338fd1498Szrj ret = node->cost;
25438fd1498Szrj free (node);
25538fd1498Szrj
25638fd1498Szrj return ret;
25738fd1498Szrj }
25838fd1498Szrj
25938fd1498Szrj
26038fd1498Szrj /* Create a new empty coalesce list object and return it. */
26138fd1498Szrj
26238fd1498Szrj static inline coalesce_list *
create_coalesce_list(void)26338fd1498Szrj create_coalesce_list (void)
26438fd1498Szrj {
26538fd1498Szrj coalesce_list *list;
26638fd1498Szrj unsigned size = num_ssa_names * 3;
26738fd1498Szrj
26838fd1498Szrj if (size < 40)
26938fd1498Szrj size = 40;
27038fd1498Szrj
27138fd1498Szrj list = (coalesce_list *) xmalloc (sizeof (struct coalesce_list));
27238fd1498Szrj list->list = new coalesce_table_type (size);
27338fd1498Szrj list->sorted = NULL;
27438fd1498Szrj list->num_sorted = 0;
27538fd1498Szrj list->cost_one_list = NULL;
27638fd1498Szrj return list;
27738fd1498Szrj }
27838fd1498Szrj
27938fd1498Szrj
28038fd1498Szrj /* Delete coalesce list CL. */
28138fd1498Szrj
28238fd1498Szrj static inline void
delete_coalesce_list(coalesce_list * cl)28338fd1498Szrj delete_coalesce_list (coalesce_list *cl)
28438fd1498Szrj {
28538fd1498Szrj gcc_assert (cl->cost_one_list == NULL);
28638fd1498Szrj delete cl->list;
28738fd1498Szrj cl->list = NULL;
28838fd1498Szrj free (cl->sorted);
28938fd1498Szrj gcc_assert (cl->num_sorted == 0);
29038fd1498Szrj free (cl);
29138fd1498Szrj }
29238fd1498Szrj
29338fd1498Szrj /* Return the number of unique coalesce pairs in CL. */
29438fd1498Szrj
29538fd1498Szrj static inline int
num_coalesce_pairs(coalesce_list * cl)29638fd1498Szrj num_coalesce_pairs (coalesce_list *cl)
29738fd1498Szrj {
29838fd1498Szrj return cl->list->elements ();
29938fd1498Szrj }
30038fd1498Szrj
30138fd1498Szrj /* Find a matching coalesce pair object in CL for the pair P1 and P2. If
30238fd1498Szrj one isn't found, return NULL if CREATE is false, otherwise create a new
30338fd1498Szrj coalesce pair object and return it. */
30438fd1498Szrj
30538fd1498Szrj static coalesce_pair *
find_coalesce_pair(coalesce_list * cl,int p1,int p2,bool create)30638fd1498Szrj find_coalesce_pair (coalesce_list *cl, int p1, int p2, bool create)
30738fd1498Szrj {
30838fd1498Szrj struct coalesce_pair p;
30938fd1498Szrj coalesce_pair **slot;
31038fd1498Szrj unsigned int hash;
31138fd1498Szrj
31238fd1498Szrj /* Normalize so that p1 is the smaller value. */
31338fd1498Szrj if (p2 < p1)
31438fd1498Szrj {
31538fd1498Szrj p.first_element = p2;
31638fd1498Szrj p.second_element = p1;
31738fd1498Szrj }
31838fd1498Szrj else
31938fd1498Szrj {
32038fd1498Szrj p.first_element = p1;
32138fd1498Szrj p.second_element = p2;
32238fd1498Szrj }
32338fd1498Szrj
32438fd1498Szrj hash = coalesce_pair_hasher::hash (&p);
32538fd1498Szrj slot = cl->list->find_slot_with_hash (&p, hash, create ? INSERT : NO_INSERT);
32638fd1498Szrj if (!slot)
32738fd1498Szrj return NULL;
32838fd1498Szrj
32938fd1498Szrj if (!*slot)
33038fd1498Szrj {
33138fd1498Szrj struct coalesce_pair * pair = XNEW (struct coalesce_pair);
33238fd1498Szrj gcc_assert (cl->sorted == NULL);
33338fd1498Szrj pair->first_element = p.first_element;
33438fd1498Szrj pair->second_element = p.second_element;
33538fd1498Szrj pair->cost = 0;
33638fd1498Szrj pair->index = num_coalesce_pairs (cl);
33738fd1498Szrj pair->conflict_count = 0;
33838fd1498Szrj *slot = pair;
33938fd1498Szrj }
34038fd1498Szrj
34138fd1498Szrj return (struct coalesce_pair *) *slot;
34238fd1498Szrj }
34338fd1498Szrj
34438fd1498Szrj static inline void
add_cost_one_coalesce(coalesce_list * cl,int p1,int p2)34538fd1498Szrj add_cost_one_coalesce (coalesce_list *cl, int p1, int p2)
34638fd1498Szrj {
34738fd1498Szrj cost_one_pair *pair;
34838fd1498Szrj
34938fd1498Szrj pair = XNEW (cost_one_pair);
35038fd1498Szrj pair->first_element = p1;
35138fd1498Szrj pair->second_element = p2;
35238fd1498Szrj pair->next = cl->cost_one_list;
35338fd1498Szrj cl->cost_one_list = pair;
35438fd1498Szrj }
35538fd1498Szrj
35638fd1498Szrj
35738fd1498Szrj /* Add a coalesce between P1 and P2 in list CL with a cost of VALUE. */
35838fd1498Szrj
35938fd1498Szrj static inline void
add_coalesce(coalesce_list * cl,int p1,int p2,int value)36038fd1498Szrj add_coalesce (coalesce_list *cl, int p1, int p2, int value)
36138fd1498Szrj {
36238fd1498Szrj coalesce_pair *node;
36338fd1498Szrj
36438fd1498Szrj gcc_assert (cl->sorted == NULL);
36538fd1498Szrj if (p1 == p2)
36638fd1498Szrj return;
36738fd1498Szrj
36838fd1498Szrj node = find_coalesce_pair (cl, p1, p2, true);
36938fd1498Szrj
37038fd1498Szrj /* Once the value is at least MUST_COALESCE_COST - 1, leave it that way. */
37138fd1498Szrj if (node->cost < MUST_COALESCE_COST - 1)
37238fd1498Szrj {
37338fd1498Szrj if (value < MUST_COALESCE_COST - 1)
37438fd1498Szrj node->cost += value;
37538fd1498Szrj else
37638fd1498Szrj node->cost = value;
37738fd1498Szrj }
37838fd1498Szrj }
37938fd1498Szrj
38038fd1498Szrj /* Compute and record how many unique conflicts would exist for the
38138fd1498Szrj representative partition for each coalesce pair in CL.
38238fd1498Szrj
38338fd1498Szrj CONFLICTS is the conflict graph and MAP is the current partition view. */
38438fd1498Szrj
38538fd1498Szrj static void
initialize_conflict_count(coalesce_pair * p,ssa_conflicts * conflicts,var_map map)38638fd1498Szrj initialize_conflict_count (coalesce_pair *p,
38738fd1498Szrj ssa_conflicts *conflicts,
38838fd1498Szrj var_map map)
38938fd1498Szrj {
39038fd1498Szrj int p1 = var_to_partition (map, ssa_name (p->first_element));
39138fd1498Szrj int p2 = var_to_partition (map, ssa_name (p->second_element));
39238fd1498Szrj
39338fd1498Szrj /* 4 cases. If both P1 and P2 have conflicts, then build their
39438fd1498Szrj union and count the members. Else handle the degenerate cases
39538fd1498Szrj in the obvious ways. */
39638fd1498Szrj if (conflicts->conflicts[p1] && conflicts->conflicts[p2])
39738fd1498Szrj p->conflict_count = bitmap_count_unique_bits (conflicts->conflicts[p1],
39838fd1498Szrj conflicts->conflicts[p2]);
39938fd1498Szrj else if (conflicts->conflicts[p1])
40038fd1498Szrj p->conflict_count = bitmap_count_bits (conflicts->conflicts[p1]);
40138fd1498Szrj else if (conflicts->conflicts[p2])
40238fd1498Szrj p->conflict_count = bitmap_count_bits (conflicts->conflicts[p2]);
40338fd1498Szrj else
40438fd1498Szrj p->conflict_count = 0;
40538fd1498Szrj }
40638fd1498Szrj
40738fd1498Szrj
40838fd1498Szrj /* Comparison function to allow qsort to sort P1 and P2 in Ascending order. */
40938fd1498Szrj
41038fd1498Szrj static int
compare_pairs(const void * p1,const void * p2)41138fd1498Szrj compare_pairs (const void *p1, const void *p2)
41238fd1498Szrj {
41338fd1498Szrj coalesce_pair *const *const pp1 = (coalesce_pair *const *) p1;
41438fd1498Szrj coalesce_pair *const *const pp2 = (coalesce_pair *const *) p2;
41538fd1498Szrj int result;
41638fd1498Szrj
41738fd1498Szrj result = (* pp1)->cost - (* pp2)->cost;
41838fd1498Szrj /* We use the size of the resulting conflict set as the secondary sort key.
41938fd1498Szrj Given two equal costing coalesce pairs, we want to prefer the pair that
42038fd1498Szrj has the smaller conflict set. */
42138fd1498Szrj if (result == 0)
42238fd1498Szrj {
42338fd1498Szrj if (flag_expensive_optimizations)
42438fd1498Szrj {
42538fd1498Szrj /* Lazily initialize the conflict counts as it's fairly expensive
42638fd1498Szrj to compute. */
42738fd1498Szrj if ((*pp2)->conflict_count == 0)
42838fd1498Szrj initialize_conflict_count (*pp2, conflicts_, map_);
42938fd1498Szrj if ((*pp1)->conflict_count == 0)
43038fd1498Szrj initialize_conflict_count (*pp1, conflicts_, map_);
43138fd1498Szrj
43238fd1498Szrj result = (*pp2)->conflict_count - (*pp1)->conflict_count;
43338fd1498Szrj }
43438fd1498Szrj
43538fd1498Szrj /* And if everything else is equal, then sort based on which
43638fd1498Szrj coalesce pair was found first. */
43738fd1498Szrj if (result == 0)
43838fd1498Szrj result = (*pp2)->index - (*pp1)->index;
43938fd1498Szrj }
44038fd1498Szrj
44138fd1498Szrj return result;
44238fd1498Szrj }
44338fd1498Szrj
44438fd1498Szrj /* Iterate over CL using ITER, returning values in PAIR. */
44538fd1498Szrj
44638fd1498Szrj #define FOR_EACH_PARTITION_PAIR(PAIR, ITER, CL) \
44738fd1498Szrj FOR_EACH_HASH_TABLE_ELEMENT (*(CL)->list, (PAIR), coalesce_pair_p, (ITER))
44838fd1498Szrj
44938fd1498Szrj
45038fd1498Szrj /* Prepare CL for removal of preferred pairs. When finished they are sorted
45138fd1498Szrj in order from most important coalesce to least important. */
45238fd1498Szrj
45338fd1498Szrj static void
sort_coalesce_list(coalesce_list * cl,ssa_conflicts * conflicts,var_map map)45438fd1498Szrj sort_coalesce_list (coalesce_list *cl, ssa_conflicts *conflicts, var_map map)
45538fd1498Szrj {
45638fd1498Szrj unsigned x, num;
45738fd1498Szrj coalesce_pair *p;
45838fd1498Szrj coalesce_iterator_type ppi;
45938fd1498Szrj
46038fd1498Szrj gcc_assert (cl->sorted == NULL);
46138fd1498Szrj
46238fd1498Szrj num = num_coalesce_pairs (cl);
46338fd1498Szrj cl->num_sorted = num;
46438fd1498Szrj if (num == 0)
46538fd1498Szrj return;
46638fd1498Szrj
46738fd1498Szrj /* Allocate a vector for the pair pointers. */
46838fd1498Szrj cl->sorted = XNEWVEC (coalesce_pair *, num);
46938fd1498Szrj
47038fd1498Szrj /* Populate the vector with pointers to the pairs. */
47138fd1498Szrj x = 0;
47238fd1498Szrj FOR_EACH_PARTITION_PAIR (p, ppi, cl)
47338fd1498Szrj cl->sorted[x++] = p;
47438fd1498Szrj gcc_assert (x == num);
47538fd1498Szrj
47638fd1498Szrj /* Already sorted. */
47738fd1498Szrj if (num == 1)
47838fd1498Szrj return;
47938fd1498Szrj
48038fd1498Szrj /* We don't want to depend on qsort_r, so we have to stuff away
48138fd1498Szrj additional data into globals so it can be referenced in
48238fd1498Szrj compare_pairs. */
48338fd1498Szrj conflicts_ = conflicts;
48438fd1498Szrj map_ = map;
48538fd1498Szrj qsort (cl->sorted, num, sizeof (coalesce_pair *), compare_pairs);
48638fd1498Szrj conflicts_ = NULL;
48738fd1498Szrj map_ = NULL;
48838fd1498Szrj }
48938fd1498Szrj
49038fd1498Szrj
49138fd1498Szrj /* Send debug info for coalesce list CL to file F. */
49238fd1498Szrj
49338fd1498Szrj static void
dump_coalesce_list(FILE * f,coalesce_list * cl)49438fd1498Szrj dump_coalesce_list (FILE *f, coalesce_list *cl)
49538fd1498Szrj {
49638fd1498Szrj coalesce_pair *node;
49738fd1498Szrj coalesce_iterator_type ppi;
49838fd1498Szrj
49938fd1498Szrj int x;
50038fd1498Szrj tree var;
50138fd1498Szrj
50238fd1498Szrj if (cl->sorted == NULL)
50338fd1498Szrj {
50438fd1498Szrj fprintf (f, "Coalesce List:\n");
50538fd1498Szrj FOR_EACH_PARTITION_PAIR (node, ppi, cl)
50638fd1498Szrj {
50738fd1498Szrj tree var1 = ssa_name (node->first_element);
50838fd1498Szrj tree var2 = ssa_name (node->second_element);
50938fd1498Szrj print_generic_expr (f, var1, TDF_SLIM);
51038fd1498Szrj fprintf (f, " <-> ");
51138fd1498Szrj print_generic_expr (f, var2, TDF_SLIM);
51238fd1498Szrj fprintf (f, " (%1d, %1d), ", node->cost, node->conflict_count);
51338fd1498Szrj fprintf (f, "\n");
51438fd1498Szrj }
51538fd1498Szrj }
51638fd1498Szrj else
51738fd1498Szrj {
51838fd1498Szrj fprintf (f, "Sorted Coalesce list:\n");
51938fd1498Szrj for (x = cl->num_sorted - 1 ; x >=0; x--)
52038fd1498Szrj {
52138fd1498Szrj node = cl->sorted[x];
52238fd1498Szrj fprintf (f, "(%d, %d) ", node->cost, node->conflict_count);
52338fd1498Szrj var = ssa_name (node->first_element);
52438fd1498Szrj print_generic_expr (f, var, TDF_SLIM);
52538fd1498Szrj fprintf (f, " <-> ");
52638fd1498Szrj var = ssa_name (node->second_element);
52738fd1498Szrj print_generic_expr (f, var, TDF_SLIM);
52838fd1498Szrj fprintf (f, "\n");
52938fd1498Szrj }
53038fd1498Szrj }
53138fd1498Szrj }
53238fd1498Szrj
53338fd1498Szrj
53438fd1498Szrj /* Return an empty new conflict graph for SIZE elements. */
53538fd1498Szrj
53638fd1498Szrj static inline ssa_conflicts *
ssa_conflicts_new(unsigned size)53738fd1498Szrj ssa_conflicts_new (unsigned size)
53838fd1498Szrj {
53938fd1498Szrj ssa_conflicts *ptr;
54038fd1498Szrj
54138fd1498Szrj ptr = XNEW (ssa_conflicts);
54238fd1498Szrj bitmap_obstack_initialize (&ptr->obstack);
54338fd1498Szrj ptr->conflicts.create (size);
54438fd1498Szrj ptr->conflicts.safe_grow_cleared (size);
54538fd1498Szrj return ptr;
54638fd1498Szrj }
54738fd1498Szrj
54838fd1498Szrj
54938fd1498Szrj /* Free storage for conflict graph PTR. */
55038fd1498Szrj
55138fd1498Szrj static inline void
ssa_conflicts_delete(ssa_conflicts * ptr)55238fd1498Szrj ssa_conflicts_delete (ssa_conflicts *ptr)
55338fd1498Szrj {
55438fd1498Szrj bitmap_obstack_release (&ptr->obstack);
55538fd1498Szrj ptr->conflicts.release ();
55638fd1498Szrj free (ptr);
55738fd1498Szrj }
55838fd1498Szrj
55938fd1498Szrj
56038fd1498Szrj /* Test if elements X and Y conflict in graph PTR. */
56138fd1498Szrj
56238fd1498Szrj static inline bool
ssa_conflicts_test_p(ssa_conflicts * ptr,unsigned x,unsigned y)56338fd1498Szrj ssa_conflicts_test_p (ssa_conflicts *ptr, unsigned x, unsigned y)
56438fd1498Szrj {
56538fd1498Szrj bitmap bx = ptr->conflicts[x];
56638fd1498Szrj bitmap by = ptr->conflicts[y];
56738fd1498Szrj
56838fd1498Szrj gcc_checking_assert (x != y);
56938fd1498Szrj
57038fd1498Szrj if (bx)
57138fd1498Szrj /* Avoid the lookup if Y has no conflicts. */
57238fd1498Szrj return by ? bitmap_bit_p (bx, y) : false;
57338fd1498Szrj else
57438fd1498Szrj return false;
57538fd1498Szrj }
57638fd1498Szrj
57738fd1498Szrj
57838fd1498Szrj /* Add a conflict with Y to the bitmap for X in graph PTR. */
57938fd1498Szrj
58038fd1498Szrj static inline void
ssa_conflicts_add_one(ssa_conflicts * ptr,unsigned x,unsigned y)58138fd1498Szrj ssa_conflicts_add_one (ssa_conflicts *ptr, unsigned x, unsigned y)
58238fd1498Szrj {
58338fd1498Szrj bitmap bx = ptr->conflicts[x];
58438fd1498Szrj /* If there are no conflicts yet, allocate the bitmap and set bit. */
58538fd1498Szrj if (! bx)
58638fd1498Szrj bx = ptr->conflicts[x] = BITMAP_ALLOC (&ptr->obstack);
58738fd1498Szrj bitmap_set_bit (bx, y);
58838fd1498Szrj }
58938fd1498Szrj
59038fd1498Szrj
59138fd1498Szrj /* Add conflicts between X and Y in graph PTR. */
59238fd1498Szrj
59338fd1498Szrj static inline void
ssa_conflicts_add(ssa_conflicts * ptr,unsigned x,unsigned y)59438fd1498Szrj ssa_conflicts_add (ssa_conflicts *ptr, unsigned x, unsigned y)
59538fd1498Szrj {
59638fd1498Szrj gcc_checking_assert (x != y);
59738fd1498Szrj ssa_conflicts_add_one (ptr, x, y);
59838fd1498Szrj ssa_conflicts_add_one (ptr, y, x);
59938fd1498Szrj }
60038fd1498Szrj
60138fd1498Szrj
60238fd1498Szrj /* Merge all Y's conflict into X in graph PTR. */
60338fd1498Szrj
60438fd1498Szrj static inline void
ssa_conflicts_merge(ssa_conflicts * ptr,unsigned x,unsigned y)60538fd1498Szrj ssa_conflicts_merge (ssa_conflicts *ptr, unsigned x, unsigned y)
60638fd1498Szrj {
60738fd1498Szrj unsigned z;
60838fd1498Szrj bitmap_iterator bi;
60938fd1498Szrj bitmap bx = ptr->conflicts[x];
61038fd1498Szrj bitmap by = ptr->conflicts[y];
61138fd1498Szrj
61238fd1498Szrj gcc_checking_assert (x != y);
61338fd1498Szrj if (! by)
61438fd1498Szrj return;
61538fd1498Szrj
61638fd1498Szrj /* Add a conflict between X and every one Y has. If the bitmap doesn't
61738fd1498Szrj exist, then it has already been coalesced, and we don't need to add a
61838fd1498Szrj conflict. */
61938fd1498Szrj EXECUTE_IF_SET_IN_BITMAP (by, 0, z, bi)
62038fd1498Szrj {
62138fd1498Szrj bitmap bz = ptr->conflicts[z];
62238fd1498Szrj if (bz)
62338fd1498Szrj bitmap_set_bit (bz, x);
62438fd1498Szrj }
62538fd1498Szrj
62638fd1498Szrj if (bx)
62738fd1498Szrj {
62838fd1498Szrj /* If X has conflicts, add Y's to X. */
62938fd1498Szrj bitmap_ior_into (bx, by);
63038fd1498Szrj BITMAP_FREE (by);
63138fd1498Szrj ptr->conflicts[y] = NULL;
63238fd1498Szrj }
63338fd1498Szrj else
63438fd1498Szrj {
63538fd1498Szrj /* If X has no conflicts, simply use Y's. */
63638fd1498Szrj ptr->conflicts[x] = by;
63738fd1498Szrj ptr->conflicts[y] = NULL;
63838fd1498Szrj }
63938fd1498Szrj }
64038fd1498Szrj
64138fd1498Szrj
64238fd1498Szrj /* Dump a conflicts graph. */
64338fd1498Szrj
64438fd1498Szrj static void
ssa_conflicts_dump(FILE * file,ssa_conflicts * ptr)64538fd1498Szrj ssa_conflicts_dump (FILE *file, ssa_conflicts *ptr)
64638fd1498Szrj {
64738fd1498Szrj unsigned x;
64838fd1498Szrj bitmap b;
64938fd1498Szrj
65038fd1498Szrj fprintf (file, "\nConflict graph:\n");
65138fd1498Szrj
65238fd1498Szrj FOR_EACH_VEC_ELT (ptr->conflicts, x, b)
65338fd1498Szrj if (b)
65438fd1498Szrj {
65538fd1498Szrj fprintf (file, "%d: ", x);
65638fd1498Szrj dump_bitmap (file, b);
65738fd1498Szrj }
65838fd1498Szrj }
65938fd1498Szrj
66038fd1498Szrj
66138fd1498Szrj /* This structure is used to efficiently record the current status of live
66238fd1498Szrj SSA_NAMES when building a conflict graph.
66338fd1498Szrj LIVE_BASE_VAR has a bit set for each base variable which has at least one
66438fd1498Szrj ssa version live.
66538fd1498Szrj LIVE_BASE_PARTITIONS is an array of bitmaps using the basevar table as an
66638fd1498Szrj index, and is used to track what partitions of each base variable are
66738fd1498Szrj live. This makes it easy to add conflicts between just live partitions
66838fd1498Szrj with the same base variable.
66938fd1498Szrj The values in LIVE_BASE_PARTITIONS are only valid if the base variable is
67038fd1498Szrj marked as being live. This delays clearing of these bitmaps until
67138fd1498Szrj they are actually needed again. */
67238fd1498Szrj
67338fd1498Szrj struct live_track
67438fd1498Szrj {
67538fd1498Szrj bitmap_obstack obstack; /* A place to allocate our bitmaps. */
67638fd1498Szrj bitmap live_base_var; /* Indicates if a basevar is live. */
67738fd1498Szrj bitmap *live_base_partitions; /* Live partitions for each basevar. */
67838fd1498Szrj var_map map; /* Var_map being used for partition mapping. */
67938fd1498Szrj };
68038fd1498Szrj
68138fd1498Szrj
68238fd1498Szrj /* This routine will create a new live track structure based on the partitions
68338fd1498Szrj in MAP. */
68438fd1498Szrj
68538fd1498Szrj static live_track *
new_live_track(var_map map)68638fd1498Szrj new_live_track (var_map map)
68738fd1498Szrj {
68838fd1498Szrj live_track *ptr;
68938fd1498Szrj int lim, x;
69038fd1498Szrj
69138fd1498Szrj /* Make sure there is a partition view in place. */
69238fd1498Szrj gcc_assert (map->partition_to_base_index != NULL);
69338fd1498Szrj
69438fd1498Szrj ptr = (live_track *) xmalloc (sizeof (live_track));
69538fd1498Szrj ptr->map = map;
69638fd1498Szrj lim = num_basevars (map);
69738fd1498Szrj bitmap_obstack_initialize (&ptr->obstack);
69838fd1498Szrj ptr->live_base_partitions = (bitmap *) xmalloc (sizeof (bitmap *) * lim);
69938fd1498Szrj ptr->live_base_var = BITMAP_ALLOC (&ptr->obstack);
70038fd1498Szrj for (x = 0; x < lim; x++)
70138fd1498Szrj ptr->live_base_partitions[x] = BITMAP_ALLOC (&ptr->obstack);
70238fd1498Szrj return ptr;
70338fd1498Szrj }
70438fd1498Szrj
70538fd1498Szrj
70638fd1498Szrj /* This routine will free the memory associated with PTR. */
70738fd1498Szrj
70838fd1498Szrj static void
delete_live_track(live_track * ptr)70938fd1498Szrj delete_live_track (live_track *ptr)
71038fd1498Szrj {
71138fd1498Szrj bitmap_obstack_release (&ptr->obstack);
71238fd1498Szrj free (ptr->live_base_partitions);
71338fd1498Szrj free (ptr);
71438fd1498Szrj }
71538fd1498Szrj
71638fd1498Szrj
71738fd1498Szrj /* This function will remove PARTITION from the live list in PTR. */
71838fd1498Szrj
71938fd1498Szrj static inline void
live_track_remove_partition(live_track * ptr,int partition)72038fd1498Szrj live_track_remove_partition (live_track *ptr, int partition)
72138fd1498Szrj {
72238fd1498Szrj int root;
72338fd1498Szrj
72438fd1498Szrj root = basevar_index (ptr->map, partition);
72538fd1498Szrj bitmap_clear_bit (ptr->live_base_partitions[root], partition);
72638fd1498Szrj /* If the element list is empty, make the base variable not live either. */
72738fd1498Szrj if (bitmap_empty_p (ptr->live_base_partitions[root]))
72838fd1498Szrj bitmap_clear_bit (ptr->live_base_var, root);
72938fd1498Szrj }
73038fd1498Szrj
73138fd1498Szrj
73238fd1498Szrj /* This function will adds PARTITION to the live list in PTR. */
73338fd1498Szrj
73438fd1498Szrj static inline void
live_track_add_partition(live_track * ptr,int partition)73538fd1498Szrj live_track_add_partition (live_track *ptr, int partition)
73638fd1498Szrj {
73738fd1498Szrj int root;
73838fd1498Szrj
73938fd1498Szrj root = basevar_index (ptr->map, partition);
74038fd1498Szrj /* If this base var wasn't live before, it is now. Clear the element list
74138fd1498Szrj since it was delayed until needed. */
74238fd1498Szrj if (bitmap_set_bit (ptr->live_base_var, root))
74338fd1498Szrj bitmap_clear (ptr->live_base_partitions[root]);
74438fd1498Szrj bitmap_set_bit (ptr->live_base_partitions[root], partition);
74538fd1498Szrj
74638fd1498Szrj }
74738fd1498Szrj
74838fd1498Szrj
74938fd1498Szrj /* Clear the live bit for VAR in PTR. */
75038fd1498Szrj
75138fd1498Szrj static inline void
live_track_clear_var(live_track * ptr,tree var)75238fd1498Szrj live_track_clear_var (live_track *ptr, tree var)
75338fd1498Szrj {
75438fd1498Szrj int p;
75538fd1498Szrj
75638fd1498Szrj p = var_to_partition (ptr->map, var);
75738fd1498Szrj if (p != NO_PARTITION)
75838fd1498Szrj live_track_remove_partition (ptr, p);
75938fd1498Szrj }
76038fd1498Szrj
76138fd1498Szrj
76238fd1498Szrj /* Return TRUE if VAR is live in PTR. */
76338fd1498Szrj
76438fd1498Szrj static inline bool
live_track_live_p(live_track * ptr,tree var)76538fd1498Szrj live_track_live_p (live_track *ptr, tree var)
76638fd1498Szrj {
76738fd1498Szrj int p, root;
76838fd1498Szrj
76938fd1498Szrj p = var_to_partition (ptr->map, var);
77038fd1498Szrj if (p != NO_PARTITION)
77138fd1498Szrj {
77238fd1498Szrj root = basevar_index (ptr->map, p);
77338fd1498Szrj if (bitmap_bit_p (ptr->live_base_var, root))
77438fd1498Szrj return bitmap_bit_p (ptr->live_base_partitions[root], p);
77538fd1498Szrj }
77638fd1498Szrj return false;
77738fd1498Szrj }
77838fd1498Szrj
77938fd1498Szrj
78038fd1498Szrj /* This routine will add USE to PTR. USE will be marked as live in both the
78138fd1498Szrj ssa live map and the live bitmap for the root of USE. */
78238fd1498Szrj
78338fd1498Szrj static inline void
live_track_process_use(live_track * ptr,tree use)78438fd1498Szrj live_track_process_use (live_track *ptr, tree use)
78538fd1498Szrj {
78638fd1498Szrj int p;
78738fd1498Szrj
78838fd1498Szrj p = var_to_partition (ptr->map, use);
78938fd1498Szrj if (p == NO_PARTITION)
79038fd1498Szrj return;
79138fd1498Szrj
79238fd1498Szrj /* Mark as live in the appropriate live list. */
79338fd1498Szrj live_track_add_partition (ptr, p);
79438fd1498Szrj }
79538fd1498Szrj
79638fd1498Szrj
79738fd1498Szrj /* This routine will process a DEF in PTR. DEF will be removed from the live
79838fd1498Szrj lists, and if there are any other live partitions with the same base
79938fd1498Szrj variable, conflicts will be added to GRAPH. */
80038fd1498Szrj
80138fd1498Szrj static inline void
live_track_process_def(live_track * ptr,tree def,ssa_conflicts * graph)80238fd1498Szrj live_track_process_def (live_track *ptr, tree def, ssa_conflicts *graph)
80338fd1498Szrj {
80438fd1498Szrj int p, root;
80538fd1498Szrj bitmap b;
80638fd1498Szrj unsigned x;
80738fd1498Szrj bitmap_iterator bi;
80838fd1498Szrj
80938fd1498Szrj p = var_to_partition (ptr->map, def);
81038fd1498Szrj if (p == NO_PARTITION)
81138fd1498Szrj return;
81238fd1498Szrj
81338fd1498Szrj /* Clear the liveness bit. */
81438fd1498Szrj live_track_remove_partition (ptr, p);
81538fd1498Szrj
81638fd1498Szrj /* If the bitmap isn't empty now, conflicts need to be added. */
81738fd1498Szrj root = basevar_index (ptr->map, p);
81838fd1498Szrj if (bitmap_bit_p (ptr->live_base_var, root))
81938fd1498Szrj {
82038fd1498Szrj b = ptr->live_base_partitions[root];
82138fd1498Szrj EXECUTE_IF_SET_IN_BITMAP (b, 0, x, bi)
82238fd1498Szrj ssa_conflicts_add (graph, p, x);
82338fd1498Szrj }
82438fd1498Szrj }
82538fd1498Szrj
82638fd1498Szrj
82738fd1498Szrj /* Initialize PTR with the partitions set in INIT. */
82838fd1498Szrj
82938fd1498Szrj static inline void
live_track_init(live_track * ptr,bitmap init)83038fd1498Szrj live_track_init (live_track *ptr, bitmap init)
83138fd1498Szrj {
83238fd1498Szrj unsigned p;
83338fd1498Szrj bitmap_iterator bi;
83438fd1498Szrj
83538fd1498Szrj /* Mark all live on exit partitions. */
83638fd1498Szrj EXECUTE_IF_SET_IN_BITMAP (init, 0, p, bi)
83738fd1498Szrj live_track_add_partition (ptr, p);
83838fd1498Szrj }
83938fd1498Szrj
84038fd1498Szrj
84138fd1498Szrj /* This routine will clear all live partitions in PTR. */
84238fd1498Szrj
84338fd1498Szrj static inline void
live_track_clear_base_vars(live_track * ptr)84438fd1498Szrj live_track_clear_base_vars (live_track *ptr)
84538fd1498Szrj {
84638fd1498Szrj /* Simply clear the live base list. Anything marked as live in the element
84738fd1498Szrj lists will be cleared later if/when the base variable ever comes alive
84838fd1498Szrj again. */
84938fd1498Szrj bitmap_clear (ptr->live_base_var);
85038fd1498Szrj }
85138fd1498Szrj
85238fd1498Szrj
85338fd1498Szrj /* Build a conflict graph based on LIVEINFO. Any partitions which are in the
85438fd1498Szrj partition view of the var_map liveinfo is based on get entries in the
85538fd1498Szrj conflict graph. Only conflicts between ssa_name partitions with the same
85638fd1498Szrj base variable are added. */
85738fd1498Szrj
85838fd1498Szrj static ssa_conflicts *
build_ssa_conflict_graph(tree_live_info_p liveinfo)85938fd1498Szrj build_ssa_conflict_graph (tree_live_info_p liveinfo)
86038fd1498Szrj {
86138fd1498Szrj ssa_conflicts *graph;
86238fd1498Szrj var_map map;
86338fd1498Szrj basic_block bb;
86438fd1498Szrj ssa_op_iter iter;
86538fd1498Szrj live_track *live;
86638fd1498Szrj basic_block entry;
86738fd1498Szrj
86838fd1498Szrj /* If inter-variable coalescing is enabled, we may attempt to
86938fd1498Szrj coalesce variables from different base variables, including
87038fd1498Szrj different parameters, so we have to make sure default defs live
87138fd1498Szrj at the entry block conflict with each other. */
87238fd1498Szrj if (flag_tree_coalesce_vars)
87338fd1498Szrj entry = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
87438fd1498Szrj else
87538fd1498Szrj entry = NULL;
87638fd1498Szrj
87738fd1498Szrj map = live_var_map (liveinfo);
87838fd1498Szrj graph = ssa_conflicts_new (num_var_partitions (map));
87938fd1498Szrj
88038fd1498Szrj live = new_live_track (map);
88138fd1498Szrj
88238fd1498Szrj FOR_EACH_BB_FN (bb, cfun)
88338fd1498Szrj {
88438fd1498Szrj /* Start with live on exit temporaries. */
88538fd1498Szrj live_track_init (live, live_on_exit (liveinfo, bb));
88638fd1498Szrj
88738fd1498Szrj for (gimple_stmt_iterator gsi = gsi_last_bb (bb); !gsi_end_p (gsi);
88838fd1498Szrj gsi_prev (&gsi))
88938fd1498Szrj {
89038fd1498Szrj tree var;
89138fd1498Szrj gimple *stmt = gsi_stmt (gsi);
89238fd1498Szrj
89338fd1498Szrj /* A copy between 2 partitions does not introduce an interference
89438fd1498Szrj by itself. If they did, you would never be able to coalesce
89538fd1498Szrj two things which are copied. If the two variables really do
89638fd1498Szrj conflict, they will conflict elsewhere in the program.
89738fd1498Szrj
89838fd1498Szrj This is handled by simply removing the SRC of the copy from the
89938fd1498Szrj live list, and processing the stmt normally. */
90038fd1498Szrj if (is_gimple_assign (stmt))
90138fd1498Szrj {
90238fd1498Szrj tree lhs = gimple_assign_lhs (stmt);
90338fd1498Szrj tree rhs1 = gimple_assign_rhs1 (stmt);
90438fd1498Szrj if (gimple_assign_copy_p (stmt)
90538fd1498Szrj && TREE_CODE (lhs) == SSA_NAME
90638fd1498Szrj && TREE_CODE (rhs1) == SSA_NAME)
90738fd1498Szrj live_track_clear_var (live, rhs1);
90838fd1498Szrj }
90938fd1498Szrj else if (is_gimple_debug (stmt))
91038fd1498Szrj continue;
91138fd1498Szrj
91238fd1498Szrj /* For stmts with more than one SSA_NAME definition pretend all the
91338fd1498Szrj SSA_NAME outputs but the first one are live at this point, so
91438fd1498Szrj that conflicts are added in between all those even when they are
91538fd1498Szrj actually not really live after the asm, because expansion might
91638fd1498Szrj copy those into pseudos after the asm and if multiple outputs
91738fd1498Szrj share the same partition, it might overwrite those that should
91838fd1498Szrj be live. E.g.
91938fd1498Szrj asm volatile (".." : "=r" (a) : "=r" (b) : "0" (a), "1" (a));
92038fd1498Szrj return a;
92138fd1498Szrj See PR70593. */
92238fd1498Szrj bool first = true;
92338fd1498Szrj FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
92438fd1498Szrj if (first)
92538fd1498Szrj first = false;
92638fd1498Szrj else
92738fd1498Szrj live_track_process_use (live, var);
92838fd1498Szrj
92938fd1498Szrj FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
93038fd1498Szrj live_track_process_def (live, var, graph);
93138fd1498Szrj
93238fd1498Szrj FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
93338fd1498Szrj live_track_process_use (live, var);
93438fd1498Szrj }
93538fd1498Szrj
93638fd1498Szrj /* If result of a PHI is unused, looping over the statements will not
93738fd1498Szrj record any conflicts since the def was never live. Since the PHI node
93838fd1498Szrj is going to be translated out of SSA form, it will insert a copy.
93938fd1498Szrj There must be a conflict recorded between the result of the PHI and
94038fd1498Szrj any variables that are live. Otherwise the out-of-ssa translation
94138fd1498Szrj may create incorrect code. */
94238fd1498Szrj for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
94338fd1498Szrj gsi_next (&gsi))
94438fd1498Szrj {
94538fd1498Szrj gphi *phi = gsi.phi ();
94638fd1498Szrj tree result = PHI_RESULT (phi);
94738fd1498Szrj if (live_track_live_p (live, result))
94838fd1498Szrj live_track_process_def (live, result, graph);
94938fd1498Szrj }
95038fd1498Szrj
95138fd1498Szrj /* Pretend there are defs for params' default defs at the start
95238fd1498Szrj of the (post-)entry block. This will prevent PARM_DECLs from
95338fd1498Szrj coalescing into the same partition. Although RESULT_DECLs'
95438fd1498Szrj default defs don't have a useful initial value, we have to
95538fd1498Szrj prevent them from coalescing with PARM_DECLs' default defs
95638fd1498Szrj too, otherwise assign_parms would attempt to assign different
95738fd1498Szrj RTL to the same partition. */
95838fd1498Szrj if (bb == entry)
95938fd1498Szrj {
96038fd1498Szrj unsigned i;
96138fd1498Szrj tree var;
96238fd1498Szrj
96338fd1498Szrj FOR_EACH_SSA_NAME (i, var, cfun)
96438fd1498Szrj {
96538fd1498Szrj if (!SSA_NAME_IS_DEFAULT_DEF (var)
96638fd1498Szrj || !SSA_NAME_VAR (var)
96738fd1498Szrj || VAR_P (SSA_NAME_VAR (var)))
96838fd1498Szrj continue;
96938fd1498Szrj
97038fd1498Szrj live_track_process_def (live, var, graph);
97138fd1498Szrj /* Process a use too, so that it remains live and
97238fd1498Szrj conflicts with other parms' default defs, even unused
97338fd1498Szrj ones. */
97438fd1498Szrj live_track_process_use (live, var);
97538fd1498Szrj }
97638fd1498Szrj }
97738fd1498Szrj
97838fd1498Szrj live_track_clear_base_vars (live);
97938fd1498Szrj }
98038fd1498Szrj
98138fd1498Szrj delete_live_track (live);
98238fd1498Szrj return graph;
98338fd1498Szrj }
98438fd1498Szrj
98538fd1498Szrj
98638fd1498Szrj /* Shortcut routine to print messages to file F of the form:
98738fd1498Szrj "STR1 EXPR1 STR2 EXPR2 STR3." */
98838fd1498Szrj
98938fd1498Szrj static inline void
print_exprs(FILE * f,const char * str1,tree expr1,const char * str2,tree expr2,const char * str3)99038fd1498Szrj print_exprs (FILE *f, const char *str1, tree expr1, const char *str2,
99138fd1498Szrj tree expr2, const char *str3)
99238fd1498Szrj {
99338fd1498Szrj fprintf (f, "%s", str1);
99438fd1498Szrj print_generic_expr (f, expr1, TDF_SLIM);
99538fd1498Szrj fprintf (f, "%s", str2);
99638fd1498Szrj print_generic_expr (f, expr2, TDF_SLIM);
99738fd1498Szrj fprintf (f, "%s", str3);
99838fd1498Szrj }
99938fd1498Szrj
100038fd1498Szrj
100138fd1498Szrj /* Print a failure to coalesce a MUST_COALESCE pair X and Y. */
100238fd1498Szrj
100338fd1498Szrj static inline void
fail_abnormal_edge_coalesce(int x,int y)100438fd1498Szrj fail_abnormal_edge_coalesce (int x, int y)
100538fd1498Szrj {
100638fd1498Szrj fprintf (stderr, "\nUnable to coalesce ssa_names %d and %d",x, y);
100738fd1498Szrj fprintf (stderr, " which are marked as MUST COALESCE.\n");
100838fd1498Szrj print_generic_expr (stderr, ssa_name (x), TDF_SLIM);
100938fd1498Szrj fprintf (stderr, " and ");
101038fd1498Szrj print_generic_stmt (stderr, ssa_name (y), TDF_SLIM);
101138fd1498Szrj
101238fd1498Szrj internal_error ("SSA corruption");
101338fd1498Szrj }
101438fd1498Szrj
101538fd1498Szrj /* Call CALLBACK for all PARM_DECLs and RESULT_DECLs for which
101638fd1498Szrj assign_parms may ask for a default partition. */
101738fd1498Szrj
101838fd1498Szrj static void
for_all_parms(void (* callback)(tree var,void * arg),void * arg)101938fd1498Szrj for_all_parms (void (*callback)(tree var, void *arg), void *arg)
102038fd1498Szrj {
102138fd1498Szrj for (tree var = DECL_ARGUMENTS (current_function_decl); var;
102238fd1498Szrj var = DECL_CHAIN (var))
102338fd1498Szrj callback (var, arg);
102438fd1498Szrj if (!VOID_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))))
102538fd1498Szrj callback (DECL_RESULT (current_function_decl), arg);
102638fd1498Szrj if (cfun->static_chain_decl)
102738fd1498Szrj callback (cfun->static_chain_decl, arg);
102838fd1498Szrj }
102938fd1498Szrj
103038fd1498Szrj /* Create a default def for VAR. */
103138fd1498Szrj
103238fd1498Szrj static void
create_default_def(tree var,void * arg ATTRIBUTE_UNUSED)103338fd1498Szrj create_default_def (tree var, void *arg ATTRIBUTE_UNUSED)
103438fd1498Szrj {
103538fd1498Szrj if (!is_gimple_reg (var))
103638fd1498Szrj return;
103738fd1498Szrj
103838fd1498Szrj tree ssa = get_or_create_ssa_default_def (cfun, var);
103938fd1498Szrj gcc_assert (ssa);
104038fd1498Szrj }
104138fd1498Szrj
104238fd1498Szrj /* Register VAR's default def in MAP. */
104338fd1498Szrj
104438fd1498Szrj static void
register_default_def(tree var,void * arg ATTRIBUTE_UNUSED)104538fd1498Szrj register_default_def (tree var, void *arg ATTRIBUTE_UNUSED)
104638fd1498Szrj {
104738fd1498Szrj if (!is_gimple_reg (var))
104838fd1498Szrj return;
104938fd1498Szrj
105038fd1498Szrj tree ssa = ssa_default_def (cfun, var);
105138fd1498Szrj gcc_assert (ssa);
105238fd1498Szrj }
105338fd1498Szrj
105438fd1498Szrj /* If VAR is an SSA_NAME associated with a PARM_DECL or a RESULT_DECL,
105538fd1498Szrj and the DECL's default def is unused (i.e., it was introduced by
105638fd1498Szrj create_default_def), mark VAR and the default def for
105738fd1498Szrj coalescing. */
105838fd1498Szrj
105938fd1498Szrj static void
coalesce_with_default(tree var,coalesce_list * cl,bitmap used_in_copy)106038fd1498Szrj coalesce_with_default (tree var, coalesce_list *cl, bitmap used_in_copy)
106138fd1498Szrj {
106238fd1498Szrj if (SSA_NAME_IS_DEFAULT_DEF (var)
106338fd1498Szrj || !SSA_NAME_VAR (var)
106438fd1498Szrj || VAR_P (SSA_NAME_VAR (var)))
106538fd1498Szrj return;
106638fd1498Szrj
106738fd1498Szrj tree ssa = ssa_default_def (cfun, SSA_NAME_VAR (var));
106838fd1498Szrj if (!has_zero_uses (ssa))
106938fd1498Szrj return;
107038fd1498Szrj
107138fd1498Szrj add_cost_one_coalesce (cl, SSA_NAME_VERSION (ssa), SSA_NAME_VERSION (var));
107238fd1498Szrj bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (var));
107338fd1498Szrj /* Default defs will have their used_in_copy bits set at the end of
107438fd1498Szrj create_outofssa_var_map. */
107538fd1498Szrj }
107638fd1498Szrj
107738fd1498Szrj /* This function creates a var_map for the current function as well as creating
107838fd1498Szrj a coalesce list for use later in the out of ssa process. */
107938fd1498Szrj
108038fd1498Szrj static var_map
create_outofssa_var_map(coalesce_list * cl,bitmap used_in_copy)108138fd1498Szrj create_outofssa_var_map (coalesce_list *cl, bitmap used_in_copy)
108238fd1498Szrj {
108338fd1498Szrj gimple_stmt_iterator gsi;
108438fd1498Szrj basic_block bb;
108538fd1498Szrj tree var;
108638fd1498Szrj gimple *stmt;
108738fd1498Szrj tree first;
108838fd1498Szrj var_map map;
108938fd1498Szrj int v1, v2, cost;
109038fd1498Szrj unsigned i;
109138fd1498Szrj
109238fd1498Szrj for_all_parms (create_default_def, NULL);
109338fd1498Szrj
109438fd1498Szrj map = init_var_map (num_ssa_names);
109538fd1498Szrj
109638fd1498Szrj for_all_parms (register_default_def, NULL);
109738fd1498Szrj
109838fd1498Szrj FOR_EACH_BB_FN (bb, cfun)
109938fd1498Szrj {
110038fd1498Szrj tree arg;
110138fd1498Szrj
110238fd1498Szrj for (gphi_iterator gpi = gsi_start_phis (bb);
110338fd1498Szrj !gsi_end_p (gpi);
110438fd1498Szrj gsi_next (&gpi))
110538fd1498Szrj {
110638fd1498Szrj gphi *phi = gpi.phi ();
110738fd1498Szrj size_t i;
110838fd1498Szrj int ver;
110938fd1498Szrj tree res;
111038fd1498Szrj bool saw_copy = false;
111138fd1498Szrj
111238fd1498Szrj res = gimple_phi_result (phi);
111338fd1498Szrj ver = SSA_NAME_VERSION (res);
111438fd1498Szrj
111538fd1498Szrj /* Register ssa_names and coalesces between the args and the result
111638fd1498Szrj of all PHI. */
111738fd1498Szrj for (i = 0; i < gimple_phi_num_args (phi); i++)
111838fd1498Szrj {
111938fd1498Szrj edge e = gimple_phi_arg_edge (phi, i);
112038fd1498Szrj arg = PHI_ARG_DEF (phi, i);
112138fd1498Szrj if (TREE_CODE (arg) != SSA_NAME)
112238fd1498Szrj continue;
112338fd1498Szrj
112438fd1498Szrj if (gimple_can_coalesce_p (arg, res)
112538fd1498Szrj || (e->flags & EDGE_ABNORMAL))
112638fd1498Szrj {
112738fd1498Szrj saw_copy = true;
112838fd1498Szrj bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (arg));
112938fd1498Szrj if ((e->flags & EDGE_ABNORMAL) == 0)
113038fd1498Szrj {
113138fd1498Szrj int cost = coalesce_cost_edge (e);
113238fd1498Szrj if (cost == 1 && has_single_use (arg))
113338fd1498Szrj add_cost_one_coalesce (cl, ver, SSA_NAME_VERSION (arg));
113438fd1498Szrj else
113538fd1498Szrj add_coalesce (cl, ver, SSA_NAME_VERSION (arg), cost);
113638fd1498Szrj }
113738fd1498Szrj }
113838fd1498Szrj }
113938fd1498Szrj if (saw_copy)
114038fd1498Szrj bitmap_set_bit (used_in_copy, ver);
114138fd1498Szrj }
114238fd1498Szrj
114338fd1498Szrj for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
114438fd1498Szrj {
114538fd1498Szrj stmt = gsi_stmt (gsi);
114638fd1498Szrj
114738fd1498Szrj if (is_gimple_debug (stmt))
114838fd1498Szrj continue;
114938fd1498Szrj
115038fd1498Szrj /* Check for copy coalesces. */
115138fd1498Szrj switch (gimple_code (stmt))
115238fd1498Szrj {
115338fd1498Szrj case GIMPLE_ASSIGN:
115438fd1498Szrj {
115538fd1498Szrj tree lhs = gimple_assign_lhs (stmt);
115638fd1498Szrj tree rhs1 = gimple_assign_rhs1 (stmt);
115738fd1498Szrj if (gimple_assign_ssa_name_copy_p (stmt)
115838fd1498Szrj && gimple_can_coalesce_p (lhs, rhs1))
115938fd1498Szrj {
116038fd1498Szrj v1 = SSA_NAME_VERSION (lhs);
116138fd1498Szrj v2 = SSA_NAME_VERSION (rhs1);
116238fd1498Szrj cost = coalesce_cost_bb (bb);
116338fd1498Szrj add_coalesce (cl, v1, v2, cost);
116438fd1498Szrj bitmap_set_bit (used_in_copy, v1);
116538fd1498Szrj bitmap_set_bit (used_in_copy, v2);
116638fd1498Szrj }
116738fd1498Szrj }
116838fd1498Szrj break;
116938fd1498Szrj
117038fd1498Szrj case GIMPLE_RETURN:
117138fd1498Szrj {
117238fd1498Szrj tree res = DECL_RESULT (current_function_decl);
117338fd1498Szrj if (VOID_TYPE_P (TREE_TYPE (res))
117438fd1498Szrj || !is_gimple_reg (res))
117538fd1498Szrj break;
117638fd1498Szrj tree rhs1 = gimple_return_retval (as_a <greturn *> (stmt));
117738fd1498Szrj if (!rhs1)
117838fd1498Szrj break;
117938fd1498Szrj tree lhs = ssa_default_def (cfun, res);
118038fd1498Szrj gcc_assert (lhs);
118138fd1498Szrj if (TREE_CODE (rhs1) == SSA_NAME
118238fd1498Szrj && gimple_can_coalesce_p (lhs, rhs1))
118338fd1498Szrj {
118438fd1498Szrj v1 = SSA_NAME_VERSION (lhs);
118538fd1498Szrj v2 = SSA_NAME_VERSION (rhs1);
118638fd1498Szrj cost = coalesce_cost_bb (bb);
118738fd1498Szrj add_coalesce (cl, v1, v2, cost);
118838fd1498Szrj bitmap_set_bit (used_in_copy, v1);
118938fd1498Szrj bitmap_set_bit (used_in_copy, v2);
119038fd1498Szrj }
119138fd1498Szrj break;
119238fd1498Szrj }
119338fd1498Szrj
119438fd1498Szrj case GIMPLE_ASM:
119538fd1498Szrj {
119638fd1498Szrj gasm *asm_stmt = as_a <gasm *> (stmt);
119738fd1498Szrj unsigned long noutputs, i;
119838fd1498Szrj unsigned long ninputs;
119938fd1498Szrj tree *outputs, link;
120038fd1498Szrj noutputs = gimple_asm_noutputs (asm_stmt);
120138fd1498Szrj ninputs = gimple_asm_ninputs (asm_stmt);
120238fd1498Szrj outputs = (tree *) alloca (noutputs * sizeof (tree));
120338fd1498Szrj for (i = 0; i < noutputs; ++i)
120438fd1498Szrj {
120538fd1498Szrj link = gimple_asm_output_op (asm_stmt, i);
120638fd1498Szrj outputs[i] = TREE_VALUE (link);
120738fd1498Szrj }
120838fd1498Szrj
120938fd1498Szrj for (i = 0; i < ninputs; ++i)
121038fd1498Szrj {
121138fd1498Szrj const char *constraint;
121238fd1498Szrj tree input;
121338fd1498Szrj char *end;
121438fd1498Szrj unsigned long match;
121538fd1498Szrj
121638fd1498Szrj link = gimple_asm_input_op (asm_stmt, i);
121738fd1498Szrj constraint
121838fd1498Szrj = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
121938fd1498Szrj input = TREE_VALUE (link);
122038fd1498Szrj
122138fd1498Szrj if (TREE_CODE (input) != SSA_NAME)
122238fd1498Szrj continue;
122338fd1498Szrj
122438fd1498Szrj match = strtoul (constraint, &end, 10);
122538fd1498Szrj if (match >= noutputs || end == constraint)
122638fd1498Szrj continue;
122738fd1498Szrj
122838fd1498Szrj if (TREE_CODE (outputs[match]) != SSA_NAME)
122938fd1498Szrj continue;
123038fd1498Szrj
123138fd1498Szrj v1 = SSA_NAME_VERSION (outputs[match]);
123238fd1498Szrj v2 = SSA_NAME_VERSION (input);
123338fd1498Szrj
123438fd1498Szrj if (gimple_can_coalesce_p (outputs[match], input))
123538fd1498Szrj {
123638fd1498Szrj cost = coalesce_cost (REG_BR_PROB_BASE,
123738fd1498Szrj optimize_bb_for_size_p (bb));
123838fd1498Szrj add_coalesce (cl, v1, v2, cost);
123938fd1498Szrj bitmap_set_bit (used_in_copy, v1);
124038fd1498Szrj bitmap_set_bit (used_in_copy, v2);
124138fd1498Szrj }
124238fd1498Szrj }
124338fd1498Szrj break;
124438fd1498Szrj }
124538fd1498Szrj
124638fd1498Szrj default:
124738fd1498Szrj break;
124838fd1498Szrj }
124938fd1498Szrj }
125038fd1498Szrj }
125138fd1498Szrj
125238fd1498Szrj /* Now process result decls and live on entry variables for entry into
125338fd1498Szrj the coalesce list. */
125438fd1498Szrj first = NULL_TREE;
125538fd1498Szrj FOR_EACH_SSA_NAME (i, var, cfun)
125638fd1498Szrj {
125738fd1498Szrj if (!virtual_operand_p (var))
125838fd1498Szrj {
125938fd1498Szrj coalesce_with_default (var, cl, used_in_copy);
126038fd1498Szrj
126138fd1498Szrj /* Add coalesces between all the result decls. */
126238fd1498Szrj if (SSA_NAME_VAR (var)
126338fd1498Szrj && TREE_CODE (SSA_NAME_VAR (var)) == RESULT_DECL)
126438fd1498Szrj {
126538fd1498Szrj bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (var));
126638fd1498Szrj if (first == NULL_TREE)
126738fd1498Szrj first = var;
126838fd1498Szrj else
126938fd1498Szrj {
127038fd1498Szrj gcc_assert (gimple_can_coalesce_p (var, first));
127138fd1498Szrj v1 = SSA_NAME_VERSION (first);
127238fd1498Szrj v2 = SSA_NAME_VERSION (var);
127338fd1498Szrj cost = coalesce_cost_bb (EXIT_BLOCK_PTR_FOR_FN (cfun));
127438fd1498Szrj add_coalesce (cl, v1, v2, cost);
127538fd1498Szrj }
127638fd1498Szrj }
127738fd1498Szrj /* Mark any default_def variables as being in the coalesce list
127838fd1498Szrj since they will have to be coalesced with the base variable. If
127938fd1498Szrj not marked as present, they won't be in the coalesce view. */
128038fd1498Szrj if (SSA_NAME_IS_DEFAULT_DEF (var)
128138fd1498Szrj && (!has_zero_uses (var)
128238fd1498Szrj || (SSA_NAME_VAR (var)
128338fd1498Szrj && !VAR_P (SSA_NAME_VAR (var)))))
128438fd1498Szrj bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (var));
128538fd1498Szrj }
128638fd1498Szrj }
128738fd1498Szrj
128838fd1498Szrj return map;
128938fd1498Szrj }
129038fd1498Szrj
129138fd1498Szrj
129238fd1498Szrj /* Attempt to coalesce ssa versions X and Y together using the partition
129338fd1498Szrj mapping in MAP and checking conflicts in GRAPH. Output any debug info to
129438fd1498Szrj DEBUG, if it is nun-NULL. */
129538fd1498Szrj
129638fd1498Szrj static inline bool
attempt_coalesce(var_map map,ssa_conflicts * graph,int x,int y,FILE * debug)129738fd1498Szrj attempt_coalesce (var_map map, ssa_conflicts *graph, int x, int y,
129838fd1498Szrj FILE *debug)
129938fd1498Szrj {
130038fd1498Szrj int z;
130138fd1498Szrj tree var1, var2;
130238fd1498Szrj int p1, p2;
130338fd1498Szrj
130438fd1498Szrj p1 = var_to_partition (map, ssa_name (x));
130538fd1498Szrj p2 = var_to_partition (map, ssa_name (y));
130638fd1498Szrj
130738fd1498Szrj if (debug)
130838fd1498Szrj {
130938fd1498Szrj fprintf (debug, "(%d)", x);
131038fd1498Szrj print_generic_expr (debug, partition_to_var (map, p1), TDF_SLIM);
131138fd1498Szrj fprintf (debug, " & (%d)", y);
131238fd1498Szrj print_generic_expr (debug, partition_to_var (map, p2), TDF_SLIM);
131338fd1498Szrj }
131438fd1498Szrj
131538fd1498Szrj if (p1 == p2)
131638fd1498Szrj {
131738fd1498Szrj if (debug)
131838fd1498Szrj fprintf (debug, ": Already Coalesced.\n");
131938fd1498Szrj return true;
132038fd1498Szrj }
132138fd1498Szrj
132238fd1498Szrj if (debug)
132338fd1498Szrj fprintf (debug, " [map: %d, %d] ", p1, p2);
132438fd1498Szrj
132538fd1498Szrj
132638fd1498Szrj if (!ssa_conflicts_test_p (graph, p1, p2))
132738fd1498Szrj {
132838fd1498Szrj var1 = partition_to_var (map, p1);
132938fd1498Szrj var2 = partition_to_var (map, p2);
133038fd1498Szrj
133138fd1498Szrj z = var_union (map, var1, var2);
133238fd1498Szrj if (z == NO_PARTITION)
133338fd1498Szrj {
133438fd1498Szrj if (debug)
133538fd1498Szrj fprintf (debug, ": Unable to perform partition union.\n");
133638fd1498Szrj return false;
133738fd1498Szrj }
133838fd1498Szrj
133938fd1498Szrj /* z is the new combined partition. Remove the other partition from
134038fd1498Szrj the list, and merge the conflicts. */
134138fd1498Szrj if (z == p1)
134238fd1498Szrj ssa_conflicts_merge (graph, p1, p2);
134338fd1498Szrj else
134438fd1498Szrj ssa_conflicts_merge (graph, p2, p1);
134538fd1498Szrj
134638fd1498Szrj if (debug)
134738fd1498Szrj fprintf (debug, ": Success -> %d\n", z);
134838fd1498Szrj
134938fd1498Szrj return true;
135038fd1498Szrj }
135138fd1498Szrj
135238fd1498Szrj if (debug)
135338fd1498Szrj fprintf (debug, ": Fail due to conflict\n");
135438fd1498Szrj
135538fd1498Szrj return false;
135638fd1498Szrj }
135738fd1498Szrj
135838fd1498Szrj
135938fd1498Szrj /* Attempt to Coalesce partitions in MAP which occur in the list CL using
136038fd1498Szrj GRAPH. Debug output is sent to DEBUG if it is non-NULL. */
136138fd1498Szrj
136238fd1498Szrj static void
coalesce_partitions(var_map map,ssa_conflicts * graph,coalesce_list * cl,FILE * debug)136338fd1498Szrj coalesce_partitions (var_map map, ssa_conflicts *graph, coalesce_list *cl,
136438fd1498Szrj FILE *debug)
136538fd1498Szrj {
136638fd1498Szrj int x = 0, y = 0;
136738fd1498Szrj tree var1, var2;
136838fd1498Szrj int cost;
136938fd1498Szrj basic_block bb;
137038fd1498Szrj edge e;
137138fd1498Szrj edge_iterator ei;
137238fd1498Szrj
137338fd1498Szrj /* First, coalesce all the copies across abnormal edges. These are not placed
137438fd1498Szrj in the coalesce list because they do not need to be sorted, and simply
137538fd1498Szrj consume extra memory/compilation time in large programs. */
137638fd1498Szrj
137738fd1498Szrj FOR_EACH_BB_FN (bb, cfun)
137838fd1498Szrj {
137938fd1498Szrj FOR_EACH_EDGE (e, ei, bb->preds)
138038fd1498Szrj if (e->flags & EDGE_ABNORMAL)
138138fd1498Szrj {
138238fd1498Szrj gphi_iterator gsi;
138338fd1498Szrj for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
138438fd1498Szrj gsi_next (&gsi))
138538fd1498Szrj {
138638fd1498Szrj gphi *phi = gsi.phi ();
138738fd1498Szrj tree arg = PHI_ARG_DEF (phi, e->dest_idx);
138838fd1498Szrj if (SSA_NAME_IS_DEFAULT_DEF (arg)
138938fd1498Szrj && (!SSA_NAME_VAR (arg)
139038fd1498Szrj || TREE_CODE (SSA_NAME_VAR (arg)) != PARM_DECL))
139138fd1498Szrj continue;
139238fd1498Szrj
139338fd1498Szrj tree res = PHI_RESULT (phi);
139438fd1498Szrj int v1 = SSA_NAME_VERSION (res);
139538fd1498Szrj int v2 = SSA_NAME_VERSION (arg);
139638fd1498Szrj
139738fd1498Szrj if (debug)
139838fd1498Szrj fprintf (debug, "Abnormal coalesce: ");
139938fd1498Szrj
140038fd1498Szrj if (!attempt_coalesce (map, graph, v1, v2, debug))
140138fd1498Szrj fail_abnormal_edge_coalesce (v1, v2);
140238fd1498Szrj }
140338fd1498Szrj }
140438fd1498Szrj }
140538fd1498Szrj
140638fd1498Szrj /* Now process the items in the coalesce list. */
140738fd1498Szrj
140838fd1498Szrj while ((cost = pop_best_coalesce (cl, &x, &y)) != NO_BEST_COALESCE)
140938fd1498Szrj {
141038fd1498Szrj var1 = ssa_name (x);
141138fd1498Szrj var2 = ssa_name (y);
141238fd1498Szrj
141338fd1498Szrj /* Assert the coalesces have the same base variable. */
141438fd1498Szrj gcc_assert (gimple_can_coalesce_p (var1, var2));
141538fd1498Szrj
141638fd1498Szrj if (debug)
141738fd1498Szrj fprintf (debug, "Coalesce list: ");
141838fd1498Szrj attempt_coalesce (map, graph, x, y, debug);
141938fd1498Szrj }
142038fd1498Szrj }
142138fd1498Szrj
142238fd1498Szrj
142338fd1498Szrj /* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR. */
142438fd1498Szrj
142538fd1498Szrj struct ssa_name_var_hash : nofree_ptr_hash <tree_node>
142638fd1498Szrj {
142738fd1498Szrj static inline hashval_t hash (const tree_node *);
142838fd1498Szrj static inline int equal (const tree_node *, const tree_node *);
142938fd1498Szrj };
143038fd1498Szrj
143138fd1498Szrj inline hashval_t
hash(const_tree n)143238fd1498Szrj ssa_name_var_hash::hash (const_tree n)
143338fd1498Szrj {
143438fd1498Szrj return DECL_UID (SSA_NAME_VAR (n));
143538fd1498Szrj }
143638fd1498Szrj
143738fd1498Szrj inline int
equal(const tree_node * n1,const tree_node * n2)143838fd1498Szrj ssa_name_var_hash::equal (const tree_node *n1, const tree_node *n2)
143938fd1498Szrj {
144038fd1498Szrj return SSA_NAME_VAR (n1) == SSA_NAME_VAR (n2);
144138fd1498Szrj }
144238fd1498Szrj
144338fd1498Szrj
144438fd1498Szrj /* Output partition map MAP with coalescing plan PART to file F. */
144538fd1498Szrj
144638fd1498Szrj void
dump_part_var_map(FILE * f,partition part,var_map map)144738fd1498Szrj dump_part_var_map (FILE *f, partition part, var_map map)
144838fd1498Szrj {
144938fd1498Szrj int t;
145038fd1498Szrj unsigned x, y;
145138fd1498Szrj int p;
145238fd1498Szrj
145338fd1498Szrj fprintf (f, "\nCoalescible Partition map \n\n");
145438fd1498Szrj
145538fd1498Szrj for (x = 0; x < map->num_partitions; x++)
145638fd1498Szrj {
145738fd1498Szrj if (map->view_to_partition != NULL)
145838fd1498Szrj p = map->view_to_partition[x];
145938fd1498Szrj else
146038fd1498Szrj p = x;
146138fd1498Szrj
146238fd1498Szrj if (ssa_name (p) == NULL_TREE
146338fd1498Szrj || virtual_operand_p (ssa_name (p)))
146438fd1498Szrj continue;
146538fd1498Szrj
146638fd1498Szrj t = 0;
146738fd1498Szrj for (y = 1; y < num_ssa_names; y++)
146838fd1498Szrj {
146938fd1498Szrj tree var = version_to_var (map, y);
147038fd1498Szrj if (!var)
147138fd1498Szrj continue;
147238fd1498Szrj int q = var_to_partition (map, var);
147338fd1498Szrj p = partition_find (part, q);
147438fd1498Szrj gcc_assert (map->partition_to_base_index[q]
147538fd1498Szrj == map->partition_to_base_index[p]);
147638fd1498Szrj
147738fd1498Szrj if (p == (int)x)
147838fd1498Szrj {
147938fd1498Szrj if (t++ == 0)
148038fd1498Szrj {
148138fd1498Szrj fprintf (f, "Partition %d, base %d (", x,
148238fd1498Szrj map->partition_to_base_index[q]);
148338fd1498Szrj print_generic_expr (f, partition_to_var (map, q), TDF_SLIM);
148438fd1498Szrj fprintf (f, " - ");
148538fd1498Szrj }
148638fd1498Szrj fprintf (f, "%d ", y);
148738fd1498Szrj }
148838fd1498Szrj }
148938fd1498Szrj if (t != 0)
149038fd1498Szrj fprintf (f, ")\n");
149138fd1498Szrj }
149238fd1498Szrj fprintf (f, "\n");
149338fd1498Szrj }
149438fd1498Szrj
149538fd1498Szrj /* Given SSA_NAMEs NAME1 and NAME2, return true if they are candidates for
149638fd1498Szrj coalescing together, false otherwise.
149738fd1498Szrj
149838fd1498Szrj This must stay consistent with compute_samebase_partition_bases and
149938fd1498Szrj compute_optimized_partition_bases. */
150038fd1498Szrj
150138fd1498Szrj bool
gimple_can_coalesce_p(tree name1,tree name2)150238fd1498Szrj gimple_can_coalesce_p (tree name1, tree name2)
150338fd1498Szrj {
150438fd1498Szrj /* First check the SSA_NAME's associated DECL. Without
150538fd1498Szrj optimization, we only want to coalesce if they have the same DECL
150638fd1498Szrj or both have no associated DECL. */
150738fd1498Szrj tree var1 = SSA_NAME_VAR (name1);
150838fd1498Szrj tree var2 = SSA_NAME_VAR (name2);
150938fd1498Szrj var1 = (var1 && (!VAR_P (var1) || !DECL_IGNORED_P (var1))) ? var1 : NULL_TREE;
151038fd1498Szrj var2 = (var2 && (!VAR_P (var2) || !DECL_IGNORED_P (var2))) ? var2 : NULL_TREE;
151138fd1498Szrj if (var1 != var2 && !flag_tree_coalesce_vars)
151238fd1498Szrj return false;
151338fd1498Szrj
151438fd1498Szrj /* Now check the types. If the types are the same, then we should
151538fd1498Szrj try to coalesce V1 and V2. */
151638fd1498Szrj tree t1 = TREE_TYPE (name1);
151738fd1498Szrj tree t2 = TREE_TYPE (name2);
151838fd1498Szrj if (t1 == t2)
151938fd1498Szrj {
152038fd1498Szrj check_modes:
152138fd1498Szrj /* If the base variables are the same, we're good: none of the
152238fd1498Szrj other tests below could possibly fail. */
152338fd1498Szrj var1 = SSA_NAME_VAR (name1);
152438fd1498Szrj var2 = SSA_NAME_VAR (name2);
152538fd1498Szrj if (var1 == var2)
152638fd1498Szrj return true;
152738fd1498Szrj
152838fd1498Szrj /* We don't want to coalesce two SSA names if one of the base
152938fd1498Szrj variables is supposed to be a register while the other is
153038fd1498Szrj supposed to be on the stack. Anonymous SSA names most often
153138fd1498Szrj take registers, but when not optimizing, user variables
153238fd1498Szrj should go on the stack, so coalescing them with the anonymous
153338fd1498Szrj variable as the partition leader would end up assigning the
153438fd1498Szrj user variable to a register. Don't do that! */
153538fd1498Szrj bool reg1 = use_register_for_decl (name1);
153638fd1498Szrj bool reg2 = use_register_for_decl (name2);
153738fd1498Szrj if (reg1 != reg2)
153838fd1498Szrj return false;
153938fd1498Szrj
154038fd1498Szrj /* Check that the promoted modes and unsignedness are the same.
154138fd1498Szrj We don't want to coalesce if the promoted modes would be
154238fd1498Szrj different, or if they would sign-extend differently. Only
154338fd1498Szrj PARM_DECLs and RESULT_DECLs have different promotion rules,
154438fd1498Szrj so skip the test if both are variables, or both are anonymous
154538fd1498Szrj SSA_NAMEs. */
154638fd1498Szrj int unsigned1, unsigned2;
154738fd1498Szrj return ((!var1 || VAR_P (var1)) && (!var2 || VAR_P (var2)))
154838fd1498Szrj || ((promote_ssa_mode (name1, &unsigned1)
154938fd1498Szrj == promote_ssa_mode (name2, &unsigned2))
155038fd1498Szrj && unsigned1 == unsigned2);
155138fd1498Szrj }
155238fd1498Szrj
155338fd1498Szrj /* If alignment requirements are different, we can't coalesce. */
155438fd1498Szrj if (MINIMUM_ALIGNMENT (t1,
155538fd1498Szrj var1 ? DECL_MODE (var1) : TYPE_MODE (t1),
155638fd1498Szrj var1 ? LOCAL_DECL_ALIGNMENT (var1) : TYPE_ALIGN (t1))
155738fd1498Szrj != MINIMUM_ALIGNMENT (t2,
155838fd1498Szrj var2 ? DECL_MODE (var2) : TYPE_MODE (t2),
155938fd1498Szrj var2 ? LOCAL_DECL_ALIGNMENT (var2) : TYPE_ALIGN (t2)))
156038fd1498Szrj return false;
156138fd1498Szrj
156238fd1498Szrj /* If the types are not the same, see whether they are compatible. This
156338fd1498Szrj (for example) allows coalescing when the types are fundamentally the
1564*58e805e6Szrj same, but just have different names. */
156538fd1498Szrj if (types_compatible_p (t1, t2))
156638fd1498Szrj goto check_modes;
156738fd1498Szrj
156838fd1498Szrj return false;
156938fd1498Szrj }
157038fd1498Szrj
157138fd1498Szrj /* Fill in MAP's partition_to_base_index, with one index for each
157238fd1498Szrj partition of SSA names USED_IN_COPIES and related by CL coalesce
157338fd1498Szrj possibilities. This must match gimple_can_coalesce_p in the
157438fd1498Szrj optimized case. */
157538fd1498Szrj
157638fd1498Szrj static void
compute_optimized_partition_bases(var_map map,bitmap used_in_copies,coalesce_list * cl)157738fd1498Szrj compute_optimized_partition_bases (var_map map, bitmap used_in_copies,
157838fd1498Szrj coalesce_list *cl)
157938fd1498Szrj {
158038fd1498Szrj int parts = num_var_partitions (map);
158138fd1498Szrj partition tentative = partition_new (parts);
158238fd1498Szrj
158338fd1498Szrj /* Partition the SSA versions so that, for each coalescible
158438fd1498Szrj pair, both of its members are in the same partition in
158538fd1498Szrj TENTATIVE. */
158638fd1498Szrj gcc_assert (!cl->sorted);
158738fd1498Szrj coalesce_pair *node;
158838fd1498Szrj coalesce_iterator_type ppi;
158938fd1498Szrj FOR_EACH_PARTITION_PAIR (node, ppi, cl)
159038fd1498Szrj {
159138fd1498Szrj tree v1 = ssa_name (node->first_element);
159238fd1498Szrj int p1 = partition_find (tentative, var_to_partition (map, v1));
159338fd1498Szrj tree v2 = ssa_name (node->second_element);
159438fd1498Szrj int p2 = partition_find (tentative, var_to_partition (map, v2));
159538fd1498Szrj
159638fd1498Szrj if (p1 == p2)
159738fd1498Szrj continue;
159838fd1498Szrj
159938fd1498Szrj partition_union (tentative, p1, p2);
160038fd1498Szrj }
160138fd1498Szrj
160238fd1498Szrj /* We have to deal with cost one pairs too. */
160338fd1498Szrj for (cost_one_pair *co = cl->cost_one_list; co; co = co->next)
160438fd1498Szrj {
160538fd1498Szrj tree v1 = ssa_name (co->first_element);
160638fd1498Szrj int p1 = partition_find (tentative, var_to_partition (map, v1));
160738fd1498Szrj tree v2 = ssa_name (co->second_element);
160838fd1498Szrj int p2 = partition_find (tentative, var_to_partition (map, v2));
160938fd1498Szrj
161038fd1498Szrj if (p1 == p2)
161138fd1498Szrj continue;
161238fd1498Szrj
161338fd1498Szrj partition_union (tentative, p1, p2);
161438fd1498Szrj }
161538fd1498Szrj
161638fd1498Szrj /* And also with abnormal edges. */
161738fd1498Szrj basic_block bb;
161838fd1498Szrj edge e;
161938fd1498Szrj edge_iterator ei;
162038fd1498Szrj FOR_EACH_BB_FN (bb, cfun)
162138fd1498Szrj {
162238fd1498Szrj FOR_EACH_EDGE (e, ei, bb->preds)
162338fd1498Szrj if (e->flags & EDGE_ABNORMAL)
162438fd1498Szrj {
162538fd1498Szrj gphi_iterator gsi;
162638fd1498Szrj for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
162738fd1498Szrj gsi_next (&gsi))
162838fd1498Szrj {
162938fd1498Szrj gphi *phi = gsi.phi ();
163038fd1498Szrj tree arg = PHI_ARG_DEF (phi, e->dest_idx);
163138fd1498Szrj if (SSA_NAME_IS_DEFAULT_DEF (arg)
163238fd1498Szrj && (!SSA_NAME_VAR (arg)
163338fd1498Szrj || TREE_CODE (SSA_NAME_VAR (arg)) != PARM_DECL))
163438fd1498Szrj continue;
163538fd1498Szrj
163638fd1498Szrj tree res = PHI_RESULT (phi);
163738fd1498Szrj
163838fd1498Szrj int p1 = partition_find (tentative, var_to_partition (map, res));
163938fd1498Szrj int p2 = partition_find (tentative, var_to_partition (map, arg));
164038fd1498Szrj
164138fd1498Szrj if (p1 == p2)
164238fd1498Szrj continue;
164338fd1498Szrj
164438fd1498Szrj partition_union (tentative, p1, p2);
164538fd1498Szrj }
164638fd1498Szrj }
164738fd1498Szrj }
164838fd1498Szrj
164938fd1498Szrj map->partition_to_base_index = XCNEWVEC (int, parts);
165038fd1498Szrj auto_vec<unsigned int> index_map (parts);
165138fd1498Szrj if (parts)
165238fd1498Szrj index_map.quick_grow (parts);
165338fd1498Szrj
165438fd1498Szrj const unsigned no_part = -1;
165538fd1498Szrj unsigned count = parts;
165638fd1498Szrj while (count)
165738fd1498Szrj index_map[--count] = no_part;
165838fd1498Szrj
165938fd1498Szrj /* Initialize MAP's mapping from partition to base index, using
166038fd1498Szrj as base indices an enumeration of the TENTATIVE partitions in
166138fd1498Szrj which each SSA version ended up, so that we compute conflicts
166238fd1498Szrj between all SSA versions that ended up in the same potential
166338fd1498Szrj coalesce partition. */
166438fd1498Szrj bitmap_iterator bi;
166538fd1498Szrj unsigned i;
166638fd1498Szrj EXECUTE_IF_SET_IN_BITMAP (used_in_copies, 0, i, bi)
166738fd1498Szrj {
166838fd1498Szrj int pidx = var_to_partition (map, ssa_name (i));
166938fd1498Szrj int base = partition_find (tentative, pidx);
167038fd1498Szrj if (index_map[base] != no_part)
167138fd1498Szrj continue;
167238fd1498Szrj index_map[base] = count++;
167338fd1498Szrj }
167438fd1498Szrj
167538fd1498Szrj map->num_basevars = count;
167638fd1498Szrj
167738fd1498Szrj EXECUTE_IF_SET_IN_BITMAP (used_in_copies, 0, i, bi)
167838fd1498Szrj {
167938fd1498Szrj int pidx = var_to_partition (map, ssa_name (i));
168038fd1498Szrj int base = partition_find (tentative, pidx);
168138fd1498Szrj gcc_assert (index_map[base] < count);
168238fd1498Szrj map->partition_to_base_index[pidx] = index_map[base];
168338fd1498Szrj }
168438fd1498Szrj
168538fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS))
168638fd1498Szrj dump_part_var_map (dump_file, tentative, map);
168738fd1498Szrj
168838fd1498Szrj partition_delete (tentative);
168938fd1498Szrj }
169038fd1498Szrj
169138fd1498Szrj /* Reduce the number of copies by coalescing variables in the function. Return
169238fd1498Szrj a partition map with the resulting coalesces. */
169338fd1498Szrj
169438fd1498Szrj extern var_map
coalesce_ssa_name(void)169538fd1498Szrj coalesce_ssa_name (void)
169638fd1498Szrj {
169738fd1498Szrj tree_live_info_p liveinfo;
169838fd1498Szrj ssa_conflicts *graph;
169938fd1498Szrj coalesce_list *cl;
170038fd1498Szrj auto_bitmap used_in_copies;
170138fd1498Szrj var_map map;
170238fd1498Szrj unsigned int i;
170338fd1498Szrj tree a;
170438fd1498Szrj
170538fd1498Szrj cl = create_coalesce_list ();
170638fd1498Szrj map = create_outofssa_var_map (cl, used_in_copies);
170738fd1498Szrj
170838fd1498Szrj /* If this optimization is disabled, we need to coalesce all the
170938fd1498Szrj names originating from the same SSA_NAME_VAR so debug info
171038fd1498Szrj remains undisturbed. */
171138fd1498Szrj if (!flag_tree_coalesce_vars)
171238fd1498Szrj {
171338fd1498Szrj hash_table<ssa_name_var_hash> ssa_name_hash (10);
171438fd1498Szrj
171538fd1498Szrj FOR_EACH_SSA_NAME (i, a, cfun)
171638fd1498Szrj {
171738fd1498Szrj if (SSA_NAME_VAR (a)
171838fd1498Szrj && !DECL_IGNORED_P (SSA_NAME_VAR (a))
171938fd1498Szrj && (!has_zero_uses (a) || !SSA_NAME_IS_DEFAULT_DEF (a)
172038fd1498Szrj || !VAR_P (SSA_NAME_VAR (a))))
172138fd1498Szrj {
172238fd1498Szrj tree *slot = ssa_name_hash.find_slot (a, INSERT);
172338fd1498Szrj
172438fd1498Szrj if (!*slot)
172538fd1498Szrj *slot = a;
172638fd1498Szrj else
172738fd1498Szrj {
172838fd1498Szrj /* If the variable is a PARM_DECL or a RESULT_DECL, we
172938fd1498Szrj _require_ that all the names originating from it be
173038fd1498Szrj coalesced, because there must be a single partition
173138fd1498Szrj containing all the names so that it can be assigned
173238fd1498Szrj the canonical RTL location of the DECL safely.
173338fd1498Szrj If in_lto_p, a function could have been compiled
173438fd1498Szrj originally with optimizations and only the link
173538fd1498Szrj performed at -O0, so we can't actually require it. */
173638fd1498Szrj const int cost
173738fd1498Szrj = (TREE_CODE (SSA_NAME_VAR (a)) == VAR_DECL || in_lto_p)
173838fd1498Szrj ? MUST_COALESCE_COST - 1 : MUST_COALESCE_COST;
173938fd1498Szrj add_coalesce (cl, SSA_NAME_VERSION (a),
174038fd1498Szrj SSA_NAME_VERSION (*slot), cost);
174138fd1498Szrj bitmap_set_bit (used_in_copies, SSA_NAME_VERSION (a));
174238fd1498Szrj bitmap_set_bit (used_in_copies, SSA_NAME_VERSION (*slot));
174338fd1498Szrj }
174438fd1498Szrj }
174538fd1498Szrj }
174638fd1498Szrj }
174738fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS))
174838fd1498Szrj dump_var_map (dump_file, map);
174938fd1498Szrj
175038fd1498Szrj partition_view_bitmap (map, used_in_copies);
175138fd1498Szrj
175238fd1498Szrj compute_optimized_partition_bases (map, used_in_copies, cl);
175338fd1498Szrj
175438fd1498Szrj if (num_var_partitions (map) < 1)
175538fd1498Szrj {
175638fd1498Szrj delete_coalesce_list (cl);
175738fd1498Szrj return map;
175838fd1498Szrj }
175938fd1498Szrj
176038fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS))
176138fd1498Szrj dump_var_map (dump_file, map);
176238fd1498Szrj
176338fd1498Szrj liveinfo = calculate_live_ranges (map, false);
176438fd1498Szrj
176538fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS))
176638fd1498Szrj dump_live_info (dump_file, liveinfo, LIVEDUMP_ENTRY);
176738fd1498Szrj
176838fd1498Szrj /* Build a conflict graph. */
176938fd1498Szrj graph = build_ssa_conflict_graph (liveinfo);
177038fd1498Szrj delete_tree_live_info (liveinfo);
177138fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS))
177238fd1498Szrj ssa_conflicts_dump (dump_file, graph);
177338fd1498Szrj
177438fd1498Szrj sort_coalesce_list (cl, graph, map);
177538fd1498Szrj
177638fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS))
177738fd1498Szrj {
177838fd1498Szrj fprintf (dump_file, "\nAfter sorting:\n");
177938fd1498Szrj dump_coalesce_list (dump_file, cl);
178038fd1498Szrj }
178138fd1498Szrj
178238fd1498Szrj /* First, coalesce all live on entry variables to their base variable.
178338fd1498Szrj This will ensure the first use is coming from the correct location. */
178438fd1498Szrj
178538fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS))
178638fd1498Szrj dump_var_map (dump_file, map);
178738fd1498Szrj
178838fd1498Szrj /* Now coalesce everything in the list. */
178938fd1498Szrj coalesce_partitions (map, graph, cl,
179038fd1498Szrj ((dump_flags & TDF_DETAILS) ? dump_file : NULL));
179138fd1498Szrj
179238fd1498Szrj delete_coalesce_list (cl);
179338fd1498Szrj ssa_conflicts_delete (graph);
179438fd1498Szrj
179538fd1498Szrj return map;
179638fd1498Szrj }
179738fd1498Szrj
179838fd1498Szrj /* We need to pass two arguments to set_parm_default_def_partition,
179938fd1498Szrj but for_all_parms only supports one. Use a pair. */
180038fd1498Szrj
180138fd1498Szrj typedef std::pair<var_map, bitmap> parm_default_def_partition_arg;
180238fd1498Szrj
180338fd1498Szrj /* Set in ARG's PARTS bitmap the bit corresponding to the partition in
180438fd1498Szrj ARG's MAP containing VAR's default def. */
180538fd1498Szrj
180638fd1498Szrj static void
set_parm_default_def_partition(tree var,void * arg_)180738fd1498Szrj set_parm_default_def_partition (tree var, void *arg_)
180838fd1498Szrj {
180938fd1498Szrj parm_default_def_partition_arg *arg = (parm_default_def_partition_arg *)arg_;
181038fd1498Szrj var_map map = arg->first;
181138fd1498Szrj bitmap parts = arg->second;
181238fd1498Szrj
181338fd1498Szrj if (!is_gimple_reg (var))
181438fd1498Szrj return;
181538fd1498Szrj
181638fd1498Szrj tree ssa = ssa_default_def (cfun, var);
181738fd1498Szrj gcc_assert (ssa);
181838fd1498Szrj
181938fd1498Szrj int version = var_to_partition (map, ssa);
182038fd1498Szrj gcc_assert (version != NO_PARTITION);
182138fd1498Szrj
182238fd1498Szrj bool changed = bitmap_set_bit (parts, version);
182338fd1498Szrj gcc_assert (changed);
182438fd1498Szrj }
182538fd1498Szrj
182638fd1498Szrj /* Allocate and return a bitmap that has a bit set for each partition
182738fd1498Szrj that contains a default def for a parameter. */
182838fd1498Szrj
182938fd1498Szrj bitmap
get_parm_default_def_partitions(var_map map)183038fd1498Szrj get_parm_default_def_partitions (var_map map)
183138fd1498Szrj {
183238fd1498Szrj bitmap parm_default_def_parts = BITMAP_ALLOC (NULL);
183338fd1498Szrj
183438fd1498Szrj parm_default_def_partition_arg
183538fd1498Szrj arg = std::make_pair (map, parm_default_def_parts);
183638fd1498Szrj
183738fd1498Szrj for_all_parms (set_parm_default_def_partition, &arg);
183838fd1498Szrj
183938fd1498Szrj return parm_default_def_parts;
184038fd1498Szrj }
184138fd1498Szrj
184238fd1498Szrj /* Allocate and return a bitmap that has a bit set for each partition
184338fd1498Szrj that contains an undefined value. */
184438fd1498Szrj
184538fd1498Szrj bitmap
get_undefined_value_partitions(var_map map)184638fd1498Szrj get_undefined_value_partitions (var_map map)
184738fd1498Szrj {
184838fd1498Szrj bitmap undefined_value_parts = BITMAP_ALLOC (NULL);
184938fd1498Szrj
185038fd1498Szrj for (unsigned int i = 1; i < num_ssa_names; i++)
185138fd1498Szrj {
185238fd1498Szrj tree var = ssa_name (i);
185338fd1498Szrj if (var
185438fd1498Szrj && !virtual_operand_p (var)
185538fd1498Szrj && !has_zero_uses (var)
185638fd1498Szrj && ssa_undefined_value_p (var))
185738fd1498Szrj {
185838fd1498Szrj const int p = var_to_partition (map, var);
185938fd1498Szrj if (p != NO_PARTITION)
186038fd1498Szrj bitmap_set_bit (undefined_value_parts, p);
186138fd1498Szrj }
186238fd1498Szrj }
186338fd1498Szrj
186438fd1498Szrj return undefined_value_parts;
186538fd1498Szrj }
1866