1*e4b17023SJohn Marino /* Global constant/copy propagation for RTL. 2*e4b17023SJohn Marino Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 3*e4b17023SJohn Marino 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4*e4b17023SJohn Marino 5*e4b17023SJohn Marino This file is part of GCC. 6*e4b17023SJohn Marino 7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under 8*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free 9*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later 10*e4b17023SJohn Marino version. 11*e4b17023SJohn Marino 12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or 14*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15*e4b17023SJohn Marino for more details. 16*e4b17023SJohn Marino 17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License 18*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see 19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */ 20*e4b17023SJohn Marino 21*e4b17023SJohn Marino #include "config.h" 22*e4b17023SJohn Marino #include "system.h" 23*e4b17023SJohn Marino #include "coretypes.h" 24*e4b17023SJohn Marino #include "tm.h" 25*e4b17023SJohn Marino #include "diagnostic-core.h" 26*e4b17023SJohn Marino #include "toplev.h" 27*e4b17023SJohn Marino 28*e4b17023SJohn Marino #include "rtl.h" 29*e4b17023SJohn Marino #include "tree.h" 30*e4b17023SJohn Marino #include "tm_p.h" 31*e4b17023SJohn Marino #include "regs.h" 32*e4b17023SJohn Marino #include "hard-reg-set.h" 33*e4b17023SJohn Marino #include "flags.h" 34*e4b17023SJohn Marino #include "insn-config.h" 35*e4b17023SJohn Marino #include "recog.h" 36*e4b17023SJohn Marino #include "basic-block.h" 37*e4b17023SJohn Marino #include "output.h" 38*e4b17023SJohn Marino #include "function.h" 39*e4b17023SJohn Marino #include "expr.h" 40*e4b17023SJohn Marino #include "except.h" 41*e4b17023SJohn Marino #include "params.h" 42*e4b17023SJohn Marino #include "cselib.h" 43*e4b17023SJohn Marino #include "intl.h" 44*e4b17023SJohn Marino #include "obstack.h" 45*e4b17023SJohn Marino #include "timevar.h" 46*e4b17023SJohn Marino #include "tree-pass.h" 47*e4b17023SJohn Marino #include "hashtab.h" 48*e4b17023SJohn Marino #include "df.h" 49*e4b17023SJohn Marino #include "dbgcnt.h" 50*e4b17023SJohn Marino #include "target.h" 51*e4b17023SJohn Marino 52*e4b17023SJohn Marino 53*e4b17023SJohn Marino /* An obstack for our working variables. */ 54*e4b17023SJohn Marino static struct obstack cprop_obstack; 55*e4b17023SJohn Marino 56*e4b17023SJohn Marino /* Occurrence of an expression. 57*e4b17023SJohn Marino There is one per basic block. If a pattern appears more than once the 58*e4b17023SJohn Marino last appearance is used. */ 59*e4b17023SJohn Marino 60*e4b17023SJohn Marino struct occr 61*e4b17023SJohn Marino { 62*e4b17023SJohn Marino /* Next occurrence of this expression. */ 63*e4b17023SJohn Marino struct occr *next; 64*e4b17023SJohn Marino /* The insn that computes the expression. */ 65*e4b17023SJohn Marino rtx insn; 66*e4b17023SJohn Marino }; 67*e4b17023SJohn Marino 68*e4b17023SJohn Marino typedef struct occr *occr_t; 69*e4b17023SJohn Marino DEF_VEC_P (occr_t); 70*e4b17023SJohn Marino DEF_VEC_ALLOC_P (occr_t, heap); 71*e4b17023SJohn Marino 72*e4b17023SJohn Marino /* Hash table entry for assignment expressions. */ 73*e4b17023SJohn Marino 74*e4b17023SJohn Marino struct expr 75*e4b17023SJohn Marino { 76*e4b17023SJohn Marino /* The expression (DEST := SRC). */ 77*e4b17023SJohn Marino rtx dest; 78*e4b17023SJohn Marino rtx src; 79*e4b17023SJohn Marino 80*e4b17023SJohn Marino /* Index in the available expression bitmaps. */ 81*e4b17023SJohn Marino int bitmap_index; 82*e4b17023SJohn Marino /* Next entry with the same hash. */ 83*e4b17023SJohn Marino struct expr *next_same_hash; 84*e4b17023SJohn Marino /* List of available occurrence in basic blocks in the function. 85*e4b17023SJohn Marino An "available occurrence" is one that is the last occurrence in the 86*e4b17023SJohn Marino basic block and whose operands are not modified by following statements 87*e4b17023SJohn Marino in the basic block [including this insn]. */ 88*e4b17023SJohn Marino struct occr *avail_occr; 89*e4b17023SJohn Marino }; 90*e4b17023SJohn Marino 91*e4b17023SJohn Marino /* Hash table for copy propagation expressions. 92*e4b17023SJohn Marino Each hash table is an array of buckets. 93*e4b17023SJohn Marino ??? It is known that if it were an array of entries, structure elements 94*e4b17023SJohn Marino `next_same_hash' and `bitmap_index' wouldn't be necessary. However, it is 95*e4b17023SJohn Marino not clear whether in the final analysis a sufficient amount of memory would 96*e4b17023SJohn Marino be saved as the size of the available expression bitmaps would be larger 97*e4b17023SJohn Marino [one could build a mapping table without holes afterwards though]. 98*e4b17023SJohn Marino Someday I'll perform the computation and figure it out. */ 99*e4b17023SJohn Marino 100*e4b17023SJohn Marino struct hash_table_d 101*e4b17023SJohn Marino { 102*e4b17023SJohn Marino /* The table itself. 103*e4b17023SJohn Marino This is an array of `set_hash_table_size' elements. */ 104*e4b17023SJohn Marino struct expr **table; 105*e4b17023SJohn Marino 106*e4b17023SJohn Marino /* Size of the hash table, in elements. */ 107*e4b17023SJohn Marino unsigned int size; 108*e4b17023SJohn Marino 109*e4b17023SJohn Marino /* Number of hash table elements. */ 110*e4b17023SJohn Marino unsigned int n_elems; 111*e4b17023SJohn Marino }; 112*e4b17023SJohn Marino 113*e4b17023SJohn Marino /* Copy propagation hash table. */ 114*e4b17023SJohn Marino static struct hash_table_d set_hash_table; 115*e4b17023SJohn Marino 116*e4b17023SJohn Marino /* Array of implicit set patterns indexed by basic block index. */ 117*e4b17023SJohn Marino static rtx *implicit_sets; 118*e4b17023SJohn Marino 119*e4b17023SJohn Marino /* Array of indexes of expressions for implicit set patterns indexed by basic 120*e4b17023SJohn Marino block index. In other words, implicit_set_indexes[i] is the bitmap_index 121*e4b17023SJohn Marino of the expression whose RTX is implicit_sets[i]. */ 122*e4b17023SJohn Marino static int *implicit_set_indexes; 123*e4b17023SJohn Marino 124*e4b17023SJohn Marino /* Bitmap containing one bit for each register in the program. 125*e4b17023SJohn Marino Used when performing GCSE to track which registers have been set since 126*e4b17023SJohn Marino the start or end of the basic block while traversing that block. */ 127*e4b17023SJohn Marino static regset reg_set_bitmap; 128*e4b17023SJohn Marino 129*e4b17023SJohn Marino /* Various variables for statistics gathering. */ 130*e4b17023SJohn Marino 131*e4b17023SJohn Marino /* Memory used in a pass. 132*e4b17023SJohn Marino This isn't intended to be absolutely precise. Its intent is only 133*e4b17023SJohn Marino to keep an eye on memory usage. */ 134*e4b17023SJohn Marino static int bytes_used; 135*e4b17023SJohn Marino 136*e4b17023SJohn Marino /* Number of local constants propagated. */ 137*e4b17023SJohn Marino static int local_const_prop_count; 138*e4b17023SJohn Marino /* Number of local copies propagated. */ 139*e4b17023SJohn Marino static int local_copy_prop_count; 140*e4b17023SJohn Marino /* Number of global constants propagated. */ 141*e4b17023SJohn Marino static int global_const_prop_count; 142*e4b17023SJohn Marino /* Number of global copies propagated. */ 143*e4b17023SJohn Marino static int global_copy_prop_count; 144*e4b17023SJohn Marino 145*e4b17023SJohn Marino #define GOBNEW(T) ((T *) cprop_alloc (sizeof (T))) 146*e4b17023SJohn Marino #define GOBNEWVAR(T, S) ((T *) cprop_alloc ((S))) 147*e4b17023SJohn Marino 148*e4b17023SJohn Marino /* Cover function to obstack_alloc. */ 149*e4b17023SJohn Marino 150*e4b17023SJohn Marino static void * 151*e4b17023SJohn Marino cprop_alloc (unsigned long size) 152*e4b17023SJohn Marino { 153*e4b17023SJohn Marino bytes_used += size; 154*e4b17023SJohn Marino return obstack_alloc (&cprop_obstack, size); 155*e4b17023SJohn Marino } 156*e4b17023SJohn Marino 157*e4b17023SJohn Marino /* Return nonzero if register X is unchanged from INSN to the end 158*e4b17023SJohn Marino of INSN's basic block. */ 159*e4b17023SJohn Marino 160*e4b17023SJohn Marino static int 161*e4b17023SJohn Marino reg_available_p (const_rtx x, const_rtx insn ATTRIBUTE_UNUSED) 162*e4b17023SJohn Marino { 163*e4b17023SJohn Marino return ! REGNO_REG_SET_P (reg_set_bitmap, REGNO (x)); 164*e4b17023SJohn Marino } 165*e4b17023SJohn Marino 166*e4b17023SJohn Marino /* Hash a set of register REGNO. 167*e4b17023SJohn Marino 168*e4b17023SJohn Marino Sets are hashed on the register that is set. This simplifies the PRE copy 169*e4b17023SJohn Marino propagation code. 170*e4b17023SJohn Marino 171*e4b17023SJohn Marino ??? May need to make things more elaborate. Later, as necessary. */ 172*e4b17023SJohn Marino 173*e4b17023SJohn Marino static unsigned int 174*e4b17023SJohn Marino hash_set (int regno, int hash_table_size) 175*e4b17023SJohn Marino { 176*e4b17023SJohn Marino unsigned int hash; 177*e4b17023SJohn Marino 178*e4b17023SJohn Marino hash = regno; 179*e4b17023SJohn Marino return hash % hash_table_size; 180*e4b17023SJohn Marino } 181*e4b17023SJohn Marino 182*e4b17023SJohn Marino /* Insert assignment DEST:=SET from INSN in the hash table. 183*e4b17023SJohn Marino DEST is a register and SET is a register or a suitable constant. 184*e4b17023SJohn Marino If the assignment is already present in the table, record it as 185*e4b17023SJohn Marino the last occurrence in INSN's basic block. 186*e4b17023SJohn Marino IMPLICIT is true if it's an implicit set, false otherwise. */ 187*e4b17023SJohn Marino 188*e4b17023SJohn Marino static void 189*e4b17023SJohn Marino insert_set_in_table (rtx dest, rtx src, rtx insn, struct hash_table_d *table, 190*e4b17023SJohn Marino bool implicit) 191*e4b17023SJohn Marino { 192*e4b17023SJohn Marino bool found = false; 193*e4b17023SJohn Marino unsigned int hash; 194*e4b17023SJohn Marino struct expr *cur_expr, *last_expr = NULL; 195*e4b17023SJohn Marino struct occr *cur_occr; 196*e4b17023SJohn Marino 197*e4b17023SJohn Marino hash = hash_set (REGNO (dest), table->size); 198*e4b17023SJohn Marino 199*e4b17023SJohn Marino for (cur_expr = table->table[hash]; cur_expr; 200*e4b17023SJohn Marino cur_expr = cur_expr->next_same_hash) 201*e4b17023SJohn Marino { 202*e4b17023SJohn Marino if (dest == cur_expr->dest 203*e4b17023SJohn Marino && src == cur_expr->src) 204*e4b17023SJohn Marino { 205*e4b17023SJohn Marino found = true; 206*e4b17023SJohn Marino break; 207*e4b17023SJohn Marino } 208*e4b17023SJohn Marino last_expr = cur_expr; 209*e4b17023SJohn Marino } 210*e4b17023SJohn Marino 211*e4b17023SJohn Marino if (! found) 212*e4b17023SJohn Marino { 213*e4b17023SJohn Marino cur_expr = GOBNEW (struct expr); 214*e4b17023SJohn Marino bytes_used += sizeof (struct expr); 215*e4b17023SJohn Marino if (table->table[hash] == NULL) 216*e4b17023SJohn Marino /* This is the first pattern that hashed to this index. */ 217*e4b17023SJohn Marino table->table[hash] = cur_expr; 218*e4b17023SJohn Marino else 219*e4b17023SJohn Marino /* Add EXPR to end of this hash chain. */ 220*e4b17023SJohn Marino last_expr->next_same_hash = cur_expr; 221*e4b17023SJohn Marino 222*e4b17023SJohn Marino /* Set the fields of the expr element. 223*e4b17023SJohn Marino We must copy X because it can be modified when copy propagation is 224*e4b17023SJohn Marino performed on its operands. */ 225*e4b17023SJohn Marino cur_expr->dest = copy_rtx (dest); 226*e4b17023SJohn Marino cur_expr->src = copy_rtx (src); 227*e4b17023SJohn Marino cur_expr->bitmap_index = table->n_elems++; 228*e4b17023SJohn Marino cur_expr->next_same_hash = NULL; 229*e4b17023SJohn Marino cur_expr->avail_occr = NULL; 230*e4b17023SJohn Marino } 231*e4b17023SJohn Marino 232*e4b17023SJohn Marino /* Now record the occurrence. */ 233*e4b17023SJohn Marino cur_occr = cur_expr->avail_occr; 234*e4b17023SJohn Marino 235*e4b17023SJohn Marino if (cur_occr 236*e4b17023SJohn Marino && BLOCK_FOR_INSN (cur_occr->insn) == BLOCK_FOR_INSN (insn)) 237*e4b17023SJohn Marino { 238*e4b17023SJohn Marino /* Found another instance of the expression in the same basic block. 239*e4b17023SJohn Marino Prefer this occurrence to the currently recorded one. We want 240*e4b17023SJohn Marino the last one in the block and the block is scanned from start 241*e4b17023SJohn Marino to end. */ 242*e4b17023SJohn Marino cur_occr->insn = insn; 243*e4b17023SJohn Marino } 244*e4b17023SJohn Marino else 245*e4b17023SJohn Marino { 246*e4b17023SJohn Marino /* First occurrence of this expression in this basic block. */ 247*e4b17023SJohn Marino cur_occr = GOBNEW (struct occr); 248*e4b17023SJohn Marino bytes_used += sizeof (struct occr); 249*e4b17023SJohn Marino cur_occr->insn = insn; 250*e4b17023SJohn Marino cur_occr->next = cur_expr->avail_occr; 251*e4b17023SJohn Marino cur_expr->avail_occr = cur_occr; 252*e4b17023SJohn Marino } 253*e4b17023SJohn Marino 254*e4b17023SJohn Marino /* Record bitmap_index of the implicit set in implicit_set_indexes. */ 255*e4b17023SJohn Marino if (implicit) 256*e4b17023SJohn Marino implicit_set_indexes[BLOCK_FOR_INSN(insn)->index] = cur_expr->bitmap_index; 257*e4b17023SJohn Marino } 258*e4b17023SJohn Marino 259*e4b17023SJohn Marino /* Determine whether the rtx X should be treated as a constant for CPROP. 260*e4b17023SJohn Marino Since X might be inserted more than once we have to take care that it 261*e4b17023SJohn Marino is sharable. */ 262*e4b17023SJohn Marino 263*e4b17023SJohn Marino static bool 264*e4b17023SJohn Marino cprop_constant_p (const_rtx x) 265*e4b17023SJohn Marino { 266*e4b17023SJohn Marino return CONSTANT_P (x) && (GET_CODE (x) != CONST || shared_const_p (x)); 267*e4b17023SJohn Marino } 268*e4b17023SJohn Marino 269*e4b17023SJohn Marino /* Scan SET present in INSN and add an entry to the hash TABLE. 270*e4b17023SJohn Marino IMPLICIT is true if it's an implicit set, false otherwise. */ 271*e4b17023SJohn Marino 272*e4b17023SJohn Marino static void 273*e4b17023SJohn Marino hash_scan_set (rtx set, rtx insn, struct hash_table_d *table, bool implicit) 274*e4b17023SJohn Marino { 275*e4b17023SJohn Marino rtx src = SET_SRC (set); 276*e4b17023SJohn Marino rtx dest = SET_DEST (set); 277*e4b17023SJohn Marino 278*e4b17023SJohn Marino if (REG_P (dest) 279*e4b17023SJohn Marino && ! HARD_REGISTER_P (dest) 280*e4b17023SJohn Marino && reg_available_p (dest, insn) 281*e4b17023SJohn Marino && can_copy_p (GET_MODE (dest))) 282*e4b17023SJohn Marino { 283*e4b17023SJohn Marino /* See if a REG_EQUAL note shows this equivalent to a simpler expression. 284*e4b17023SJohn Marino 285*e4b17023SJohn Marino This allows us to do a single CPROP pass and still eliminate 286*e4b17023SJohn Marino redundant constants, addresses or other expressions that are 287*e4b17023SJohn Marino constructed with multiple instructions. 288*e4b17023SJohn Marino 289*e4b17023SJohn Marino However, keep the original SRC if INSN is a simple reg-reg move. In 290*e4b17023SJohn Marino In this case, there will almost always be a REG_EQUAL note on the 291*e4b17023SJohn Marino insn that sets SRC. By recording the REG_EQUAL value here as SRC 292*e4b17023SJohn Marino for INSN, we miss copy propagation opportunities. 293*e4b17023SJohn Marino 294*e4b17023SJohn Marino Note that this does not impede profitable constant propagations. We 295*e4b17023SJohn Marino "look through" reg-reg sets in lookup_set. */ 296*e4b17023SJohn Marino rtx note = find_reg_equal_equiv_note (insn); 297*e4b17023SJohn Marino if (note != 0 298*e4b17023SJohn Marino && REG_NOTE_KIND (note) == REG_EQUAL 299*e4b17023SJohn Marino && !REG_P (src) 300*e4b17023SJohn Marino && cprop_constant_p (XEXP (note, 0))) 301*e4b17023SJohn Marino src = XEXP (note, 0), set = gen_rtx_SET (VOIDmode, dest, src); 302*e4b17023SJohn Marino 303*e4b17023SJohn Marino /* Record sets for constant/copy propagation. */ 304*e4b17023SJohn Marino if ((REG_P (src) 305*e4b17023SJohn Marino && src != dest 306*e4b17023SJohn Marino && ! HARD_REGISTER_P (src) 307*e4b17023SJohn Marino && reg_available_p (src, insn)) 308*e4b17023SJohn Marino || cprop_constant_p (src)) 309*e4b17023SJohn Marino insert_set_in_table (dest, src, insn, table, implicit); 310*e4b17023SJohn Marino } 311*e4b17023SJohn Marino } 312*e4b17023SJohn Marino 313*e4b17023SJohn Marino /* Process INSN and add hash table entries as appropriate. */ 314*e4b17023SJohn Marino 315*e4b17023SJohn Marino static void 316*e4b17023SJohn Marino hash_scan_insn (rtx insn, struct hash_table_d *table) 317*e4b17023SJohn Marino { 318*e4b17023SJohn Marino rtx pat = PATTERN (insn); 319*e4b17023SJohn Marino int i; 320*e4b17023SJohn Marino 321*e4b17023SJohn Marino /* Pick out the sets of INSN and for other forms of instructions record 322*e4b17023SJohn Marino what's been modified. */ 323*e4b17023SJohn Marino 324*e4b17023SJohn Marino if (GET_CODE (pat) == SET) 325*e4b17023SJohn Marino hash_scan_set (pat, insn, table, false); 326*e4b17023SJohn Marino else if (GET_CODE (pat) == PARALLEL) 327*e4b17023SJohn Marino for (i = 0; i < XVECLEN (pat, 0); i++) 328*e4b17023SJohn Marino { 329*e4b17023SJohn Marino rtx x = XVECEXP (pat, 0, i); 330*e4b17023SJohn Marino 331*e4b17023SJohn Marino if (GET_CODE (x) == SET) 332*e4b17023SJohn Marino hash_scan_set (x, insn, table, false); 333*e4b17023SJohn Marino } 334*e4b17023SJohn Marino } 335*e4b17023SJohn Marino 336*e4b17023SJohn Marino /* Dump the hash table TABLE to file FILE under the name NAME. */ 337*e4b17023SJohn Marino 338*e4b17023SJohn Marino static void 339*e4b17023SJohn Marino dump_hash_table (FILE *file, const char *name, struct hash_table_d *table) 340*e4b17023SJohn Marino { 341*e4b17023SJohn Marino int i; 342*e4b17023SJohn Marino /* Flattened out table, so it's printed in proper order. */ 343*e4b17023SJohn Marino struct expr **flat_table; 344*e4b17023SJohn Marino unsigned int *hash_val; 345*e4b17023SJohn Marino struct expr *expr; 346*e4b17023SJohn Marino 347*e4b17023SJohn Marino flat_table = XCNEWVEC (struct expr *, table->n_elems); 348*e4b17023SJohn Marino hash_val = XNEWVEC (unsigned int, table->n_elems); 349*e4b17023SJohn Marino 350*e4b17023SJohn Marino for (i = 0; i < (int) table->size; i++) 351*e4b17023SJohn Marino for (expr = table->table[i]; expr != NULL; expr = expr->next_same_hash) 352*e4b17023SJohn Marino { 353*e4b17023SJohn Marino flat_table[expr->bitmap_index] = expr; 354*e4b17023SJohn Marino hash_val[expr->bitmap_index] = i; 355*e4b17023SJohn Marino } 356*e4b17023SJohn Marino 357*e4b17023SJohn Marino fprintf (file, "%s hash table (%d buckets, %d entries)\n", 358*e4b17023SJohn Marino name, table->size, table->n_elems); 359*e4b17023SJohn Marino 360*e4b17023SJohn Marino for (i = 0; i < (int) table->n_elems; i++) 361*e4b17023SJohn Marino if (flat_table[i] != 0) 362*e4b17023SJohn Marino { 363*e4b17023SJohn Marino expr = flat_table[i]; 364*e4b17023SJohn Marino fprintf (file, "Index %d (hash value %d)\n ", 365*e4b17023SJohn Marino expr->bitmap_index, hash_val[i]); 366*e4b17023SJohn Marino print_rtl (file, expr->dest); 367*e4b17023SJohn Marino fprintf (file, " := "); 368*e4b17023SJohn Marino print_rtl (file, expr->src); 369*e4b17023SJohn Marino fprintf (file, "\n"); 370*e4b17023SJohn Marino } 371*e4b17023SJohn Marino 372*e4b17023SJohn Marino fprintf (file, "\n"); 373*e4b17023SJohn Marino 374*e4b17023SJohn Marino free (flat_table); 375*e4b17023SJohn Marino free (hash_val); 376*e4b17023SJohn Marino } 377*e4b17023SJohn Marino 378*e4b17023SJohn Marino /* Record as unavailable all registers that are DEF operands of INSN. */ 379*e4b17023SJohn Marino 380*e4b17023SJohn Marino static void 381*e4b17023SJohn Marino make_set_regs_unavailable (rtx insn) 382*e4b17023SJohn Marino { 383*e4b17023SJohn Marino struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); 384*e4b17023SJohn Marino df_ref *def_rec; 385*e4b17023SJohn Marino 386*e4b17023SJohn Marino for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++) 387*e4b17023SJohn Marino SET_REGNO_REG_SET (reg_set_bitmap, DF_REF_REGNO (*def_rec)); 388*e4b17023SJohn Marino } 389*e4b17023SJohn Marino 390*e4b17023SJohn Marino /* Top level function to create an assignment hash table. 391*e4b17023SJohn Marino 392*e4b17023SJohn Marino Assignment entries are placed in the hash table if 393*e4b17023SJohn Marino - they are of the form (set (pseudo-reg) src), 394*e4b17023SJohn Marino - src is something we want to perform const/copy propagation on, 395*e4b17023SJohn Marino - none of the operands or target are subsequently modified in the block 396*e4b17023SJohn Marino 397*e4b17023SJohn Marino Currently src must be a pseudo-reg or a const_int. 398*e4b17023SJohn Marino 399*e4b17023SJohn Marino TABLE is the table computed. */ 400*e4b17023SJohn Marino 401*e4b17023SJohn Marino static void 402*e4b17023SJohn Marino compute_hash_table_work (struct hash_table_d *table) 403*e4b17023SJohn Marino { 404*e4b17023SJohn Marino basic_block bb; 405*e4b17023SJohn Marino 406*e4b17023SJohn Marino /* Allocate vars to track sets of regs. */ 407*e4b17023SJohn Marino reg_set_bitmap = ALLOC_REG_SET (NULL); 408*e4b17023SJohn Marino 409*e4b17023SJohn Marino FOR_EACH_BB (bb) 410*e4b17023SJohn Marino { 411*e4b17023SJohn Marino rtx insn; 412*e4b17023SJohn Marino 413*e4b17023SJohn Marino /* Reset tables used to keep track of what's not yet invalid [since 414*e4b17023SJohn Marino the end of the block]. */ 415*e4b17023SJohn Marino CLEAR_REG_SET (reg_set_bitmap); 416*e4b17023SJohn Marino 417*e4b17023SJohn Marino /* Go over all insns from the last to the first. This is convenient 418*e4b17023SJohn Marino for tracking available registers, i.e. not set between INSN and 419*e4b17023SJohn Marino the end of the basic block BB. */ 420*e4b17023SJohn Marino FOR_BB_INSNS_REVERSE (bb, insn) 421*e4b17023SJohn Marino { 422*e4b17023SJohn Marino /* Only real insns are interesting. */ 423*e4b17023SJohn Marino if (!NONDEBUG_INSN_P (insn)) 424*e4b17023SJohn Marino continue; 425*e4b17023SJohn Marino 426*e4b17023SJohn Marino /* Record interesting sets from INSN in the hash table. */ 427*e4b17023SJohn Marino hash_scan_insn (insn, table); 428*e4b17023SJohn Marino 429*e4b17023SJohn Marino /* Any registers set in INSN will make SETs above it not AVAIL. */ 430*e4b17023SJohn Marino make_set_regs_unavailable (insn); 431*e4b17023SJohn Marino } 432*e4b17023SJohn Marino 433*e4b17023SJohn Marino /* Insert implicit sets in the hash table, pretending they appear as 434*e4b17023SJohn Marino insns at the head of the basic block. */ 435*e4b17023SJohn Marino if (implicit_sets[bb->index] != NULL_RTX) 436*e4b17023SJohn Marino hash_scan_set (implicit_sets[bb->index], BB_HEAD (bb), table, true); 437*e4b17023SJohn Marino } 438*e4b17023SJohn Marino 439*e4b17023SJohn Marino FREE_REG_SET (reg_set_bitmap); 440*e4b17023SJohn Marino } 441*e4b17023SJohn Marino 442*e4b17023SJohn Marino /* Allocate space for the set/expr hash TABLE. 443*e4b17023SJohn Marino It is used to determine the number of buckets to use. */ 444*e4b17023SJohn Marino 445*e4b17023SJohn Marino static void 446*e4b17023SJohn Marino alloc_hash_table (struct hash_table_d *table) 447*e4b17023SJohn Marino { 448*e4b17023SJohn Marino int n; 449*e4b17023SJohn Marino 450*e4b17023SJohn Marino n = get_max_insn_count (); 451*e4b17023SJohn Marino 452*e4b17023SJohn Marino table->size = n / 4; 453*e4b17023SJohn Marino if (table->size < 11) 454*e4b17023SJohn Marino table->size = 11; 455*e4b17023SJohn Marino 456*e4b17023SJohn Marino /* Attempt to maintain efficient use of hash table. 457*e4b17023SJohn Marino Making it an odd number is simplest for now. 458*e4b17023SJohn Marino ??? Later take some measurements. */ 459*e4b17023SJohn Marino table->size |= 1; 460*e4b17023SJohn Marino n = table->size * sizeof (struct expr *); 461*e4b17023SJohn Marino table->table = XNEWVAR (struct expr *, n); 462*e4b17023SJohn Marino } 463*e4b17023SJohn Marino 464*e4b17023SJohn Marino /* Free things allocated by alloc_hash_table. */ 465*e4b17023SJohn Marino 466*e4b17023SJohn Marino static void 467*e4b17023SJohn Marino free_hash_table (struct hash_table_d *table) 468*e4b17023SJohn Marino { 469*e4b17023SJohn Marino free (table->table); 470*e4b17023SJohn Marino } 471*e4b17023SJohn Marino 472*e4b17023SJohn Marino /* Compute the hash TABLE for doing copy/const propagation or 473*e4b17023SJohn Marino expression hash table. */ 474*e4b17023SJohn Marino 475*e4b17023SJohn Marino static void 476*e4b17023SJohn Marino compute_hash_table (struct hash_table_d *table) 477*e4b17023SJohn Marino { 478*e4b17023SJohn Marino /* Initialize count of number of entries in hash table. */ 479*e4b17023SJohn Marino table->n_elems = 0; 480*e4b17023SJohn Marino memset (table->table, 0, table->size * sizeof (struct expr *)); 481*e4b17023SJohn Marino 482*e4b17023SJohn Marino compute_hash_table_work (table); 483*e4b17023SJohn Marino } 484*e4b17023SJohn Marino 485*e4b17023SJohn Marino /* Expression tracking support. */ 486*e4b17023SJohn Marino 487*e4b17023SJohn Marino /* Lookup REGNO in the set TABLE. The result is a pointer to the 488*e4b17023SJohn Marino table entry, or NULL if not found. */ 489*e4b17023SJohn Marino 490*e4b17023SJohn Marino static struct expr * 491*e4b17023SJohn Marino lookup_set (unsigned int regno, struct hash_table_d *table) 492*e4b17023SJohn Marino { 493*e4b17023SJohn Marino unsigned int hash = hash_set (regno, table->size); 494*e4b17023SJohn Marino struct expr *expr; 495*e4b17023SJohn Marino 496*e4b17023SJohn Marino expr = table->table[hash]; 497*e4b17023SJohn Marino 498*e4b17023SJohn Marino while (expr && REGNO (expr->dest) != regno) 499*e4b17023SJohn Marino expr = expr->next_same_hash; 500*e4b17023SJohn Marino 501*e4b17023SJohn Marino return expr; 502*e4b17023SJohn Marino } 503*e4b17023SJohn Marino 504*e4b17023SJohn Marino /* Return the next entry for REGNO in list EXPR. */ 505*e4b17023SJohn Marino 506*e4b17023SJohn Marino static struct expr * 507*e4b17023SJohn Marino next_set (unsigned int regno, struct expr *expr) 508*e4b17023SJohn Marino { 509*e4b17023SJohn Marino do 510*e4b17023SJohn Marino expr = expr->next_same_hash; 511*e4b17023SJohn Marino while (expr && REGNO (expr->dest) != regno); 512*e4b17023SJohn Marino 513*e4b17023SJohn Marino return expr; 514*e4b17023SJohn Marino } 515*e4b17023SJohn Marino 516*e4b17023SJohn Marino /* Reset tables used to keep track of what's still available [since the 517*e4b17023SJohn Marino start of the block]. */ 518*e4b17023SJohn Marino 519*e4b17023SJohn Marino static void 520*e4b17023SJohn Marino reset_opr_set_tables (void) 521*e4b17023SJohn Marino { 522*e4b17023SJohn Marino /* Maintain a bitmap of which regs have been set since beginning of 523*e4b17023SJohn Marino the block. */ 524*e4b17023SJohn Marino CLEAR_REG_SET (reg_set_bitmap); 525*e4b17023SJohn Marino } 526*e4b17023SJohn Marino 527*e4b17023SJohn Marino /* Return nonzero if the register X has not been set yet [since the 528*e4b17023SJohn Marino start of the basic block containing INSN]. */ 529*e4b17023SJohn Marino 530*e4b17023SJohn Marino static int 531*e4b17023SJohn Marino reg_not_set_p (const_rtx x, const_rtx insn ATTRIBUTE_UNUSED) 532*e4b17023SJohn Marino { 533*e4b17023SJohn Marino return ! REGNO_REG_SET_P (reg_set_bitmap, REGNO (x)); 534*e4b17023SJohn Marino } 535*e4b17023SJohn Marino 536*e4b17023SJohn Marino /* Record things set by INSN. 537*e4b17023SJohn Marino This data is used by reg_not_set_p. */ 538*e4b17023SJohn Marino 539*e4b17023SJohn Marino static void 540*e4b17023SJohn Marino mark_oprs_set (rtx insn) 541*e4b17023SJohn Marino { 542*e4b17023SJohn Marino struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); 543*e4b17023SJohn Marino df_ref *def_rec; 544*e4b17023SJohn Marino 545*e4b17023SJohn Marino for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++) 546*e4b17023SJohn Marino SET_REGNO_REG_SET (reg_set_bitmap, DF_REF_REGNO (*def_rec)); 547*e4b17023SJohn Marino } 548*e4b17023SJohn Marino 549*e4b17023SJohn Marino /* Compute copy/constant propagation working variables. */ 550*e4b17023SJohn Marino 551*e4b17023SJohn Marino /* Local properties of assignments. */ 552*e4b17023SJohn Marino static sbitmap *cprop_avloc; 553*e4b17023SJohn Marino static sbitmap *cprop_kill; 554*e4b17023SJohn Marino 555*e4b17023SJohn Marino /* Global properties of assignments (computed from the local properties). */ 556*e4b17023SJohn Marino static sbitmap *cprop_avin; 557*e4b17023SJohn Marino static sbitmap *cprop_avout; 558*e4b17023SJohn Marino 559*e4b17023SJohn Marino /* Allocate vars used for copy/const propagation. N_BLOCKS is the number of 560*e4b17023SJohn Marino basic blocks. N_SETS is the number of sets. */ 561*e4b17023SJohn Marino 562*e4b17023SJohn Marino static void 563*e4b17023SJohn Marino alloc_cprop_mem (int n_blocks, int n_sets) 564*e4b17023SJohn Marino { 565*e4b17023SJohn Marino cprop_avloc = sbitmap_vector_alloc (n_blocks, n_sets); 566*e4b17023SJohn Marino cprop_kill = sbitmap_vector_alloc (n_blocks, n_sets); 567*e4b17023SJohn Marino 568*e4b17023SJohn Marino cprop_avin = sbitmap_vector_alloc (n_blocks, n_sets); 569*e4b17023SJohn Marino cprop_avout = sbitmap_vector_alloc (n_blocks, n_sets); 570*e4b17023SJohn Marino } 571*e4b17023SJohn Marino 572*e4b17023SJohn Marino /* Free vars used by copy/const propagation. */ 573*e4b17023SJohn Marino 574*e4b17023SJohn Marino static void 575*e4b17023SJohn Marino free_cprop_mem (void) 576*e4b17023SJohn Marino { 577*e4b17023SJohn Marino sbitmap_vector_free (cprop_avloc); 578*e4b17023SJohn Marino sbitmap_vector_free (cprop_kill); 579*e4b17023SJohn Marino sbitmap_vector_free (cprop_avin); 580*e4b17023SJohn Marino sbitmap_vector_free (cprop_avout); 581*e4b17023SJohn Marino } 582*e4b17023SJohn Marino 583*e4b17023SJohn Marino /* Compute the local properties of each recorded expression. 584*e4b17023SJohn Marino 585*e4b17023SJohn Marino Local properties are those that are defined by the block, irrespective of 586*e4b17023SJohn Marino other blocks. 587*e4b17023SJohn Marino 588*e4b17023SJohn Marino An expression is killed in a block if its operands, either DEST or SRC, are 589*e4b17023SJohn Marino modified in the block. 590*e4b17023SJohn Marino 591*e4b17023SJohn Marino An expression is computed (locally available) in a block if it is computed 592*e4b17023SJohn Marino at least once and expression would contain the same value if the 593*e4b17023SJohn Marino computation was moved to the end of the block. 594*e4b17023SJohn Marino 595*e4b17023SJohn Marino KILL and COMP are destination sbitmaps for recording local properties. */ 596*e4b17023SJohn Marino 597*e4b17023SJohn Marino static void 598*e4b17023SJohn Marino compute_local_properties (sbitmap *kill, sbitmap *comp, 599*e4b17023SJohn Marino struct hash_table_d *table) 600*e4b17023SJohn Marino { 601*e4b17023SJohn Marino unsigned int i; 602*e4b17023SJohn Marino 603*e4b17023SJohn Marino /* Initialize the bitmaps that were passed in. */ 604*e4b17023SJohn Marino sbitmap_vector_zero (kill, last_basic_block); 605*e4b17023SJohn Marino sbitmap_vector_zero (comp, last_basic_block); 606*e4b17023SJohn Marino 607*e4b17023SJohn Marino for (i = 0; i < table->size; i++) 608*e4b17023SJohn Marino { 609*e4b17023SJohn Marino struct expr *expr; 610*e4b17023SJohn Marino 611*e4b17023SJohn Marino for (expr = table->table[i]; expr != NULL; expr = expr->next_same_hash) 612*e4b17023SJohn Marino { 613*e4b17023SJohn Marino int indx = expr->bitmap_index; 614*e4b17023SJohn Marino df_ref def; 615*e4b17023SJohn Marino struct occr *occr; 616*e4b17023SJohn Marino 617*e4b17023SJohn Marino /* For each definition of the destination pseudo-reg, the expression 618*e4b17023SJohn Marino is killed in the block where the definition is. */ 619*e4b17023SJohn Marino for (def = DF_REG_DEF_CHAIN (REGNO (expr->dest)); 620*e4b17023SJohn Marino def; def = DF_REF_NEXT_REG (def)) 621*e4b17023SJohn Marino SET_BIT (kill[DF_REF_BB (def)->index], indx); 622*e4b17023SJohn Marino 623*e4b17023SJohn Marino /* If the source is a pseudo-reg, for each definition of the source, 624*e4b17023SJohn Marino the expression is killed in the block where the definition is. */ 625*e4b17023SJohn Marino if (REG_P (expr->src)) 626*e4b17023SJohn Marino for (def = DF_REG_DEF_CHAIN (REGNO (expr->src)); 627*e4b17023SJohn Marino def; def = DF_REF_NEXT_REG (def)) 628*e4b17023SJohn Marino SET_BIT (kill[DF_REF_BB (def)->index], indx); 629*e4b17023SJohn Marino 630*e4b17023SJohn Marino /* The occurrences recorded in avail_occr are exactly those that 631*e4b17023SJohn Marino are locally available in the block where they are. */ 632*e4b17023SJohn Marino for (occr = expr->avail_occr; occr != NULL; occr = occr->next) 633*e4b17023SJohn Marino { 634*e4b17023SJohn Marino SET_BIT (comp[BLOCK_FOR_INSN (occr->insn)->index], indx); 635*e4b17023SJohn Marino } 636*e4b17023SJohn Marino } 637*e4b17023SJohn Marino } 638*e4b17023SJohn Marino } 639*e4b17023SJohn Marino 640*e4b17023SJohn Marino /* Hash table support. */ 641*e4b17023SJohn Marino 642*e4b17023SJohn Marino /* Top level routine to do the dataflow analysis needed by copy/const 643*e4b17023SJohn Marino propagation. */ 644*e4b17023SJohn Marino 645*e4b17023SJohn Marino static void 646*e4b17023SJohn Marino compute_cprop_data (void) 647*e4b17023SJohn Marino { 648*e4b17023SJohn Marino basic_block bb; 649*e4b17023SJohn Marino 650*e4b17023SJohn Marino compute_local_properties (cprop_kill, cprop_avloc, &set_hash_table); 651*e4b17023SJohn Marino compute_available (cprop_avloc, cprop_kill, cprop_avout, cprop_avin); 652*e4b17023SJohn Marino 653*e4b17023SJohn Marino /* Merge implicit sets into CPROP_AVIN. They are always available at the 654*e4b17023SJohn Marino entry of their basic block. We need to do this because 1) implicit sets 655*e4b17023SJohn Marino aren't recorded for the local pass so they cannot be propagated within 656*e4b17023SJohn Marino their basic block by this pass and 2) the global pass would otherwise 657*e4b17023SJohn Marino propagate them only in the successors of their basic block. */ 658*e4b17023SJohn Marino FOR_EACH_BB (bb) 659*e4b17023SJohn Marino { 660*e4b17023SJohn Marino int index = implicit_set_indexes[bb->index]; 661*e4b17023SJohn Marino if (index != -1) 662*e4b17023SJohn Marino SET_BIT (cprop_avin[bb->index], index); 663*e4b17023SJohn Marino } 664*e4b17023SJohn Marino } 665*e4b17023SJohn Marino 666*e4b17023SJohn Marino /* Copy/constant propagation. */ 667*e4b17023SJohn Marino 668*e4b17023SJohn Marino /* Maximum number of register uses in an insn that we handle. */ 669*e4b17023SJohn Marino #define MAX_USES 8 670*e4b17023SJohn Marino 671*e4b17023SJohn Marino /* Table of uses (registers, both hard and pseudo) found in an insn. 672*e4b17023SJohn Marino Allocated statically to avoid alloc/free complexity and overhead. */ 673*e4b17023SJohn Marino static rtx reg_use_table[MAX_USES]; 674*e4b17023SJohn Marino 675*e4b17023SJohn Marino /* Index into `reg_use_table' while building it. */ 676*e4b17023SJohn Marino static unsigned reg_use_count; 677*e4b17023SJohn Marino 678*e4b17023SJohn Marino /* Set up a list of register numbers used in INSN. The found uses are stored 679*e4b17023SJohn Marino in `reg_use_table'. `reg_use_count' is initialized to zero before entry, 680*e4b17023SJohn Marino and contains the number of uses in the table upon exit. 681*e4b17023SJohn Marino 682*e4b17023SJohn Marino ??? If a register appears multiple times we will record it multiple times. 683*e4b17023SJohn Marino This doesn't hurt anything but it will slow things down. */ 684*e4b17023SJohn Marino 685*e4b17023SJohn Marino static void 686*e4b17023SJohn Marino find_used_regs (rtx *xptr, void *data ATTRIBUTE_UNUSED) 687*e4b17023SJohn Marino { 688*e4b17023SJohn Marino int i, j; 689*e4b17023SJohn Marino enum rtx_code code; 690*e4b17023SJohn Marino const char *fmt; 691*e4b17023SJohn Marino rtx x = *xptr; 692*e4b17023SJohn Marino 693*e4b17023SJohn Marino /* repeat is used to turn tail-recursion into iteration since GCC 694*e4b17023SJohn Marino can't do it when there's no return value. */ 695*e4b17023SJohn Marino repeat: 696*e4b17023SJohn Marino if (x == 0) 697*e4b17023SJohn Marino return; 698*e4b17023SJohn Marino 699*e4b17023SJohn Marino code = GET_CODE (x); 700*e4b17023SJohn Marino if (REG_P (x)) 701*e4b17023SJohn Marino { 702*e4b17023SJohn Marino if (reg_use_count == MAX_USES) 703*e4b17023SJohn Marino return; 704*e4b17023SJohn Marino 705*e4b17023SJohn Marino reg_use_table[reg_use_count] = x; 706*e4b17023SJohn Marino reg_use_count++; 707*e4b17023SJohn Marino } 708*e4b17023SJohn Marino 709*e4b17023SJohn Marino /* Recursively scan the operands of this expression. */ 710*e4b17023SJohn Marino 711*e4b17023SJohn Marino for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--) 712*e4b17023SJohn Marino { 713*e4b17023SJohn Marino if (fmt[i] == 'e') 714*e4b17023SJohn Marino { 715*e4b17023SJohn Marino /* If we are about to do the last recursive call 716*e4b17023SJohn Marino needed at this level, change it into iteration. 717*e4b17023SJohn Marino This function is called enough to be worth it. */ 718*e4b17023SJohn Marino if (i == 0) 719*e4b17023SJohn Marino { 720*e4b17023SJohn Marino x = XEXP (x, 0); 721*e4b17023SJohn Marino goto repeat; 722*e4b17023SJohn Marino } 723*e4b17023SJohn Marino 724*e4b17023SJohn Marino find_used_regs (&XEXP (x, i), data); 725*e4b17023SJohn Marino } 726*e4b17023SJohn Marino else if (fmt[i] == 'E') 727*e4b17023SJohn Marino for (j = 0; j < XVECLEN (x, i); j++) 728*e4b17023SJohn Marino find_used_regs (&XVECEXP (x, i, j), data); 729*e4b17023SJohn Marino } 730*e4b17023SJohn Marino } 731*e4b17023SJohn Marino 732*e4b17023SJohn Marino /* Try to replace all uses of FROM in INSN with TO. 733*e4b17023SJohn Marino Return nonzero if successful. */ 734*e4b17023SJohn Marino 735*e4b17023SJohn Marino static int 736*e4b17023SJohn Marino try_replace_reg (rtx from, rtx to, rtx insn) 737*e4b17023SJohn Marino { 738*e4b17023SJohn Marino rtx note = find_reg_equal_equiv_note (insn); 739*e4b17023SJohn Marino rtx src = 0; 740*e4b17023SJohn Marino int success = 0; 741*e4b17023SJohn Marino rtx set = single_set (insn); 742*e4b17023SJohn Marino 743*e4b17023SJohn Marino /* Usually we substitute easy stuff, so we won't copy everything. 744*e4b17023SJohn Marino We however need to take care to not duplicate non-trivial CONST 745*e4b17023SJohn Marino expressions. */ 746*e4b17023SJohn Marino to = copy_rtx (to); 747*e4b17023SJohn Marino 748*e4b17023SJohn Marino validate_replace_src_group (from, to, insn); 749*e4b17023SJohn Marino if (num_changes_pending () && apply_change_group ()) 750*e4b17023SJohn Marino success = 1; 751*e4b17023SJohn Marino 752*e4b17023SJohn Marino /* Try to simplify SET_SRC if we have substituted a constant. */ 753*e4b17023SJohn Marino if (success && set && CONSTANT_P (to)) 754*e4b17023SJohn Marino { 755*e4b17023SJohn Marino src = simplify_rtx (SET_SRC (set)); 756*e4b17023SJohn Marino 757*e4b17023SJohn Marino if (src) 758*e4b17023SJohn Marino validate_change (insn, &SET_SRC (set), src, 0); 759*e4b17023SJohn Marino } 760*e4b17023SJohn Marino 761*e4b17023SJohn Marino /* If there is already a REG_EQUAL note, update the expression in it 762*e4b17023SJohn Marino with our replacement. */ 763*e4b17023SJohn Marino if (note != 0 && REG_NOTE_KIND (note) == REG_EQUAL) 764*e4b17023SJohn Marino set_unique_reg_note (insn, REG_EQUAL, 765*e4b17023SJohn Marino simplify_replace_rtx (XEXP (note, 0), from, to)); 766*e4b17023SJohn Marino if (!success && set && reg_mentioned_p (from, SET_SRC (set))) 767*e4b17023SJohn Marino { 768*e4b17023SJohn Marino /* If above failed and this is a single set, try to simplify the source 769*e4b17023SJohn Marino of the set given our substitution. We could perhaps try this for 770*e4b17023SJohn Marino multiple SETs, but it probably won't buy us anything. */ 771*e4b17023SJohn Marino src = simplify_replace_rtx (SET_SRC (set), from, to); 772*e4b17023SJohn Marino 773*e4b17023SJohn Marino if (!rtx_equal_p (src, SET_SRC (set)) 774*e4b17023SJohn Marino && validate_change (insn, &SET_SRC (set), src, 0)) 775*e4b17023SJohn Marino success = 1; 776*e4b17023SJohn Marino 777*e4b17023SJohn Marino /* If we've failed perform the replacement, have a single SET to 778*e4b17023SJohn Marino a REG destination and don't yet have a note, add a REG_EQUAL note 779*e4b17023SJohn Marino to not lose information. */ 780*e4b17023SJohn Marino if (!success && note == 0 && set != 0 && REG_P (SET_DEST (set))) 781*e4b17023SJohn Marino note = set_unique_reg_note (insn, REG_EQUAL, copy_rtx (src)); 782*e4b17023SJohn Marino } 783*e4b17023SJohn Marino 784*e4b17023SJohn Marino if (set && MEM_P (SET_DEST (set)) && reg_mentioned_p (from, SET_DEST (set))) 785*e4b17023SJohn Marino { 786*e4b17023SJohn Marino /* Registers can also appear as uses in SET_DEST if it is a MEM. 787*e4b17023SJohn Marino We could perhaps try this for multiple SETs, but it probably 788*e4b17023SJohn Marino won't buy us anything. */ 789*e4b17023SJohn Marino rtx dest = simplify_replace_rtx (SET_DEST (set), from, to); 790*e4b17023SJohn Marino 791*e4b17023SJohn Marino if (!rtx_equal_p (dest, SET_DEST (set)) 792*e4b17023SJohn Marino && validate_change (insn, &SET_DEST (set), dest, 0)) 793*e4b17023SJohn Marino success = 1; 794*e4b17023SJohn Marino } 795*e4b17023SJohn Marino 796*e4b17023SJohn Marino /* REG_EQUAL may get simplified into register. 797*e4b17023SJohn Marino We don't allow that. Remove that note. This code ought 798*e4b17023SJohn Marino not to happen, because previous code ought to synthesize 799*e4b17023SJohn Marino reg-reg move, but be on the safe side. */ 800*e4b17023SJohn Marino if (note && REG_NOTE_KIND (note) == REG_EQUAL && REG_P (XEXP (note, 0))) 801*e4b17023SJohn Marino remove_note (insn, note); 802*e4b17023SJohn Marino 803*e4b17023SJohn Marino return success; 804*e4b17023SJohn Marino } 805*e4b17023SJohn Marino 806*e4b17023SJohn Marino /* Find a set of REGNOs that are available on entry to INSN's block. Return 807*e4b17023SJohn Marino NULL no such set is found. */ 808*e4b17023SJohn Marino 809*e4b17023SJohn Marino static struct expr * 810*e4b17023SJohn Marino find_avail_set (int regno, rtx insn) 811*e4b17023SJohn Marino { 812*e4b17023SJohn Marino /* SET1 contains the last set found that can be returned to the caller for 813*e4b17023SJohn Marino use in a substitution. */ 814*e4b17023SJohn Marino struct expr *set1 = 0; 815*e4b17023SJohn Marino 816*e4b17023SJohn Marino /* Loops are not possible here. To get a loop we would need two sets 817*e4b17023SJohn Marino available at the start of the block containing INSN. i.e. we would 818*e4b17023SJohn Marino need two sets like this available at the start of the block: 819*e4b17023SJohn Marino 820*e4b17023SJohn Marino (set (reg X) (reg Y)) 821*e4b17023SJohn Marino (set (reg Y) (reg X)) 822*e4b17023SJohn Marino 823*e4b17023SJohn Marino This can not happen since the set of (reg Y) would have killed the 824*e4b17023SJohn Marino set of (reg X) making it unavailable at the start of this block. */ 825*e4b17023SJohn Marino while (1) 826*e4b17023SJohn Marino { 827*e4b17023SJohn Marino rtx src; 828*e4b17023SJohn Marino struct expr *set = lookup_set (regno, &set_hash_table); 829*e4b17023SJohn Marino 830*e4b17023SJohn Marino /* Find a set that is available at the start of the block 831*e4b17023SJohn Marino which contains INSN. */ 832*e4b17023SJohn Marino while (set) 833*e4b17023SJohn Marino { 834*e4b17023SJohn Marino if (TEST_BIT (cprop_avin[BLOCK_FOR_INSN (insn)->index], 835*e4b17023SJohn Marino set->bitmap_index)) 836*e4b17023SJohn Marino break; 837*e4b17023SJohn Marino set = next_set (regno, set); 838*e4b17023SJohn Marino } 839*e4b17023SJohn Marino 840*e4b17023SJohn Marino /* If no available set was found we've reached the end of the 841*e4b17023SJohn Marino (possibly empty) copy chain. */ 842*e4b17023SJohn Marino if (set == 0) 843*e4b17023SJohn Marino break; 844*e4b17023SJohn Marino 845*e4b17023SJohn Marino src = set->src; 846*e4b17023SJohn Marino 847*e4b17023SJohn Marino /* We know the set is available. 848*e4b17023SJohn Marino Now check that SRC is locally anticipatable (i.e. none of the 849*e4b17023SJohn Marino source operands have changed since the start of the block). 850*e4b17023SJohn Marino 851*e4b17023SJohn Marino If the source operand changed, we may still use it for the next 852*e4b17023SJohn Marino iteration of this loop, but we may not use it for substitutions. */ 853*e4b17023SJohn Marino 854*e4b17023SJohn Marino if (cprop_constant_p (src) || reg_not_set_p (src, insn)) 855*e4b17023SJohn Marino set1 = set; 856*e4b17023SJohn Marino 857*e4b17023SJohn Marino /* If the source of the set is anything except a register, then 858*e4b17023SJohn Marino we have reached the end of the copy chain. */ 859*e4b17023SJohn Marino if (! REG_P (src)) 860*e4b17023SJohn Marino break; 861*e4b17023SJohn Marino 862*e4b17023SJohn Marino /* Follow the copy chain, i.e. start another iteration of the loop 863*e4b17023SJohn Marino and see if we have an available copy into SRC. */ 864*e4b17023SJohn Marino regno = REGNO (src); 865*e4b17023SJohn Marino } 866*e4b17023SJohn Marino 867*e4b17023SJohn Marino /* SET1 holds the last set that was available and anticipatable at 868*e4b17023SJohn Marino INSN. */ 869*e4b17023SJohn Marino return set1; 870*e4b17023SJohn Marino } 871*e4b17023SJohn Marino 872*e4b17023SJohn Marino /* Subroutine of cprop_insn that tries to propagate constants into 873*e4b17023SJohn Marino JUMP_INSNS. JUMP must be a conditional jump. If SETCC is non-NULL 874*e4b17023SJohn Marino it is the instruction that immediately precedes JUMP, and must be a 875*e4b17023SJohn Marino single SET of a register. FROM is what we will try to replace, 876*e4b17023SJohn Marino SRC is the constant we will try to substitute for it. Return nonzero 877*e4b17023SJohn Marino if a change was made. */ 878*e4b17023SJohn Marino 879*e4b17023SJohn Marino static int 880*e4b17023SJohn Marino cprop_jump (basic_block bb, rtx setcc, rtx jump, rtx from, rtx src) 881*e4b17023SJohn Marino { 882*e4b17023SJohn Marino rtx new_rtx, set_src, note_src; 883*e4b17023SJohn Marino rtx set = pc_set (jump); 884*e4b17023SJohn Marino rtx note = find_reg_equal_equiv_note (jump); 885*e4b17023SJohn Marino 886*e4b17023SJohn Marino if (note) 887*e4b17023SJohn Marino { 888*e4b17023SJohn Marino note_src = XEXP (note, 0); 889*e4b17023SJohn Marino if (GET_CODE (note_src) == EXPR_LIST) 890*e4b17023SJohn Marino note_src = NULL_RTX; 891*e4b17023SJohn Marino } 892*e4b17023SJohn Marino else note_src = NULL_RTX; 893*e4b17023SJohn Marino 894*e4b17023SJohn Marino /* Prefer REG_EQUAL notes except those containing EXPR_LISTs. */ 895*e4b17023SJohn Marino set_src = note_src ? note_src : SET_SRC (set); 896*e4b17023SJohn Marino 897*e4b17023SJohn Marino /* First substitute the SETCC condition into the JUMP instruction, 898*e4b17023SJohn Marino then substitute that given values into this expanded JUMP. */ 899*e4b17023SJohn Marino if (setcc != NULL_RTX 900*e4b17023SJohn Marino && !modified_between_p (from, setcc, jump) 901*e4b17023SJohn Marino && !modified_between_p (src, setcc, jump)) 902*e4b17023SJohn Marino { 903*e4b17023SJohn Marino rtx setcc_src; 904*e4b17023SJohn Marino rtx setcc_set = single_set (setcc); 905*e4b17023SJohn Marino rtx setcc_note = find_reg_equal_equiv_note (setcc); 906*e4b17023SJohn Marino setcc_src = (setcc_note && GET_CODE (XEXP (setcc_note, 0)) != EXPR_LIST) 907*e4b17023SJohn Marino ? XEXP (setcc_note, 0) : SET_SRC (setcc_set); 908*e4b17023SJohn Marino set_src = simplify_replace_rtx (set_src, SET_DEST (setcc_set), 909*e4b17023SJohn Marino setcc_src); 910*e4b17023SJohn Marino } 911*e4b17023SJohn Marino else 912*e4b17023SJohn Marino setcc = NULL_RTX; 913*e4b17023SJohn Marino 914*e4b17023SJohn Marino new_rtx = simplify_replace_rtx (set_src, from, src); 915*e4b17023SJohn Marino 916*e4b17023SJohn Marino /* If no simplification can be made, then try the next register. */ 917*e4b17023SJohn Marino if (rtx_equal_p (new_rtx, SET_SRC (set))) 918*e4b17023SJohn Marino return 0; 919*e4b17023SJohn Marino 920*e4b17023SJohn Marino /* If this is now a no-op delete it, otherwise this must be a valid insn. */ 921*e4b17023SJohn Marino if (new_rtx == pc_rtx) 922*e4b17023SJohn Marino delete_insn (jump); 923*e4b17023SJohn Marino else 924*e4b17023SJohn Marino { 925*e4b17023SJohn Marino /* Ensure the value computed inside the jump insn to be equivalent 926*e4b17023SJohn Marino to one computed by setcc. */ 927*e4b17023SJohn Marino if (setcc && modified_in_p (new_rtx, setcc)) 928*e4b17023SJohn Marino return 0; 929*e4b17023SJohn Marino if (! validate_unshare_change (jump, &SET_SRC (set), new_rtx, 0)) 930*e4b17023SJohn Marino { 931*e4b17023SJohn Marino /* When (some) constants are not valid in a comparison, and there 932*e4b17023SJohn Marino are two registers to be replaced by constants before the entire 933*e4b17023SJohn Marino comparison can be folded into a constant, we need to keep 934*e4b17023SJohn Marino intermediate information in REG_EQUAL notes. For targets with 935*e4b17023SJohn Marino separate compare insns, such notes are added by try_replace_reg. 936*e4b17023SJohn Marino When we have a combined compare-and-branch instruction, however, 937*e4b17023SJohn Marino we need to attach a note to the branch itself to make this 938*e4b17023SJohn Marino optimization work. */ 939*e4b17023SJohn Marino 940*e4b17023SJohn Marino if (!rtx_equal_p (new_rtx, note_src)) 941*e4b17023SJohn Marino set_unique_reg_note (jump, REG_EQUAL, copy_rtx (new_rtx)); 942*e4b17023SJohn Marino return 0; 943*e4b17023SJohn Marino } 944*e4b17023SJohn Marino 945*e4b17023SJohn Marino /* Remove REG_EQUAL note after simplification. */ 946*e4b17023SJohn Marino if (note_src) 947*e4b17023SJohn Marino remove_note (jump, note); 948*e4b17023SJohn Marino } 949*e4b17023SJohn Marino 950*e4b17023SJohn Marino #ifdef HAVE_cc0 951*e4b17023SJohn Marino /* Delete the cc0 setter. */ 952*e4b17023SJohn Marino if (setcc != NULL && CC0_P (SET_DEST (single_set (setcc)))) 953*e4b17023SJohn Marino delete_insn (setcc); 954*e4b17023SJohn Marino #endif 955*e4b17023SJohn Marino 956*e4b17023SJohn Marino global_const_prop_count++; 957*e4b17023SJohn Marino if (dump_file != NULL) 958*e4b17023SJohn Marino { 959*e4b17023SJohn Marino fprintf (dump_file, 960*e4b17023SJohn Marino "GLOBAL CONST-PROP: Replacing reg %d in jump_insn %d with" 961*e4b17023SJohn Marino "constant ", REGNO (from), INSN_UID (jump)); 962*e4b17023SJohn Marino print_rtl (dump_file, src); 963*e4b17023SJohn Marino fprintf (dump_file, "\n"); 964*e4b17023SJohn Marino } 965*e4b17023SJohn Marino purge_dead_edges (bb); 966*e4b17023SJohn Marino 967*e4b17023SJohn Marino /* If a conditional jump has been changed into unconditional jump, remove 968*e4b17023SJohn Marino the jump and make the edge fallthru - this is always called in 969*e4b17023SJohn Marino cfglayout mode. */ 970*e4b17023SJohn Marino if (new_rtx != pc_rtx && simplejump_p (jump)) 971*e4b17023SJohn Marino { 972*e4b17023SJohn Marino edge e; 973*e4b17023SJohn Marino edge_iterator ei; 974*e4b17023SJohn Marino 975*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->succs) 976*e4b17023SJohn Marino if (e->dest != EXIT_BLOCK_PTR 977*e4b17023SJohn Marino && BB_HEAD (e->dest) == JUMP_LABEL (jump)) 978*e4b17023SJohn Marino { 979*e4b17023SJohn Marino e->flags |= EDGE_FALLTHRU; 980*e4b17023SJohn Marino break; 981*e4b17023SJohn Marino } 982*e4b17023SJohn Marino delete_insn (jump); 983*e4b17023SJohn Marino } 984*e4b17023SJohn Marino 985*e4b17023SJohn Marino return 1; 986*e4b17023SJohn Marino } 987*e4b17023SJohn Marino 988*e4b17023SJohn Marino /* Subroutine of cprop_insn that tries to propagate constants. FROM is what 989*e4b17023SJohn Marino we will try to replace, SRC is the constant we will try to substitute for 990*e4b17023SJohn Marino it and INSN is the instruction where this will be happening. */ 991*e4b17023SJohn Marino 992*e4b17023SJohn Marino static int 993*e4b17023SJohn Marino constprop_register (rtx from, rtx src, rtx insn) 994*e4b17023SJohn Marino { 995*e4b17023SJohn Marino rtx sset; 996*e4b17023SJohn Marino 997*e4b17023SJohn Marino /* Check for reg or cc0 setting instructions followed by 998*e4b17023SJohn Marino conditional branch instructions first. */ 999*e4b17023SJohn Marino if ((sset = single_set (insn)) != NULL 1000*e4b17023SJohn Marino && NEXT_INSN (insn) 1001*e4b17023SJohn Marino && any_condjump_p (NEXT_INSN (insn)) && onlyjump_p (NEXT_INSN (insn))) 1002*e4b17023SJohn Marino { 1003*e4b17023SJohn Marino rtx dest = SET_DEST (sset); 1004*e4b17023SJohn Marino if ((REG_P (dest) || CC0_P (dest)) 1005*e4b17023SJohn Marino && cprop_jump (BLOCK_FOR_INSN (insn), insn, NEXT_INSN (insn), 1006*e4b17023SJohn Marino from, src)) 1007*e4b17023SJohn Marino return 1; 1008*e4b17023SJohn Marino } 1009*e4b17023SJohn Marino 1010*e4b17023SJohn Marino /* Handle normal insns next. */ 1011*e4b17023SJohn Marino if (NONJUMP_INSN_P (insn) && try_replace_reg (from, src, insn)) 1012*e4b17023SJohn Marino return 1; 1013*e4b17023SJohn Marino 1014*e4b17023SJohn Marino /* Try to propagate a CONST_INT into a conditional jump. 1015*e4b17023SJohn Marino We're pretty specific about what we will handle in this 1016*e4b17023SJohn Marino code, we can extend this as necessary over time. 1017*e4b17023SJohn Marino 1018*e4b17023SJohn Marino Right now the insn in question must look like 1019*e4b17023SJohn Marino (set (pc) (if_then_else ...)) */ 1020*e4b17023SJohn Marino else if (any_condjump_p (insn) && onlyjump_p (insn)) 1021*e4b17023SJohn Marino return cprop_jump (BLOCK_FOR_INSN (insn), NULL, insn, from, src); 1022*e4b17023SJohn Marino return 0; 1023*e4b17023SJohn Marino } 1024*e4b17023SJohn Marino 1025*e4b17023SJohn Marino /* Perform constant and copy propagation on INSN. 1026*e4b17023SJohn Marino Return nonzero if a change was made. */ 1027*e4b17023SJohn Marino 1028*e4b17023SJohn Marino static int 1029*e4b17023SJohn Marino cprop_insn (rtx insn) 1030*e4b17023SJohn Marino { 1031*e4b17023SJohn Marino unsigned i; 1032*e4b17023SJohn Marino int changed = 0, changed_this_round; 1033*e4b17023SJohn Marino rtx note; 1034*e4b17023SJohn Marino 1035*e4b17023SJohn Marino retry: 1036*e4b17023SJohn Marino changed_this_round = 0; 1037*e4b17023SJohn Marino reg_use_count = 0; 1038*e4b17023SJohn Marino note_uses (&PATTERN (insn), find_used_regs, NULL); 1039*e4b17023SJohn Marino 1040*e4b17023SJohn Marino /* We may win even when propagating constants into notes. */ 1041*e4b17023SJohn Marino note = find_reg_equal_equiv_note (insn); 1042*e4b17023SJohn Marino if (note) 1043*e4b17023SJohn Marino find_used_regs (&XEXP (note, 0), NULL); 1044*e4b17023SJohn Marino 1045*e4b17023SJohn Marino for (i = 0; i < reg_use_count; i++) 1046*e4b17023SJohn Marino { 1047*e4b17023SJohn Marino rtx reg_used = reg_use_table[i]; 1048*e4b17023SJohn Marino unsigned int regno = REGNO (reg_used); 1049*e4b17023SJohn Marino rtx src; 1050*e4b17023SJohn Marino struct expr *set; 1051*e4b17023SJohn Marino 1052*e4b17023SJohn Marino /* If the register has already been set in this block, there's 1053*e4b17023SJohn Marino nothing we can do. */ 1054*e4b17023SJohn Marino if (! reg_not_set_p (reg_used, insn)) 1055*e4b17023SJohn Marino continue; 1056*e4b17023SJohn Marino 1057*e4b17023SJohn Marino /* Find an assignment that sets reg_used and is available 1058*e4b17023SJohn Marino at the start of the block. */ 1059*e4b17023SJohn Marino set = find_avail_set (regno, insn); 1060*e4b17023SJohn Marino if (! set) 1061*e4b17023SJohn Marino continue; 1062*e4b17023SJohn Marino 1063*e4b17023SJohn Marino src = set->src; 1064*e4b17023SJohn Marino 1065*e4b17023SJohn Marino /* Constant propagation. */ 1066*e4b17023SJohn Marino if (cprop_constant_p (src)) 1067*e4b17023SJohn Marino { 1068*e4b17023SJohn Marino if (constprop_register (reg_used, src, insn)) 1069*e4b17023SJohn Marino { 1070*e4b17023SJohn Marino changed_this_round = changed = 1; 1071*e4b17023SJohn Marino global_const_prop_count++; 1072*e4b17023SJohn Marino if (dump_file != NULL) 1073*e4b17023SJohn Marino { 1074*e4b17023SJohn Marino fprintf (dump_file, 1075*e4b17023SJohn Marino "GLOBAL CONST-PROP: Replacing reg %d in ", regno); 1076*e4b17023SJohn Marino fprintf (dump_file, "insn %d with constant ", 1077*e4b17023SJohn Marino INSN_UID (insn)); 1078*e4b17023SJohn Marino print_rtl (dump_file, src); 1079*e4b17023SJohn Marino fprintf (dump_file, "\n"); 1080*e4b17023SJohn Marino } 1081*e4b17023SJohn Marino if (INSN_DELETED_P (insn)) 1082*e4b17023SJohn Marino return 1; 1083*e4b17023SJohn Marino } 1084*e4b17023SJohn Marino } 1085*e4b17023SJohn Marino else if (REG_P (src) 1086*e4b17023SJohn Marino && REGNO (src) >= FIRST_PSEUDO_REGISTER 1087*e4b17023SJohn Marino && REGNO (src) != regno) 1088*e4b17023SJohn Marino { 1089*e4b17023SJohn Marino if (try_replace_reg (reg_used, src, insn)) 1090*e4b17023SJohn Marino { 1091*e4b17023SJohn Marino changed_this_round = changed = 1; 1092*e4b17023SJohn Marino global_copy_prop_count++; 1093*e4b17023SJohn Marino if (dump_file != NULL) 1094*e4b17023SJohn Marino { 1095*e4b17023SJohn Marino fprintf (dump_file, 1096*e4b17023SJohn Marino "GLOBAL COPY-PROP: Replacing reg %d in insn %d", 1097*e4b17023SJohn Marino regno, INSN_UID (insn)); 1098*e4b17023SJohn Marino fprintf (dump_file, " with reg %d\n", REGNO (src)); 1099*e4b17023SJohn Marino } 1100*e4b17023SJohn Marino 1101*e4b17023SJohn Marino /* The original insn setting reg_used may or may not now be 1102*e4b17023SJohn Marino deletable. We leave the deletion to DCE. */ 1103*e4b17023SJohn Marino /* FIXME: If it turns out that the insn isn't deletable, 1104*e4b17023SJohn Marino then we may have unnecessarily extended register lifetimes 1105*e4b17023SJohn Marino and made things worse. */ 1106*e4b17023SJohn Marino } 1107*e4b17023SJohn Marino } 1108*e4b17023SJohn Marino 1109*e4b17023SJohn Marino /* If try_replace_reg simplified the insn, the regs found 1110*e4b17023SJohn Marino by find_used_regs may not be valid anymore. Start over. */ 1111*e4b17023SJohn Marino if (changed_this_round) 1112*e4b17023SJohn Marino goto retry; 1113*e4b17023SJohn Marino } 1114*e4b17023SJohn Marino 1115*e4b17023SJohn Marino if (changed && DEBUG_INSN_P (insn)) 1116*e4b17023SJohn Marino return 0; 1117*e4b17023SJohn Marino 1118*e4b17023SJohn Marino return changed; 1119*e4b17023SJohn Marino } 1120*e4b17023SJohn Marino 1121*e4b17023SJohn Marino /* Like find_used_regs, but avoid recording uses that appear in 1122*e4b17023SJohn Marino input-output contexts such as zero_extract or pre_dec. This 1123*e4b17023SJohn Marino restricts the cases we consider to those for which local cprop 1124*e4b17023SJohn Marino can legitimately make replacements. */ 1125*e4b17023SJohn Marino 1126*e4b17023SJohn Marino static void 1127*e4b17023SJohn Marino local_cprop_find_used_regs (rtx *xptr, void *data) 1128*e4b17023SJohn Marino { 1129*e4b17023SJohn Marino rtx x = *xptr; 1130*e4b17023SJohn Marino 1131*e4b17023SJohn Marino if (x == 0) 1132*e4b17023SJohn Marino return; 1133*e4b17023SJohn Marino 1134*e4b17023SJohn Marino switch (GET_CODE (x)) 1135*e4b17023SJohn Marino { 1136*e4b17023SJohn Marino case ZERO_EXTRACT: 1137*e4b17023SJohn Marino case SIGN_EXTRACT: 1138*e4b17023SJohn Marino case STRICT_LOW_PART: 1139*e4b17023SJohn Marino return; 1140*e4b17023SJohn Marino 1141*e4b17023SJohn Marino case PRE_DEC: 1142*e4b17023SJohn Marino case PRE_INC: 1143*e4b17023SJohn Marino case POST_DEC: 1144*e4b17023SJohn Marino case POST_INC: 1145*e4b17023SJohn Marino case PRE_MODIFY: 1146*e4b17023SJohn Marino case POST_MODIFY: 1147*e4b17023SJohn Marino /* Can only legitimately appear this early in the context of 1148*e4b17023SJohn Marino stack pushes for function arguments, but handle all of the 1149*e4b17023SJohn Marino codes nonetheless. */ 1150*e4b17023SJohn Marino return; 1151*e4b17023SJohn Marino 1152*e4b17023SJohn Marino case SUBREG: 1153*e4b17023SJohn Marino /* Setting a subreg of a register larger than word_mode leaves 1154*e4b17023SJohn Marino the non-written words unchanged. */ 1155*e4b17023SJohn Marino if (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) > BITS_PER_WORD) 1156*e4b17023SJohn Marino return; 1157*e4b17023SJohn Marino break; 1158*e4b17023SJohn Marino 1159*e4b17023SJohn Marino default: 1160*e4b17023SJohn Marino break; 1161*e4b17023SJohn Marino } 1162*e4b17023SJohn Marino 1163*e4b17023SJohn Marino find_used_regs (xptr, data); 1164*e4b17023SJohn Marino } 1165*e4b17023SJohn Marino 1166*e4b17023SJohn Marino /* Try to perform local const/copy propagation on X in INSN. */ 1167*e4b17023SJohn Marino 1168*e4b17023SJohn Marino static bool 1169*e4b17023SJohn Marino do_local_cprop (rtx x, rtx insn) 1170*e4b17023SJohn Marino { 1171*e4b17023SJohn Marino rtx newreg = NULL, newcnst = NULL; 1172*e4b17023SJohn Marino 1173*e4b17023SJohn Marino /* Rule out USE instructions and ASM statements as we don't want to 1174*e4b17023SJohn Marino change the hard registers mentioned. */ 1175*e4b17023SJohn Marino if (REG_P (x) 1176*e4b17023SJohn Marino && (REGNO (x) >= FIRST_PSEUDO_REGISTER 1177*e4b17023SJohn Marino || (GET_CODE (PATTERN (insn)) != USE 1178*e4b17023SJohn Marino && asm_noperands (PATTERN (insn)) < 0))) 1179*e4b17023SJohn Marino { 1180*e4b17023SJohn Marino cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode); 1181*e4b17023SJohn Marino struct elt_loc_list *l; 1182*e4b17023SJohn Marino 1183*e4b17023SJohn Marino if (!val) 1184*e4b17023SJohn Marino return false; 1185*e4b17023SJohn Marino for (l = val->locs; l; l = l->next) 1186*e4b17023SJohn Marino { 1187*e4b17023SJohn Marino rtx this_rtx = l->loc; 1188*e4b17023SJohn Marino rtx note; 1189*e4b17023SJohn Marino 1190*e4b17023SJohn Marino if (cprop_constant_p (this_rtx)) 1191*e4b17023SJohn Marino newcnst = this_rtx; 1192*e4b17023SJohn Marino if (REG_P (this_rtx) && REGNO (this_rtx) >= FIRST_PSEUDO_REGISTER 1193*e4b17023SJohn Marino /* Don't copy propagate if it has attached REG_EQUIV note. 1194*e4b17023SJohn Marino At this point this only function parameters should have 1195*e4b17023SJohn Marino REG_EQUIV notes and if the argument slot is used somewhere 1196*e4b17023SJohn Marino explicitly, it means address of parameter has been taken, 1197*e4b17023SJohn Marino so we should not extend the lifetime of the pseudo. */ 1198*e4b17023SJohn Marino && (!(note = find_reg_note (l->setting_insn, REG_EQUIV, NULL_RTX)) 1199*e4b17023SJohn Marino || ! MEM_P (XEXP (note, 0)))) 1200*e4b17023SJohn Marino newreg = this_rtx; 1201*e4b17023SJohn Marino } 1202*e4b17023SJohn Marino if (newcnst && constprop_register (x, newcnst, insn)) 1203*e4b17023SJohn Marino { 1204*e4b17023SJohn Marino if (dump_file != NULL) 1205*e4b17023SJohn Marino { 1206*e4b17023SJohn Marino fprintf (dump_file, "LOCAL CONST-PROP: Replacing reg %d in ", 1207*e4b17023SJohn Marino REGNO (x)); 1208*e4b17023SJohn Marino fprintf (dump_file, "insn %d with constant ", 1209*e4b17023SJohn Marino INSN_UID (insn)); 1210*e4b17023SJohn Marino print_rtl (dump_file, newcnst); 1211*e4b17023SJohn Marino fprintf (dump_file, "\n"); 1212*e4b17023SJohn Marino } 1213*e4b17023SJohn Marino local_const_prop_count++; 1214*e4b17023SJohn Marino return true; 1215*e4b17023SJohn Marino } 1216*e4b17023SJohn Marino else if (newreg && newreg != x && try_replace_reg (x, newreg, insn)) 1217*e4b17023SJohn Marino { 1218*e4b17023SJohn Marino if (dump_file != NULL) 1219*e4b17023SJohn Marino { 1220*e4b17023SJohn Marino fprintf (dump_file, 1221*e4b17023SJohn Marino "LOCAL COPY-PROP: Replacing reg %d in insn %d", 1222*e4b17023SJohn Marino REGNO (x), INSN_UID (insn)); 1223*e4b17023SJohn Marino fprintf (dump_file, " with reg %d\n", REGNO (newreg)); 1224*e4b17023SJohn Marino } 1225*e4b17023SJohn Marino local_copy_prop_count++; 1226*e4b17023SJohn Marino return true; 1227*e4b17023SJohn Marino } 1228*e4b17023SJohn Marino } 1229*e4b17023SJohn Marino return false; 1230*e4b17023SJohn Marino } 1231*e4b17023SJohn Marino 1232*e4b17023SJohn Marino /* Do local const/copy propagation (i.e. within each basic block). */ 1233*e4b17023SJohn Marino 1234*e4b17023SJohn Marino static int 1235*e4b17023SJohn Marino local_cprop_pass (void) 1236*e4b17023SJohn Marino { 1237*e4b17023SJohn Marino basic_block bb; 1238*e4b17023SJohn Marino rtx insn; 1239*e4b17023SJohn Marino bool changed = false; 1240*e4b17023SJohn Marino unsigned i; 1241*e4b17023SJohn Marino 1242*e4b17023SJohn Marino cselib_init (0); 1243*e4b17023SJohn Marino FOR_EACH_BB (bb) 1244*e4b17023SJohn Marino { 1245*e4b17023SJohn Marino FOR_BB_INSNS (bb, insn) 1246*e4b17023SJohn Marino { 1247*e4b17023SJohn Marino if (INSN_P (insn)) 1248*e4b17023SJohn Marino { 1249*e4b17023SJohn Marino rtx note = find_reg_equal_equiv_note (insn); 1250*e4b17023SJohn Marino do 1251*e4b17023SJohn Marino { 1252*e4b17023SJohn Marino reg_use_count = 0; 1253*e4b17023SJohn Marino note_uses (&PATTERN (insn), local_cprop_find_used_regs, 1254*e4b17023SJohn Marino NULL); 1255*e4b17023SJohn Marino if (note) 1256*e4b17023SJohn Marino local_cprop_find_used_regs (&XEXP (note, 0), NULL); 1257*e4b17023SJohn Marino 1258*e4b17023SJohn Marino for (i = 0; i < reg_use_count; i++) 1259*e4b17023SJohn Marino { 1260*e4b17023SJohn Marino if (do_local_cprop (reg_use_table[i], insn)) 1261*e4b17023SJohn Marino { 1262*e4b17023SJohn Marino if (!DEBUG_INSN_P (insn)) 1263*e4b17023SJohn Marino changed = true; 1264*e4b17023SJohn Marino break; 1265*e4b17023SJohn Marino } 1266*e4b17023SJohn Marino } 1267*e4b17023SJohn Marino if (INSN_DELETED_P (insn)) 1268*e4b17023SJohn Marino break; 1269*e4b17023SJohn Marino } 1270*e4b17023SJohn Marino while (i < reg_use_count); 1271*e4b17023SJohn Marino } 1272*e4b17023SJohn Marino cselib_process_insn (insn); 1273*e4b17023SJohn Marino } 1274*e4b17023SJohn Marino 1275*e4b17023SJohn Marino /* Forget everything at the end of a basic block. */ 1276*e4b17023SJohn Marino cselib_clear_table (); 1277*e4b17023SJohn Marino } 1278*e4b17023SJohn Marino 1279*e4b17023SJohn Marino cselib_finish (); 1280*e4b17023SJohn Marino 1281*e4b17023SJohn Marino return changed; 1282*e4b17023SJohn Marino } 1283*e4b17023SJohn Marino 1284*e4b17023SJohn Marino /* Similar to get_condition, only the resulting condition must be 1285*e4b17023SJohn Marino valid at JUMP, instead of at EARLIEST. 1286*e4b17023SJohn Marino 1287*e4b17023SJohn Marino This differs from noce_get_condition in ifcvt.c in that we prefer not to 1288*e4b17023SJohn Marino settle for the condition variable in the jump instruction being integral. 1289*e4b17023SJohn Marino We prefer to be able to record the value of a user variable, rather than 1290*e4b17023SJohn Marino the value of a temporary used in a condition. This could be solved by 1291*e4b17023SJohn Marino recording the value of *every* register scanned by canonicalize_condition, 1292*e4b17023SJohn Marino but this would require some code reorganization. */ 1293*e4b17023SJohn Marino 1294*e4b17023SJohn Marino rtx 1295*e4b17023SJohn Marino fis_get_condition (rtx jump) 1296*e4b17023SJohn Marino { 1297*e4b17023SJohn Marino return get_condition (jump, NULL, false, true); 1298*e4b17023SJohn Marino } 1299*e4b17023SJohn Marino 1300*e4b17023SJohn Marino /* Check the comparison COND to see if we can safely form an implicit 1301*e4b17023SJohn Marino set from it. */ 1302*e4b17023SJohn Marino 1303*e4b17023SJohn Marino static bool 1304*e4b17023SJohn Marino implicit_set_cond_p (const_rtx cond) 1305*e4b17023SJohn Marino { 1306*e4b17023SJohn Marino enum machine_mode mode; 1307*e4b17023SJohn Marino rtx cst; 1308*e4b17023SJohn Marino 1309*e4b17023SJohn Marino /* COND must be either an EQ or NE comparison. */ 1310*e4b17023SJohn Marino if (GET_CODE (cond) != EQ && GET_CODE (cond) != NE) 1311*e4b17023SJohn Marino return false; 1312*e4b17023SJohn Marino 1313*e4b17023SJohn Marino /* The first operand of COND must be a pseudo-reg. */ 1314*e4b17023SJohn Marino if (! REG_P (XEXP (cond, 0)) 1315*e4b17023SJohn Marino || HARD_REGISTER_P (XEXP (cond, 0))) 1316*e4b17023SJohn Marino return false; 1317*e4b17023SJohn Marino 1318*e4b17023SJohn Marino /* The second operand of COND must be a suitable constant. */ 1319*e4b17023SJohn Marino mode = GET_MODE (XEXP (cond, 0)); 1320*e4b17023SJohn Marino cst = XEXP (cond, 1); 1321*e4b17023SJohn Marino 1322*e4b17023SJohn Marino /* We can't perform this optimization if either operand might be or might 1323*e4b17023SJohn Marino contain a signed zero. */ 1324*e4b17023SJohn Marino if (HONOR_SIGNED_ZEROS (mode)) 1325*e4b17023SJohn Marino { 1326*e4b17023SJohn Marino /* It is sufficient to check if CST is or contains a zero. We must 1327*e4b17023SJohn Marino handle float, complex, and vector. If any subpart is a zero, then 1328*e4b17023SJohn Marino the optimization can't be performed. */ 1329*e4b17023SJohn Marino /* ??? The complex and vector checks are not implemented yet. We just 1330*e4b17023SJohn Marino always return zero for them. */ 1331*e4b17023SJohn Marino if (GET_CODE (cst) == CONST_DOUBLE) 1332*e4b17023SJohn Marino { 1333*e4b17023SJohn Marino REAL_VALUE_TYPE d; 1334*e4b17023SJohn Marino REAL_VALUE_FROM_CONST_DOUBLE (d, cst); 1335*e4b17023SJohn Marino if (REAL_VALUES_EQUAL (d, dconst0)) 1336*e4b17023SJohn Marino return 0; 1337*e4b17023SJohn Marino } 1338*e4b17023SJohn Marino else 1339*e4b17023SJohn Marino return 0; 1340*e4b17023SJohn Marino } 1341*e4b17023SJohn Marino 1342*e4b17023SJohn Marino return cprop_constant_p (cst); 1343*e4b17023SJohn Marino } 1344*e4b17023SJohn Marino 1345*e4b17023SJohn Marino /* Find the implicit sets of a function. An "implicit set" is a constraint 1346*e4b17023SJohn Marino on the value of a variable, implied by a conditional jump. For example, 1347*e4b17023SJohn Marino following "if (x == 2)", the then branch may be optimized as though the 1348*e4b17023SJohn Marino conditional performed an "explicit set", in this example, "x = 2". This 1349*e4b17023SJohn Marino function records the set patterns that are implicit at the start of each 1350*e4b17023SJohn Marino basic block. 1351*e4b17023SJohn Marino 1352*e4b17023SJohn Marino If an implicit set is found but the set is implicit on a critical edge, 1353*e4b17023SJohn Marino this critical edge is split. 1354*e4b17023SJohn Marino 1355*e4b17023SJohn Marino Return true if the CFG was modified, false otherwise. */ 1356*e4b17023SJohn Marino 1357*e4b17023SJohn Marino static bool 1358*e4b17023SJohn Marino find_implicit_sets (void) 1359*e4b17023SJohn Marino { 1360*e4b17023SJohn Marino basic_block bb, dest; 1361*e4b17023SJohn Marino rtx cond, new_rtx; 1362*e4b17023SJohn Marino unsigned int count = 0; 1363*e4b17023SJohn Marino bool edges_split = false; 1364*e4b17023SJohn Marino size_t implicit_sets_size = last_basic_block + 10; 1365*e4b17023SJohn Marino 1366*e4b17023SJohn Marino implicit_sets = XCNEWVEC (rtx, implicit_sets_size); 1367*e4b17023SJohn Marino 1368*e4b17023SJohn Marino FOR_EACH_BB (bb) 1369*e4b17023SJohn Marino { 1370*e4b17023SJohn Marino /* Check for more than one successor. */ 1371*e4b17023SJohn Marino if (EDGE_COUNT (bb->succs) <= 1) 1372*e4b17023SJohn Marino continue; 1373*e4b17023SJohn Marino 1374*e4b17023SJohn Marino cond = fis_get_condition (BB_END (bb)); 1375*e4b17023SJohn Marino 1376*e4b17023SJohn Marino /* If no condition is found or if it isn't of a suitable form, 1377*e4b17023SJohn Marino ignore it. */ 1378*e4b17023SJohn Marino if (! cond || ! implicit_set_cond_p (cond)) 1379*e4b17023SJohn Marino continue; 1380*e4b17023SJohn Marino 1381*e4b17023SJohn Marino dest = GET_CODE (cond) == EQ 1382*e4b17023SJohn Marino ? BRANCH_EDGE (bb)->dest : FALLTHRU_EDGE (bb)->dest; 1383*e4b17023SJohn Marino 1384*e4b17023SJohn Marino /* If DEST doesn't go anywhere, ignore it. */ 1385*e4b17023SJohn Marino if (! dest || dest == EXIT_BLOCK_PTR) 1386*e4b17023SJohn Marino continue; 1387*e4b17023SJohn Marino 1388*e4b17023SJohn Marino /* We have found a suitable implicit set. Try to record it now as 1389*e4b17023SJohn Marino a SET in DEST. If DEST has more than one predecessor, the edge 1390*e4b17023SJohn Marino between BB and DEST is a critical edge and we must split it, 1391*e4b17023SJohn Marino because we can only record one implicit set per DEST basic block. */ 1392*e4b17023SJohn Marino if (! single_pred_p (dest)) 1393*e4b17023SJohn Marino { 1394*e4b17023SJohn Marino dest = split_edge (find_edge (bb, dest)); 1395*e4b17023SJohn Marino edges_split = true; 1396*e4b17023SJohn Marino } 1397*e4b17023SJohn Marino 1398*e4b17023SJohn Marino if (implicit_sets_size <= (size_t) dest->index) 1399*e4b17023SJohn Marino { 1400*e4b17023SJohn Marino size_t old_implicit_sets_size = implicit_sets_size; 1401*e4b17023SJohn Marino implicit_sets_size *= 2; 1402*e4b17023SJohn Marino implicit_sets = XRESIZEVEC (rtx, implicit_sets, implicit_sets_size); 1403*e4b17023SJohn Marino memset (implicit_sets + old_implicit_sets_size, 0, 1404*e4b17023SJohn Marino (implicit_sets_size - old_implicit_sets_size) * sizeof (rtx)); 1405*e4b17023SJohn Marino } 1406*e4b17023SJohn Marino 1407*e4b17023SJohn Marino new_rtx = gen_rtx_SET (VOIDmode, XEXP (cond, 0), 1408*e4b17023SJohn Marino XEXP (cond, 1)); 1409*e4b17023SJohn Marino implicit_sets[dest->index] = new_rtx; 1410*e4b17023SJohn Marino if (dump_file) 1411*e4b17023SJohn Marino { 1412*e4b17023SJohn Marino fprintf(dump_file, "Implicit set of reg %d in ", 1413*e4b17023SJohn Marino REGNO (XEXP (cond, 0))); 1414*e4b17023SJohn Marino fprintf(dump_file, "basic block %d\n", dest->index); 1415*e4b17023SJohn Marino } 1416*e4b17023SJohn Marino count++; 1417*e4b17023SJohn Marino } 1418*e4b17023SJohn Marino 1419*e4b17023SJohn Marino if (dump_file) 1420*e4b17023SJohn Marino fprintf (dump_file, "Found %d implicit sets\n", count); 1421*e4b17023SJohn Marino 1422*e4b17023SJohn Marino /* Confess our sins. */ 1423*e4b17023SJohn Marino return edges_split; 1424*e4b17023SJohn Marino } 1425*e4b17023SJohn Marino 1426*e4b17023SJohn Marino /* Bypass conditional jumps. */ 1427*e4b17023SJohn Marino 1428*e4b17023SJohn Marino /* The value of last_basic_block at the beginning of the jump_bypass 1429*e4b17023SJohn Marino pass. The use of redirect_edge_and_branch_force may introduce new 1430*e4b17023SJohn Marino basic blocks, but the data flow analysis is only valid for basic 1431*e4b17023SJohn Marino block indices less than bypass_last_basic_block. */ 1432*e4b17023SJohn Marino 1433*e4b17023SJohn Marino static int bypass_last_basic_block; 1434*e4b17023SJohn Marino 1435*e4b17023SJohn Marino /* Find a set of REGNO to a constant that is available at the end of basic 1436*e4b17023SJohn Marino block BB. Return NULL if no such set is found. Based heavily upon 1437*e4b17023SJohn Marino find_avail_set. */ 1438*e4b17023SJohn Marino 1439*e4b17023SJohn Marino static struct expr * 1440*e4b17023SJohn Marino find_bypass_set (int regno, int bb) 1441*e4b17023SJohn Marino { 1442*e4b17023SJohn Marino struct expr *result = 0; 1443*e4b17023SJohn Marino 1444*e4b17023SJohn Marino for (;;) 1445*e4b17023SJohn Marino { 1446*e4b17023SJohn Marino rtx src; 1447*e4b17023SJohn Marino struct expr *set = lookup_set (regno, &set_hash_table); 1448*e4b17023SJohn Marino 1449*e4b17023SJohn Marino while (set) 1450*e4b17023SJohn Marino { 1451*e4b17023SJohn Marino if (TEST_BIT (cprop_avout[bb], set->bitmap_index)) 1452*e4b17023SJohn Marino break; 1453*e4b17023SJohn Marino set = next_set (regno, set); 1454*e4b17023SJohn Marino } 1455*e4b17023SJohn Marino 1456*e4b17023SJohn Marino if (set == 0) 1457*e4b17023SJohn Marino break; 1458*e4b17023SJohn Marino 1459*e4b17023SJohn Marino src = set->src; 1460*e4b17023SJohn Marino if (cprop_constant_p (src)) 1461*e4b17023SJohn Marino result = set; 1462*e4b17023SJohn Marino 1463*e4b17023SJohn Marino if (! REG_P (src)) 1464*e4b17023SJohn Marino break; 1465*e4b17023SJohn Marino 1466*e4b17023SJohn Marino regno = REGNO (src); 1467*e4b17023SJohn Marino } 1468*e4b17023SJohn Marino return result; 1469*e4b17023SJohn Marino } 1470*e4b17023SJohn Marino 1471*e4b17023SJohn Marino /* Subroutine of bypass_block that checks whether a pseudo is killed by 1472*e4b17023SJohn Marino any of the instructions inserted on an edge. Jump bypassing places 1473*e4b17023SJohn Marino condition code setters on CFG edges using insert_insn_on_edge. This 1474*e4b17023SJohn Marino function is required to check that our data flow analysis is still 1475*e4b17023SJohn Marino valid prior to commit_edge_insertions. */ 1476*e4b17023SJohn Marino 1477*e4b17023SJohn Marino static bool 1478*e4b17023SJohn Marino reg_killed_on_edge (const_rtx reg, const_edge e) 1479*e4b17023SJohn Marino { 1480*e4b17023SJohn Marino rtx insn; 1481*e4b17023SJohn Marino 1482*e4b17023SJohn Marino for (insn = e->insns.r; insn; insn = NEXT_INSN (insn)) 1483*e4b17023SJohn Marino if (INSN_P (insn) && reg_set_p (reg, insn)) 1484*e4b17023SJohn Marino return true; 1485*e4b17023SJohn Marino 1486*e4b17023SJohn Marino return false; 1487*e4b17023SJohn Marino } 1488*e4b17023SJohn Marino 1489*e4b17023SJohn Marino /* Subroutine of bypass_conditional_jumps that attempts to bypass the given 1490*e4b17023SJohn Marino basic block BB which has more than one predecessor. If not NULL, SETCC 1491*e4b17023SJohn Marino is the first instruction of BB, which is immediately followed by JUMP_INSN 1492*e4b17023SJohn Marino JUMP. Otherwise, SETCC is NULL, and JUMP is the first insn of BB. 1493*e4b17023SJohn Marino Returns nonzero if a change was made. 1494*e4b17023SJohn Marino 1495*e4b17023SJohn Marino During the jump bypassing pass, we may place copies of SETCC instructions 1496*e4b17023SJohn Marino on CFG edges. The following routine must be careful to pay attention to 1497*e4b17023SJohn Marino these inserted insns when performing its transformations. */ 1498*e4b17023SJohn Marino 1499*e4b17023SJohn Marino static int 1500*e4b17023SJohn Marino bypass_block (basic_block bb, rtx setcc, rtx jump) 1501*e4b17023SJohn Marino { 1502*e4b17023SJohn Marino rtx insn, note; 1503*e4b17023SJohn Marino edge e, edest; 1504*e4b17023SJohn Marino int change; 1505*e4b17023SJohn Marino int may_be_loop_header; 1506*e4b17023SJohn Marino unsigned removed_p; 1507*e4b17023SJohn Marino unsigned i; 1508*e4b17023SJohn Marino edge_iterator ei; 1509*e4b17023SJohn Marino 1510*e4b17023SJohn Marino insn = (setcc != NULL) ? setcc : jump; 1511*e4b17023SJohn Marino 1512*e4b17023SJohn Marino /* Determine set of register uses in INSN. */ 1513*e4b17023SJohn Marino reg_use_count = 0; 1514*e4b17023SJohn Marino note_uses (&PATTERN (insn), find_used_regs, NULL); 1515*e4b17023SJohn Marino note = find_reg_equal_equiv_note (insn); 1516*e4b17023SJohn Marino if (note) 1517*e4b17023SJohn Marino find_used_regs (&XEXP (note, 0), NULL); 1518*e4b17023SJohn Marino 1519*e4b17023SJohn Marino may_be_loop_header = false; 1520*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->preds) 1521*e4b17023SJohn Marino if (e->flags & EDGE_DFS_BACK) 1522*e4b17023SJohn Marino { 1523*e4b17023SJohn Marino may_be_loop_header = true; 1524*e4b17023SJohn Marino break; 1525*e4b17023SJohn Marino } 1526*e4b17023SJohn Marino 1527*e4b17023SJohn Marino change = 0; 1528*e4b17023SJohn Marino for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); ) 1529*e4b17023SJohn Marino { 1530*e4b17023SJohn Marino removed_p = 0; 1531*e4b17023SJohn Marino 1532*e4b17023SJohn Marino if (e->flags & EDGE_COMPLEX) 1533*e4b17023SJohn Marino { 1534*e4b17023SJohn Marino ei_next (&ei); 1535*e4b17023SJohn Marino continue; 1536*e4b17023SJohn Marino } 1537*e4b17023SJohn Marino 1538*e4b17023SJohn Marino /* We can't redirect edges from new basic blocks. */ 1539*e4b17023SJohn Marino if (e->src->index >= bypass_last_basic_block) 1540*e4b17023SJohn Marino { 1541*e4b17023SJohn Marino ei_next (&ei); 1542*e4b17023SJohn Marino continue; 1543*e4b17023SJohn Marino } 1544*e4b17023SJohn Marino 1545*e4b17023SJohn Marino /* The irreducible loops created by redirecting of edges entering the 1546*e4b17023SJohn Marino loop from outside would decrease effectiveness of some of the 1547*e4b17023SJohn Marino following optimizations, so prevent this. */ 1548*e4b17023SJohn Marino if (may_be_loop_header 1549*e4b17023SJohn Marino && !(e->flags & EDGE_DFS_BACK)) 1550*e4b17023SJohn Marino { 1551*e4b17023SJohn Marino ei_next (&ei); 1552*e4b17023SJohn Marino continue; 1553*e4b17023SJohn Marino } 1554*e4b17023SJohn Marino 1555*e4b17023SJohn Marino for (i = 0; i < reg_use_count; i++) 1556*e4b17023SJohn Marino { 1557*e4b17023SJohn Marino rtx reg_used = reg_use_table[i]; 1558*e4b17023SJohn Marino unsigned int regno = REGNO (reg_used); 1559*e4b17023SJohn Marino basic_block dest, old_dest; 1560*e4b17023SJohn Marino struct expr *set; 1561*e4b17023SJohn Marino rtx src, new_rtx; 1562*e4b17023SJohn Marino 1563*e4b17023SJohn Marino set = find_bypass_set (regno, e->src->index); 1564*e4b17023SJohn Marino 1565*e4b17023SJohn Marino if (! set) 1566*e4b17023SJohn Marino continue; 1567*e4b17023SJohn Marino 1568*e4b17023SJohn Marino /* Check the data flow is valid after edge insertions. */ 1569*e4b17023SJohn Marino if (e->insns.r && reg_killed_on_edge (reg_used, e)) 1570*e4b17023SJohn Marino continue; 1571*e4b17023SJohn Marino 1572*e4b17023SJohn Marino src = SET_SRC (pc_set (jump)); 1573*e4b17023SJohn Marino 1574*e4b17023SJohn Marino if (setcc != NULL) 1575*e4b17023SJohn Marino src = simplify_replace_rtx (src, 1576*e4b17023SJohn Marino SET_DEST (PATTERN (setcc)), 1577*e4b17023SJohn Marino SET_SRC (PATTERN (setcc))); 1578*e4b17023SJohn Marino 1579*e4b17023SJohn Marino new_rtx = simplify_replace_rtx (src, reg_used, set->src); 1580*e4b17023SJohn Marino 1581*e4b17023SJohn Marino /* Jump bypassing may have already placed instructions on 1582*e4b17023SJohn Marino edges of the CFG. We can't bypass an outgoing edge that 1583*e4b17023SJohn Marino has instructions associated with it, as these insns won't 1584*e4b17023SJohn Marino get executed if the incoming edge is redirected. */ 1585*e4b17023SJohn Marino if (new_rtx == pc_rtx) 1586*e4b17023SJohn Marino { 1587*e4b17023SJohn Marino edest = FALLTHRU_EDGE (bb); 1588*e4b17023SJohn Marino dest = edest->insns.r ? NULL : edest->dest; 1589*e4b17023SJohn Marino } 1590*e4b17023SJohn Marino else if (GET_CODE (new_rtx) == LABEL_REF) 1591*e4b17023SJohn Marino { 1592*e4b17023SJohn Marino dest = BLOCK_FOR_INSN (XEXP (new_rtx, 0)); 1593*e4b17023SJohn Marino /* Don't bypass edges containing instructions. */ 1594*e4b17023SJohn Marino edest = find_edge (bb, dest); 1595*e4b17023SJohn Marino if (edest && edest->insns.r) 1596*e4b17023SJohn Marino dest = NULL; 1597*e4b17023SJohn Marino } 1598*e4b17023SJohn Marino else 1599*e4b17023SJohn Marino dest = NULL; 1600*e4b17023SJohn Marino 1601*e4b17023SJohn Marino /* Avoid unification of the edge with other edges from original 1602*e4b17023SJohn Marino branch. We would end up emitting the instruction on "both" 1603*e4b17023SJohn Marino edges. */ 1604*e4b17023SJohn Marino if (dest && setcc && !CC0_P (SET_DEST (PATTERN (setcc))) 1605*e4b17023SJohn Marino && find_edge (e->src, dest)) 1606*e4b17023SJohn Marino dest = NULL; 1607*e4b17023SJohn Marino 1608*e4b17023SJohn Marino old_dest = e->dest; 1609*e4b17023SJohn Marino if (dest != NULL 1610*e4b17023SJohn Marino && dest != old_dest 1611*e4b17023SJohn Marino && dest != EXIT_BLOCK_PTR) 1612*e4b17023SJohn Marino { 1613*e4b17023SJohn Marino redirect_edge_and_branch_force (e, dest); 1614*e4b17023SJohn Marino 1615*e4b17023SJohn Marino /* Copy the register setter to the redirected edge. 1616*e4b17023SJohn Marino Don't copy CC0 setters, as CC0 is dead after jump. */ 1617*e4b17023SJohn Marino if (setcc) 1618*e4b17023SJohn Marino { 1619*e4b17023SJohn Marino rtx pat = PATTERN (setcc); 1620*e4b17023SJohn Marino if (!CC0_P (SET_DEST (pat))) 1621*e4b17023SJohn Marino insert_insn_on_edge (copy_insn (pat), e); 1622*e4b17023SJohn Marino } 1623*e4b17023SJohn Marino 1624*e4b17023SJohn Marino if (dump_file != NULL) 1625*e4b17023SJohn Marino { 1626*e4b17023SJohn Marino fprintf (dump_file, "JUMP-BYPASS: Proved reg %d " 1627*e4b17023SJohn Marino "in jump_insn %d equals constant ", 1628*e4b17023SJohn Marino regno, INSN_UID (jump)); 1629*e4b17023SJohn Marino print_rtl (dump_file, set->src); 1630*e4b17023SJohn Marino fprintf (dump_file, "\nBypass edge from %d->%d to %d\n", 1631*e4b17023SJohn Marino e->src->index, old_dest->index, dest->index); 1632*e4b17023SJohn Marino } 1633*e4b17023SJohn Marino change = 1; 1634*e4b17023SJohn Marino removed_p = 1; 1635*e4b17023SJohn Marino break; 1636*e4b17023SJohn Marino } 1637*e4b17023SJohn Marino } 1638*e4b17023SJohn Marino if (!removed_p) 1639*e4b17023SJohn Marino ei_next (&ei); 1640*e4b17023SJohn Marino } 1641*e4b17023SJohn Marino return change; 1642*e4b17023SJohn Marino } 1643*e4b17023SJohn Marino 1644*e4b17023SJohn Marino /* Find basic blocks with more than one predecessor that only contain a 1645*e4b17023SJohn Marino single conditional jump. If the result of the comparison is known at 1646*e4b17023SJohn Marino compile-time from any incoming edge, redirect that edge to the 1647*e4b17023SJohn Marino appropriate target. Return nonzero if a change was made. 1648*e4b17023SJohn Marino 1649*e4b17023SJohn Marino This function is now mis-named, because we also handle indirect jumps. */ 1650*e4b17023SJohn Marino 1651*e4b17023SJohn Marino static int 1652*e4b17023SJohn Marino bypass_conditional_jumps (void) 1653*e4b17023SJohn Marino { 1654*e4b17023SJohn Marino basic_block bb; 1655*e4b17023SJohn Marino int changed; 1656*e4b17023SJohn Marino rtx setcc; 1657*e4b17023SJohn Marino rtx insn; 1658*e4b17023SJohn Marino rtx dest; 1659*e4b17023SJohn Marino 1660*e4b17023SJohn Marino /* Note we start at block 1. */ 1661*e4b17023SJohn Marino if (ENTRY_BLOCK_PTR->next_bb == EXIT_BLOCK_PTR) 1662*e4b17023SJohn Marino return 0; 1663*e4b17023SJohn Marino 1664*e4b17023SJohn Marino bypass_last_basic_block = last_basic_block; 1665*e4b17023SJohn Marino mark_dfs_back_edges (); 1666*e4b17023SJohn Marino 1667*e4b17023SJohn Marino changed = 0; 1668*e4b17023SJohn Marino FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb->next_bb, 1669*e4b17023SJohn Marino EXIT_BLOCK_PTR, next_bb) 1670*e4b17023SJohn Marino { 1671*e4b17023SJohn Marino /* Check for more than one predecessor. */ 1672*e4b17023SJohn Marino if (!single_pred_p (bb)) 1673*e4b17023SJohn Marino { 1674*e4b17023SJohn Marino setcc = NULL_RTX; 1675*e4b17023SJohn Marino FOR_BB_INSNS (bb, insn) 1676*e4b17023SJohn Marino if (DEBUG_INSN_P (insn)) 1677*e4b17023SJohn Marino continue; 1678*e4b17023SJohn Marino else if (NONJUMP_INSN_P (insn)) 1679*e4b17023SJohn Marino { 1680*e4b17023SJohn Marino if (setcc) 1681*e4b17023SJohn Marino break; 1682*e4b17023SJohn Marino if (GET_CODE (PATTERN (insn)) != SET) 1683*e4b17023SJohn Marino break; 1684*e4b17023SJohn Marino 1685*e4b17023SJohn Marino dest = SET_DEST (PATTERN (insn)); 1686*e4b17023SJohn Marino if (REG_P (dest) || CC0_P (dest)) 1687*e4b17023SJohn Marino setcc = insn; 1688*e4b17023SJohn Marino else 1689*e4b17023SJohn Marino break; 1690*e4b17023SJohn Marino } 1691*e4b17023SJohn Marino else if (JUMP_P (insn)) 1692*e4b17023SJohn Marino { 1693*e4b17023SJohn Marino if ((any_condjump_p (insn) || computed_jump_p (insn)) 1694*e4b17023SJohn Marino && onlyjump_p (insn)) 1695*e4b17023SJohn Marino changed |= bypass_block (bb, setcc, insn); 1696*e4b17023SJohn Marino break; 1697*e4b17023SJohn Marino } 1698*e4b17023SJohn Marino else if (INSN_P (insn)) 1699*e4b17023SJohn Marino break; 1700*e4b17023SJohn Marino } 1701*e4b17023SJohn Marino } 1702*e4b17023SJohn Marino 1703*e4b17023SJohn Marino /* If we bypassed any register setting insns, we inserted a 1704*e4b17023SJohn Marino copy on the redirected edge. These need to be committed. */ 1705*e4b17023SJohn Marino if (changed) 1706*e4b17023SJohn Marino commit_edge_insertions (); 1707*e4b17023SJohn Marino 1708*e4b17023SJohn Marino return changed; 1709*e4b17023SJohn Marino } 1710*e4b17023SJohn Marino 1711*e4b17023SJohn Marino /* Return true if the graph is too expensive to optimize. PASS is the 1712*e4b17023SJohn Marino optimization about to be performed. */ 1713*e4b17023SJohn Marino 1714*e4b17023SJohn Marino static bool 1715*e4b17023SJohn Marino is_too_expensive (const char *pass) 1716*e4b17023SJohn Marino { 1717*e4b17023SJohn Marino /* Trying to perform global optimizations on flow graphs which have 1718*e4b17023SJohn Marino a high connectivity will take a long time and is unlikely to be 1719*e4b17023SJohn Marino particularly useful. 1720*e4b17023SJohn Marino 1721*e4b17023SJohn Marino In normal circumstances a cfg should have about twice as many 1722*e4b17023SJohn Marino edges as blocks. But we do not want to punish small functions 1723*e4b17023SJohn Marino which have a couple switch statements. Rather than simply 1724*e4b17023SJohn Marino threshold the number of blocks, uses something with a more 1725*e4b17023SJohn Marino graceful degradation. */ 1726*e4b17023SJohn Marino if (n_edges > 20000 + n_basic_blocks * 4) 1727*e4b17023SJohn Marino { 1728*e4b17023SJohn Marino warning (OPT_Wdisabled_optimization, 1729*e4b17023SJohn Marino "%s: %d basic blocks and %d edges/basic block", 1730*e4b17023SJohn Marino pass, n_basic_blocks, n_edges / n_basic_blocks); 1731*e4b17023SJohn Marino 1732*e4b17023SJohn Marino return true; 1733*e4b17023SJohn Marino } 1734*e4b17023SJohn Marino 1735*e4b17023SJohn Marino /* If allocating memory for the cprop bitmap would take up too much 1736*e4b17023SJohn Marino storage it's better just to disable the optimization. */ 1737*e4b17023SJohn Marino if ((n_basic_blocks 1738*e4b17023SJohn Marino * SBITMAP_SET_SIZE (max_reg_num ()) 1739*e4b17023SJohn Marino * sizeof (SBITMAP_ELT_TYPE)) > MAX_GCSE_MEMORY) 1740*e4b17023SJohn Marino { 1741*e4b17023SJohn Marino warning (OPT_Wdisabled_optimization, 1742*e4b17023SJohn Marino "%s: %d basic blocks and %d registers", 1743*e4b17023SJohn Marino pass, n_basic_blocks, max_reg_num ()); 1744*e4b17023SJohn Marino 1745*e4b17023SJohn Marino return true; 1746*e4b17023SJohn Marino } 1747*e4b17023SJohn Marino 1748*e4b17023SJohn Marino return false; 1749*e4b17023SJohn Marino } 1750*e4b17023SJohn Marino 1751*e4b17023SJohn Marino /* Main function for the CPROP pass. */ 1752*e4b17023SJohn Marino 1753*e4b17023SJohn Marino static int 1754*e4b17023SJohn Marino one_cprop_pass (void) 1755*e4b17023SJohn Marino { 1756*e4b17023SJohn Marino int i; 1757*e4b17023SJohn Marino int changed = 0; 1758*e4b17023SJohn Marino 1759*e4b17023SJohn Marino /* Return if there's nothing to do, or it is too expensive. */ 1760*e4b17023SJohn Marino if (n_basic_blocks <= NUM_FIXED_BLOCKS + 1 1761*e4b17023SJohn Marino || is_too_expensive (_ ("const/copy propagation disabled"))) 1762*e4b17023SJohn Marino return 0; 1763*e4b17023SJohn Marino 1764*e4b17023SJohn Marino global_const_prop_count = local_const_prop_count = 0; 1765*e4b17023SJohn Marino global_copy_prop_count = local_copy_prop_count = 0; 1766*e4b17023SJohn Marino 1767*e4b17023SJohn Marino bytes_used = 0; 1768*e4b17023SJohn Marino gcc_obstack_init (&cprop_obstack); 1769*e4b17023SJohn Marino 1770*e4b17023SJohn Marino /* Do a local const/copy propagation pass first. The global pass 1771*e4b17023SJohn Marino only handles global opportunities. 1772*e4b17023SJohn Marino If the local pass changes something, remove any unreachable blocks 1773*e4b17023SJohn Marino because the CPROP global dataflow analysis may get into infinite 1774*e4b17023SJohn Marino loops for CFGs with unreachable blocks. 1775*e4b17023SJohn Marino 1776*e4b17023SJohn Marino FIXME: This local pass should not be necessary after CSE (but for 1777*e4b17023SJohn Marino some reason it still is). It is also (proven) not necessary 1778*e4b17023SJohn Marino to run the local pass right after FWPWOP. 1779*e4b17023SJohn Marino 1780*e4b17023SJohn Marino FIXME: The global analysis would not get into infinite loops if it 1781*e4b17023SJohn Marino would use the DF solver (via df_simple_dataflow) instead of 1782*e4b17023SJohn Marino the solver implemented in this file. */ 1783*e4b17023SJohn Marino changed |= local_cprop_pass (); 1784*e4b17023SJohn Marino if (changed) 1785*e4b17023SJohn Marino delete_unreachable_blocks (); 1786*e4b17023SJohn Marino 1787*e4b17023SJohn Marino /* Determine implicit sets. This may change the CFG (split critical 1788*e4b17023SJohn Marino edges if that exposes an implicit set). 1789*e4b17023SJohn Marino Note that find_implicit_sets() does not rely on up-to-date DF caches 1790*e4b17023SJohn Marino so that we do not have to re-run df_analyze() even if local CPROP 1791*e4b17023SJohn Marino changed something. 1792*e4b17023SJohn Marino ??? This could run earlier so that any uncovered implicit sets 1793*e4b17023SJohn Marino sets could be exploited in local_cprop_pass() also. Later. */ 1794*e4b17023SJohn Marino changed |= find_implicit_sets (); 1795*e4b17023SJohn Marino 1796*e4b17023SJohn Marino /* If local_cprop_pass() or find_implicit_sets() changed something, 1797*e4b17023SJohn Marino run df_analyze() to bring all insn caches up-to-date, and to take 1798*e4b17023SJohn Marino new basic blocks from edge splitting on the DF radar. 1799*e4b17023SJohn Marino NB: This also runs the fast DCE pass, because execute_rtl_cprop 1800*e4b17023SJohn Marino sets DF_LR_RUN_DCE. */ 1801*e4b17023SJohn Marino if (changed) 1802*e4b17023SJohn Marino df_analyze (); 1803*e4b17023SJohn Marino 1804*e4b17023SJohn Marino /* Initialize implicit_set_indexes array. */ 1805*e4b17023SJohn Marino implicit_set_indexes = XNEWVEC (int, last_basic_block); 1806*e4b17023SJohn Marino for (i = 0; i < last_basic_block; i++) 1807*e4b17023SJohn Marino implicit_set_indexes[i] = -1; 1808*e4b17023SJohn Marino 1809*e4b17023SJohn Marino alloc_hash_table (&set_hash_table); 1810*e4b17023SJohn Marino compute_hash_table (&set_hash_table); 1811*e4b17023SJohn Marino 1812*e4b17023SJohn Marino /* Free implicit_sets before peak usage. */ 1813*e4b17023SJohn Marino free (implicit_sets); 1814*e4b17023SJohn Marino implicit_sets = NULL; 1815*e4b17023SJohn Marino 1816*e4b17023SJohn Marino if (dump_file) 1817*e4b17023SJohn Marino dump_hash_table (dump_file, "SET", &set_hash_table); 1818*e4b17023SJohn Marino if (set_hash_table.n_elems > 0) 1819*e4b17023SJohn Marino { 1820*e4b17023SJohn Marino basic_block bb; 1821*e4b17023SJohn Marino rtx insn; 1822*e4b17023SJohn Marino 1823*e4b17023SJohn Marino alloc_cprop_mem (last_basic_block, set_hash_table.n_elems); 1824*e4b17023SJohn Marino compute_cprop_data (); 1825*e4b17023SJohn Marino 1826*e4b17023SJohn Marino free (implicit_set_indexes); 1827*e4b17023SJohn Marino implicit_set_indexes = NULL; 1828*e4b17023SJohn Marino 1829*e4b17023SJohn Marino /* Allocate vars to track sets of regs. */ 1830*e4b17023SJohn Marino reg_set_bitmap = ALLOC_REG_SET (NULL); 1831*e4b17023SJohn Marino 1832*e4b17023SJohn Marino FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb->next_bb, EXIT_BLOCK_PTR, 1833*e4b17023SJohn Marino next_bb) 1834*e4b17023SJohn Marino { 1835*e4b17023SJohn Marino /* Reset tables used to keep track of what's still valid [since 1836*e4b17023SJohn Marino the start of the block]. */ 1837*e4b17023SJohn Marino reset_opr_set_tables (); 1838*e4b17023SJohn Marino 1839*e4b17023SJohn Marino FOR_BB_INSNS (bb, insn) 1840*e4b17023SJohn Marino if (INSN_P (insn)) 1841*e4b17023SJohn Marino { 1842*e4b17023SJohn Marino changed |= cprop_insn (insn); 1843*e4b17023SJohn Marino 1844*e4b17023SJohn Marino /* Keep track of everything modified by this insn. */ 1845*e4b17023SJohn Marino /* ??? Need to be careful w.r.t. mods done to INSN. 1846*e4b17023SJohn Marino Don't call mark_oprs_set if we turned the 1847*e4b17023SJohn Marino insn into a NOTE, or deleted the insn. */ 1848*e4b17023SJohn Marino if (! NOTE_P (insn) && ! INSN_DELETED_P (insn)) 1849*e4b17023SJohn Marino mark_oprs_set (insn); 1850*e4b17023SJohn Marino } 1851*e4b17023SJohn Marino } 1852*e4b17023SJohn Marino 1853*e4b17023SJohn Marino changed |= bypass_conditional_jumps (); 1854*e4b17023SJohn Marino 1855*e4b17023SJohn Marino FREE_REG_SET (reg_set_bitmap); 1856*e4b17023SJohn Marino free_cprop_mem (); 1857*e4b17023SJohn Marino } 1858*e4b17023SJohn Marino else 1859*e4b17023SJohn Marino { 1860*e4b17023SJohn Marino free (implicit_set_indexes); 1861*e4b17023SJohn Marino implicit_set_indexes = NULL; 1862*e4b17023SJohn Marino } 1863*e4b17023SJohn Marino 1864*e4b17023SJohn Marino free_hash_table (&set_hash_table); 1865*e4b17023SJohn Marino obstack_free (&cprop_obstack, NULL); 1866*e4b17023SJohn Marino 1867*e4b17023SJohn Marino if (dump_file) 1868*e4b17023SJohn Marino { 1869*e4b17023SJohn Marino fprintf (dump_file, "CPROP of %s, %d basic blocks, %d bytes needed, ", 1870*e4b17023SJohn Marino current_function_name (), n_basic_blocks, bytes_used); 1871*e4b17023SJohn Marino fprintf (dump_file, "%d local const props, %d local copy props, ", 1872*e4b17023SJohn Marino local_const_prop_count, local_copy_prop_count); 1873*e4b17023SJohn Marino fprintf (dump_file, "%d global const props, %d global copy props\n\n", 1874*e4b17023SJohn Marino global_const_prop_count, global_copy_prop_count); 1875*e4b17023SJohn Marino } 1876*e4b17023SJohn Marino 1877*e4b17023SJohn Marino return changed; 1878*e4b17023SJohn Marino } 1879*e4b17023SJohn Marino 1880*e4b17023SJohn Marino /* All the passes implemented in this file. Each pass has its 1881*e4b17023SJohn Marino own gate and execute function, and at the end of the file a 1882*e4b17023SJohn Marino pass definition for passes.c. 1883*e4b17023SJohn Marino 1884*e4b17023SJohn Marino We do not construct an accurate cfg in functions which call 1885*e4b17023SJohn Marino setjmp, so none of these passes runs if the function calls 1886*e4b17023SJohn Marino setjmp. 1887*e4b17023SJohn Marino FIXME: Should just handle setjmp via REG_SETJMP notes. */ 1888*e4b17023SJohn Marino 1889*e4b17023SJohn Marino static bool 1890*e4b17023SJohn Marino gate_rtl_cprop (void) 1891*e4b17023SJohn Marino { 1892*e4b17023SJohn Marino return optimize > 0 && flag_gcse 1893*e4b17023SJohn Marino && !cfun->calls_setjmp 1894*e4b17023SJohn Marino && dbg_cnt (cprop); 1895*e4b17023SJohn Marino } 1896*e4b17023SJohn Marino 1897*e4b17023SJohn Marino static unsigned int 1898*e4b17023SJohn Marino execute_rtl_cprop (void) 1899*e4b17023SJohn Marino { 1900*e4b17023SJohn Marino int changed; 1901*e4b17023SJohn Marino delete_unreachable_blocks (); 1902*e4b17023SJohn Marino df_set_flags (DF_LR_RUN_DCE); 1903*e4b17023SJohn Marino df_analyze (); 1904*e4b17023SJohn Marino changed = one_cprop_pass (); 1905*e4b17023SJohn Marino flag_rerun_cse_after_global_opts |= changed; 1906*e4b17023SJohn Marino if (changed) 1907*e4b17023SJohn Marino cleanup_cfg (0); 1908*e4b17023SJohn Marino return 0; 1909*e4b17023SJohn Marino } 1910*e4b17023SJohn Marino 1911*e4b17023SJohn Marino struct rtl_opt_pass pass_rtl_cprop = 1912*e4b17023SJohn Marino { 1913*e4b17023SJohn Marino { 1914*e4b17023SJohn Marino RTL_PASS, 1915*e4b17023SJohn Marino "cprop", /* name */ 1916*e4b17023SJohn Marino gate_rtl_cprop, /* gate */ 1917*e4b17023SJohn Marino execute_rtl_cprop, /* execute */ 1918*e4b17023SJohn Marino NULL, /* sub */ 1919*e4b17023SJohn Marino NULL, /* next */ 1920*e4b17023SJohn Marino 0, /* static_pass_number */ 1921*e4b17023SJohn Marino TV_CPROP, /* tv_id */ 1922*e4b17023SJohn Marino PROP_cfglayout, /* properties_required */ 1923*e4b17023SJohn Marino 0, /* properties_provided */ 1924*e4b17023SJohn Marino 0, /* properties_destroyed */ 1925*e4b17023SJohn Marino 0, /* todo_flags_start */ 1926*e4b17023SJohn Marino TODO_df_finish | TODO_verify_rtl_sharing | 1927*e4b17023SJohn Marino TODO_verify_flow | TODO_ggc_collect /* todo_flags_finish */ 1928*e4b17023SJohn Marino } 1929*e4b17023SJohn Marino }; 1930