xref: /dflybsd-src/contrib/gcc-8.0/gcc/tree-ssa-coalesce.c (revision 95059079af47f9a66a175f374f2da1a5020e3255)
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