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, ®_last->sets, 0, 3102*e4b17023SJohn Marino REG_DEP_OUTPUT); 3103*e4b17023SJohn Marino add_dependence_list_and_free (deps, insn, 3104*e4b17023SJohn Marino ®_last->implicit_sets, 0, 3105*e4b17023SJohn Marino REG_DEP_ANTI); 3106*e4b17023SJohn Marino add_dependence_list_and_free (deps, insn, ®_last->uses, 0, 3107*e4b17023SJohn Marino REG_DEP_ANTI); 3108*e4b17023SJohn Marino add_dependence_list_and_free (deps, insn, 3109*e4b17023SJohn Marino ®_last->control_uses, 0, 3110*e4b17023SJohn Marino REG_DEP_ANTI); 3111*e4b17023SJohn Marino add_dependence_list_and_free 3112*e4b17023SJohn Marino (deps, insn, ®_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, ®_last->sets, 0, 3143*e4b17023SJohn Marino REG_DEP_OUTPUT); 3144*e4b17023SJohn Marino add_dependence_list_and_free (deps, insn, 3145*e4b17023SJohn Marino ®_last->implicit_sets, 3146*e4b17023SJohn Marino 0, REG_DEP_ANTI); 3147*e4b17023SJohn Marino add_dependence_list_and_free (deps, insn, ®_last->clobbers, 0, 3148*e4b17023SJohn Marino REG_DEP_OUTPUT); 3149*e4b17023SJohn Marino add_dependence_list_and_free (deps, insn, ®_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, ®_last->uses, 0, 3235*e4b17023SJohn Marino REG_DEP_ANTI); 3236*e4b17023SJohn Marino add_dependence_list_and_free (deps, insn, 3237*e4b17023SJohn Marino ®_last->control_uses, 0, 3238*e4b17023SJohn Marino REG_DEP_CONTROL); 3239*e4b17023SJohn Marino add_dependence_list_and_free (deps, insn, ®_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 ®_last->implicit_sets, 0, 3244*e4b17023SJohn Marino REG_DEP_ANTI); 3245*e4b17023SJohn Marino add_dependence_list_and_free (deps, insn, ®_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 (®_last->uses); 3800*e4b17023SJohn Marino if (reg_last->sets) 3801*e4b17023SJohn Marino free_INSN_LIST_list (®_last->sets); 3802*e4b17023SJohn Marino if (reg_last->implicit_sets) 3803*e4b17023SJohn Marino free_INSN_LIST_list (®_last->implicit_sets); 3804*e4b17023SJohn Marino if (reg_last->control_uses) 3805*e4b17023SJohn Marino free_INSN_LIST_list (®_last->control_uses); 3806*e4b17023SJohn Marino if (reg_last->clobbers) 3807*e4b17023SJohn Marino free_INSN_LIST_list (®_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, ®_last->uses); 3845*e4b17023SJohn Marino if (reg_last->sets) 3846*e4b17023SJohn Marino remove_from_dependence_list (insn, ®_last->sets); 3847*e4b17023SJohn Marino if (reg_last->implicit_sets) 3848*e4b17023SJohn Marino remove_from_dependence_list (insn, ®_last->implicit_sets); 3849*e4b17023SJohn Marino if (reg_last->clobbers) 3850*e4b17023SJohn Marino remove_from_dependence_list (insn, ®_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 (®_obstack); 4005*e4b17023SJohn Marino reg_pending_clobbers = ALLOC_REG_SET (®_obstack); 4006*e4b17023SJohn Marino reg_pending_uses = ALLOC_REG_SET (®_obstack); 4007*e4b17023SJohn Marino reg_pending_control_uses = ALLOC_REG_SET (®_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