1*38fd1498Szrj /* IRA conflict builder.
2*38fd1498Szrj    Copyright (C) 2006-2018 Free Software Foundation, Inc.
3*38fd1498Szrj    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
4*38fd1498Szrj 
5*38fd1498Szrj This file is part of GCC.
6*38fd1498Szrj 
7*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
8*38fd1498Szrj the terms of the GNU General Public License as published by the Free
9*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
10*38fd1498Szrj version.
11*38fd1498Szrj 
12*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15*38fd1498Szrj for more details.
16*38fd1498Szrj 
17*38fd1498Szrj You should have received a copy of the GNU General Public License
18*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
19*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
20*38fd1498Szrj 
21*38fd1498Szrj #include "config.h"
22*38fd1498Szrj #include "system.h"
23*38fd1498Szrj #include "coretypes.h"
24*38fd1498Szrj #include "backend.h"
25*38fd1498Szrj #include "target.h"
26*38fd1498Szrj #include "rtl.h"
27*38fd1498Szrj #include "predict.h"
28*38fd1498Szrj #include "memmodel.h"
29*38fd1498Szrj #include "tm_p.h"
30*38fd1498Szrj #include "insn-config.h"
31*38fd1498Szrj #include "regs.h"
32*38fd1498Szrj #include "ira.h"
33*38fd1498Szrj #include "ira-int.h"
34*38fd1498Szrj #include "params.h"
35*38fd1498Szrj #include "sparseset.h"
36*38fd1498Szrj #include "addresses.h"
37*38fd1498Szrj 
38*38fd1498Szrj /* This file contains code responsible for allocno conflict creation,
39*38fd1498Szrj    allocno copy creation and allocno info accumulation on upper level
40*38fd1498Szrj    regions.  */
41*38fd1498Szrj 
42*38fd1498Szrj /* ira_allocnos_num array of arrays of bits, recording whether two
43*38fd1498Szrj    allocno's conflict (can't go in the same hardware register).
44*38fd1498Szrj 
45*38fd1498Szrj    Some arrays will be used as conflict bit vector of the
46*38fd1498Szrj    corresponding allocnos see function build_object_conflicts.  */
47*38fd1498Szrj static IRA_INT_TYPE **conflicts;
48*38fd1498Szrj 
49*38fd1498Szrj /* Macro to test a conflict of C1 and C2 in `conflicts'.  */
50*38fd1498Szrj #define OBJECTS_CONFLICT_P(C1, C2)					\
51*38fd1498Szrj   (OBJECT_MIN (C1) <= OBJECT_CONFLICT_ID (C2)				\
52*38fd1498Szrj    && OBJECT_CONFLICT_ID (C2) <= OBJECT_MAX (C1)			\
53*38fd1498Szrj    && TEST_MINMAX_SET_BIT (conflicts[OBJECT_CONFLICT_ID (C1)],		\
54*38fd1498Szrj 			   OBJECT_CONFLICT_ID (C2),			\
55*38fd1498Szrj 			   OBJECT_MIN (C1), OBJECT_MAX (C1)))
56*38fd1498Szrj 
57*38fd1498Szrj 
58*38fd1498Szrj /* Record a conflict between objects OBJ1 and OBJ2.  If necessary,
59*38fd1498Szrj    canonicalize the conflict by recording it for lower-order subobjects
60*38fd1498Szrj    of the corresponding allocnos.  */
61*38fd1498Szrj static void
record_object_conflict(ira_object_t obj1,ira_object_t obj2)62*38fd1498Szrj record_object_conflict (ira_object_t obj1, ira_object_t obj2)
63*38fd1498Szrj {
64*38fd1498Szrj   ira_allocno_t a1 = OBJECT_ALLOCNO (obj1);
65*38fd1498Szrj   ira_allocno_t a2 = OBJECT_ALLOCNO (obj2);
66*38fd1498Szrj   int w1 = OBJECT_SUBWORD (obj1);
67*38fd1498Szrj   int w2 = OBJECT_SUBWORD (obj2);
68*38fd1498Szrj   int id1, id2;
69*38fd1498Szrj 
70*38fd1498Szrj   /* Canonicalize the conflict.  If two identically-numbered words
71*38fd1498Szrj      conflict, always record this as a conflict between words 0.  That
72*38fd1498Szrj      is the only information we need, and it is easier to test for if
73*38fd1498Szrj      it is collected in each allocno's lowest-order object.  */
74*38fd1498Szrj   if (w1 == w2 && w1 > 0)
75*38fd1498Szrj     {
76*38fd1498Szrj       obj1 = ALLOCNO_OBJECT (a1, 0);
77*38fd1498Szrj       obj2 = ALLOCNO_OBJECT (a2, 0);
78*38fd1498Szrj     }
79*38fd1498Szrj   id1 = OBJECT_CONFLICT_ID (obj1);
80*38fd1498Szrj   id2 = OBJECT_CONFLICT_ID (obj2);
81*38fd1498Szrj 
82*38fd1498Szrj   SET_MINMAX_SET_BIT (conflicts[id1], id2, OBJECT_MIN (obj1),
83*38fd1498Szrj 		      OBJECT_MAX (obj1));
84*38fd1498Szrj   SET_MINMAX_SET_BIT (conflicts[id2], id1, OBJECT_MIN (obj2),
85*38fd1498Szrj 		      OBJECT_MAX (obj2));
86*38fd1498Szrj }
87*38fd1498Szrj 
88*38fd1498Szrj /* Build allocno conflict table by processing allocno live ranges.
89*38fd1498Szrj    Return true if the table was built.  The table is not built if it
90*38fd1498Szrj    is too big.  */
91*38fd1498Szrj static bool
build_conflict_bit_table(void)92*38fd1498Szrj build_conflict_bit_table (void)
93*38fd1498Szrj {
94*38fd1498Szrj   int i;
95*38fd1498Szrj   unsigned int j;
96*38fd1498Szrj   enum reg_class aclass;
97*38fd1498Szrj   int object_set_words, allocated_words_num, conflict_bit_vec_words_num;
98*38fd1498Szrj   live_range_t r;
99*38fd1498Szrj   ira_allocno_t allocno;
100*38fd1498Szrj   ira_allocno_iterator ai;
101*38fd1498Szrj   sparseset objects_live;
102*38fd1498Szrj   ira_object_t obj;
103*38fd1498Szrj   ira_allocno_object_iterator aoi;
104*38fd1498Szrj 
105*38fd1498Szrj   allocated_words_num = 0;
106*38fd1498Szrj   FOR_EACH_ALLOCNO (allocno, ai)
107*38fd1498Szrj     FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
108*38fd1498Szrj       {
109*38fd1498Szrj 	if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
110*38fd1498Szrj 	  continue;
111*38fd1498Szrj 	conflict_bit_vec_words_num
112*38fd1498Szrj 	  = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
113*38fd1498Szrj 	     / IRA_INT_BITS);
114*38fd1498Szrj 	allocated_words_num += conflict_bit_vec_words_num;
115*38fd1498Szrj 	if ((uint64_t) allocated_words_num * sizeof (IRA_INT_TYPE)
116*38fd1498Szrj 	    > (uint64_t) IRA_MAX_CONFLICT_TABLE_SIZE * 1024 * 1024)
117*38fd1498Szrj 	  {
118*38fd1498Szrj 	    if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
119*38fd1498Szrj 	      fprintf
120*38fd1498Szrj 		(ira_dump_file,
121*38fd1498Szrj 		 "+++Conflict table will be too big(>%dMB) -- don't use it\n",
122*38fd1498Szrj 		 IRA_MAX_CONFLICT_TABLE_SIZE);
123*38fd1498Szrj 	    return false;
124*38fd1498Szrj 	  }
125*38fd1498Szrj       }
126*38fd1498Szrj 
127*38fd1498Szrj   conflicts = (IRA_INT_TYPE **) ira_allocate (sizeof (IRA_INT_TYPE *)
128*38fd1498Szrj 					      * ira_objects_num);
129*38fd1498Szrj   allocated_words_num = 0;
130*38fd1498Szrj   FOR_EACH_ALLOCNO (allocno, ai)
131*38fd1498Szrj     FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
132*38fd1498Szrj       {
133*38fd1498Szrj 	int id = OBJECT_CONFLICT_ID (obj);
134*38fd1498Szrj 	if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
135*38fd1498Szrj 	  {
136*38fd1498Szrj 	    conflicts[id] = NULL;
137*38fd1498Szrj 	    continue;
138*38fd1498Szrj 	  }
139*38fd1498Szrj 	conflict_bit_vec_words_num
140*38fd1498Szrj 	  = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
141*38fd1498Szrj 	     / IRA_INT_BITS);
142*38fd1498Szrj 	allocated_words_num += conflict_bit_vec_words_num;
143*38fd1498Szrj 	conflicts[id]
144*38fd1498Szrj 	  = (IRA_INT_TYPE *) ira_allocate (sizeof (IRA_INT_TYPE)
145*38fd1498Szrj 					   * conflict_bit_vec_words_num);
146*38fd1498Szrj 	memset (conflicts[id], 0,
147*38fd1498Szrj 		sizeof (IRA_INT_TYPE) * conflict_bit_vec_words_num);
148*38fd1498Szrj       }
149*38fd1498Szrj 
150*38fd1498Szrj   object_set_words = (ira_objects_num + IRA_INT_BITS - 1) / IRA_INT_BITS;
151*38fd1498Szrj   if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
152*38fd1498Szrj     fprintf
153*38fd1498Szrj       (ira_dump_file,
154*38fd1498Szrj        "+++Allocating %ld bytes for conflict table (uncompressed size %ld)\n",
155*38fd1498Szrj        (long) allocated_words_num * sizeof (IRA_INT_TYPE),
156*38fd1498Szrj        (long) object_set_words * ira_objects_num * sizeof (IRA_INT_TYPE));
157*38fd1498Szrj 
158*38fd1498Szrj   objects_live = sparseset_alloc (ira_objects_num);
159*38fd1498Szrj   for (i = 0; i < ira_max_point; i++)
160*38fd1498Szrj     {
161*38fd1498Szrj       for (r = ira_start_point_ranges[i]; r != NULL; r = r->start_next)
162*38fd1498Szrj 	{
163*38fd1498Szrj 	  ira_object_t obj = r->object;
164*38fd1498Szrj 	  ira_allocno_t allocno = OBJECT_ALLOCNO (obj);
165*38fd1498Szrj 	  int id = OBJECT_CONFLICT_ID (obj);
166*38fd1498Szrj 
167*38fd1498Szrj 	  gcc_assert (id < ira_objects_num);
168*38fd1498Szrj 
169*38fd1498Szrj 	  aclass = ALLOCNO_CLASS (allocno);
170*38fd1498Szrj 	  EXECUTE_IF_SET_IN_SPARSESET (objects_live, j)
171*38fd1498Szrj 	    {
172*38fd1498Szrj 	      ira_object_t live_obj = ira_object_id_map[j];
173*38fd1498Szrj 	      ira_allocno_t live_a = OBJECT_ALLOCNO (live_obj);
174*38fd1498Szrj 	      enum reg_class live_aclass = ALLOCNO_CLASS (live_a);
175*38fd1498Szrj 
176*38fd1498Szrj 	      if (ira_reg_classes_intersect_p[aclass][live_aclass]
177*38fd1498Szrj 		  /* Don't set up conflict for the allocno with itself.  */
178*38fd1498Szrj 		  && live_a != allocno)
179*38fd1498Szrj 		{
180*38fd1498Szrj 		  record_object_conflict (obj, live_obj);
181*38fd1498Szrj 		}
182*38fd1498Szrj 	    }
183*38fd1498Szrj 	  sparseset_set_bit (objects_live, id);
184*38fd1498Szrj 	}
185*38fd1498Szrj 
186*38fd1498Szrj       for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next)
187*38fd1498Szrj 	sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (r->object));
188*38fd1498Szrj     }
189*38fd1498Szrj   sparseset_free (objects_live);
190*38fd1498Szrj   return true;
191*38fd1498Szrj }
192*38fd1498Szrj 
193*38fd1498Szrj /* Return true iff allocnos A1 and A2 cannot be allocated to the same
194*38fd1498Szrj    register due to conflicts.  */
195*38fd1498Szrj 
196*38fd1498Szrj static bool
allocnos_conflict_for_copy_p(ira_allocno_t a1,ira_allocno_t a2)197*38fd1498Szrj allocnos_conflict_for_copy_p (ira_allocno_t a1, ira_allocno_t a2)
198*38fd1498Szrj {
199*38fd1498Szrj   /* Due to the fact that we canonicalize conflicts (see
200*38fd1498Szrj      record_object_conflict), we only need to test for conflicts of
201*38fd1498Szrj      the lowest order words.  */
202*38fd1498Szrj   ira_object_t obj1 = ALLOCNO_OBJECT (a1, 0);
203*38fd1498Szrj   ira_object_t obj2 = ALLOCNO_OBJECT (a2, 0);
204*38fd1498Szrj 
205*38fd1498Szrj   return OBJECTS_CONFLICT_P (obj1, obj2);
206*38fd1498Szrj }
207*38fd1498Szrj 
208*38fd1498Szrj /* Check that X is REG or SUBREG of REG.  */
209*38fd1498Szrj #define REG_SUBREG_P(x)							\
210*38fd1498Szrj    (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))))
211*38fd1498Szrj 
212*38fd1498Szrj /* Return X if X is a REG, otherwise it should be SUBREG of REG and
213*38fd1498Szrj    the function returns the reg in this case.  *OFFSET will be set to
214*38fd1498Szrj    0 in the first case or the regno offset in the first case.  */
215*38fd1498Szrj static rtx
go_through_subreg(rtx x,int * offset)216*38fd1498Szrj go_through_subreg (rtx x, int *offset)
217*38fd1498Szrj {
218*38fd1498Szrj   rtx reg;
219*38fd1498Szrj 
220*38fd1498Szrj   *offset = 0;
221*38fd1498Szrj   if (REG_P (x))
222*38fd1498Szrj     return x;
223*38fd1498Szrj   ira_assert (GET_CODE (x) == SUBREG);
224*38fd1498Szrj   reg = SUBREG_REG (x);
225*38fd1498Szrj   ira_assert (REG_P (reg));
226*38fd1498Szrj   if (REGNO (reg) < FIRST_PSEUDO_REGISTER)
227*38fd1498Szrj     *offset = subreg_regno_offset (REGNO (reg), GET_MODE (reg),
228*38fd1498Szrj 				   SUBREG_BYTE (x), GET_MODE (x));
229*38fd1498Szrj   else if (!can_div_trunc_p (SUBREG_BYTE (x),
230*38fd1498Szrj 			     REGMODE_NATURAL_SIZE (GET_MODE (x)), offset))
231*38fd1498Szrj     /* Checked by validate_subreg.  We must know at compile time which
232*38fd1498Szrj        inner hard registers are being accessed.  */
233*38fd1498Szrj     gcc_unreachable ();
234*38fd1498Szrj   return reg;
235*38fd1498Szrj }
236*38fd1498Szrj 
237*38fd1498Szrj /* Process registers REG1 and REG2 in move INSN with execution
238*38fd1498Szrj    frequency FREQ.  The function also processes the registers in a
239*38fd1498Szrj    potential move insn (INSN == NULL in this case) with frequency
240*38fd1498Szrj    FREQ.  The function can modify hard register costs of the
241*38fd1498Szrj    corresponding allocnos or create a copy involving the corresponding
242*38fd1498Szrj    allocnos.  The function does nothing if the both registers are hard
243*38fd1498Szrj    registers.  When nothing is changed, the function returns
244*38fd1498Szrj    FALSE.  */
245*38fd1498Szrj static bool
process_regs_for_copy(rtx reg1,rtx reg2,bool constraint_p,rtx_insn * insn,int freq)246*38fd1498Szrj process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
247*38fd1498Szrj 		       rtx_insn *insn, int freq)
248*38fd1498Szrj {
249*38fd1498Szrj   int allocno_preferenced_hard_regno, cost, index, offset1, offset2;
250*38fd1498Szrj   bool only_regs_p;
251*38fd1498Szrj   ira_allocno_t a;
252*38fd1498Szrj   reg_class_t rclass, aclass;
253*38fd1498Szrj   machine_mode mode;
254*38fd1498Szrj   ira_copy_t cp;
255*38fd1498Szrj 
256*38fd1498Szrj   gcc_assert (REG_SUBREG_P (reg1) && REG_SUBREG_P (reg2));
257*38fd1498Szrj   only_regs_p = REG_P (reg1) && REG_P (reg2);
258*38fd1498Szrj   reg1 = go_through_subreg (reg1, &offset1);
259*38fd1498Szrj   reg2 = go_through_subreg (reg2, &offset2);
260*38fd1498Szrj   /* Set up hard regno preferenced by allocno.  If allocno gets the
261*38fd1498Szrj      hard regno the copy (or potential move) insn will be removed.  */
262*38fd1498Szrj   if (HARD_REGISTER_P (reg1))
263*38fd1498Szrj     {
264*38fd1498Szrj       if (HARD_REGISTER_P (reg2))
265*38fd1498Szrj 	return false;
266*38fd1498Szrj       allocno_preferenced_hard_regno = REGNO (reg1) + offset1 - offset2;
267*38fd1498Szrj       a = ira_curr_regno_allocno_map[REGNO (reg2)];
268*38fd1498Szrj     }
269*38fd1498Szrj   else if (HARD_REGISTER_P (reg2))
270*38fd1498Szrj     {
271*38fd1498Szrj       allocno_preferenced_hard_regno = REGNO (reg2) + offset2 - offset1;
272*38fd1498Szrj       a = ira_curr_regno_allocno_map[REGNO (reg1)];
273*38fd1498Szrj     }
274*38fd1498Szrj   else
275*38fd1498Szrj     {
276*38fd1498Szrj       ira_allocno_t a1 = ira_curr_regno_allocno_map[REGNO (reg1)];
277*38fd1498Szrj       ira_allocno_t a2 = ira_curr_regno_allocno_map[REGNO (reg2)];
278*38fd1498Szrj 
279*38fd1498Szrj       if (!allocnos_conflict_for_copy_p (a1, a2) && offset1 == offset2)
280*38fd1498Szrj 	{
281*38fd1498Szrj 	  cp = ira_add_allocno_copy (a1, a2, freq, constraint_p, insn,
282*38fd1498Szrj 				     ira_curr_loop_tree_node);
283*38fd1498Szrj 	  bitmap_set_bit (ira_curr_loop_tree_node->local_copies, cp->num);
284*38fd1498Szrj 	  return true;
285*38fd1498Szrj 	}
286*38fd1498Szrj       else
287*38fd1498Szrj 	return false;
288*38fd1498Szrj     }
289*38fd1498Szrj 
290*38fd1498Szrj   if (! IN_RANGE (allocno_preferenced_hard_regno,
291*38fd1498Szrj 		  0, FIRST_PSEUDO_REGISTER - 1))
292*38fd1498Szrj     /* Can not be tied.  */
293*38fd1498Szrj     return false;
294*38fd1498Szrj   rclass = REGNO_REG_CLASS (allocno_preferenced_hard_regno);
295*38fd1498Szrj   mode = ALLOCNO_MODE (a);
296*38fd1498Szrj   aclass = ALLOCNO_CLASS (a);
297*38fd1498Szrj   if (only_regs_p && insn != NULL_RTX
298*38fd1498Szrj       && reg_class_size[rclass] <= ira_reg_class_max_nregs [rclass][mode])
299*38fd1498Szrj     /* It is already taken into account in ira-costs.c.  */
300*38fd1498Szrj     return false;
301*38fd1498Szrj   index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno];
302*38fd1498Szrj   if (index < 0)
303*38fd1498Szrj     /* Can not be tied.  It is not in the allocno class.  */
304*38fd1498Szrj     return false;
305*38fd1498Szrj   ira_init_register_move_cost_if_necessary (mode);
306*38fd1498Szrj   if (HARD_REGISTER_P (reg1))
307*38fd1498Szrj     cost = ira_register_move_cost[mode][aclass][rclass] * freq;
308*38fd1498Szrj   else
309*38fd1498Szrj     cost = ira_register_move_cost[mode][rclass][aclass] * freq;
310*38fd1498Szrj   do
311*38fd1498Szrj     {
312*38fd1498Szrj       ira_allocate_and_set_costs
313*38fd1498Szrj 	(&ALLOCNO_HARD_REG_COSTS (a), aclass,
314*38fd1498Szrj 	 ALLOCNO_CLASS_COST (a));
315*38fd1498Szrj       ira_allocate_and_set_costs
316*38fd1498Szrj 	(&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), aclass, 0);
317*38fd1498Szrj       ALLOCNO_HARD_REG_COSTS (a)[index] -= cost;
318*38fd1498Szrj       ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= cost;
319*38fd1498Szrj       if (ALLOCNO_HARD_REG_COSTS (a)[index] < ALLOCNO_CLASS_COST (a))
320*38fd1498Szrj 	ALLOCNO_CLASS_COST (a) = ALLOCNO_HARD_REG_COSTS (a)[index];
321*38fd1498Szrj       ira_add_allocno_pref (a, allocno_preferenced_hard_regno, freq);
322*38fd1498Szrj       a = ira_parent_or_cap_allocno (a);
323*38fd1498Szrj     }
324*38fd1498Szrj   while (a != NULL);
325*38fd1498Szrj   return true;
326*38fd1498Szrj }
327*38fd1498Szrj 
328*38fd1498Szrj /* Process all of the output registers of the current insn which are
329*38fd1498Szrj    not bound (BOUND_P) and the input register REG (its operand number
330*38fd1498Szrj    OP_NUM) which dies in the insn as if there were a move insn between
331*38fd1498Szrj    them with frequency FREQ.  */
332*38fd1498Szrj static void
process_reg_shuffles(rtx reg,int op_num,int freq,bool * bound_p)333*38fd1498Szrj process_reg_shuffles (rtx reg, int op_num, int freq, bool *bound_p)
334*38fd1498Szrj {
335*38fd1498Szrj   int i;
336*38fd1498Szrj   rtx another_reg;
337*38fd1498Szrj 
338*38fd1498Szrj   gcc_assert (REG_SUBREG_P (reg));
339*38fd1498Szrj   for (i = 0; i < recog_data.n_operands; i++)
340*38fd1498Szrj     {
341*38fd1498Szrj       another_reg = recog_data.operand[i];
342*38fd1498Szrj 
343*38fd1498Szrj       if (!REG_SUBREG_P (another_reg) || op_num == i
344*38fd1498Szrj 	  || recog_data.operand_type[i] != OP_OUT
345*38fd1498Szrj 	  || bound_p[i])
346*38fd1498Szrj 	continue;
347*38fd1498Szrj 
348*38fd1498Szrj       process_regs_for_copy (reg, another_reg, false, NULL, freq);
349*38fd1498Szrj     }
350*38fd1498Szrj }
351*38fd1498Szrj 
352*38fd1498Szrj /* Process INSN and create allocno copies if necessary.  For example,
353*38fd1498Szrj    it might be because INSN is a pseudo-register move or INSN is two
354*38fd1498Szrj    operand insn.  */
355*38fd1498Szrj static void
add_insn_allocno_copies(rtx_insn * insn)356*38fd1498Szrj add_insn_allocno_copies (rtx_insn *insn)
357*38fd1498Szrj {
358*38fd1498Szrj   rtx set, operand, dup;
359*38fd1498Szrj   bool bound_p[MAX_RECOG_OPERANDS];
360*38fd1498Szrj   int i, n, freq;
361*38fd1498Szrj   HARD_REG_SET alts;
362*38fd1498Szrj 
363*38fd1498Szrj   freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
364*38fd1498Szrj   if (freq == 0)
365*38fd1498Szrj     freq = 1;
366*38fd1498Szrj   if ((set = single_set (insn)) != NULL_RTX
367*38fd1498Szrj       && REG_SUBREG_P (SET_DEST (set)) && REG_SUBREG_P (SET_SRC (set))
368*38fd1498Szrj       && ! side_effects_p (set)
369*38fd1498Szrj       && find_reg_note (insn, REG_DEAD,
370*38fd1498Szrj 			REG_P (SET_SRC (set))
371*38fd1498Szrj 			? SET_SRC (set)
372*38fd1498Szrj 			: SUBREG_REG (SET_SRC (set))) != NULL_RTX)
373*38fd1498Szrj     {
374*38fd1498Szrj       process_regs_for_copy (SET_SRC (set), SET_DEST (set),
375*38fd1498Szrj 			     false, insn, freq);
376*38fd1498Szrj       return;
377*38fd1498Szrj     }
378*38fd1498Szrj   /* Fast check of possibility of constraint or shuffle copies.  If
379*38fd1498Szrj      there are no dead registers, there will be no such copies.  */
380*38fd1498Szrj   if (! find_reg_note (insn, REG_DEAD, NULL_RTX))
381*38fd1498Szrj     return;
382*38fd1498Szrj   ira_setup_alts (insn, alts);
383*38fd1498Szrj   for (i = 0; i < recog_data.n_operands; i++)
384*38fd1498Szrj     bound_p[i] = false;
385*38fd1498Szrj   for (i = 0; i < recog_data.n_operands; i++)
386*38fd1498Szrj     {
387*38fd1498Szrj       operand = recog_data.operand[i];
388*38fd1498Szrj       if (! REG_SUBREG_P (operand))
389*38fd1498Szrj 	continue;
390*38fd1498Szrj       if ((n = ira_get_dup_out_num (i, alts)) >= 0)
391*38fd1498Szrj 	{
392*38fd1498Szrj 	  bound_p[n] = true;
393*38fd1498Szrj 	  dup = recog_data.operand[n];
394*38fd1498Szrj 	  if (REG_SUBREG_P (dup)
395*38fd1498Szrj 	      && find_reg_note (insn, REG_DEAD,
396*38fd1498Szrj 				REG_P (operand)
397*38fd1498Szrj 				? operand
398*38fd1498Szrj 				: SUBREG_REG (operand)) != NULL_RTX)
399*38fd1498Szrj 	    process_regs_for_copy (operand, dup, true, NULL,
400*38fd1498Szrj 				   freq);
401*38fd1498Szrj 	}
402*38fd1498Szrj     }
403*38fd1498Szrj   for (i = 0; i < recog_data.n_operands; i++)
404*38fd1498Szrj     {
405*38fd1498Szrj       operand = recog_data.operand[i];
406*38fd1498Szrj       if (REG_SUBREG_P (operand)
407*38fd1498Szrj 	  && find_reg_note (insn, REG_DEAD,
408*38fd1498Szrj 			    REG_P (operand)
409*38fd1498Szrj 			    ? operand : SUBREG_REG (operand)) != NULL_RTX)
410*38fd1498Szrj 	/* If an operand dies, prefer its hard register for the output
411*38fd1498Szrj 	   operands by decreasing the hard register cost or creating
412*38fd1498Szrj 	   the corresponding allocno copies.  The cost will not
413*38fd1498Szrj 	   correspond to a real move insn cost, so make the frequency
414*38fd1498Szrj 	   smaller.  */
415*38fd1498Szrj 	process_reg_shuffles (operand, i, freq < 8 ? 1 : freq / 8, bound_p);
416*38fd1498Szrj     }
417*38fd1498Szrj }
418*38fd1498Szrj 
419*38fd1498Szrj /* Add copies originated from BB given by LOOP_TREE_NODE.  */
420*38fd1498Szrj static void
add_copies(ira_loop_tree_node_t loop_tree_node)421*38fd1498Szrj add_copies (ira_loop_tree_node_t loop_tree_node)
422*38fd1498Szrj {
423*38fd1498Szrj   basic_block bb;
424*38fd1498Szrj   rtx_insn *insn;
425*38fd1498Szrj 
426*38fd1498Szrj   bb = loop_tree_node->bb;
427*38fd1498Szrj   if (bb == NULL)
428*38fd1498Szrj     return;
429*38fd1498Szrj   FOR_BB_INSNS (bb, insn)
430*38fd1498Szrj     if (NONDEBUG_INSN_P (insn))
431*38fd1498Szrj       add_insn_allocno_copies (insn);
432*38fd1498Szrj }
433*38fd1498Szrj 
434*38fd1498Szrj /* Propagate copies the corresponding allocnos on upper loop tree
435*38fd1498Szrj    level.  */
436*38fd1498Szrj static void
propagate_copies(void)437*38fd1498Szrj propagate_copies (void)
438*38fd1498Szrj {
439*38fd1498Szrj   ira_copy_t cp;
440*38fd1498Szrj   ira_copy_iterator ci;
441*38fd1498Szrj   ira_allocno_t a1, a2, parent_a1, parent_a2;
442*38fd1498Szrj 
443*38fd1498Szrj   FOR_EACH_COPY (cp, ci)
444*38fd1498Szrj     {
445*38fd1498Szrj       a1 = cp->first;
446*38fd1498Szrj       a2 = cp->second;
447*38fd1498Szrj       if (ALLOCNO_LOOP_TREE_NODE (a1) == ira_loop_tree_root)
448*38fd1498Szrj 	continue;
449*38fd1498Szrj       ira_assert ((ALLOCNO_LOOP_TREE_NODE (a2) != ira_loop_tree_root));
450*38fd1498Szrj       parent_a1 = ira_parent_or_cap_allocno (a1);
451*38fd1498Szrj       parent_a2 = ira_parent_or_cap_allocno (a2);
452*38fd1498Szrj       ira_assert (parent_a1 != NULL && parent_a2 != NULL);
453*38fd1498Szrj       if (! allocnos_conflict_for_copy_p (parent_a1, parent_a2))
454*38fd1498Szrj 	ira_add_allocno_copy (parent_a1, parent_a2, cp->freq,
455*38fd1498Szrj 			      cp->constraint_p, cp->insn, cp->loop_tree_node);
456*38fd1498Szrj     }
457*38fd1498Szrj }
458*38fd1498Szrj 
459*38fd1498Szrj /* Array used to collect all conflict allocnos for given allocno.  */
460*38fd1498Szrj static ira_object_t *collected_conflict_objects;
461*38fd1498Szrj 
462*38fd1498Szrj /* Build conflict vectors or bit conflict vectors (whatever is more
463*38fd1498Szrj    profitable) for object OBJ from the conflict table.  */
464*38fd1498Szrj static void
build_object_conflicts(ira_object_t obj)465*38fd1498Szrj build_object_conflicts (ira_object_t obj)
466*38fd1498Szrj {
467*38fd1498Szrj   int i, px, parent_num;
468*38fd1498Szrj   ira_allocno_t parent_a, another_parent_a;
469*38fd1498Szrj   ira_object_t parent_obj;
470*38fd1498Szrj   ira_allocno_t a = OBJECT_ALLOCNO (obj);
471*38fd1498Szrj   IRA_INT_TYPE *object_conflicts;
472*38fd1498Szrj   minmax_set_iterator asi;
473*38fd1498Szrj   int parent_min, parent_max ATTRIBUTE_UNUSED;
474*38fd1498Szrj 
475*38fd1498Szrj   object_conflicts = conflicts[OBJECT_CONFLICT_ID (obj)];
476*38fd1498Szrj   px = 0;
477*38fd1498Szrj   FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
478*38fd1498Szrj 			      OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
479*38fd1498Szrj     {
480*38fd1498Szrj       ira_object_t another_obj = ira_object_id_map[i];
481*38fd1498Szrj       ira_allocno_t another_a = OBJECT_ALLOCNO (obj);
482*38fd1498Szrj 
483*38fd1498Szrj       ira_assert (ira_reg_classes_intersect_p
484*38fd1498Szrj 		  [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
485*38fd1498Szrj       collected_conflict_objects[px++] = another_obj;
486*38fd1498Szrj     }
487*38fd1498Szrj   if (ira_conflict_vector_profitable_p (obj, px))
488*38fd1498Szrj     {
489*38fd1498Szrj       ira_object_t *vec;
490*38fd1498Szrj       ira_allocate_conflict_vec (obj, px);
491*38fd1498Szrj       vec = OBJECT_CONFLICT_VEC (obj);
492*38fd1498Szrj       memcpy (vec, collected_conflict_objects, sizeof (ira_object_t) * px);
493*38fd1498Szrj       vec[px] = NULL;
494*38fd1498Szrj       OBJECT_NUM_CONFLICTS (obj) = px;
495*38fd1498Szrj     }
496*38fd1498Szrj   else
497*38fd1498Szrj     {
498*38fd1498Szrj       int conflict_bit_vec_words_num;
499*38fd1498Szrj 
500*38fd1498Szrj       OBJECT_CONFLICT_ARRAY (obj) = object_conflicts;
501*38fd1498Szrj       if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
502*38fd1498Szrj 	conflict_bit_vec_words_num = 0;
503*38fd1498Szrj       else
504*38fd1498Szrj 	conflict_bit_vec_words_num
505*38fd1498Szrj 	  = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
506*38fd1498Szrj 	     / IRA_INT_BITS);
507*38fd1498Szrj       OBJECT_CONFLICT_ARRAY_SIZE (obj)
508*38fd1498Szrj 	= conflict_bit_vec_words_num * sizeof (IRA_INT_TYPE);
509*38fd1498Szrj     }
510*38fd1498Szrj 
511*38fd1498Szrj   parent_a = ira_parent_or_cap_allocno (a);
512*38fd1498Szrj   if (parent_a == NULL)
513*38fd1498Szrj     return;
514*38fd1498Szrj   ira_assert (ALLOCNO_CLASS (a) == ALLOCNO_CLASS (parent_a));
515*38fd1498Szrj   ira_assert (ALLOCNO_NUM_OBJECTS (a) == ALLOCNO_NUM_OBJECTS (parent_a));
516*38fd1498Szrj   parent_obj = ALLOCNO_OBJECT (parent_a, OBJECT_SUBWORD (obj));
517*38fd1498Szrj   parent_num = OBJECT_CONFLICT_ID (parent_obj);
518*38fd1498Szrj   parent_min = OBJECT_MIN (parent_obj);
519*38fd1498Szrj   parent_max = OBJECT_MAX (parent_obj);
520*38fd1498Szrj   FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
521*38fd1498Szrj 			      OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
522*38fd1498Szrj     {
523*38fd1498Szrj       ira_object_t another_obj = ira_object_id_map[i];
524*38fd1498Szrj       ira_allocno_t another_a = OBJECT_ALLOCNO (another_obj);
525*38fd1498Szrj       int another_word = OBJECT_SUBWORD (another_obj);
526*38fd1498Szrj 
527*38fd1498Szrj       ira_assert (ira_reg_classes_intersect_p
528*38fd1498Szrj 		  [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
529*38fd1498Szrj 
530*38fd1498Szrj       another_parent_a = ira_parent_or_cap_allocno (another_a);
531*38fd1498Szrj       if (another_parent_a == NULL)
532*38fd1498Szrj 	continue;
533*38fd1498Szrj       ira_assert (ALLOCNO_NUM (another_parent_a) >= 0);
534*38fd1498Szrj       ira_assert (ALLOCNO_CLASS (another_a)
535*38fd1498Szrj 		  == ALLOCNO_CLASS (another_parent_a));
536*38fd1498Szrj       ira_assert (ALLOCNO_NUM_OBJECTS (another_a)
537*38fd1498Szrj 		  == ALLOCNO_NUM_OBJECTS (another_parent_a));
538*38fd1498Szrj       SET_MINMAX_SET_BIT (conflicts[parent_num],
539*38fd1498Szrj 			  OBJECT_CONFLICT_ID (ALLOCNO_OBJECT (another_parent_a,
540*38fd1498Szrj 							      another_word)),
541*38fd1498Szrj 			  parent_min, parent_max);
542*38fd1498Szrj     }
543*38fd1498Szrj }
544*38fd1498Szrj 
545*38fd1498Szrj /* Build conflict vectors or bit conflict vectors (whatever is more
546*38fd1498Szrj    profitable) of all allocnos from the conflict table.  */
547*38fd1498Szrj static void
build_conflicts(void)548*38fd1498Szrj build_conflicts (void)
549*38fd1498Szrj {
550*38fd1498Szrj   int i;
551*38fd1498Szrj   ira_allocno_t a, cap;
552*38fd1498Szrj 
553*38fd1498Szrj   collected_conflict_objects
554*38fd1498Szrj     = (ira_object_t *) ira_allocate (sizeof (ira_object_t)
555*38fd1498Szrj 					  * ira_objects_num);
556*38fd1498Szrj   for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
557*38fd1498Szrj     for (a = ira_regno_allocno_map[i];
558*38fd1498Szrj 	 a != NULL;
559*38fd1498Szrj 	 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
560*38fd1498Szrj       {
561*38fd1498Szrj 	int j, nregs = ALLOCNO_NUM_OBJECTS (a);
562*38fd1498Szrj 	for (j = 0; j < nregs; j++)
563*38fd1498Szrj 	  {
564*38fd1498Szrj 	    ira_object_t obj = ALLOCNO_OBJECT (a, j);
565*38fd1498Szrj 	    build_object_conflicts (obj);
566*38fd1498Szrj 	    for (cap = ALLOCNO_CAP (a); cap != NULL; cap = ALLOCNO_CAP (cap))
567*38fd1498Szrj 	      {
568*38fd1498Szrj 		ira_object_t cap_obj = ALLOCNO_OBJECT (cap, j);
569*38fd1498Szrj 		gcc_assert (ALLOCNO_NUM_OBJECTS (cap) == ALLOCNO_NUM_OBJECTS (a));
570*38fd1498Szrj 		build_object_conflicts (cap_obj);
571*38fd1498Szrj 	      }
572*38fd1498Szrj 	  }
573*38fd1498Szrj       }
574*38fd1498Szrj   ira_free (collected_conflict_objects);
575*38fd1498Szrj }
576*38fd1498Szrj 
577*38fd1498Szrj 
578*38fd1498Szrj 
579*38fd1498Szrj /* Print hard reg set SET with TITLE to FILE.  */
580*38fd1498Szrj static void
print_hard_reg_set(FILE * file,const char * title,HARD_REG_SET set)581*38fd1498Szrj print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set)
582*38fd1498Szrj {
583*38fd1498Szrj   int i, start;
584*38fd1498Szrj 
585*38fd1498Szrj   fputs (title, file);
586*38fd1498Szrj   for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
587*38fd1498Szrj     {
588*38fd1498Szrj       if (TEST_HARD_REG_BIT (set, i))
589*38fd1498Szrj 	{
590*38fd1498Szrj 	  if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
591*38fd1498Szrj 	    start = i;
592*38fd1498Szrj 	}
593*38fd1498Szrj       if (start >= 0
594*38fd1498Szrj 	  && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
595*38fd1498Szrj 	{
596*38fd1498Szrj 	  if (start == i - 1)
597*38fd1498Szrj 	    fprintf (file, " %d", start);
598*38fd1498Szrj 	  else if (start == i - 2)
599*38fd1498Szrj 	    fprintf (file, " %d %d", start, start + 1);
600*38fd1498Szrj 	  else
601*38fd1498Szrj 	    fprintf (file, " %d-%d", start, i - 1);
602*38fd1498Szrj 	  start = -1;
603*38fd1498Szrj 	}
604*38fd1498Szrj     }
605*38fd1498Szrj   putc ('\n', file);
606*38fd1498Szrj }
607*38fd1498Szrj 
608*38fd1498Szrj static void
print_allocno_conflicts(FILE * file,bool reg_p,ira_allocno_t a)609*38fd1498Szrj print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
610*38fd1498Szrj {
611*38fd1498Szrj   HARD_REG_SET conflicting_hard_regs;
612*38fd1498Szrj   basic_block bb;
613*38fd1498Szrj   int n, i;
614*38fd1498Szrj 
615*38fd1498Szrj   if (reg_p)
616*38fd1498Szrj     fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
617*38fd1498Szrj   else
618*38fd1498Szrj     {
619*38fd1498Szrj       fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
620*38fd1498Szrj       if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
621*38fd1498Szrj         fprintf (file, "b%d", bb->index);
622*38fd1498Szrj       else
623*38fd1498Szrj         fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
624*38fd1498Szrj       putc (')', file);
625*38fd1498Szrj     }
626*38fd1498Szrj 
627*38fd1498Szrj   fputs (" conflicts:", file);
628*38fd1498Szrj   n = ALLOCNO_NUM_OBJECTS (a);
629*38fd1498Szrj   for (i = 0; i < n; i++)
630*38fd1498Szrj     {
631*38fd1498Szrj       ira_object_t obj = ALLOCNO_OBJECT (a, i);
632*38fd1498Szrj       ira_object_t conflict_obj;
633*38fd1498Szrj       ira_object_conflict_iterator oci;
634*38fd1498Szrj 
635*38fd1498Szrj       if (OBJECT_CONFLICT_ARRAY (obj) == NULL)
636*38fd1498Szrj 	continue;
637*38fd1498Szrj       if (n > 1)
638*38fd1498Szrj 	fprintf (file, "\n;;   subobject %d:", i);
639*38fd1498Szrj       FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
640*38fd1498Szrj 	{
641*38fd1498Szrj 	  ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
642*38fd1498Szrj 	  if (reg_p)
643*38fd1498Szrj 	    fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
644*38fd1498Szrj 	  else
645*38fd1498Szrj 	    {
646*38fd1498Szrj 	      fprintf (file, " a%d(r%d", ALLOCNO_NUM (conflict_a),
647*38fd1498Szrj 		       ALLOCNO_REGNO (conflict_a));
648*38fd1498Szrj 	      if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
649*38fd1498Szrj 		fprintf (file, ",w%d", OBJECT_SUBWORD (conflict_obj));
650*38fd1498Szrj 	      if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
651*38fd1498Szrj 		fprintf (file, ",b%d", bb->index);
652*38fd1498Szrj 	      else
653*38fd1498Szrj 		fprintf (file, ",l%d",
654*38fd1498Szrj 			 ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num);
655*38fd1498Szrj 	      putc (')', file);
656*38fd1498Szrj 	    }
657*38fd1498Szrj 	}
658*38fd1498Szrj       COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
659*38fd1498Szrj       AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
660*38fd1498Szrj       AND_HARD_REG_SET (conflicting_hard_regs,
661*38fd1498Szrj 			reg_class_contents[ALLOCNO_CLASS (a)]);
662*38fd1498Szrj       print_hard_reg_set (file, "\n;;     total conflict hard regs:",
663*38fd1498Szrj 			  conflicting_hard_regs);
664*38fd1498Szrj 
665*38fd1498Szrj       COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_CONFLICT_HARD_REGS (obj));
666*38fd1498Szrj       AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
667*38fd1498Szrj       AND_HARD_REG_SET (conflicting_hard_regs,
668*38fd1498Szrj 			reg_class_contents[ALLOCNO_CLASS (a)]);
669*38fd1498Szrj       print_hard_reg_set (file, ";;     conflict hard regs:",
670*38fd1498Szrj 			  conflicting_hard_regs);
671*38fd1498Szrj       putc ('\n', file);
672*38fd1498Szrj     }
673*38fd1498Szrj 
674*38fd1498Szrj }
675*38fd1498Szrj 
676*38fd1498Szrj /* Print information about allocno or only regno (if REG_P) conflicts
677*38fd1498Szrj    to FILE.  */
678*38fd1498Szrj static void
print_conflicts(FILE * file,bool reg_p)679*38fd1498Szrj print_conflicts (FILE *file, bool reg_p)
680*38fd1498Szrj {
681*38fd1498Szrj   ira_allocno_t a;
682*38fd1498Szrj   ira_allocno_iterator ai;
683*38fd1498Szrj 
684*38fd1498Szrj   FOR_EACH_ALLOCNO (a, ai)
685*38fd1498Szrj     print_allocno_conflicts (file, reg_p, a);
686*38fd1498Szrj }
687*38fd1498Szrj 
688*38fd1498Szrj /* Print information about allocno or only regno (if REG_P) conflicts
689*38fd1498Szrj    to stderr.  */
690*38fd1498Szrj void
ira_debug_conflicts(bool reg_p)691*38fd1498Szrj ira_debug_conflicts (bool reg_p)
692*38fd1498Szrj {
693*38fd1498Szrj   print_conflicts (stderr, reg_p);
694*38fd1498Szrj }
695*38fd1498Szrj 
696*38fd1498Szrj 
697*38fd1498Szrj 
698*38fd1498Szrj /* Entry function which builds allocno conflicts and allocno copies
699*38fd1498Szrj    and accumulate some allocno info on upper level regions.  */
700*38fd1498Szrj void
ira_build_conflicts(void)701*38fd1498Szrj ira_build_conflicts (void)
702*38fd1498Szrj {
703*38fd1498Szrj   enum reg_class base;
704*38fd1498Szrj   ira_allocno_t a;
705*38fd1498Szrj   ira_allocno_iterator ai;
706*38fd1498Szrj   HARD_REG_SET temp_hard_reg_set;
707*38fd1498Szrj 
708*38fd1498Szrj   if (ira_conflicts_p)
709*38fd1498Szrj     {
710*38fd1498Szrj       ira_conflicts_p = build_conflict_bit_table ();
711*38fd1498Szrj       if (ira_conflicts_p)
712*38fd1498Szrj 	{
713*38fd1498Szrj 	  ira_object_t obj;
714*38fd1498Szrj 	  ira_object_iterator oi;
715*38fd1498Szrj 
716*38fd1498Szrj 	  build_conflicts ();
717*38fd1498Szrj 	  ira_traverse_loop_tree (true, ira_loop_tree_root, add_copies, NULL);
718*38fd1498Szrj 	  /* We need finished conflict table for the subsequent call.  */
719*38fd1498Szrj 	  if (flag_ira_region == IRA_REGION_ALL
720*38fd1498Szrj 	      || flag_ira_region == IRA_REGION_MIXED)
721*38fd1498Szrj 	    propagate_copies ();
722*38fd1498Szrj 
723*38fd1498Szrj 	  /* Now we can free memory for the conflict table (see function
724*38fd1498Szrj 	     build_object_conflicts for details).  */
725*38fd1498Szrj 	  FOR_EACH_OBJECT (obj, oi)
726*38fd1498Szrj 	    {
727*38fd1498Szrj 	      if (OBJECT_CONFLICT_ARRAY (obj) != conflicts[OBJECT_CONFLICT_ID (obj)])
728*38fd1498Szrj 		ira_free (conflicts[OBJECT_CONFLICT_ID (obj)]);
729*38fd1498Szrj 	    }
730*38fd1498Szrj 	  ira_free (conflicts);
731*38fd1498Szrj 	}
732*38fd1498Szrj     }
733*38fd1498Szrj   base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH);
734*38fd1498Szrj   if (! targetm.class_likely_spilled_p (base))
735*38fd1498Szrj     CLEAR_HARD_REG_SET (temp_hard_reg_set);
736*38fd1498Szrj   else
737*38fd1498Szrj     {
738*38fd1498Szrj       COPY_HARD_REG_SET (temp_hard_reg_set, reg_class_contents[base]);
739*38fd1498Szrj       AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs);
740*38fd1498Szrj       AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set);
741*38fd1498Szrj     }
742*38fd1498Szrj   FOR_EACH_ALLOCNO (a, ai)
743*38fd1498Szrj     {
744*38fd1498Szrj       int i, n = ALLOCNO_NUM_OBJECTS (a);
745*38fd1498Szrj 
746*38fd1498Szrj       for (i = 0; i < n; i++)
747*38fd1498Szrj 	{
748*38fd1498Szrj 	  ira_object_t obj = ALLOCNO_OBJECT (a, i);
749*38fd1498Szrj 	  machine_mode obj_mode = obj->allocno->mode;
750*38fd1498Szrj 	  rtx allocno_reg = regno_reg_rtx [ALLOCNO_REGNO (a)];
751*38fd1498Szrj 
752*38fd1498Szrj 	  if ((! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
753*38fd1498Szrj 	      /* For debugging purposes don't put user defined variables in
754*38fd1498Szrj 		 callee-clobbered registers.  However, do allow parameters
755*38fd1498Szrj 		 in callee-clobbered registers to improve debugging.  This
756*38fd1498Szrj 		 is a bit of a fragile hack.  */
757*38fd1498Szrj 	      || (optimize == 0
758*38fd1498Szrj 		  && REG_USERVAR_P (allocno_reg)
759*38fd1498Szrj 		  && ! reg_is_parm_p (allocno_reg)))
760*38fd1498Szrj 	    {
761*38fd1498Szrj 	      IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
762*38fd1498Szrj 				call_used_reg_set);
763*38fd1498Szrj 	      IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
764*38fd1498Szrj 				call_used_reg_set);
765*38fd1498Szrj 	    }
766*38fd1498Szrj 	  else if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
767*38fd1498Szrj 	    {
768*38fd1498Szrj 	      IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
769*38fd1498Szrj 				no_caller_save_reg_set);
770*38fd1498Szrj 	      IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
771*38fd1498Szrj 				temp_hard_reg_set);
772*38fd1498Szrj 	      IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
773*38fd1498Szrj 				no_caller_save_reg_set);
774*38fd1498Szrj 	      IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
775*38fd1498Szrj 				temp_hard_reg_set);
776*38fd1498Szrj 	    }
777*38fd1498Szrj 
778*38fd1498Szrj 	  /* Now we deal with paradoxical subreg cases where certain registers
779*38fd1498Szrj 	     cannot be accessed in the widest mode.  */
780*38fd1498Szrj 	  machine_mode outer_mode = ALLOCNO_WMODE (a);
781*38fd1498Szrj 	  machine_mode inner_mode = ALLOCNO_MODE (a);
782*38fd1498Szrj 	  if (paradoxical_subreg_p (outer_mode, inner_mode))
783*38fd1498Szrj 	    {
784*38fd1498Szrj 	      enum reg_class aclass = ALLOCNO_CLASS (a);
785*38fd1498Szrj 	      for (int j = ira_class_hard_regs_num[aclass] - 1; j >= 0; --j)
786*38fd1498Szrj 		{
787*38fd1498Szrj 		   int inner_regno = ira_class_hard_regs[aclass][j];
788*38fd1498Szrj 		   int outer_regno = simplify_subreg_regno (inner_regno,
789*38fd1498Szrj 							    inner_mode, 0,
790*38fd1498Szrj 							    outer_mode);
791*38fd1498Szrj 		   if (outer_regno < 0
792*38fd1498Szrj 		       || !in_hard_reg_set_p (reg_class_contents[aclass],
793*38fd1498Szrj 					      outer_mode, outer_regno))
794*38fd1498Szrj 		     {
795*38fd1498Szrj 		       SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
796*38fd1498Szrj 					 inner_regno);
797*38fd1498Szrj 		       SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj),
798*38fd1498Szrj 					 inner_regno);
799*38fd1498Szrj 		     }
800*38fd1498Szrj 		}
801*38fd1498Szrj 	    }
802*38fd1498Szrj 
803*38fd1498Szrj 	  if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
804*38fd1498Szrj 	    {
805*38fd1498Szrj 	      int regno;
806*38fd1498Szrj 
807*38fd1498Szrj 	      /* Allocnos bigger than the saved part of call saved
808*38fd1498Szrj 		 regs must conflict with them.  */
809*38fd1498Szrj 	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
810*38fd1498Szrj 		if (!TEST_HARD_REG_BIT (call_used_reg_set, regno)
811*38fd1498Szrj 		    && targetm.hard_regno_call_part_clobbered (regno,
812*38fd1498Szrj 							       obj_mode))
813*38fd1498Szrj 		  {
814*38fd1498Szrj 		    SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno);
815*38fd1498Szrj 		    SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
816*38fd1498Szrj 				      regno);
817*38fd1498Szrj 		  }
818*38fd1498Szrj 	    }
819*38fd1498Szrj 	}
820*38fd1498Szrj     }
821*38fd1498Szrj   if (optimize && ira_conflicts_p
822*38fd1498Szrj       && internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
823*38fd1498Szrj     print_conflicts (ira_dump_file, false);
824*38fd1498Szrj }
825