xref: /dflybsd-src/contrib/gcc-4.7/gcc/sched-deps.c (revision e4b17023d31ea40e02fa06b141db27753ecc6934)
1*e4b17023SJohn Marino /* Instruction scheduling pass.  This file computes dependencies between
2*e4b17023SJohn Marino    instructions.
3*e4b17023SJohn Marino    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4*e4b17023SJohn Marino    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
5*e4b17023SJohn Marino    2011, 2012
6*e4b17023SJohn Marino    Free Software Foundation, Inc.
7*e4b17023SJohn Marino    Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
8*e4b17023SJohn Marino    and currently maintained by, Jim Wilson (wilson@cygnus.com)
9*e4b17023SJohn Marino 
10*e4b17023SJohn Marino This file is part of GCC.
11*e4b17023SJohn Marino 
12*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
13*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
14*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
15*e4b17023SJohn Marino version.
16*e4b17023SJohn Marino 
17*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
19*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20*e4b17023SJohn Marino for more details.
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
23*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
24*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
25*e4b17023SJohn Marino 
26*e4b17023SJohn Marino #include "config.h"
27*e4b17023SJohn Marino #include "system.h"
28*e4b17023SJohn Marino #include "coretypes.h"
29*e4b17023SJohn Marino #include "tm.h"
30*e4b17023SJohn Marino #include "diagnostic-core.h"
31*e4b17023SJohn Marino #include "rtl.h"
32*e4b17023SJohn Marino #include "tm_p.h"
33*e4b17023SJohn Marino #include "hard-reg-set.h"
34*e4b17023SJohn Marino #include "regs.h"
35*e4b17023SJohn Marino #include "function.h"
36*e4b17023SJohn Marino #include "flags.h"
37*e4b17023SJohn Marino #include "insn-config.h"
38*e4b17023SJohn Marino #include "insn-attr.h"
39*e4b17023SJohn Marino #include "except.h"
40*e4b17023SJohn Marino #include "recog.h"
41*e4b17023SJohn Marino #include "sched-int.h"
42*e4b17023SJohn Marino #include "params.h"
43*e4b17023SJohn Marino #include "cselib.h"
44*e4b17023SJohn Marino #include "ira.h"
45*e4b17023SJohn Marino #include "target.h"
46*e4b17023SJohn Marino 
47*e4b17023SJohn Marino #ifdef INSN_SCHEDULING
48*e4b17023SJohn Marino 
49*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
50*e4b17023SJohn Marino #define CHECK (true)
51*e4b17023SJohn Marino #else
52*e4b17023SJohn Marino #define CHECK (false)
53*e4b17023SJohn Marino #endif
54*e4b17023SJohn Marino 
55*e4b17023SJohn Marino /* Holds current parameters for the dependency analyzer.  */
56*e4b17023SJohn Marino struct sched_deps_info_def *sched_deps_info;
57*e4b17023SJohn Marino 
58*e4b17023SJohn Marino /* The data is specific to the Haifa scheduler.  */
59*e4b17023SJohn Marino VEC(haifa_deps_insn_data_def, heap) *h_d_i_d = NULL;
60*e4b17023SJohn Marino 
61*e4b17023SJohn Marino /* Return the major type present in the DS.  */
62*e4b17023SJohn Marino enum reg_note
63*e4b17023SJohn Marino ds_to_dk (ds_t ds)
64*e4b17023SJohn Marino {
65*e4b17023SJohn Marino   if (ds & DEP_TRUE)
66*e4b17023SJohn Marino     return REG_DEP_TRUE;
67*e4b17023SJohn Marino 
68*e4b17023SJohn Marino   if (ds & DEP_OUTPUT)
69*e4b17023SJohn Marino     return REG_DEP_OUTPUT;
70*e4b17023SJohn Marino 
71*e4b17023SJohn Marino   if (ds & DEP_CONTROL)
72*e4b17023SJohn Marino     return REG_DEP_CONTROL;
73*e4b17023SJohn Marino 
74*e4b17023SJohn Marino   gcc_assert (ds & DEP_ANTI);
75*e4b17023SJohn Marino 
76*e4b17023SJohn Marino   return REG_DEP_ANTI;
77*e4b17023SJohn Marino }
78*e4b17023SJohn Marino 
79*e4b17023SJohn Marino /* Return equivalent dep_status.  */
80*e4b17023SJohn Marino ds_t
81*e4b17023SJohn Marino dk_to_ds (enum reg_note dk)
82*e4b17023SJohn Marino {
83*e4b17023SJohn Marino   switch (dk)
84*e4b17023SJohn Marino     {
85*e4b17023SJohn Marino     case REG_DEP_TRUE:
86*e4b17023SJohn Marino       return DEP_TRUE;
87*e4b17023SJohn Marino 
88*e4b17023SJohn Marino     case REG_DEP_OUTPUT:
89*e4b17023SJohn Marino       return DEP_OUTPUT;
90*e4b17023SJohn Marino 
91*e4b17023SJohn Marino     case REG_DEP_CONTROL:
92*e4b17023SJohn Marino       return DEP_CONTROL;
93*e4b17023SJohn Marino 
94*e4b17023SJohn Marino     default:
95*e4b17023SJohn Marino       gcc_assert (dk == REG_DEP_ANTI);
96*e4b17023SJohn Marino       return DEP_ANTI;
97*e4b17023SJohn Marino     }
98*e4b17023SJohn Marino }
99*e4b17023SJohn Marino 
100*e4b17023SJohn Marino /* Functions to operate with dependence information container - dep_t.  */
101*e4b17023SJohn Marino 
102*e4b17023SJohn Marino /* Init DEP with the arguments.  */
103*e4b17023SJohn Marino void
104*e4b17023SJohn Marino init_dep_1 (dep_t dep, rtx pro, rtx con, enum reg_note type, ds_t ds)
105*e4b17023SJohn Marino {
106*e4b17023SJohn Marino   DEP_PRO (dep) = pro;
107*e4b17023SJohn Marino   DEP_CON (dep) = con;
108*e4b17023SJohn Marino   DEP_TYPE (dep) = type;
109*e4b17023SJohn Marino   DEP_STATUS (dep) = ds;
110*e4b17023SJohn Marino   DEP_COST (dep) = UNKNOWN_DEP_COST;
111*e4b17023SJohn Marino }
112*e4b17023SJohn Marino 
113*e4b17023SJohn Marino /* Init DEP with the arguments.
114*e4b17023SJohn Marino    While most of the scheduler (including targets) only need the major type
115*e4b17023SJohn Marino    of the dependency, it is convenient to hide full dep_status from them.  */
116*e4b17023SJohn Marino void
117*e4b17023SJohn Marino init_dep (dep_t dep, rtx pro, rtx con, enum reg_note kind)
118*e4b17023SJohn Marino {
119*e4b17023SJohn Marino   ds_t ds;
120*e4b17023SJohn Marino 
121*e4b17023SJohn Marino   if ((current_sched_info->flags & USE_DEPS_LIST))
122*e4b17023SJohn Marino     ds = dk_to_ds (kind);
123*e4b17023SJohn Marino   else
124*e4b17023SJohn Marino     ds = 0;
125*e4b17023SJohn Marino 
126*e4b17023SJohn Marino   init_dep_1 (dep, pro, con, kind, ds);
127*e4b17023SJohn Marino }
128*e4b17023SJohn Marino 
129*e4b17023SJohn Marino /* Make a copy of FROM in TO.  */
130*e4b17023SJohn Marino static void
131*e4b17023SJohn Marino copy_dep (dep_t to, dep_t from)
132*e4b17023SJohn Marino {
133*e4b17023SJohn Marino   memcpy (to, from, sizeof (*to));
134*e4b17023SJohn Marino }
135*e4b17023SJohn Marino 
136*e4b17023SJohn Marino static void dump_ds (FILE *, ds_t);
137*e4b17023SJohn Marino 
138*e4b17023SJohn Marino /* Define flags for dump_dep ().  */
139*e4b17023SJohn Marino 
140*e4b17023SJohn Marino /* Dump producer of the dependence.  */
141*e4b17023SJohn Marino #define DUMP_DEP_PRO (2)
142*e4b17023SJohn Marino 
143*e4b17023SJohn Marino /* Dump consumer of the dependence.  */
144*e4b17023SJohn Marino #define DUMP_DEP_CON (4)
145*e4b17023SJohn Marino 
146*e4b17023SJohn Marino /* Dump type of the dependence.  */
147*e4b17023SJohn Marino #define DUMP_DEP_TYPE (8)
148*e4b17023SJohn Marino 
149*e4b17023SJohn Marino /* Dump status of the dependence.  */
150*e4b17023SJohn Marino #define DUMP_DEP_STATUS (16)
151*e4b17023SJohn Marino 
152*e4b17023SJohn Marino /* Dump all information about the dependence.  */
153*e4b17023SJohn Marino #define DUMP_DEP_ALL (DUMP_DEP_PRO | DUMP_DEP_CON | DUMP_DEP_TYPE	\
154*e4b17023SJohn Marino 		      |DUMP_DEP_STATUS)
155*e4b17023SJohn Marino 
156*e4b17023SJohn Marino /* Dump DEP to DUMP.
157*e4b17023SJohn Marino    FLAGS is a bit mask specifying what information about DEP needs
158*e4b17023SJohn Marino    to be printed.
159*e4b17023SJohn Marino    If FLAGS has the very first bit set, then dump all information about DEP
160*e4b17023SJohn Marino    and propagate this bit into the callee dump functions.  */
161*e4b17023SJohn Marino static void
162*e4b17023SJohn Marino dump_dep (FILE *dump, dep_t dep, int flags)
163*e4b17023SJohn Marino {
164*e4b17023SJohn Marino   if (flags & 1)
165*e4b17023SJohn Marino     flags |= DUMP_DEP_ALL;
166*e4b17023SJohn Marino 
167*e4b17023SJohn Marino   fprintf (dump, "<");
168*e4b17023SJohn Marino 
169*e4b17023SJohn Marino   if (flags & DUMP_DEP_PRO)
170*e4b17023SJohn Marino     fprintf (dump, "%d; ", INSN_UID (DEP_PRO (dep)));
171*e4b17023SJohn Marino 
172*e4b17023SJohn Marino   if (flags & DUMP_DEP_CON)
173*e4b17023SJohn Marino     fprintf (dump, "%d; ", INSN_UID (DEP_CON (dep)));
174*e4b17023SJohn Marino 
175*e4b17023SJohn Marino   if (flags & DUMP_DEP_TYPE)
176*e4b17023SJohn Marino     {
177*e4b17023SJohn Marino       char t;
178*e4b17023SJohn Marino       enum reg_note type = DEP_TYPE (dep);
179*e4b17023SJohn Marino 
180*e4b17023SJohn Marino       switch (type)
181*e4b17023SJohn Marino 	{
182*e4b17023SJohn Marino 	case REG_DEP_TRUE:
183*e4b17023SJohn Marino 	  t = 't';
184*e4b17023SJohn Marino 	  break;
185*e4b17023SJohn Marino 
186*e4b17023SJohn Marino 	case REG_DEP_OUTPUT:
187*e4b17023SJohn Marino 	  t = 'o';
188*e4b17023SJohn Marino 	  break;
189*e4b17023SJohn Marino 
190*e4b17023SJohn Marino 	case REG_DEP_CONTROL:
191*e4b17023SJohn Marino 	  t = 'c';
192*e4b17023SJohn Marino 	  break;
193*e4b17023SJohn Marino 
194*e4b17023SJohn Marino 	case REG_DEP_ANTI:
195*e4b17023SJohn Marino 	  t = 'a';
196*e4b17023SJohn Marino 	  break;
197*e4b17023SJohn Marino 
198*e4b17023SJohn Marino 	default:
199*e4b17023SJohn Marino 	  gcc_unreachable ();
200*e4b17023SJohn Marino 	  break;
201*e4b17023SJohn Marino 	}
202*e4b17023SJohn Marino 
203*e4b17023SJohn Marino       fprintf (dump, "%c; ", t);
204*e4b17023SJohn Marino     }
205*e4b17023SJohn Marino 
206*e4b17023SJohn Marino   if (flags & DUMP_DEP_STATUS)
207*e4b17023SJohn Marino     {
208*e4b17023SJohn Marino       if (current_sched_info->flags & USE_DEPS_LIST)
209*e4b17023SJohn Marino 	dump_ds (dump, DEP_STATUS (dep));
210*e4b17023SJohn Marino     }
211*e4b17023SJohn Marino 
212*e4b17023SJohn Marino   fprintf (dump, ">");
213*e4b17023SJohn Marino }
214*e4b17023SJohn Marino 
215*e4b17023SJohn Marino /* Default flags for dump_dep ().  */
216*e4b17023SJohn Marino static int dump_dep_flags = (DUMP_DEP_PRO | DUMP_DEP_CON);
217*e4b17023SJohn Marino 
218*e4b17023SJohn Marino /* Dump all fields of DEP to STDERR.  */
219*e4b17023SJohn Marino void
220*e4b17023SJohn Marino sd_debug_dep (dep_t dep)
221*e4b17023SJohn Marino {
222*e4b17023SJohn Marino   dump_dep (stderr, dep, 1);
223*e4b17023SJohn Marino   fprintf (stderr, "\n");
224*e4b17023SJohn Marino }
225*e4b17023SJohn Marino 
226*e4b17023SJohn Marino /* Determine whether DEP is a dependency link of a non-debug insn on a
227*e4b17023SJohn Marino    debug insn.  */
228*e4b17023SJohn Marino 
229*e4b17023SJohn Marino static inline bool
230*e4b17023SJohn Marino depl_on_debug_p (dep_link_t dep)
231*e4b17023SJohn Marino {
232*e4b17023SJohn Marino   return (DEBUG_INSN_P (DEP_LINK_PRO (dep))
233*e4b17023SJohn Marino 	  && !DEBUG_INSN_P (DEP_LINK_CON (dep)));
234*e4b17023SJohn Marino }
235*e4b17023SJohn Marino 
236*e4b17023SJohn Marino /* Functions to operate with a single link from the dependencies lists -
237*e4b17023SJohn Marino    dep_link_t.  */
238*e4b17023SJohn Marino 
239*e4b17023SJohn Marino /* Attach L to appear after link X whose &DEP_LINK_NEXT (X) is given by
240*e4b17023SJohn Marino    PREV_NEXT_P.  */
241*e4b17023SJohn Marino static void
242*e4b17023SJohn Marino attach_dep_link (dep_link_t l, dep_link_t *prev_nextp)
243*e4b17023SJohn Marino {
244*e4b17023SJohn Marino   dep_link_t next = *prev_nextp;
245*e4b17023SJohn Marino 
246*e4b17023SJohn Marino   gcc_assert (DEP_LINK_PREV_NEXTP (l) == NULL
247*e4b17023SJohn Marino 	      && DEP_LINK_NEXT (l) == NULL);
248*e4b17023SJohn Marino 
249*e4b17023SJohn Marino   /* Init node being inserted.  */
250*e4b17023SJohn Marino   DEP_LINK_PREV_NEXTP (l) = prev_nextp;
251*e4b17023SJohn Marino   DEP_LINK_NEXT (l) = next;
252*e4b17023SJohn Marino 
253*e4b17023SJohn Marino   /* Fix next node.  */
254*e4b17023SJohn Marino   if (next != NULL)
255*e4b17023SJohn Marino     {
256*e4b17023SJohn Marino       gcc_assert (DEP_LINK_PREV_NEXTP (next) == prev_nextp);
257*e4b17023SJohn Marino 
258*e4b17023SJohn Marino       DEP_LINK_PREV_NEXTP (next) = &DEP_LINK_NEXT (l);
259*e4b17023SJohn Marino     }
260*e4b17023SJohn Marino 
261*e4b17023SJohn Marino   /* Fix prev node.  */
262*e4b17023SJohn Marino   *prev_nextp = l;
263*e4b17023SJohn Marino }
264*e4b17023SJohn Marino 
265*e4b17023SJohn Marino /* Add dep_link LINK to deps_list L.  */
266*e4b17023SJohn Marino static void
267*e4b17023SJohn Marino add_to_deps_list (dep_link_t link, deps_list_t l)
268*e4b17023SJohn Marino {
269*e4b17023SJohn Marino   attach_dep_link (link, &DEPS_LIST_FIRST (l));
270*e4b17023SJohn Marino 
271*e4b17023SJohn Marino   /* Don't count debug deps.  */
272*e4b17023SJohn Marino   if (!depl_on_debug_p (link))
273*e4b17023SJohn Marino     ++DEPS_LIST_N_LINKS (l);
274*e4b17023SJohn Marino }
275*e4b17023SJohn Marino 
276*e4b17023SJohn Marino /* Detach dep_link L from the list.  */
277*e4b17023SJohn Marino static void
278*e4b17023SJohn Marino detach_dep_link (dep_link_t l)
279*e4b17023SJohn Marino {
280*e4b17023SJohn Marino   dep_link_t *prev_nextp = DEP_LINK_PREV_NEXTP (l);
281*e4b17023SJohn Marino   dep_link_t next = DEP_LINK_NEXT (l);
282*e4b17023SJohn Marino 
283*e4b17023SJohn Marino   *prev_nextp = next;
284*e4b17023SJohn Marino 
285*e4b17023SJohn Marino   if (next != NULL)
286*e4b17023SJohn Marino     DEP_LINK_PREV_NEXTP (next) = prev_nextp;
287*e4b17023SJohn Marino 
288*e4b17023SJohn Marino   DEP_LINK_PREV_NEXTP (l) = NULL;
289*e4b17023SJohn Marino   DEP_LINK_NEXT (l) = NULL;
290*e4b17023SJohn Marino }
291*e4b17023SJohn Marino 
292*e4b17023SJohn Marino /* Remove link LINK from list LIST.  */
293*e4b17023SJohn Marino static void
294*e4b17023SJohn Marino remove_from_deps_list (dep_link_t link, deps_list_t list)
295*e4b17023SJohn Marino {
296*e4b17023SJohn Marino   detach_dep_link (link);
297*e4b17023SJohn Marino 
298*e4b17023SJohn Marino   /* Don't count debug deps.  */
299*e4b17023SJohn Marino   if (!depl_on_debug_p (link))
300*e4b17023SJohn Marino     --DEPS_LIST_N_LINKS (list);
301*e4b17023SJohn Marino }
302*e4b17023SJohn Marino 
303*e4b17023SJohn Marino /* Move link LINK from list FROM to list TO.  */
304*e4b17023SJohn Marino static void
305*e4b17023SJohn Marino move_dep_link (dep_link_t link, deps_list_t from, deps_list_t to)
306*e4b17023SJohn Marino {
307*e4b17023SJohn Marino   remove_from_deps_list (link, from);
308*e4b17023SJohn Marino   add_to_deps_list (link, to);
309*e4b17023SJohn Marino }
310*e4b17023SJohn Marino 
311*e4b17023SJohn Marino /* Return true of LINK is not attached to any list.  */
312*e4b17023SJohn Marino static bool
313*e4b17023SJohn Marino dep_link_is_detached_p (dep_link_t link)
314*e4b17023SJohn Marino {
315*e4b17023SJohn Marino   return DEP_LINK_PREV_NEXTP (link) == NULL;
316*e4b17023SJohn Marino }
317*e4b17023SJohn Marino 
318*e4b17023SJohn Marino /* Pool to hold all dependency nodes (dep_node_t).  */
319*e4b17023SJohn Marino static alloc_pool dn_pool;
320*e4b17023SJohn Marino 
321*e4b17023SJohn Marino /* Number of dep_nodes out there.  */
322*e4b17023SJohn Marino static int dn_pool_diff = 0;
323*e4b17023SJohn Marino 
324*e4b17023SJohn Marino /* Create a dep_node.  */
325*e4b17023SJohn Marino static dep_node_t
326*e4b17023SJohn Marino create_dep_node (void)
327*e4b17023SJohn Marino {
328*e4b17023SJohn Marino   dep_node_t n = (dep_node_t) pool_alloc (dn_pool);
329*e4b17023SJohn Marino   dep_link_t back = DEP_NODE_BACK (n);
330*e4b17023SJohn Marino   dep_link_t forw = DEP_NODE_FORW (n);
331*e4b17023SJohn Marino 
332*e4b17023SJohn Marino   DEP_LINK_NODE (back) = n;
333*e4b17023SJohn Marino   DEP_LINK_NEXT (back) = NULL;
334*e4b17023SJohn Marino   DEP_LINK_PREV_NEXTP (back) = NULL;
335*e4b17023SJohn Marino 
336*e4b17023SJohn Marino   DEP_LINK_NODE (forw) = n;
337*e4b17023SJohn Marino   DEP_LINK_NEXT (forw) = NULL;
338*e4b17023SJohn Marino   DEP_LINK_PREV_NEXTP (forw) = NULL;
339*e4b17023SJohn Marino 
340*e4b17023SJohn Marino   ++dn_pool_diff;
341*e4b17023SJohn Marino 
342*e4b17023SJohn Marino   return n;
343*e4b17023SJohn Marino }
344*e4b17023SJohn Marino 
345*e4b17023SJohn Marino /* Delete dep_node N.  N must not be connected to any deps_list.  */
346*e4b17023SJohn Marino static void
347*e4b17023SJohn Marino delete_dep_node (dep_node_t n)
348*e4b17023SJohn Marino {
349*e4b17023SJohn Marino   gcc_assert (dep_link_is_detached_p (DEP_NODE_BACK (n))
350*e4b17023SJohn Marino 	      && dep_link_is_detached_p (DEP_NODE_FORW (n)));
351*e4b17023SJohn Marino 
352*e4b17023SJohn Marino   --dn_pool_diff;
353*e4b17023SJohn Marino 
354*e4b17023SJohn Marino   pool_free (dn_pool, n);
355*e4b17023SJohn Marino }
356*e4b17023SJohn Marino 
357*e4b17023SJohn Marino /* Pool to hold dependencies lists (deps_list_t).  */
358*e4b17023SJohn Marino static alloc_pool dl_pool;
359*e4b17023SJohn Marino 
360*e4b17023SJohn Marino /* Number of deps_lists out there.  */
361*e4b17023SJohn Marino static int dl_pool_diff = 0;
362*e4b17023SJohn Marino 
363*e4b17023SJohn Marino /* Functions to operate with dependences lists - deps_list_t.  */
364*e4b17023SJohn Marino 
365*e4b17023SJohn Marino /* Return true if list L is empty.  */
366*e4b17023SJohn Marino static bool
367*e4b17023SJohn Marino deps_list_empty_p (deps_list_t l)
368*e4b17023SJohn Marino {
369*e4b17023SJohn Marino   return DEPS_LIST_N_LINKS (l) == 0;
370*e4b17023SJohn Marino }
371*e4b17023SJohn Marino 
372*e4b17023SJohn Marino /* Create a new deps_list.  */
373*e4b17023SJohn Marino static deps_list_t
374*e4b17023SJohn Marino create_deps_list (void)
375*e4b17023SJohn Marino {
376*e4b17023SJohn Marino   deps_list_t l = (deps_list_t) pool_alloc (dl_pool);
377*e4b17023SJohn Marino 
378*e4b17023SJohn Marino   DEPS_LIST_FIRST (l) = NULL;
379*e4b17023SJohn Marino   DEPS_LIST_N_LINKS (l) = 0;
380*e4b17023SJohn Marino 
381*e4b17023SJohn Marino   ++dl_pool_diff;
382*e4b17023SJohn Marino   return l;
383*e4b17023SJohn Marino }
384*e4b17023SJohn Marino 
385*e4b17023SJohn Marino /* Free deps_list L.  */
386*e4b17023SJohn Marino static void
387*e4b17023SJohn Marino free_deps_list (deps_list_t l)
388*e4b17023SJohn Marino {
389*e4b17023SJohn Marino   gcc_assert (deps_list_empty_p (l));
390*e4b17023SJohn Marino 
391*e4b17023SJohn Marino   --dl_pool_diff;
392*e4b17023SJohn Marino 
393*e4b17023SJohn Marino   pool_free (dl_pool, l);
394*e4b17023SJohn Marino }
395*e4b17023SJohn Marino 
396*e4b17023SJohn Marino /* Return true if there is no dep_nodes and deps_lists out there.
397*e4b17023SJohn Marino    After the region is scheduled all the dependency nodes and lists
398*e4b17023SJohn Marino    should [generally] be returned to pool.  */
399*e4b17023SJohn Marino bool
400*e4b17023SJohn Marino deps_pools_are_empty_p (void)
401*e4b17023SJohn Marino {
402*e4b17023SJohn Marino   return dn_pool_diff == 0 && dl_pool_diff == 0;
403*e4b17023SJohn Marino }
404*e4b17023SJohn Marino 
405*e4b17023SJohn Marino /* Remove all elements from L.  */
406*e4b17023SJohn Marino static void
407*e4b17023SJohn Marino clear_deps_list (deps_list_t l)
408*e4b17023SJohn Marino {
409*e4b17023SJohn Marino   do
410*e4b17023SJohn Marino     {
411*e4b17023SJohn Marino       dep_link_t link = DEPS_LIST_FIRST (l);
412*e4b17023SJohn Marino 
413*e4b17023SJohn Marino       if (link == NULL)
414*e4b17023SJohn Marino 	break;
415*e4b17023SJohn Marino 
416*e4b17023SJohn Marino       remove_from_deps_list (link, l);
417*e4b17023SJohn Marino     }
418*e4b17023SJohn Marino   while (1);
419*e4b17023SJohn Marino }
420*e4b17023SJohn Marino 
421*e4b17023SJohn Marino /* Decide whether a dependency should be treated as a hard or a speculative
422*e4b17023SJohn Marino    dependency.  */
423*e4b17023SJohn Marino static bool
424*e4b17023SJohn Marino dep_spec_p (dep_t dep)
425*e4b17023SJohn Marino {
426*e4b17023SJohn Marino   if (current_sched_info->flags & DO_SPECULATION)
427*e4b17023SJohn Marino     {
428*e4b17023SJohn Marino       if (DEP_STATUS (dep) & SPECULATIVE)
429*e4b17023SJohn Marino 	return true;
430*e4b17023SJohn Marino     }
431*e4b17023SJohn Marino   if (current_sched_info->flags & DO_PREDICATION)
432*e4b17023SJohn Marino     {
433*e4b17023SJohn Marino       if (DEP_TYPE (dep) == REG_DEP_CONTROL)
434*e4b17023SJohn Marino 	return true;
435*e4b17023SJohn Marino     }
436*e4b17023SJohn Marino   return false;
437*e4b17023SJohn Marino }
438*e4b17023SJohn Marino 
439*e4b17023SJohn Marino static regset reg_pending_sets;
440*e4b17023SJohn Marino static regset reg_pending_clobbers;
441*e4b17023SJohn Marino static regset reg_pending_uses;
442*e4b17023SJohn Marino static regset reg_pending_control_uses;
443*e4b17023SJohn Marino static enum reg_pending_barrier_mode reg_pending_barrier;
444*e4b17023SJohn Marino 
445*e4b17023SJohn Marino /* Hard registers implicitly clobbered or used (or may be implicitly
446*e4b17023SJohn Marino    clobbered or used) by the currently analyzed insn.  For example,
447*e4b17023SJohn Marino    insn in its constraint has one register class.  Even if there is
448*e4b17023SJohn Marino    currently no hard register in the insn, the particular hard
449*e4b17023SJohn Marino    register will be in the insn after reload pass because the
450*e4b17023SJohn Marino    constraint requires it.  */
451*e4b17023SJohn Marino static HARD_REG_SET implicit_reg_pending_clobbers;
452*e4b17023SJohn Marino static HARD_REG_SET implicit_reg_pending_uses;
453*e4b17023SJohn Marino 
454*e4b17023SJohn Marino /* To speed up the test for duplicate dependency links we keep a
455*e4b17023SJohn Marino    record of dependencies created by add_dependence when the average
456*e4b17023SJohn Marino    number of instructions in a basic block is very large.
457*e4b17023SJohn Marino 
458*e4b17023SJohn Marino    Studies have shown that there is typically around 5 instructions between
459*e4b17023SJohn Marino    branches for typical C code.  So we can make a guess that the average
460*e4b17023SJohn Marino    basic block is approximately 5 instructions long; we will choose 100X
461*e4b17023SJohn Marino    the average size as a very large basic block.
462*e4b17023SJohn Marino 
463*e4b17023SJohn Marino    Each insn has associated bitmaps for its dependencies.  Each bitmap
464*e4b17023SJohn Marino    has enough entries to represent a dependency on any other insn in
465*e4b17023SJohn Marino    the insn chain.  All bitmap for true dependencies cache is
466*e4b17023SJohn Marino    allocated then the rest two ones are also allocated.  */
467*e4b17023SJohn Marino static bitmap_head *true_dependency_cache = NULL;
468*e4b17023SJohn Marino static bitmap_head *output_dependency_cache = NULL;
469*e4b17023SJohn Marino static bitmap_head *anti_dependency_cache = NULL;
470*e4b17023SJohn Marino static bitmap_head *control_dependency_cache = NULL;
471*e4b17023SJohn Marino static bitmap_head *spec_dependency_cache = NULL;
472*e4b17023SJohn Marino static int cache_size;
473*e4b17023SJohn Marino 
474*e4b17023SJohn Marino static int deps_may_trap_p (const_rtx);
475*e4b17023SJohn Marino static void add_dependence_1 (rtx, rtx, enum reg_note);
476*e4b17023SJohn Marino static void add_dependence_list (rtx, rtx, int, enum reg_note);
477*e4b17023SJohn Marino static void add_dependence_list_and_free (struct deps_desc *, rtx,
478*e4b17023SJohn Marino 					  rtx *, int, enum reg_note);
479*e4b17023SJohn Marino static void delete_all_dependences (rtx);
480*e4b17023SJohn Marino static void fixup_sched_groups (rtx);
481*e4b17023SJohn Marino 
482*e4b17023SJohn Marino static void flush_pending_lists (struct deps_desc *, rtx, int, int);
483*e4b17023SJohn Marino static void sched_analyze_1 (struct deps_desc *, rtx, rtx);
484*e4b17023SJohn Marino static void sched_analyze_2 (struct deps_desc *, rtx, rtx);
485*e4b17023SJohn Marino static void sched_analyze_insn (struct deps_desc *, rtx, rtx);
486*e4b17023SJohn Marino 
487*e4b17023SJohn Marino static bool sched_has_condition_p (const_rtx);
488*e4b17023SJohn Marino static int conditions_mutex_p (const_rtx, const_rtx, bool, bool);
489*e4b17023SJohn Marino 
490*e4b17023SJohn Marino static enum DEPS_ADJUST_RESULT maybe_add_or_update_dep_1 (dep_t, bool,
491*e4b17023SJohn Marino 							  rtx, rtx);
492*e4b17023SJohn Marino static enum DEPS_ADJUST_RESULT add_or_update_dep_1 (dep_t, bool, rtx, rtx);
493*e4b17023SJohn Marino 
494*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
495*e4b17023SJohn Marino static void check_dep (dep_t, bool);
496*e4b17023SJohn Marino #endif
497*e4b17023SJohn Marino 
498*e4b17023SJohn Marino /* Return nonzero if a load of the memory reference MEM can cause a trap.  */
499*e4b17023SJohn Marino 
500*e4b17023SJohn Marino static int
501*e4b17023SJohn Marino deps_may_trap_p (const_rtx mem)
502*e4b17023SJohn Marino {
503*e4b17023SJohn Marino   const_rtx addr = XEXP (mem, 0);
504*e4b17023SJohn Marino 
505*e4b17023SJohn Marino   if (REG_P (addr) && REGNO (addr) >= FIRST_PSEUDO_REGISTER)
506*e4b17023SJohn Marino     {
507*e4b17023SJohn Marino       const_rtx t = get_reg_known_value (REGNO (addr));
508*e4b17023SJohn Marino       if (t)
509*e4b17023SJohn Marino 	addr = t;
510*e4b17023SJohn Marino     }
511*e4b17023SJohn Marino   return rtx_addr_can_trap_p (addr);
512*e4b17023SJohn Marino }
513*e4b17023SJohn Marino 
514*e4b17023SJohn Marino 
515*e4b17023SJohn Marino /* Find the condition under which INSN is executed.  If REV is not NULL,
516*e4b17023SJohn Marino    it is set to TRUE when the returned comparison should be reversed
517*e4b17023SJohn Marino    to get the actual condition.  */
518*e4b17023SJohn Marino static rtx
519*e4b17023SJohn Marino sched_get_condition_with_rev_uncached (const_rtx insn, bool *rev)
520*e4b17023SJohn Marino {
521*e4b17023SJohn Marino   rtx pat = PATTERN (insn);
522*e4b17023SJohn Marino   rtx src;
523*e4b17023SJohn Marino 
524*e4b17023SJohn Marino   if (rev)
525*e4b17023SJohn Marino     *rev = false;
526*e4b17023SJohn Marino 
527*e4b17023SJohn Marino   if (GET_CODE (pat) == COND_EXEC)
528*e4b17023SJohn Marino     return COND_EXEC_TEST (pat);
529*e4b17023SJohn Marino 
530*e4b17023SJohn Marino   if (!any_condjump_p (insn) || !onlyjump_p (insn))
531*e4b17023SJohn Marino     return 0;
532*e4b17023SJohn Marino 
533*e4b17023SJohn Marino   src = SET_SRC (pc_set (insn));
534*e4b17023SJohn Marino 
535*e4b17023SJohn Marino   if (XEXP (src, 2) == pc_rtx)
536*e4b17023SJohn Marino     return XEXP (src, 0);
537*e4b17023SJohn Marino   else if (XEXP (src, 1) == pc_rtx)
538*e4b17023SJohn Marino     {
539*e4b17023SJohn Marino       rtx cond = XEXP (src, 0);
540*e4b17023SJohn Marino       enum rtx_code revcode = reversed_comparison_code (cond, insn);
541*e4b17023SJohn Marino 
542*e4b17023SJohn Marino       if (revcode == UNKNOWN)
543*e4b17023SJohn Marino 	return 0;
544*e4b17023SJohn Marino 
545*e4b17023SJohn Marino       if (rev)
546*e4b17023SJohn Marino 	*rev = true;
547*e4b17023SJohn Marino       return cond;
548*e4b17023SJohn Marino     }
549*e4b17023SJohn Marino 
550*e4b17023SJohn Marino   return 0;
551*e4b17023SJohn Marino }
552*e4b17023SJohn Marino 
553*e4b17023SJohn Marino /* Return the condition under which INSN does not execute (i.e.  the
554*e4b17023SJohn Marino    not-taken condition for a conditional branch), or NULL if we cannot
555*e4b17023SJohn Marino    find such a condition.  The caller should make a copy of the condition
556*e4b17023SJohn Marino    before using it.  */
557*e4b17023SJohn Marino rtx
558*e4b17023SJohn Marino sched_get_reverse_condition_uncached (const_rtx insn)
559*e4b17023SJohn Marino {
560*e4b17023SJohn Marino   bool rev;
561*e4b17023SJohn Marino   rtx cond = sched_get_condition_with_rev_uncached (insn, &rev);
562*e4b17023SJohn Marino   if (cond == NULL_RTX)
563*e4b17023SJohn Marino     return cond;
564*e4b17023SJohn Marino   if (!rev)
565*e4b17023SJohn Marino     {
566*e4b17023SJohn Marino       enum rtx_code revcode = reversed_comparison_code (cond, insn);
567*e4b17023SJohn Marino       cond = gen_rtx_fmt_ee (revcode, GET_MODE (cond),
568*e4b17023SJohn Marino 			     XEXP (cond, 0),
569*e4b17023SJohn Marino 			     XEXP (cond, 1));
570*e4b17023SJohn Marino     }
571*e4b17023SJohn Marino   return cond;
572*e4b17023SJohn Marino }
573*e4b17023SJohn Marino 
574*e4b17023SJohn Marino /* Caching variant of sched_get_condition_with_rev_uncached.
575*e4b17023SJohn Marino    We only do actual work the first time we come here for an insn; the
576*e4b17023SJohn Marino    results are cached in INSN_CACHED_COND and INSN_REVERSE_COND.  */
577*e4b17023SJohn Marino static rtx
578*e4b17023SJohn Marino sched_get_condition_with_rev (const_rtx insn, bool *rev)
579*e4b17023SJohn Marino {
580*e4b17023SJohn Marino   bool tmp;
581*e4b17023SJohn Marino 
582*e4b17023SJohn Marino   if (INSN_LUID (insn) == 0)
583*e4b17023SJohn Marino     return sched_get_condition_with_rev_uncached (insn, rev);
584*e4b17023SJohn Marino 
585*e4b17023SJohn Marino   if (INSN_CACHED_COND (insn) == const_true_rtx)
586*e4b17023SJohn Marino     return NULL_RTX;
587*e4b17023SJohn Marino 
588*e4b17023SJohn Marino   if (INSN_CACHED_COND (insn) != NULL_RTX)
589*e4b17023SJohn Marino     {
590*e4b17023SJohn Marino       if (rev)
591*e4b17023SJohn Marino 	*rev = INSN_REVERSE_COND (insn);
592*e4b17023SJohn Marino       return INSN_CACHED_COND (insn);
593*e4b17023SJohn Marino     }
594*e4b17023SJohn Marino 
595*e4b17023SJohn Marino   INSN_CACHED_COND (insn) = sched_get_condition_with_rev_uncached (insn, &tmp);
596*e4b17023SJohn Marino   INSN_REVERSE_COND (insn) = tmp;
597*e4b17023SJohn Marino 
598*e4b17023SJohn Marino   if (INSN_CACHED_COND (insn) == NULL_RTX)
599*e4b17023SJohn Marino     {
600*e4b17023SJohn Marino       INSN_CACHED_COND (insn) = const_true_rtx;
601*e4b17023SJohn Marino       return NULL_RTX;
602*e4b17023SJohn Marino     }
603*e4b17023SJohn Marino 
604*e4b17023SJohn Marino   if (rev)
605*e4b17023SJohn Marino     *rev = INSN_REVERSE_COND (insn);
606*e4b17023SJohn Marino   return INSN_CACHED_COND (insn);
607*e4b17023SJohn Marino }
608*e4b17023SJohn Marino 
609*e4b17023SJohn Marino /* True when we can find a condition under which INSN is executed.  */
610*e4b17023SJohn Marino static bool
611*e4b17023SJohn Marino sched_has_condition_p (const_rtx insn)
612*e4b17023SJohn Marino {
613*e4b17023SJohn Marino   return !! sched_get_condition_with_rev (insn, NULL);
614*e4b17023SJohn Marino }
615*e4b17023SJohn Marino 
616*e4b17023SJohn Marino 
617*e4b17023SJohn Marino 
618*e4b17023SJohn Marino /* Return nonzero if conditions COND1 and COND2 can never be both true.  */
619*e4b17023SJohn Marino static int
620*e4b17023SJohn Marino conditions_mutex_p (const_rtx cond1, const_rtx cond2, bool rev1, bool rev2)
621*e4b17023SJohn Marino {
622*e4b17023SJohn Marino   if (COMPARISON_P (cond1)
623*e4b17023SJohn Marino       && COMPARISON_P (cond2)
624*e4b17023SJohn Marino       && GET_CODE (cond1) ==
625*e4b17023SJohn Marino 	  (rev1==rev2
626*e4b17023SJohn Marino 	  ? reversed_comparison_code (cond2, NULL)
627*e4b17023SJohn Marino 	  : GET_CODE (cond2))
628*e4b17023SJohn Marino       && rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
629*e4b17023SJohn Marino       && XEXP (cond1, 1) == XEXP (cond2, 1))
630*e4b17023SJohn Marino     return 1;
631*e4b17023SJohn Marino   return 0;
632*e4b17023SJohn Marino }
633*e4b17023SJohn Marino 
634*e4b17023SJohn Marino /* Return true if insn1 and insn2 can never depend on one another because
635*e4b17023SJohn Marino    the conditions under which they are executed are mutually exclusive.  */
636*e4b17023SJohn Marino bool
637*e4b17023SJohn Marino sched_insns_conditions_mutex_p (const_rtx insn1, const_rtx insn2)
638*e4b17023SJohn Marino {
639*e4b17023SJohn Marino   rtx cond1, cond2;
640*e4b17023SJohn Marino   bool rev1 = false, rev2 = false;
641*e4b17023SJohn Marino 
642*e4b17023SJohn Marino   /* df doesn't handle conditional lifetimes entirely correctly;
643*e4b17023SJohn Marino      calls mess up the conditional lifetimes.  */
644*e4b17023SJohn Marino   if (!CALL_P (insn1) && !CALL_P (insn2))
645*e4b17023SJohn Marino     {
646*e4b17023SJohn Marino       cond1 = sched_get_condition_with_rev (insn1, &rev1);
647*e4b17023SJohn Marino       cond2 = sched_get_condition_with_rev (insn2, &rev2);
648*e4b17023SJohn Marino       if (cond1 && cond2
649*e4b17023SJohn Marino 	  && conditions_mutex_p (cond1, cond2, rev1, rev2)
650*e4b17023SJohn Marino 	  /* Make sure first instruction doesn't affect condition of second
651*e4b17023SJohn Marino 	     instruction if switched.  */
652*e4b17023SJohn Marino 	  && !modified_in_p (cond1, insn2)
653*e4b17023SJohn Marino 	  /* Make sure second instruction doesn't affect condition of first
654*e4b17023SJohn Marino 	     instruction if switched.  */
655*e4b17023SJohn Marino 	  && !modified_in_p (cond2, insn1))
656*e4b17023SJohn Marino 	return true;
657*e4b17023SJohn Marino     }
658*e4b17023SJohn Marino   return false;
659*e4b17023SJohn Marino }
660*e4b17023SJohn Marino 
661*e4b17023SJohn Marino 
662*e4b17023SJohn Marino /* Return true if INSN can potentially be speculated with type DS.  */
663*e4b17023SJohn Marino bool
664*e4b17023SJohn Marino sched_insn_is_legitimate_for_speculation_p (const_rtx insn, ds_t ds)
665*e4b17023SJohn Marino {
666*e4b17023SJohn Marino   if (HAS_INTERNAL_DEP (insn))
667*e4b17023SJohn Marino     return false;
668*e4b17023SJohn Marino 
669*e4b17023SJohn Marino   if (!NONJUMP_INSN_P (insn))
670*e4b17023SJohn Marino     return false;
671*e4b17023SJohn Marino 
672*e4b17023SJohn Marino   if (SCHED_GROUP_P (insn))
673*e4b17023SJohn Marino     return false;
674*e4b17023SJohn Marino 
675*e4b17023SJohn Marino   if (IS_SPECULATION_CHECK_P (CONST_CAST_RTX (insn)))
676*e4b17023SJohn Marino     return false;
677*e4b17023SJohn Marino 
678*e4b17023SJohn Marino   if (side_effects_p (PATTERN (insn)))
679*e4b17023SJohn Marino     return false;
680*e4b17023SJohn Marino 
681*e4b17023SJohn Marino   if (ds & BE_IN_SPEC)
682*e4b17023SJohn Marino     /* The following instructions, which depend on a speculatively scheduled
683*e4b17023SJohn Marino        instruction, cannot be speculatively scheduled along.  */
684*e4b17023SJohn Marino     {
685*e4b17023SJohn Marino       if (may_trap_or_fault_p (PATTERN (insn)))
686*e4b17023SJohn Marino 	/* If instruction might fault, it cannot be speculatively scheduled.
687*e4b17023SJohn Marino 	   For control speculation it's obvious why and for data speculation
688*e4b17023SJohn Marino 	   it's because the insn might get wrong input if speculation
689*e4b17023SJohn Marino 	   wasn't successful.  */
690*e4b17023SJohn Marino 	return false;
691*e4b17023SJohn Marino 
692*e4b17023SJohn Marino       if ((ds & BE_IN_DATA)
693*e4b17023SJohn Marino 	  && sched_has_condition_p (insn))
694*e4b17023SJohn Marino 	/* If this is a predicated instruction, then it cannot be
695*e4b17023SJohn Marino 	   speculatively scheduled.  See PR35659.  */
696*e4b17023SJohn Marino 	return false;
697*e4b17023SJohn Marino     }
698*e4b17023SJohn Marino 
699*e4b17023SJohn Marino   return true;
700*e4b17023SJohn Marino }
701*e4b17023SJohn Marino 
702*e4b17023SJohn Marino /* Initialize LIST_PTR to point to one of the lists present in TYPES_PTR,
703*e4b17023SJohn Marino    initialize RESOLVED_P_PTR with true if that list consists of resolved deps,
704*e4b17023SJohn Marino    and remove the type of returned [through LIST_PTR] list from TYPES_PTR.
705*e4b17023SJohn Marino    This function is used to switch sd_iterator to the next list.
706*e4b17023SJohn Marino    !!! For internal use only.  Might consider moving it to sched-int.h.  */
707*e4b17023SJohn Marino void
708*e4b17023SJohn Marino sd_next_list (const_rtx insn, sd_list_types_def *types_ptr,
709*e4b17023SJohn Marino 	      deps_list_t *list_ptr, bool *resolved_p_ptr)
710*e4b17023SJohn Marino {
711*e4b17023SJohn Marino   sd_list_types_def types = *types_ptr;
712*e4b17023SJohn Marino 
713*e4b17023SJohn Marino   if (types & SD_LIST_HARD_BACK)
714*e4b17023SJohn Marino     {
715*e4b17023SJohn Marino       *list_ptr = INSN_HARD_BACK_DEPS (insn);
716*e4b17023SJohn Marino       *resolved_p_ptr = false;
717*e4b17023SJohn Marino       *types_ptr = types & ~SD_LIST_HARD_BACK;
718*e4b17023SJohn Marino     }
719*e4b17023SJohn Marino   else if (types & SD_LIST_SPEC_BACK)
720*e4b17023SJohn Marino     {
721*e4b17023SJohn Marino       *list_ptr = INSN_SPEC_BACK_DEPS (insn);
722*e4b17023SJohn Marino       *resolved_p_ptr = false;
723*e4b17023SJohn Marino       *types_ptr = types & ~SD_LIST_SPEC_BACK;
724*e4b17023SJohn Marino     }
725*e4b17023SJohn Marino   else if (types & SD_LIST_FORW)
726*e4b17023SJohn Marino     {
727*e4b17023SJohn Marino       *list_ptr = INSN_FORW_DEPS (insn);
728*e4b17023SJohn Marino       *resolved_p_ptr = false;
729*e4b17023SJohn Marino       *types_ptr = types & ~SD_LIST_FORW;
730*e4b17023SJohn Marino     }
731*e4b17023SJohn Marino   else if (types & SD_LIST_RES_BACK)
732*e4b17023SJohn Marino     {
733*e4b17023SJohn Marino       *list_ptr = INSN_RESOLVED_BACK_DEPS (insn);
734*e4b17023SJohn Marino       *resolved_p_ptr = true;
735*e4b17023SJohn Marino       *types_ptr = types & ~SD_LIST_RES_BACK;
736*e4b17023SJohn Marino     }
737*e4b17023SJohn Marino   else if (types & SD_LIST_RES_FORW)
738*e4b17023SJohn Marino     {
739*e4b17023SJohn Marino       *list_ptr = INSN_RESOLVED_FORW_DEPS (insn);
740*e4b17023SJohn Marino       *resolved_p_ptr = true;
741*e4b17023SJohn Marino       *types_ptr = types & ~SD_LIST_RES_FORW;
742*e4b17023SJohn Marino     }
743*e4b17023SJohn Marino   else
744*e4b17023SJohn Marino     {
745*e4b17023SJohn Marino       *list_ptr = NULL;
746*e4b17023SJohn Marino       *resolved_p_ptr = false;
747*e4b17023SJohn Marino       *types_ptr = SD_LIST_NONE;
748*e4b17023SJohn Marino     }
749*e4b17023SJohn Marino }
750*e4b17023SJohn Marino 
751*e4b17023SJohn Marino /* Return the summary size of INSN's lists defined by LIST_TYPES.  */
752*e4b17023SJohn Marino int
753*e4b17023SJohn Marino sd_lists_size (const_rtx insn, sd_list_types_def list_types)
754*e4b17023SJohn Marino {
755*e4b17023SJohn Marino   int size = 0;
756*e4b17023SJohn Marino 
757*e4b17023SJohn Marino   while (list_types != SD_LIST_NONE)
758*e4b17023SJohn Marino     {
759*e4b17023SJohn Marino       deps_list_t list;
760*e4b17023SJohn Marino       bool resolved_p;
761*e4b17023SJohn Marino 
762*e4b17023SJohn Marino       sd_next_list (insn, &list_types, &list, &resolved_p);
763*e4b17023SJohn Marino       if (list)
764*e4b17023SJohn Marino 	size += DEPS_LIST_N_LINKS (list);
765*e4b17023SJohn Marino     }
766*e4b17023SJohn Marino 
767*e4b17023SJohn Marino   return size;
768*e4b17023SJohn Marino }
769*e4b17023SJohn Marino 
770*e4b17023SJohn Marino /* Return true if INSN's lists defined by LIST_TYPES are all empty.  */
771*e4b17023SJohn Marino 
772*e4b17023SJohn Marino bool
773*e4b17023SJohn Marino sd_lists_empty_p (const_rtx insn, sd_list_types_def list_types)
774*e4b17023SJohn Marino {
775*e4b17023SJohn Marino   while (list_types != SD_LIST_NONE)
776*e4b17023SJohn Marino     {
777*e4b17023SJohn Marino       deps_list_t list;
778*e4b17023SJohn Marino       bool resolved_p;
779*e4b17023SJohn Marino 
780*e4b17023SJohn Marino       sd_next_list (insn, &list_types, &list, &resolved_p);
781*e4b17023SJohn Marino       if (!deps_list_empty_p (list))
782*e4b17023SJohn Marino 	return false;
783*e4b17023SJohn Marino     }
784*e4b17023SJohn Marino 
785*e4b17023SJohn Marino   return true;
786*e4b17023SJohn Marino }
787*e4b17023SJohn Marino 
788*e4b17023SJohn Marino /* Initialize data for INSN.  */
789*e4b17023SJohn Marino void
790*e4b17023SJohn Marino sd_init_insn (rtx insn)
791*e4b17023SJohn Marino {
792*e4b17023SJohn Marino   INSN_HARD_BACK_DEPS (insn) = create_deps_list ();
793*e4b17023SJohn Marino   INSN_SPEC_BACK_DEPS (insn) = create_deps_list ();
794*e4b17023SJohn Marino   INSN_RESOLVED_BACK_DEPS (insn) = create_deps_list ();
795*e4b17023SJohn Marino   INSN_FORW_DEPS (insn) = create_deps_list ();
796*e4b17023SJohn Marino   INSN_RESOLVED_FORW_DEPS (insn) = create_deps_list ();
797*e4b17023SJohn Marino 
798*e4b17023SJohn Marino   /* ??? It would be nice to allocate dependency caches here.  */
799*e4b17023SJohn Marino }
800*e4b17023SJohn Marino 
801*e4b17023SJohn Marino /* Free data for INSN.  */
802*e4b17023SJohn Marino void
803*e4b17023SJohn Marino sd_finish_insn (rtx insn)
804*e4b17023SJohn Marino {
805*e4b17023SJohn Marino   /* ??? It would be nice to deallocate dependency caches here.  */
806*e4b17023SJohn Marino 
807*e4b17023SJohn Marino   free_deps_list (INSN_HARD_BACK_DEPS (insn));
808*e4b17023SJohn Marino   INSN_HARD_BACK_DEPS (insn) = NULL;
809*e4b17023SJohn Marino 
810*e4b17023SJohn Marino   free_deps_list (INSN_SPEC_BACK_DEPS (insn));
811*e4b17023SJohn Marino   INSN_SPEC_BACK_DEPS (insn) = NULL;
812*e4b17023SJohn Marino 
813*e4b17023SJohn Marino   free_deps_list (INSN_RESOLVED_BACK_DEPS (insn));
814*e4b17023SJohn Marino   INSN_RESOLVED_BACK_DEPS (insn) = NULL;
815*e4b17023SJohn Marino 
816*e4b17023SJohn Marino   free_deps_list (INSN_FORW_DEPS (insn));
817*e4b17023SJohn Marino   INSN_FORW_DEPS (insn) = NULL;
818*e4b17023SJohn Marino 
819*e4b17023SJohn Marino   free_deps_list (INSN_RESOLVED_FORW_DEPS (insn));
820*e4b17023SJohn Marino   INSN_RESOLVED_FORW_DEPS (insn) = NULL;
821*e4b17023SJohn Marino }
822*e4b17023SJohn Marino 
823*e4b17023SJohn Marino /* Find a dependency between producer PRO and consumer CON.
824*e4b17023SJohn Marino    Search through resolved dependency lists if RESOLVED_P is true.
825*e4b17023SJohn Marino    If no such dependency is found return NULL,
826*e4b17023SJohn Marino    otherwise return the dependency and initialize SD_IT_PTR [if it is nonnull]
827*e4b17023SJohn Marino    with an iterator pointing to it.  */
828*e4b17023SJohn Marino static dep_t
829*e4b17023SJohn Marino sd_find_dep_between_no_cache (rtx pro, rtx con, bool resolved_p,
830*e4b17023SJohn Marino 			      sd_iterator_def *sd_it_ptr)
831*e4b17023SJohn Marino {
832*e4b17023SJohn Marino   sd_list_types_def pro_list_type;
833*e4b17023SJohn Marino   sd_list_types_def con_list_type;
834*e4b17023SJohn Marino   sd_iterator_def sd_it;
835*e4b17023SJohn Marino   dep_t dep;
836*e4b17023SJohn Marino   bool found_p = false;
837*e4b17023SJohn Marino 
838*e4b17023SJohn Marino   if (resolved_p)
839*e4b17023SJohn Marino     {
840*e4b17023SJohn Marino       pro_list_type = SD_LIST_RES_FORW;
841*e4b17023SJohn Marino       con_list_type = SD_LIST_RES_BACK;
842*e4b17023SJohn Marino     }
843*e4b17023SJohn Marino   else
844*e4b17023SJohn Marino     {
845*e4b17023SJohn Marino       pro_list_type = SD_LIST_FORW;
846*e4b17023SJohn Marino       con_list_type = SD_LIST_BACK;
847*e4b17023SJohn Marino     }
848*e4b17023SJohn Marino 
849*e4b17023SJohn Marino   /* Walk through either back list of INSN or forw list of ELEM
850*e4b17023SJohn Marino      depending on which one is shorter.  */
851*e4b17023SJohn Marino   if (sd_lists_size (con, con_list_type) < sd_lists_size (pro, pro_list_type))
852*e4b17023SJohn Marino     {
853*e4b17023SJohn Marino       /* Find the dep_link with producer PRO in consumer's back_deps.  */
854*e4b17023SJohn Marino       FOR_EACH_DEP (con, con_list_type, sd_it, dep)
855*e4b17023SJohn Marino 	if (DEP_PRO (dep) == pro)
856*e4b17023SJohn Marino 	  {
857*e4b17023SJohn Marino 	    found_p = true;
858*e4b17023SJohn Marino 	    break;
859*e4b17023SJohn Marino 	  }
860*e4b17023SJohn Marino     }
861*e4b17023SJohn Marino   else
862*e4b17023SJohn Marino     {
863*e4b17023SJohn Marino       /* Find the dep_link with consumer CON in producer's forw_deps.  */
864*e4b17023SJohn Marino       FOR_EACH_DEP (pro, pro_list_type, sd_it, dep)
865*e4b17023SJohn Marino 	if (DEP_CON (dep) == con)
866*e4b17023SJohn Marino 	  {
867*e4b17023SJohn Marino 	    found_p = true;
868*e4b17023SJohn Marino 	    break;
869*e4b17023SJohn Marino 	  }
870*e4b17023SJohn Marino     }
871*e4b17023SJohn Marino 
872*e4b17023SJohn Marino   if (found_p)
873*e4b17023SJohn Marino     {
874*e4b17023SJohn Marino       if (sd_it_ptr != NULL)
875*e4b17023SJohn Marino 	*sd_it_ptr = sd_it;
876*e4b17023SJohn Marino 
877*e4b17023SJohn Marino       return dep;
878*e4b17023SJohn Marino     }
879*e4b17023SJohn Marino 
880*e4b17023SJohn Marino   return NULL;
881*e4b17023SJohn Marino }
882*e4b17023SJohn Marino 
883*e4b17023SJohn Marino /* Find a dependency between producer PRO and consumer CON.
884*e4b17023SJohn Marino    Use dependency [if available] to check if dependency is present at all.
885*e4b17023SJohn Marino    Search through resolved dependency lists if RESOLVED_P is true.
886*e4b17023SJohn Marino    If the dependency or NULL if none found.  */
887*e4b17023SJohn Marino dep_t
888*e4b17023SJohn Marino sd_find_dep_between (rtx pro, rtx con, bool resolved_p)
889*e4b17023SJohn Marino {
890*e4b17023SJohn Marino   if (true_dependency_cache != NULL)
891*e4b17023SJohn Marino     /* Avoiding the list walk below can cut compile times dramatically
892*e4b17023SJohn Marino        for some code.  */
893*e4b17023SJohn Marino     {
894*e4b17023SJohn Marino       int elem_luid = INSN_LUID (pro);
895*e4b17023SJohn Marino       int insn_luid = INSN_LUID (con);
896*e4b17023SJohn Marino 
897*e4b17023SJohn Marino       if (!bitmap_bit_p (&true_dependency_cache[insn_luid], elem_luid)
898*e4b17023SJohn Marino 	  && !bitmap_bit_p (&output_dependency_cache[insn_luid], elem_luid)
899*e4b17023SJohn Marino 	  && !bitmap_bit_p (&anti_dependency_cache[insn_luid], elem_luid)
900*e4b17023SJohn Marino 	  && !bitmap_bit_p (&control_dependency_cache[insn_luid], elem_luid))
901*e4b17023SJohn Marino 	return NULL;
902*e4b17023SJohn Marino     }
903*e4b17023SJohn Marino 
904*e4b17023SJohn Marino   return sd_find_dep_between_no_cache (pro, con, resolved_p, NULL);
905*e4b17023SJohn Marino }
906*e4b17023SJohn Marino 
907*e4b17023SJohn Marino /* Add or update  a dependence described by DEP.
908*e4b17023SJohn Marino    MEM1 and MEM2, if non-null, correspond to memory locations in case of
909*e4b17023SJohn Marino    data speculation.
910*e4b17023SJohn Marino 
911*e4b17023SJohn Marino    The function returns a value indicating if an old entry has been changed
912*e4b17023SJohn Marino    or a new entry has been added to insn's backward deps.
913*e4b17023SJohn Marino 
914*e4b17023SJohn Marino    This function merely checks if producer and consumer is the same insn
915*e4b17023SJohn Marino    and doesn't create a dep in this case.  Actual manipulation of
916*e4b17023SJohn Marino    dependence data structures is performed in add_or_update_dep_1.  */
917*e4b17023SJohn Marino static enum DEPS_ADJUST_RESULT
918*e4b17023SJohn Marino maybe_add_or_update_dep_1 (dep_t dep, bool resolved_p, rtx mem1, rtx mem2)
919*e4b17023SJohn Marino {
920*e4b17023SJohn Marino   rtx elem = DEP_PRO (dep);
921*e4b17023SJohn Marino   rtx insn = DEP_CON (dep);
922*e4b17023SJohn Marino 
923*e4b17023SJohn Marino   gcc_assert (INSN_P (insn) && INSN_P (elem));
924*e4b17023SJohn Marino 
925*e4b17023SJohn Marino   /* Don't depend an insn on itself.  */
926*e4b17023SJohn Marino   if (insn == elem)
927*e4b17023SJohn Marino     {
928*e4b17023SJohn Marino       if (sched_deps_info->generate_spec_deps)
929*e4b17023SJohn Marino         /* INSN has an internal dependence, which we can't overcome.  */
930*e4b17023SJohn Marino         HAS_INTERNAL_DEP (insn) = 1;
931*e4b17023SJohn Marino 
932*e4b17023SJohn Marino       return DEP_NODEP;
933*e4b17023SJohn Marino     }
934*e4b17023SJohn Marino 
935*e4b17023SJohn Marino   return add_or_update_dep_1 (dep, resolved_p, mem1, mem2);
936*e4b17023SJohn Marino }
937*e4b17023SJohn Marino 
938*e4b17023SJohn Marino /* Ask dependency caches what needs to be done for dependence DEP.
939*e4b17023SJohn Marino    Return DEP_CREATED if new dependence should be created and there is no
940*e4b17023SJohn Marino    need to try to find one searching the dependencies lists.
941*e4b17023SJohn Marino    Return DEP_PRESENT if there already is a dependence described by DEP and
942*e4b17023SJohn Marino    hence nothing is to be done.
943*e4b17023SJohn Marino    Return DEP_CHANGED if there already is a dependence, but it should be
944*e4b17023SJohn Marino    updated to incorporate additional information from DEP.  */
945*e4b17023SJohn Marino static enum DEPS_ADJUST_RESULT
946*e4b17023SJohn Marino ask_dependency_caches (dep_t dep)
947*e4b17023SJohn Marino {
948*e4b17023SJohn Marino   int elem_luid = INSN_LUID (DEP_PRO (dep));
949*e4b17023SJohn Marino   int insn_luid = INSN_LUID (DEP_CON (dep));
950*e4b17023SJohn Marino 
951*e4b17023SJohn Marino   gcc_assert (true_dependency_cache != NULL
952*e4b17023SJohn Marino 	      && output_dependency_cache != NULL
953*e4b17023SJohn Marino 	      && anti_dependency_cache != NULL
954*e4b17023SJohn Marino 	      && control_dependency_cache != NULL);
955*e4b17023SJohn Marino 
956*e4b17023SJohn Marino   if (!(current_sched_info->flags & USE_DEPS_LIST))
957*e4b17023SJohn Marino     {
958*e4b17023SJohn Marino       enum reg_note present_dep_type;
959*e4b17023SJohn Marino 
960*e4b17023SJohn Marino       if (bitmap_bit_p (&true_dependency_cache[insn_luid], elem_luid))
961*e4b17023SJohn Marino 	present_dep_type = REG_DEP_TRUE;
962*e4b17023SJohn Marino       else if (bitmap_bit_p (&output_dependency_cache[insn_luid], elem_luid))
963*e4b17023SJohn Marino 	present_dep_type = REG_DEP_OUTPUT;
964*e4b17023SJohn Marino       else if (bitmap_bit_p (&anti_dependency_cache[insn_luid], elem_luid))
965*e4b17023SJohn Marino 	present_dep_type = REG_DEP_ANTI;
966*e4b17023SJohn Marino       else if (bitmap_bit_p (&control_dependency_cache[insn_luid], elem_luid))
967*e4b17023SJohn Marino 	present_dep_type = REG_DEP_CONTROL;
968*e4b17023SJohn Marino       else
969*e4b17023SJohn Marino 	/* There is no existing dep so it should be created.  */
970*e4b17023SJohn Marino 	return DEP_CREATED;
971*e4b17023SJohn Marino 
972*e4b17023SJohn Marino       if ((int) DEP_TYPE (dep) >= (int) present_dep_type)
973*e4b17023SJohn Marino 	/* DEP does not add anything to the existing dependence.  */
974*e4b17023SJohn Marino 	return DEP_PRESENT;
975*e4b17023SJohn Marino     }
976*e4b17023SJohn Marino   else
977*e4b17023SJohn Marino     {
978*e4b17023SJohn Marino       ds_t present_dep_types = 0;
979*e4b17023SJohn Marino 
980*e4b17023SJohn Marino       if (bitmap_bit_p (&true_dependency_cache[insn_luid], elem_luid))
981*e4b17023SJohn Marino 	present_dep_types |= DEP_TRUE;
982*e4b17023SJohn Marino       if (bitmap_bit_p (&output_dependency_cache[insn_luid], elem_luid))
983*e4b17023SJohn Marino 	present_dep_types |= DEP_OUTPUT;
984*e4b17023SJohn Marino       if (bitmap_bit_p (&anti_dependency_cache[insn_luid], elem_luid))
985*e4b17023SJohn Marino 	present_dep_types |= DEP_ANTI;
986*e4b17023SJohn Marino       if (bitmap_bit_p (&control_dependency_cache[insn_luid], elem_luid))
987*e4b17023SJohn Marino 	present_dep_types |= DEP_CONTROL;
988*e4b17023SJohn Marino 
989*e4b17023SJohn Marino       if (present_dep_types == 0)
990*e4b17023SJohn Marino 	/* There is no existing dep so it should be created.  */
991*e4b17023SJohn Marino 	return DEP_CREATED;
992*e4b17023SJohn Marino 
993*e4b17023SJohn Marino       if (!(current_sched_info->flags & DO_SPECULATION)
994*e4b17023SJohn Marino 	  || !bitmap_bit_p (&spec_dependency_cache[insn_luid], elem_luid))
995*e4b17023SJohn Marino 	{
996*e4b17023SJohn Marino 	  if ((present_dep_types | (DEP_STATUS (dep) & DEP_TYPES))
997*e4b17023SJohn Marino 	      == present_dep_types)
998*e4b17023SJohn Marino 	    /* DEP does not add anything to the existing dependence.  */
999*e4b17023SJohn Marino 	    return DEP_PRESENT;
1000*e4b17023SJohn Marino 	}
1001*e4b17023SJohn Marino       else
1002*e4b17023SJohn Marino 	{
1003*e4b17023SJohn Marino 	  /* Only true dependencies can be data speculative and
1004*e4b17023SJohn Marino 	     only anti dependencies can be control speculative.  */
1005*e4b17023SJohn Marino 	  gcc_assert ((present_dep_types & (DEP_TRUE | DEP_ANTI))
1006*e4b17023SJohn Marino 		      == present_dep_types);
1007*e4b17023SJohn Marino 
1008*e4b17023SJohn Marino 	  /* if (DEP is SPECULATIVE) then
1009*e4b17023SJohn Marino 	     ..we should update DEP_STATUS
1010*e4b17023SJohn Marino 	     else
1011*e4b17023SJohn Marino 	     ..we should reset existing dep to non-speculative.  */
1012*e4b17023SJohn Marino 	}
1013*e4b17023SJohn Marino     }
1014*e4b17023SJohn Marino 
1015*e4b17023SJohn Marino   return DEP_CHANGED;
1016*e4b17023SJohn Marino }
1017*e4b17023SJohn Marino 
1018*e4b17023SJohn Marino /* Set dependency caches according to DEP.  */
1019*e4b17023SJohn Marino static void
1020*e4b17023SJohn Marino set_dependency_caches (dep_t dep)
1021*e4b17023SJohn Marino {
1022*e4b17023SJohn Marino   int elem_luid = INSN_LUID (DEP_PRO (dep));
1023*e4b17023SJohn Marino   int insn_luid = INSN_LUID (DEP_CON (dep));
1024*e4b17023SJohn Marino 
1025*e4b17023SJohn Marino   if (!(current_sched_info->flags & USE_DEPS_LIST))
1026*e4b17023SJohn Marino     {
1027*e4b17023SJohn Marino       switch (DEP_TYPE (dep))
1028*e4b17023SJohn Marino 	{
1029*e4b17023SJohn Marino 	case REG_DEP_TRUE:
1030*e4b17023SJohn Marino 	  bitmap_set_bit (&true_dependency_cache[insn_luid], elem_luid);
1031*e4b17023SJohn Marino 	  break;
1032*e4b17023SJohn Marino 
1033*e4b17023SJohn Marino 	case REG_DEP_OUTPUT:
1034*e4b17023SJohn Marino 	  bitmap_set_bit (&output_dependency_cache[insn_luid], elem_luid);
1035*e4b17023SJohn Marino 	  break;
1036*e4b17023SJohn Marino 
1037*e4b17023SJohn Marino 	case REG_DEP_ANTI:
1038*e4b17023SJohn Marino 	  bitmap_set_bit (&anti_dependency_cache[insn_luid], elem_luid);
1039*e4b17023SJohn Marino 	  break;
1040*e4b17023SJohn Marino 
1041*e4b17023SJohn Marino 	case REG_DEP_CONTROL:
1042*e4b17023SJohn Marino 	  bitmap_set_bit (&control_dependency_cache[insn_luid], elem_luid);
1043*e4b17023SJohn Marino 	  break;
1044*e4b17023SJohn Marino 
1045*e4b17023SJohn Marino 	default:
1046*e4b17023SJohn Marino 	  gcc_unreachable ();
1047*e4b17023SJohn Marino 	}
1048*e4b17023SJohn Marino     }
1049*e4b17023SJohn Marino   else
1050*e4b17023SJohn Marino     {
1051*e4b17023SJohn Marino       ds_t ds = DEP_STATUS (dep);
1052*e4b17023SJohn Marino 
1053*e4b17023SJohn Marino       if (ds & DEP_TRUE)
1054*e4b17023SJohn Marino 	bitmap_set_bit (&true_dependency_cache[insn_luid], elem_luid);
1055*e4b17023SJohn Marino       if (ds & DEP_OUTPUT)
1056*e4b17023SJohn Marino 	bitmap_set_bit (&output_dependency_cache[insn_luid], elem_luid);
1057*e4b17023SJohn Marino       if (ds & DEP_ANTI)
1058*e4b17023SJohn Marino 	bitmap_set_bit (&anti_dependency_cache[insn_luid], elem_luid);
1059*e4b17023SJohn Marino       if (ds & DEP_CONTROL)
1060*e4b17023SJohn Marino 	bitmap_set_bit (&control_dependency_cache[insn_luid], elem_luid);
1061*e4b17023SJohn Marino 
1062*e4b17023SJohn Marino       if (ds & SPECULATIVE)
1063*e4b17023SJohn Marino 	{
1064*e4b17023SJohn Marino 	  gcc_assert (current_sched_info->flags & DO_SPECULATION);
1065*e4b17023SJohn Marino 	  bitmap_set_bit (&spec_dependency_cache[insn_luid], elem_luid);
1066*e4b17023SJohn Marino 	}
1067*e4b17023SJohn Marino     }
1068*e4b17023SJohn Marino }
1069*e4b17023SJohn Marino 
1070*e4b17023SJohn Marino /* Type of dependence DEP have changed from OLD_TYPE.  Update dependency
1071*e4b17023SJohn Marino    caches accordingly.  */
1072*e4b17023SJohn Marino static void
1073*e4b17023SJohn Marino update_dependency_caches (dep_t dep, enum reg_note old_type)
1074*e4b17023SJohn Marino {
1075*e4b17023SJohn Marino   int elem_luid = INSN_LUID (DEP_PRO (dep));
1076*e4b17023SJohn Marino   int insn_luid = INSN_LUID (DEP_CON (dep));
1077*e4b17023SJohn Marino 
1078*e4b17023SJohn Marino   /* Clear corresponding cache entry because type of the link
1079*e4b17023SJohn Marino      may have changed.  Keep them if we use_deps_list.  */
1080*e4b17023SJohn Marino   if (!(current_sched_info->flags & USE_DEPS_LIST))
1081*e4b17023SJohn Marino     {
1082*e4b17023SJohn Marino       switch (old_type)
1083*e4b17023SJohn Marino 	{
1084*e4b17023SJohn Marino 	case REG_DEP_OUTPUT:
1085*e4b17023SJohn Marino 	  bitmap_clear_bit (&output_dependency_cache[insn_luid], elem_luid);
1086*e4b17023SJohn Marino 	  break;
1087*e4b17023SJohn Marino 
1088*e4b17023SJohn Marino 	case REG_DEP_ANTI:
1089*e4b17023SJohn Marino 	  bitmap_clear_bit (&anti_dependency_cache[insn_luid], elem_luid);
1090*e4b17023SJohn Marino 	  break;
1091*e4b17023SJohn Marino 
1092*e4b17023SJohn Marino 	case REG_DEP_CONTROL:
1093*e4b17023SJohn Marino 	  bitmap_clear_bit (&control_dependency_cache[insn_luid], elem_luid);
1094*e4b17023SJohn Marino 	  break;
1095*e4b17023SJohn Marino 
1096*e4b17023SJohn Marino 	default:
1097*e4b17023SJohn Marino 	  gcc_unreachable ();
1098*e4b17023SJohn Marino 	}
1099*e4b17023SJohn Marino     }
1100*e4b17023SJohn Marino 
1101*e4b17023SJohn Marino   set_dependency_caches (dep);
1102*e4b17023SJohn Marino }
1103*e4b17023SJohn Marino 
1104*e4b17023SJohn Marino /* Convert a dependence pointed to by SD_IT to be non-speculative.  */
1105*e4b17023SJohn Marino static void
1106*e4b17023SJohn Marino change_spec_dep_to_hard (sd_iterator_def sd_it)
1107*e4b17023SJohn Marino {
1108*e4b17023SJohn Marino   dep_node_t node = DEP_LINK_NODE (*sd_it.linkp);
1109*e4b17023SJohn Marino   dep_link_t link = DEP_NODE_BACK (node);
1110*e4b17023SJohn Marino   dep_t dep = DEP_NODE_DEP (node);
1111*e4b17023SJohn Marino   rtx elem = DEP_PRO (dep);
1112*e4b17023SJohn Marino   rtx insn = DEP_CON (dep);
1113*e4b17023SJohn Marino 
1114*e4b17023SJohn Marino   move_dep_link (link, INSN_SPEC_BACK_DEPS (insn), INSN_HARD_BACK_DEPS (insn));
1115*e4b17023SJohn Marino 
1116*e4b17023SJohn Marino   DEP_STATUS (dep) &= ~SPECULATIVE;
1117*e4b17023SJohn Marino 
1118*e4b17023SJohn Marino   if (true_dependency_cache != NULL)
1119*e4b17023SJohn Marino     /* Clear the cache entry.  */
1120*e4b17023SJohn Marino     bitmap_clear_bit (&spec_dependency_cache[INSN_LUID (insn)],
1121*e4b17023SJohn Marino 		      INSN_LUID (elem));
1122*e4b17023SJohn Marino }
1123*e4b17023SJohn Marino 
1124*e4b17023SJohn Marino /* Update DEP to incorporate information from NEW_DEP.
1125*e4b17023SJohn Marino    SD_IT points to DEP in case it should be moved to another list.
1126*e4b17023SJohn Marino    MEM1 and MEM2, if nonnull, correspond to memory locations in case if
1127*e4b17023SJohn Marino    data-speculative dependence should be updated.  */
1128*e4b17023SJohn Marino static enum DEPS_ADJUST_RESULT
1129*e4b17023SJohn Marino update_dep (dep_t dep, dep_t new_dep,
1130*e4b17023SJohn Marino 	    sd_iterator_def sd_it ATTRIBUTE_UNUSED,
1131*e4b17023SJohn Marino 	    rtx mem1 ATTRIBUTE_UNUSED,
1132*e4b17023SJohn Marino 	    rtx mem2 ATTRIBUTE_UNUSED)
1133*e4b17023SJohn Marino {
1134*e4b17023SJohn Marino   enum DEPS_ADJUST_RESULT res = DEP_PRESENT;
1135*e4b17023SJohn Marino   enum reg_note old_type = DEP_TYPE (dep);
1136*e4b17023SJohn Marino   bool was_spec = dep_spec_p (dep);
1137*e4b17023SJohn Marino 
1138*e4b17023SJohn Marino   /* If this is a more restrictive type of dependence than the
1139*e4b17023SJohn Marino      existing one, then change the existing dependence to this
1140*e4b17023SJohn Marino      type.  */
1141*e4b17023SJohn Marino   if ((int) DEP_TYPE (new_dep) < (int) old_type)
1142*e4b17023SJohn Marino     {
1143*e4b17023SJohn Marino       DEP_TYPE (dep) = DEP_TYPE (new_dep);
1144*e4b17023SJohn Marino       res = DEP_CHANGED;
1145*e4b17023SJohn Marino     }
1146*e4b17023SJohn Marino 
1147*e4b17023SJohn Marino   if (current_sched_info->flags & USE_DEPS_LIST)
1148*e4b17023SJohn Marino     /* Update DEP_STATUS.  */
1149*e4b17023SJohn Marino     {
1150*e4b17023SJohn Marino       ds_t dep_status = DEP_STATUS (dep);
1151*e4b17023SJohn Marino       ds_t ds = DEP_STATUS (new_dep);
1152*e4b17023SJohn Marino       ds_t new_status = ds | dep_status;
1153*e4b17023SJohn Marino 
1154*e4b17023SJohn Marino       if (new_status & SPECULATIVE)
1155*e4b17023SJohn Marino 	{
1156*e4b17023SJohn Marino 	  /* Either existing dep or a dep we're adding or both are
1157*e4b17023SJohn Marino 	     speculative.  */
1158*e4b17023SJohn Marino 	  if (!(ds & SPECULATIVE)
1159*e4b17023SJohn Marino 	      || !(dep_status & SPECULATIVE))
1160*e4b17023SJohn Marino 	    /* The new dep can't be speculative.  */
1161*e4b17023SJohn Marino 	    new_status &= ~SPECULATIVE;
1162*e4b17023SJohn Marino 	  else
1163*e4b17023SJohn Marino 	    {
1164*e4b17023SJohn Marino 	      /* Both are speculative.  Merge probabilities.  */
1165*e4b17023SJohn Marino 	      if (mem1 != NULL)
1166*e4b17023SJohn Marino 		{
1167*e4b17023SJohn Marino 		  dw_t dw;
1168*e4b17023SJohn Marino 
1169*e4b17023SJohn Marino 		  dw = estimate_dep_weak (mem1, mem2);
1170*e4b17023SJohn Marino 		  ds = set_dep_weak (ds, BEGIN_DATA, dw);
1171*e4b17023SJohn Marino 		}
1172*e4b17023SJohn Marino 
1173*e4b17023SJohn Marino 	      new_status = ds_merge (dep_status, ds);
1174*e4b17023SJohn Marino 	    }
1175*e4b17023SJohn Marino 	}
1176*e4b17023SJohn Marino 
1177*e4b17023SJohn Marino       ds = new_status;
1178*e4b17023SJohn Marino 
1179*e4b17023SJohn Marino       if (dep_status != ds)
1180*e4b17023SJohn Marino 	{
1181*e4b17023SJohn Marino 	  DEP_STATUS (dep) = ds;
1182*e4b17023SJohn Marino 	  res = DEP_CHANGED;
1183*e4b17023SJohn Marino 	}
1184*e4b17023SJohn Marino     }
1185*e4b17023SJohn Marino 
1186*e4b17023SJohn Marino   if (was_spec && !dep_spec_p (dep))
1187*e4b17023SJohn Marino     /* The old dep was speculative, but now it isn't.  */
1188*e4b17023SJohn Marino     change_spec_dep_to_hard (sd_it);
1189*e4b17023SJohn Marino 
1190*e4b17023SJohn Marino   if (true_dependency_cache != NULL
1191*e4b17023SJohn Marino       && res == DEP_CHANGED)
1192*e4b17023SJohn Marino     update_dependency_caches (dep, old_type);
1193*e4b17023SJohn Marino 
1194*e4b17023SJohn Marino   return res;
1195*e4b17023SJohn Marino }
1196*e4b17023SJohn Marino 
1197*e4b17023SJohn Marino /* Add or update  a dependence described by DEP.
1198*e4b17023SJohn Marino    MEM1 and MEM2, if non-null, correspond to memory locations in case of
1199*e4b17023SJohn Marino    data speculation.
1200*e4b17023SJohn Marino 
1201*e4b17023SJohn Marino    The function returns a value indicating if an old entry has been changed
1202*e4b17023SJohn Marino    or a new entry has been added to insn's backward deps or nothing has
1203*e4b17023SJohn Marino    been updated at all.  */
1204*e4b17023SJohn Marino static enum DEPS_ADJUST_RESULT
1205*e4b17023SJohn Marino add_or_update_dep_1 (dep_t new_dep, bool resolved_p,
1206*e4b17023SJohn Marino 		     rtx mem1 ATTRIBUTE_UNUSED, rtx mem2 ATTRIBUTE_UNUSED)
1207*e4b17023SJohn Marino {
1208*e4b17023SJohn Marino   bool maybe_present_p = true;
1209*e4b17023SJohn Marino   bool present_p = false;
1210*e4b17023SJohn Marino 
1211*e4b17023SJohn Marino   gcc_assert (INSN_P (DEP_PRO (new_dep)) && INSN_P (DEP_CON (new_dep))
1212*e4b17023SJohn Marino 	      && DEP_PRO (new_dep) != DEP_CON (new_dep));
1213*e4b17023SJohn Marino 
1214*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
1215*e4b17023SJohn Marino   check_dep (new_dep, mem1 != NULL);
1216*e4b17023SJohn Marino #endif
1217*e4b17023SJohn Marino 
1218*e4b17023SJohn Marino   if (true_dependency_cache != NULL)
1219*e4b17023SJohn Marino     {
1220*e4b17023SJohn Marino       switch (ask_dependency_caches (new_dep))
1221*e4b17023SJohn Marino 	{
1222*e4b17023SJohn Marino 	case DEP_PRESENT:
1223*e4b17023SJohn Marino 	  return DEP_PRESENT;
1224*e4b17023SJohn Marino 
1225*e4b17023SJohn Marino 	case DEP_CHANGED:
1226*e4b17023SJohn Marino 	  maybe_present_p = true;
1227*e4b17023SJohn Marino 	  present_p = true;
1228*e4b17023SJohn Marino 	  break;
1229*e4b17023SJohn Marino 
1230*e4b17023SJohn Marino 	case DEP_CREATED:
1231*e4b17023SJohn Marino 	  maybe_present_p = false;
1232*e4b17023SJohn Marino 	  present_p = false;
1233*e4b17023SJohn Marino 	  break;
1234*e4b17023SJohn Marino 
1235*e4b17023SJohn Marino 	default:
1236*e4b17023SJohn Marino 	  gcc_unreachable ();
1237*e4b17023SJohn Marino 	  break;
1238*e4b17023SJohn Marino 	}
1239*e4b17023SJohn Marino     }
1240*e4b17023SJohn Marino 
1241*e4b17023SJohn Marino   /* Check that we don't already have this dependence.  */
1242*e4b17023SJohn Marino   if (maybe_present_p)
1243*e4b17023SJohn Marino     {
1244*e4b17023SJohn Marino       dep_t present_dep;
1245*e4b17023SJohn Marino       sd_iterator_def sd_it;
1246*e4b17023SJohn Marino 
1247*e4b17023SJohn Marino       gcc_assert (true_dependency_cache == NULL || present_p);
1248*e4b17023SJohn Marino 
1249*e4b17023SJohn Marino       present_dep = sd_find_dep_between_no_cache (DEP_PRO (new_dep),
1250*e4b17023SJohn Marino 						  DEP_CON (new_dep),
1251*e4b17023SJohn Marino 						  resolved_p, &sd_it);
1252*e4b17023SJohn Marino 
1253*e4b17023SJohn Marino       if (present_dep != NULL)
1254*e4b17023SJohn Marino 	/* We found an existing dependency between ELEM and INSN.  */
1255*e4b17023SJohn Marino 	return update_dep (present_dep, new_dep, sd_it, mem1, mem2);
1256*e4b17023SJohn Marino       else
1257*e4b17023SJohn Marino 	/* We didn't find a dep, it shouldn't present in the cache.  */
1258*e4b17023SJohn Marino 	gcc_assert (!present_p);
1259*e4b17023SJohn Marino     }
1260*e4b17023SJohn Marino 
1261*e4b17023SJohn Marino   /* Might want to check one level of transitivity to save conses.
1262*e4b17023SJohn Marino      This check should be done in maybe_add_or_update_dep_1.
1263*e4b17023SJohn Marino      Since we made it to add_or_update_dep_1, we must create
1264*e4b17023SJohn Marino      (or update) a link.  */
1265*e4b17023SJohn Marino 
1266*e4b17023SJohn Marino   if (mem1 != NULL_RTX)
1267*e4b17023SJohn Marino     {
1268*e4b17023SJohn Marino       gcc_assert (sched_deps_info->generate_spec_deps);
1269*e4b17023SJohn Marino       DEP_STATUS (new_dep) = set_dep_weak (DEP_STATUS (new_dep), BEGIN_DATA,
1270*e4b17023SJohn Marino 					   estimate_dep_weak (mem1, mem2));
1271*e4b17023SJohn Marino     }
1272*e4b17023SJohn Marino 
1273*e4b17023SJohn Marino   sd_add_dep (new_dep, resolved_p);
1274*e4b17023SJohn Marino 
1275*e4b17023SJohn Marino   return DEP_CREATED;
1276*e4b17023SJohn Marino }
1277*e4b17023SJohn Marino 
1278*e4b17023SJohn Marino /* Initialize BACK_LIST_PTR with consumer's backward list and
1279*e4b17023SJohn Marino    FORW_LIST_PTR with producer's forward list.  If RESOLVED_P is true
1280*e4b17023SJohn Marino    initialize with lists that hold resolved deps.  */
1281*e4b17023SJohn Marino static void
1282*e4b17023SJohn Marino get_back_and_forw_lists (dep_t dep, bool resolved_p,
1283*e4b17023SJohn Marino 			 deps_list_t *back_list_ptr,
1284*e4b17023SJohn Marino 			 deps_list_t *forw_list_ptr)
1285*e4b17023SJohn Marino {
1286*e4b17023SJohn Marino   rtx con = DEP_CON (dep);
1287*e4b17023SJohn Marino 
1288*e4b17023SJohn Marino   if (!resolved_p)
1289*e4b17023SJohn Marino     {
1290*e4b17023SJohn Marino       if (dep_spec_p (dep))
1291*e4b17023SJohn Marino 	*back_list_ptr = INSN_SPEC_BACK_DEPS (con);
1292*e4b17023SJohn Marino       else
1293*e4b17023SJohn Marino 	*back_list_ptr = INSN_HARD_BACK_DEPS (con);
1294*e4b17023SJohn Marino 
1295*e4b17023SJohn Marino       *forw_list_ptr = INSN_FORW_DEPS (DEP_PRO (dep));
1296*e4b17023SJohn Marino     }
1297*e4b17023SJohn Marino   else
1298*e4b17023SJohn Marino     {
1299*e4b17023SJohn Marino       *back_list_ptr = INSN_RESOLVED_BACK_DEPS (con);
1300*e4b17023SJohn Marino       *forw_list_ptr = INSN_RESOLVED_FORW_DEPS (DEP_PRO (dep));
1301*e4b17023SJohn Marino     }
1302*e4b17023SJohn Marino }
1303*e4b17023SJohn Marino 
1304*e4b17023SJohn Marino /* Add dependence described by DEP.
1305*e4b17023SJohn Marino    If RESOLVED_P is true treat the dependence as a resolved one.  */
1306*e4b17023SJohn Marino void
1307*e4b17023SJohn Marino sd_add_dep (dep_t dep, bool resolved_p)
1308*e4b17023SJohn Marino {
1309*e4b17023SJohn Marino   dep_node_t n = create_dep_node ();
1310*e4b17023SJohn Marino   deps_list_t con_back_deps;
1311*e4b17023SJohn Marino   deps_list_t pro_forw_deps;
1312*e4b17023SJohn Marino   rtx elem = DEP_PRO (dep);
1313*e4b17023SJohn Marino   rtx insn = DEP_CON (dep);
1314*e4b17023SJohn Marino 
1315*e4b17023SJohn Marino   gcc_assert (INSN_P (insn) && INSN_P (elem) && insn != elem);
1316*e4b17023SJohn Marino 
1317*e4b17023SJohn Marino   if ((current_sched_info->flags & DO_SPECULATION) == 0
1318*e4b17023SJohn Marino       || !sched_insn_is_legitimate_for_speculation_p (insn, DEP_STATUS (dep)))
1319*e4b17023SJohn Marino     DEP_STATUS (dep) &= ~SPECULATIVE;
1320*e4b17023SJohn Marino 
1321*e4b17023SJohn Marino   copy_dep (DEP_NODE_DEP (n), dep);
1322*e4b17023SJohn Marino 
1323*e4b17023SJohn Marino   get_back_and_forw_lists (dep, resolved_p, &con_back_deps, &pro_forw_deps);
1324*e4b17023SJohn Marino 
1325*e4b17023SJohn Marino   add_to_deps_list (DEP_NODE_BACK (n), con_back_deps);
1326*e4b17023SJohn Marino 
1327*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
1328*e4b17023SJohn Marino   check_dep (dep, false);
1329*e4b17023SJohn Marino #endif
1330*e4b17023SJohn Marino 
1331*e4b17023SJohn Marino   add_to_deps_list (DEP_NODE_FORW (n), pro_forw_deps);
1332*e4b17023SJohn Marino 
1333*e4b17023SJohn Marino   /* If we are adding a dependency to INSN's LOG_LINKs, then note that
1334*e4b17023SJohn Marino      in the bitmap caches of dependency information.  */
1335*e4b17023SJohn Marino   if (true_dependency_cache != NULL)
1336*e4b17023SJohn Marino     set_dependency_caches (dep);
1337*e4b17023SJohn Marino }
1338*e4b17023SJohn Marino 
1339*e4b17023SJohn Marino /* Add or update backward dependence between INSN and ELEM
1340*e4b17023SJohn Marino    with given type DEP_TYPE and dep_status DS.
1341*e4b17023SJohn Marino    This function is a convenience wrapper.  */
1342*e4b17023SJohn Marino enum DEPS_ADJUST_RESULT
1343*e4b17023SJohn Marino sd_add_or_update_dep (dep_t dep, bool resolved_p)
1344*e4b17023SJohn Marino {
1345*e4b17023SJohn Marino   return add_or_update_dep_1 (dep, resolved_p, NULL_RTX, NULL_RTX);
1346*e4b17023SJohn Marino }
1347*e4b17023SJohn Marino 
1348*e4b17023SJohn Marino /* Resolved dependence pointed to by SD_IT.
1349*e4b17023SJohn Marino    SD_IT will advance to the next element.  */
1350*e4b17023SJohn Marino void
1351*e4b17023SJohn Marino sd_resolve_dep (sd_iterator_def sd_it)
1352*e4b17023SJohn Marino {
1353*e4b17023SJohn Marino   dep_node_t node = DEP_LINK_NODE (*sd_it.linkp);
1354*e4b17023SJohn Marino   dep_t dep = DEP_NODE_DEP (node);
1355*e4b17023SJohn Marino   rtx pro = DEP_PRO (dep);
1356*e4b17023SJohn Marino   rtx con = DEP_CON (dep);
1357*e4b17023SJohn Marino 
1358*e4b17023SJohn Marino   if (dep_spec_p (dep))
1359*e4b17023SJohn Marino     move_dep_link (DEP_NODE_BACK (node), INSN_SPEC_BACK_DEPS (con),
1360*e4b17023SJohn Marino 		   INSN_RESOLVED_BACK_DEPS (con));
1361*e4b17023SJohn Marino   else
1362*e4b17023SJohn Marino     move_dep_link (DEP_NODE_BACK (node), INSN_HARD_BACK_DEPS (con),
1363*e4b17023SJohn Marino 		   INSN_RESOLVED_BACK_DEPS (con));
1364*e4b17023SJohn Marino 
1365*e4b17023SJohn Marino   move_dep_link (DEP_NODE_FORW (node), INSN_FORW_DEPS (pro),
1366*e4b17023SJohn Marino 		 INSN_RESOLVED_FORW_DEPS (pro));
1367*e4b17023SJohn Marino }
1368*e4b17023SJohn Marino 
1369*e4b17023SJohn Marino /* Perform the inverse operation of sd_resolve_dep.  Restore the dependence
1370*e4b17023SJohn Marino    pointed to by SD_IT to unresolved state.  */
1371*e4b17023SJohn Marino void
1372*e4b17023SJohn Marino sd_unresolve_dep (sd_iterator_def sd_it)
1373*e4b17023SJohn Marino {
1374*e4b17023SJohn Marino   dep_node_t node = DEP_LINK_NODE (*sd_it.linkp);
1375*e4b17023SJohn Marino   dep_t dep = DEP_NODE_DEP (node);
1376*e4b17023SJohn Marino   rtx pro = DEP_PRO (dep);
1377*e4b17023SJohn Marino   rtx con = DEP_CON (dep);
1378*e4b17023SJohn Marino 
1379*e4b17023SJohn Marino   if (dep_spec_p (dep))
1380*e4b17023SJohn Marino     move_dep_link (DEP_NODE_BACK (node), INSN_RESOLVED_BACK_DEPS (con),
1381*e4b17023SJohn Marino 		   INSN_SPEC_BACK_DEPS (con));
1382*e4b17023SJohn Marino   else
1383*e4b17023SJohn Marino     move_dep_link (DEP_NODE_BACK (node), INSN_RESOLVED_BACK_DEPS (con),
1384*e4b17023SJohn Marino 		   INSN_HARD_BACK_DEPS (con));
1385*e4b17023SJohn Marino 
1386*e4b17023SJohn Marino   move_dep_link (DEP_NODE_FORW (node), INSN_RESOLVED_FORW_DEPS (pro),
1387*e4b17023SJohn Marino 		 INSN_FORW_DEPS (pro));
1388*e4b17023SJohn Marino }
1389*e4b17023SJohn Marino 
1390*e4b17023SJohn Marino /* Make TO depend on all the FROM's producers.
1391*e4b17023SJohn Marino    If RESOLVED_P is true add dependencies to the resolved lists.  */
1392*e4b17023SJohn Marino void
1393*e4b17023SJohn Marino sd_copy_back_deps (rtx to, rtx from, bool resolved_p)
1394*e4b17023SJohn Marino {
1395*e4b17023SJohn Marino   sd_list_types_def list_type;
1396*e4b17023SJohn Marino   sd_iterator_def sd_it;
1397*e4b17023SJohn Marino   dep_t dep;
1398*e4b17023SJohn Marino 
1399*e4b17023SJohn Marino   list_type = resolved_p ? SD_LIST_RES_BACK : SD_LIST_BACK;
1400*e4b17023SJohn Marino 
1401*e4b17023SJohn Marino   FOR_EACH_DEP (from, list_type, sd_it, dep)
1402*e4b17023SJohn Marino     {
1403*e4b17023SJohn Marino       dep_def _new_dep, *new_dep = &_new_dep;
1404*e4b17023SJohn Marino 
1405*e4b17023SJohn Marino       copy_dep (new_dep, dep);
1406*e4b17023SJohn Marino       DEP_CON (new_dep) = to;
1407*e4b17023SJohn Marino       sd_add_dep (new_dep, resolved_p);
1408*e4b17023SJohn Marino     }
1409*e4b17023SJohn Marino }
1410*e4b17023SJohn Marino 
1411*e4b17023SJohn Marino /* Remove a dependency referred to by SD_IT.
1412*e4b17023SJohn Marino    SD_IT will point to the next dependence after removal.  */
1413*e4b17023SJohn Marino void
1414*e4b17023SJohn Marino sd_delete_dep (sd_iterator_def sd_it)
1415*e4b17023SJohn Marino {
1416*e4b17023SJohn Marino   dep_node_t n = DEP_LINK_NODE (*sd_it.linkp);
1417*e4b17023SJohn Marino   dep_t dep = DEP_NODE_DEP (n);
1418*e4b17023SJohn Marino   rtx pro = DEP_PRO (dep);
1419*e4b17023SJohn Marino   rtx con = DEP_CON (dep);
1420*e4b17023SJohn Marino   deps_list_t con_back_deps;
1421*e4b17023SJohn Marino   deps_list_t pro_forw_deps;
1422*e4b17023SJohn Marino 
1423*e4b17023SJohn Marino   if (true_dependency_cache != NULL)
1424*e4b17023SJohn Marino     {
1425*e4b17023SJohn Marino       int elem_luid = INSN_LUID (pro);
1426*e4b17023SJohn Marino       int insn_luid = INSN_LUID (con);
1427*e4b17023SJohn Marino 
1428*e4b17023SJohn Marino       bitmap_clear_bit (&true_dependency_cache[insn_luid], elem_luid);
1429*e4b17023SJohn Marino       bitmap_clear_bit (&anti_dependency_cache[insn_luid], elem_luid);
1430*e4b17023SJohn Marino       bitmap_clear_bit (&control_dependency_cache[insn_luid], elem_luid);
1431*e4b17023SJohn Marino       bitmap_clear_bit (&output_dependency_cache[insn_luid], elem_luid);
1432*e4b17023SJohn Marino 
1433*e4b17023SJohn Marino       if (current_sched_info->flags & DO_SPECULATION)
1434*e4b17023SJohn Marino 	bitmap_clear_bit (&spec_dependency_cache[insn_luid], elem_luid);
1435*e4b17023SJohn Marino     }
1436*e4b17023SJohn Marino 
1437*e4b17023SJohn Marino   get_back_and_forw_lists (dep, sd_it.resolved_p,
1438*e4b17023SJohn Marino 			   &con_back_deps, &pro_forw_deps);
1439*e4b17023SJohn Marino 
1440*e4b17023SJohn Marino   remove_from_deps_list (DEP_NODE_BACK (n), con_back_deps);
1441*e4b17023SJohn Marino   remove_from_deps_list (DEP_NODE_FORW (n), pro_forw_deps);
1442*e4b17023SJohn Marino 
1443*e4b17023SJohn Marino   delete_dep_node (n);
1444*e4b17023SJohn Marino }
1445*e4b17023SJohn Marino 
1446*e4b17023SJohn Marino /* Dump size of the lists.  */
1447*e4b17023SJohn Marino #define DUMP_LISTS_SIZE (2)
1448*e4b17023SJohn Marino 
1449*e4b17023SJohn Marino /* Dump dependencies of the lists.  */
1450*e4b17023SJohn Marino #define DUMP_LISTS_DEPS (4)
1451*e4b17023SJohn Marino 
1452*e4b17023SJohn Marino /* Dump all information about the lists.  */
1453*e4b17023SJohn Marino #define DUMP_LISTS_ALL (DUMP_LISTS_SIZE | DUMP_LISTS_DEPS)
1454*e4b17023SJohn Marino 
1455*e4b17023SJohn Marino /* Dump deps_lists of INSN specified by TYPES to DUMP.
1456*e4b17023SJohn Marino    FLAGS is a bit mask specifying what information about the lists needs
1457*e4b17023SJohn Marino    to be printed.
1458*e4b17023SJohn Marino    If FLAGS has the very first bit set, then dump all information about
1459*e4b17023SJohn Marino    the lists and propagate this bit into the callee dump functions.  */
1460*e4b17023SJohn Marino static void
1461*e4b17023SJohn Marino dump_lists (FILE *dump, rtx insn, sd_list_types_def types, int flags)
1462*e4b17023SJohn Marino {
1463*e4b17023SJohn Marino   sd_iterator_def sd_it;
1464*e4b17023SJohn Marino   dep_t dep;
1465*e4b17023SJohn Marino   int all;
1466*e4b17023SJohn Marino 
1467*e4b17023SJohn Marino   all = (flags & 1);
1468*e4b17023SJohn Marino 
1469*e4b17023SJohn Marino   if (all)
1470*e4b17023SJohn Marino     flags |= DUMP_LISTS_ALL;
1471*e4b17023SJohn Marino 
1472*e4b17023SJohn Marino   fprintf (dump, "[");
1473*e4b17023SJohn Marino 
1474*e4b17023SJohn Marino   if (flags & DUMP_LISTS_SIZE)
1475*e4b17023SJohn Marino     fprintf (dump, "%d; ", sd_lists_size (insn, types));
1476*e4b17023SJohn Marino 
1477*e4b17023SJohn Marino   if (flags & DUMP_LISTS_DEPS)
1478*e4b17023SJohn Marino     {
1479*e4b17023SJohn Marino       FOR_EACH_DEP (insn, types, sd_it, dep)
1480*e4b17023SJohn Marino 	{
1481*e4b17023SJohn Marino 	  dump_dep (dump, dep, dump_dep_flags | all);
1482*e4b17023SJohn Marino 	  fprintf (dump, " ");
1483*e4b17023SJohn Marino 	}
1484*e4b17023SJohn Marino     }
1485*e4b17023SJohn Marino }
1486*e4b17023SJohn Marino 
1487*e4b17023SJohn Marino /* Dump all information about deps_lists of INSN specified by TYPES
1488*e4b17023SJohn Marino    to STDERR.  */
1489*e4b17023SJohn Marino void
1490*e4b17023SJohn Marino sd_debug_lists (rtx insn, sd_list_types_def types)
1491*e4b17023SJohn Marino {
1492*e4b17023SJohn Marino   dump_lists (stderr, insn, types, 1);
1493*e4b17023SJohn Marino   fprintf (stderr, "\n");
1494*e4b17023SJohn Marino }
1495*e4b17023SJohn Marino 
1496*e4b17023SJohn Marino /* A wrapper around add_dependence_1, to add a dependence of CON on
1497*e4b17023SJohn Marino    PRO, with type DEP_TYPE.  This function implements special handling
1498*e4b17023SJohn Marino    for REG_DEP_CONTROL dependencies.  For these, we optionally promote
1499*e4b17023SJohn Marino    the type to REG_DEP_ANTI if we can determine that predication is
1500*e4b17023SJohn Marino    impossible; otherwise we add additional true dependencies on the
1501*e4b17023SJohn Marino    INSN_COND_DEPS list of the jump (which PRO must be).  */
1502*e4b17023SJohn Marino void
1503*e4b17023SJohn Marino add_dependence (rtx con, rtx pro, enum reg_note dep_type)
1504*e4b17023SJohn Marino {
1505*e4b17023SJohn Marino   if (dep_type == REG_DEP_CONTROL
1506*e4b17023SJohn Marino       && !(current_sched_info->flags & DO_PREDICATION))
1507*e4b17023SJohn Marino     dep_type = REG_DEP_ANTI;
1508*e4b17023SJohn Marino 
1509*e4b17023SJohn Marino   /* A REG_DEP_CONTROL dependence may be eliminated through predication,
1510*e4b17023SJohn Marino      so we must also make the insn dependent on the setter of the
1511*e4b17023SJohn Marino      condition.  */
1512*e4b17023SJohn Marino   if (dep_type == REG_DEP_CONTROL)
1513*e4b17023SJohn Marino     {
1514*e4b17023SJohn Marino       rtx real_pro = pro;
1515*e4b17023SJohn Marino       rtx other = real_insn_for_shadow (real_pro);
1516*e4b17023SJohn Marino       rtx cond;
1517*e4b17023SJohn Marino 
1518*e4b17023SJohn Marino       if (other != NULL_RTX)
1519*e4b17023SJohn Marino 	real_pro = other;
1520*e4b17023SJohn Marino       cond = sched_get_reverse_condition_uncached (real_pro);
1521*e4b17023SJohn Marino       /* Verify that the insn does not use a different value in
1522*e4b17023SJohn Marino 	 the condition register than the one that was present at
1523*e4b17023SJohn Marino 	 the jump.  */
1524*e4b17023SJohn Marino       if (cond == NULL_RTX)
1525*e4b17023SJohn Marino 	dep_type = REG_DEP_ANTI;
1526*e4b17023SJohn Marino       else if (INSN_CACHED_COND (real_pro) == const_true_rtx)
1527*e4b17023SJohn Marino 	{
1528*e4b17023SJohn Marino 	  HARD_REG_SET uses;
1529*e4b17023SJohn Marino 	  CLEAR_HARD_REG_SET (uses);
1530*e4b17023SJohn Marino 	  note_uses (&PATTERN (con), record_hard_reg_uses, &uses);
1531*e4b17023SJohn Marino 	  if (TEST_HARD_REG_BIT (uses, REGNO (XEXP (cond, 0))))
1532*e4b17023SJohn Marino 	    dep_type = REG_DEP_ANTI;
1533*e4b17023SJohn Marino 	}
1534*e4b17023SJohn Marino       if (dep_type == REG_DEP_CONTROL)
1535*e4b17023SJohn Marino 	{
1536*e4b17023SJohn Marino 	  if (sched_verbose >= 5)
1537*e4b17023SJohn Marino 	    fprintf (sched_dump, "making DEP_CONTROL for %d\n",
1538*e4b17023SJohn Marino 		     INSN_UID (real_pro));
1539*e4b17023SJohn Marino 	  add_dependence_list (con, INSN_COND_DEPS (real_pro), 0,
1540*e4b17023SJohn Marino 			       REG_DEP_TRUE);
1541*e4b17023SJohn Marino 	}
1542*e4b17023SJohn Marino     }
1543*e4b17023SJohn Marino 
1544*e4b17023SJohn Marino   add_dependence_1 (con, pro, dep_type);
1545*e4b17023SJohn Marino }
1546*e4b17023SJohn Marino 
1547*e4b17023SJohn Marino /* A convenience wrapper to operate on an entire list.  */
1548*e4b17023SJohn Marino 
1549*e4b17023SJohn Marino static void
1550*e4b17023SJohn Marino add_dependence_list (rtx insn, rtx list, int uncond, enum reg_note dep_type)
1551*e4b17023SJohn Marino {
1552*e4b17023SJohn Marino   for (; list; list = XEXP (list, 1))
1553*e4b17023SJohn Marino     {
1554*e4b17023SJohn Marino       if (uncond || ! sched_insns_conditions_mutex_p (insn, XEXP (list, 0)))
1555*e4b17023SJohn Marino 	add_dependence (insn, XEXP (list, 0), dep_type);
1556*e4b17023SJohn Marino     }
1557*e4b17023SJohn Marino }
1558*e4b17023SJohn Marino 
1559*e4b17023SJohn Marino /* Similar, but free *LISTP at the same time, when the context
1560*e4b17023SJohn Marino    is not readonly.  */
1561*e4b17023SJohn Marino 
1562*e4b17023SJohn Marino static void
1563*e4b17023SJohn Marino add_dependence_list_and_free (struct deps_desc *deps, rtx insn, rtx *listp,
1564*e4b17023SJohn Marino                               int uncond, enum reg_note dep_type)
1565*e4b17023SJohn Marino {
1566*e4b17023SJohn Marino   rtx list, next;
1567*e4b17023SJohn Marino 
1568*e4b17023SJohn Marino   /* We don't want to short-circuit dependencies involving debug
1569*e4b17023SJohn Marino      insns, because they may cause actual dependencies to be
1570*e4b17023SJohn Marino      disregarded.  */
1571*e4b17023SJohn Marino   if (deps->readonly || DEBUG_INSN_P (insn))
1572*e4b17023SJohn Marino     {
1573*e4b17023SJohn Marino       add_dependence_list (insn, *listp, uncond, dep_type);
1574*e4b17023SJohn Marino       return;
1575*e4b17023SJohn Marino     }
1576*e4b17023SJohn Marino 
1577*e4b17023SJohn Marino   for (list = *listp, *listp = NULL; list ; list = next)
1578*e4b17023SJohn Marino     {
1579*e4b17023SJohn Marino       next = XEXP (list, 1);
1580*e4b17023SJohn Marino       if (uncond || ! sched_insns_conditions_mutex_p (insn, XEXP (list, 0)))
1581*e4b17023SJohn Marino 	add_dependence (insn, XEXP (list, 0), dep_type);
1582*e4b17023SJohn Marino       free_INSN_LIST_node (list);
1583*e4b17023SJohn Marino     }
1584*e4b17023SJohn Marino }
1585*e4b17023SJohn Marino 
1586*e4b17023SJohn Marino /* Remove all occurences of INSN from LIST.  Return the number of
1587*e4b17023SJohn Marino    occurences removed.  */
1588*e4b17023SJohn Marino 
1589*e4b17023SJohn Marino static int
1590*e4b17023SJohn Marino remove_from_dependence_list (rtx insn, rtx* listp)
1591*e4b17023SJohn Marino {
1592*e4b17023SJohn Marino   int removed = 0;
1593*e4b17023SJohn Marino 
1594*e4b17023SJohn Marino   while (*listp)
1595*e4b17023SJohn Marino     {
1596*e4b17023SJohn Marino       if (XEXP (*listp, 0) == insn)
1597*e4b17023SJohn Marino         {
1598*e4b17023SJohn Marino           remove_free_INSN_LIST_node (listp);
1599*e4b17023SJohn Marino           removed++;
1600*e4b17023SJohn Marino           continue;
1601*e4b17023SJohn Marino         }
1602*e4b17023SJohn Marino 
1603*e4b17023SJohn Marino       listp = &XEXP (*listp, 1);
1604*e4b17023SJohn Marino     }
1605*e4b17023SJohn Marino 
1606*e4b17023SJohn Marino   return removed;
1607*e4b17023SJohn Marino }
1608*e4b17023SJohn Marino 
1609*e4b17023SJohn Marino /* Same as above, but process two lists at once.  */
1610*e4b17023SJohn Marino static int
1611*e4b17023SJohn Marino remove_from_both_dependence_lists (rtx insn, rtx *listp, rtx *exprp)
1612*e4b17023SJohn Marino {
1613*e4b17023SJohn Marino   int removed = 0;
1614*e4b17023SJohn Marino 
1615*e4b17023SJohn Marino   while (*listp)
1616*e4b17023SJohn Marino     {
1617*e4b17023SJohn Marino       if (XEXP (*listp, 0) == insn)
1618*e4b17023SJohn Marino         {
1619*e4b17023SJohn Marino           remove_free_INSN_LIST_node (listp);
1620*e4b17023SJohn Marino           remove_free_EXPR_LIST_node (exprp);
1621*e4b17023SJohn Marino           removed++;
1622*e4b17023SJohn Marino           continue;
1623*e4b17023SJohn Marino         }
1624*e4b17023SJohn Marino 
1625*e4b17023SJohn Marino       listp = &XEXP (*listp, 1);
1626*e4b17023SJohn Marino       exprp = &XEXP (*exprp, 1);
1627*e4b17023SJohn Marino     }
1628*e4b17023SJohn Marino 
1629*e4b17023SJohn Marino   return removed;
1630*e4b17023SJohn Marino }
1631*e4b17023SJohn Marino 
1632*e4b17023SJohn Marino /* Clear all dependencies for an insn.  */
1633*e4b17023SJohn Marino static void
1634*e4b17023SJohn Marino delete_all_dependences (rtx insn)
1635*e4b17023SJohn Marino {
1636*e4b17023SJohn Marino   sd_iterator_def sd_it;
1637*e4b17023SJohn Marino   dep_t dep;
1638*e4b17023SJohn Marino 
1639*e4b17023SJohn Marino   /* The below cycle can be optimized to clear the caches and back_deps
1640*e4b17023SJohn Marino      in one call but that would provoke duplication of code from
1641*e4b17023SJohn Marino      delete_dep ().  */
1642*e4b17023SJohn Marino 
1643*e4b17023SJohn Marino   for (sd_it = sd_iterator_start (insn, SD_LIST_BACK);
1644*e4b17023SJohn Marino        sd_iterator_cond (&sd_it, &dep);)
1645*e4b17023SJohn Marino     sd_delete_dep (sd_it);
1646*e4b17023SJohn Marino }
1647*e4b17023SJohn Marino 
1648*e4b17023SJohn Marino /* All insns in a scheduling group except the first should only have
1649*e4b17023SJohn Marino    dependencies on the previous insn in the group.  So we find the
1650*e4b17023SJohn Marino    first instruction in the scheduling group by walking the dependence
1651*e4b17023SJohn Marino    chains backwards. Then we add the dependencies for the group to
1652*e4b17023SJohn Marino    the previous nonnote insn.  */
1653*e4b17023SJohn Marino 
1654*e4b17023SJohn Marino static void
1655*e4b17023SJohn Marino fixup_sched_groups (rtx insn)
1656*e4b17023SJohn Marino {
1657*e4b17023SJohn Marino   sd_iterator_def sd_it;
1658*e4b17023SJohn Marino   dep_t dep;
1659*e4b17023SJohn Marino   rtx prev_nonnote;
1660*e4b17023SJohn Marino 
1661*e4b17023SJohn Marino   FOR_EACH_DEP (insn, SD_LIST_BACK, sd_it, dep)
1662*e4b17023SJohn Marino     {
1663*e4b17023SJohn Marino       rtx i = insn;
1664*e4b17023SJohn Marino       rtx pro = DEP_PRO (dep);
1665*e4b17023SJohn Marino 
1666*e4b17023SJohn Marino       do
1667*e4b17023SJohn Marino 	{
1668*e4b17023SJohn Marino 	  i = prev_nonnote_insn (i);
1669*e4b17023SJohn Marino 
1670*e4b17023SJohn Marino 	  if (pro == i)
1671*e4b17023SJohn Marino 	    goto next_link;
1672*e4b17023SJohn Marino 	} while (SCHED_GROUP_P (i) || DEBUG_INSN_P (i));
1673*e4b17023SJohn Marino 
1674*e4b17023SJohn Marino       if (! sched_insns_conditions_mutex_p (i, pro))
1675*e4b17023SJohn Marino 	add_dependence (i, pro, DEP_TYPE (dep));
1676*e4b17023SJohn Marino     next_link:;
1677*e4b17023SJohn Marino     }
1678*e4b17023SJohn Marino 
1679*e4b17023SJohn Marino   delete_all_dependences (insn);
1680*e4b17023SJohn Marino 
1681*e4b17023SJohn Marino   prev_nonnote = prev_nonnote_nondebug_insn (insn);
1682*e4b17023SJohn Marino   if (BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (prev_nonnote)
1683*e4b17023SJohn Marino       && ! sched_insns_conditions_mutex_p (insn, prev_nonnote))
1684*e4b17023SJohn Marino     add_dependence (insn, prev_nonnote, REG_DEP_ANTI);
1685*e4b17023SJohn Marino }
1686*e4b17023SJohn Marino 
1687*e4b17023SJohn Marino /* Process an insn's memory dependencies.  There are four kinds of
1688*e4b17023SJohn Marino    dependencies:
1689*e4b17023SJohn Marino 
1690*e4b17023SJohn Marino    (0) read dependence: read follows read
1691*e4b17023SJohn Marino    (1) true dependence: read follows write
1692*e4b17023SJohn Marino    (2) output dependence: write follows write
1693*e4b17023SJohn Marino    (3) anti dependence: write follows read
1694*e4b17023SJohn Marino 
1695*e4b17023SJohn Marino    We are careful to build only dependencies which actually exist, and
1696*e4b17023SJohn Marino    use transitivity to avoid building too many links.  */
1697*e4b17023SJohn Marino 
1698*e4b17023SJohn Marino /* Add an INSN and MEM reference pair to a pending INSN_LIST and MEM_LIST.
1699*e4b17023SJohn Marino    The MEM is a memory reference contained within INSN, which we are saving
1700*e4b17023SJohn Marino    so that we can do memory aliasing on it.  */
1701*e4b17023SJohn Marino 
1702*e4b17023SJohn Marino static void
1703*e4b17023SJohn Marino add_insn_mem_dependence (struct deps_desc *deps, bool read_p,
1704*e4b17023SJohn Marino 			 rtx insn, rtx mem)
1705*e4b17023SJohn Marino {
1706*e4b17023SJohn Marino   rtx *insn_list;
1707*e4b17023SJohn Marino   rtx *mem_list;
1708*e4b17023SJohn Marino   rtx link;
1709*e4b17023SJohn Marino 
1710*e4b17023SJohn Marino   gcc_assert (!deps->readonly);
1711*e4b17023SJohn Marino   if (read_p)
1712*e4b17023SJohn Marino     {
1713*e4b17023SJohn Marino       insn_list = &deps->pending_read_insns;
1714*e4b17023SJohn Marino       mem_list = &deps->pending_read_mems;
1715*e4b17023SJohn Marino       if (!DEBUG_INSN_P (insn))
1716*e4b17023SJohn Marino 	deps->pending_read_list_length++;
1717*e4b17023SJohn Marino     }
1718*e4b17023SJohn Marino   else
1719*e4b17023SJohn Marino     {
1720*e4b17023SJohn Marino       insn_list = &deps->pending_write_insns;
1721*e4b17023SJohn Marino       mem_list = &deps->pending_write_mems;
1722*e4b17023SJohn Marino       deps->pending_write_list_length++;
1723*e4b17023SJohn Marino     }
1724*e4b17023SJohn Marino 
1725*e4b17023SJohn Marino   link = alloc_INSN_LIST (insn, *insn_list);
1726*e4b17023SJohn Marino   *insn_list = link;
1727*e4b17023SJohn Marino 
1728*e4b17023SJohn Marino   if (sched_deps_info->use_cselib)
1729*e4b17023SJohn Marino     {
1730*e4b17023SJohn Marino       mem = shallow_copy_rtx (mem);
1731*e4b17023SJohn Marino       XEXP (mem, 0) = cselib_subst_to_values_from_insn (XEXP (mem, 0),
1732*e4b17023SJohn Marino 							GET_MODE (mem), insn);
1733*e4b17023SJohn Marino     }
1734*e4b17023SJohn Marino   link = alloc_EXPR_LIST (VOIDmode, canon_rtx (mem), *mem_list);
1735*e4b17023SJohn Marino   *mem_list = link;
1736*e4b17023SJohn Marino }
1737*e4b17023SJohn Marino 
1738*e4b17023SJohn Marino /* Make a dependency between every memory reference on the pending lists
1739*e4b17023SJohn Marino    and INSN, thus flushing the pending lists.  FOR_READ is true if emitting
1740*e4b17023SJohn Marino    dependencies for a read operation, similarly with FOR_WRITE.  */
1741*e4b17023SJohn Marino 
1742*e4b17023SJohn Marino static void
1743*e4b17023SJohn Marino flush_pending_lists (struct deps_desc *deps, rtx insn, int for_read,
1744*e4b17023SJohn Marino 		     int for_write)
1745*e4b17023SJohn Marino {
1746*e4b17023SJohn Marino   if (for_write)
1747*e4b17023SJohn Marino     {
1748*e4b17023SJohn Marino       add_dependence_list_and_free (deps, insn, &deps->pending_read_insns,
1749*e4b17023SJohn Marino                                     1, REG_DEP_ANTI);
1750*e4b17023SJohn Marino       if (!deps->readonly)
1751*e4b17023SJohn Marino         {
1752*e4b17023SJohn Marino           free_EXPR_LIST_list (&deps->pending_read_mems);
1753*e4b17023SJohn Marino           deps->pending_read_list_length = 0;
1754*e4b17023SJohn Marino         }
1755*e4b17023SJohn Marino     }
1756*e4b17023SJohn Marino 
1757*e4b17023SJohn Marino   add_dependence_list_and_free (deps, insn, &deps->pending_write_insns, 1,
1758*e4b17023SJohn Marino 				for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT);
1759*e4b17023SJohn Marino 
1760*e4b17023SJohn Marino   add_dependence_list_and_free (deps, insn,
1761*e4b17023SJohn Marino                                 &deps->last_pending_memory_flush, 1,
1762*e4b17023SJohn Marino                                 for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT);
1763*e4b17023SJohn Marino 
1764*e4b17023SJohn Marino   add_dependence_list_and_free (deps, insn, &deps->pending_jump_insns, 1,
1765*e4b17023SJohn Marino 				REG_DEP_ANTI);
1766*e4b17023SJohn Marino 
1767*e4b17023SJohn Marino   if (!deps->readonly)
1768*e4b17023SJohn Marino     {
1769*e4b17023SJohn Marino       free_EXPR_LIST_list (&deps->pending_write_mems);
1770*e4b17023SJohn Marino       deps->pending_write_list_length = 0;
1771*e4b17023SJohn Marino 
1772*e4b17023SJohn Marino       deps->last_pending_memory_flush = alloc_INSN_LIST (insn, NULL_RTX);
1773*e4b17023SJohn Marino       deps->pending_flush_length = 1;
1774*e4b17023SJohn Marino     }
1775*e4b17023SJohn Marino }
1776*e4b17023SJohn Marino 
1777*e4b17023SJohn Marino /* Instruction which dependencies we are analyzing.  */
1778*e4b17023SJohn Marino static rtx cur_insn = NULL_RTX;
1779*e4b17023SJohn Marino 
1780*e4b17023SJohn Marino /* Implement hooks for haifa scheduler.  */
1781*e4b17023SJohn Marino 
1782*e4b17023SJohn Marino static void
1783*e4b17023SJohn Marino haifa_start_insn (rtx insn)
1784*e4b17023SJohn Marino {
1785*e4b17023SJohn Marino   gcc_assert (insn && !cur_insn);
1786*e4b17023SJohn Marino 
1787*e4b17023SJohn Marino   cur_insn = insn;
1788*e4b17023SJohn Marino }
1789*e4b17023SJohn Marino 
1790*e4b17023SJohn Marino static void
1791*e4b17023SJohn Marino haifa_finish_insn (void)
1792*e4b17023SJohn Marino {
1793*e4b17023SJohn Marino   cur_insn = NULL;
1794*e4b17023SJohn Marino }
1795*e4b17023SJohn Marino 
1796*e4b17023SJohn Marino void
1797*e4b17023SJohn Marino haifa_note_reg_set (int regno)
1798*e4b17023SJohn Marino {
1799*e4b17023SJohn Marino   SET_REGNO_REG_SET (reg_pending_sets, regno);
1800*e4b17023SJohn Marino }
1801*e4b17023SJohn Marino 
1802*e4b17023SJohn Marino void
1803*e4b17023SJohn Marino haifa_note_reg_clobber (int regno)
1804*e4b17023SJohn Marino {
1805*e4b17023SJohn Marino   SET_REGNO_REG_SET (reg_pending_clobbers, regno);
1806*e4b17023SJohn Marino }
1807*e4b17023SJohn Marino 
1808*e4b17023SJohn Marino void
1809*e4b17023SJohn Marino haifa_note_reg_use (int regno)
1810*e4b17023SJohn Marino {
1811*e4b17023SJohn Marino   SET_REGNO_REG_SET (reg_pending_uses, regno);
1812*e4b17023SJohn Marino }
1813*e4b17023SJohn Marino 
1814*e4b17023SJohn Marino static void
1815*e4b17023SJohn Marino haifa_note_mem_dep (rtx mem, rtx pending_mem, rtx pending_insn, ds_t ds)
1816*e4b17023SJohn Marino {
1817*e4b17023SJohn Marino   if (!(ds & SPECULATIVE))
1818*e4b17023SJohn Marino     {
1819*e4b17023SJohn Marino       mem = NULL_RTX;
1820*e4b17023SJohn Marino       pending_mem = NULL_RTX;
1821*e4b17023SJohn Marino     }
1822*e4b17023SJohn Marino   else
1823*e4b17023SJohn Marino     gcc_assert (ds & BEGIN_DATA);
1824*e4b17023SJohn Marino 
1825*e4b17023SJohn Marino   {
1826*e4b17023SJohn Marino     dep_def _dep, *dep = &_dep;
1827*e4b17023SJohn Marino 
1828*e4b17023SJohn Marino     init_dep_1 (dep, pending_insn, cur_insn, ds_to_dt (ds),
1829*e4b17023SJohn Marino                 current_sched_info->flags & USE_DEPS_LIST ? ds : 0);
1830*e4b17023SJohn Marino     maybe_add_or_update_dep_1 (dep, false, pending_mem, mem);
1831*e4b17023SJohn Marino   }
1832*e4b17023SJohn Marino 
1833*e4b17023SJohn Marino }
1834*e4b17023SJohn Marino 
1835*e4b17023SJohn Marino static void
1836*e4b17023SJohn Marino haifa_note_dep (rtx elem, ds_t ds)
1837*e4b17023SJohn Marino {
1838*e4b17023SJohn Marino   dep_def _dep;
1839*e4b17023SJohn Marino   dep_t dep = &_dep;
1840*e4b17023SJohn Marino 
1841*e4b17023SJohn Marino   init_dep (dep, elem, cur_insn, ds_to_dt (ds));
1842*e4b17023SJohn Marino   maybe_add_or_update_dep_1 (dep, false, NULL_RTX, NULL_RTX);
1843*e4b17023SJohn Marino }
1844*e4b17023SJohn Marino 
1845*e4b17023SJohn Marino static void
1846*e4b17023SJohn Marino note_reg_use (int r)
1847*e4b17023SJohn Marino {
1848*e4b17023SJohn Marino   if (sched_deps_info->note_reg_use)
1849*e4b17023SJohn Marino     sched_deps_info->note_reg_use (r);
1850*e4b17023SJohn Marino }
1851*e4b17023SJohn Marino 
1852*e4b17023SJohn Marino static void
1853*e4b17023SJohn Marino note_reg_set (int r)
1854*e4b17023SJohn Marino {
1855*e4b17023SJohn Marino   if (sched_deps_info->note_reg_set)
1856*e4b17023SJohn Marino     sched_deps_info->note_reg_set (r);
1857*e4b17023SJohn Marino }
1858*e4b17023SJohn Marino 
1859*e4b17023SJohn Marino static void
1860*e4b17023SJohn Marino note_reg_clobber (int r)
1861*e4b17023SJohn Marino {
1862*e4b17023SJohn Marino   if (sched_deps_info->note_reg_clobber)
1863*e4b17023SJohn Marino     sched_deps_info->note_reg_clobber (r);
1864*e4b17023SJohn Marino }
1865*e4b17023SJohn Marino 
1866*e4b17023SJohn Marino static void
1867*e4b17023SJohn Marino note_mem_dep (rtx m1, rtx m2, rtx e, ds_t ds)
1868*e4b17023SJohn Marino {
1869*e4b17023SJohn Marino   if (sched_deps_info->note_mem_dep)
1870*e4b17023SJohn Marino     sched_deps_info->note_mem_dep (m1, m2, e, ds);
1871*e4b17023SJohn Marino }
1872*e4b17023SJohn Marino 
1873*e4b17023SJohn Marino static void
1874*e4b17023SJohn Marino note_dep (rtx e, ds_t ds)
1875*e4b17023SJohn Marino {
1876*e4b17023SJohn Marino   if (sched_deps_info->note_dep)
1877*e4b17023SJohn Marino     sched_deps_info->note_dep (e, ds);
1878*e4b17023SJohn Marino }
1879*e4b17023SJohn Marino 
1880*e4b17023SJohn Marino /* Return corresponding to DS reg_note.  */
1881*e4b17023SJohn Marino enum reg_note
1882*e4b17023SJohn Marino ds_to_dt (ds_t ds)
1883*e4b17023SJohn Marino {
1884*e4b17023SJohn Marino   if (ds & DEP_TRUE)
1885*e4b17023SJohn Marino     return REG_DEP_TRUE;
1886*e4b17023SJohn Marino   else if (ds & DEP_OUTPUT)
1887*e4b17023SJohn Marino     return REG_DEP_OUTPUT;
1888*e4b17023SJohn Marino   else if (ds & DEP_ANTI)
1889*e4b17023SJohn Marino     return REG_DEP_ANTI;
1890*e4b17023SJohn Marino   else
1891*e4b17023SJohn Marino     {
1892*e4b17023SJohn Marino       gcc_assert (ds & DEP_CONTROL);
1893*e4b17023SJohn Marino       return REG_DEP_CONTROL;
1894*e4b17023SJohn Marino     }
1895*e4b17023SJohn Marino }
1896*e4b17023SJohn Marino 
1897*e4b17023SJohn Marino 
1898*e4b17023SJohn Marino 
1899*e4b17023SJohn Marino /* Functions for computation of info needed for register pressure
1900*e4b17023SJohn Marino    sensitive insn scheduling.  */
1901*e4b17023SJohn Marino 
1902*e4b17023SJohn Marino 
1903*e4b17023SJohn Marino /* Allocate and return reg_use_data structure for REGNO and INSN.  */
1904*e4b17023SJohn Marino static struct reg_use_data *
1905*e4b17023SJohn Marino create_insn_reg_use (int regno, rtx insn)
1906*e4b17023SJohn Marino {
1907*e4b17023SJohn Marino   struct reg_use_data *use;
1908*e4b17023SJohn Marino 
1909*e4b17023SJohn Marino   use = (struct reg_use_data *) xmalloc (sizeof (struct reg_use_data));
1910*e4b17023SJohn Marino   use->regno = regno;
1911*e4b17023SJohn Marino   use->insn = insn;
1912*e4b17023SJohn Marino   use->next_insn_use = INSN_REG_USE_LIST (insn);
1913*e4b17023SJohn Marino   INSN_REG_USE_LIST (insn) = use;
1914*e4b17023SJohn Marino   return use;
1915*e4b17023SJohn Marino }
1916*e4b17023SJohn Marino 
1917*e4b17023SJohn Marino /* Allocate and return reg_set_data structure for REGNO and INSN.  */
1918*e4b17023SJohn Marino static struct reg_set_data *
1919*e4b17023SJohn Marino create_insn_reg_set (int regno, rtx insn)
1920*e4b17023SJohn Marino {
1921*e4b17023SJohn Marino   struct reg_set_data *set;
1922*e4b17023SJohn Marino 
1923*e4b17023SJohn Marino   set = (struct reg_set_data *) xmalloc (sizeof (struct reg_set_data));
1924*e4b17023SJohn Marino   set->regno = regno;
1925*e4b17023SJohn Marino   set->insn = insn;
1926*e4b17023SJohn Marino   set->next_insn_set = INSN_REG_SET_LIST (insn);
1927*e4b17023SJohn Marino   INSN_REG_SET_LIST (insn) = set;
1928*e4b17023SJohn Marino   return set;
1929*e4b17023SJohn Marino }
1930*e4b17023SJohn Marino 
1931*e4b17023SJohn Marino /* Set up insn register uses for INSN and dependency context DEPS.  */
1932*e4b17023SJohn Marino static void
1933*e4b17023SJohn Marino setup_insn_reg_uses (struct deps_desc *deps, rtx insn)
1934*e4b17023SJohn Marino {
1935*e4b17023SJohn Marino   unsigned i;
1936*e4b17023SJohn Marino   reg_set_iterator rsi;
1937*e4b17023SJohn Marino   rtx list;
1938*e4b17023SJohn Marino   struct reg_use_data *use, *use2, *next;
1939*e4b17023SJohn Marino   struct deps_reg *reg_last;
1940*e4b17023SJohn Marino 
1941*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_REG_SET (reg_pending_uses, 0, i, rsi)
1942*e4b17023SJohn Marino     {
1943*e4b17023SJohn Marino       if (i < FIRST_PSEUDO_REGISTER
1944*e4b17023SJohn Marino 	  && TEST_HARD_REG_BIT (ira_no_alloc_regs, i))
1945*e4b17023SJohn Marino 	continue;
1946*e4b17023SJohn Marino 
1947*e4b17023SJohn Marino       if (find_regno_note (insn, REG_DEAD, i) == NULL_RTX
1948*e4b17023SJohn Marino 	  && ! REGNO_REG_SET_P (reg_pending_sets, i)
1949*e4b17023SJohn Marino 	  && ! REGNO_REG_SET_P (reg_pending_clobbers, i))
1950*e4b17023SJohn Marino 	/* Ignore use which is not dying.  */
1951*e4b17023SJohn Marino 	continue;
1952*e4b17023SJohn Marino 
1953*e4b17023SJohn Marino       use = create_insn_reg_use (i, insn);
1954*e4b17023SJohn Marino       use->next_regno_use = use;
1955*e4b17023SJohn Marino       reg_last = &deps->reg_last[i];
1956*e4b17023SJohn Marino 
1957*e4b17023SJohn Marino       /* Create the cycle list of uses.  */
1958*e4b17023SJohn Marino       for (list = reg_last->uses; list; list = XEXP (list, 1))
1959*e4b17023SJohn Marino 	{
1960*e4b17023SJohn Marino 	  use2 = create_insn_reg_use (i, XEXP (list, 0));
1961*e4b17023SJohn Marino 	  next = use->next_regno_use;
1962*e4b17023SJohn Marino 	  use->next_regno_use = use2;
1963*e4b17023SJohn Marino 	  use2->next_regno_use = next;
1964*e4b17023SJohn Marino 	}
1965*e4b17023SJohn Marino     }
1966*e4b17023SJohn Marino }
1967*e4b17023SJohn Marino 
1968*e4b17023SJohn Marino /* Register pressure info for the currently processed insn.  */
1969*e4b17023SJohn Marino static struct reg_pressure_data reg_pressure_info[N_REG_CLASSES];
1970*e4b17023SJohn Marino 
1971*e4b17023SJohn Marino /* Return TRUE if INSN has the use structure for REGNO.  */
1972*e4b17023SJohn Marino static bool
1973*e4b17023SJohn Marino insn_use_p (rtx insn, int regno)
1974*e4b17023SJohn Marino {
1975*e4b17023SJohn Marino   struct reg_use_data *use;
1976*e4b17023SJohn Marino 
1977*e4b17023SJohn Marino   for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use)
1978*e4b17023SJohn Marino     if (use->regno == regno)
1979*e4b17023SJohn Marino       return true;
1980*e4b17023SJohn Marino   return false;
1981*e4b17023SJohn Marino }
1982*e4b17023SJohn Marino 
1983*e4b17023SJohn Marino /* Update the register pressure info after birth of pseudo register REGNO
1984*e4b17023SJohn Marino    in INSN.  Arguments CLOBBER_P and UNUSED_P say correspondingly that
1985*e4b17023SJohn Marino    the register is in clobber or unused after the insn.  */
1986*e4b17023SJohn Marino static void
1987*e4b17023SJohn Marino mark_insn_pseudo_birth (rtx insn, int regno, bool clobber_p, bool unused_p)
1988*e4b17023SJohn Marino {
1989*e4b17023SJohn Marino   int incr, new_incr;
1990*e4b17023SJohn Marino   enum reg_class cl;
1991*e4b17023SJohn Marino 
1992*e4b17023SJohn Marino   gcc_assert (regno >= FIRST_PSEUDO_REGISTER);
1993*e4b17023SJohn Marino   cl = sched_regno_pressure_class[regno];
1994*e4b17023SJohn Marino   if (cl != NO_REGS)
1995*e4b17023SJohn Marino     {
1996*e4b17023SJohn Marino       incr = ira_reg_class_max_nregs[cl][PSEUDO_REGNO_MODE (regno)];
1997*e4b17023SJohn Marino       if (clobber_p)
1998*e4b17023SJohn Marino 	{
1999*e4b17023SJohn Marino 	  new_incr = reg_pressure_info[cl].clobber_increase + incr;
2000*e4b17023SJohn Marino 	  reg_pressure_info[cl].clobber_increase = new_incr;
2001*e4b17023SJohn Marino 	}
2002*e4b17023SJohn Marino       else if (unused_p)
2003*e4b17023SJohn Marino 	{
2004*e4b17023SJohn Marino 	  new_incr = reg_pressure_info[cl].unused_set_increase + incr;
2005*e4b17023SJohn Marino 	  reg_pressure_info[cl].unused_set_increase = new_incr;
2006*e4b17023SJohn Marino 	}
2007*e4b17023SJohn Marino       else
2008*e4b17023SJohn Marino 	{
2009*e4b17023SJohn Marino 	  new_incr = reg_pressure_info[cl].set_increase + incr;
2010*e4b17023SJohn Marino 	  reg_pressure_info[cl].set_increase = new_incr;
2011*e4b17023SJohn Marino 	  if (! insn_use_p (insn, regno))
2012*e4b17023SJohn Marino 	    reg_pressure_info[cl].change += incr;
2013*e4b17023SJohn Marino 	  create_insn_reg_set (regno, insn);
2014*e4b17023SJohn Marino 	}
2015*e4b17023SJohn Marino       gcc_assert (new_incr < (1 << INCREASE_BITS));
2016*e4b17023SJohn Marino     }
2017*e4b17023SJohn Marino }
2018*e4b17023SJohn Marino 
2019*e4b17023SJohn Marino /* Like mark_insn_pseudo_regno_birth except that NREGS saying how many
2020*e4b17023SJohn Marino    hard registers involved in the birth.  */
2021*e4b17023SJohn Marino static void
2022*e4b17023SJohn Marino mark_insn_hard_regno_birth (rtx insn, int regno, int nregs,
2023*e4b17023SJohn Marino 			    bool clobber_p, bool unused_p)
2024*e4b17023SJohn Marino {
2025*e4b17023SJohn Marino   enum reg_class cl;
2026*e4b17023SJohn Marino   int new_incr, last = regno + nregs;
2027*e4b17023SJohn Marino 
2028*e4b17023SJohn Marino   while (regno < last)
2029*e4b17023SJohn Marino     {
2030*e4b17023SJohn Marino       gcc_assert (regno < FIRST_PSEUDO_REGISTER);
2031*e4b17023SJohn Marino       if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
2032*e4b17023SJohn Marino 	{
2033*e4b17023SJohn Marino 	  cl = sched_regno_pressure_class[regno];
2034*e4b17023SJohn Marino 	  if (cl != NO_REGS)
2035*e4b17023SJohn Marino 	    {
2036*e4b17023SJohn Marino 	      if (clobber_p)
2037*e4b17023SJohn Marino 		{
2038*e4b17023SJohn Marino 		  new_incr = reg_pressure_info[cl].clobber_increase + 1;
2039*e4b17023SJohn Marino 		  reg_pressure_info[cl].clobber_increase = new_incr;
2040*e4b17023SJohn Marino 		}
2041*e4b17023SJohn Marino 	      else if (unused_p)
2042*e4b17023SJohn Marino 		{
2043*e4b17023SJohn Marino 		  new_incr = reg_pressure_info[cl].unused_set_increase + 1;
2044*e4b17023SJohn Marino 		  reg_pressure_info[cl].unused_set_increase = new_incr;
2045*e4b17023SJohn Marino 		}
2046*e4b17023SJohn Marino 	      else
2047*e4b17023SJohn Marino 		{
2048*e4b17023SJohn Marino 		  new_incr = reg_pressure_info[cl].set_increase + 1;
2049*e4b17023SJohn Marino 		  reg_pressure_info[cl].set_increase = new_incr;
2050*e4b17023SJohn Marino 		  if (! insn_use_p (insn, regno))
2051*e4b17023SJohn Marino 		    reg_pressure_info[cl].change += 1;
2052*e4b17023SJohn Marino 		  create_insn_reg_set (regno, insn);
2053*e4b17023SJohn Marino 		}
2054*e4b17023SJohn Marino 	      gcc_assert (new_incr < (1 << INCREASE_BITS));
2055*e4b17023SJohn Marino 	    }
2056*e4b17023SJohn Marino 	}
2057*e4b17023SJohn Marino       regno++;
2058*e4b17023SJohn Marino     }
2059*e4b17023SJohn Marino }
2060*e4b17023SJohn Marino 
2061*e4b17023SJohn Marino /* Update the register pressure info after birth of pseudo or hard
2062*e4b17023SJohn Marino    register REG in INSN.  Arguments CLOBBER_P and UNUSED_P say
2063*e4b17023SJohn Marino    correspondingly that the register is in clobber or unused after the
2064*e4b17023SJohn Marino    insn.  */
2065*e4b17023SJohn Marino static void
2066*e4b17023SJohn Marino mark_insn_reg_birth (rtx insn, rtx reg, bool clobber_p, bool unused_p)
2067*e4b17023SJohn Marino {
2068*e4b17023SJohn Marino   int regno;
2069*e4b17023SJohn Marino 
2070*e4b17023SJohn Marino   if (GET_CODE (reg) == SUBREG)
2071*e4b17023SJohn Marino     reg = SUBREG_REG (reg);
2072*e4b17023SJohn Marino 
2073*e4b17023SJohn Marino   if (! REG_P (reg))
2074*e4b17023SJohn Marino     return;
2075*e4b17023SJohn Marino 
2076*e4b17023SJohn Marino   regno = REGNO (reg);
2077*e4b17023SJohn Marino   if (regno < FIRST_PSEUDO_REGISTER)
2078*e4b17023SJohn Marino     mark_insn_hard_regno_birth (insn, regno,
2079*e4b17023SJohn Marino 				hard_regno_nregs[regno][GET_MODE (reg)],
2080*e4b17023SJohn Marino 				clobber_p, unused_p);
2081*e4b17023SJohn Marino   else
2082*e4b17023SJohn Marino     mark_insn_pseudo_birth (insn, regno, clobber_p, unused_p);
2083*e4b17023SJohn Marino }
2084*e4b17023SJohn Marino 
2085*e4b17023SJohn Marino /* Update the register pressure info after death of pseudo register
2086*e4b17023SJohn Marino    REGNO.  */
2087*e4b17023SJohn Marino static void
2088*e4b17023SJohn Marino mark_pseudo_death (int regno)
2089*e4b17023SJohn Marino {
2090*e4b17023SJohn Marino   int incr;
2091*e4b17023SJohn Marino   enum reg_class cl;
2092*e4b17023SJohn Marino 
2093*e4b17023SJohn Marino   gcc_assert (regno >= FIRST_PSEUDO_REGISTER);
2094*e4b17023SJohn Marino   cl = sched_regno_pressure_class[regno];
2095*e4b17023SJohn Marino   if (cl != NO_REGS)
2096*e4b17023SJohn Marino     {
2097*e4b17023SJohn Marino       incr = ira_reg_class_max_nregs[cl][PSEUDO_REGNO_MODE (regno)];
2098*e4b17023SJohn Marino       reg_pressure_info[cl].change -= incr;
2099*e4b17023SJohn Marino     }
2100*e4b17023SJohn Marino }
2101*e4b17023SJohn Marino 
2102*e4b17023SJohn Marino /* Like mark_pseudo_death except that NREGS saying how many hard
2103*e4b17023SJohn Marino    registers involved in the death.  */
2104*e4b17023SJohn Marino static void
2105*e4b17023SJohn Marino mark_hard_regno_death (int regno, int nregs)
2106*e4b17023SJohn Marino {
2107*e4b17023SJohn Marino   enum reg_class cl;
2108*e4b17023SJohn Marino   int last = regno + nregs;
2109*e4b17023SJohn Marino 
2110*e4b17023SJohn Marino   while (regno < last)
2111*e4b17023SJohn Marino     {
2112*e4b17023SJohn Marino       gcc_assert (regno < FIRST_PSEUDO_REGISTER);
2113*e4b17023SJohn Marino       if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
2114*e4b17023SJohn Marino 	{
2115*e4b17023SJohn Marino 	  cl = sched_regno_pressure_class[regno];
2116*e4b17023SJohn Marino 	  if (cl != NO_REGS)
2117*e4b17023SJohn Marino 	    reg_pressure_info[cl].change -= 1;
2118*e4b17023SJohn Marino 	}
2119*e4b17023SJohn Marino       regno++;
2120*e4b17023SJohn Marino     }
2121*e4b17023SJohn Marino }
2122*e4b17023SJohn Marino 
2123*e4b17023SJohn Marino /* Update the register pressure info after death of pseudo or hard
2124*e4b17023SJohn Marino    register REG.  */
2125*e4b17023SJohn Marino static void
2126*e4b17023SJohn Marino mark_reg_death (rtx reg)
2127*e4b17023SJohn Marino {
2128*e4b17023SJohn Marino   int regno;
2129*e4b17023SJohn Marino 
2130*e4b17023SJohn Marino   if (GET_CODE (reg) == SUBREG)
2131*e4b17023SJohn Marino     reg = SUBREG_REG (reg);
2132*e4b17023SJohn Marino 
2133*e4b17023SJohn Marino   if (! REG_P (reg))
2134*e4b17023SJohn Marino     return;
2135*e4b17023SJohn Marino 
2136*e4b17023SJohn Marino   regno = REGNO (reg);
2137*e4b17023SJohn Marino   if (regno < FIRST_PSEUDO_REGISTER)
2138*e4b17023SJohn Marino     mark_hard_regno_death (regno, hard_regno_nregs[regno][GET_MODE (reg)]);
2139*e4b17023SJohn Marino   else
2140*e4b17023SJohn Marino     mark_pseudo_death (regno);
2141*e4b17023SJohn Marino }
2142*e4b17023SJohn Marino 
2143*e4b17023SJohn Marino /* Process SETTER of REG.  DATA is an insn containing the setter.  */
2144*e4b17023SJohn Marino static void
2145*e4b17023SJohn Marino mark_insn_reg_store (rtx reg, const_rtx setter, void *data)
2146*e4b17023SJohn Marino {
2147*e4b17023SJohn Marino   if (setter != NULL_RTX && GET_CODE (setter) != SET)
2148*e4b17023SJohn Marino     return;
2149*e4b17023SJohn Marino   mark_insn_reg_birth
2150*e4b17023SJohn Marino     ((rtx) data, reg, false,
2151*e4b17023SJohn Marino      find_reg_note ((const_rtx) data, REG_UNUSED, reg) != NULL_RTX);
2152*e4b17023SJohn Marino }
2153*e4b17023SJohn Marino 
2154*e4b17023SJohn Marino /* Like mark_insn_reg_store except notice just CLOBBERs; ignore SETs.  */
2155*e4b17023SJohn Marino static void
2156*e4b17023SJohn Marino mark_insn_reg_clobber (rtx reg, const_rtx setter, void *data)
2157*e4b17023SJohn Marino {
2158*e4b17023SJohn Marino   if (GET_CODE (setter) == CLOBBER)
2159*e4b17023SJohn Marino     mark_insn_reg_birth ((rtx) data, reg, true, false);
2160*e4b17023SJohn Marino }
2161*e4b17023SJohn Marino 
2162*e4b17023SJohn Marino /* Set up reg pressure info related to INSN.  */
2163*e4b17023SJohn Marino void
2164*e4b17023SJohn Marino init_insn_reg_pressure_info (rtx insn)
2165*e4b17023SJohn Marino {
2166*e4b17023SJohn Marino   int i, len;
2167*e4b17023SJohn Marino   enum reg_class cl;
2168*e4b17023SJohn Marino   static struct reg_pressure_data *pressure_info;
2169*e4b17023SJohn Marino   rtx link;
2170*e4b17023SJohn Marino 
2171*e4b17023SJohn Marino   gcc_assert (sched_pressure_p);
2172*e4b17023SJohn Marino 
2173*e4b17023SJohn Marino   if (! INSN_P (insn))
2174*e4b17023SJohn Marino     return;
2175*e4b17023SJohn Marino 
2176*e4b17023SJohn Marino   for (i = 0; i < ira_pressure_classes_num; i++)
2177*e4b17023SJohn Marino     {
2178*e4b17023SJohn Marino       cl = ira_pressure_classes[i];
2179*e4b17023SJohn Marino       reg_pressure_info[cl].clobber_increase = 0;
2180*e4b17023SJohn Marino       reg_pressure_info[cl].set_increase = 0;
2181*e4b17023SJohn Marino       reg_pressure_info[cl].unused_set_increase = 0;
2182*e4b17023SJohn Marino       reg_pressure_info[cl].change = 0;
2183*e4b17023SJohn Marino     }
2184*e4b17023SJohn Marino 
2185*e4b17023SJohn Marino   note_stores (PATTERN (insn), mark_insn_reg_clobber, insn);
2186*e4b17023SJohn Marino 
2187*e4b17023SJohn Marino   note_stores (PATTERN (insn), mark_insn_reg_store, insn);
2188*e4b17023SJohn Marino 
2189*e4b17023SJohn Marino #ifdef AUTO_INC_DEC
2190*e4b17023SJohn Marino   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
2191*e4b17023SJohn Marino     if (REG_NOTE_KIND (link) == REG_INC)
2192*e4b17023SJohn Marino       mark_insn_reg_store (XEXP (link, 0), NULL_RTX, insn);
2193*e4b17023SJohn Marino #endif
2194*e4b17023SJohn Marino 
2195*e4b17023SJohn Marino   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
2196*e4b17023SJohn Marino     if (REG_NOTE_KIND (link) == REG_DEAD)
2197*e4b17023SJohn Marino       mark_reg_death (XEXP (link, 0));
2198*e4b17023SJohn Marino 
2199*e4b17023SJohn Marino   len = sizeof (struct reg_pressure_data) * ira_pressure_classes_num;
2200*e4b17023SJohn Marino   pressure_info
2201*e4b17023SJohn Marino     = INSN_REG_PRESSURE (insn) = (struct reg_pressure_data *) xmalloc (len);
2202*e4b17023SJohn Marino   INSN_MAX_REG_PRESSURE (insn) = (int *) xcalloc (ira_pressure_classes_num
2203*e4b17023SJohn Marino 						  * sizeof (int), 1);
2204*e4b17023SJohn Marino   for (i = 0; i < ira_pressure_classes_num; i++)
2205*e4b17023SJohn Marino     {
2206*e4b17023SJohn Marino       cl = ira_pressure_classes[i];
2207*e4b17023SJohn Marino       pressure_info[i].clobber_increase
2208*e4b17023SJohn Marino 	= reg_pressure_info[cl].clobber_increase;
2209*e4b17023SJohn Marino       pressure_info[i].set_increase = reg_pressure_info[cl].set_increase;
2210*e4b17023SJohn Marino       pressure_info[i].unused_set_increase
2211*e4b17023SJohn Marino 	= reg_pressure_info[cl].unused_set_increase;
2212*e4b17023SJohn Marino       pressure_info[i].change = reg_pressure_info[cl].change;
2213*e4b17023SJohn Marino     }
2214*e4b17023SJohn Marino }
2215*e4b17023SJohn Marino 
2216*e4b17023SJohn Marino 
2217*e4b17023SJohn Marino 
2218*e4b17023SJohn Marino 
2219*e4b17023SJohn Marino /* Internal variable for sched_analyze_[12] () functions.
2220*e4b17023SJohn Marino    If it is nonzero, this means that sched_analyze_[12] looks
2221*e4b17023SJohn Marino    at the most toplevel SET.  */
2222*e4b17023SJohn Marino static bool can_start_lhs_rhs_p;
2223*e4b17023SJohn Marino 
2224*e4b17023SJohn Marino /* Extend reg info for the deps context DEPS given that
2225*e4b17023SJohn Marino    we have just generated a register numbered REGNO.  */
2226*e4b17023SJohn Marino static void
2227*e4b17023SJohn Marino extend_deps_reg_info (struct deps_desc *deps, int regno)
2228*e4b17023SJohn Marino {
2229*e4b17023SJohn Marino   int max_regno = regno + 1;
2230*e4b17023SJohn Marino 
2231*e4b17023SJohn Marino   gcc_assert (!reload_completed);
2232*e4b17023SJohn Marino 
2233*e4b17023SJohn Marino   /* In a readonly context, it would not hurt to extend info,
2234*e4b17023SJohn Marino      but it should not be needed.  */
2235*e4b17023SJohn Marino   if (reload_completed && deps->readonly)
2236*e4b17023SJohn Marino     {
2237*e4b17023SJohn Marino       deps->max_reg = max_regno;
2238*e4b17023SJohn Marino       return;
2239*e4b17023SJohn Marino     }
2240*e4b17023SJohn Marino 
2241*e4b17023SJohn Marino   if (max_regno > deps->max_reg)
2242*e4b17023SJohn Marino     {
2243*e4b17023SJohn Marino       deps->reg_last = XRESIZEVEC (struct deps_reg, deps->reg_last,
2244*e4b17023SJohn Marino                                    max_regno);
2245*e4b17023SJohn Marino       memset (&deps->reg_last[deps->max_reg],
2246*e4b17023SJohn Marino               0, (max_regno - deps->max_reg)
2247*e4b17023SJohn Marino               * sizeof (struct deps_reg));
2248*e4b17023SJohn Marino       deps->max_reg = max_regno;
2249*e4b17023SJohn Marino     }
2250*e4b17023SJohn Marino }
2251*e4b17023SJohn Marino 
2252*e4b17023SJohn Marino /* Extends REG_INFO_P if needed.  */
2253*e4b17023SJohn Marino void
2254*e4b17023SJohn Marino maybe_extend_reg_info_p (void)
2255*e4b17023SJohn Marino {
2256*e4b17023SJohn Marino   /* Extend REG_INFO_P, if needed.  */
2257*e4b17023SJohn Marino   if ((unsigned int)max_regno - 1 >= reg_info_p_size)
2258*e4b17023SJohn Marino     {
2259*e4b17023SJohn Marino       size_t new_reg_info_p_size = max_regno + 128;
2260*e4b17023SJohn Marino 
2261*e4b17023SJohn Marino       gcc_assert (!reload_completed && sel_sched_p ());
2262*e4b17023SJohn Marino 
2263*e4b17023SJohn Marino       reg_info_p = (struct reg_info_t *) xrecalloc (reg_info_p,
2264*e4b17023SJohn Marino                                                     new_reg_info_p_size,
2265*e4b17023SJohn Marino                                                     reg_info_p_size,
2266*e4b17023SJohn Marino                                                     sizeof (*reg_info_p));
2267*e4b17023SJohn Marino       reg_info_p_size = new_reg_info_p_size;
2268*e4b17023SJohn Marino     }
2269*e4b17023SJohn Marino }
2270*e4b17023SJohn Marino 
2271*e4b17023SJohn Marino /* Analyze a single reference to register (reg:MODE REGNO) in INSN.
2272*e4b17023SJohn Marino    The type of the reference is specified by REF and can be SET,
2273*e4b17023SJohn Marino    CLOBBER, PRE_DEC, POST_DEC, PRE_INC, POST_INC or USE.  */
2274*e4b17023SJohn Marino 
2275*e4b17023SJohn Marino static void
2276*e4b17023SJohn Marino sched_analyze_reg (struct deps_desc *deps, int regno, enum machine_mode mode,
2277*e4b17023SJohn Marino 		   enum rtx_code ref, rtx insn)
2278*e4b17023SJohn Marino {
2279*e4b17023SJohn Marino   /* We could emit new pseudos in renaming.  Extend the reg structures.  */
2280*e4b17023SJohn Marino   if (!reload_completed && sel_sched_p ()
2281*e4b17023SJohn Marino       && (regno >= max_reg_num () - 1 || regno >= deps->max_reg))
2282*e4b17023SJohn Marino     extend_deps_reg_info (deps, regno);
2283*e4b17023SJohn Marino 
2284*e4b17023SJohn Marino   maybe_extend_reg_info_p ();
2285*e4b17023SJohn Marino 
2286*e4b17023SJohn Marino   /* A hard reg in a wide mode may really be multiple registers.
2287*e4b17023SJohn Marino      If so, mark all of them just like the first.  */
2288*e4b17023SJohn Marino   if (regno < FIRST_PSEUDO_REGISTER)
2289*e4b17023SJohn Marino     {
2290*e4b17023SJohn Marino       int i = hard_regno_nregs[regno][mode];
2291*e4b17023SJohn Marino       if (ref == SET)
2292*e4b17023SJohn Marino 	{
2293*e4b17023SJohn Marino 	  while (--i >= 0)
2294*e4b17023SJohn Marino 	    note_reg_set (regno + i);
2295*e4b17023SJohn Marino 	}
2296*e4b17023SJohn Marino       else if (ref == USE)
2297*e4b17023SJohn Marino 	{
2298*e4b17023SJohn Marino 	  while (--i >= 0)
2299*e4b17023SJohn Marino 	    note_reg_use (regno + i);
2300*e4b17023SJohn Marino 	}
2301*e4b17023SJohn Marino       else
2302*e4b17023SJohn Marino 	{
2303*e4b17023SJohn Marino 	  while (--i >= 0)
2304*e4b17023SJohn Marino 	    note_reg_clobber (regno + i);
2305*e4b17023SJohn Marino 	}
2306*e4b17023SJohn Marino     }
2307*e4b17023SJohn Marino 
2308*e4b17023SJohn Marino   /* ??? Reload sometimes emits USEs and CLOBBERs of pseudos that
2309*e4b17023SJohn Marino      it does not reload.  Ignore these as they have served their
2310*e4b17023SJohn Marino      purpose already.  */
2311*e4b17023SJohn Marino   else if (regno >= deps->max_reg)
2312*e4b17023SJohn Marino     {
2313*e4b17023SJohn Marino       enum rtx_code code = GET_CODE (PATTERN (insn));
2314*e4b17023SJohn Marino       gcc_assert (code == USE || code == CLOBBER);
2315*e4b17023SJohn Marino     }
2316*e4b17023SJohn Marino 
2317*e4b17023SJohn Marino   else
2318*e4b17023SJohn Marino     {
2319*e4b17023SJohn Marino       if (ref == SET)
2320*e4b17023SJohn Marino 	note_reg_set (regno);
2321*e4b17023SJohn Marino       else if (ref == USE)
2322*e4b17023SJohn Marino 	note_reg_use (regno);
2323*e4b17023SJohn Marino       else
2324*e4b17023SJohn Marino 	note_reg_clobber (regno);
2325*e4b17023SJohn Marino 
2326*e4b17023SJohn Marino       /* Pseudos that are REG_EQUIV to something may be replaced
2327*e4b17023SJohn Marino 	 by that during reloading.  We need only add dependencies for
2328*e4b17023SJohn Marino 	the address in the REG_EQUIV note.  */
2329*e4b17023SJohn Marino       if (!reload_completed && get_reg_known_equiv_p (regno))
2330*e4b17023SJohn Marino 	{
2331*e4b17023SJohn Marino 	  rtx t = get_reg_known_value (regno);
2332*e4b17023SJohn Marino 	  if (MEM_P (t))
2333*e4b17023SJohn Marino 	    sched_analyze_2 (deps, XEXP (t, 0), insn);
2334*e4b17023SJohn Marino 	}
2335*e4b17023SJohn Marino 
2336*e4b17023SJohn Marino       /* Don't let it cross a call after scheduling if it doesn't
2337*e4b17023SJohn Marino 	 already cross one.  */
2338*e4b17023SJohn Marino       if (REG_N_CALLS_CROSSED (regno) == 0)
2339*e4b17023SJohn Marino 	{
2340*e4b17023SJohn Marino 	  if (!deps->readonly && ref == USE && !DEBUG_INSN_P (insn))
2341*e4b17023SJohn Marino 	    deps->sched_before_next_call
2342*e4b17023SJohn Marino 	      = alloc_INSN_LIST (insn, deps->sched_before_next_call);
2343*e4b17023SJohn Marino 	  else
2344*e4b17023SJohn Marino 	    add_dependence_list (insn, deps->last_function_call, 1,
2345*e4b17023SJohn Marino 				 REG_DEP_ANTI);
2346*e4b17023SJohn Marino 	}
2347*e4b17023SJohn Marino     }
2348*e4b17023SJohn Marino }
2349*e4b17023SJohn Marino 
2350*e4b17023SJohn Marino /* Analyze a single SET, CLOBBER, PRE_DEC, POST_DEC, PRE_INC or POST_INC
2351*e4b17023SJohn Marino    rtx, X, creating all dependencies generated by the write to the
2352*e4b17023SJohn Marino    destination of X, and reads of everything mentioned.  */
2353*e4b17023SJohn Marino 
2354*e4b17023SJohn Marino static void
2355*e4b17023SJohn Marino sched_analyze_1 (struct deps_desc *deps, rtx x, rtx insn)
2356*e4b17023SJohn Marino {
2357*e4b17023SJohn Marino   rtx dest = XEXP (x, 0);
2358*e4b17023SJohn Marino   enum rtx_code code = GET_CODE (x);
2359*e4b17023SJohn Marino   bool cslr_p = can_start_lhs_rhs_p;
2360*e4b17023SJohn Marino 
2361*e4b17023SJohn Marino   can_start_lhs_rhs_p = false;
2362*e4b17023SJohn Marino 
2363*e4b17023SJohn Marino   gcc_assert (dest);
2364*e4b17023SJohn Marino   if (dest == 0)
2365*e4b17023SJohn Marino     return;
2366*e4b17023SJohn Marino 
2367*e4b17023SJohn Marino   if (cslr_p && sched_deps_info->start_lhs)
2368*e4b17023SJohn Marino     sched_deps_info->start_lhs (dest);
2369*e4b17023SJohn Marino 
2370*e4b17023SJohn Marino   if (GET_CODE (dest) == PARALLEL)
2371*e4b17023SJohn Marino     {
2372*e4b17023SJohn Marino       int i;
2373*e4b17023SJohn Marino 
2374*e4b17023SJohn Marino       for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
2375*e4b17023SJohn Marino 	if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
2376*e4b17023SJohn Marino 	  sched_analyze_1 (deps,
2377*e4b17023SJohn Marino 			   gen_rtx_CLOBBER (VOIDmode,
2378*e4b17023SJohn Marino 					    XEXP (XVECEXP (dest, 0, i), 0)),
2379*e4b17023SJohn Marino 			   insn);
2380*e4b17023SJohn Marino 
2381*e4b17023SJohn Marino       if (cslr_p && sched_deps_info->finish_lhs)
2382*e4b17023SJohn Marino 	sched_deps_info->finish_lhs ();
2383*e4b17023SJohn Marino 
2384*e4b17023SJohn Marino       if (code == SET)
2385*e4b17023SJohn Marino 	{
2386*e4b17023SJohn Marino 	  can_start_lhs_rhs_p = cslr_p;
2387*e4b17023SJohn Marino 
2388*e4b17023SJohn Marino 	  sched_analyze_2 (deps, SET_SRC (x), insn);
2389*e4b17023SJohn Marino 
2390*e4b17023SJohn Marino 	  can_start_lhs_rhs_p = false;
2391*e4b17023SJohn Marino 	}
2392*e4b17023SJohn Marino 
2393*e4b17023SJohn Marino       return;
2394*e4b17023SJohn Marino     }
2395*e4b17023SJohn Marino 
2396*e4b17023SJohn Marino   while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SUBREG
2397*e4b17023SJohn Marino 	 || GET_CODE (dest) == ZERO_EXTRACT)
2398*e4b17023SJohn Marino     {
2399*e4b17023SJohn Marino       if (GET_CODE (dest) == STRICT_LOW_PART
2400*e4b17023SJohn Marino 	 || GET_CODE (dest) == ZERO_EXTRACT
2401*e4b17023SJohn Marino 	 || df_read_modify_subreg_p (dest))
2402*e4b17023SJohn Marino         {
2403*e4b17023SJohn Marino 	  /* These both read and modify the result.  We must handle
2404*e4b17023SJohn Marino              them as writes to get proper dependencies for following
2405*e4b17023SJohn Marino              instructions.  We must handle them as reads to get proper
2406*e4b17023SJohn Marino              dependencies from this to previous instructions.
2407*e4b17023SJohn Marino              Thus we need to call sched_analyze_2.  */
2408*e4b17023SJohn Marino 
2409*e4b17023SJohn Marino 	  sched_analyze_2 (deps, XEXP (dest, 0), insn);
2410*e4b17023SJohn Marino 	}
2411*e4b17023SJohn Marino       if (GET_CODE (dest) == ZERO_EXTRACT)
2412*e4b17023SJohn Marino 	{
2413*e4b17023SJohn Marino 	  /* The second and third arguments are values read by this insn.  */
2414*e4b17023SJohn Marino 	  sched_analyze_2 (deps, XEXP (dest, 1), insn);
2415*e4b17023SJohn Marino 	  sched_analyze_2 (deps, XEXP (dest, 2), insn);
2416*e4b17023SJohn Marino 	}
2417*e4b17023SJohn Marino       dest = XEXP (dest, 0);
2418*e4b17023SJohn Marino     }
2419*e4b17023SJohn Marino 
2420*e4b17023SJohn Marino   if (REG_P (dest))
2421*e4b17023SJohn Marino     {
2422*e4b17023SJohn Marino       int regno = REGNO (dest);
2423*e4b17023SJohn Marino       enum machine_mode mode = GET_MODE (dest);
2424*e4b17023SJohn Marino 
2425*e4b17023SJohn Marino       sched_analyze_reg (deps, regno, mode, code, insn);
2426*e4b17023SJohn Marino 
2427*e4b17023SJohn Marino #ifdef STACK_REGS
2428*e4b17023SJohn Marino       /* Treat all writes to a stack register as modifying the TOS.  */
2429*e4b17023SJohn Marino       if (regno >= FIRST_STACK_REG && regno <= LAST_STACK_REG)
2430*e4b17023SJohn Marino 	{
2431*e4b17023SJohn Marino 	  /* Avoid analyzing the same register twice.  */
2432*e4b17023SJohn Marino 	  if (regno != FIRST_STACK_REG)
2433*e4b17023SJohn Marino 	    sched_analyze_reg (deps, FIRST_STACK_REG, mode, code, insn);
2434*e4b17023SJohn Marino 
2435*e4b17023SJohn Marino 	  add_to_hard_reg_set (&implicit_reg_pending_uses, mode,
2436*e4b17023SJohn Marino 			       FIRST_STACK_REG);
2437*e4b17023SJohn Marino 	}
2438*e4b17023SJohn Marino #endif
2439*e4b17023SJohn Marino     }
2440*e4b17023SJohn Marino   else if (MEM_P (dest))
2441*e4b17023SJohn Marino     {
2442*e4b17023SJohn Marino       /* Writing memory.  */
2443*e4b17023SJohn Marino       rtx t = dest;
2444*e4b17023SJohn Marino 
2445*e4b17023SJohn Marino       if (sched_deps_info->use_cselib)
2446*e4b17023SJohn Marino 	{
2447*e4b17023SJohn Marino 	  enum machine_mode address_mode
2448*e4b17023SJohn Marino 	    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (dest));
2449*e4b17023SJohn Marino 
2450*e4b17023SJohn Marino 	  t = shallow_copy_rtx (dest);
2451*e4b17023SJohn Marino 	  cselib_lookup_from_insn (XEXP (t, 0), address_mode, 1,
2452*e4b17023SJohn Marino 				   GET_MODE (t), insn);
2453*e4b17023SJohn Marino 	  XEXP (t, 0)
2454*e4b17023SJohn Marino 	    = cselib_subst_to_values_from_insn (XEXP (t, 0), GET_MODE (t),
2455*e4b17023SJohn Marino 						insn);
2456*e4b17023SJohn Marino 	}
2457*e4b17023SJohn Marino       t = canon_rtx (t);
2458*e4b17023SJohn Marino 
2459*e4b17023SJohn Marino       /* Pending lists can't get larger with a readonly context.  */
2460*e4b17023SJohn Marino       if (!deps->readonly
2461*e4b17023SJohn Marino           && ((deps->pending_read_list_length + deps->pending_write_list_length)
2462*e4b17023SJohn Marino               > MAX_PENDING_LIST_LENGTH))
2463*e4b17023SJohn Marino 	{
2464*e4b17023SJohn Marino 	  /* Flush all pending reads and writes to prevent the pending lists
2465*e4b17023SJohn Marino 	     from getting any larger.  Insn scheduling runs too slowly when
2466*e4b17023SJohn Marino 	     these lists get long.  When compiling GCC with itself,
2467*e4b17023SJohn Marino 	     this flush occurs 8 times for sparc, and 10 times for m88k using
2468*e4b17023SJohn Marino 	     the default value of 32.  */
2469*e4b17023SJohn Marino 	  flush_pending_lists (deps, insn, false, true);
2470*e4b17023SJohn Marino 	}
2471*e4b17023SJohn Marino       else
2472*e4b17023SJohn Marino 	{
2473*e4b17023SJohn Marino 	  rtx pending, pending_mem;
2474*e4b17023SJohn Marino 
2475*e4b17023SJohn Marino 	  pending = deps->pending_read_insns;
2476*e4b17023SJohn Marino 	  pending_mem = deps->pending_read_mems;
2477*e4b17023SJohn Marino 	  while (pending)
2478*e4b17023SJohn Marino 	    {
2479*e4b17023SJohn Marino 	      if (anti_dependence (XEXP (pending_mem, 0), t)
2480*e4b17023SJohn Marino 		  && ! sched_insns_conditions_mutex_p (insn, XEXP (pending, 0)))
2481*e4b17023SJohn Marino 		note_mem_dep (t, XEXP (pending_mem, 0), XEXP (pending, 0),
2482*e4b17023SJohn Marino 			      DEP_ANTI);
2483*e4b17023SJohn Marino 
2484*e4b17023SJohn Marino 	      pending = XEXP (pending, 1);
2485*e4b17023SJohn Marino 	      pending_mem = XEXP (pending_mem, 1);
2486*e4b17023SJohn Marino 	    }
2487*e4b17023SJohn Marino 
2488*e4b17023SJohn Marino 	  pending = deps->pending_write_insns;
2489*e4b17023SJohn Marino 	  pending_mem = deps->pending_write_mems;
2490*e4b17023SJohn Marino 	  while (pending)
2491*e4b17023SJohn Marino 	    {
2492*e4b17023SJohn Marino 	      if (output_dependence (XEXP (pending_mem, 0), t)
2493*e4b17023SJohn Marino 		  && ! sched_insns_conditions_mutex_p (insn, XEXP (pending, 0)))
2494*e4b17023SJohn Marino 		note_mem_dep (t, XEXP (pending_mem, 0), XEXP (pending, 0),
2495*e4b17023SJohn Marino 			      DEP_OUTPUT);
2496*e4b17023SJohn Marino 
2497*e4b17023SJohn Marino 	      pending = XEXP (pending, 1);
2498*e4b17023SJohn Marino 	      pending_mem = XEXP (pending_mem, 1);
2499*e4b17023SJohn Marino 	    }
2500*e4b17023SJohn Marino 
2501*e4b17023SJohn Marino 	  add_dependence_list (insn, deps->last_pending_memory_flush, 1,
2502*e4b17023SJohn Marino 			       REG_DEP_ANTI);
2503*e4b17023SJohn Marino 	  add_dependence_list (insn, deps->pending_jump_insns, 1,
2504*e4b17023SJohn Marino 			       REG_DEP_CONTROL);
2505*e4b17023SJohn Marino 
2506*e4b17023SJohn Marino           if (!deps->readonly)
2507*e4b17023SJohn Marino             add_insn_mem_dependence (deps, false, insn, dest);
2508*e4b17023SJohn Marino 	}
2509*e4b17023SJohn Marino       sched_analyze_2 (deps, XEXP (dest, 0), insn);
2510*e4b17023SJohn Marino     }
2511*e4b17023SJohn Marino 
2512*e4b17023SJohn Marino   if (cslr_p && sched_deps_info->finish_lhs)
2513*e4b17023SJohn Marino     sched_deps_info->finish_lhs ();
2514*e4b17023SJohn Marino 
2515*e4b17023SJohn Marino   /* Analyze reads.  */
2516*e4b17023SJohn Marino   if (GET_CODE (x) == SET)
2517*e4b17023SJohn Marino     {
2518*e4b17023SJohn Marino       can_start_lhs_rhs_p = cslr_p;
2519*e4b17023SJohn Marino 
2520*e4b17023SJohn Marino       sched_analyze_2 (deps, SET_SRC (x), insn);
2521*e4b17023SJohn Marino 
2522*e4b17023SJohn Marino       can_start_lhs_rhs_p = false;
2523*e4b17023SJohn Marino     }
2524*e4b17023SJohn Marino }
2525*e4b17023SJohn Marino 
2526*e4b17023SJohn Marino /* Analyze the uses of memory and registers in rtx X in INSN.  */
2527*e4b17023SJohn Marino static void
2528*e4b17023SJohn Marino sched_analyze_2 (struct deps_desc *deps, rtx x, rtx insn)
2529*e4b17023SJohn Marino {
2530*e4b17023SJohn Marino   int i;
2531*e4b17023SJohn Marino   int j;
2532*e4b17023SJohn Marino   enum rtx_code code;
2533*e4b17023SJohn Marino   const char *fmt;
2534*e4b17023SJohn Marino   bool cslr_p = can_start_lhs_rhs_p;
2535*e4b17023SJohn Marino 
2536*e4b17023SJohn Marino   can_start_lhs_rhs_p = false;
2537*e4b17023SJohn Marino 
2538*e4b17023SJohn Marino   gcc_assert (x);
2539*e4b17023SJohn Marino   if (x == 0)
2540*e4b17023SJohn Marino     return;
2541*e4b17023SJohn Marino 
2542*e4b17023SJohn Marino   if (cslr_p && sched_deps_info->start_rhs)
2543*e4b17023SJohn Marino     sched_deps_info->start_rhs (x);
2544*e4b17023SJohn Marino 
2545*e4b17023SJohn Marino   code = GET_CODE (x);
2546*e4b17023SJohn Marino 
2547*e4b17023SJohn Marino   switch (code)
2548*e4b17023SJohn Marino     {
2549*e4b17023SJohn Marino     case CONST_INT:
2550*e4b17023SJohn Marino     case CONST_DOUBLE:
2551*e4b17023SJohn Marino     case CONST_FIXED:
2552*e4b17023SJohn Marino     case CONST_VECTOR:
2553*e4b17023SJohn Marino     case SYMBOL_REF:
2554*e4b17023SJohn Marino     case CONST:
2555*e4b17023SJohn Marino     case LABEL_REF:
2556*e4b17023SJohn Marino       /* Ignore constants.  */
2557*e4b17023SJohn Marino       if (cslr_p && sched_deps_info->finish_rhs)
2558*e4b17023SJohn Marino 	sched_deps_info->finish_rhs ();
2559*e4b17023SJohn Marino 
2560*e4b17023SJohn Marino       return;
2561*e4b17023SJohn Marino 
2562*e4b17023SJohn Marino #ifdef HAVE_cc0
2563*e4b17023SJohn Marino     case CC0:
2564*e4b17023SJohn Marino       /* User of CC0 depends on immediately preceding insn.  */
2565*e4b17023SJohn Marino       SCHED_GROUP_P (insn) = 1;
2566*e4b17023SJohn Marino        /* Don't move CC0 setter to another block (it can set up the
2567*e4b17023SJohn Marino         same flag for previous CC0 users which is safe).  */
2568*e4b17023SJohn Marino       CANT_MOVE (prev_nonnote_insn (insn)) = 1;
2569*e4b17023SJohn Marino 
2570*e4b17023SJohn Marino       if (cslr_p && sched_deps_info->finish_rhs)
2571*e4b17023SJohn Marino 	sched_deps_info->finish_rhs ();
2572*e4b17023SJohn Marino 
2573*e4b17023SJohn Marino       return;
2574*e4b17023SJohn Marino #endif
2575*e4b17023SJohn Marino 
2576*e4b17023SJohn Marino     case REG:
2577*e4b17023SJohn Marino       {
2578*e4b17023SJohn Marino 	int regno = REGNO (x);
2579*e4b17023SJohn Marino 	enum machine_mode mode = GET_MODE (x);
2580*e4b17023SJohn Marino 
2581*e4b17023SJohn Marino 	sched_analyze_reg (deps, regno, mode, USE, insn);
2582*e4b17023SJohn Marino 
2583*e4b17023SJohn Marino #ifdef STACK_REGS
2584*e4b17023SJohn Marino       /* Treat all reads of a stack register as modifying the TOS.  */
2585*e4b17023SJohn Marino       if (regno >= FIRST_STACK_REG && regno <= LAST_STACK_REG)
2586*e4b17023SJohn Marino 	{
2587*e4b17023SJohn Marino 	  /* Avoid analyzing the same register twice.  */
2588*e4b17023SJohn Marino 	  if (regno != FIRST_STACK_REG)
2589*e4b17023SJohn Marino 	    sched_analyze_reg (deps, FIRST_STACK_REG, mode, USE, insn);
2590*e4b17023SJohn Marino 	  sched_analyze_reg (deps, FIRST_STACK_REG, mode, SET, insn);
2591*e4b17023SJohn Marino 	}
2592*e4b17023SJohn Marino #endif
2593*e4b17023SJohn Marino 
2594*e4b17023SJohn Marino 	if (cslr_p && sched_deps_info->finish_rhs)
2595*e4b17023SJohn Marino 	  sched_deps_info->finish_rhs ();
2596*e4b17023SJohn Marino 
2597*e4b17023SJohn Marino 	return;
2598*e4b17023SJohn Marino       }
2599*e4b17023SJohn Marino 
2600*e4b17023SJohn Marino     case MEM:
2601*e4b17023SJohn Marino       {
2602*e4b17023SJohn Marino 	/* Reading memory.  */
2603*e4b17023SJohn Marino 	rtx u;
2604*e4b17023SJohn Marino 	rtx pending, pending_mem;
2605*e4b17023SJohn Marino 	rtx t = x;
2606*e4b17023SJohn Marino 
2607*e4b17023SJohn Marino 	if (sched_deps_info->use_cselib)
2608*e4b17023SJohn Marino 	  {
2609*e4b17023SJohn Marino 	    enum machine_mode address_mode
2610*e4b17023SJohn Marino 	      = targetm.addr_space.address_mode (MEM_ADDR_SPACE (t));
2611*e4b17023SJohn Marino 
2612*e4b17023SJohn Marino 	    t = shallow_copy_rtx (t);
2613*e4b17023SJohn Marino 	    cselib_lookup_from_insn (XEXP (t, 0), address_mode, 1,
2614*e4b17023SJohn Marino 				     GET_MODE (t), insn);
2615*e4b17023SJohn Marino 	    XEXP (t, 0)
2616*e4b17023SJohn Marino 	      = cselib_subst_to_values_from_insn (XEXP (t, 0), GET_MODE (t),
2617*e4b17023SJohn Marino 						  insn);
2618*e4b17023SJohn Marino 	  }
2619*e4b17023SJohn Marino 
2620*e4b17023SJohn Marino 	if (!DEBUG_INSN_P (insn))
2621*e4b17023SJohn Marino 	  {
2622*e4b17023SJohn Marino 	    t = canon_rtx (t);
2623*e4b17023SJohn Marino 	    pending = deps->pending_read_insns;
2624*e4b17023SJohn Marino 	    pending_mem = deps->pending_read_mems;
2625*e4b17023SJohn Marino 	    while (pending)
2626*e4b17023SJohn Marino 	      {
2627*e4b17023SJohn Marino 		if (read_dependence (XEXP (pending_mem, 0), t)
2628*e4b17023SJohn Marino 		    && ! sched_insns_conditions_mutex_p (insn,
2629*e4b17023SJohn Marino 							 XEXP (pending, 0)))
2630*e4b17023SJohn Marino 		  note_mem_dep (t, XEXP (pending_mem, 0), XEXP (pending, 0),
2631*e4b17023SJohn Marino 				DEP_ANTI);
2632*e4b17023SJohn Marino 
2633*e4b17023SJohn Marino 		pending = XEXP (pending, 1);
2634*e4b17023SJohn Marino 		pending_mem = XEXP (pending_mem, 1);
2635*e4b17023SJohn Marino 	      }
2636*e4b17023SJohn Marino 
2637*e4b17023SJohn Marino 	    pending = deps->pending_write_insns;
2638*e4b17023SJohn Marino 	    pending_mem = deps->pending_write_mems;
2639*e4b17023SJohn Marino 	    while (pending)
2640*e4b17023SJohn Marino 	      {
2641*e4b17023SJohn Marino 		if (true_dependence (XEXP (pending_mem, 0), VOIDmode, t)
2642*e4b17023SJohn Marino 		    && ! sched_insns_conditions_mutex_p (insn,
2643*e4b17023SJohn Marino 							 XEXP (pending, 0)))
2644*e4b17023SJohn Marino 		  note_mem_dep (t, XEXP (pending_mem, 0), XEXP (pending, 0),
2645*e4b17023SJohn Marino 				sched_deps_info->generate_spec_deps
2646*e4b17023SJohn Marino 				? BEGIN_DATA | DEP_TRUE : DEP_TRUE);
2647*e4b17023SJohn Marino 
2648*e4b17023SJohn Marino 		pending = XEXP (pending, 1);
2649*e4b17023SJohn Marino 		pending_mem = XEXP (pending_mem, 1);
2650*e4b17023SJohn Marino 	      }
2651*e4b17023SJohn Marino 
2652*e4b17023SJohn Marino 	    for (u = deps->last_pending_memory_flush; u; u = XEXP (u, 1))
2653*e4b17023SJohn Marino 	      add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
2654*e4b17023SJohn Marino 
2655*e4b17023SJohn Marino 	    for (u = deps->pending_jump_insns; u; u = XEXP (u, 1))
2656*e4b17023SJohn Marino 	      if (deps_may_trap_p (x))
2657*e4b17023SJohn Marino 		{
2658*e4b17023SJohn Marino 		  if ((sched_deps_info->generate_spec_deps)
2659*e4b17023SJohn Marino 		      && sel_sched_p () && (spec_info->mask & BEGIN_CONTROL))
2660*e4b17023SJohn Marino 		    {
2661*e4b17023SJohn Marino 		      ds_t ds = set_dep_weak (DEP_ANTI, BEGIN_CONTROL,
2662*e4b17023SJohn Marino 					      MAX_DEP_WEAK);
2663*e4b17023SJohn Marino 
2664*e4b17023SJohn Marino 		      note_dep (XEXP (u, 0), ds);
2665*e4b17023SJohn Marino 		    }
2666*e4b17023SJohn Marino 		  else
2667*e4b17023SJohn Marino 		    add_dependence (insn, XEXP (u, 0), REG_DEP_CONTROL);
2668*e4b17023SJohn Marino 		}
2669*e4b17023SJohn Marino 	  }
2670*e4b17023SJohn Marino 
2671*e4b17023SJohn Marino 	/* Always add these dependencies to pending_reads, since
2672*e4b17023SJohn Marino 	   this insn may be followed by a write.  */
2673*e4b17023SJohn Marino         if (!deps->readonly)
2674*e4b17023SJohn Marino           add_insn_mem_dependence (deps, true, insn, x);
2675*e4b17023SJohn Marino 
2676*e4b17023SJohn Marino 	sched_analyze_2 (deps, XEXP (x, 0), insn);
2677*e4b17023SJohn Marino 
2678*e4b17023SJohn Marino 	if (cslr_p && sched_deps_info->finish_rhs)
2679*e4b17023SJohn Marino 	  sched_deps_info->finish_rhs ();
2680*e4b17023SJohn Marino 
2681*e4b17023SJohn Marino 	return;
2682*e4b17023SJohn Marino       }
2683*e4b17023SJohn Marino 
2684*e4b17023SJohn Marino     /* Force pending stores to memory in case a trap handler needs them.  */
2685*e4b17023SJohn Marino     case TRAP_IF:
2686*e4b17023SJohn Marino       flush_pending_lists (deps, insn, true, false);
2687*e4b17023SJohn Marino       break;
2688*e4b17023SJohn Marino 
2689*e4b17023SJohn Marino     case PREFETCH:
2690*e4b17023SJohn Marino       if (PREFETCH_SCHEDULE_BARRIER_P (x))
2691*e4b17023SJohn Marino 	reg_pending_barrier = TRUE_BARRIER;
2692*e4b17023SJohn Marino       break;
2693*e4b17023SJohn Marino 
2694*e4b17023SJohn Marino     case UNSPEC_VOLATILE:
2695*e4b17023SJohn Marino       flush_pending_lists (deps, insn, true, true);
2696*e4b17023SJohn Marino       /* FALLTHRU */
2697*e4b17023SJohn Marino 
2698*e4b17023SJohn Marino     case ASM_OPERANDS:
2699*e4b17023SJohn Marino     case ASM_INPUT:
2700*e4b17023SJohn Marino       {
2701*e4b17023SJohn Marino 	/* Traditional and volatile asm instructions must be considered to use
2702*e4b17023SJohn Marino 	   and clobber all hard registers, all pseudo-registers and all of
2703*e4b17023SJohn Marino 	   memory.  So must TRAP_IF and UNSPEC_VOLATILE operations.
2704*e4b17023SJohn Marino 
2705*e4b17023SJohn Marino 	   Consider for instance a volatile asm that changes the fpu rounding
2706*e4b17023SJohn Marino 	   mode.  An insn should not be moved across this even if it only uses
2707*e4b17023SJohn Marino 	   pseudo-regs because it might give an incorrectly rounded result.  */
2708*e4b17023SJohn Marino 	if (code != ASM_OPERANDS || MEM_VOLATILE_P (x))
2709*e4b17023SJohn Marino 	  reg_pending_barrier = TRUE_BARRIER;
2710*e4b17023SJohn Marino 
2711*e4b17023SJohn Marino 	/* For all ASM_OPERANDS, we must traverse the vector of input operands.
2712*e4b17023SJohn Marino 	   We can not just fall through here since then we would be confused
2713*e4b17023SJohn Marino 	   by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate
2714*e4b17023SJohn Marino 	   traditional asms unlike their normal usage.  */
2715*e4b17023SJohn Marino 
2716*e4b17023SJohn Marino 	if (code == ASM_OPERANDS)
2717*e4b17023SJohn Marino 	  {
2718*e4b17023SJohn Marino 	    for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
2719*e4b17023SJohn Marino 	      sched_analyze_2 (deps, ASM_OPERANDS_INPUT (x, j), insn);
2720*e4b17023SJohn Marino 
2721*e4b17023SJohn Marino 	    if (cslr_p && sched_deps_info->finish_rhs)
2722*e4b17023SJohn Marino 	      sched_deps_info->finish_rhs ();
2723*e4b17023SJohn Marino 
2724*e4b17023SJohn Marino 	    return;
2725*e4b17023SJohn Marino 	  }
2726*e4b17023SJohn Marino 	break;
2727*e4b17023SJohn Marino       }
2728*e4b17023SJohn Marino 
2729*e4b17023SJohn Marino     case PRE_DEC:
2730*e4b17023SJohn Marino     case POST_DEC:
2731*e4b17023SJohn Marino     case PRE_INC:
2732*e4b17023SJohn Marino     case POST_INC:
2733*e4b17023SJohn Marino       /* These both read and modify the result.  We must handle them as writes
2734*e4b17023SJohn Marino          to get proper dependencies for following instructions.  We must handle
2735*e4b17023SJohn Marino          them as reads to get proper dependencies from this to previous
2736*e4b17023SJohn Marino          instructions.  Thus we need to pass them to both sched_analyze_1
2737*e4b17023SJohn Marino          and sched_analyze_2.  We must call sched_analyze_2 first in order
2738*e4b17023SJohn Marino          to get the proper antecedent for the read.  */
2739*e4b17023SJohn Marino       sched_analyze_2 (deps, XEXP (x, 0), insn);
2740*e4b17023SJohn Marino       sched_analyze_1 (deps, x, insn);
2741*e4b17023SJohn Marino 
2742*e4b17023SJohn Marino       if (cslr_p && sched_deps_info->finish_rhs)
2743*e4b17023SJohn Marino 	sched_deps_info->finish_rhs ();
2744*e4b17023SJohn Marino 
2745*e4b17023SJohn Marino       return;
2746*e4b17023SJohn Marino 
2747*e4b17023SJohn Marino     case POST_MODIFY:
2748*e4b17023SJohn Marino     case PRE_MODIFY:
2749*e4b17023SJohn Marino       /* op0 = op0 + op1 */
2750*e4b17023SJohn Marino       sched_analyze_2 (deps, XEXP (x, 0), insn);
2751*e4b17023SJohn Marino       sched_analyze_2 (deps, XEXP (x, 1), insn);
2752*e4b17023SJohn Marino       sched_analyze_1 (deps, x, insn);
2753*e4b17023SJohn Marino 
2754*e4b17023SJohn Marino       if (cslr_p && sched_deps_info->finish_rhs)
2755*e4b17023SJohn Marino 	sched_deps_info->finish_rhs ();
2756*e4b17023SJohn Marino 
2757*e4b17023SJohn Marino       return;
2758*e4b17023SJohn Marino 
2759*e4b17023SJohn Marino     default:
2760*e4b17023SJohn Marino       break;
2761*e4b17023SJohn Marino     }
2762*e4b17023SJohn Marino 
2763*e4b17023SJohn Marino   /* Other cases: walk the insn.  */
2764*e4b17023SJohn Marino   fmt = GET_RTX_FORMAT (code);
2765*e4b17023SJohn Marino   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2766*e4b17023SJohn Marino     {
2767*e4b17023SJohn Marino       if (fmt[i] == 'e')
2768*e4b17023SJohn Marino 	sched_analyze_2 (deps, XEXP (x, i), insn);
2769*e4b17023SJohn Marino       else if (fmt[i] == 'E')
2770*e4b17023SJohn Marino 	for (j = 0; j < XVECLEN (x, i); j++)
2771*e4b17023SJohn Marino 	  sched_analyze_2 (deps, XVECEXP (x, i, j), insn);
2772*e4b17023SJohn Marino     }
2773*e4b17023SJohn Marino 
2774*e4b17023SJohn Marino   if (cslr_p && sched_deps_info->finish_rhs)
2775*e4b17023SJohn Marino     sched_deps_info->finish_rhs ();
2776*e4b17023SJohn Marino }
2777*e4b17023SJohn Marino 
2778*e4b17023SJohn Marino /* Analyze an INSN with pattern X to find all dependencies.  */
2779*e4b17023SJohn Marino static void
2780*e4b17023SJohn Marino sched_analyze_insn (struct deps_desc *deps, rtx x, rtx insn)
2781*e4b17023SJohn Marino {
2782*e4b17023SJohn Marino   RTX_CODE code = GET_CODE (x);
2783*e4b17023SJohn Marino   rtx link;
2784*e4b17023SJohn Marino   unsigned i;
2785*e4b17023SJohn Marino   reg_set_iterator rsi;
2786*e4b17023SJohn Marino 
2787*e4b17023SJohn Marino   if (! reload_completed)
2788*e4b17023SJohn Marino     {
2789*e4b17023SJohn Marino       HARD_REG_SET temp;
2790*e4b17023SJohn Marino 
2791*e4b17023SJohn Marino       extract_insn (insn);
2792*e4b17023SJohn Marino       preprocess_constraints ();
2793*e4b17023SJohn Marino       ira_implicitly_set_insn_hard_regs (&temp);
2794*e4b17023SJohn Marino       AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
2795*e4b17023SJohn Marino       IOR_HARD_REG_SET (implicit_reg_pending_clobbers, temp);
2796*e4b17023SJohn Marino     }
2797*e4b17023SJohn Marino 
2798*e4b17023SJohn Marino   can_start_lhs_rhs_p = (NONJUMP_INSN_P (insn)
2799*e4b17023SJohn Marino 			 && code == SET);
2800*e4b17023SJohn Marino 
2801*e4b17023SJohn Marino   if (may_trap_p (x))
2802*e4b17023SJohn Marino     /* Avoid moving trapping instructions accross function calls that might
2803*e4b17023SJohn Marino        not always return.  */
2804*e4b17023SJohn Marino     add_dependence_list (insn, deps->last_function_call_may_noreturn,
2805*e4b17023SJohn Marino 			 1, REG_DEP_ANTI);
2806*e4b17023SJohn Marino 
2807*e4b17023SJohn Marino   /* We must avoid creating a situation in which two successors of the
2808*e4b17023SJohn Marino      current block have different unwind info after scheduling.  If at any
2809*e4b17023SJohn Marino      point the two paths re-join this leads to incorrect unwind info.  */
2810*e4b17023SJohn Marino   /* ??? There are certain situations involving a forced frame pointer in
2811*e4b17023SJohn Marino      which, with extra effort, we could fix up the unwind info at a later
2812*e4b17023SJohn Marino      CFG join.  However, it seems better to notice these cases earlier
2813*e4b17023SJohn Marino      during prologue generation and avoid marking the frame pointer setup
2814*e4b17023SJohn Marino      as frame-related at all.  */
2815*e4b17023SJohn Marino   if (RTX_FRAME_RELATED_P (insn))
2816*e4b17023SJohn Marino     {
2817*e4b17023SJohn Marino       /* Make sure prologue insn is scheduled before next jump.  */
2818*e4b17023SJohn Marino       deps->sched_before_next_jump
2819*e4b17023SJohn Marino 	= alloc_INSN_LIST (insn, deps->sched_before_next_jump);
2820*e4b17023SJohn Marino 
2821*e4b17023SJohn Marino       /* Make sure epilogue insn is scheduled after preceding jumps.  */
2822*e4b17023SJohn Marino       add_dependence_list (insn, deps->pending_jump_insns, 1, REG_DEP_ANTI);
2823*e4b17023SJohn Marino     }
2824*e4b17023SJohn Marino 
2825*e4b17023SJohn Marino   if (code == COND_EXEC)
2826*e4b17023SJohn Marino     {
2827*e4b17023SJohn Marino       sched_analyze_2 (deps, COND_EXEC_TEST (x), insn);
2828*e4b17023SJohn Marino 
2829*e4b17023SJohn Marino       /* ??? Should be recording conditions so we reduce the number of
2830*e4b17023SJohn Marino 	 false dependencies.  */
2831*e4b17023SJohn Marino       x = COND_EXEC_CODE (x);
2832*e4b17023SJohn Marino       code = GET_CODE (x);
2833*e4b17023SJohn Marino     }
2834*e4b17023SJohn Marino   if (code == SET || code == CLOBBER)
2835*e4b17023SJohn Marino     {
2836*e4b17023SJohn Marino       sched_analyze_1 (deps, x, insn);
2837*e4b17023SJohn Marino 
2838*e4b17023SJohn Marino       /* Bare clobber insns are used for letting life analysis, reg-stack
2839*e4b17023SJohn Marino 	 and others know that a value is dead.  Depend on the last call
2840*e4b17023SJohn Marino 	 instruction so that reg-stack won't get confused.  */
2841*e4b17023SJohn Marino       if (code == CLOBBER)
2842*e4b17023SJohn Marino 	add_dependence_list (insn, deps->last_function_call, 1,
2843*e4b17023SJohn Marino 			     REG_DEP_OUTPUT);
2844*e4b17023SJohn Marino     }
2845*e4b17023SJohn Marino   else if (code == PARALLEL)
2846*e4b17023SJohn Marino     {
2847*e4b17023SJohn Marino       for (i = XVECLEN (x, 0); i--;)
2848*e4b17023SJohn Marino 	{
2849*e4b17023SJohn Marino 	  rtx sub = XVECEXP (x, 0, i);
2850*e4b17023SJohn Marino 	  code = GET_CODE (sub);
2851*e4b17023SJohn Marino 
2852*e4b17023SJohn Marino 	  if (code == COND_EXEC)
2853*e4b17023SJohn Marino 	    {
2854*e4b17023SJohn Marino 	      sched_analyze_2 (deps, COND_EXEC_TEST (sub), insn);
2855*e4b17023SJohn Marino 	      sub = COND_EXEC_CODE (sub);
2856*e4b17023SJohn Marino 	      code = GET_CODE (sub);
2857*e4b17023SJohn Marino 	    }
2858*e4b17023SJohn Marino 	  if (code == SET || code == CLOBBER)
2859*e4b17023SJohn Marino 	    sched_analyze_1 (deps, sub, insn);
2860*e4b17023SJohn Marino 	  else
2861*e4b17023SJohn Marino 	    sched_analyze_2 (deps, sub, insn);
2862*e4b17023SJohn Marino 	}
2863*e4b17023SJohn Marino     }
2864*e4b17023SJohn Marino   else
2865*e4b17023SJohn Marino     sched_analyze_2 (deps, x, insn);
2866*e4b17023SJohn Marino 
2867*e4b17023SJohn Marino   /* Mark registers CLOBBERED or used by called function.  */
2868*e4b17023SJohn Marino   if (CALL_P (insn))
2869*e4b17023SJohn Marino     {
2870*e4b17023SJohn Marino       for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
2871*e4b17023SJohn Marino 	{
2872*e4b17023SJohn Marino 	  if (GET_CODE (XEXP (link, 0)) == CLOBBER)
2873*e4b17023SJohn Marino 	    sched_analyze_1 (deps, XEXP (link, 0), insn);
2874*e4b17023SJohn Marino 	  else
2875*e4b17023SJohn Marino 	    sched_analyze_2 (deps, XEXP (link, 0), insn);
2876*e4b17023SJohn Marino 	}
2877*e4b17023SJohn Marino       /* Don't schedule anything after a tail call, tail call needs
2878*e4b17023SJohn Marino 	 to use at least all call-saved registers.  */
2879*e4b17023SJohn Marino       if (SIBLING_CALL_P (insn))
2880*e4b17023SJohn Marino 	reg_pending_barrier = TRUE_BARRIER;
2881*e4b17023SJohn Marino       else if (find_reg_note (insn, REG_SETJMP, NULL))
2882*e4b17023SJohn Marino 	reg_pending_barrier = MOVE_BARRIER;
2883*e4b17023SJohn Marino     }
2884*e4b17023SJohn Marino 
2885*e4b17023SJohn Marino   if (JUMP_P (insn))
2886*e4b17023SJohn Marino     {
2887*e4b17023SJohn Marino       rtx next;
2888*e4b17023SJohn Marino       next = next_nonnote_nondebug_insn (insn);
2889*e4b17023SJohn Marino       if (next && BARRIER_P (next))
2890*e4b17023SJohn Marino 	reg_pending_barrier = MOVE_BARRIER;
2891*e4b17023SJohn Marino       else
2892*e4b17023SJohn Marino 	{
2893*e4b17023SJohn Marino 	  rtx pending, pending_mem;
2894*e4b17023SJohn Marino 
2895*e4b17023SJohn Marino           if (sched_deps_info->compute_jump_reg_dependencies)
2896*e4b17023SJohn Marino             {
2897*e4b17023SJohn Marino               (*sched_deps_info->compute_jump_reg_dependencies)
2898*e4b17023SJohn Marino 		(insn, reg_pending_control_uses);
2899*e4b17023SJohn Marino 
2900*e4b17023SJohn Marino               /* Make latency of jump equal to 0 by using anti-dependence.  */
2901*e4b17023SJohn Marino               EXECUTE_IF_SET_IN_REG_SET (reg_pending_control_uses, 0, i, rsi)
2902*e4b17023SJohn Marino                 {
2903*e4b17023SJohn Marino                   struct deps_reg *reg_last = &deps->reg_last[i];
2904*e4b17023SJohn Marino                   add_dependence_list (insn, reg_last->sets, 0, REG_DEP_ANTI);
2905*e4b17023SJohn Marino                   add_dependence_list (insn, reg_last->implicit_sets,
2906*e4b17023SJohn Marino 				       0, REG_DEP_ANTI);
2907*e4b17023SJohn Marino                   add_dependence_list (insn, reg_last->clobbers, 0,
2908*e4b17023SJohn Marino 				       REG_DEP_ANTI);
2909*e4b17023SJohn Marino                 }
2910*e4b17023SJohn Marino             }
2911*e4b17023SJohn Marino 
2912*e4b17023SJohn Marino 	  /* All memory writes and volatile reads must happen before the
2913*e4b17023SJohn Marino 	     jump.  Non-volatile reads must happen before the jump iff
2914*e4b17023SJohn Marino 	     the result is needed by the above register used mask.  */
2915*e4b17023SJohn Marino 
2916*e4b17023SJohn Marino 	  pending = deps->pending_write_insns;
2917*e4b17023SJohn Marino 	  pending_mem = deps->pending_write_mems;
2918*e4b17023SJohn Marino 	  while (pending)
2919*e4b17023SJohn Marino 	    {
2920*e4b17023SJohn Marino 	      if (! sched_insns_conditions_mutex_p (insn, XEXP (pending, 0)))
2921*e4b17023SJohn Marino 		add_dependence (insn, XEXP (pending, 0), REG_DEP_OUTPUT);
2922*e4b17023SJohn Marino 	      pending = XEXP (pending, 1);
2923*e4b17023SJohn Marino 	      pending_mem = XEXP (pending_mem, 1);
2924*e4b17023SJohn Marino 	    }
2925*e4b17023SJohn Marino 
2926*e4b17023SJohn Marino 	  pending = deps->pending_read_insns;
2927*e4b17023SJohn Marino 	  pending_mem = deps->pending_read_mems;
2928*e4b17023SJohn Marino 	  while (pending)
2929*e4b17023SJohn Marino 	    {
2930*e4b17023SJohn Marino 	      if (MEM_VOLATILE_P (XEXP (pending_mem, 0))
2931*e4b17023SJohn Marino 		  && ! sched_insns_conditions_mutex_p (insn, XEXP (pending, 0)))
2932*e4b17023SJohn Marino 		add_dependence (insn, XEXP (pending, 0), REG_DEP_OUTPUT);
2933*e4b17023SJohn Marino 	      pending = XEXP (pending, 1);
2934*e4b17023SJohn Marino 	      pending_mem = XEXP (pending_mem, 1);
2935*e4b17023SJohn Marino 	    }
2936*e4b17023SJohn Marino 
2937*e4b17023SJohn Marino 	  add_dependence_list (insn, deps->last_pending_memory_flush, 1,
2938*e4b17023SJohn Marino 			       REG_DEP_ANTI);
2939*e4b17023SJohn Marino 	  add_dependence_list (insn, deps->pending_jump_insns, 1,
2940*e4b17023SJohn Marino 			       REG_DEP_ANTI);
2941*e4b17023SJohn Marino 	}
2942*e4b17023SJohn Marino     }
2943*e4b17023SJohn Marino 
2944*e4b17023SJohn Marino   /* If this instruction can throw an exception, then moving it changes
2945*e4b17023SJohn Marino      where block boundaries fall.  This is mighty confusing elsewhere.
2946*e4b17023SJohn Marino      Therefore, prevent such an instruction from being moved.  Same for
2947*e4b17023SJohn Marino      non-jump instructions that define block boundaries.
2948*e4b17023SJohn Marino      ??? Unclear whether this is still necessary in EBB mode.  If not,
2949*e4b17023SJohn Marino      add_branch_dependences should be adjusted for RGN mode instead.  */
2950*e4b17023SJohn Marino   if (((CALL_P (insn) || JUMP_P (insn)) && can_throw_internal (insn))
2951*e4b17023SJohn Marino       || (NONJUMP_INSN_P (insn) && control_flow_insn_p (insn)))
2952*e4b17023SJohn Marino     reg_pending_barrier = MOVE_BARRIER;
2953*e4b17023SJohn Marino 
2954*e4b17023SJohn Marino   if (sched_pressure_p)
2955*e4b17023SJohn Marino     {
2956*e4b17023SJohn Marino       setup_insn_reg_uses (deps, insn);
2957*e4b17023SJohn Marino       init_insn_reg_pressure_info (insn);
2958*e4b17023SJohn Marino     }
2959*e4b17023SJohn Marino 
2960*e4b17023SJohn Marino   /* Add register dependencies for insn.  */
2961*e4b17023SJohn Marino   if (DEBUG_INSN_P (insn))
2962*e4b17023SJohn Marino     {
2963*e4b17023SJohn Marino       rtx prev = deps->last_debug_insn;
2964*e4b17023SJohn Marino       rtx u;
2965*e4b17023SJohn Marino 
2966*e4b17023SJohn Marino       if (!deps->readonly)
2967*e4b17023SJohn Marino 	deps->last_debug_insn = insn;
2968*e4b17023SJohn Marino 
2969*e4b17023SJohn Marino       if (prev)
2970*e4b17023SJohn Marino 	add_dependence (insn, prev, REG_DEP_ANTI);
2971*e4b17023SJohn Marino 
2972*e4b17023SJohn Marino       add_dependence_list (insn, deps->last_function_call, 1,
2973*e4b17023SJohn Marino 			   REG_DEP_ANTI);
2974*e4b17023SJohn Marino 
2975*e4b17023SJohn Marino       for (u = deps->last_pending_memory_flush; u; u = XEXP (u, 1))
2976*e4b17023SJohn Marino 	if (!sel_sched_p ())
2977*e4b17023SJohn Marino 	  add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
2978*e4b17023SJohn Marino 
2979*e4b17023SJohn Marino       EXECUTE_IF_SET_IN_REG_SET (reg_pending_uses, 0, i, rsi)
2980*e4b17023SJohn Marino 	{
2981*e4b17023SJohn Marino 	  struct deps_reg *reg_last = &deps->reg_last[i];
2982*e4b17023SJohn Marino 	  add_dependence_list (insn, reg_last->sets, 1, REG_DEP_ANTI);
2983*e4b17023SJohn Marino 	  /* There's no point in making REG_DEP_CONTROL dependencies for
2984*e4b17023SJohn Marino 	     debug insns.  */
2985*e4b17023SJohn Marino 	  add_dependence_list (insn, reg_last->clobbers, 1, REG_DEP_ANTI);
2986*e4b17023SJohn Marino 
2987*e4b17023SJohn Marino 	  if (!deps->readonly)
2988*e4b17023SJohn Marino 	    reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
2989*e4b17023SJohn Marino 	}
2990*e4b17023SJohn Marino       CLEAR_REG_SET (reg_pending_uses);
2991*e4b17023SJohn Marino 
2992*e4b17023SJohn Marino       /* Quite often, a debug insn will refer to stuff in the
2993*e4b17023SJohn Marino 	 previous instruction, but the reason we want this
2994*e4b17023SJohn Marino 	 dependency here is to make sure the scheduler doesn't
2995*e4b17023SJohn Marino 	 gratuitously move a debug insn ahead.  This could dirty
2996*e4b17023SJohn Marino 	 DF flags and cause additional analysis that wouldn't have
2997*e4b17023SJohn Marino 	 occurred in compilation without debug insns, and such
2998*e4b17023SJohn Marino 	 additional analysis can modify the generated code.  */
2999*e4b17023SJohn Marino       prev = PREV_INSN (insn);
3000*e4b17023SJohn Marino 
3001*e4b17023SJohn Marino       if (prev && NONDEBUG_INSN_P (prev))
3002*e4b17023SJohn Marino 	add_dependence (insn, prev, REG_DEP_ANTI);
3003*e4b17023SJohn Marino     }
3004*e4b17023SJohn Marino   else
3005*e4b17023SJohn Marino     {
3006*e4b17023SJohn Marino       regset_head set_or_clobbered;
3007*e4b17023SJohn Marino 
3008*e4b17023SJohn Marino       EXECUTE_IF_SET_IN_REG_SET (reg_pending_uses, 0, i, rsi)
3009*e4b17023SJohn Marino 	{
3010*e4b17023SJohn Marino 	  struct deps_reg *reg_last = &deps->reg_last[i];
3011*e4b17023SJohn Marino 	  add_dependence_list (insn, reg_last->sets, 0, REG_DEP_TRUE);
3012*e4b17023SJohn Marino 	  add_dependence_list (insn, reg_last->implicit_sets, 0, REG_DEP_ANTI);
3013*e4b17023SJohn Marino 	  add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_TRUE);
3014*e4b17023SJohn Marino 
3015*e4b17023SJohn Marino 	  if (!deps->readonly)
3016*e4b17023SJohn Marino 	    {
3017*e4b17023SJohn Marino 	      reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
3018*e4b17023SJohn Marino 	      reg_last->uses_length++;
3019*e4b17023SJohn Marino 	    }
3020*e4b17023SJohn Marino 	}
3021*e4b17023SJohn Marino 
3022*e4b17023SJohn Marino       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3023*e4b17023SJohn Marino 	if (TEST_HARD_REG_BIT (implicit_reg_pending_uses, i))
3024*e4b17023SJohn Marino 	  {
3025*e4b17023SJohn Marino 	    struct deps_reg *reg_last = &deps->reg_last[i];
3026*e4b17023SJohn Marino 	    add_dependence_list (insn, reg_last->sets, 0, REG_DEP_TRUE);
3027*e4b17023SJohn Marino 	    add_dependence_list (insn, reg_last->implicit_sets, 0,
3028*e4b17023SJohn Marino 				 REG_DEP_ANTI);
3029*e4b17023SJohn Marino 	    add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_TRUE);
3030*e4b17023SJohn Marino 
3031*e4b17023SJohn Marino 	    if (!deps->readonly)
3032*e4b17023SJohn Marino 	      {
3033*e4b17023SJohn Marino 		reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
3034*e4b17023SJohn Marino 		reg_last->uses_length++;
3035*e4b17023SJohn Marino 	      }
3036*e4b17023SJohn Marino 	  }
3037*e4b17023SJohn Marino 
3038*e4b17023SJohn Marino       if (targetm.sched.exposed_pipeline)
3039*e4b17023SJohn Marino 	{
3040*e4b17023SJohn Marino 	  INIT_REG_SET (&set_or_clobbered);
3041*e4b17023SJohn Marino 	  bitmap_ior (&set_or_clobbered, reg_pending_clobbers,
3042*e4b17023SJohn Marino 		      reg_pending_sets);
3043*e4b17023SJohn Marino 	  EXECUTE_IF_SET_IN_REG_SET (&set_or_clobbered, 0, i, rsi)
3044*e4b17023SJohn Marino 	    {
3045*e4b17023SJohn Marino 	      struct deps_reg *reg_last = &deps->reg_last[i];
3046*e4b17023SJohn Marino 	      rtx list;
3047*e4b17023SJohn Marino 	      for (list = reg_last->uses; list; list = XEXP (list, 1))
3048*e4b17023SJohn Marino 		{
3049*e4b17023SJohn Marino 		  rtx other = XEXP (list, 0);
3050*e4b17023SJohn Marino 		  if (INSN_CACHED_COND (other) != const_true_rtx
3051*e4b17023SJohn Marino 		      && refers_to_regno_p (i, i + 1, INSN_CACHED_COND (other), NULL))
3052*e4b17023SJohn Marino 		    INSN_CACHED_COND (other) = const_true_rtx;
3053*e4b17023SJohn Marino 		}
3054*e4b17023SJohn Marino 	    }
3055*e4b17023SJohn Marino 	}
3056*e4b17023SJohn Marino 
3057*e4b17023SJohn Marino       /* If the current insn is conditional, we can't free any
3058*e4b17023SJohn Marino 	 of the lists.  */
3059*e4b17023SJohn Marino       if (sched_has_condition_p (insn))
3060*e4b17023SJohn Marino 	{
3061*e4b17023SJohn Marino 	  EXECUTE_IF_SET_IN_REG_SET (reg_pending_clobbers, 0, i, rsi)
3062*e4b17023SJohn Marino 	    {
3063*e4b17023SJohn Marino 	      struct deps_reg *reg_last = &deps->reg_last[i];
3064*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->sets, 0, REG_DEP_OUTPUT);
3065*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->implicit_sets, 0,
3066*e4b17023SJohn Marino 				   REG_DEP_ANTI);
3067*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI);
3068*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->control_uses, 0,
3069*e4b17023SJohn Marino 				   REG_DEP_CONTROL);
3070*e4b17023SJohn Marino 
3071*e4b17023SJohn Marino 	      if (!deps->readonly)
3072*e4b17023SJohn Marino 		{
3073*e4b17023SJohn Marino 		  reg_last->clobbers
3074*e4b17023SJohn Marino 		    = alloc_INSN_LIST (insn, reg_last->clobbers);
3075*e4b17023SJohn Marino 		  reg_last->clobbers_length++;
3076*e4b17023SJohn Marino 		}
3077*e4b17023SJohn Marino 	    }
3078*e4b17023SJohn Marino 	  EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i, rsi)
3079*e4b17023SJohn Marino 	    {
3080*e4b17023SJohn Marino 	      struct deps_reg *reg_last = &deps->reg_last[i];
3081*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->sets, 0, REG_DEP_OUTPUT);
3082*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->implicit_sets, 0,
3083*e4b17023SJohn Marino 				   REG_DEP_ANTI);
3084*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_OUTPUT);
3085*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI);
3086*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->control_uses, 0,
3087*e4b17023SJohn Marino 				   REG_DEP_CONTROL);
3088*e4b17023SJohn Marino 
3089*e4b17023SJohn Marino 	      if (!deps->readonly)
3090*e4b17023SJohn Marino 		reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
3091*e4b17023SJohn Marino 	    }
3092*e4b17023SJohn Marino 	}
3093*e4b17023SJohn Marino       else
3094*e4b17023SJohn Marino 	{
3095*e4b17023SJohn Marino 	  EXECUTE_IF_SET_IN_REG_SET (reg_pending_clobbers, 0, i, rsi)
3096*e4b17023SJohn Marino 	    {
3097*e4b17023SJohn Marino 	      struct deps_reg *reg_last = &deps->reg_last[i];
3098*e4b17023SJohn Marino 	      if (reg_last->uses_length > MAX_PENDING_LIST_LENGTH
3099*e4b17023SJohn Marino 		  || reg_last->clobbers_length > MAX_PENDING_LIST_LENGTH)
3100*e4b17023SJohn Marino 		{
3101*e4b17023SJohn Marino 		  add_dependence_list_and_free (deps, insn, &reg_last->sets, 0,
3102*e4b17023SJohn Marino 						REG_DEP_OUTPUT);
3103*e4b17023SJohn Marino 		  add_dependence_list_and_free (deps, insn,
3104*e4b17023SJohn Marino 						&reg_last->implicit_sets, 0,
3105*e4b17023SJohn Marino 						REG_DEP_ANTI);
3106*e4b17023SJohn Marino 		  add_dependence_list_and_free (deps, insn, &reg_last->uses, 0,
3107*e4b17023SJohn Marino 						REG_DEP_ANTI);
3108*e4b17023SJohn Marino 		  add_dependence_list_and_free (deps, insn,
3109*e4b17023SJohn Marino 						&reg_last->control_uses, 0,
3110*e4b17023SJohn Marino 						REG_DEP_ANTI);
3111*e4b17023SJohn Marino 		  add_dependence_list_and_free
3112*e4b17023SJohn Marino 		    (deps, insn, &reg_last->clobbers, 0, REG_DEP_OUTPUT);
3113*e4b17023SJohn Marino 
3114*e4b17023SJohn Marino 		  if (!deps->readonly)
3115*e4b17023SJohn Marino 		    {
3116*e4b17023SJohn Marino 		      reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
3117*e4b17023SJohn Marino 		      reg_last->clobbers_length = 0;
3118*e4b17023SJohn Marino 		      reg_last->uses_length = 0;
3119*e4b17023SJohn Marino 		    }
3120*e4b17023SJohn Marino 		}
3121*e4b17023SJohn Marino 	      else
3122*e4b17023SJohn Marino 		{
3123*e4b17023SJohn Marino 		  add_dependence_list (insn, reg_last->sets, 0, REG_DEP_OUTPUT);
3124*e4b17023SJohn Marino 		  add_dependence_list (insn, reg_last->implicit_sets, 0,
3125*e4b17023SJohn Marino 				       REG_DEP_ANTI);
3126*e4b17023SJohn Marino 		  add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI);
3127*e4b17023SJohn Marino 		  add_dependence_list (insn, reg_last->control_uses, 0,
3128*e4b17023SJohn Marino 				       REG_DEP_CONTROL);
3129*e4b17023SJohn Marino 		}
3130*e4b17023SJohn Marino 
3131*e4b17023SJohn Marino 	      if (!deps->readonly)
3132*e4b17023SJohn Marino 		{
3133*e4b17023SJohn Marino 		  reg_last->clobbers_length++;
3134*e4b17023SJohn Marino 		  reg_last->clobbers
3135*e4b17023SJohn Marino 		    = alloc_INSN_LIST (insn, reg_last->clobbers);
3136*e4b17023SJohn Marino 		}
3137*e4b17023SJohn Marino 	    }
3138*e4b17023SJohn Marino 	  EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i, rsi)
3139*e4b17023SJohn Marino 	    {
3140*e4b17023SJohn Marino 	      struct deps_reg *reg_last = &deps->reg_last[i];
3141*e4b17023SJohn Marino 
3142*e4b17023SJohn Marino 	      add_dependence_list_and_free (deps, insn, &reg_last->sets, 0,
3143*e4b17023SJohn Marino 					    REG_DEP_OUTPUT);
3144*e4b17023SJohn Marino 	      add_dependence_list_and_free (deps, insn,
3145*e4b17023SJohn Marino 					    &reg_last->implicit_sets,
3146*e4b17023SJohn Marino 					    0, REG_DEP_ANTI);
3147*e4b17023SJohn Marino 	      add_dependence_list_and_free (deps, insn, &reg_last->clobbers, 0,
3148*e4b17023SJohn Marino 					    REG_DEP_OUTPUT);
3149*e4b17023SJohn Marino 	      add_dependence_list_and_free (deps, insn, &reg_last->uses, 0,
3150*e4b17023SJohn Marino 					    REG_DEP_ANTI);
3151*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->control_uses, 0,
3152*e4b17023SJohn Marino 				   REG_DEP_CONTROL);
3153*e4b17023SJohn Marino 
3154*e4b17023SJohn Marino 	      if (!deps->readonly)
3155*e4b17023SJohn Marino 		{
3156*e4b17023SJohn Marino 		  reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
3157*e4b17023SJohn Marino 		  reg_last->uses_length = 0;
3158*e4b17023SJohn Marino 		  reg_last->clobbers_length = 0;
3159*e4b17023SJohn Marino 		}
3160*e4b17023SJohn Marino 	    }
3161*e4b17023SJohn Marino 	}
3162*e4b17023SJohn Marino       if (!deps->readonly)
3163*e4b17023SJohn Marino 	{
3164*e4b17023SJohn Marino 	  EXECUTE_IF_SET_IN_REG_SET (reg_pending_control_uses, 0, i, rsi)
3165*e4b17023SJohn Marino 	    {
3166*e4b17023SJohn Marino 	      struct deps_reg *reg_last = &deps->reg_last[i];
3167*e4b17023SJohn Marino 	      reg_last->control_uses
3168*e4b17023SJohn Marino 		= alloc_INSN_LIST (insn, reg_last->control_uses);
3169*e4b17023SJohn Marino 	    }
3170*e4b17023SJohn Marino 	}
3171*e4b17023SJohn Marino     }
3172*e4b17023SJohn Marino 
3173*e4b17023SJohn Marino   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3174*e4b17023SJohn Marino     if (TEST_HARD_REG_BIT (implicit_reg_pending_clobbers, i))
3175*e4b17023SJohn Marino       {
3176*e4b17023SJohn Marino 	struct deps_reg *reg_last = &deps->reg_last[i];
3177*e4b17023SJohn Marino 	add_dependence_list (insn, reg_last->sets, 0, REG_DEP_ANTI);
3178*e4b17023SJohn Marino 	add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_ANTI);
3179*e4b17023SJohn Marino 	add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI);
3180*e4b17023SJohn Marino 	add_dependence_list (insn, reg_last->control_uses, 0, REG_DEP_ANTI);
3181*e4b17023SJohn Marino 
3182*e4b17023SJohn Marino 	if (!deps->readonly)
3183*e4b17023SJohn Marino 	  reg_last->implicit_sets
3184*e4b17023SJohn Marino 	    = alloc_INSN_LIST (insn, reg_last->implicit_sets);
3185*e4b17023SJohn Marino       }
3186*e4b17023SJohn Marino 
3187*e4b17023SJohn Marino   if (!deps->readonly)
3188*e4b17023SJohn Marino     {
3189*e4b17023SJohn Marino       IOR_REG_SET (&deps->reg_last_in_use, reg_pending_uses);
3190*e4b17023SJohn Marino       IOR_REG_SET (&deps->reg_last_in_use, reg_pending_clobbers);
3191*e4b17023SJohn Marino       IOR_REG_SET (&deps->reg_last_in_use, reg_pending_sets);
3192*e4b17023SJohn Marino       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3193*e4b17023SJohn Marino 	if (TEST_HARD_REG_BIT (implicit_reg_pending_uses, i)
3194*e4b17023SJohn Marino 	    || TEST_HARD_REG_BIT (implicit_reg_pending_clobbers, i))
3195*e4b17023SJohn Marino 	  SET_REGNO_REG_SET (&deps->reg_last_in_use, i);
3196*e4b17023SJohn Marino 
3197*e4b17023SJohn Marino       /* Set up the pending barrier found.  */
3198*e4b17023SJohn Marino       deps->last_reg_pending_barrier = reg_pending_barrier;
3199*e4b17023SJohn Marino     }
3200*e4b17023SJohn Marino 
3201*e4b17023SJohn Marino   CLEAR_REG_SET (reg_pending_uses);
3202*e4b17023SJohn Marino   CLEAR_REG_SET (reg_pending_clobbers);
3203*e4b17023SJohn Marino   CLEAR_REG_SET (reg_pending_sets);
3204*e4b17023SJohn Marino   CLEAR_REG_SET (reg_pending_control_uses);
3205*e4b17023SJohn Marino   CLEAR_HARD_REG_SET (implicit_reg_pending_clobbers);
3206*e4b17023SJohn Marino   CLEAR_HARD_REG_SET (implicit_reg_pending_uses);
3207*e4b17023SJohn Marino 
3208*e4b17023SJohn Marino   /* Add dependencies if a scheduling barrier was found.  */
3209*e4b17023SJohn Marino   if (reg_pending_barrier)
3210*e4b17023SJohn Marino     {
3211*e4b17023SJohn Marino       /* In the case of barrier the most added dependencies are not
3212*e4b17023SJohn Marino          real, so we use anti-dependence here.  */
3213*e4b17023SJohn Marino       if (sched_has_condition_p (insn))
3214*e4b17023SJohn Marino 	{
3215*e4b17023SJohn Marino 	  EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i, rsi)
3216*e4b17023SJohn Marino 	    {
3217*e4b17023SJohn Marino 	      struct deps_reg *reg_last = &deps->reg_last[i];
3218*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI);
3219*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->sets, 0,
3220*e4b17023SJohn Marino 				   reg_pending_barrier == TRUE_BARRIER
3221*e4b17023SJohn Marino 				   ? REG_DEP_TRUE : REG_DEP_ANTI);
3222*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->implicit_sets, 0,
3223*e4b17023SJohn Marino 				   REG_DEP_ANTI);
3224*e4b17023SJohn Marino 	      add_dependence_list (insn, reg_last->clobbers, 0,
3225*e4b17023SJohn Marino 				   reg_pending_barrier == TRUE_BARRIER
3226*e4b17023SJohn Marino 				   ? REG_DEP_TRUE : REG_DEP_ANTI);
3227*e4b17023SJohn Marino 	    }
3228*e4b17023SJohn Marino 	}
3229*e4b17023SJohn Marino       else
3230*e4b17023SJohn Marino 	{
3231*e4b17023SJohn Marino 	  EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i, rsi)
3232*e4b17023SJohn Marino 	    {
3233*e4b17023SJohn Marino 	      struct deps_reg *reg_last = &deps->reg_last[i];
3234*e4b17023SJohn Marino 	      add_dependence_list_and_free (deps, insn, &reg_last->uses, 0,
3235*e4b17023SJohn Marino 					    REG_DEP_ANTI);
3236*e4b17023SJohn Marino 	      add_dependence_list_and_free (deps, insn,
3237*e4b17023SJohn Marino 					    &reg_last->control_uses, 0,
3238*e4b17023SJohn Marino 					    REG_DEP_CONTROL);
3239*e4b17023SJohn Marino 	      add_dependence_list_and_free (deps, insn, &reg_last->sets, 0,
3240*e4b17023SJohn Marino 					    reg_pending_barrier == TRUE_BARRIER
3241*e4b17023SJohn Marino 					    ? REG_DEP_TRUE : REG_DEP_ANTI);
3242*e4b17023SJohn Marino 	      add_dependence_list_and_free (deps, insn,
3243*e4b17023SJohn Marino 					    &reg_last->implicit_sets, 0,
3244*e4b17023SJohn Marino 					    REG_DEP_ANTI);
3245*e4b17023SJohn Marino 	      add_dependence_list_and_free (deps, insn, &reg_last->clobbers, 0,
3246*e4b17023SJohn Marino 					    reg_pending_barrier == TRUE_BARRIER
3247*e4b17023SJohn Marino 					    ? REG_DEP_TRUE : REG_DEP_ANTI);
3248*e4b17023SJohn Marino 
3249*e4b17023SJohn Marino               if (!deps->readonly)
3250*e4b17023SJohn Marino                 {
3251*e4b17023SJohn Marino                   reg_last->uses_length = 0;
3252*e4b17023SJohn Marino                   reg_last->clobbers_length = 0;
3253*e4b17023SJohn Marino                 }
3254*e4b17023SJohn Marino 	    }
3255*e4b17023SJohn Marino 	}
3256*e4b17023SJohn Marino 
3257*e4b17023SJohn Marino       if (!deps->readonly)
3258*e4b17023SJohn Marino         for (i = 0; i < (unsigned)deps->max_reg; i++)
3259*e4b17023SJohn Marino           {
3260*e4b17023SJohn Marino             struct deps_reg *reg_last = &deps->reg_last[i];
3261*e4b17023SJohn Marino             reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
3262*e4b17023SJohn Marino             SET_REGNO_REG_SET (&deps->reg_last_in_use, i);
3263*e4b17023SJohn Marino           }
3264*e4b17023SJohn Marino 
3265*e4b17023SJohn Marino       /* Flush pending lists on jumps, but not on speculative checks.  */
3266*e4b17023SJohn Marino       if (JUMP_P (insn) && !(sel_sched_p ()
3267*e4b17023SJohn Marino                              && sel_insn_is_speculation_check (insn)))
3268*e4b17023SJohn Marino 	flush_pending_lists (deps, insn, true, true);
3269*e4b17023SJohn Marino 
3270*e4b17023SJohn Marino       reg_pending_barrier = NOT_A_BARRIER;
3271*e4b17023SJohn Marino     }
3272*e4b17023SJohn Marino 
3273*e4b17023SJohn Marino   /* If a post-call group is still open, see if it should remain so.
3274*e4b17023SJohn Marino      This insn must be a simple move of a hard reg to a pseudo or
3275*e4b17023SJohn Marino      vice-versa.
3276*e4b17023SJohn Marino 
3277*e4b17023SJohn Marino      We must avoid moving these insns for correctness on targets
3278*e4b17023SJohn Marino      with small register classes, and for special registers like
3279*e4b17023SJohn Marino      PIC_OFFSET_TABLE_REGNUM.  For simplicity, extend this to all
3280*e4b17023SJohn Marino      hard regs for all targets.  */
3281*e4b17023SJohn Marino 
3282*e4b17023SJohn Marino   if (deps->in_post_call_group_p)
3283*e4b17023SJohn Marino     {
3284*e4b17023SJohn Marino       rtx tmp, set = single_set (insn);
3285*e4b17023SJohn Marino       int src_regno, dest_regno;
3286*e4b17023SJohn Marino 
3287*e4b17023SJohn Marino       if (set == NULL)
3288*e4b17023SJohn Marino 	{
3289*e4b17023SJohn Marino 	  if (DEBUG_INSN_P (insn))
3290*e4b17023SJohn Marino 	    /* We don't want to mark debug insns as part of the same
3291*e4b17023SJohn Marino 	       sched group.  We know they really aren't, but if we use
3292*e4b17023SJohn Marino 	       debug insns to tell that a call group is over, we'll
3293*e4b17023SJohn Marino 	       get different code if debug insns are not there and
3294*e4b17023SJohn Marino 	       instructions that follow seem like they should be part
3295*e4b17023SJohn Marino 	       of the call group.
3296*e4b17023SJohn Marino 
3297*e4b17023SJohn Marino 	       Also, if we did, fixup_sched_groups() would move the
3298*e4b17023SJohn Marino 	       deps of the debug insn to the call insn, modifying
3299*e4b17023SJohn Marino 	       non-debug post-dependency counts of the debug insn
3300*e4b17023SJohn Marino 	       dependencies and otherwise messing with the scheduling
3301*e4b17023SJohn Marino 	       order.
3302*e4b17023SJohn Marino 
3303*e4b17023SJohn Marino 	       Instead, let such debug insns be scheduled freely, but
3304*e4b17023SJohn Marino 	       keep the call group open in case there are insns that
3305*e4b17023SJohn Marino 	       should be part of it afterwards.  Since we grant debug
3306*e4b17023SJohn Marino 	       insns higher priority than even sched group insns, it
3307*e4b17023SJohn Marino 	       will all turn out all right.  */
3308*e4b17023SJohn Marino 	    goto debug_dont_end_call_group;
3309*e4b17023SJohn Marino 	  else
3310*e4b17023SJohn Marino 	    goto end_call_group;
3311*e4b17023SJohn Marino 	}
3312*e4b17023SJohn Marino 
3313*e4b17023SJohn Marino       tmp = SET_DEST (set);
3314*e4b17023SJohn Marino       if (GET_CODE (tmp) == SUBREG)
3315*e4b17023SJohn Marino 	tmp = SUBREG_REG (tmp);
3316*e4b17023SJohn Marino       if (REG_P (tmp))
3317*e4b17023SJohn Marino 	dest_regno = REGNO (tmp);
3318*e4b17023SJohn Marino       else
3319*e4b17023SJohn Marino 	goto end_call_group;
3320*e4b17023SJohn Marino 
3321*e4b17023SJohn Marino       tmp = SET_SRC (set);
3322*e4b17023SJohn Marino       if (GET_CODE (tmp) == SUBREG)
3323*e4b17023SJohn Marino 	tmp = SUBREG_REG (tmp);
3324*e4b17023SJohn Marino       if ((GET_CODE (tmp) == PLUS
3325*e4b17023SJohn Marino 	   || GET_CODE (tmp) == MINUS)
3326*e4b17023SJohn Marino 	  && REG_P (XEXP (tmp, 0))
3327*e4b17023SJohn Marino 	  && REGNO (XEXP (tmp, 0)) == STACK_POINTER_REGNUM
3328*e4b17023SJohn Marino 	  && dest_regno == STACK_POINTER_REGNUM)
3329*e4b17023SJohn Marino 	src_regno = STACK_POINTER_REGNUM;
3330*e4b17023SJohn Marino       else if (REG_P (tmp))
3331*e4b17023SJohn Marino 	src_regno = REGNO (tmp);
3332*e4b17023SJohn Marino       else
3333*e4b17023SJohn Marino 	goto end_call_group;
3334*e4b17023SJohn Marino 
3335*e4b17023SJohn Marino       if (src_regno < FIRST_PSEUDO_REGISTER
3336*e4b17023SJohn Marino 	  || dest_regno < FIRST_PSEUDO_REGISTER)
3337*e4b17023SJohn Marino 	{
3338*e4b17023SJohn Marino 	  if (!deps->readonly
3339*e4b17023SJohn Marino               && deps->in_post_call_group_p == post_call_initial)
3340*e4b17023SJohn Marino 	    deps->in_post_call_group_p = post_call;
3341*e4b17023SJohn Marino 
3342*e4b17023SJohn Marino           if (!sel_sched_p () || sched_emulate_haifa_p)
3343*e4b17023SJohn Marino             {
3344*e4b17023SJohn Marino               SCHED_GROUP_P (insn) = 1;
3345*e4b17023SJohn Marino               CANT_MOVE (insn) = 1;
3346*e4b17023SJohn Marino             }
3347*e4b17023SJohn Marino 	}
3348*e4b17023SJohn Marino       else
3349*e4b17023SJohn Marino 	{
3350*e4b17023SJohn Marino 	end_call_group:
3351*e4b17023SJohn Marino           if (!deps->readonly)
3352*e4b17023SJohn Marino             deps->in_post_call_group_p = not_post_call;
3353*e4b17023SJohn Marino 	}
3354*e4b17023SJohn Marino     }
3355*e4b17023SJohn Marino 
3356*e4b17023SJohn Marino  debug_dont_end_call_group:
3357*e4b17023SJohn Marino   if ((current_sched_info->flags & DO_SPECULATION)
3358*e4b17023SJohn Marino       && !sched_insn_is_legitimate_for_speculation_p (insn, 0))
3359*e4b17023SJohn Marino     /* INSN has an internal dependency (e.g. r14 = [r14]) and thus cannot
3360*e4b17023SJohn Marino        be speculated.  */
3361*e4b17023SJohn Marino     {
3362*e4b17023SJohn Marino       if (sel_sched_p ())
3363*e4b17023SJohn Marino         sel_mark_hard_insn (insn);
3364*e4b17023SJohn Marino       else
3365*e4b17023SJohn Marino         {
3366*e4b17023SJohn Marino           sd_iterator_def sd_it;
3367*e4b17023SJohn Marino           dep_t dep;
3368*e4b17023SJohn Marino 
3369*e4b17023SJohn Marino           for (sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
3370*e4b17023SJohn Marino                sd_iterator_cond (&sd_it, &dep);)
3371*e4b17023SJohn Marino             change_spec_dep_to_hard (sd_it);
3372*e4b17023SJohn Marino         }
3373*e4b17023SJohn Marino     }
3374*e4b17023SJohn Marino }
3375*e4b17023SJohn Marino 
3376*e4b17023SJohn Marino /* Return TRUE if INSN might not always return normally (e.g. call exit,
3377*e4b17023SJohn Marino    longjmp, loop forever, ...).  */
3378*e4b17023SJohn Marino static bool
3379*e4b17023SJohn Marino call_may_noreturn_p (rtx insn)
3380*e4b17023SJohn Marino {
3381*e4b17023SJohn Marino   rtx call;
3382*e4b17023SJohn Marino 
3383*e4b17023SJohn Marino   /* const or pure calls that aren't looping will always return.  */
3384*e4b17023SJohn Marino   if (RTL_CONST_OR_PURE_CALL_P (insn)
3385*e4b17023SJohn Marino       && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))
3386*e4b17023SJohn Marino     return false;
3387*e4b17023SJohn Marino 
3388*e4b17023SJohn Marino   call = PATTERN (insn);
3389*e4b17023SJohn Marino   if (GET_CODE (call) == PARALLEL)
3390*e4b17023SJohn Marino     call = XVECEXP (call, 0, 0);
3391*e4b17023SJohn Marino   if (GET_CODE (call) == SET)
3392*e4b17023SJohn Marino     call = SET_SRC (call);
3393*e4b17023SJohn Marino   if (GET_CODE (call) == CALL
3394*e4b17023SJohn Marino       && MEM_P (XEXP (call, 0))
3395*e4b17023SJohn Marino       && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
3396*e4b17023SJohn Marino     {
3397*e4b17023SJohn Marino       rtx symbol = XEXP (XEXP (call, 0), 0);
3398*e4b17023SJohn Marino       if (SYMBOL_REF_DECL (symbol)
3399*e4b17023SJohn Marino 	  && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL)
3400*e4b17023SJohn Marino 	{
3401*e4b17023SJohn Marino 	  if (DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (symbol))
3402*e4b17023SJohn Marino 	      == BUILT_IN_NORMAL)
3403*e4b17023SJohn Marino 	    switch (DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol)))
3404*e4b17023SJohn Marino 	      {
3405*e4b17023SJohn Marino 	      case BUILT_IN_BCMP:
3406*e4b17023SJohn Marino 	      case BUILT_IN_BCOPY:
3407*e4b17023SJohn Marino 	      case BUILT_IN_BZERO:
3408*e4b17023SJohn Marino 	      case BUILT_IN_INDEX:
3409*e4b17023SJohn Marino 	      case BUILT_IN_MEMCHR:
3410*e4b17023SJohn Marino 	      case BUILT_IN_MEMCMP:
3411*e4b17023SJohn Marino 	      case BUILT_IN_MEMCPY:
3412*e4b17023SJohn Marino 	      case BUILT_IN_MEMMOVE:
3413*e4b17023SJohn Marino 	      case BUILT_IN_MEMPCPY:
3414*e4b17023SJohn Marino 	      case BUILT_IN_MEMSET:
3415*e4b17023SJohn Marino 	      case BUILT_IN_RINDEX:
3416*e4b17023SJohn Marino 	      case BUILT_IN_STPCPY:
3417*e4b17023SJohn Marino 	      case BUILT_IN_STPNCPY:
3418*e4b17023SJohn Marino 	      case BUILT_IN_STRCAT:
3419*e4b17023SJohn Marino 	      case BUILT_IN_STRCHR:
3420*e4b17023SJohn Marino 	      case BUILT_IN_STRCMP:
3421*e4b17023SJohn Marino 	      case BUILT_IN_STRCPY:
3422*e4b17023SJohn Marino 	      case BUILT_IN_STRCSPN:
3423*e4b17023SJohn Marino 	      case BUILT_IN_STRLEN:
3424*e4b17023SJohn Marino 	      case BUILT_IN_STRNCAT:
3425*e4b17023SJohn Marino 	      case BUILT_IN_STRNCMP:
3426*e4b17023SJohn Marino 	      case BUILT_IN_STRNCPY:
3427*e4b17023SJohn Marino 	      case BUILT_IN_STRPBRK:
3428*e4b17023SJohn Marino 	      case BUILT_IN_STRRCHR:
3429*e4b17023SJohn Marino 	      case BUILT_IN_STRSPN:
3430*e4b17023SJohn Marino 	      case BUILT_IN_STRSTR:
3431*e4b17023SJohn Marino 		/* Assume certain string/memory builtins always return.  */
3432*e4b17023SJohn Marino 		return false;
3433*e4b17023SJohn Marino 	      default:
3434*e4b17023SJohn Marino 		break;
3435*e4b17023SJohn Marino 	      }
3436*e4b17023SJohn Marino 	}
3437*e4b17023SJohn Marino     }
3438*e4b17023SJohn Marino 
3439*e4b17023SJohn Marino   /* For all other calls assume that they might not always return.  */
3440*e4b17023SJohn Marino   return true;
3441*e4b17023SJohn Marino }
3442*e4b17023SJohn Marino 
3443*e4b17023SJohn Marino /* Analyze INSN with DEPS as a context.  */
3444*e4b17023SJohn Marino void
3445*e4b17023SJohn Marino deps_analyze_insn (struct deps_desc *deps, rtx insn)
3446*e4b17023SJohn Marino {
3447*e4b17023SJohn Marino   if (sched_deps_info->start_insn)
3448*e4b17023SJohn Marino     sched_deps_info->start_insn (insn);
3449*e4b17023SJohn Marino 
3450*e4b17023SJohn Marino   /* Record the condition for this insn.  */
3451*e4b17023SJohn Marino   if (NONDEBUG_INSN_P (insn))
3452*e4b17023SJohn Marino     {
3453*e4b17023SJohn Marino       rtx t;
3454*e4b17023SJohn Marino       sched_get_condition_with_rev (insn, NULL);
3455*e4b17023SJohn Marino       t = INSN_CACHED_COND (insn);
3456*e4b17023SJohn Marino       INSN_COND_DEPS (insn) = NULL_RTX;
3457*e4b17023SJohn Marino       if (reload_completed
3458*e4b17023SJohn Marino 	  && (current_sched_info->flags & DO_PREDICATION)
3459*e4b17023SJohn Marino 	  && COMPARISON_P (t)
3460*e4b17023SJohn Marino 	  && REG_P (XEXP (t, 0))
3461*e4b17023SJohn Marino 	  && CONSTANT_P (XEXP (t, 1)))
3462*e4b17023SJohn Marino 	{
3463*e4b17023SJohn Marino 	  unsigned int regno;
3464*e4b17023SJohn Marino 	  int nregs;
3465*e4b17023SJohn Marino 	  t = XEXP (t, 0);
3466*e4b17023SJohn Marino 	  regno = REGNO (t);
3467*e4b17023SJohn Marino 	  nregs = hard_regno_nregs[regno][GET_MODE (t)];
3468*e4b17023SJohn Marino 	  t = NULL_RTX;
3469*e4b17023SJohn Marino 	  while (nregs-- > 0)
3470*e4b17023SJohn Marino 	    {
3471*e4b17023SJohn Marino 	      struct deps_reg *reg_last = &deps->reg_last[regno + nregs];
3472*e4b17023SJohn Marino 	      t = concat_INSN_LIST (reg_last->sets, t);
3473*e4b17023SJohn Marino 	      t = concat_INSN_LIST (reg_last->clobbers, t);
3474*e4b17023SJohn Marino 	      t = concat_INSN_LIST (reg_last->implicit_sets, t);
3475*e4b17023SJohn Marino 	    }
3476*e4b17023SJohn Marino 	  INSN_COND_DEPS (insn) = t;
3477*e4b17023SJohn Marino 	}
3478*e4b17023SJohn Marino     }
3479*e4b17023SJohn Marino 
3480*e4b17023SJohn Marino   if (JUMP_P (insn))
3481*e4b17023SJohn Marino     {
3482*e4b17023SJohn Marino       /* Make each JUMP_INSN (but not a speculative check)
3483*e4b17023SJohn Marino          a scheduling barrier for memory references.  */
3484*e4b17023SJohn Marino       if (!deps->readonly
3485*e4b17023SJohn Marino           && !(sel_sched_p ()
3486*e4b17023SJohn Marino                && sel_insn_is_speculation_check (insn)))
3487*e4b17023SJohn Marino         {
3488*e4b17023SJohn Marino           /* Keep the list a reasonable size.  */
3489*e4b17023SJohn Marino           if (deps->pending_flush_length++ > MAX_PENDING_LIST_LENGTH)
3490*e4b17023SJohn Marino             flush_pending_lists (deps, insn, true, true);
3491*e4b17023SJohn Marino           else
3492*e4b17023SJohn Marino 	    deps->pending_jump_insns
3493*e4b17023SJohn Marino               = alloc_INSN_LIST (insn, deps->pending_jump_insns);
3494*e4b17023SJohn Marino         }
3495*e4b17023SJohn Marino 
3496*e4b17023SJohn Marino       /* For each insn which shouldn't cross a jump, add a dependence.  */
3497*e4b17023SJohn Marino       add_dependence_list_and_free (deps, insn,
3498*e4b17023SJohn Marino 				    &deps->sched_before_next_jump, 1,
3499*e4b17023SJohn Marino 				    REG_DEP_ANTI);
3500*e4b17023SJohn Marino 
3501*e4b17023SJohn Marino       sched_analyze_insn (deps, PATTERN (insn), insn);
3502*e4b17023SJohn Marino     }
3503*e4b17023SJohn Marino   else if (NONJUMP_INSN_P (insn) || DEBUG_INSN_P (insn))
3504*e4b17023SJohn Marino     {
3505*e4b17023SJohn Marino       sched_analyze_insn (deps, PATTERN (insn), insn);
3506*e4b17023SJohn Marino     }
3507*e4b17023SJohn Marino   else if (CALL_P (insn))
3508*e4b17023SJohn Marino     {
3509*e4b17023SJohn Marino       int i;
3510*e4b17023SJohn Marino 
3511*e4b17023SJohn Marino       CANT_MOVE (insn) = 1;
3512*e4b17023SJohn Marino 
3513*e4b17023SJohn Marino       if (find_reg_note (insn, REG_SETJMP, NULL))
3514*e4b17023SJohn Marino         {
3515*e4b17023SJohn Marino           /* This is setjmp.  Assume that all registers, not just
3516*e4b17023SJohn Marino              hard registers, may be clobbered by this call.  */
3517*e4b17023SJohn Marino           reg_pending_barrier = MOVE_BARRIER;
3518*e4b17023SJohn Marino         }
3519*e4b17023SJohn Marino       else
3520*e4b17023SJohn Marino         {
3521*e4b17023SJohn Marino           for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3522*e4b17023SJohn Marino             /* A call may read and modify global register variables.  */
3523*e4b17023SJohn Marino             if (global_regs[i])
3524*e4b17023SJohn Marino               {
3525*e4b17023SJohn Marino                 SET_REGNO_REG_SET (reg_pending_sets, i);
3526*e4b17023SJohn Marino                 SET_HARD_REG_BIT (implicit_reg_pending_uses, i);
3527*e4b17023SJohn Marino               }
3528*e4b17023SJohn Marino           /* Other call-clobbered hard regs may be clobbered.
3529*e4b17023SJohn Marino              Since we only have a choice between 'might be clobbered'
3530*e4b17023SJohn Marino              and 'definitely not clobbered', we must include all
3531*e4b17023SJohn Marino              partly call-clobbered registers here.  */
3532*e4b17023SJohn Marino             else if (HARD_REGNO_CALL_PART_CLOBBERED (i, reg_raw_mode[i])
3533*e4b17023SJohn Marino                      || TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
3534*e4b17023SJohn Marino               SET_REGNO_REG_SET (reg_pending_clobbers, i);
3535*e4b17023SJohn Marino           /* We don't know what set of fixed registers might be used
3536*e4b17023SJohn Marino              by the function, but it is certain that the stack pointer
3537*e4b17023SJohn Marino              is among them, but be conservative.  */
3538*e4b17023SJohn Marino             else if (fixed_regs[i])
3539*e4b17023SJohn Marino 	      SET_HARD_REG_BIT (implicit_reg_pending_uses, i);
3540*e4b17023SJohn Marino           /* The frame pointer is normally not used by the function
3541*e4b17023SJohn Marino              itself, but by the debugger.  */
3542*e4b17023SJohn Marino           /* ??? MIPS o32 is an exception.  It uses the frame pointer
3543*e4b17023SJohn Marino              in the macro expansion of jal but does not represent this
3544*e4b17023SJohn Marino              fact in the call_insn rtl.  */
3545*e4b17023SJohn Marino             else if (i == FRAME_POINTER_REGNUM
3546*e4b17023SJohn Marino                      || (i == HARD_FRAME_POINTER_REGNUM
3547*e4b17023SJohn Marino                          && (! reload_completed || frame_pointer_needed)))
3548*e4b17023SJohn Marino 	      SET_HARD_REG_BIT (implicit_reg_pending_uses, i);
3549*e4b17023SJohn Marino         }
3550*e4b17023SJohn Marino 
3551*e4b17023SJohn Marino       /* For each insn which shouldn't cross a call, add a dependence
3552*e4b17023SJohn Marino          between that insn and this call insn.  */
3553*e4b17023SJohn Marino       add_dependence_list_and_free (deps, insn,
3554*e4b17023SJohn Marino                                     &deps->sched_before_next_call, 1,
3555*e4b17023SJohn Marino                                     REG_DEP_ANTI);
3556*e4b17023SJohn Marino 
3557*e4b17023SJohn Marino       sched_analyze_insn (deps, PATTERN (insn), insn);
3558*e4b17023SJohn Marino 
3559*e4b17023SJohn Marino       /* If CALL would be in a sched group, then this will violate
3560*e4b17023SJohn Marino 	 convention that sched group insns have dependencies only on the
3561*e4b17023SJohn Marino 	 previous instruction.
3562*e4b17023SJohn Marino 
3563*e4b17023SJohn Marino 	 Of course one can say: "Hey!  What about head of the sched group?"
3564*e4b17023SJohn Marino 	 And I will answer: "Basic principles (one dep per insn) are always
3565*e4b17023SJohn Marino 	 the same."  */
3566*e4b17023SJohn Marino       gcc_assert (!SCHED_GROUP_P (insn));
3567*e4b17023SJohn Marino 
3568*e4b17023SJohn Marino       /* In the absence of interprocedural alias analysis, we must flush
3569*e4b17023SJohn Marino          all pending reads and writes, and start new dependencies starting
3570*e4b17023SJohn Marino          from here.  But only flush writes for constant calls (which may
3571*e4b17023SJohn Marino          be passed a pointer to something we haven't written yet).  */
3572*e4b17023SJohn Marino       flush_pending_lists (deps, insn, true, ! RTL_CONST_OR_PURE_CALL_P (insn));
3573*e4b17023SJohn Marino 
3574*e4b17023SJohn Marino       if (!deps->readonly)
3575*e4b17023SJohn Marino         {
3576*e4b17023SJohn Marino           /* Remember the last function call for limiting lifetimes.  */
3577*e4b17023SJohn Marino           free_INSN_LIST_list (&deps->last_function_call);
3578*e4b17023SJohn Marino           deps->last_function_call = alloc_INSN_LIST (insn, NULL_RTX);
3579*e4b17023SJohn Marino 
3580*e4b17023SJohn Marino 	  if (call_may_noreturn_p (insn))
3581*e4b17023SJohn Marino 	    {
3582*e4b17023SJohn Marino 	      /* Remember the last function call that might not always return
3583*e4b17023SJohn Marino 		 normally for limiting moves of trapping insns.  */
3584*e4b17023SJohn Marino 	      free_INSN_LIST_list (&deps->last_function_call_may_noreturn);
3585*e4b17023SJohn Marino 	      deps->last_function_call_may_noreturn
3586*e4b17023SJohn Marino 		= alloc_INSN_LIST (insn, NULL_RTX);
3587*e4b17023SJohn Marino 	    }
3588*e4b17023SJohn Marino 
3589*e4b17023SJohn Marino           /* Before reload, begin a post-call group, so as to keep the
3590*e4b17023SJohn Marino              lifetimes of hard registers correct.  */
3591*e4b17023SJohn Marino           if (! reload_completed)
3592*e4b17023SJohn Marino             deps->in_post_call_group_p = post_call;
3593*e4b17023SJohn Marino         }
3594*e4b17023SJohn Marino     }
3595*e4b17023SJohn Marino 
3596*e4b17023SJohn Marino   if (sched_deps_info->use_cselib)
3597*e4b17023SJohn Marino     cselib_process_insn (insn);
3598*e4b17023SJohn Marino 
3599*e4b17023SJohn Marino   /* EH_REGION insn notes can not appear until well after we complete
3600*e4b17023SJohn Marino      scheduling.  */
3601*e4b17023SJohn Marino   if (NOTE_P (insn))
3602*e4b17023SJohn Marino     gcc_assert (NOTE_KIND (insn) != NOTE_INSN_EH_REGION_BEG
3603*e4b17023SJohn Marino 		&& NOTE_KIND (insn) != NOTE_INSN_EH_REGION_END);
3604*e4b17023SJohn Marino 
3605*e4b17023SJohn Marino   if (sched_deps_info->finish_insn)
3606*e4b17023SJohn Marino     sched_deps_info->finish_insn ();
3607*e4b17023SJohn Marino 
3608*e4b17023SJohn Marino   /* Fixup the dependencies in the sched group.  */
3609*e4b17023SJohn Marino   if ((NONJUMP_INSN_P (insn) || JUMP_P (insn))
3610*e4b17023SJohn Marino       && SCHED_GROUP_P (insn) && !sel_sched_p ())
3611*e4b17023SJohn Marino     fixup_sched_groups (insn);
3612*e4b17023SJohn Marino }
3613*e4b17023SJohn Marino 
3614*e4b17023SJohn Marino /* Initialize DEPS for the new block beginning with HEAD.  */
3615*e4b17023SJohn Marino void
3616*e4b17023SJohn Marino deps_start_bb (struct deps_desc *deps, rtx head)
3617*e4b17023SJohn Marino {
3618*e4b17023SJohn Marino   gcc_assert (!deps->readonly);
3619*e4b17023SJohn Marino 
3620*e4b17023SJohn Marino   /* Before reload, if the previous block ended in a call, show that
3621*e4b17023SJohn Marino      we are inside a post-call group, so as to keep the lifetimes of
3622*e4b17023SJohn Marino      hard registers correct.  */
3623*e4b17023SJohn Marino   if (! reload_completed && !LABEL_P (head))
3624*e4b17023SJohn Marino     {
3625*e4b17023SJohn Marino       rtx insn = prev_nonnote_nondebug_insn (head);
3626*e4b17023SJohn Marino 
3627*e4b17023SJohn Marino       if (insn && CALL_P (insn))
3628*e4b17023SJohn Marino 	deps->in_post_call_group_p = post_call_initial;
3629*e4b17023SJohn Marino     }
3630*e4b17023SJohn Marino }
3631*e4b17023SJohn Marino 
3632*e4b17023SJohn Marino /* Analyze every insn between HEAD and TAIL inclusive, creating backward
3633*e4b17023SJohn Marino    dependencies for each insn.  */
3634*e4b17023SJohn Marino void
3635*e4b17023SJohn Marino sched_analyze (struct deps_desc *deps, rtx head, rtx tail)
3636*e4b17023SJohn Marino {
3637*e4b17023SJohn Marino   rtx insn;
3638*e4b17023SJohn Marino 
3639*e4b17023SJohn Marino   if (sched_deps_info->use_cselib)
3640*e4b17023SJohn Marino     cselib_init (CSELIB_RECORD_MEMORY);
3641*e4b17023SJohn Marino 
3642*e4b17023SJohn Marino   deps_start_bb (deps, head);
3643*e4b17023SJohn Marino 
3644*e4b17023SJohn Marino   for (insn = head;; insn = NEXT_INSN (insn))
3645*e4b17023SJohn Marino     {
3646*e4b17023SJohn Marino 
3647*e4b17023SJohn Marino       if (INSN_P (insn))
3648*e4b17023SJohn Marino 	{
3649*e4b17023SJohn Marino 	  /* And initialize deps_lists.  */
3650*e4b17023SJohn Marino 	  sd_init_insn (insn);
3651*e4b17023SJohn Marino 	}
3652*e4b17023SJohn Marino 
3653*e4b17023SJohn Marino       deps_analyze_insn (deps, insn);
3654*e4b17023SJohn Marino 
3655*e4b17023SJohn Marino       if (insn == tail)
3656*e4b17023SJohn Marino 	{
3657*e4b17023SJohn Marino 	  if (sched_deps_info->use_cselib)
3658*e4b17023SJohn Marino 	    cselib_finish ();
3659*e4b17023SJohn Marino 	  return;
3660*e4b17023SJohn Marino 	}
3661*e4b17023SJohn Marino     }
3662*e4b17023SJohn Marino   gcc_unreachable ();
3663*e4b17023SJohn Marino }
3664*e4b17023SJohn Marino 
3665*e4b17023SJohn Marino /* Helper for sched_free_deps ().
3666*e4b17023SJohn Marino    Delete INSN's (RESOLVED_P) backward dependencies.  */
3667*e4b17023SJohn Marino static void
3668*e4b17023SJohn Marino delete_dep_nodes_in_back_deps (rtx insn, bool resolved_p)
3669*e4b17023SJohn Marino {
3670*e4b17023SJohn Marino   sd_iterator_def sd_it;
3671*e4b17023SJohn Marino   dep_t dep;
3672*e4b17023SJohn Marino   sd_list_types_def types;
3673*e4b17023SJohn Marino 
3674*e4b17023SJohn Marino   if (resolved_p)
3675*e4b17023SJohn Marino     types = SD_LIST_RES_BACK;
3676*e4b17023SJohn Marino   else
3677*e4b17023SJohn Marino     types = SD_LIST_BACK;
3678*e4b17023SJohn Marino 
3679*e4b17023SJohn Marino   for (sd_it = sd_iterator_start (insn, types);
3680*e4b17023SJohn Marino        sd_iterator_cond (&sd_it, &dep);)
3681*e4b17023SJohn Marino     {
3682*e4b17023SJohn Marino       dep_link_t link = *sd_it.linkp;
3683*e4b17023SJohn Marino       dep_node_t node = DEP_LINK_NODE (link);
3684*e4b17023SJohn Marino       deps_list_t back_list;
3685*e4b17023SJohn Marino       deps_list_t forw_list;
3686*e4b17023SJohn Marino 
3687*e4b17023SJohn Marino       get_back_and_forw_lists (dep, resolved_p, &back_list, &forw_list);
3688*e4b17023SJohn Marino       remove_from_deps_list (link, back_list);
3689*e4b17023SJohn Marino       delete_dep_node (node);
3690*e4b17023SJohn Marino     }
3691*e4b17023SJohn Marino }
3692*e4b17023SJohn Marino 
3693*e4b17023SJohn Marino /* Delete (RESOLVED_P) dependencies between HEAD and TAIL together with
3694*e4b17023SJohn Marino    deps_lists.  */
3695*e4b17023SJohn Marino void
3696*e4b17023SJohn Marino sched_free_deps (rtx head, rtx tail, bool resolved_p)
3697*e4b17023SJohn Marino {
3698*e4b17023SJohn Marino   rtx insn;
3699*e4b17023SJohn Marino   rtx next_tail = NEXT_INSN (tail);
3700*e4b17023SJohn Marino 
3701*e4b17023SJohn Marino   /* We make two passes since some insns may be scheduled before their
3702*e4b17023SJohn Marino      dependencies are resolved.  */
3703*e4b17023SJohn Marino   for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
3704*e4b17023SJohn Marino     if (INSN_P (insn) && INSN_LUID (insn) > 0)
3705*e4b17023SJohn Marino       {
3706*e4b17023SJohn Marino 	/* Clear forward deps and leave the dep_nodes to the
3707*e4b17023SJohn Marino 	   corresponding back_deps list.  */
3708*e4b17023SJohn Marino 	if (resolved_p)
3709*e4b17023SJohn Marino 	  clear_deps_list (INSN_RESOLVED_FORW_DEPS (insn));
3710*e4b17023SJohn Marino 	else
3711*e4b17023SJohn Marino 	  clear_deps_list (INSN_FORW_DEPS (insn));
3712*e4b17023SJohn Marino       }
3713*e4b17023SJohn Marino   for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
3714*e4b17023SJohn Marino     if (INSN_P (insn) && INSN_LUID (insn) > 0)
3715*e4b17023SJohn Marino       {
3716*e4b17023SJohn Marino 	/* Clear resolved back deps together with its dep_nodes.  */
3717*e4b17023SJohn Marino 	delete_dep_nodes_in_back_deps (insn, resolved_p);
3718*e4b17023SJohn Marino 
3719*e4b17023SJohn Marino 	sd_finish_insn (insn);
3720*e4b17023SJohn Marino       }
3721*e4b17023SJohn Marino }
3722*e4b17023SJohn Marino 
3723*e4b17023SJohn Marino /* Initialize variables for region data dependence analysis.
3724*e4b17023SJohn Marino    When LAZY_REG_LAST is true, do not allocate reg_last array
3725*e4b17023SJohn Marino    of struct deps_desc immediately.  */
3726*e4b17023SJohn Marino 
3727*e4b17023SJohn Marino void
3728*e4b17023SJohn Marino init_deps (struct deps_desc *deps, bool lazy_reg_last)
3729*e4b17023SJohn Marino {
3730*e4b17023SJohn Marino   int max_reg = (reload_completed ? FIRST_PSEUDO_REGISTER : max_reg_num ());
3731*e4b17023SJohn Marino 
3732*e4b17023SJohn Marino   deps->max_reg = max_reg;
3733*e4b17023SJohn Marino   if (lazy_reg_last)
3734*e4b17023SJohn Marino     deps->reg_last = NULL;
3735*e4b17023SJohn Marino   else
3736*e4b17023SJohn Marino     deps->reg_last = XCNEWVEC (struct deps_reg, max_reg);
3737*e4b17023SJohn Marino   INIT_REG_SET (&deps->reg_last_in_use);
3738*e4b17023SJohn Marino 
3739*e4b17023SJohn Marino   deps->pending_read_insns = 0;
3740*e4b17023SJohn Marino   deps->pending_read_mems = 0;
3741*e4b17023SJohn Marino   deps->pending_write_insns = 0;
3742*e4b17023SJohn Marino   deps->pending_write_mems = 0;
3743*e4b17023SJohn Marino   deps->pending_jump_insns = 0;
3744*e4b17023SJohn Marino   deps->pending_read_list_length = 0;
3745*e4b17023SJohn Marino   deps->pending_write_list_length = 0;
3746*e4b17023SJohn Marino   deps->pending_flush_length = 0;
3747*e4b17023SJohn Marino   deps->last_pending_memory_flush = 0;
3748*e4b17023SJohn Marino   deps->last_function_call = 0;
3749*e4b17023SJohn Marino   deps->last_function_call_may_noreturn = 0;
3750*e4b17023SJohn Marino   deps->sched_before_next_call = 0;
3751*e4b17023SJohn Marino   deps->sched_before_next_jump = 0;
3752*e4b17023SJohn Marino   deps->in_post_call_group_p = not_post_call;
3753*e4b17023SJohn Marino   deps->last_debug_insn = 0;
3754*e4b17023SJohn Marino   deps->last_reg_pending_barrier = NOT_A_BARRIER;
3755*e4b17023SJohn Marino   deps->readonly = 0;
3756*e4b17023SJohn Marino }
3757*e4b17023SJohn Marino 
3758*e4b17023SJohn Marino /* Init only reg_last field of DEPS, which was not allocated before as
3759*e4b17023SJohn Marino    we inited DEPS lazily.  */
3760*e4b17023SJohn Marino void
3761*e4b17023SJohn Marino init_deps_reg_last (struct deps_desc *deps)
3762*e4b17023SJohn Marino {
3763*e4b17023SJohn Marino   gcc_assert (deps && deps->max_reg > 0);
3764*e4b17023SJohn Marino   gcc_assert (deps->reg_last == NULL);
3765*e4b17023SJohn Marino 
3766*e4b17023SJohn Marino   deps->reg_last = XCNEWVEC (struct deps_reg, deps->max_reg);
3767*e4b17023SJohn Marino }
3768*e4b17023SJohn Marino 
3769*e4b17023SJohn Marino 
3770*e4b17023SJohn Marino /* Free insn lists found in DEPS.  */
3771*e4b17023SJohn Marino 
3772*e4b17023SJohn Marino void
3773*e4b17023SJohn Marino free_deps (struct deps_desc *deps)
3774*e4b17023SJohn Marino {
3775*e4b17023SJohn Marino   unsigned i;
3776*e4b17023SJohn Marino   reg_set_iterator rsi;
3777*e4b17023SJohn Marino 
3778*e4b17023SJohn Marino   /* We set max_reg to 0 when this context was already freed.  */
3779*e4b17023SJohn Marino   if (deps->max_reg == 0)
3780*e4b17023SJohn Marino     {
3781*e4b17023SJohn Marino       gcc_assert (deps->reg_last == NULL);
3782*e4b17023SJohn Marino       return;
3783*e4b17023SJohn Marino     }
3784*e4b17023SJohn Marino   deps->max_reg = 0;
3785*e4b17023SJohn Marino 
3786*e4b17023SJohn Marino   free_INSN_LIST_list (&deps->pending_read_insns);
3787*e4b17023SJohn Marino   free_EXPR_LIST_list (&deps->pending_read_mems);
3788*e4b17023SJohn Marino   free_INSN_LIST_list (&deps->pending_write_insns);
3789*e4b17023SJohn Marino   free_EXPR_LIST_list (&deps->pending_write_mems);
3790*e4b17023SJohn Marino   free_INSN_LIST_list (&deps->last_pending_memory_flush);
3791*e4b17023SJohn Marino 
3792*e4b17023SJohn Marino   /* Without the EXECUTE_IF_SET, this loop is executed max_reg * nr_regions
3793*e4b17023SJohn Marino      times.  For a testcase with 42000 regs and 8000 small basic blocks,
3794*e4b17023SJohn Marino      this loop accounted for nearly 60% (84 sec) of the total -O2 runtime.  */
3795*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i, rsi)
3796*e4b17023SJohn Marino     {
3797*e4b17023SJohn Marino       struct deps_reg *reg_last = &deps->reg_last[i];
3798*e4b17023SJohn Marino       if (reg_last->uses)
3799*e4b17023SJohn Marino 	free_INSN_LIST_list (&reg_last->uses);
3800*e4b17023SJohn Marino       if (reg_last->sets)
3801*e4b17023SJohn Marino 	free_INSN_LIST_list (&reg_last->sets);
3802*e4b17023SJohn Marino       if (reg_last->implicit_sets)
3803*e4b17023SJohn Marino 	free_INSN_LIST_list (&reg_last->implicit_sets);
3804*e4b17023SJohn Marino       if (reg_last->control_uses)
3805*e4b17023SJohn Marino 	free_INSN_LIST_list (&reg_last->control_uses);
3806*e4b17023SJohn Marino       if (reg_last->clobbers)
3807*e4b17023SJohn Marino 	free_INSN_LIST_list (&reg_last->clobbers);
3808*e4b17023SJohn Marino     }
3809*e4b17023SJohn Marino   CLEAR_REG_SET (&deps->reg_last_in_use);
3810*e4b17023SJohn Marino 
3811*e4b17023SJohn Marino   /* As we initialize reg_last lazily, it is possible that we didn't allocate
3812*e4b17023SJohn Marino      it at all.  */
3813*e4b17023SJohn Marino   free (deps->reg_last);
3814*e4b17023SJohn Marino   deps->reg_last = NULL;
3815*e4b17023SJohn Marino 
3816*e4b17023SJohn Marino   deps = NULL;
3817*e4b17023SJohn Marino }
3818*e4b17023SJohn Marino 
3819*e4b17023SJohn Marino /* Remove INSN from dependence contexts DEPS.  */
3820*e4b17023SJohn Marino void
3821*e4b17023SJohn Marino remove_from_deps (struct deps_desc *deps, rtx insn)
3822*e4b17023SJohn Marino {
3823*e4b17023SJohn Marino   int removed;
3824*e4b17023SJohn Marino   unsigned i;
3825*e4b17023SJohn Marino   reg_set_iterator rsi;
3826*e4b17023SJohn Marino 
3827*e4b17023SJohn Marino   removed = remove_from_both_dependence_lists (insn, &deps->pending_read_insns,
3828*e4b17023SJohn Marino                                                &deps->pending_read_mems);
3829*e4b17023SJohn Marino   if (!DEBUG_INSN_P (insn))
3830*e4b17023SJohn Marino     deps->pending_read_list_length -= removed;
3831*e4b17023SJohn Marino   removed = remove_from_both_dependence_lists (insn, &deps->pending_write_insns,
3832*e4b17023SJohn Marino                                                &deps->pending_write_mems);
3833*e4b17023SJohn Marino   deps->pending_write_list_length -= removed;
3834*e4b17023SJohn Marino 
3835*e4b17023SJohn Marino   removed = remove_from_dependence_list (insn, &deps->pending_jump_insns);
3836*e4b17023SJohn Marino   deps->pending_flush_length -= removed;
3837*e4b17023SJohn Marino   removed = remove_from_dependence_list (insn, &deps->last_pending_memory_flush);
3838*e4b17023SJohn Marino   deps->pending_flush_length -= removed;
3839*e4b17023SJohn Marino 
3840*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i, rsi)
3841*e4b17023SJohn Marino     {
3842*e4b17023SJohn Marino       struct deps_reg *reg_last = &deps->reg_last[i];
3843*e4b17023SJohn Marino       if (reg_last->uses)
3844*e4b17023SJohn Marino 	remove_from_dependence_list (insn, &reg_last->uses);
3845*e4b17023SJohn Marino       if (reg_last->sets)
3846*e4b17023SJohn Marino 	remove_from_dependence_list (insn, &reg_last->sets);
3847*e4b17023SJohn Marino       if (reg_last->implicit_sets)
3848*e4b17023SJohn Marino 	remove_from_dependence_list (insn, &reg_last->implicit_sets);
3849*e4b17023SJohn Marino       if (reg_last->clobbers)
3850*e4b17023SJohn Marino 	remove_from_dependence_list (insn, &reg_last->clobbers);
3851*e4b17023SJohn Marino       if (!reg_last->uses && !reg_last->sets && !reg_last->implicit_sets
3852*e4b17023SJohn Marino 	  && !reg_last->clobbers)
3853*e4b17023SJohn Marino         CLEAR_REGNO_REG_SET (&deps->reg_last_in_use, i);
3854*e4b17023SJohn Marino     }
3855*e4b17023SJohn Marino 
3856*e4b17023SJohn Marino   if (CALL_P (insn))
3857*e4b17023SJohn Marino     {
3858*e4b17023SJohn Marino       remove_from_dependence_list (insn, &deps->last_function_call);
3859*e4b17023SJohn Marino       remove_from_dependence_list (insn,
3860*e4b17023SJohn Marino 				   &deps->last_function_call_may_noreturn);
3861*e4b17023SJohn Marino     }
3862*e4b17023SJohn Marino   remove_from_dependence_list (insn, &deps->sched_before_next_call);
3863*e4b17023SJohn Marino }
3864*e4b17023SJohn Marino 
3865*e4b17023SJohn Marino /* Init deps data vector.  */
3866*e4b17023SJohn Marino static void
3867*e4b17023SJohn Marino init_deps_data_vector (void)
3868*e4b17023SJohn Marino {
3869*e4b17023SJohn Marino   int reserve = (sched_max_luid + 1
3870*e4b17023SJohn Marino                  - VEC_length (haifa_deps_insn_data_def, h_d_i_d));
3871*e4b17023SJohn Marino   if (reserve > 0
3872*e4b17023SJohn Marino       && ! VEC_space (haifa_deps_insn_data_def, h_d_i_d, reserve))
3873*e4b17023SJohn Marino     VEC_safe_grow_cleared (haifa_deps_insn_data_def, heap, h_d_i_d,
3874*e4b17023SJohn Marino                            3 * sched_max_luid / 2);
3875*e4b17023SJohn Marino }
3876*e4b17023SJohn Marino 
3877*e4b17023SJohn Marino /* If it is profitable to use them, initialize or extend (depending on
3878*e4b17023SJohn Marino    GLOBAL_P) dependency data.  */
3879*e4b17023SJohn Marino void
3880*e4b17023SJohn Marino sched_deps_init (bool global_p)
3881*e4b17023SJohn Marino {
3882*e4b17023SJohn Marino   /* Average number of insns in the basic block.
3883*e4b17023SJohn Marino      '+ 1' is used to make it nonzero.  */
3884*e4b17023SJohn Marino   int insns_in_block = sched_max_luid / n_basic_blocks + 1;
3885*e4b17023SJohn Marino 
3886*e4b17023SJohn Marino   init_deps_data_vector ();
3887*e4b17023SJohn Marino 
3888*e4b17023SJohn Marino   /* We use another caching mechanism for selective scheduling, so
3889*e4b17023SJohn Marino      we don't use this one.  */
3890*e4b17023SJohn Marino   if (!sel_sched_p () && global_p && insns_in_block > 100 * 5)
3891*e4b17023SJohn Marino     {
3892*e4b17023SJohn Marino       /* ?!? We could save some memory by computing a per-region luid mapping
3893*e4b17023SJohn Marino          which could reduce both the number of vectors in the cache and the
3894*e4b17023SJohn Marino          size of each vector.  Instead we just avoid the cache entirely unless
3895*e4b17023SJohn Marino          the average number of instructions in a basic block is very high.  See
3896*e4b17023SJohn Marino          the comment before the declaration of true_dependency_cache for
3897*e4b17023SJohn Marino          what we consider "very high".  */
3898*e4b17023SJohn Marino       cache_size = 0;
3899*e4b17023SJohn Marino       extend_dependency_caches (sched_max_luid, true);
3900*e4b17023SJohn Marino     }
3901*e4b17023SJohn Marino 
3902*e4b17023SJohn Marino   if (global_p)
3903*e4b17023SJohn Marino     {
3904*e4b17023SJohn Marino       dl_pool = create_alloc_pool ("deps_list", sizeof (struct _deps_list),
3905*e4b17023SJohn Marino                                    /* Allocate lists for one block at a time.  */
3906*e4b17023SJohn Marino                                    insns_in_block);
3907*e4b17023SJohn Marino       dn_pool = create_alloc_pool ("dep_node", sizeof (struct _dep_node),
3908*e4b17023SJohn Marino                                    /* Allocate nodes for one block at a time.
3909*e4b17023SJohn Marino                                       We assume that average insn has
3910*e4b17023SJohn Marino                                       5 producers.  */
3911*e4b17023SJohn Marino                                    5 * insns_in_block);
3912*e4b17023SJohn Marino     }
3913*e4b17023SJohn Marino }
3914*e4b17023SJohn Marino 
3915*e4b17023SJohn Marino 
3916*e4b17023SJohn Marino /* Create or extend (depending on CREATE_P) dependency caches to
3917*e4b17023SJohn Marino    size N.  */
3918*e4b17023SJohn Marino void
3919*e4b17023SJohn Marino extend_dependency_caches (int n, bool create_p)
3920*e4b17023SJohn Marino {
3921*e4b17023SJohn Marino   if (create_p || true_dependency_cache)
3922*e4b17023SJohn Marino     {
3923*e4b17023SJohn Marino       int i, luid = cache_size + n;
3924*e4b17023SJohn Marino 
3925*e4b17023SJohn Marino       true_dependency_cache = XRESIZEVEC (bitmap_head, true_dependency_cache,
3926*e4b17023SJohn Marino 					  luid);
3927*e4b17023SJohn Marino       output_dependency_cache = XRESIZEVEC (bitmap_head,
3928*e4b17023SJohn Marino 					    output_dependency_cache, luid);
3929*e4b17023SJohn Marino       anti_dependency_cache = XRESIZEVEC (bitmap_head, anti_dependency_cache,
3930*e4b17023SJohn Marino 					  luid);
3931*e4b17023SJohn Marino       control_dependency_cache = XRESIZEVEC (bitmap_head, control_dependency_cache,
3932*e4b17023SJohn Marino 					  luid);
3933*e4b17023SJohn Marino 
3934*e4b17023SJohn Marino       if (current_sched_info->flags & DO_SPECULATION)
3935*e4b17023SJohn Marino         spec_dependency_cache = XRESIZEVEC (bitmap_head, spec_dependency_cache,
3936*e4b17023SJohn Marino 					    luid);
3937*e4b17023SJohn Marino 
3938*e4b17023SJohn Marino       for (i = cache_size; i < luid; i++)
3939*e4b17023SJohn Marino 	{
3940*e4b17023SJohn Marino 	  bitmap_initialize (&true_dependency_cache[i], 0);
3941*e4b17023SJohn Marino 	  bitmap_initialize (&output_dependency_cache[i], 0);
3942*e4b17023SJohn Marino 	  bitmap_initialize (&anti_dependency_cache[i], 0);
3943*e4b17023SJohn Marino 	  bitmap_initialize (&control_dependency_cache[i], 0);
3944*e4b17023SJohn Marino 
3945*e4b17023SJohn Marino           if (current_sched_info->flags & DO_SPECULATION)
3946*e4b17023SJohn Marino             bitmap_initialize (&spec_dependency_cache[i], 0);
3947*e4b17023SJohn Marino 	}
3948*e4b17023SJohn Marino       cache_size = luid;
3949*e4b17023SJohn Marino     }
3950*e4b17023SJohn Marino }
3951*e4b17023SJohn Marino 
3952*e4b17023SJohn Marino /* Finalize dependency information for the whole function.  */
3953*e4b17023SJohn Marino void
3954*e4b17023SJohn Marino sched_deps_finish (void)
3955*e4b17023SJohn Marino {
3956*e4b17023SJohn Marino   gcc_assert (deps_pools_are_empty_p ());
3957*e4b17023SJohn Marino   free_alloc_pool_if_empty (&dn_pool);
3958*e4b17023SJohn Marino   free_alloc_pool_if_empty (&dl_pool);
3959*e4b17023SJohn Marino   gcc_assert (dn_pool == NULL && dl_pool == NULL);
3960*e4b17023SJohn Marino 
3961*e4b17023SJohn Marino   VEC_free (haifa_deps_insn_data_def, heap, h_d_i_d);
3962*e4b17023SJohn Marino   cache_size = 0;
3963*e4b17023SJohn Marino 
3964*e4b17023SJohn Marino   if (true_dependency_cache)
3965*e4b17023SJohn Marino     {
3966*e4b17023SJohn Marino       int i;
3967*e4b17023SJohn Marino 
3968*e4b17023SJohn Marino       for (i = 0; i < cache_size; i++)
3969*e4b17023SJohn Marino 	{
3970*e4b17023SJohn Marino 	  bitmap_clear (&true_dependency_cache[i]);
3971*e4b17023SJohn Marino 	  bitmap_clear (&output_dependency_cache[i]);
3972*e4b17023SJohn Marino 	  bitmap_clear (&anti_dependency_cache[i]);
3973*e4b17023SJohn Marino 	  bitmap_clear (&control_dependency_cache[i]);
3974*e4b17023SJohn Marino 
3975*e4b17023SJohn Marino           if (sched_deps_info->generate_spec_deps)
3976*e4b17023SJohn Marino             bitmap_clear (&spec_dependency_cache[i]);
3977*e4b17023SJohn Marino 	}
3978*e4b17023SJohn Marino       free (true_dependency_cache);
3979*e4b17023SJohn Marino       true_dependency_cache = NULL;
3980*e4b17023SJohn Marino       free (output_dependency_cache);
3981*e4b17023SJohn Marino       output_dependency_cache = NULL;
3982*e4b17023SJohn Marino       free (anti_dependency_cache);
3983*e4b17023SJohn Marino       anti_dependency_cache = NULL;
3984*e4b17023SJohn Marino       free (control_dependency_cache);
3985*e4b17023SJohn Marino       control_dependency_cache = NULL;
3986*e4b17023SJohn Marino 
3987*e4b17023SJohn Marino       if (sched_deps_info->generate_spec_deps)
3988*e4b17023SJohn Marino         {
3989*e4b17023SJohn Marino           free (spec_dependency_cache);
3990*e4b17023SJohn Marino           spec_dependency_cache = NULL;
3991*e4b17023SJohn Marino         }
3992*e4b17023SJohn Marino 
3993*e4b17023SJohn Marino     }
3994*e4b17023SJohn Marino }
3995*e4b17023SJohn Marino 
3996*e4b17023SJohn Marino /* Initialize some global variables needed by the dependency analysis
3997*e4b17023SJohn Marino    code.  */
3998*e4b17023SJohn Marino 
3999*e4b17023SJohn Marino void
4000*e4b17023SJohn Marino init_deps_global (void)
4001*e4b17023SJohn Marino {
4002*e4b17023SJohn Marino   CLEAR_HARD_REG_SET (implicit_reg_pending_clobbers);
4003*e4b17023SJohn Marino   CLEAR_HARD_REG_SET (implicit_reg_pending_uses);
4004*e4b17023SJohn Marino   reg_pending_sets = ALLOC_REG_SET (&reg_obstack);
4005*e4b17023SJohn Marino   reg_pending_clobbers = ALLOC_REG_SET (&reg_obstack);
4006*e4b17023SJohn Marino   reg_pending_uses = ALLOC_REG_SET (&reg_obstack);
4007*e4b17023SJohn Marino   reg_pending_control_uses = ALLOC_REG_SET (&reg_obstack);
4008*e4b17023SJohn Marino   reg_pending_barrier = NOT_A_BARRIER;
4009*e4b17023SJohn Marino 
4010*e4b17023SJohn Marino   if (!sel_sched_p () || sched_emulate_haifa_p)
4011*e4b17023SJohn Marino     {
4012*e4b17023SJohn Marino       sched_deps_info->start_insn = haifa_start_insn;
4013*e4b17023SJohn Marino       sched_deps_info->finish_insn = haifa_finish_insn;
4014*e4b17023SJohn Marino 
4015*e4b17023SJohn Marino       sched_deps_info->note_reg_set = haifa_note_reg_set;
4016*e4b17023SJohn Marino       sched_deps_info->note_reg_clobber = haifa_note_reg_clobber;
4017*e4b17023SJohn Marino       sched_deps_info->note_reg_use = haifa_note_reg_use;
4018*e4b17023SJohn Marino 
4019*e4b17023SJohn Marino       sched_deps_info->note_mem_dep = haifa_note_mem_dep;
4020*e4b17023SJohn Marino       sched_deps_info->note_dep = haifa_note_dep;
4021*e4b17023SJohn Marino    }
4022*e4b17023SJohn Marino }
4023*e4b17023SJohn Marino 
4024*e4b17023SJohn Marino /* Free everything used by the dependency analysis code.  */
4025*e4b17023SJohn Marino 
4026*e4b17023SJohn Marino void
4027*e4b17023SJohn Marino finish_deps_global (void)
4028*e4b17023SJohn Marino {
4029*e4b17023SJohn Marino   FREE_REG_SET (reg_pending_sets);
4030*e4b17023SJohn Marino   FREE_REG_SET (reg_pending_clobbers);
4031*e4b17023SJohn Marino   FREE_REG_SET (reg_pending_uses);
4032*e4b17023SJohn Marino   FREE_REG_SET (reg_pending_control_uses);
4033*e4b17023SJohn Marino }
4034*e4b17023SJohn Marino 
4035*e4b17023SJohn Marino /* Estimate the weakness of dependence between MEM1 and MEM2.  */
4036*e4b17023SJohn Marino dw_t
4037*e4b17023SJohn Marino estimate_dep_weak (rtx mem1, rtx mem2)
4038*e4b17023SJohn Marino {
4039*e4b17023SJohn Marino   rtx r1, r2;
4040*e4b17023SJohn Marino 
4041*e4b17023SJohn Marino   if (mem1 == mem2)
4042*e4b17023SJohn Marino     /* MEMs are the same - don't speculate.  */
4043*e4b17023SJohn Marino     return MIN_DEP_WEAK;
4044*e4b17023SJohn Marino 
4045*e4b17023SJohn Marino   r1 = XEXP (mem1, 0);
4046*e4b17023SJohn Marino   r2 = XEXP (mem2, 0);
4047*e4b17023SJohn Marino 
4048*e4b17023SJohn Marino   if (r1 == r2
4049*e4b17023SJohn Marino       || (REG_P (r1) && REG_P (r2)
4050*e4b17023SJohn Marino 	  && REGNO (r1) == REGNO (r2)))
4051*e4b17023SJohn Marino     /* Again, MEMs are the same.  */
4052*e4b17023SJohn Marino     return MIN_DEP_WEAK;
4053*e4b17023SJohn Marino   else if ((REG_P (r1) && !REG_P (r2))
4054*e4b17023SJohn Marino 	   || (!REG_P (r1) && REG_P (r2)))
4055*e4b17023SJohn Marino     /* Different addressing modes - reason to be more speculative,
4056*e4b17023SJohn Marino        than usual.  */
4057*e4b17023SJohn Marino     return NO_DEP_WEAK - (NO_DEP_WEAK - UNCERTAIN_DEP_WEAK) / 2;
4058*e4b17023SJohn Marino   else
4059*e4b17023SJohn Marino     /* We can't say anything about the dependence.  */
4060*e4b17023SJohn Marino     return UNCERTAIN_DEP_WEAK;
4061*e4b17023SJohn Marino }
4062*e4b17023SJohn Marino 
4063*e4b17023SJohn Marino /* Add or update backward dependence between INSN and ELEM with type DEP_TYPE.
4064*e4b17023SJohn Marino    This function can handle same INSN and ELEM (INSN == ELEM).
4065*e4b17023SJohn Marino    It is a convenience wrapper.  */
4066*e4b17023SJohn Marino static void
4067*e4b17023SJohn Marino add_dependence_1 (rtx insn, rtx elem, enum reg_note dep_type)
4068*e4b17023SJohn Marino {
4069*e4b17023SJohn Marino   ds_t ds;
4070*e4b17023SJohn Marino   bool internal;
4071*e4b17023SJohn Marino 
4072*e4b17023SJohn Marino   if (dep_type == REG_DEP_TRUE)
4073*e4b17023SJohn Marino     ds = DEP_TRUE;
4074*e4b17023SJohn Marino   else if (dep_type == REG_DEP_OUTPUT)
4075*e4b17023SJohn Marino     ds = DEP_OUTPUT;
4076*e4b17023SJohn Marino   else if (dep_type == REG_DEP_CONTROL)
4077*e4b17023SJohn Marino     ds = DEP_CONTROL;
4078*e4b17023SJohn Marino   else
4079*e4b17023SJohn Marino     {
4080*e4b17023SJohn Marino       gcc_assert (dep_type == REG_DEP_ANTI);
4081*e4b17023SJohn Marino       ds = DEP_ANTI;
4082*e4b17023SJohn Marino     }
4083*e4b17023SJohn Marino 
4084*e4b17023SJohn Marino   /* When add_dependence is called from inside sched-deps.c, we expect
4085*e4b17023SJohn Marino      cur_insn to be non-null.  */
4086*e4b17023SJohn Marino   internal = cur_insn != NULL;
4087*e4b17023SJohn Marino   if (internal)
4088*e4b17023SJohn Marino     gcc_assert (insn == cur_insn);
4089*e4b17023SJohn Marino   else
4090*e4b17023SJohn Marino     cur_insn = insn;
4091*e4b17023SJohn Marino 
4092*e4b17023SJohn Marino   note_dep (elem, ds);
4093*e4b17023SJohn Marino   if (!internal)
4094*e4b17023SJohn Marino     cur_insn = NULL;
4095*e4b17023SJohn Marino }
4096*e4b17023SJohn Marino 
4097*e4b17023SJohn Marino /* Return weakness of speculative type TYPE in the dep_status DS.  */
4098*e4b17023SJohn Marino dw_t
4099*e4b17023SJohn Marino get_dep_weak_1 (ds_t ds, ds_t type)
4100*e4b17023SJohn Marino {
4101*e4b17023SJohn Marino   ds = ds & type;
4102*e4b17023SJohn Marino 
4103*e4b17023SJohn Marino   switch (type)
4104*e4b17023SJohn Marino     {
4105*e4b17023SJohn Marino     case BEGIN_DATA: ds >>= BEGIN_DATA_BITS_OFFSET; break;
4106*e4b17023SJohn Marino     case BE_IN_DATA: ds >>= BE_IN_DATA_BITS_OFFSET; break;
4107*e4b17023SJohn Marino     case BEGIN_CONTROL: ds >>= BEGIN_CONTROL_BITS_OFFSET; break;
4108*e4b17023SJohn Marino     case BE_IN_CONTROL: ds >>= BE_IN_CONTROL_BITS_OFFSET; break;
4109*e4b17023SJohn Marino     default: gcc_unreachable ();
4110*e4b17023SJohn Marino     }
4111*e4b17023SJohn Marino 
4112*e4b17023SJohn Marino   return (dw_t) ds;
4113*e4b17023SJohn Marino }
4114*e4b17023SJohn Marino 
4115*e4b17023SJohn Marino dw_t
4116*e4b17023SJohn Marino get_dep_weak (ds_t ds, ds_t type)
4117*e4b17023SJohn Marino {
4118*e4b17023SJohn Marino   dw_t dw = get_dep_weak_1 (ds, type);
4119*e4b17023SJohn Marino 
4120*e4b17023SJohn Marino   gcc_assert (MIN_DEP_WEAK <= dw && dw <= MAX_DEP_WEAK);
4121*e4b17023SJohn Marino   return dw;
4122*e4b17023SJohn Marino }
4123*e4b17023SJohn Marino 
4124*e4b17023SJohn Marino /* Return the dep_status, which has the same parameters as DS, except for
4125*e4b17023SJohn Marino    speculative type TYPE, that will have weakness DW.  */
4126*e4b17023SJohn Marino ds_t
4127*e4b17023SJohn Marino set_dep_weak (ds_t ds, ds_t type, dw_t dw)
4128*e4b17023SJohn Marino {
4129*e4b17023SJohn Marino   gcc_assert (MIN_DEP_WEAK <= dw && dw <= MAX_DEP_WEAK);
4130*e4b17023SJohn Marino 
4131*e4b17023SJohn Marino   ds &= ~type;
4132*e4b17023SJohn Marino   switch (type)
4133*e4b17023SJohn Marino     {
4134*e4b17023SJohn Marino     case BEGIN_DATA: ds |= ((ds_t) dw) << BEGIN_DATA_BITS_OFFSET; break;
4135*e4b17023SJohn Marino     case BE_IN_DATA: ds |= ((ds_t) dw) << BE_IN_DATA_BITS_OFFSET; break;
4136*e4b17023SJohn Marino     case BEGIN_CONTROL: ds |= ((ds_t) dw) << BEGIN_CONTROL_BITS_OFFSET; break;
4137*e4b17023SJohn Marino     case BE_IN_CONTROL: ds |= ((ds_t) dw) << BE_IN_CONTROL_BITS_OFFSET; break;
4138*e4b17023SJohn Marino     default: gcc_unreachable ();
4139*e4b17023SJohn Marino     }
4140*e4b17023SJohn Marino   return ds;
4141*e4b17023SJohn Marino }
4142*e4b17023SJohn Marino 
4143*e4b17023SJohn Marino /* Return the join of two dep_statuses DS1 and DS2.
4144*e4b17023SJohn Marino    If MAX_P is true then choose the greater probability,
4145*e4b17023SJohn Marino    otherwise multiply probabilities.
4146*e4b17023SJohn Marino    This function assumes that both DS1 and DS2 contain speculative bits.  */
4147*e4b17023SJohn Marino static ds_t
4148*e4b17023SJohn Marino ds_merge_1 (ds_t ds1, ds_t ds2, bool max_p)
4149*e4b17023SJohn Marino {
4150*e4b17023SJohn Marino   ds_t ds, t;
4151*e4b17023SJohn Marino 
4152*e4b17023SJohn Marino   gcc_assert ((ds1 & SPECULATIVE) && (ds2 & SPECULATIVE));
4153*e4b17023SJohn Marino 
4154*e4b17023SJohn Marino   ds = (ds1 & DEP_TYPES) | (ds2 & DEP_TYPES);
4155*e4b17023SJohn Marino 
4156*e4b17023SJohn Marino   t = FIRST_SPEC_TYPE;
4157*e4b17023SJohn Marino   do
4158*e4b17023SJohn Marino     {
4159*e4b17023SJohn Marino       if ((ds1 & t) && !(ds2 & t))
4160*e4b17023SJohn Marino 	ds |= ds1 & t;
4161*e4b17023SJohn Marino       else if (!(ds1 & t) && (ds2 & t))
4162*e4b17023SJohn Marino 	ds |= ds2 & t;
4163*e4b17023SJohn Marino       else if ((ds1 & t) && (ds2 & t))
4164*e4b17023SJohn Marino 	{
4165*e4b17023SJohn Marino 	  dw_t dw1 = get_dep_weak (ds1, t);
4166*e4b17023SJohn Marino 	  dw_t dw2 = get_dep_weak (ds2, t);
4167*e4b17023SJohn Marino 	  ds_t dw;
4168*e4b17023SJohn Marino 
4169*e4b17023SJohn Marino 	  if (!max_p)
4170*e4b17023SJohn Marino 	    {
4171*e4b17023SJohn Marino 	      dw = ((ds_t) dw1) * ((ds_t) dw2);
4172*e4b17023SJohn Marino 	      dw /= MAX_DEP_WEAK;
4173*e4b17023SJohn Marino 	      if (dw < MIN_DEP_WEAK)
4174*e4b17023SJohn Marino 		dw = MIN_DEP_WEAK;
4175*e4b17023SJohn Marino 	    }
4176*e4b17023SJohn Marino 	  else
4177*e4b17023SJohn Marino 	    {
4178*e4b17023SJohn Marino 	      if (dw1 >= dw2)
4179*e4b17023SJohn Marino 		dw = dw1;
4180*e4b17023SJohn Marino 	      else
4181*e4b17023SJohn Marino 		dw = dw2;
4182*e4b17023SJohn Marino 	    }
4183*e4b17023SJohn Marino 
4184*e4b17023SJohn Marino 	  ds = set_dep_weak (ds, t, (dw_t) dw);
4185*e4b17023SJohn Marino 	}
4186*e4b17023SJohn Marino 
4187*e4b17023SJohn Marino       if (t == LAST_SPEC_TYPE)
4188*e4b17023SJohn Marino 	break;
4189*e4b17023SJohn Marino       t <<= SPEC_TYPE_SHIFT;
4190*e4b17023SJohn Marino     }
4191*e4b17023SJohn Marino   while (1);
4192*e4b17023SJohn Marino 
4193*e4b17023SJohn Marino   return ds;
4194*e4b17023SJohn Marino }
4195*e4b17023SJohn Marino 
4196*e4b17023SJohn Marino /* Return the join of two dep_statuses DS1 and DS2.
4197*e4b17023SJohn Marino    This function assumes that both DS1 and DS2 contain speculative bits.  */
4198*e4b17023SJohn Marino ds_t
4199*e4b17023SJohn Marino ds_merge (ds_t ds1, ds_t ds2)
4200*e4b17023SJohn Marino {
4201*e4b17023SJohn Marino   return ds_merge_1 (ds1, ds2, false);
4202*e4b17023SJohn Marino }
4203*e4b17023SJohn Marino 
4204*e4b17023SJohn Marino /* Return the join of two dep_statuses DS1 and DS2.  */
4205*e4b17023SJohn Marino ds_t
4206*e4b17023SJohn Marino ds_full_merge (ds_t ds, ds_t ds2, rtx mem1, rtx mem2)
4207*e4b17023SJohn Marino {
4208*e4b17023SJohn Marino   ds_t new_status = ds | ds2;
4209*e4b17023SJohn Marino 
4210*e4b17023SJohn Marino   if (new_status & SPECULATIVE)
4211*e4b17023SJohn Marino     {
4212*e4b17023SJohn Marino       if ((ds && !(ds & SPECULATIVE))
4213*e4b17023SJohn Marino 	  || (ds2 && !(ds2 & SPECULATIVE)))
4214*e4b17023SJohn Marino 	/* Then this dep can't be speculative.  */
4215*e4b17023SJohn Marino 	new_status &= ~SPECULATIVE;
4216*e4b17023SJohn Marino       else
4217*e4b17023SJohn Marino 	{
4218*e4b17023SJohn Marino 	  /* Both are speculative.  Merging probabilities.  */
4219*e4b17023SJohn Marino 	  if (mem1)
4220*e4b17023SJohn Marino 	    {
4221*e4b17023SJohn Marino 	      dw_t dw;
4222*e4b17023SJohn Marino 
4223*e4b17023SJohn Marino 	      dw = estimate_dep_weak (mem1, mem2);
4224*e4b17023SJohn Marino 	      ds = set_dep_weak (ds, BEGIN_DATA, dw);
4225*e4b17023SJohn Marino 	    }
4226*e4b17023SJohn Marino 
4227*e4b17023SJohn Marino 	  if (!ds)
4228*e4b17023SJohn Marino 	    new_status = ds2;
4229*e4b17023SJohn Marino 	  else if (!ds2)
4230*e4b17023SJohn Marino 	    new_status = ds;
4231*e4b17023SJohn Marino 	  else
4232*e4b17023SJohn Marino 	    new_status = ds_merge (ds2, ds);
4233*e4b17023SJohn Marino 	}
4234*e4b17023SJohn Marino     }
4235*e4b17023SJohn Marino 
4236*e4b17023SJohn Marino   return new_status;
4237*e4b17023SJohn Marino }
4238*e4b17023SJohn Marino 
4239*e4b17023SJohn Marino /* Return the join of DS1 and DS2.  Use maximum instead of multiplying
4240*e4b17023SJohn Marino    probabilities.  */
4241*e4b17023SJohn Marino ds_t
4242*e4b17023SJohn Marino ds_max_merge (ds_t ds1, ds_t ds2)
4243*e4b17023SJohn Marino {
4244*e4b17023SJohn Marino   if (ds1 == 0 && ds2 == 0)
4245*e4b17023SJohn Marino     return 0;
4246*e4b17023SJohn Marino 
4247*e4b17023SJohn Marino   if (ds1 == 0 && ds2 != 0)
4248*e4b17023SJohn Marino     return ds2;
4249*e4b17023SJohn Marino 
4250*e4b17023SJohn Marino   if (ds1 != 0 && ds2 == 0)
4251*e4b17023SJohn Marino     return ds1;
4252*e4b17023SJohn Marino 
4253*e4b17023SJohn Marino   return ds_merge_1 (ds1, ds2, true);
4254*e4b17023SJohn Marino }
4255*e4b17023SJohn Marino 
4256*e4b17023SJohn Marino /* Return the probability of speculation success for the speculation
4257*e4b17023SJohn Marino    status DS.  */
4258*e4b17023SJohn Marino dw_t
4259*e4b17023SJohn Marino ds_weak (ds_t ds)
4260*e4b17023SJohn Marino {
4261*e4b17023SJohn Marino   ds_t res = 1, dt;
4262*e4b17023SJohn Marino   int n = 0;
4263*e4b17023SJohn Marino 
4264*e4b17023SJohn Marino   dt = FIRST_SPEC_TYPE;
4265*e4b17023SJohn Marino   do
4266*e4b17023SJohn Marino     {
4267*e4b17023SJohn Marino       if (ds & dt)
4268*e4b17023SJohn Marino 	{
4269*e4b17023SJohn Marino 	  res *= (ds_t) get_dep_weak (ds, dt);
4270*e4b17023SJohn Marino 	  n++;
4271*e4b17023SJohn Marino 	}
4272*e4b17023SJohn Marino 
4273*e4b17023SJohn Marino       if (dt == LAST_SPEC_TYPE)
4274*e4b17023SJohn Marino 	break;
4275*e4b17023SJohn Marino       dt <<= SPEC_TYPE_SHIFT;
4276*e4b17023SJohn Marino     }
4277*e4b17023SJohn Marino   while (1);
4278*e4b17023SJohn Marino 
4279*e4b17023SJohn Marino   gcc_assert (n);
4280*e4b17023SJohn Marino   while (--n)
4281*e4b17023SJohn Marino     res /= MAX_DEP_WEAK;
4282*e4b17023SJohn Marino 
4283*e4b17023SJohn Marino   if (res < MIN_DEP_WEAK)
4284*e4b17023SJohn Marino     res = MIN_DEP_WEAK;
4285*e4b17023SJohn Marino 
4286*e4b17023SJohn Marino   gcc_assert (res <= MAX_DEP_WEAK);
4287*e4b17023SJohn Marino 
4288*e4b17023SJohn Marino   return (dw_t) res;
4289*e4b17023SJohn Marino }
4290*e4b17023SJohn Marino 
4291*e4b17023SJohn Marino /* Return a dep status that contains all speculation types of DS.  */
4292*e4b17023SJohn Marino ds_t
4293*e4b17023SJohn Marino ds_get_speculation_types (ds_t ds)
4294*e4b17023SJohn Marino {
4295*e4b17023SJohn Marino   if (ds & BEGIN_DATA)
4296*e4b17023SJohn Marino     ds |= BEGIN_DATA;
4297*e4b17023SJohn Marino   if (ds & BE_IN_DATA)
4298*e4b17023SJohn Marino     ds |= BE_IN_DATA;
4299*e4b17023SJohn Marino   if (ds & BEGIN_CONTROL)
4300*e4b17023SJohn Marino     ds |= BEGIN_CONTROL;
4301*e4b17023SJohn Marino   if (ds & BE_IN_CONTROL)
4302*e4b17023SJohn Marino     ds |= BE_IN_CONTROL;
4303*e4b17023SJohn Marino 
4304*e4b17023SJohn Marino   return ds & SPECULATIVE;
4305*e4b17023SJohn Marino }
4306*e4b17023SJohn Marino 
4307*e4b17023SJohn Marino /* Return a dep status that contains maximal weakness for each speculation
4308*e4b17023SJohn Marino    type present in DS.  */
4309*e4b17023SJohn Marino ds_t
4310*e4b17023SJohn Marino ds_get_max_dep_weak (ds_t ds)
4311*e4b17023SJohn Marino {
4312*e4b17023SJohn Marino   if (ds & BEGIN_DATA)
4313*e4b17023SJohn Marino     ds = set_dep_weak (ds, BEGIN_DATA, MAX_DEP_WEAK);
4314*e4b17023SJohn Marino   if (ds & BE_IN_DATA)
4315*e4b17023SJohn Marino     ds = set_dep_weak (ds, BE_IN_DATA, MAX_DEP_WEAK);
4316*e4b17023SJohn Marino   if (ds & BEGIN_CONTROL)
4317*e4b17023SJohn Marino     ds = set_dep_weak (ds, BEGIN_CONTROL, MAX_DEP_WEAK);
4318*e4b17023SJohn Marino   if (ds & BE_IN_CONTROL)
4319*e4b17023SJohn Marino     ds = set_dep_weak (ds, BE_IN_CONTROL, MAX_DEP_WEAK);
4320*e4b17023SJohn Marino 
4321*e4b17023SJohn Marino   return ds;
4322*e4b17023SJohn Marino }
4323*e4b17023SJohn Marino 
4324*e4b17023SJohn Marino /* Dump information about the dependence status S.  */
4325*e4b17023SJohn Marino static void
4326*e4b17023SJohn Marino dump_ds (FILE *f, ds_t s)
4327*e4b17023SJohn Marino {
4328*e4b17023SJohn Marino   fprintf (f, "{");
4329*e4b17023SJohn Marino 
4330*e4b17023SJohn Marino   if (s & BEGIN_DATA)
4331*e4b17023SJohn Marino     fprintf (f, "BEGIN_DATA: %d; ", get_dep_weak_1 (s, BEGIN_DATA));
4332*e4b17023SJohn Marino   if (s & BE_IN_DATA)
4333*e4b17023SJohn Marino     fprintf (f, "BE_IN_DATA: %d; ", get_dep_weak_1 (s, BE_IN_DATA));
4334*e4b17023SJohn Marino   if (s & BEGIN_CONTROL)
4335*e4b17023SJohn Marino     fprintf (f, "BEGIN_CONTROL: %d; ", get_dep_weak_1 (s, BEGIN_CONTROL));
4336*e4b17023SJohn Marino   if (s & BE_IN_CONTROL)
4337*e4b17023SJohn Marino     fprintf (f, "BE_IN_CONTROL: %d; ", get_dep_weak_1 (s, BE_IN_CONTROL));
4338*e4b17023SJohn Marino 
4339*e4b17023SJohn Marino   if (s & HARD_DEP)
4340*e4b17023SJohn Marino     fprintf (f, "HARD_DEP; ");
4341*e4b17023SJohn Marino 
4342*e4b17023SJohn Marino   if (s & DEP_TRUE)
4343*e4b17023SJohn Marino     fprintf (f, "DEP_TRUE; ");
4344*e4b17023SJohn Marino   if (s & DEP_OUTPUT)
4345*e4b17023SJohn Marino     fprintf (f, "DEP_OUTPUT; ");
4346*e4b17023SJohn Marino   if (s & DEP_ANTI)
4347*e4b17023SJohn Marino     fprintf (f, "DEP_ANTI; ");
4348*e4b17023SJohn Marino   if (s & DEP_CONTROL)
4349*e4b17023SJohn Marino     fprintf (f, "DEP_CONTROL; ");
4350*e4b17023SJohn Marino 
4351*e4b17023SJohn Marino   fprintf (f, "}");
4352*e4b17023SJohn Marino }
4353*e4b17023SJohn Marino 
4354*e4b17023SJohn Marino DEBUG_FUNCTION void
4355*e4b17023SJohn Marino debug_ds (ds_t s)
4356*e4b17023SJohn Marino {
4357*e4b17023SJohn Marino   dump_ds (stderr, s);
4358*e4b17023SJohn Marino   fprintf (stderr, "\n");
4359*e4b17023SJohn Marino }
4360*e4b17023SJohn Marino 
4361*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
4362*e4b17023SJohn Marino /* Verify that dependence type and status are consistent.
4363*e4b17023SJohn Marino    If RELAXED_P is true, then skip dep_weakness checks.  */
4364*e4b17023SJohn Marino static void
4365*e4b17023SJohn Marino check_dep (dep_t dep, bool relaxed_p)
4366*e4b17023SJohn Marino {
4367*e4b17023SJohn Marino   enum reg_note dt = DEP_TYPE (dep);
4368*e4b17023SJohn Marino   ds_t ds = DEP_STATUS (dep);
4369*e4b17023SJohn Marino 
4370*e4b17023SJohn Marino   gcc_assert (DEP_PRO (dep) != DEP_CON (dep));
4371*e4b17023SJohn Marino 
4372*e4b17023SJohn Marino   if (!(current_sched_info->flags & USE_DEPS_LIST))
4373*e4b17023SJohn Marino     {
4374*e4b17023SJohn Marino       gcc_assert (ds == 0);
4375*e4b17023SJohn Marino       return;
4376*e4b17023SJohn Marino     }
4377*e4b17023SJohn Marino 
4378*e4b17023SJohn Marino   /* Check that dependence type contains the same bits as the status.  */
4379*e4b17023SJohn Marino   if (dt == REG_DEP_TRUE)
4380*e4b17023SJohn Marino     gcc_assert (ds & DEP_TRUE);
4381*e4b17023SJohn Marino   else if (dt == REG_DEP_OUTPUT)
4382*e4b17023SJohn Marino     gcc_assert ((ds & DEP_OUTPUT)
4383*e4b17023SJohn Marino 		&& !(ds & DEP_TRUE));
4384*e4b17023SJohn Marino   else if (dt == REG_DEP_ANTI)
4385*e4b17023SJohn Marino     gcc_assert ((ds & DEP_ANTI)
4386*e4b17023SJohn Marino 		&& !(ds & (DEP_OUTPUT | DEP_TRUE)));
4387*e4b17023SJohn Marino   else
4388*e4b17023SJohn Marino     gcc_assert (dt == REG_DEP_CONTROL
4389*e4b17023SJohn Marino 		&& (ds & DEP_CONTROL)
4390*e4b17023SJohn Marino 		&& !(ds & (DEP_OUTPUT | DEP_ANTI | DEP_TRUE)));
4391*e4b17023SJohn Marino 
4392*e4b17023SJohn Marino   /* HARD_DEP can not appear in dep_status of a link.  */
4393*e4b17023SJohn Marino   gcc_assert (!(ds & HARD_DEP));
4394*e4b17023SJohn Marino 
4395*e4b17023SJohn Marino   /* Check that dependence status is set correctly when speculation is not
4396*e4b17023SJohn Marino      supported.  */
4397*e4b17023SJohn Marino   if (!sched_deps_info->generate_spec_deps)
4398*e4b17023SJohn Marino     gcc_assert (!(ds & SPECULATIVE));
4399*e4b17023SJohn Marino   else if (ds & SPECULATIVE)
4400*e4b17023SJohn Marino     {
4401*e4b17023SJohn Marino       if (!relaxed_p)
4402*e4b17023SJohn Marino 	{
4403*e4b17023SJohn Marino 	  ds_t type = FIRST_SPEC_TYPE;
4404*e4b17023SJohn Marino 
4405*e4b17023SJohn Marino 	  /* Check that dependence weakness is in proper range.  */
4406*e4b17023SJohn Marino 	  do
4407*e4b17023SJohn Marino 	    {
4408*e4b17023SJohn Marino 	      if (ds & type)
4409*e4b17023SJohn Marino 		get_dep_weak (ds, type);
4410*e4b17023SJohn Marino 
4411*e4b17023SJohn Marino 	      if (type == LAST_SPEC_TYPE)
4412*e4b17023SJohn Marino 		break;
4413*e4b17023SJohn Marino 	      type <<= SPEC_TYPE_SHIFT;
4414*e4b17023SJohn Marino 	    }
4415*e4b17023SJohn Marino 	  while (1);
4416*e4b17023SJohn Marino 	}
4417*e4b17023SJohn Marino 
4418*e4b17023SJohn Marino       if (ds & BEGIN_SPEC)
4419*e4b17023SJohn Marino 	{
4420*e4b17023SJohn Marino 	  /* Only true dependence can be data speculative.  */
4421*e4b17023SJohn Marino 	  if (ds & BEGIN_DATA)
4422*e4b17023SJohn Marino 	    gcc_assert (ds & DEP_TRUE);
4423*e4b17023SJohn Marino 
4424*e4b17023SJohn Marino 	  /* Control dependencies in the insn scheduler are represented by
4425*e4b17023SJohn Marino 	     anti-dependencies, therefore only anti dependence can be
4426*e4b17023SJohn Marino 	     control speculative.  */
4427*e4b17023SJohn Marino 	  if (ds & BEGIN_CONTROL)
4428*e4b17023SJohn Marino 	    gcc_assert (ds & DEP_ANTI);
4429*e4b17023SJohn Marino 	}
4430*e4b17023SJohn Marino       else
4431*e4b17023SJohn Marino 	{
4432*e4b17023SJohn Marino 	  /* Subsequent speculations should resolve true dependencies.  */
4433*e4b17023SJohn Marino 	  gcc_assert ((ds & DEP_TYPES) == DEP_TRUE);
4434*e4b17023SJohn Marino 	}
4435*e4b17023SJohn Marino 
4436*e4b17023SJohn Marino       /* Check that true and anti dependencies can't have other speculative
4437*e4b17023SJohn Marino 	 statuses.  */
4438*e4b17023SJohn Marino       if (ds & DEP_TRUE)
4439*e4b17023SJohn Marino 	gcc_assert (ds & (BEGIN_DATA | BE_IN_SPEC));
4440*e4b17023SJohn Marino       /* An output dependence can't be speculative at all.  */
4441*e4b17023SJohn Marino       gcc_assert (!(ds & DEP_OUTPUT));
4442*e4b17023SJohn Marino       if (ds & DEP_ANTI)
4443*e4b17023SJohn Marino 	gcc_assert (ds & BEGIN_CONTROL);
4444*e4b17023SJohn Marino     }
4445*e4b17023SJohn Marino }
4446*e4b17023SJohn Marino #endif /* ENABLE_CHECKING */
4447*e4b17023SJohn Marino 
4448*e4b17023SJohn Marino #endif /* INSN_SCHEDULING */
4449