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