1 /* Variable tracking routines for the GNU compiler.
2    Copyright (C) 2002-2018 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
7    under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10 
11    GCC is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License 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 /* This file contains the variable tracking pass.  It computes where
21    variables are located (which registers or where in memory) at each position
22    in instruction stream and emits notes describing the locations.
23    Debug information (DWARF2 location lists) is finally generated from
24    these notes.
25    With this debug information, it is possible to show variables
26    even when debugging optimized code.
27 
28    How does the variable tracking pass work?
29 
30    First, it scans RTL code for uses, stores and clobbers (register/memory
31    references in instructions), for call insns and for stack adjustments
32    separately for each basic block and saves them to an array of micro
33    operations.
34    The micro operations of one instruction are ordered so that
35    pre-modifying stack adjustment < use < use with no var < call insn <
36      < clobber < set < post-modifying stack adjustment
37 
38    Then, a forward dataflow analysis is performed to find out how locations
39    of variables change through code and to propagate the variable locations
40    along control flow graph.
41    The IN set for basic block BB is computed as a union of OUT sets of BB's
42    predecessors, the OUT set for BB is copied from the IN set for BB and
43    is changed according to micro operations in BB.
44 
45    The IN and OUT sets for basic blocks consist of a current stack adjustment
46    (used for adjusting offset of variables addressed using stack pointer),
47    the table of structures describing the locations of parts of a variable
48    and for each physical register a linked list for each physical register.
49    The linked list is a list of variable parts stored in the register,
50    i.e. it is a list of triplets (reg, decl, offset) where decl is
51    REG_EXPR (reg) and offset is REG_OFFSET (reg).  The linked list is used for
52    effective deleting appropriate variable parts when we set or clobber the
53    register.
54 
55    There may be more than one variable part in a register.  The linked lists
56    should be pretty short so it is a good data structure here.
57    For example in the following code, register allocator may assign same
58    register to variables A and B, and both of them are stored in the same
59    register in CODE:
60 
61      if (cond)
62        set A;
63      else
64        set B;
65      CODE;
66      if (cond)
67        use A;
68      else
69        use B;
70 
71    Finally, the NOTE_INSN_VAR_LOCATION notes describing the variable locations
72    are emitted to appropriate positions in RTL code.  Each such a note describes
73    the location of one variable at the point in instruction stream where the
74    note is.  There is no need to emit a note for each variable before each
75    instruction, we only emit these notes where the location of variable changes
76    (this means that we also emit notes for changes between the OUT set of the
77    previous block and the IN set of the current block).
78 
79    The notes consist of two parts:
80    1. the declaration (from REG_EXPR or MEM_EXPR)
81    2. the location of a variable - it is either a simple register/memory
82       reference (for simple variables, for example int),
83       or a parallel of register/memory references (for a large variables
84       which consist of several parts, for example long long).
85 
86 */
87 
88 #include "config.h"
89 #include "system.h"
90 #include "coretypes.h"
91 #include "backend.h"
92 #include "target.h"
93 #include "rtl.h"
94 #include "tree.h"
95 #include "cfghooks.h"
96 #include "alloc-pool.h"
97 #include "tree-pass.h"
98 #include "memmodel.h"
99 #include "tm_p.h"
100 #include "insn-config.h"
101 #include "regs.h"
102 #include "emit-rtl.h"
103 #include "recog.h"
104 #include "diagnostic.h"
105 #include "varasm.h"
106 #include "stor-layout.h"
107 #include "cfgrtl.h"
108 #include "cfganal.h"
109 #include "reload.h"
110 #include "calls.h"
111 #include "tree-dfa.h"
112 #include "tree-ssa.h"
113 #include "cselib.h"
114 #include "params.h"
115 #include "tree-pretty-print.h"
116 #include "rtl-iter.h"
117 #include "fibonacci_heap.h"
118 
119 typedef fibonacci_heap <long, basic_block_def> bb_heap_t;
120 typedef fibonacci_node <long, basic_block_def> bb_heap_node_t;
121 
122 /* var-tracking.c assumes that tree code with the same value as VALUE rtx code
123    has no chance to appear in REG_EXPR/MEM_EXPRs and isn't a decl.
124    Currently the value is the same as IDENTIFIER_NODE, which has such
125    a property.  If this compile time assertion ever fails, make sure that
126    the new tree code that equals (int) VALUE has the same property.  */
127 extern char check_value_val[(int) VALUE == (int) IDENTIFIER_NODE ? 1 : -1];
128 
129 /* Type of micro operation.  */
130 enum micro_operation_type
131 {
132   MO_USE,	/* Use location (REG or MEM).  */
133   MO_USE_NO_VAR,/* Use location which is not associated with a variable
134 		   or the variable is not trackable.  */
135   MO_VAL_USE,	/* Use location which is associated with a value.  */
136   MO_VAL_LOC,   /* Use location which appears in a debug insn.  */
137   MO_VAL_SET,	/* Set location associated with a value.  */
138   MO_SET,	/* Set location.  */
139   MO_COPY,	/* Copy the same portion of a variable from one
140 		   location to another.  */
141   MO_CLOBBER,	/* Clobber location.  */
142   MO_CALL,	/* Call insn.  */
143   MO_ADJUST	/* Adjust stack pointer.  */
144 
145 };
146 
147 static const char * const ATTRIBUTE_UNUSED
148 micro_operation_type_name[] = {
149   "MO_USE",
150   "MO_USE_NO_VAR",
151   "MO_VAL_USE",
152   "MO_VAL_LOC",
153   "MO_VAL_SET",
154   "MO_SET",
155   "MO_COPY",
156   "MO_CLOBBER",
157   "MO_CALL",
158   "MO_ADJUST"
159 };
160 
161 /* Where shall the note be emitted?  BEFORE or AFTER the instruction.
162    Notes emitted as AFTER_CALL are to take effect during the call,
163    rather than after the call.  */
164 enum emit_note_where
165 {
166   EMIT_NOTE_BEFORE_INSN,
167   EMIT_NOTE_AFTER_INSN,
168   EMIT_NOTE_AFTER_CALL_INSN
169 };
170 
171 /* Structure holding information about micro operation.  */
172 struct micro_operation
173 {
174   /* Type of micro operation.  */
175   enum micro_operation_type type;
176 
177   /* The instruction which the micro operation is in, for MO_USE,
178      MO_USE_NO_VAR, MO_CALL and MO_ADJUST, or the subsequent
179      instruction or note in the original flow (before any var-tracking
180      notes are inserted, to simplify emission of notes), for MO_SET
181      and MO_CLOBBER.  */
182   rtx_insn *insn;
183 
184   union {
185     /* Location.  For MO_SET and MO_COPY, this is the SET that
186        performs the assignment, if known, otherwise it is the target
187        of the assignment.  For MO_VAL_USE and MO_VAL_SET, it is a
188        CONCAT of the VALUE and the LOC associated with it.  For
189        MO_VAL_LOC, it is a CONCAT of the VALUE and the VAR_LOCATION
190        associated with it.  */
191     rtx loc;
192 
193     /* Stack adjustment.  */
194     HOST_WIDE_INT adjust;
195   } u;
196 };
197 
198 
199 /* A declaration of a variable, or an RTL value being handled like a
200    declaration.  */
201 typedef void *decl_or_value;
202 
203 /* Return true if a decl_or_value DV is a DECL or NULL.  */
204 static inline bool
205 dv_is_decl_p (decl_or_value dv)
206 {
207   return !dv || (int) TREE_CODE ((tree) dv) != (int) VALUE;
208 }
209 
210 /* Return true if a decl_or_value is a VALUE rtl.  */
211 static inline bool
212 dv_is_value_p (decl_or_value dv)
213 {
214   return dv && !dv_is_decl_p (dv);
215 }
216 
217 /* Return the decl in the decl_or_value.  */
218 static inline tree
219 dv_as_decl (decl_or_value dv)
220 {
221   gcc_checking_assert (dv_is_decl_p (dv));
222   return (tree) dv;
223 }
224 
225 /* Return the value in the decl_or_value.  */
226 static inline rtx
227 dv_as_value (decl_or_value dv)
228 {
229   gcc_checking_assert (dv_is_value_p (dv));
230   return (rtx)dv;
231 }
232 
233 /* Return the opaque pointer in the decl_or_value.  */
234 static inline void *
235 dv_as_opaque (decl_or_value dv)
236 {
237   return dv;
238 }
239 
240 
241 /* Description of location of a part of a variable.  The content of a physical
242    register is described by a chain of these structures.
243    The chains are pretty short (usually 1 or 2 elements) and thus
244    chain is the best data structure.  */
245 struct attrs
246 {
247   /* Pointer to next member of the list.  */
248   attrs *next;
249 
250   /* The rtx of register.  */
251   rtx loc;
252 
253   /* The declaration corresponding to LOC.  */
254   decl_or_value dv;
255 
256   /* Offset from start of DECL.  */
257   HOST_WIDE_INT offset;
258 };
259 
260 /* Structure for chaining the locations.  */
261 struct location_chain
262 {
263   /* Next element in the chain.  */
264   location_chain *next;
265 
266   /* The location (REG, MEM or VALUE).  */
267   rtx loc;
268 
269   /* The "value" stored in this location.  */
270   rtx set_src;
271 
272   /* Initialized? */
273   enum var_init_status init;
274 };
275 
276 /* A vector of loc_exp_dep holds the active dependencies of a one-part
277    DV on VALUEs, i.e., the VALUEs expanded so as to form the current
278    location of DV.  Each entry is also part of VALUE' s linked-list of
279    backlinks back to DV.  */
280 struct loc_exp_dep
281 {
282   /* The dependent DV.  */
283   decl_or_value dv;
284   /* The dependency VALUE or DECL_DEBUG.  */
285   rtx value;
286   /* The next entry in VALUE's backlinks list.  */
287   struct loc_exp_dep *next;
288   /* A pointer to the pointer to this entry (head or prev's next) in
289      the doubly-linked list.  */
290   struct loc_exp_dep **pprev;
291 };
292 
293 
294 /* This data structure holds information about the depth of a variable
295    expansion.  */
296 struct expand_depth
297 {
298   /* This measures the complexity of the expanded expression.  It
299      grows by one for each level of expansion that adds more than one
300      operand.  */
301   int complexity;
302   /* This counts the number of ENTRY_VALUE expressions in an
303      expansion.  We want to minimize their use.  */
304   int entryvals;
305 };
306 
307 /* This data structure is allocated for one-part variables at the time
308    of emitting notes.  */
309 struct onepart_aux
310 {
311   /* Doubly-linked list of dependent DVs.  These are DVs whose cur_loc
312      computation used the expansion of this variable, and that ought
313      to be notified should this variable change.  If the DV's cur_loc
314      expanded to NULL, all components of the loc list are regarded as
315      active, so that any changes in them give us a chance to get a
316      location.  Otherwise, only components of the loc that expanded to
317      non-NULL are regarded as active dependencies.  */
318   loc_exp_dep *backlinks;
319   /* This holds the LOC that was expanded into cur_loc.  We need only
320      mark a one-part variable as changed if the FROM loc is removed,
321      or if it has no known location and a loc is added, or if it gets
322      a change notification from any of its active dependencies.  */
323   rtx from;
324   /* The depth of the cur_loc expression.  */
325   expand_depth depth;
326   /* Dependencies actively used when expand FROM into cur_loc.  */
327   vec<loc_exp_dep, va_heap, vl_embed> deps;
328 };
329 
330 /* Structure describing one part of variable.  */
331 struct variable_part
332 {
333   /* Chain of locations of the part.  */
334   location_chain *loc_chain;
335 
336   /* Location which was last emitted to location list.  */
337   rtx cur_loc;
338 
339   union variable_aux
340   {
341     /* The offset in the variable, if !var->onepart.  */
342     HOST_WIDE_INT offset;
343 
344     /* Pointer to auxiliary data, if var->onepart and emit_notes.  */
345     struct onepart_aux *onepaux;
346   } aux;
347 };
348 
349 /* Maximum number of location parts.  */
350 #define MAX_VAR_PARTS 16
351 
352 /* Enumeration type used to discriminate various types of one-part
353    variables.  */
354 enum onepart_enum
355 {
356   /* Not a one-part variable.  */
357   NOT_ONEPART = 0,
358   /* A one-part DECL that is not a DEBUG_EXPR_DECL.  */
359   ONEPART_VDECL = 1,
360   /* A DEBUG_EXPR_DECL.  */
361   ONEPART_DEXPR = 2,
362   /* A VALUE.  */
363   ONEPART_VALUE = 3
364 };
365 
366 /* Structure describing where the variable is located.  */
367 struct variable
368 {
369   /* The declaration of the variable, or an RTL value being handled
370      like a declaration.  */
371   decl_or_value dv;
372 
373   /* Reference count.  */
374   int refcount;
375 
376   /* Number of variable parts.  */
377   char n_var_parts;
378 
379   /* What type of DV this is, according to enum onepart_enum.  */
380   ENUM_BITFIELD (onepart_enum) onepart : CHAR_BIT;
381 
382   /* True if this variable_def struct is currently in the
383      changed_variables hash table.  */
384   bool in_changed_variables;
385 
386   /* The variable parts.  */
387   variable_part var_part[1];
388 };
389 
390 /* Pointer to the BB's information specific to variable tracking pass.  */
391 #define VTI(BB) ((variable_tracking_info *) (BB)->aux)
392 
393 /* Return MEM_OFFSET (MEM) as a HOST_WIDE_INT, or 0 if we can't.  */
394 
395 static inline HOST_WIDE_INT
396 int_mem_offset (const_rtx mem)
397 {
398   HOST_WIDE_INT offset;
399   if (MEM_OFFSET_KNOWN_P (mem) && MEM_OFFSET (mem).is_constant (&offset))
400     return offset;
401   return 0;
402 }
403 
404 #if CHECKING_P && (GCC_VERSION >= 2007)
405 
406 /* Access VAR's Ith part's offset, checking that it's not a one-part
407    variable.  */
408 #define VAR_PART_OFFSET(var, i) __extension__			\
409 (*({  variable *const __v = (var);				\
410       gcc_checking_assert (!__v->onepart);			\
411       &__v->var_part[(i)].aux.offset; }))
412 
413 /* Access VAR's one-part auxiliary data, checking that it is a
414    one-part variable.  */
415 #define VAR_LOC_1PAUX(var) __extension__			\
416 (*({  variable *const __v = (var);				\
417       gcc_checking_assert (__v->onepart);			\
418       &__v->var_part[0].aux.onepaux; }))
419 
420 #else
421 #define VAR_PART_OFFSET(var, i) ((var)->var_part[(i)].aux.offset)
422 #define VAR_LOC_1PAUX(var) ((var)->var_part[0].aux.onepaux)
423 #endif
424 
425 /* These are accessor macros for the one-part auxiliary data.  When
426    convenient for users, they're guarded by tests that the data was
427    allocated.  */
428 #define VAR_LOC_DEP_LST(var) (VAR_LOC_1PAUX (var)		  \
429 			      ? VAR_LOC_1PAUX (var)->backlinks	  \
430 			      : NULL)
431 #define VAR_LOC_DEP_LSTP(var) (VAR_LOC_1PAUX (var)		  \
432 			       ? &VAR_LOC_1PAUX (var)->backlinks  \
433 			       : NULL)
434 #define VAR_LOC_FROM(var) (VAR_LOC_1PAUX (var)->from)
435 #define VAR_LOC_DEPTH(var) (VAR_LOC_1PAUX (var)->depth)
436 #define VAR_LOC_DEP_VEC(var) (VAR_LOC_1PAUX (var)		  \
437 			      ? &VAR_LOC_1PAUX (var)->deps	  \
438 			      : NULL)
439 
440 
441 
442 typedef unsigned int dvuid;
443 
444 /* Return the uid of DV.  */
445 
446 static inline dvuid
447 dv_uid (decl_or_value dv)
448 {
449   if (dv_is_value_p (dv))
450     return CSELIB_VAL_PTR (dv_as_value (dv))->uid;
451   else
452     return DECL_UID (dv_as_decl (dv));
453 }
454 
455 /* Compute the hash from the uid.  */
456 
457 static inline hashval_t
458 dv_uid2hash (dvuid uid)
459 {
460   return uid;
461 }
462 
463 /* The hash function for a mask table in a shared_htab chain.  */
464 
465 static inline hashval_t
466 dv_htab_hash (decl_or_value dv)
467 {
468   return dv_uid2hash (dv_uid (dv));
469 }
470 
471 static void variable_htab_free (void *);
472 
473 /* Variable hashtable helpers.  */
474 
475 struct variable_hasher : pointer_hash <variable>
476 {
477   typedef void *compare_type;
478   static inline hashval_t hash (const variable *);
479   static inline bool equal (const variable *, const void *);
480   static inline void remove (variable *);
481 };
482 
483 /* The hash function for variable_htab, computes the hash value
484    from the declaration of variable X.  */
485 
486 inline hashval_t
487 variable_hasher::hash (const variable *v)
488 {
489   return dv_htab_hash (v->dv);
490 }
491 
492 /* Compare the declaration of variable X with declaration Y.  */
493 
494 inline bool
495 variable_hasher::equal (const variable *v, const void *y)
496 {
497   decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y);
498 
499   return (dv_as_opaque (v->dv) == dv_as_opaque (dv));
500 }
501 
502 /* Free the element of VARIABLE_HTAB (its type is struct variable_def).  */
503 
504 inline void
505 variable_hasher::remove (variable *var)
506 {
507   variable_htab_free (var);
508 }
509 
510 typedef hash_table<variable_hasher> variable_table_type;
511 typedef variable_table_type::iterator variable_iterator_type;
512 
513 /* Structure for passing some other parameters to function
514    emit_note_insn_var_location.  */
515 struct emit_note_data
516 {
517   /* The instruction which the note will be emitted before/after.  */
518   rtx_insn *insn;
519 
520   /* Where the note will be emitted (before/after insn)?  */
521   enum emit_note_where where;
522 
523   /* The variables and values active at this point.  */
524   variable_table_type *vars;
525 };
526 
527 /* Structure holding a refcounted hash table.  If refcount > 1,
528    it must be first unshared before modified.  */
529 struct shared_hash
530 {
531   /* Reference count.  */
532   int refcount;
533 
534   /* Actual hash table.  */
535   variable_table_type *htab;
536 };
537 
538 /* Structure holding the IN or OUT set for a basic block.  */
539 struct dataflow_set
540 {
541   /* Adjustment of stack offset.  */
542   HOST_WIDE_INT stack_adjust;
543 
544   /* Attributes for registers (lists of attrs).  */
545   attrs *regs[FIRST_PSEUDO_REGISTER];
546 
547   /* Variable locations.  */
548   shared_hash *vars;
549 
550   /* Vars that is being traversed.  */
551   shared_hash *traversed_vars;
552 };
553 
554 /* The structure (one for each basic block) containing the information
555    needed for variable tracking.  */
556 struct variable_tracking_info
557 {
558   /* The vector of micro operations.  */
559   vec<micro_operation> mos;
560 
561   /* The IN and OUT set for dataflow analysis.  */
562   dataflow_set in;
563   dataflow_set out;
564 
565   /* The permanent-in dataflow set for this block.  This is used to
566      hold values for which we had to compute entry values.  ??? This
567      should probably be dynamically allocated, to avoid using more
568      memory in non-debug builds.  */
569   dataflow_set *permp;
570 
571   /* Has the block been visited in DFS?  */
572   bool visited;
573 
574   /* Has the block been flooded in VTA?  */
575   bool flooded;
576 
577 };
578 
579 /* Alloc pool for struct attrs_def.  */
580 object_allocator<attrs> attrs_pool ("attrs pool");
581 
582 /* Alloc pool for struct variable_def with MAX_VAR_PARTS entries.  */
583 
584 static pool_allocator var_pool
585   ("variable_def pool", sizeof (variable) +
586    (MAX_VAR_PARTS - 1) * sizeof (((variable *)NULL)->var_part[0]));
587 
588 /* Alloc pool for struct variable_def with a single var_part entry.  */
589 static pool_allocator valvar_pool
590   ("small variable_def pool", sizeof (variable));
591 
592 /* Alloc pool for struct location_chain.  */
593 static object_allocator<location_chain> location_chain_pool
594   ("location_chain pool");
595 
596 /* Alloc pool for struct shared_hash.  */
597 static object_allocator<shared_hash> shared_hash_pool ("shared_hash pool");
598 
599 /* Alloc pool for struct loc_exp_dep_s for NOT_ONEPART variables.  */
600 object_allocator<loc_exp_dep> loc_exp_dep_pool ("loc_exp_dep pool");
601 
602 /* Changed variables, notes will be emitted for them.  */
603 static variable_table_type *changed_variables;
604 
605 /* Shall notes be emitted?  */
606 static bool emit_notes;
607 
608 /* Values whose dynamic location lists have gone empty, but whose
609    cselib location lists are still usable.  Use this to hold the
610    current location, the backlinks, etc, during emit_notes.  */
611 static variable_table_type *dropped_values;
612 
613 /* Empty shared hashtable.  */
614 static shared_hash *empty_shared_hash;
615 
616 /* Scratch register bitmap used by cselib_expand_value_rtx.  */
617 static bitmap scratch_regs = NULL;
618 
619 #ifdef HAVE_window_save
620 struct GTY(()) parm_reg {
621   rtx outgoing;
622   rtx incoming;
623 };
624 
625 
626 /* Vector of windowed parameter registers, if any.  */
627 static vec<parm_reg, va_gc> *windowed_parm_regs = NULL;
628 #endif
629 
630 /* Variable used to tell whether cselib_process_insn called our hook.  */
631 static bool cselib_hook_called;
632 
633 /* Local function prototypes.  */
634 static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
635 					  HOST_WIDE_INT *);
636 static void insn_stack_adjust_offset_pre_post (rtx_insn *, HOST_WIDE_INT *,
637 					       HOST_WIDE_INT *);
638 static bool vt_stack_adjustments (void);
639 
640 static void init_attrs_list_set (attrs **);
641 static void attrs_list_clear (attrs **);
642 static attrs *attrs_list_member (attrs *, decl_or_value, HOST_WIDE_INT);
643 static void attrs_list_insert (attrs **, decl_or_value, HOST_WIDE_INT, rtx);
644 static void attrs_list_copy (attrs **, attrs *);
645 static void attrs_list_union (attrs **, attrs *);
646 
647 static variable **unshare_variable (dataflow_set *set, variable **slot,
648 					variable *var, enum var_init_status);
649 static void vars_copy (variable_table_type *, variable_table_type *);
650 static tree var_debug_decl (tree);
651 static void var_reg_set (dataflow_set *, rtx, enum var_init_status, rtx);
652 static void var_reg_delete_and_set (dataflow_set *, rtx, bool,
653 				    enum var_init_status, rtx);
654 static void var_reg_delete (dataflow_set *, rtx, bool);
655 static void var_regno_delete (dataflow_set *, int);
656 static void var_mem_set (dataflow_set *, rtx, enum var_init_status, rtx);
657 static void var_mem_delete_and_set (dataflow_set *, rtx, bool,
658 				    enum var_init_status, rtx);
659 static void var_mem_delete (dataflow_set *, rtx, bool);
660 
661 static void dataflow_set_init (dataflow_set *);
662 static void dataflow_set_clear (dataflow_set *);
663 static void dataflow_set_copy (dataflow_set *, dataflow_set *);
664 static int variable_union_info_cmp_pos (const void *, const void *);
665 static void dataflow_set_union (dataflow_set *, dataflow_set *);
666 static location_chain *find_loc_in_1pdv (rtx, variable *,
667 					 variable_table_type *);
668 static bool canon_value_cmp (rtx, rtx);
669 static int loc_cmp (rtx, rtx);
670 static bool variable_part_different_p (variable_part *, variable_part *);
671 static bool onepart_variable_different_p (variable *, variable *);
672 static bool variable_different_p (variable *, variable *);
673 static bool dataflow_set_different (dataflow_set *, dataflow_set *);
674 static void dataflow_set_destroy (dataflow_set *);
675 
676 static bool track_expr_p (tree, bool);
677 static void add_uses_1 (rtx *, void *);
678 static void add_stores (rtx, const_rtx, void *);
679 static bool compute_bb_dataflow (basic_block);
680 static bool vt_find_locations (void);
681 
682 static void dump_attrs_list (attrs *);
683 static void dump_var (variable *);
684 static void dump_vars (variable_table_type *);
685 static void dump_dataflow_set (dataflow_set *);
686 static void dump_dataflow_sets (void);
687 
688 static void set_dv_changed (decl_or_value, bool);
689 static void variable_was_changed (variable *, dataflow_set *);
690 static variable **set_slot_part (dataflow_set *, rtx, variable **,
691 				 decl_or_value, HOST_WIDE_INT,
692 				 enum var_init_status, rtx);
693 static void set_variable_part (dataflow_set *, rtx,
694 			       decl_or_value, HOST_WIDE_INT,
695 			       enum var_init_status, rtx, enum insert_option);
696 static variable **clobber_slot_part (dataflow_set *, rtx,
697 				     variable **, HOST_WIDE_INT, rtx);
698 static void clobber_variable_part (dataflow_set *, rtx,
699 				   decl_or_value, HOST_WIDE_INT, rtx);
700 static variable **delete_slot_part (dataflow_set *, rtx, variable **,
701 				    HOST_WIDE_INT);
702 static void delete_variable_part (dataflow_set *, rtx,
703 				  decl_or_value, HOST_WIDE_INT);
704 static void emit_notes_in_bb (basic_block, dataflow_set *);
705 static void vt_emit_notes (void);
706 
707 static void vt_add_function_parameters (void);
708 static bool vt_initialize (void);
709 static void vt_finalize (void);
710 
711 /* Callback for stack_adjust_offset_pre_post, called via for_each_inc_dec.  */
712 
713 static int
714 stack_adjust_offset_pre_post_cb (rtx, rtx op, rtx dest, rtx src, rtx srcoff,
715 				 void *arg)
716 {
717   if (dest != stack_pointer_rtx)
718     return 0;
719 
720   switch (GET_CODE (op))
721     {
722     case PRE_INC:
723     case PRE_DEC:
724       ((HOST_WIDE_INT *)arg)[0] -= INTVAL (srcoff);
725       return 0;
726     case POST_INC:
727     case POST_DEC:
728       ((HOST_WIDE_INT *)arg)[1] -= INTVAL (srcoff);
729       return 0;
730     case PRE_MODIFY:
731     case POST_MODIFY:
732       /* We handle only adjustments by constant amount.  */
733       gcc_assert (GET_CODE (src) == PLUS
734 		  && CONST_INT_P (XEXP (src, 1))
735 		  && XEXP (src, 0) == stack_pointer_rtx);
736       ((HOST_WIDE_INT *)arg)[GET_CODE (op) == POST_MODIFY]
737 	-= INTVAL (XEXP (src, 1));
738       return 0;
739     default:
740       gcc_unreachable ();
741     }
742 }
743 
744 /* Given a SET, calculate the amount of stack adjustment it contains
745    PRE- and POST-modifying stack pointer.
746    This function is similar to stack_adjust_offset.  */
747 
748 static void
749 stack_adjust_offset_pre_post (rtx pattern, HOST_WIDE_INT *pre,
750 			      HOST_WIDE_INT *post)
751 {
752   rtx src = SET_SRC (pattern);
753   rtx dest = SET_DEST (pattern);
754   enum rtx_code code;
755 
756   if (dest == stack_pointer_rtx)
757     {
758       /* (set (reg sp) (plus (reg sp) (const_int))) */
759       code = GET_CODE (src);
760       if (! (code == PLUS || code == MINUS)
761 	  || XEXP (src, 0) != stack_pointer_rtx
762 	  || !CONST_INT_P (XEXP (src, 1)))
763 	return;
764 
765       if (code == MINUS)
766 	*post += INTVAL (XEXP (src, 1));
767       else
768 	*post -= INTVAL (XEXP (src, 1));
769       return;
770     }
771   HOST_WIDE_INT res[2] = { 0, 0 };
772   for_each_inc_dec (pattern, stack_adjust_offset_pre_post_cb, res);
773   *pre += res[0];
774   *post += res[1];
775 }
776 
777 /* Given an INSN, calculate the amount of stack adjustment it contains
778    PRE- and POST-modifying stack pointer.  */
779 
780 static void
781 insn_stack_adjust_offset_pre_post (rtx_insn *insn, HOST_WIDE_INT *pre,
782 				   HOST_WIDE_INT *post)
783 {
784   rtx pattern;
785 
786   *pre = 0;
787   *post = 0;
788 
789   pattern = PATTERN (insn);
790   if (RTX_FRAME_RELATED_P (insn))
791     {
792       rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
793       if (expr)
794 	pattern = XEXP (expr, 0);
795     }
796 
797   if (GET_CODE (pattern) == SET)
798     stack_adjust_offset_pre_post (pattern, pre, post);
799   else if (GET_CODE (pattern) == PARALLEL
800 	   || GET_CODE (pattern) == SEQUENCE)
801     {
802       int i;
803 
804       /* There may be stack adjustments inside compound insns.  Search
805 	 for them.  */
806       for ( i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
807 	if (GET_CODE (XVECEXP (pattern, 0, i)) == SET)
808 	  stack_adjust_offset_pre_post (XVECEXP (pattern, 0, i), pre, post);
809     }
810 }
811 
812 /* Compute stack adjustments for all blocks by traversing DFS tree.
813    Return true when the adjustments on all incoming edges are consistent.
814    Heavily borrowed from pre_and_rev_post_order_compute.  */
815 
816 static bool
817 vt_stack_adjustments (void)
818 {
819   edge_iterator *stack;
820   int sp;
821 
822   /* Initialize entry block.  */
823   VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->visited = true;
824   VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->in.stack_adjust
825     = INCOMING_FRAME_SP_OFFSET;
826   VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->out.stack_adjust
827     = INCOMING_FRAME_SP_OFFSET;
828 
829   /* Allocate stack for back-tracking up CFG.  */
830   stack = XNEWVEC (edge_iterator, n_basic_blocks_for_fn (cfun) + 1);
831   sp = 0;
832 
833   /* Push the first edge on to the stack.  */
834   stack[sp++] = ei_start (ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs);
835 
836   while (sp)
837     {
838       edge_iterator ei;
839       basic_block src;
840       basic_block dest;
841 
842       /* Look at the edge on the top of the stack.  */
843       ei = stack[sp - 1];
844       src = ei_edge (ei)->src;
845       dest = ei_edge (ei)->dest;
846 
847       /* Check if the edge destination has been visited yet.  */
848       if (!VTI (dest)->visited)
849 	{
850 	  rtx_insn *insn;
851 	  HOST_WIDE_INT pre, post, offset;
852 	  VTI (dest)->visited = true;
853 	  VTI (dest)->in.stack_adjust = offset = VTI (src)->out.stack_adjust;
854 
855 	  if (dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
856 	    for (insn = BB_HEAD (dest);
857 		 insn != NEXT_INSN (BB_END (dest));
858 		 insn = NEXT_INSN (insn))
859 	      if (INSN_P (insn))
860 		{
861 		  insn_stack_adjust_offset_pre_post (insn, &pre, &post);
862 		  offset += pre + post;
863 		}
864 
865 	  VTI (dest)->out.stack_adjust = offset;
866 
867 	  if (EDGE_COUNT (dest->succs) > 0)
868 	    /* Since the DEST node has been visited for the first
869 	       time, check its successors.  */
870 	    stack[sp++] = ei_start (dest->succs);
871 	}
872       else
873 	{
874 	  /* We can end up with different stack adjustments for the exit block
875 	     of a shrink-wrapped function if stack_adjust_offset_pre_post
876 	     doesn't understand the rtx pattern used to restore the stack
877 	     pointer in the epilogue.  For example, on s390(x), the stack
878 	     pointer is often restored via a load-multiple instruction
879 	     and so no stack_adjust offset is recorded for it.  This means
880 	     that the stack offset at the end of the epilogue block is the
881 	     same as the offset before the epilogue, whereas other paths
882 	     to the exit block will have the correct stack_adjust.
883 
884 	     It is safe to ignore these differences because (a) we never
885 	     use the stack_adjust for the exit block in this pass and
886 	     (b) dwarf2cfi checks whether the CFA notes in a shrink-wrapped
887 	     function are correct.
888 
889 	     We must check whether the adjustments on other edges are
890 	     the same though.  */
891 	  if (dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
892 	      && VTI (dest)->in.stack_adjust != VTI (src)->out.stack_adjust)
893 	    {
894 	      free (stack);
895 	      return false;
896 	    }
897 
898 	  if (! ei_one_before_end_p (ei))
899 	    /* Go to the next edge.  */
900 	    ei_next (&stack[sp - 1]);
901 	  else
902 	    /* Return to previous level if there are no more edges.  */
903 	    sp--;
904 	}
905     }
906 
907   free (stack);
908   return true;
909 }
910 
911 /* arg_pointer_rtx resp. frame_pointer_rtx if stack_pointer_rtx or
912    hard_frame_pointer_rtx is being mapped to it and offset for it.  */
913 static rtx cfa_base_rtx;
914 static HOST_WIDE_INT cfa_base_offset;
915 
916 /* Compute a CFA-based value for an ADJUSTMENT made to stack_pointer_rtx
917    or hard_frame_pointer_rtx.  */
918 
919 static inline rtx
920 compute_cfa_pointer (HOST_WIDE_INT adjustment)
921 {
922   return plus_constant (Pmode, cfa_base_rtx, adjustment + cfa_base_offset);
923 }
924 
925 /* Adjustment for hard_frame_pointer_rtx to cfa base reg,
926    or -1 if the replacement shouldn't be done.  */
927 static HOST_WIDE_INT hard_frame_pointer_adjustment = -1;
928 
929 /* Data for adjust_mems callback.  */
930 
931 struct adjust_mem_data
932 {
933   bool store;
934   machine_mode mem_mode;
935   HOST_WIDE_INT stack_adjust;
936   auto_vec<rtx> side_effects;
937 };
938 
939 /* Helper for adjust_mems.  Return true if X is suitable for
940    transformation of wider mode arithmetics to narrower mode.  */
941 
942 static bool
943 use_narrower_mode_test (rtx x, const_rtx subreg)
944 {
945   subrtx_var_iterator::array_type array;
946   FOR_EACH_SUBRTX_VAR (iter, array, x, NONCONST)
947     {
948       rtx x = *iter;
949       if (CONSTANT_P (x))
950 	iter.skip_subrtxes ();
951       else
952 	switch (GET_CODE (x))
953 	  {
954 	  case REG:
955 	    if (cselib_lookup (x, GET_MODE (SUBREG_REG (subreg)), 0, VOIDmode))
956 	      return false;
957 	    if (!validate_subreg (GET_MODE (subreg), GET_MODE (x), x,
958 				  subreg_lowpart_offset (GET_MODE (subreg),
959 							 GET_MODE (x))))
960 	      return false;
961 	    break;
962 	  case PLUS:
963 	  case MINUS:
964 	  case MULT:
965 	    break;
966 	  case ASHIFT:
967 	    iter.substitute (XEXP (x, 0));
968 	    break;
969 	  default:
970 	    return false;
971 	  }
972     }
973   return true;
974 }
975 
976 /* Transform X into narrower mode MODE from wider mode WMODE.  */
977 
978 static rtx
979 use_narrower_mode (rtx x, scalar_int_mode mode, scalar_int_mode wmode)
980 {
981   rtx op0, op1;
982   if (CONSTANT_P (x))
983     return lowpart_subreg (mode, x, wmode);
984   switch (GET_CODE (x))
985     {
986     case REG:
987       return lowpart_subreg (mode, x, wmode);
988     case PLUS:
989     case MINUS:
990     case MULT:
991       op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
992       op1 = use_narrower_mode (XEXP (x, 1), mode, wmode);
993       return simplify_gen_binary (GET_CODE (x), mode, op0, op1);
994     case ASHIFT:
995       op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
996       op1 = XEXP (x, 1);
997       /* Ensure shift amount is not wider than mode.  */
998       if (GET_MODE (op1) == VOIDmode)
999 	op1 = lowpart_subreg (mode, op1, wmode);
1000       else if (GET_MODE_PRECISION (mode)
1001 	       < GET_MODE_PRECISION (as_a <scalar_int_mode> (GET_MODE (op1))))
1002 	op1 = lowpart_subreg (mode, op1, GET_MODE (op1));
1003       return simplify_gen_binary (ASHIFT, mode, op0, op1);
1004     default:
1005       gcc_unreachable ();
1006     }
1007 }
1008 
1009 /* Helper function for adjusting used MEMs.  */
1010 
1011 static rtx
1012 adjust_mems (rtx loc, const_rtx old_rtx, void *data)
1013 {
1014   struct adjust_mem_data *amd = (struct adjust_mem_data *) data;
1015   rtx mem, addr = loc, tem;
1016   machine_mode mem_mode_save;
1017   bool store_save;
1018   scalar_int_mode tem_mode, tem_subreg_mode;
1019   poly_int64 size;
1020   switch (GET_CODE (loc))
1021     {
1022     case REG:
1023       /* Don't do any sp or fp replacements outside of MEM addresses
1024          on the LHS.  */
1025       if (amd->mem_mode == VOIDmode && amd->store)
1026 	return loc;
1027       if (loc == stack_pointer_rtx
1028 	  && !frame_pointer_needed
1029 	  && cfa_base_rtx)
1030 	return compute_cfa_pointer (amd->stack_adjust);
1031       else if (loc == hard_frame_pointer_rtx
1032 	       && frame_pointer_needed
1033 	       && hard_frame_pointer_adjustment != -1
1034 	       && cfa_base_rtx)
1035 	return compute_cfa_pointer (hard_frame_pointer_adjustment);
1036       gcc_checking_assert (loc != virtual_incoming_args_rtx);
1037       return loc;
1038     case MEM:
1039       mem = loc;
1040       if (!amd->store)
1041 	{
1042 	  mem = targetm.delegitimize_address (mem);
1043 	  if (mem != loc && !MEM_P (mem))
1044 	    return simplify_replace_fn_rtx (mem, old_rtx, adjust_mems, data);
1045 	}
1046 
1047       addr = XEXP (mem, 0);
1048       mem_mode_save = amd->mem_mode;
1049       amd->mem_mode = GET_MODE (mem);
1050       store_save = amd->store;
1051       amd->store = false;
1052       addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
1053       amd->store = store_save;
1054       amd->mem_mode = mem_mode_save;
1055       if (mem == loc)
1056 	addr = targetm.delegitimize_address (addr);
1057       if (addr != XEXP (mem, 0))
1058 	mem = replace_equiv_address_nv (mem, addr);
1059       if (!amd->store)
1060 	mem = avoid_constant_pool_reference (mem);
1061       return mem;
1062     case PRE_INC:
1063     case PRE_DEC:
1064       size = GET_MODE_SIZE (amd->mem_mode);
1065       addr = plus_constant (GET_MODE (loc), XEXP (loc, 0),
1066 			    GET_CODE (loc) == PRE_INC ? size : -size);
1067       /* FALLTHRU */
1068     case POST_INC:
1069     case POST_DEC:
1070       if (addr == loc)
1071 	addr = XEXP (loc, 0);
1072       gcc_assert (amd->mem_mode != VOIDmode && amd->mem_mode != BLKmode);
1073       addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
1074       size = GET_MODE_SIZE (amd->mem_mode);
1075       tem = plus_constant (GET_MODE (loc), XEXP (loc, 0),
1076 			   (GET_CODE (loc) == PRE_INC
1077 			    || GET_CODE (loc) == POST_INC) ? size : -size);
1078       store_save = amd->store;
1079       amd->store = false;
1080       tem = simplify_replace_fn_rtx (tem, old_rtx, adjust_mems, data);
1081       amd->store = store_save;
1082       amd->side_effects.safe_push (gen_rtx_SET (XEXP (loc, 0), tem));
1083       return addr;
1084     case PRE_MODIFY:
1085       addr = XEXP (loc, 1);
1086       /* FALLTHRU */
1087     case POST_MODIFY:
1088       if (addr == loc)
1089 	addr = XEXP (loc, 0);
1090       gcc_assert (amd->mem_mode != VOIDmode);
1091       addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
1092       store_save = amd->store;
1093       amd->store = false;
1094       tem = simplify_replace_fn_rtx (XEXP (loc, 1), old_rtx,
1095 				     adjust_mems, data);
1096       amd->store = store_save;
1097       amd->side_effects.safe_push (gen_rtx_SET (XEXP (loc, 0), tem));
1098       return addr;
1099     case SUBREG:
1100       /* First try without delegitimization of whole MEMs and
1101 	 avoid_constant_pool_reference, which is more likely to succeed.  */
1102       store_save = amd->store;
1103       amd->store = true;
1104       addr = simplify_replace_fn_rtx (SUBREG_REG (loc), old_rtx, adjust_mems,
1105 				      data);
1106       amd->store = store_save;
1107       mem = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
1108       if (mem == SUBREG_REG (loc))
1109 	{
1110 	  tem = loc;
1111 	  goto finish_subreg;
1112 	}
1113       tem = simplify_gen_subreg (GET_MODE (loc), mem,
1114 				 GET_MODE (SUBREG_REG (loc)),
1115 				 SUBREG_BYTE (loc));
1116       if (tem)
1117 	goto finish_subreg;
1118       tem = simplify_gen_subreg (GET_MODE (loc), addr,
1119 				 GET_MODE (SUBREG_REG (loc)),
1120 				 SUBREG_BYTE (loc));
1121       if (tem == NULL_RTX)
1122 	tem = gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc));
1123     finish_subreg:
1124       if (MAY_HAVE_DEBUG_BIND_INSNS
1125 	  && GET_CODE (tem) == SUBREG
1126 	  && (GET_CODE (SUBREG_REG (tem)) == PLUS
1127 	      || GET_CODE (SUBREG_REG (tem)) == MINUS
1128 	      || GET_CODE (SUBREG_REG (tem)) == MULT
1129 	      || GET_CODE (SUBREG_REG (tem)) == ASHIFT)
1130 	  && is_a <scalar_int_mode> (GET_MODE (tem), &tem_mode)
1131 	  && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (tem)),
1132 				     &tem_subreg_mode)
1133 	  && (GET_MODE_PRECISION (tem_mode)
1134 	      < GET_MODE_PRECISION (tem_subreg_mode))
1135 	  && subreg_lowpart_p (tem)
1136 	  && use_narrower_mode_test (SUBREG_REG (tem), tem))
1137 	return use_narrower_mode (SUBREG_REG (tem), tem_mode, tem_subreg_mode);
1138       return tem;
1139     case ASM_OPERANDS:
1140       /* Don't do any replacements in second and following
1141 	 ASM_OPERANDS of inline-asm with multiple sets.
1142 	 ASM_OPERANDS_INPUT_VEC, ASM_OPERANDS_INPUT_CONSTRAINT_VEC
1143 	 and ASM_OPERANDS_LABEL_VEC need to be equal between
1144 	 all the ASM_OPERANDs in the insn and adjust_insn will
1145 	 fix this up.  */
1146       if (ASM_OPERANDS_OUTPUT_IDX (loc) != 0)
1147 	return loc;
1148       break;
1149     default:
1150       break;
1151     }
1152   return NULL_RTX;
1153 }
1154 
1155 /* Helper function for replacement of uses.  */
1156 
1157 static void
1158 adjust_mem_uses (rtx *x, void *data)
1159 {
1160   rtx new_x = simplify_replace_fn_rtx (*x, NULL_RTX, adjust_mems, data);
1161   if (new_x != *x)
1162     validate_change (NULL_RTX, x, new_x, true);
1163 }
1164 
1165 /* Helper function for replacement of stores.  */
1166 
1167 static void
1168 adjust_mem_stores (rtx loc, const_rtx expr, void *data)
1169 {
1170   if (MEM_P (loc))
1171     {
1172       rtx new_dest = simplify_replace_fn_rtx (SET_DEST (expr), NULL_RTX,
1173 					      adjust_mems, data);
1174       if (new_dest != SET_DEST (expr))
1175 	{
1176 	  rtx xexpr = CONST_CAST_RTX (expr);
1177 	  validate_change (NULL_RTX, &SET_DEST (xexpr), new_dest, true);
1178 	}
1179     }
1180 }
1181 
1182 /* Simplify INSN.  Remove all {PRE,POST}_{INC,DEC,MODIFY} rtxes,
1183    replace them with their value in the insn and add the side-effects
1184    as other sets to the insn.  */
1185 
1186 static void
1187 adjust_insn (basic_block bb, rtx_insn *insn)
1188 {
1189   rtx set;
1190 
1191 #ifdef HAVE_window_save
1192   /* If the target machine has an explicit window save instruction, the
1193      transformation OUTGOING_REGNO -> INCOMING_REGNO is done there.  */
1194   if (RTX_FRAME_RELATED_P (insn)
1195       && find_reg_note (insn, REG_CFA_WINDOW_SAVE, NULL_RTX))
1196     {
1197       unsigned int i, nregs = vec_safe_length (windowed_parm_regs);
1198       rtx rtl = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs * 2));
1199       parm_reg *p;
1200 
1201       FOR_EACH_VEC_SAFE_ELT (windowed_parm_regs, i, p)
1202 	{
1203 	  XVECEXP (rtl, 0, i * 2)
1204 	    = gen_rtx_SET (p->incoming, p->outgoing);
1205 	  /* Do not clobber the attached DECL, but only the REG.  */
1206 	  XVECEXP (rtl, 0, i * 2 + 1)
1207 	    = gen_rtx_CLOBBER (GET_MODE (p->outgoing),
1208 			       gen_raw_REG (GET_MODE (p->outgoing),
1209 					    REGNO (p->outgoing)));
1210 	}
1211 
1212       validate_change (NULL_RTX, &PATTERN (insn), rtl, true);
1213       return;
1214     }
1215 #endif
1216 
1217   adjust_mem_data amd;
1218   amd.mem_mode = VOIDmode;
1219   amd.stack_adjust = -VTI (bb)->out.stack_adjust;
1220 
1221   amd.store = true;
1222   note_stores (PATTERN (insn), adjust_mem_stores, &amd);
1223 
1224   amd.store = false;
1225   if (GET_CODE (PATTERN (insn)) == PARALLEL
1226       && asm_noperands (PATTERN (insn)) > 0
1227       && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
1228     {
1229       rtx body, set0;
1230       int i;
1231 
1232       /* inline-asm with multiple sets is tiny bit more complicated,
1233 	 because the 3 vectors in ASM_OPERANDS need to be shared between
1234 	 all ASM_OPERANDS in the instruction.  adjust_mems will
1235 	 not touch ASM_OPERANDS other than the first one, asm_noperands
1236 	 test above needs to be called before that (otherwise it would fail)
1237 	 and afterwards this code fixes it up.  */
1238       note_uses (&PATTERN (insn), adjust_mem_uses, &amd);
1239       body = PATTERN (insn);
1240       set0 = XVECEXP (body, 0, 0);
1241       gcc_checking_assert (GET_CODE (set0) == SET
1242 			   && GET_CODE (SET_SRC (set0)) == ASM_OPERANDS
1243 			   && ASM_OPERANDS_OUTPUT_IDX (SET_SRC (set0)) == 0);
1244       for (i = 1; i < XVECLEN (body, 0); i++)
1245 	if (GET_CODE (XVECEXP (body, 0, i)) != SET)
1246 	  break;
1247 	else
1248 	  {
1249 	    set = XVECEXP (body, 0, i);
1250 	    gcc_checking_assert (GET_CODE (SET_SRC (set)) == ASM_OPERANDS
1251 				 && ASM_OPERANDS_OUTPUT_IDX (SET_SRC (set))
1252 				    == i);
1253 	    if (ASM_OPERANDS_INPUT_VEC (SET_SRC (set))
1254 		!= ASM_OPERANDS_INPUT_VEC (SET_SRC (set0))
1255 		|| ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set))
1256 		   != ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set0))
1257 		|| ASM_OPERANDS_LABEL_VEC (SET_SRC (set))
1258 		   != ASM_OPERANDS_LABEL_VEC (SET_SRC (set0)))
1259 	      {
1260 		rtx newsrc = shallow_copy_rtx (SET_SRC (set));
1261 		ASM_OPERANDS_INPUT_VEC (newsrc)
1262 		  = ASM_OPERANDS_INPUT_VEC (SET_SRC (set0));
1263 		ASM_OPERANDS_INPUT_CONSTRAINT_VEC (newsrc)
1264 		  = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set0));
1265 		ASM_OPERANDS_LABEL_VEC (newsrc)
1266 		  = ASM_OPERANDS_LABEL_VEC (SET_SRC (set0));
1267 		validate_change (NULL_RTX, &SET_SRC (set), newsrc, true);
1268 	      }
1269 	  }
1270     }
1271   else
1272     note_uses (&PATTERN (insn), adjust_mem_uses, &amd);
1273 
1274   /* For read-only MEMs containing some constant, prefer those
1275      constants.  */
1276   set = single_set (insn);
1277   if (set && MEM_P (SET_SRC (set)) && MEM_READONLY_P (SET_SRC (set)))
1278     {
1279       rtx note = find_reg_equal_equiv_note (insn);
1280 
1281       if (note && CONSTANT_P (XEXP (note, 0)))
1282 	validate_change (NULL_RTX, &SET_SRC (set), XEXP (note, 0), true);
1283     }
1284 
1285   if (!amd.side_effects.is_empty ())
1286     {
1287       rtx *pat, new_pat;
1288       int i, oldn;
1289 
1290       pat = &PATTERN (insn);
1291       if (GET_CODE (*pat) == COND_EXEC)
1292 	pat = &COND_EXEC_CODE (*pat);
1293       if (GET_CODE (*pat) == PARALLEL)
1294 	oldn = XVECLEN (*pat, 0);
1295       else
1296 	oldn = 1;
1297       unsigned int newn = amd.side_effects.length ();
1298       new_pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (oldn + newn));
1299       if (GET_CODE (*pat) == PARALLEL)
1300 	for (i = 0; i < oldn; i++)
1301 	  XVECEXP (new_pat, 0, i) = XVECEXP (*pat, 0, i);
1302       else
1303 	XVECEXP (new_pat, 0, 0) = *pat;
1304 
1305       rtx effect;
1306       unsigned int j;
1307       FOR_EACH_VEC_ELT_REVERSE (amd.side_effects, j, effect)
1308 	XVECEXP (new_pat, 0, j + oldn) = effect;
1309       validate_change (NULL_RTX, pat, new_pat, true);
1310     }
1311 }
1312 
1313 /* Return the DEBUG_EXPR of a DEBUG_EXPR_DECL or the VALUE in DV.  */
1314 static inline rtx
1315 dv_as_rtx (decl_or_value dv)
1316 {
1317   tree decl;
1318 
1319   if (dv_is_value_p (dv))
1320     return dv_as_value (dv);
1321 
1322   decl = dv_as_decl (dv);
1323 
1324   gcc_checking_assert (TREE_CODE (decl) == DEBUG_EXPR_DECL);
1325   return DECL_RTL_KNOWN_SET (decl);
1326 }
1327 
1328 /* Return nonzero if a decl_or_value must not have more than one
1329    variable part.  The returned value discriminates among various
1330    kinds of one-part DVs ccording to enum onepart_enum.  */
1331 static inline onepart_enum
1332 dv_onepart_p (decl_or_value dv)
1333 {
1334   tree decl;
1335 
1336   if (!MAY_HAVE_DEBUG_BIND_INSNS)
1337     return NOT_ONEPART;
1338 
1339   if (dv_is_value_p (dv))
1340     return ONEPART_VALUE;
1341 
1342   decl = dv_as_decl (dv);
1343 
1344   if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
1345     return ONEPART_DEXPR;
1346 
1347   if (target_for_debug_bind (decl) != NULL_TREE)
1348     return ONEPART_VDECL;
1349 
1350   return NOT_ONEPART;
1351 }
1352 
1353 /* Return the variable pool to be used for a dv of type ONEPART.  */
1354 static inline pool_allocator &
1355 onepart_pool (onepart_enum onepart)
1356 {
1357   return onepart ? valvar_pool : var_pool;
1358 }
1359 
1360 /* Allocate a variable_def from the corresponding variable pool.  */
1361 static inline variable *
1362 onepart_pool_allocate (onepart_enum onepart)
1363 {
1364   return (variable*) onepart_pool (onepart).allocate ();
1365 }
1366 
1367 /* Build a decl_or_value out of a decl.  */
1368 static inline decl_or_value
1369 dv_from_decl (tree decl)
1370 {
1371   decl_or_value dv;
1372   dv = decl;
1373   gcc_checking_assert (dv_is_decl_p (dv));
1374   return dv;
1375 }
1376 
1377 /* Build a decl_or_value out of a value.  */
1378 static inline decl_or_value
1379 dv_from_value (rtx value)
1380 {
1381   decl_or_value dv;
1382   dv = value;
1383   gcc_checking_assert (dv_is_value_p (dv));
1384   return dv;
1385 }
1386 
1387 /* Return a value or the decl of a debug_expr as a decl_or_value.  */
1388 static inline decl_or_value
1389 dv_from_rtx (rtx x)
1390 {
1391   decl_or_value dv;
1392 
1393   switch (GET_CODE (x))
1394     {
1395     case DEBUG_EXPR:
1396       dv = dv_from_decl (DEBUG_EXPR_TREE_DECL (x));
1397       gcc_checking_assert (DECL_RTL_KNOWN_SET (DEBUG_EXPR_TREE_DECL (x)) == x);
1398       break;
1399 
1400     case VALUE:
1401       dv = dv_from_value (x);
1402       break;
1403 
1404     default:
1405       gcc_unreachable ();
1406     }
1407 
1408   return dv;
1409 }
1410 
1411 extern void debug_dv (decl_or_value dv);
1412 
1413 DEBUG_FUNCTION void
1414 debug_dv (decl_or_value dv)
1415 {
1416   if (dv_is_value_p (dv))
1417     debug_rtx (dv_as_value (dv));
1418   else
1419     debug_generic_stmt (dv_as_decl (dv));
1420 }
1421 
1422 static void loc_exp_dep_clear (variable *var);
1423 
1424 /* Free the element of VARIABLE_HTAB (its type is struct variable_def).  */
1425 
1426 static void
1427 variable_htab_free (void *elem)
1428 {
1429   int i;
1430   variable *var = (variable *) elem;
1431   location_chain *node, *next;
1432 
1433   gcc_checking_assert (var->refcount > 0);
1434 
1435   var->refcount--;
1436   if (var->refcount > 0)
1437     return;
1438 
1439   for (i = 0; i < var->n_var_parts; i++)
1440     {
1441       for (node = var->var_part[i].loc_chain; node; node = next)
1442 	{
1443 	  next = node->next;
1444 	  delete node;
1445 	}
1446       var->var_part[i].loc_chain = NULL;
1447     }
1448   if (var->onepart && VAR_LOC_1PAUX (var))
1449     {
1450       loc_exp_dep_clear (var);
1451       if (VAR_LOC_DEP_LST (var))
1452 	VAR_LOC_DEP_LST (var)->pprev = NULL;
1453       XDELETE (VAR_LOC_1PAUX (var));
1454       /* These may be reused across functions, so reset
1455 	 e.g. NO_LOC_P.  */
1456       if (var->onepart == ONEPART_DEXPR)
1457 	set_dv_changed (var->dv, true);
1458     }
1459   onepart_pool (var->onepart).remove (var);
1460 }
1461 
1462 /* Initialize the set (array) SET of attrs to empty lists.  */
1463 
1464 static void
1465 init_attrs_list_set (attrs **set)
1466 {
1467   int i;
1468 
1469   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1470     set[i] = NULL;
1471 }
1472 
1473 /* Make the list *LISTP empty.  */
1474 
1475 static void
1476 attrs_list_clear (attrs **listp)
1477 {
1478   attrs *list, *next;
1479 
1480   for (list = *listp; list; list = next)
1481     {
1482       next = list->next;
1483       delete list;
1484     }
1485   *listp = NULL;
1486 }
1487 
1488 /* Return true if the pair of DECL and OFFSET is the member of the LIST.  */
1489 
1490 static attrs *
1491 attrs_list_member (attrs *list, decl_or_value dv, HOST_WIDE_INT offset)
1492 {
1493   for (; list; list = list->next)
1494     if (dv_as_opaque (list->dv) == dv_as_opaque (dv) && list->offset == offset)
1495       return list;
1496   return NULL;
1497 }
1498 
1499 /* Insert the triplet DECL, OFFSET, LOC to the list *LISTP.  */
1500 
1501 static void
1502 attrs_list_insert (attrs **listp, decl_or_value dv,
1503 		   HOST_WIDE_INT offset, rtx loc)
1504 {
1505   attrs *list = new attrs;
1506   list->loc = loc;
1507   list->dv = dv;
1508   list->offset = offset;
1509   list->next = *listp;
1510   *listp = list;
1511 }
1512 
1513 /* Copy all nodes from SRC and create a list *DSTP of the copies.  */
1514 
1515 static void
1516 attrs_list_copy (attrs **dstp, attrs *src)
1517 {
1518   attrs_list_clear (dstp);
1519   for (; src; src = src->next)
1520     {
1521       attrs *n = new attrs;
1522       n->loc = src->loc;
1523       n->dv = src->dv;
1524       n->offset = src->offset;
1525       n->next = *dstp;
1526       *dstp = n;
1527     }
1528 }
1529 
1530 /* Add all nodes from SRC which are not in *DSTP to *DSTP.  */
1531 
1532 static void
1533 attrs_list_union (attrs **dstp, attrs *src)
1534 {
1535   for (; src; src = src->next)
1536     {
1537       if (!attrs_list_member (*dstp, src->dv, src->offset))
1538 	attrs_list_insert (dstp, src->dv, src->offset, src->loc);
1539     }
1540 }
1541 
1542 /* Combine nodes that are not onepart nodes from SRC and SRC2 into
1543    *DSTP.  */
1544 
1545 static void
1546 attrs_list_mpdv_union (attrs **dstp, attrs *src, attrs *src2)
1547 {
1548   gcc_assert (!*dstp);
1549   for (; src; src = src->next)
1550     {
1551       if (!dv_onepart_p (src->dv))
1552 	attrs_list_insert (dstp, src->dv, src->offset, src->loc);
1553     }
1554   for (src = src2; src; src = src->next)
1555     {
1556       if (!dv_onepart_p (src->dv)
1557 	  && !attrs_list_member (*dstp, src->dv, src->offset))
1558 	attrs_list_insert (dstp, src->dv, src->offset, src->loc);
1559     }
1560 }
1561 
1562 /* Shared hashtable support.  */
1563 
1564 /* Return true if VARS is shared.  */
1565 
1566 static inline bool
1567 shared_hash_shared (shared_hash *vars)
1568 {
1569   return vars->refcount > 1;
1570 }
1571 
1572 /* Return the hash table for VARS.  */
1573 
1574 static inline variable_table_type *
1575 shared_hash_htab (shared_hash *vars)
1576 {
1577   return vars->htab;
1578 }
1579 
1580 /* Return true if VAR is shared, or maybe because VARS is shared.  */
1581 
1582 static inline bool
1583 shared_var_p (variable *var, shared_hash *vars)
1584 {
1585   /* Don't count an entry in the changed_variables table as a duplicate.  */
1586   return ((var->refcount > 1 + (int) var->in_changed_variables)
1587 	  || shared_hash_shared (vars));
1588 }
1589 
1590 /* Copy variables into a new hash table.  */
1591 
1592 static shared_hash *
1593 shared_hash_unshare (shared_hash *vars)
1594 {
1595   shared_hash *new_vars = new shared_hash;
1596   gcc_assert (vars->refcount > 1);
1597   new_vars->refcount = 1;
1598   new_vars->htab = new variable_table_type (vars->htab->elements () + 3);
1599   vars_copy (new_vars->htab, vars->htab);
1600   vars->refcount--;
1601   return new_vars;
1602 }
1603 
1604 /* Increment reference counter on VARS and return it.  */
1605 
1606 static inline shared_hash *
1607 shared_hash_copy (shared_hash *vars)
1608 {
1609   vars->refcount++;
1610   return vars;
1611 }
1612 
1613 /* Decrement reference counter and destroy hash table if not shared
1614    anymore.  */
1615 
1616 static void
1617 shared_hash_destroy (shared_hash *vars)
1618 {
1619   gcc_checking_assert (vars->refcount > 0);
1620   if (--vars->refcount == 0)
1621     {
1622       delete vars->htab;
1623       delete vars;
1624     }
1625 }
1626 
1627 /* Unshare *PVARS if shared and return slot for DV.  If INS is
1628    INSERT, insert it if not already present.  */
1629 
1630 static inline variable **
1631 shared_hash_find_slot_unshare_1 (shared_hash **pvars, decl_or_value dv,
1632 				 hashval_t dvhash, enum insert_option ins)
1633 {
1634   if (shared_hash_shared (*pvars))
1635     *pvars = shared_hash_unshare (*pvars);
1636   return shared_hash_htab (*pvars)->find_slot_with_hash (dv, dvhash, ins);
1637 }
1638 
1639 static inline variable **
1640 shared_hash_find_slot_unshare (shared_hash **pvars, decl_or_value dv,
1641 			       enum insert_option ins)
1642 {
1643   return shared_hash_find_slot_unshare_1 (pvars, dv, dv_htab_hash (dv), ins);
1644 }
1645 
1646 /* Return slot for DV, if it is already present in the hash table.
1647    If it is not present, insert it only VARS is not shared, otherwise
1648    return NULL.  */
1649 
1650 static inline variable **
1651 shared_hash_find_slot_1 (shared_hash *vars, decl_or_value dv, hashval_t dvhash)
1652 {
1653   return shared_hash_htab (vars)->find_slot_with_hash (dv, dvhash,
1654 						       shared_hash_shared (vars)
1655 						       ? NO_INSERT : INSERT);
1656 }
1657 
1658 static inline variable **
1659 shared_hash_find_slot (shared_hash *vars, decl_or_value dv)
1660 {
1661   return shared_hash_find_slot_1 (vars, dv, dv_htab_hash (dv));
1662 }
1663 
1664 /* Return slot for DV only if it is already present in the hash table.  */
1665 
1666 static inline variable **
1667 shared_hash_find_slot_noinsert_1 (shared_hash *vars, decl_or_value dv,
1668 				  hashval_t dvhash)
1669 {
1670   return shared_hash_htab (vars)->find_slot_with_hash (dv, dvhash, NO_INSERT);
1671 }
1672 
1673 static inline variable **
1674 shared_hash_find_slot_noinsert (shared_hash *vars, decl_or_value dv)
1675 {
1676   return shared_hash_find_slot_noinsert_1 (vars, dv, dv_htab_hash (dv));
1677 }
1678 
1679 /* Return variable for DV or NULL if not already present in the hash
1680    table.  */
1681 
1682 static inline variable *
1683 shared_hash_find_1 (shared_hash *vars, decl_or_value dv, hashval_t dvhash)
1684 {
1685   return shared_hash_htab (vars)->find_with_hash (dv, dvhash);
1686 }
1687 
1688 static inline variable *
1689 shared_hash_find (shared_hash *vars, decl_or_value dv)
1690 {
1691   return shared_hash_find_1 (vars, dv, dv_htab_hash (dv));
1692 }
1693 
1694 /* Return true if TVAL is better than CVAL as a canonival value.  We
1695    choose lowest-numbered VALUEs, using the RTX address as a
1696    tie-breaker.  The idea is to arrange them into a star topology,
1697    such that all of them are at most one step away from the canonical
1698    value, and the canonical value has backlinks to all of them, in
1699    addition to all the actual locations.  We don't enforce this
1700    topology throughout the entire dataflow analysis, though.
1701  */
1702 
1703 static inline bool
1704 canon_value_cmp (rtx tval, rtx cval)
1705 {
1706   return !cval
1707     || CSELIB_VAL_PTR (tval)->uid < CSELIB_VAL_PTR (cval)->uid;
1708 }
1709 
1710 static bool dst_can_be_shared;
1711 
1712 /* Return a copy of a variable VAR and insert it to dataflow set SET.  */
1713 
1714 static variable **
1715 unshare_variable (dataflow_set *set, variable **slot, variable *var,
1716 		  enum var_init_status initialized)
1717 {
1718   variable *new_var;
1719   int i;
1720 
1721   new_var = onepart_pool_allocate (var->onepart);
1722   new_var->dv = var->dv;
1723   new_var->refcount = 1;
1724   var->refcount--;
1725   new_var->n_var_parts = var->n_var_parts;
1726   new_var->onepart = var->onepart;
1727   new_var->in_changed_variables = false;
1728 
1729   if (! flag_var_tracking_uninit)
1730     initialized = VAR_INIT_STATUS_INITIALIZED;
1731 
1732   for (i = 0; i < var->n_var_parts; i++)
1733     {
1734       location_chain *node;
1735       location_chain **nextp;
1736 
1737       if (i == 0 && var->onepart)
1738 	{
1739 	  /* One-part auxiliary data is only used while emitting
1740 	     notes, so propagate it to the new variable in the active
1741 	     dataflow set.  If we're not emitting notes, this will be
1742 	     a no-op.  */
1743 	  gcc_checking_assert (!VAR_LOC_1PAUX (var) || emit_notes);
1744 	  VAR_LOC_1PAUX (new_var) = VAR_LOC_1PAUX (var);
1745 	  VAR_LOC_1PAUX (var) = NULL;
1746 	}
1747       else
1748 	VAR_PART_OFFSET (new_var, i) = VAR_PART_OFFSET (var, i);
1749       nextp = &new_var->var_part[i].loc_chain;
1750       for (node = var->var_part[i].loc_chain; node; node = node->next)
1751 	{
1752 	  location_chain *new_lc;
1753 
1754 	  new_lc = new location_chain;
1755 	  new_lc->next = NULL;
1756 	  if (node->init > initialized)
1757 	    new_lc->init = node->init;
1758 	  else
1759 	    new_lc->init = initialized;
1760 	  if (node->set_src && !(MEM_P (node->set_src)))
1761 	    new_lc->set_src = node->set_src;
1762 	  else
1763 	    new_lc->set_src = NULL;
1764 	  new_lc->loc = node->loc;
1765 
1766 	  *nextp = new_lc;
1767 	  nextp = &new_lc->next;
1768 	}
1769 
1770       new_var->var_part[i].cur_loc = var->var_part[i].cur_loc;
1771     }
1772 
1773   dst_can_be_shared = false;
1774   if (shared_hash_shared (set->vars))
1775     slot = shared_hash_find_slot_unshare (&set->vars, var->dv, NO_INSERT);
1776   else if (set->traversed_vars && set->vars != set->traversed_vars)
1777     slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
1778   *slot = new_var;
1779   if (var->in_changed_variables)
1780     {
1781       variable **cslot
1782 	= changed_variables->find_slot_with_hash (var->dv,
1783 						  dv_htab_hash (var->dv),
1784 						  NO_INSERT);
1785       gcc_assert (*cslot == (void *) var);
1786       var->in_changed_variables = false;
1787       variable_htab_free (var);
1788       *cslot = new_var;
1789       new_var->in_changed_variables = true;
1790     }
1791   return slot;
1792 }
1793 
1794 /* Copy all variables from hash table SRC to hash table DST.  */
1795 
1796 static void
1797 vars_copy (variable_table_type *dst, variable_table_type *src)
1798 {
1799   variable_iterator_type hi;
1800   variable *var;
1801 
1802   FOR_EACH_HASH_TABLE_ELEMENT (*src, var, variable, hi)
1803     {
1804       variable **dstp;
1805       var->refcount++;
1806       dstp = dst->find_slot_with_hash (var->dv, dv_htab_hash (var->dv),
1807 				       INSERT);
1808       *dstp = var;
1809     }
1810 }
1811 
1812 /* Map a decl to its main debug decl.  */
1813 
1814 static inline tree
1815 var_debug_decl (tree decl)
1816 {
1817   if (decl && VAR_P (decl) && DECL_HAS_DEBUG_EXPR_P (decl))
1818     {
1819       tree debugdecl = DECL_DEBUG_EXPR (decl);
1820       if (DECL_P (debugdecl))
1821 	decl = debugdecl;
1822     }
1823 
1824   return decl;
1825 }
1826 
1827 /* Set the register LOC to contain DV, OFFSET.  */
1828 
1829 static void
1830 var_reg_decl_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1831 		  decl_or_value dv, HOST_WIDE_INT offset, rtx set_src,
1832 		  enum insert_option iopt)
1833 {
1834   attrs *node;
1835   bool decl_p = dv_is_decl_p (dv);
1836 
1837   if (decl_p)
1838     dv = dv_from_decl (var_debug_decl (dv_as_decl (dv)));
1839 
1840   for (node = set->regs[REGNO (loc)]; node; node = node->next)
1841     if (dv_as_opaque (node->dv) == dv_as_opaque (dv)
1842 	&& node->offset == offset)
1843       break;
1844   if (!node)
1845     attrs_list_insert (&set->regs[REGNO (loc)], dv, offset, loc);
1846   set_variable_part (set, loc, dv, offset, initialized, set_src, iopt);
1847 }
1848 
1849 /* Return true if we should track a location that is OFFSET bytes from
1850    a variable.  Store the constant offset in *OFFSET_OUT if so.  */
1851 
1852 static bool
1853 track_offset_p (poly_int64 offset, HOST_WIDE_INT *offset_out)
1854 {
1855   HOST_WIDE_INT const_offset;
1856   if (!offset.is_constant (&const_offset)
1857       || !IN_RANGE (const_offset, 0, MAX_VAR_PARTS - 1))
1858     return false;
1859   *offset_out = const_offset;
1860   return true;
1861 }
1862 
1863 /* Return the offset of a register that track_offset_p says we
1864    should track.  */
1865 
1866 static HOST_WIDE_INT
1867 get_tracked_reg_offset (rtx loc)
1868 {
1869   HOST_WIDE_INT offset;
1870   if (!track_offset_p (REG_OFFSET (loc), &offset))
1871     gcc_unreachable ();
1872   return offset;
1873 }
1874 
1875 /* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  */
1876 
1877 static void
1878 var_reg_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1879 	     rtx set_src)
1880 {
1881   tree decl = REG_EXPR (loc);
1882   HOST_WIDE_INT offset = get_tracked_reg_offset (loc);
1883 
1884   var_reg_decl_set (set, loc, initialized,
1885 		    dv_from_decl (decl), offset, set_src, INSERT);
1886 }
1887 
1888 static enum var_init_status
1889 get_init_value (dataflow_set *set, rtx loc, decl_or_value dv)
1890 {
1891   variable *var;
1892   int i;
1893   enum var_init_status ret_val = VAR_INIT_STATUS_UNKNOWN;
1894 
1895   if (! flag_var_tracking_uninit)
1896     return VAR_INIT_STATUS_INITIALIZED;
1897 
1898   var = shared_hash_find (set->vars, dv);
1899   if (var)
1900     {
1901       for (i = 0; i < var->n_var_parts && ret_val == VAR_INIT_STATUS_UNKNOWN; i++)
1902 	{
1903 	  location_chain *nextp;
1904 	  for (nextp = var->var_part[i].loc_chain; nextp; nextp = nextp->next)
1905 	    if (rtx_equal_p (nextp->loc, loc))
1906 	      {
1907 		ret_val = nextp->init;
1908 		break;
1909 	      }
1910 	}
1911     }
1912 
1913   return ret_val;
1914 }
1915 
1916 /* Delete current content of register LOC in dataflow set SET and set
1917    the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  If
1918    MODIFY is true, any other live copies of the same variable part are
1919    also deleted from the dataflow set, otherwise the variable part is
1920    assumed to be copied from another location holding the same
1921    part.  */
1922 
1923 static void
1924 var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify,
1925 			enum var_init_status initialized, rtx set_src)
1926 {
1927   tree decl = REG_EXPR (loc);
1928   HOST_WIDE_INT offset = get_tracked_reg_offset (loc);
1929   attrs *node, *next;
1930   attrs **nextp;
1931 
1932   decl = var_debug_decl (decl);
1933 
1934   if (initialized == VAR_INIT_STATUS_UNKNOWN)
1935     initialized = get_init_value (set, loc, dv_from_decl (decl));
1936 
1937   nextp = &set->regs[REGNO (loc)];
1938   for (node = *nextp; node; node = next)
1939     {
1940       next = node->next;
1941       if (dv_as_opaque (node->dv) != decl || node->offset != offset)
1942 	{
1943 	  delete_variable_part (set, node->loc, node->dv, node->offset);
1944 	  delete node;
1945 	  *nextp = next;
1946 	}
1947       else
1948 	{
1949 	  node->loc = loc;
1950 	  nextp = &node->next;
1951 	}
1952     }
1953   if (modify)
1954     clobber_variable_part (set, loc, dv_from_decl (decl), offset, set_src);
1955   var_reg_set (set, loc, initialized, set_src);
1956 }
1957 
1958 /* Delete the association of register LOC in dataflow set SET with any
1959    variables that aren't onepart.  If CLOBBER is true, also delete any
1960    other live copies of the same variable part, and delete the
1961    association with onepart dvs too.  */
1962 
1963 static void
1964 var_reg_delete (dataflow_set *set, rtx loc, bool clobber)
1965 {
1966   attrs **nextp = &set->regs[REGNO (loc)];
1967   attrs *node, *next;
1968 
1969   HOST_WIDE_INT offset;
1970   if (clobber && track_offset_p (REG_OFFSET (loc), &offset))
1971     {
1972       tree decl = REG_EXPR (loc);
1973 
1974       decl = var_debug_decl (decl);
1975 
1976       clobber_variable_part (set, NULL, dv_from_decl (decl), offset, NULL);
1977     }
1978 
1979   for (node = *nextp; node; node = next)
1980     {
1981       next = node->next;
1982       if (clobber || !dv_onepart_p (node->dv))
1983 	{
1984 	  delete_variable_part (set, node->loc, node->dv, node->offset);
1985 	  delete node;
1986 	  *nextp = next;
1987 	}
1988       else
1989 	nextp = &node->next;
1990     }
1991 }
1992 
1993 /* Delete content of register with number REGNO in dataflow set SET.  */
1994 
1995 static void
1996 var_regno_delete (dataflow_set *set, int regno)
1997 {
1998   attrs **reg = &set->regs[regno];
1999   attrs *node, *next;
2000 
2001   for (node = *reg; node; node = next)
2002     {
2003       next = node->next;
2004       delete_variable_part (set, node->loc, node->dv, node->offset);
2005       delete node;
2006     }
2007   *reg = NULL;
2008 }
2009 
2010 /* Return true if I is the negated value of a power of two.  */
2011 static bool
2012 negative_power_of_two_p (HOST_WIDE_INT i)
2013 {
2014   unsigned HOST_WIDE_INT x = -(unsigned HOST_WIDE_INT)i;
2015   return pow2_or_zerop (x);
2016 }
2017 
2018 /* Strip constant offsets and alignments off of LOC.  Return the base
2019    expression.  */
2020 
2021 static rtx
2022 vt_get_canonicalize_base (rtx loc)
2023 {
2024   while ((GET_CODE (loc) == PLUS
2025 	  || GET_CODE (loc) == AND)
2026 	 && GET_CODE (XEXP (loc, 1)) == CONST_INT
2027 	 && (GET_CODE (loc) != AND
2028 	     || negative_power_of_two_p (INTVAL (XEXP (loc, 1)))))
2029     loc = XEXP (loc, 0);
2030 
2031   return loc;
2032 }
2033 
2034 /* This caches canonicalized addresses for VALUEs, computed using
2035    information in the global cselib table.  */
2036 static hash_map<rtx, rtx> *global_get_addr_cache;
2037 
2038 /* This caches canonicalized addresses for VALUEs, computed using
2039    information from the global cache and information pertaining to a
2040    basic block being analyzed.  */
2041 static hash_map<rtx, rtx> *local_get_addr_cache;
2042 
2043 static rtx vt_canonicalize_addr (dataflow_set *, rtx);
2044 
2045 /* Return the canonical address for LOC, that must be a VALUE, using a
2046    cached global equivalence or computing it and storing it in the
2047    global cache.  */
2048 
2049 static rtx
2050 get_addr_from_global_cache (rtx const loc)
2051 {
2052   rtx x;
2053 
2054   gcc_checking_assert (GET_CODE (loc) == VALUE);
2055 
2056   bool existed;
2057   rtx *slot = &global_get_addr_cache->get_or_insert (loc, &existed);
2058   if (existed)
2059     return *slot;
2060 
2061   x = canon_rtx (get_addr (loc));
2062 
2063   /* Tentative, avoiding infinite recursion.  */
2064   *slot = x;
2065 
2066   if (x != loc)
2067     {
2068       rtx nx = vt_canonicalize_addr (NULL, x);
2069       if (nx != x)
2070 	{
2071 	  /* The table may have moved during recursion, recompute
2072 	     SLOT.  */
2073 	  *global_get_addr_cache->get (loc) = x = nx;
2074 	}
2075     }
2076 
2077   return x;
2078 }
2079 
2080 /* Return the canonical address for LOC, that must be a VALUE, using a
2081    cached local equivalence or computing it and storing it in the
2082    local cache.  */
2083 
2084 static rtx
2085 get_addr_from_local_cache (dataflow_set *set, rtx const loc)
2086 {
2087   rtx x;
2088   decl_or_value dv;
2089   variable *var;
2090   location_chain *l;
2091 
2092   gcc_checking_assert (GET_CODE (loc) == VALUE);
2093 
2094   bool existed;
2095   rtx *slot = &local_get_addr_cache->get_or_insert (loc, &existed);
2096   if (existed)
2097     return *slot;
2098 
2099   x = get_addr_from_global_cache (loc);
2100 
2101   /* Tentative, avoiding infinite recursion.  */
2102   *slot = x;
2103 
2104   /* Recurse to cache local expansion of X, or if we need to search
2105      for a VALUE in the expansion.  */
2106   if (x != loc)
2107     {
2108       rtx nx = vt_canonicalize_addr (set, x);
2109       if (nx != x)
2110 	{
2111 	  slot = local_get_addr_cache->get (loc);
2112 	  *slot = x = nx;
2113 	}
2114       return x;
2115     }
2116 
2117   dv = dv_from_rtx (x);
2118   var = shared_hash_find (set->vars, dv);
2119   if (!var)
2120     return x;
2121 
2122   /* Look for an improved equivalent expression.  */
2123   for (l = var->var_part[0].loc_chain; l; l = l->next)
2124     {
2125       rtx base = vt_get_canonicalize_base (l->loc);
2126       if (GET_CODE (base) == VALUE
2127 	  && canon_value_cmp (base, loc))
2128 	{
2129 	  rtx nx = vt_canonicalize_addr (set, l->loc);
2130 	  if (x != nx)
2131 	    {
2132 	      slot = local_get_addr_cache->get (loc);
2133 	      *slot = x = nx;
2134 	    }
2135 	  break;
2136 	}
2137     }
2138 
2139   return x;
2140 }
2141 
2142 /* Canonicalize LOC using equivalences from SET in addition to those
2143    in the cselib static table.  It expects a VALUE-based expression,
2144    and it will only substitute VALUEs with other VALUEs or
2145    function-global equivalences, so that, if two addresses have base
2146    VALUEs that are locally or globally related in ways that
2147    memrefs_conflict_p cares about, they will both canonicalize to
2148    expressions that have the same base VALUE.
2149 
2150    The use of VALUEs as canonical base addresses enables the canonical
2151    RTXs to remain unchanged globally, if they resolve to a constant,
2152    or throughout a basic block otherwise, so that they can be cached
2153    and the cache needs not be invalidated when REGs, MEMs or such
2154    change.  */
2155 
2156 static rtx
2157 vt_canonicalize_addr (dataflow_set *set, rtx oloc)
2158 {
2159   HOST_WIDE_INT ofst = 0;
2160   machine_mode mode = GET_MODE (oloc);
2161   rtx loc = oloc;
2162   rtx x;
2163   bool retry = true;
2164 
2165   while (retry)
2166     {
2167       while (GET_CODE (loc) == PLUS
2168 	     && GET_CODE (XEXP (loc, 1)) == CONST_INT)
2169 	{
2170 	  ofst += INTVAL (XEXP (loc, 1));
2171 	  loc = XEXP (loc, 0);
2172 	}
2173 
2174       /* Alignment operations can't normally be combined, so just
2175 	 canonicalize the base and we're done.  We'll normally have
2176 	 only one stack alignment anyway.  */
2177       if (GET_CODE (loc) == AND
2178 	  && GET_CODE (XEXP (loc, 1)) == CONST_INT
2179 	  && negative_power_of_two_p (INTVAL (XEXP (loc, 1))))
2180 	{
2181 	  x = vt_canonicalize_addr (set, XEXP (loc, 0));
2182 	  if (x != XEXP (loc, 0))
2183 	    loc = gen_rtx_AND (mode, x, XEXP (loc, 1));
2184 	  retry = false;
2185 	}
2186 
2187       if (GET_CODE (loc) == VALUE)
2188 	{
2189 	  if (set)
2190 	    loc = get_addr_from_local_cache (set, loc);
2191 	  else
2192 	    loc = get_addr_from_global_cache (loc);
2193 
2194 	  /* Consolidate plus_constants.  */
2195 	  while (ofst && GET_CODE (loc) == PLUS
2196 		 && GET_CODE (XEXP (loc, 1)) == CONST_INT)
2197 	    {
2198 	      ofst += INTVAL (XEXP (loc, 1));
2199 	      loc = XEXP (loc, 0);
2200 	    }
2201 
2202 	  retry = false;
2203 	}
2204       else
2205 	{
2206 	  x = canon_rtx (loc);
2207 	  if (retry)
2208 	    retry = (x != loc);
2209 	  loc = x;
2210 	}
2211     }
2212 
2213   /* Add OFST back in.  */
2214   if (ofst)
2215     {
2216       /* Don't build new RTL if we can help it.  */
2217       if (GET_CODE (oloc) == PLUS
2218 	  && XEXP (oloc, 0) == loc
2219 	  && INTVAL (XEXP (oloc, 1)) == ofst)
2220 	return oloc;
2221 
2222       loc = plus_constant (mode, loc, ofst);
2223     }
2224 
2225   return loc;
2226 }
2227 
2228 /* Return true iff there's a true dependence between MLOC and LOC.
2229    MADDR must be a canonicalized version of MLOC's address.  */
2230 
2231 static inline bool
2232 vt_canon_true_dep (dataflow_set *set, rtx mloc, rtx maddr, rtx loc)
2233 {
2234   if (GET_CODE (loc) != MEM)
2235     return false;
2236 
2237   rtx addr = vt_canonicalize_addr (set, XEXP (loc, 0));
2238   if (!canon_true_dependence (mloc, GET_MODE (mloc), maddr, loc, addr))
2239     return false;
2240 
2241   return true;
2242 }
2243 
2244 /* Hold parameters for the hashtab traversal function
2245    drop_overlapping_mem_locs, see below.  */
2246 
2247 struct overlapping_mems
2248 {
2249   dataflow_set *set;
2250   rtx loc, addr;
2251 };
2252 
2253 /* Remove all MEMs that overlap with COMS->LOC from the location list
2254    of a hash table entry for a onepart variable.  COMS->ADDR must be a
2255    canonicalized form of COMS->LOC's address, and COMS->LOC must be
2256    canonicalized itself.  */
2257 
2258 int
2259 drop_overlapping_mem_locs (variable **slot, overlapping_mems *coms)
2260 {
2261   dataflow_set *set = coms->set;
2262   rtx mloc = coms->loc, addr = coms->addr;
2263   variable *var = *slot;
2264 
2265   if (var->onepart != NOT_ONEPART)
2266     {
2267       location_chain *loc, **locp;
2268       bool changed = false;
2269       rtx cur_loc;
2270 
2271       gcc_assert (var->n_var_parts == 1);
2272 
2273       if (shared_var_p (var, set->vars))
2274 	{
2275 	  for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
2276 	    if (vt_canon_true_dep (set, mloc, addr, loc->loc))
2277 	      break;
2278 
2279 	  if (!loc)
2280 	    return 1;
2281 
2282 	  slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
2283 	  var = *slot;
2284 	  gcc_assert (var->n_var_parts == 1);
2285 	}
2286 
2287       if (VAR_LOC_1PAUX (var))
2288 	cur_loc = VAR_LOC_FROM (var);
2289       else
2290 	cur_loc = var->var_part[0].cur_loc;
2291 
2292       for (locp = &var->var_part[0].loc_chain, loc = *locp;
2293 	   loc; loc = *locp)
2294 	{
2295 	  if (!vt_canon_true_dep (set, mloc, addr, loc->loc))
2296 	    {
2297 	      locp = &loc->next;
2298 	      continue;
2299 	    }
2300 
2301 	  *locp = loc->next;
2302 	  /* If we have deleted the location which was last emitted
2303 	     we have to emit new location so add the variable to set
2304 	     of changed variables.  */
2305 	  if (cur_loc == loc->loc)
2306 	    {
2307 	      changed = true;
2308 	      var->var_part[0].cur_loc = NULL;
2309 	      if (VAR_LOC_1PAUX (var))
2310 		VAR_LOC_FROM (var) = NULL;
2311 	    }
2312 	  delete loc;
2313 	}
2314 
2315       if (!var->var_part[0].loc_chain)
2316 	{
2317 	  var->n_var_parts--;
2318 	  changed = true;
2319 	}
2320       if (changed)
2321 	variable_was_changed (var, set);
2322     }
2323 
2324   return 1;
2325 }
2326 
2327 /* Remove from SET all VALUE bindings to MEMs that overlap with LOC.  */
2328 
2329 static void
2330 clobber_overlapping_mems (dataflow_set *set, rtx loc)
2331 {
2332   struct overlapping_mems coms;
2333 
2334   gcc_checking_assert (GET_CODE (loc) == MEM);
2335 
2336   coms.set = set;
2337   coms.loc = canon_rtx (loc);
2338   coms.addr = vt_canonicalize_addr (set, XEXP (loc, 0));
2339 
2340   set->traversed_vars = set->vars;
2341   shared_hash_htab (set->vars)
2342     ->traverse <overlapping_mems*, drop_overlapping_mem_locs> (&coms);
2343   set->traversed_vars = NULL;
2344 }
2345 
2346 /* Set the location of DV, OFFSET as the MEM LOC.  */
2347 
2348 static void
2349 var_mem_decl_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
2350 		  decl_or_value dv, HOST_WIDE_INT offset, rtx set_src,
2351 		  enum insert_option iopt)
2352 {
2353   if (dv_is_decl_p (dv))
2354     dv = dv_from_decl (var_debug_decl (dv_as_decl (dv)));
2355 
2356   set_variable_part (set, loc, dv, offset, initialized, set_src, iopt);
2357 }
2358 
2359 /* Set the location part of variable MEM_EXPR (LOC) in dataflow set
2360    SET to LOC.
2361    Adjust the address first if it is stack pointer based.  */
2362 
2363 static void
2364 var_mem_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
2365 	     rtx set_src)
2366 {
2367   tree decl = MEM_EXPR (loc);
2368   HOST_WIDE_INT offset = int_mem_offset (loc);
2369 
2370   var_mem_decl_set (set, loc, initialized,
2371 		    dv_from_decl (decl), offset, set_src, INSERT);
2372 }
2373 
2374 /* Delete and set the location part of variable MEM_EXPR (LOC) in
2375    dataflow set SET to LOC.  If MODIFY is true, any other live copies
2376    of the same variable part are also deleted from the dataflow set,
2377    otherwise the variable part is assumed to be copied from another
2378    location holding the same part.
2379    Adjust the address first if it is stack pointer based.  */
2380 
2381 static void
2382 var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify,
2383 			enum var_init_status initialized, rtx set_src)
2384 {
2385   tree decl = MEM_EXPR (loc);
2386   HOST_WIDE_INT offset = int_mem_offset (loc);
2387 
2388   clobber_overlapping_mems (set, loc);
2389   decl = var_debug_decl (decl);
2390 
2391   if (initialized == VAR_INIT_STATUS_UNKNOWN)
2392     initialized = get_init_value (set, loc, dv_from_decl (decl));
2393 
2394   if (modify)
2395     clobber_variable_part (set, NULL, dv_from_decl (decl), offset, set_src);
2396   var_mem_set (set, loc, initialized, set_src);
2397 }
2398 
2399 /* Delete the location part LOC from dataflow set SET.  If CLOBBER is
2400    true, also delete any other live copies of the same variable part.
2401    Adjust the address first if it is stack pointer based.  */
2402 
2403 static void
2404 var_mem_delete (dataflow_set *set, rtx loc, bool clobber)
2405 {
2406   tree decl = MEM_EXPR (loc);
2407   HOST_WIDE_INT offset = int_mem_offset (loc);
2408 
2409   clobber_overlapping_mems (set, loc);
2410   decl = var_debug_decl (decl);
2411   if (clobber)
2412     clobber_variable_part (set, NULL, dv_from_decl (decl), offset, NULL);
2413   delete_variable_part (set, loc, dv_from_decl (decl), offset);
2414 }
2415 
2416 /* Return true if LOC should not be expanded for location expressions,
2417    or used in them.  */
2418 
2419 static inline bool
2420 unsuitable_loc (rtx loc)
2421 {
2422   switch (GET_CODE (loc))
2423     {
2424     case PC:
2425     case SCRATCH:
2426     case CC0:
2427     case ASM_INPUT:
2428     case ASM_OPERANDS:
2429       return true;
2430 
2431     default:
2432       return false;
2433     }
2434 }
2435 
2436 /* Bind VAL to LOC in SET.  If MODIFIED, detach LOC from any values
2437    bound to it.  */
2438 
2439 static inline void
2440 val_bind (dataflow_set *set, rtx val, rtx loc, bool modified)
2441 {
2442   if (REG_P (loc))
2443     {
2444       if (modified)
2445 	var_regno_delete (set, REGNO (loc));
2446       var_reg_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
2447 			dv_from_value (val), 0, NULL_RTX, INSERT);
2448     }
2449   else if (MEM_P (loc))
2450     {
2451       struct elt_loc_list *l = CSELIB_VAL_PTR (val)->locs;
2452 
2453       if (modified)
2454 	clobber_overlapping_mems (set, loc);
2455 
2456       if (l && GET_CODE (l->loc) == VALUE)
2457 	l = canonical_cselib_val (CSELIB_VAL_PTR (l->loc))->locs;
2458 
2459       /* If this MEM is a global constant, we don't need it in the
2460 	 dynamic tables.  ??? We should test this before emitting the
2461 	 micro-op in the first place.  */
2462       while (l)
2463 	if (GET_CODE (l->loc) == MEM && XEXP (l->loc, 0) == XEXP (loc, 0))
2464 	  break;
2465 	else
2466 	  l = l->next;
2467 
2468       if (!l)
2469 	var_mem_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
2470 			  dv_from_value (val), 0, NULL_RTX, INSERT);
2471     }
2472   else
2473     {
2474       /* Other kinds of equivalences are necessarily static, at least
2475 	 so long as we do not perform substitutions while merging
2476 	 expressions.  */
2477       gcc_unreachable ();
2478       set_variable_part (set, loc, dv_from_value (val), 0,
2479 			 VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
2480     }
2481 }
2482 
2483 /* Bind a value to a location it was just stored in.  If MODIFIED
2484    holds, assume the location was modified, detaching it from any
2485    values bound to it.  */
2486 
2487 static void
2488 val_store (dataflow_set *set, rtx val, rtx loc, rtx_insn *insn,
2489 	   bool modified)
2490 {
2491   cselib_val *v = CSELIB_VAL_PTR (val);
2492 
2493   gcc_assert (cselib_preserved_value_p (v));
2494 
2495   if (dump_file)
2496     {
2497       fprintf (dump_file, "%i: ", insn ? INSN_UID (insn) : 0);
2498       print_inline_rtx (dump_file, loc, 0);
2499       fprintf (dump_file, " evaluates to ");
2500       print_inline_rtx (dump_file, val, 0);
2501       if (v->locs)
2502 	{
2503 	  struct elt_loc_list *l;
2504 	  for (l = v->locs; l; l = l->next)
2505 	    {
2506 	      fprintf (dump_file, "\n%i: ", INSN_UID (l->setting_insn));
2507 	      print_inline_rtx (dump_file, l->loc, 0);
2508 	    }
2509 	}
2510       fprintf (dump_file, "\n");
2511     }
2512 
2513   gcc_checking_assert (!unsuitable_loc (loc));
2514 
2515   val_bind (set, val, loc, modified);
2516 }
2517 
2518 /* Clear (canonical address) slots that reference X.  */
2519 
2520 bool
2521 local_get_addr_clear_given_value (rtx const &, rtx *slot, rtx x)
2522 {
2523   if (vt_get_canonicalize_base (*slot) == x)
2524     *slot = NULL;
2525   return true;
2526 }
2527 
2528 /* Reset this node, detaching all its equivalences.  Return the slot
2529    in the variable hash table that holds dv, if there is one.  */
2530 
2531 static void
2532 val_reset (dataflow_set *set, decl_or_value dv)
2533 {
2534   variable *var = shared_hash_find (set->vars, dv) ;
2535   location_chain *node;
2536   rtx cval;
2537 
2538   if (!var || !var->n_var_parts)
2539     return;
2540 
2541   gcc_assert (var->n_var_parts == 1);
2542 
2543   if (var->onepart == ONEPART_VALUE)
2544     {
2545       rtx x = dv_as_value (dv);
2546 
2547       /* Relationships in the global cache don't change, so reset the
2548 	 local cache entry only.  */
2549       rtx *slot = local_get_addr_cache->get (x);
2550       if (slot)
2551 	{
2552 	  /* If the value resolved back to itself, odds are that other
2553 	     values may have cached it too.  These entries now refer
2554 	     to the old X, so detach them too.  Entries that used the
2555 	     old X but resolved to something else remain ok as long as
2556 	     that something else isn't also reset.  */
2557 	  if (*slot == x)
2558 	    local_get_addr_cache
2559 	      ->traverse<rtx, local_get_addr_clear_given_value> (x);
2560 	  *slot = NULL;
2561 	}
2562     }
2563 
2564   cval = NULL;
2565   for (node = var->var_part[0].loc_chain; node; node = node->next)
2566     if (GET_CODE (node->loc) == VALUE
2567 	&& canon_value_cmp (node->loc, cval))
2568       cval = node->loc;
2569 
2570   for (node = var->var_part[0].loc_chain; node; node = node->next)
2571     if (GET_CODE (node->loc) == VALUE && cval != node->loc)
2572       {
2573 	/* Redirect the equivalence link to the new canonical
2574 	   value, or simply remove it if it would point at
2575 	   itself.  */
2576 	if (cval)
2577 	  set_variable_part (set, cval, dv_from_value (node->loc),
2578 			     0, node->init, node->set_src, NO_INSERT);
2579 	delete_variable_part (set, dv_as_value (dv),
2580 			      dv_from_value (node->loc), 0);
2581       }
2582 
2583   if (cval)
2584     {
2585       decl_or_value cdv = dv_from_value (cval);
2586 
2587       /* Keep the remaining values connected, accumulating links
2588 	 in the canonical value.  */
2589       for (node = var->var_part[0].loc_chain; node; node = node->next)
2590 	{
2591 	  if (node->loc == cval)
2592 	    continue;
2593 	  else if (GET_CODE (node->loc) == REG)
2594 	    var_reg_decl_set (set, node->loc, node->init, cdv, 0,
2595 			      node->set_src, NO_INSERT);
2596 	  else if (GET_CODE (node->loc) == MEM)
2597 	    var_mem_decl_set (set, node->loc, node->init, cdv, 0,
2598 			      node->set_src, NO_INSERT);
2599 	  else
2600 	    set_variable_part (set, node->loc, cdv, 0,
2601 			       node->init, node->set_src, NO_INSERT);
2602 	}
2603     }
2604 
2605   /* We remove this last, to make sure that the canonical value is not
2606      removed to the point of requiring reinsertion.  */
2607   if (cval)
2608     delete_variable_part (set, dv_as_value (dv), dv_from_value (cval), 0);
2609 
2610   clobber_variable_part (set, NULL, dv, 0, NULL);
2611 }
2612 
2613 /* Find the values in a given location and map the val to another
2614    value, if it is unique, or add the location as one holding the
2615    value.  */
2616 
2617 static void
2618 val_resolve (dataflow_set *set, rtx val, rtx loc, rtx_insn *insn)
2619 {
2620   decl_or_value dv = dv_from_value (val);
2621 
2622   if (dump_file && (dump_flags & TDF_DETAILS))
2623     {
2624       if (insn)
2625 	fprintf (dump_file, "%i: ", INSN_UID (insn));
2626       else
2627 	fprintf (dump_file, "head: ");
2628       print_inline_rtx (dump_file, val, 0);
2629       fputs (" is at ", dump_file);
2630       print_inline_rtx (dump_file, loc, 0);
2631       fputc ('\n', dump_file);
2632     }
2633 
2634   val_reset (set, dv);
2635 
2636   gcc_checking_assert (!unsuitable_loc (loc));
2637 
2638   if (REG_P (loc))
2639     {
2640       attrs *node, *found = NULL;
2641 
2642       for (node = set->regs[REGNO (loc)]; node; node = node->next)
2643 	if (dv_is_value_p (node->dv)
2644 	    && GET_MODE (dv_as_value (node->dv)) == GET_MODE (loc))
2645 	  {
2646 	    found = node;
2647 
2648 	    /* Map incoming equivalences.  ??? Wouldn't it be nice if
2649 	     we just started sharing the location lists?  Maybe a
2650 	     circular list ending at the value itself or some
2651 	     such.  */
2652 	    set_variable_part (set, dv_as_value (node->dv),
2653 			       dv_from_value (val), node->offset,
2654 			       VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
2655 	    set_variable_part (set, val, node->dv, node->offset,
2656 			       VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
2657 	  }
2658 
2659       /* If we didn't find any equivalence, we need to remember that
2660 	 this value is held in the named register.  */
2661       if (found)
2662 	return;
2663     }
2664   /* ??? Attempt to find and merge equivalent MEMs or other
2665      expressions too.  */
2666 
2667   val_bind (set, val, loc, false);
2668 }
2669 
2670 /* Initialize dataflow set SET to be empty.
2671    VARS_SIZE is the initial size of hash table VARS.  */
2672 
2673 static void
2674 dataflow_set_init (dataflow_set *set)
2675 {
2676   init_attrs_list_set (set->regs);
2677   set->vars = shared_hash_copy (empty_shared_hash);
2678   set->stack_adjust = 0;
2679   set->traversed_vars = NULL;
2680 }
2681 
2682 /* Delete the contents of dataflow set SET.  */
2683 
2684 static void
2685 dataflow_set_clear (dataflow_set *set)
2686 {
2687   int i;
2688 
2689   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2690     attrs_list_clear (&set->regs[i]);
2691 
2692   shared_hash_destroy (set->vars);
2693   set->vars = shared_hash_copy (empty_shared_hash);
2694 }
2695 
2696 /* Copy the contents of dataflow set SRC to DST.  */
2697 
2698 static void
2699 dataflow_set_copy (dataflow_set *dst, dataflow_set *src)
2700 {
2701   int i;
2702 
2703   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2704     attrs_list_copy (&dst->regs[i], src->regs[i]);
2705 
2706   shared_hash_destroy (dst->vars);
2707   dst->vars = shared_hash_copy (src->vars);
2708   dst->stack_adjust = src->stack_adjust;
2709 }
2710 
2711 /* Information for merging lists of locations for a given offset of variable.
2712  */
2713 struct variable_union_info
2714 {
2715   /* Node of the location chain.  */
2716   location_chain *lc;
2717 
2718   /* The sum of positions in the input chains.  */
2719   int pos;
2720 
2721   /* The position in the chain of DST dataflow set.  */
2722   int pos_dst;
2723 };
2724 
2725 /* Buffer for location list sorting and its allocated size.  */
2726 static struct variable_union_info *vui_vec;
2727 static int vui_allocated;
2728 
2729 /* Compare function for qsort, order the structures by POS element.  */
2730 
2731 static int
2732 variable_union_info_cmp_pos (const void *n1, const void *n2)
2733 {
2734   const struct variable_union_info *const i1 =
2735     (const struct variable_union_info *) n1;
2736   const struct variable_union_info *const i2 =
2737     ( const struct variable_union_info *) n2;
2738 
2739   if (i1->pos != i2->pos)
2740     return i1->pos - i2->pos;
2741 
2742   return (i1->pos_dst - i2->pos_dst);
2743 }
2744 
2745 /* Compute union of location parts of variable *SLOT and the same variable
2746    from hash table DATA.  Compute "sorted" union of the location chains
2747    for common offsets, i.e. the locations of a variable part are sorted by
2748    a priority where the priority is the sum of the positions in the 2 chains
2749    (if a location is only in one list the position in the second list is
2750    defined to be larger than the length of the chains).
2751    When we are updating the location parts the newest location is in the
2752    beginning of the chain, so when we do the described "sorted" union
2753    we keep the newest locations in the beginning.  */
2754 
2755 static int
2756 variable_union (variable *src, dataflow_set *set)
2757 {
2758   variable *dst;
2759   variable **dstp;
2760   int i, j, k;
2761 
2762   dstp = shared_hash_find_slot (set->vars, src->dv);
2763   if (!dstp || !*dstp)
2764     {
2765       src->refcount++;
2766 
2767       dst_can_be_shared = false;
2768       if (!dstp)
2769 	dstp = shared_hash_find_slot_unshare (&set->vars, src->dv, INSERT);
2770 
2771       *dstp = src;
2772 
2773       /* Continue traversing the hash table.  */
2774       return 1;
2775     }
2776   else
2777     dst = *dstp;
2778 
2779   gcc_assert (src->n_var_parts);
2780   gcc_checking_assert (src->onepart == dst->onepart);
2781 
2782   /* We can combine one-part variables very efficiently, because their
2783      entries are in canonical order.  */
2784   if (src->onepart)
2785     {
2786       location_chain **nodep, *dnode, *snode;
2787 
2788       gcc_assert (src->n_var_parts == 1
2789 		  && dst->n_var_parts == 1);
2790 
2791       snode = src->var_part[0].loc_chain;
2792       gcc_assert (snode);
2793 
2794     restart_onepart_unshared:
2795       nodep = &dst->var_part[0].loc_chain;
2796       dnode = *nodep;
2797       gcc_assert (dnode);
2798 
2799       while (snode)
2800 	{
2801 	  int r = dnode ? loc_cmp (dnode->loc, snode->loc) : 1;
2802 
2803 	  if (r > 0)
2804 	    {
2805 	      location_chain *nnode;
2806 
2807 	      if (shared_var_p (dst, set->vars))
2808 		{
2809 		  dstp = unshare_variable (set, dstp, dst,
2810 					   VAR_INIT_STATUS_INITIALIZED);
2811 		  dst = *dstp;
2812 		  goto restart_onepart_unshared;
2813 		}
2814 
2815 	      *nodep = nnode = new location_chain;
2816 	      nnode->loc = snode->loc;
2817 	      nnode->init = snode->init;
2818 	      if (!snode->set_src || MEM_P (snode->set_src))
2819 		nnode->set_src = NULL;
2820 	      else
2821 		nnode->set_src = snode->set_src;
2822 	      nnode->next = dnode;
2823 	      dnode = nnode;
2824 	    }
2825 	  else if (r == 0)
2826 	    gcc_checking_assert (rtx_equal_p (dnode->loc, snode->loc));
2827 
2828 	  if (r >= 0)
2829 	    snode = snode->next;
2830 
2831 	  nodep = &dnode->next;
2832 	  dnode = *nodep;
2833 	}
2834 
2835       return 1;
2836     }
2837 
2838   gcc_checking_assert (!src->onepart);
2839 
2840   /* Count the number of location parts, result is K.  */
2841   for (i = 0, j = 0, k = 0;
2842        i < src->n_var_parts && j < dst->n_var_parts; k++)
2843     {
2844       if (VAR_PART_OFFSET (src, i) == VAR_PART_OFFSET (dst, j))
2845 	{
2846 	  i++;
2847 	  j++;
2848 	}
2849       else if (VAR_PART_OFFSET (src, i) < VAR_PART_OFFSET (dst, j))
2850 	i++;
2851       else
2852 	j++;
2853     }
2854   k += src->n_var_parts - i;
2855   k += dst->n_var_parts - j;
2856 
2857   /* We track only variables whose size is <= MAX_VAR_PARTS bytes
2858      thus there are at most MAX_VAR_PARTS different offsets.  */
2859   gcc_checking_assert (dst->onepart ? k == 1 : k <= MAX_VAR_PARTS);
2860 
2861   if (dst->n_var_parts != k && shared_var_p (dst, set->vars))
2862     {
2863       dstp = unshare_variable (set, dstp, dst, VAR_INIT_STATUS_UNKNOWN);
2864       dst = *dstp;
2865     }
2866 
2867   i = src->n_var_parts - 1;
2868   j = dst->n_var_parts - 1;
2869   dst->n_var_parts = k;
2870 
2871   for (k--; k >= 0; k--)
2872     {
2873       location_chain *node, *node2;
2874 
2875       if (i >= 0 && j >= 0
2876 	  && VAR_PART_OFFSET (src, i) == VAR_PART_OFFSET (dst, j))
2877 	{
2878 	  /* Compute the "sorted" union of the chains, i.e. the locations which
2879 	     are in both chains go first, they are sorted by the sum of
2880 	     positions in the chains.  */
2881 	  int dst_l, src_l;
2882 	  int ii, jj, n;
2883 	  struct variable_union_info *vui;
2884 
2885 	  /* If DST is shared compare the location chains.
2886 	     If they are different we will modify the chain in DST with
2887 	     high probability so make a copy of DST.  */
2888 	  if (shared_var_p (dst, set->vars))
2889 	    {
2890 	      for (node = src->var_part[i].loc_chain,
2891 		   node2 = dst->var_part[j].loc_chain; node && node2;
2892 		   node = node->next, node2 = node2->next)
2893 		{
2894 		  if (!((REG_P (node2->loc)
2895 			 && REG_P (node->loc)
2896 			 && REGNO (node2->loc) == REGNO (node->loc))
2897 			|| rtx_equal_p (node2->loc, node->loc)))
2898 		    {
2899 		      if (node2->init < node->init)
2900 		        node2->init = node->init;
2901 		      break;
2902 		    }
2903 		}
2904 	      if (node || node2)
2905 		{
2906 		  dstp = unshare_variable (set, dstp, dst,
2907 					   VAR_INIT_STATUS_UNKNOWN);
2908 		  dst = (variable *)*dstp;
2909 		}
2910 	    }
2911 
2912 	  src_l = 0;
2913 	  for (node = src->var_part[i].loc_chain; node; node = node->next)
2914 	    src_l++;
2915 	  dst_l = 0;
2916 	  for (node = dst->var_part[j].loc_chain; node; node = node->next)
2917 	    dst_l++;
2918 
2919 	  if (dst_l == 1)
2920 	    {
2921 	      /* The most common case, much simpler, no qsort is needed.  */
2922 	      location_chain *dstnode = dst->var_part[j].loc_chain;
2923 	      dst->var_part[k].loc_chain = dstnode;
2924 	      VAR_PART_OFFSET (dst, k) = VAR_PART_OFFSET (dst, j);
2925 	      node2 = dstnode;
2926 	      for (node = src->var_part[i].loc_chain; node; node = node->next)
2927 		if (!((REG_P (dstnode->loc)
2928 		       && REG_P (node->loc)
2929 		       && REGNO (dstnode->loc) == REGNO (node->loc))
2930 		      || rtx_equal_p (dstnode->loc, node->loc)))
2931 		  {
2932 		    location_chain *new_node;
2933 
2934 		    /* Copy the location from SRC.  */
2935 		    new_node = new location_chain;
2936 		    new_node->loc = node->loc;
2937 		    new_node->init = node->init;
2938 		    if (!node->set_src || MEM_P (node->set_src))
2939 		      new_node->set_src = NULL;
2940 		    else
2941 		      new_node->set_src = node->set_src;
2942 		    node2->next = new_node;
2943 		    node2 = new_node;
2944 		  }
2945 	      node2->next = NULL;
2946 	    }
2947 	  else
2948 	    {
2949 	      if (src_l + dst_l > vui_allocated)
2950 		{
2951 		  vui_allocated = MAX (vui_allocated * 2, src_l + dst_l);
2952 		  vui_vec = XRESIZEVEC (struct variable_union_info, vui_vec,
2953 					vui_allocated);
2954 		}
2955 	      vui = vui_vec;
2956 
2957 	      /* Fill in the locations from DST.  */
2958 	      for (node = dst->var_part[j].loc_chain, jj = 0; node;
2959 		   node = node->next, jj++)
2960 		{
2961 		  vui[jj].lc = node;
2962 		  vui[jj].pos_dst = jj;
2963 
2964 		  /* Pos plus value larger than a sum of 2 valid positions.  */
2965 		  vui[jj].pos = jj + src_l + dst_l;
2966 		}
2967 
2968 	      /* Fill in the locations from SRC.  */
2969 	      n = dst_l;
2970 	      for (node = src->var_part[i].loc_chain, ii = 0; node;
2971 		   node = node->next, ii++)
2972 		{
2973 		  /* Find location from NODE.  */
2974 		  for (jj = 0; jj < dst_l; jj++)
2975 		    {
2976 		      if ((REG_P (vui[jj].lc->loc)
2977 			   && REG_P (node->loc)
2978 			   && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
2979 			  || rtx_equal_p (vui[jj].lc->loc, node->loc))
2980 			{
2981 			  vui[jj].pos = jj + ii;
2982 			  break;
2983 			}
2984 		    }
2985 		  if (jj >= dst_l)	/* The location has not been found.  */
2986 		    {
2987 		      location_chain *new_node;
2988 
2989 		      /* Copy the location from SRC.  */
2990 		      new_node = new location_chain;
2991 		      new_node->loc = node->loc;
2992 		      new_node->init = node->init;
2993 		      if (!node->set_src || MEM_P (node->set_src))
2994 			new_node->set_src = NULL;
2995 		      else
2996 			new_node->set_src = node->set_src;
2997 		      vui[n].lc = new_node;
2998 		      vui[n].pos_dst = src_l + dst_l;
2999 		      vui[n].pos = ii + src_l + dst_l;
3000 		      n++;
3001 		    }
3002 		}
3003 
3004 	      if (dst_l == 2)
3005 		{
3006 		  /* Special case still very common case.  For dst_l == 2
3007 		     all entries dst_l ... n-1 are sorted, with for i >= dst_l
3008 		     vui[i].pos == i + src_l + dst_l.  */
3009 		  if (vui[0].pos > vui[1].pos)
3010 		    {
3011 		      /* Order should be 1, 0, 2... */
3012 		      dst->var_part[k].loc_chain = vui[1].lc;
3013 		      vui[1].lc->next = vui[0].lc;
3014 		      if (n >= 3)
3015 			{
3016 			  vui[0].lc->next = vui[2].lc;
3017 			  vui[n - 1].lc->next = NULL;
3018 			}
3019 		      else
3020 			vui[0].lc->next = NULL;
3021 		      ii = 3;
3022 		    }
3023 		  else
3024 		    {
3025 		      dst->var_part[k].loc_chain = vui[0].lc;
3026 		      if (n >= 3 && vui[2].pos < vui[1].pos)
3027 			{
3028 			  /* Order should be 0, 2, 1, 3... */
3029 			  vui[0].lc->next = vui[2].lc;
3030 			  vui[2].lc->next = vui[1].lc;
3031 			  if (n >= 4)
3032 			    {
3033 			      vui[1].lc->next = vui[3].lc;
3034 			      vui[n - 1].lc->next = NULL;
3035 			    }
3036 			  else
3037 			    vui[1].lc->next = NULL;
3038 			  ii = 4;
3039 			}
3040 		      else
3041 			{
3042 			  /* Order should be 0, 1, 2... */
3043 			  ii = 1;
3044 			  vui[n - 1].lc->next = NULL;
3045 			}
3046 		    }
3047 		  for (; ii < n; ii++)
3048 		    vui[ii - 1].lc->next = vui[ii].lc;
3049 		}
3050 	      else
3051 		{
3052 		  qsort (vui, n, sizeof (struct variable_union_info),
3053 			 variable_union_info_cmp_pos);
3054 
3055 		  /* Reconnect the nodes in sorted order.  */
3056 		  for (ii = 1; ii < n; ii++)
3057 		    vui[ii - 1].lc->next = vui[ii].lc;
3058 		  vui[n - 1].lc->next = NULL;
3059 		  dst->var_part[k].loc_chain = vui[0].lc;
3060 		}
3061 
3062 	      VAR_PART_OFFSET (dst, k) = VAR_PART_OFFSET (dst, j);
3063 	    }
3064 	  i--;
3065 	  j--;
3066 	}
3067       else if ((i >= 0 && j >= 0
3068 		&& VAR_PART_OFFSET (src, i) < VAR_PART_OFFSET (dst, j))
3069 	       || i < 0)
3070 	{
3071 	  dst->var_part[k] = dst->var_part[j];
3072 	  j--;
3073 	}
3074       else if ((i >= 0 && j >= 0
3075 		&& VAR_PART_OFFSET (src, i) > VAR_PART_OFFSET (dst, j))
3076 	       || j < 0)
3077 	{
3078 	  location_chain **nextp;
3079 
3080 	  /* Copy the chain from SRC.  */
3081 	  nextp = &dst->var_part[k].loc_chain;
3082 	  for (node = src->var_part[i].loc_chain; node; node = node->next)
3083 	    {
3084 	      location_chain *new_lc;
3085 
3086 	      new_lc = new location_chain;
3087 	      new_lc->next = NULL;
3088 	      new_lc->init = node->init;
3089 	      if (!node->set_src || MEM_P (node->set_src))
3090 		new_lc->set_src = NULL;
3091 	      else
3092 		new_lc->set_src = node->set_src;
3093 	      new_lc->loc = node->loc;
3094 
3095 	      *nextp = new_lc;
3096 	      nextp = &new_lc->next;
3097 	    }
3098 
3099 	  VAR_PART_OFFSET (dst, k) = VAR_PART_OFFSET (src, i);
3100 	  i--;
3101 	}
3102       dst->var_part[k].cur_loc = NULL;
3103     }
3104 
3105   if (flag_var_tracking_uninit)
3106     for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
3107       {
3108 	location_chain *node, *node2;
3109 	for (node = src->var_part[i].loc_chain; node; node = node->next)
3110 	  for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
3111 	    if (rtx_equal_p (node->loc, node2->loc))
3112 	      {
3113 		if (node->init > node2->init)
3114 		  node2->init = node->init;
3115 	      }
3116       }
3117 
3118   /* Continue traversing the hash table.  */
3119   return 1;
3120 }
3121 
3122 /* Compute union of dataflow sets SRC and DST and store it to DST.  */
3123 
3124 static void
3125 dataflow_set_union (dataflow_set *dst, dataflow_set *src)
3126 {
3127   int i;
3128 
3129   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3130     attrs_list_union (&dst->regs[i], src->regs[i]);
3131 
3132   if (dst->vars == empty_shared_hash)
3133     {
3134       shared_hash_destroy (dst->vars);
3135       dst->vars = shared_hash_copy (src->vars);
3136     }
3137   else
3138     {
3139       variable_iterator_type hi;
3140       variable *var;
3141 
3142       FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (src->vars),
3143 				   var, variable, hi)
3144 	variable_union (var, dst);
3145     }
3146 }
3147 
3148 /* Whether the value is currently being expanded.  */
3149 #define VALUE_RECURSED_INTO(x) \
3150   (RTL_FLAG_CHECK2 ("VALUE_RECURSED_INTO", (x), VALUE, DEBUG_EXPR)->used)
3151 
3152 /* Whether no expansion was found, saving useless lookups.
3153    It must only be set when VALUE_CHANGED is clear.  */
3154 #define NO_LOC_P(x) \
3155   (RTL_FLAG_CHECK2 ("NO_LOC_P", (x), VALUE, DEBUG_EXPR)->return_val)
3156 
3157 /* Whether cur_loc in the value needs to be (re)computed.  */
3158 #define VALUE_CHANGED(x) \
3159   (RTL_FLAG_CHECK1 ("VALUE_CHANGED", (x), VALUE)->frame_related)
3160 /* Whether cur_loc in the decl needs to be (re)computed.  */
3161 #define DECL_CHANGED(x) TREE_VISITED (x)
3162 
3163 /* Record (if NEWV) that DV needs to have its cur_loc recomputed.  For
3164    user DECLs, this means they're in changed_variables.  Values and
3165    debug exprs may be left with this flag set if no user variable
3166    requires them to be evaluated.  */
3167 
3168 static inline void
3169 set_dv_changed (decl_or_value dv, bool newv)
3170 {
3171   switch (dv_onepart_p (dv))
3172     {
3173     case ONEPART_VALUE:
3174       if (newv)
3175 	NO_LOC_P (dv_as_value (dv)) = false;
3176       VALUE_CHANGED (dv_as_value (dv)) = newv;
3177       break;
3178 
3179     case ONEPART_DEXPR:
3180       if (newv)
3181 	NO_LOC_P (DECL_RTL_KNOWN_SET (dv_as_decl (dv))) = false;
3182       /* Fall through.  */
3183 
3184     default:
3185       DECL_CHANGED (dv_as_decl (dv)) = newv;
3186       break;
3187     }
3188 }
3189 
3190 /* Return true if DV needs to have its cur_loc recomputed.  */
3191 
3192 static inline bool
3193 dv_changed_p (decl_or_value dv)
3194 {
3195   return (dv_is_value_p (dv)
3196 	  ? VALUE_CHANGED (dv_as_value (dv))
3197 	  : DECL_CHANGED (dv_as_decl (dv)));
3198 }
3199 
3200 /* Return a location list node whose loc is rtx_equal to LOC, in the
3201    location list of a one-part variable or value VAR, or in that of
3202    any values recursively mentioned in the location lists.  VARS must
3203    be in star-canonical form.  */
3204 
3205 static location_chain *
3206 find_loc_in_1pdv (rtx loc, variable *var, variable_table_type *vars)
3207 {
3208   location_chain *node;
3209   enum rtx_code loc_code;
3210 
3211   if (!var)
3212     return NULL;
3213 
3214   gcc_checking_assert (var->onepart);
3215 
3216   if (!var->n_var_parts)
3217     return NULL;
3218 
3219   gcc_checking_assert (loc != dv_as_opaque (var->dv));
3220 
3221   loc_code = GET_CODE (loc);
3222   for (node = var->var_part[0].loc_chain; node; node = node->next)
3223     {
3224       decl_or_value dv;
3225       variable *rvar;
3226 
3227       if (GET_CODE (node->loc) != loc_code)
3228 	{
3229 	  if (GET_CODE (node->loc) != VALUE)
3230 	    continue;
3231 	}
3232       else if (loc == node->loc)
3233 	return node;
3234       else if (loc_code != VALUE)
3235 	{
3236 	  if (rtx_equal_p (loc, node->loc))
3237 	    return node;
3238 	  continue;
3239 	}
3240 
3241       /* Since we're in star-canonical form, we don't need to visit
3242 	 non-canonical nodes: one-part variables and non-canonical
3243 	 values would only point back to the canonical node.  */
3244       if (dv_is_value_p (var->dv)
3245 	  && !canon_value_cmp (node->loc, dv_as_value (var->dv)))
3246 	{
3247 	  /* Skip all subsequent VALUEs.  */
3248 	  while (node->next && GET_CODE (node->next->loc) == VALUE)
3249 	    {
3250 	      node = node->next;
3251 	      gcc_checking_assert (!canon_value_cmp (node->loc,
3252 						     dv_as_value (var->dv)));
3253 	      if (loc == node->loc)
3254 		return node;
3255 	    }
3256 	  continue;
3257 	}
3258 
3259       gcc_checking_assert (node == var->var_part[0].loc_chain);
3260       gcc_checking_assert (!node->next);
3261 
3262       dv = dv_from_value (node->loc);
3263       rvar = vars->find_with_hash (dv, dv_htab_hash (dv));
3264       return find_loc_in_1pdv (loc, rvar, vars);
3265     }
3266 
3267   /* ??? Gotta look in cselib_val locations too.  */
3268 
3269   return NULL;
3270 }
3271 
3272 /* Hash table iteration argument passed to variable_merge.  */
3273 struct dfset_merge
3274 {
3275   /* The set in which the merge is to be inserted.  */
3276   dataflow_set *dst;
3277   /* The set that we're iterating in.  */
3278   dataflow_set *cur;
3279   /* The set that may contain the other dv we are to merge with.  */
3280   dataflow_set *src;
3281   /* Number of onepart dvs in src.  */
3282   int src_onepart_cnt;
3283 };
3284 
3285 /* Insert LOC in *DNODE, if it's not there yet.  The list must be in
3286    loc_cmp order, and it is maintained as such.  */
3287 
3288 static void
3289 insert_into_intersection (location_chain **nodep, rtx loc,
3290 			  enum var_init_status status)
3291 {
3292   location_chain *node;
3293   int r;
3294 
3295   for (node = *nodep; node; nodep = &node->next, node = *nodep)
3296     if ((r = loc_cmp (node->loc, loc)) == 0)
3297       {
3298 	node->init = MIN (node->init, status);
3299 	return;
3300       }
3301     else if (r > 0)
3302       break;
3303 
3304   node = new location_chain;
3305 
3306   node->loc = loc;
3307   node->set_src = NULL;
3308   node->init = status;
3309   node->next = *nodep;
3310   *nodep = node;
3311 }
3312 
3313 /* Insert in DEST the intersection of the locations present in both
3314    S1NODE and S2VAR, directly or indirectly.  S1NODE is from a
3315    variable in DSM->cur, whereas S2VAR is from DSM->src.  dvar is in
3316    DSM->dst.  */
3317 
3318 static void
3319 intersect_loc_chains (rtx val, location_chain **dest, struct dfset_merge *dsm,
3320 		      location_chain *s1node, variable *s2var)
3321 {
3322   dataflow_set *s1set = dsm->cur;
3323   dataflow_set *s2set = dsm->src;
3324   location_chain *found;
3325 
3326   if (s2var)
3327     {
3328       location_chain *s2node;
3329 
3330       gcc_checking_assert (s2var->onepart);
3331 
3332       if (s2var->n_var_parts)
3333 	{
3334 	  s2node = s2var->var_part[0].loc_chain;
3335 
3336 	  for (; s1node && s2node;
3337 	       s1node = s1node->next, s2node = s2node->next)
3338 	    if (s1node->loc != s2node->loc)
3339 	      break;
3340 	    else if (s1node->loc == val)
3341 	      continue;
3342 	    else
3343 	      insert_into_intersection (dest, s1node->loc,
3344 					MIN (s1node->init, s2node->init));
3345 	}
3346     }
3347 
3348   for (; s1node; s1node = s1node->next)
3349     {
3350       if (s1node->loc == val)
3351 	continue;
3352 
3353       if ((found = find_loc_in_1pdv (s1node->loc, s2var,
3354 				     shared_hash_htab (s2set->vars))))
3355 	{
3356 	  insert_into_intersection (dest, s1node->loc,
3357 				    MIN (s1node->init, found->init));
3358 	  continue;
3359 	}
3360 
3361       if (GET_CODE (s1node->loc) == VALUE
3362 	  && !VALUE_RECURSED_INTO (s1node->loc))
3363 	{
3364 	  decl_or_value dv = dv_from_value (s1node->loc);
3365 	  variable *svar = shared_hash_find (s1set->vars, dv);
3366 	  if (svar)
3367 	    {
3368 	      if (svar->n_var_parts == 1)
3369 		{
3370 		  VALUE_RECURSED_INTO (s1node->loc) = true;
3371 		  intersect_loc_chains (val, dest, dsm,
3372 					svar->var_part[0].loc_chain,
3373 					s2var);
3374 		  VALUE_RECURSED_INTO (s1node->loc) = false;
3375 		}
3376 	    }
3377 	}
3378 
3379       /* ??? gotta look in cselib_val locations too.  */
3380 
3381       /* ??? if the location is equivalent to any location in src,
3382 	 searched recursively
3383 
3384 	   add to dst the values needed to represent the equivalence
3385 
3386      telling whether locations S is equivalent to another dv's
3387      location list:
3388 
3389        for each location D in the list
3390 
3391          if S and D satisfy rtx_equal_p, then it is present
3392 
3393 	 else if D is a value, recurse without cycles
3394 
3395 	 else if S and D have the same CODE and MODE
3396 
3397 	   for each operand oS and the corresponding oD
3398 
3399 	     if oS and oD are not equivalent, then S an D are not equivalent
3400 
3401 	     else if they are RTX vectors
3402 
3403 	       if any vector oS element is not equivalent to its respective oD,
3404 	       then S and D are not equivalent
3405 
3406    */
3407 
3408 
3409     }
3410 }
3411 
3412 /* Return -1 if X should be before Y in a location list for a 1-part
3413    variable, 1 if Y should be before X, and 0 if they're equivalent
3414    and should not appear in the list.  */
3415 
3416 static int
3417 loc_cmp (rtx x, rtx y)
3418 {
3419   int i, j, r;
3420   RTX_CODE code = GET_CODE (x);
3421   const char *fmt;
3422 
3423   if (x == y)
3424     return 0;
3425 
3426   if (REG_P (x))
3427     {
3428       if (!REG_P (y))
3429 	return -1;
3430       gcc_assert (GET_MODE (x) == GET_MODE (y));
3431       if (REGNO (x) == REGNO (y))
3432 	return 0;
3433       else if (REGNO (x) < REGNO (y))
3434 	return -1;
3435       else
3436 	return 1;
3437     }
3438 
3439   if (REG_P (y))
3440     return 1;
3441 
3442   if (MEM_P (x))
3443     {
3444       if (!MEM_P (y))
3445 	return -1;
3446       gcc_assert (GET_MODE (x) == GET_MODE (y));
3447       return loc_cmp (XEXP (x, 0), XEXP (y, 0));
3448     }
3449 
3450   if (MEM_P (y))
3451     return 1;
3452 
3453   if (GET_CODE (x) == VALUE)
3454     {
3455       if (GET_CODE (y) != VALUE)
3456 	return -1;
3457       /* Don't assert the modes are the same, that is true only
3458 	 when not recursing.  (subreg:QI (value:SI 1:1) 0)
3459 	 and (subreg:QI (value:DI 2:2) 0) can be compared,
3460 	 even when the modes are different.  */
3461       if (canon_value_cmp (x, y))
3462 	return -1;
3463       else
3464 	return 1;
3465     }
3466 
3467   if (GET_CODE (y) == VALUE)
3468     return 1;
3469 
3470   /* Entry value is the least preferable kind of expression.  */
3471   if (GET_CODE (x) == ENTRY_VALUE)
3472     {
3473       if (GET_CODE (y) != ENTRY_VALUE)
3474 	return 1;
3475       gcc_assert (GET_MODE (x) == GET_MODE (y));
3476       return loc_cmp (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
3477     }
3478 
3479   if (GET_CODE (y) == ENTRY_VALUE)
3480     return -1;
3481 
3482   if (GET_CODE (x) == GET_CODE (y))
3483     /* Compare operands below.  */;
3484   else if (GET_CODE (x) < GET_CODE (y))
3485     return -1;
3486   else
3487     return 1;
3488 
3489   gcc_assert (GET_MODE (x) == GET_MODE (y));
3490 
3491   if (GET_CODE (x) == DEBUG_EXPR)
3492     {
3493       if (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x))
3494 	  < DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y)))
3495 	return -1;
3496       gcc_checking_assert (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x))
3497 			   > DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y)));
3498       return 1;
3499     }
3500 
3501   fmt = GET_RTX_FORMAT (code);
3502   for (i = 0; i < GET_RTX_LENGTH (code); i++)
3503     switch (fmt[i])
3504       {
3505       case 'w':
3506 	if (XWINT (x, i) == XWINT (y, i))
3507 	  break;
3508 	else if (XWINT (x, i) < XWINT (y, i))
3509 	  return -1;
3510 	else
3511 	  return 1;
3512 
3513       case 'n':
3514       case 'i':
3515 	if (XINT (x, i) == XINT (y, i))
3516 	  break;
3517 	else if (XINT (x, i) < XINT (y, i))
3518 	  return -1;
3519 	else
3520 	  return 1;
3521 
3522       case 'p':
3523 	r = compare_sizes_for_sort (SUBREG_BYTE (x), SUBREG_BYTE (y));
3524 	if (r != 0)
3525 	  return r;
3526 	break;
3527 
3528       case 'V':
3529       case 'E':
3530 	/* Compare the vector length first.  */
3531 	if (XVECLEN (x, i) == XVECLEN (y, i))
3532 	  /* Compare the vectors elements.  */;
3533 	else if (XVECLEN (x, i) < XVECLEN (y, i))
3534 	  return -1;
3535 	else
3536 	  return 1;
3537 
3538 	for (j = 0; j < XVECLEN (x, i); j++)
3539 	  if ((r = loc_cmp (XVECEXP (x, i, j),
3540 			    XVECEXP (y, i, j))))
3541 	    return r;
3542 	break;
3543 
3544       case 'e':
3545 	if ((r = loc_cmp (XEXP (x, i), XEXP (y, i))))
3546 	  return r;
3547 	break;
3548 
3549       case 'S':
3550       case 's':
3551 	if (XSTR (x, i) == XSTR (y, i))
3552 	  break;
3553 	if (!XSTR (x, i))
3554 	  return -1;
3555 	if (!XSTR (y, i))
3556 	  return 1;
3557 	if ((r = strcmp (XSTR (x, i), XSTR (y, i))) == 0)
3558 	  break;
3559 	else if (r < 0)
3560 	  return -1;
3561 	else
3562 	  return 1;
3563 
3564       case 'u':
3565 	/* These are just backpointers, so they don't matter.  */
3566 	break;
3567 
3568       case '0':
3569       case 't':
3570 	break;
3571 
3572 	/* It is believed that rtx's at this level will never
3573 	   contain anything but integers and other rtx's,
3574 	   except for within LABEL_REFs and SYMBOL_REFs.  */
3575       default:
3576 	gcc_unreachable ();
3577       }
3578   if (CONST_WIDE_INT_P (x))
3579     {
3580       /* Compare the vector length first.  */
3581       if (CONST_WIDE_INT_NUNITS (x) >= CONST_WIDE_INT_NUNITS (y))
3582 	return 1;
3583       else if (CONST_WIDE_INT_NUNITS (x) < CONST_WIDE_INT_NUNITS (y))
3584 	return -1;
3585 
3586       /* Compare the vectors elements.  */;
3587       for (j = CONST_WIDE_INT_NUNITS (x) - 1; j >= 0 ; j--)
3588 	{
3589 	  if (CONST_WIDE_INT_ELT (x, j) < CONST_WIDE_INT_ELT (y, j))
3590 	    return -1;
3591 	  if (CONST_WIDE_INT_ELT (x, j) > CONST_WIDE_INT_ELT (y, j))
3592 	    return 1;
3593 	}
3594     }
3595 
3596   return 0;
3597 }
3598 
3599 /* Check the order of entries in one-part variables.   */
3600 
3601 int
3602 canonicalize_loc_order_check (variable **slot,
3603 			      dataflow_set *data ATTRIBUTE_UNUSED)
3604 {
3605   variable *var = *slot;
3606   location_chain *node, *next;
3607 
3608 #ifdef ENABLE_RTL_CHECKING
3609   int i;
3610   for (i = 0; i < var->n_var_parts; i++)
3611     gcc_assert (var->var_part[0].cur_loc == NULL);
3612   gcc_assert (!var->in_changed_variables);
3613 #endif
3614 
3615   if (!var->onepart)
3616     return 1;
3617 
3618   gcc_assert (var->n_var_parts == 1);
3619   node = var->var_part[0].loc_chain;
3620   gcc_assert (node);
3621 
3622   while ((next = node->next))
3623     {
3624       gcc_assert (loc_cmp (node->loc, next->loc) < 0);
3625       node = next;
3626     }
3627 
3628   return 1;
3629 }
3630 
3631 /* Mark with VALUE_RECURSED_INTO values that have neighbors that are
3632    more likely to be chosen as canonical for an equivalence set.
3633    Ensure less likely values can reach more likely neighbors, making
3634    the connections bidirectional.  */
3635 
3636 int
3637 canonicalize_values_mark (variable **slot, dataflow_set *set)
3638 {
3639   variable *var = *slot;
3640   decl_or_value dv = var->dv;
3641   rtx val;
3642   location_chain *node;
3643 
3644   if (!dv_is_value_p (dv))
3645     return 1;
3646 
3647   gcc_checking_assert (var->n_var_parts == 1);
3648 
3649   val = dv_as_value (dv);
3650 
3651   for (node = var->var_part[0].loc_chain; node; node = node->next)
3652     if (GET_CODE (node->loc) == VALUE)
3653       {
3654 	if (canon_value_cmp (node->loc, val))
3655 	  VALUE_RECURSED_INTO (val) = true;
3656 	else
3657 	  {
3658 	    decl_or_value odv = dv_from_value (node->loc);
3659 	    variable **oslot;
3660 	    oslot = shared_hash_find_slot_noinsert (set->vars, odv);
3661 
3662 	    set_slot_part (set, val, oslot, odv, 0,
3663 			   node->init, NULL_RTX);
3664 
3665 	    VALUE_RECURSED_INTO (node->loc) = true;
3666 	  }
3667       }
3668 
3669   return 1;
3670 }
3671 
3672 /* Remove redundant entries from equivalence lists in onepart
3673    variables, canonicalizing equivalence sets into star shapes.  */
3674 
3675 int
3676 canonicalize_values_star (variable **slot, dataflow_set *set)
3677 {
3678   variable *var = *slot;
3679   decl_or_value dv = var->dv;
3680   location_chain *node;
3681   decl_or_value cdv;
3682   rtx val, cval;
3683   variable **cslot;
3684   bool has_value;
3685   bool has_marks;
3686 
3687   if (!var->onepart)
3688     return 1;
3689 
3690   gcc_checking_assert (var->n_var_parts == 1);
3691 
3692   if (dv_is_value_p (dv))
3693     {
3694       cval = dv_as_value (dv);
3695       if (!VALUE_RECURSED_INTO (cval))
3696 	return 1;
3697       VALUE_RECURSED_INTO (cval) = false;
3698     }
3699   else
3700     cval = NULL_RTX;
3701 
3702  restart:
3703   val = cval;
3704   has_value = false;
3705   has_marks = false;
3706 
3707   gcc_assert (var->n_var_parts == 1);
3708 
3709   for (node = var->var_part[0].loc_chain; node; node = node->next)
3710     if (GET_CODE (node->loc) == VALUE)
3711       {
3712 	has_value = true;
3713 	if (VALUE_RECURSED_INTO (node->loc))
3714 	  has_marks = true;
3715 	if (canon_value_cmp (node->loc, cval))
3716 	  cval = node->loc;
3717       }
3718 
3719   if (!has_value)
3720     return 1;
3721 
3722   if (cval == val)
3723     {
3724       if (!has_marks || dv_is_decl_p (dv))
3725 	return 1;
3726 
3727       /* Keep it marked so that we revisit it, either after visiting a
3728 	 child node, or after visiting a new parent that might be
3729 	 found out.  */
3730       VALUE_RECURSED_INTO (val) = true;
3731 
3732       for (node = var->var_part[0].loc_chain; node; node = node->next)
3733 	if (GET_CODE (node->loc) == VALUE
3734 	    && VALUE_RECURSED_INTO (node->loc))
3735 	  {
3736 	    cval = node->loc;
3737 	  restart_with_cval:
3738 	    VALUE_RECURSED_INTO (cval) = false;
3739 	    dv = dv_from_value (cval);
3740 	    slot = shared_hash_find_slot_noinsert (set->vars, dv);
3741 	    if (!slot)
3742 	      {
3743 		gcc_assert (dv_is_decl_p (var->dv));
3744 		/* The canonical value was reset and dropped.
3745 		   Remove it.  */
3746 		clobber_variable_part (set, NULL, var->dv, 0, NULL);
3747 		return 1;
3748 	      }
3749 	    var = *slot;
3750 	    gcc_assert (dv_is_value_p (var->dv));
3751 	    if (var->n_var_parts == 0)
3752 	      return 1;
3753 	    gcc_assert (var->n_var_parts == 1);
3754 	    goto restart;
3755 	  }
3756 
3757       VALUE_RECURSED_INTO (val) = false;
3758 
3759       return 1;
3760     }
3761 
3762   /* Push values to the canonical one.  */
3763   cdv = dv_from_value (cval);
3764   cslot = shared_hash_find_slot_noinsert (set->vars, cdv);
3765 
3766   for (node = var->var_part[0].loc_chain; node; node = node->next)
3767     if (node->loc != cval)
3768       {
3769 	cslot = set_slot_part (set, node->loc, cslot, cdv, 0,
3770 			       node->init, NULL_RTX);
3771 	if (GET_CODE (node->loc) == VALUE)
3772 	  {
3773 	    decl_or_value ndv = dv_from_value (node->loc);
3774 
3775 	    set_variable_part (set, cval, ndv, 0, node->init, NULL_RTX,
3776 			       NO_INSERT);
3777 
3778 	    if (canon_value_cmp (node->loc, val))
3779 	      {
3780 		/* If it could have been a local minimum, it's not any more,
3781 		   since it's now neighbor to cval, so it may have to push
3782 		   to it.  Conversely, if it wouldn't have prevailed over
3783 		   val, then whatever mark it has is fine: if it was to
3784 		   push, it will now push to a more canonical node, but if
3785 		   it wasn't, then it has already pushed any values it might
3786 		   have to.  */
3787 		VALUE_RECURSED_INTO (node->loc) = true;
3788 		/* Make sure we visit node->loc by ensuring we cval is
3789 		   visited too.  */
3790 		VALUE_RECURSED_INTO (cval) = true;
3791 	      }
3792 	    else if (!VALUE_RECURSED_INTO (node->loc))
3793 	      /* If we have no need to "recurse" into this node, it's
3794 		 already "canonicalized", so drop the link to the old
3795 		 parent.  */
3796 	      clobber_variable_part (set, cval, ndv, 0, NULL);
3797 	  }
3798 	else if (GET_CODE (node->loc) == REG)
3799 	  {
3800 	    attrs *list = set->regs[REGNO (node->loc)], **listp;
3801 
3802 	    /* Change an existing attribute referring to dv so that it
3803 	       refers to cdv, removing any duplicate this might
3804 	       introduce, and checking that no previous duplicates
3805 	       existed, all in a single pass.  */
3806 
3807 	    while (list)
3808 	      {
3809 		if (list->offset == 0
3810 		    && (dv_as_opaque (list->dv) == dv_as_opaque (dv)
3811 			|| dv_as_opaque (list->dv) == dv_as_opaque (cdv)))
3812 		  break;
3813 
3814 		list = list->next;
3815 	      }
3816 
3817 	    gcc_assert (list);
3818 	    if (dv_as_opaque (list->dv) == dv_as_opaque (dv))
3819 	      {
3820 		list->dv = cdv;
3821 		for (listp = &list->next; (list = *listp); listp = &list->next)
3822 		  {
3823 		    if (list->offset)
3824 		      continue;
3825 
3826 		    if (dv_as_opaque (list->dv) == dv_as_opaque (cdv))
3827 		      {
3828 			*listp = list->next;
3829 			delete list;
3830 			list = *listp;
3831 			break;
3832 		      }
3833 
3834 		    gcc_assert (dv_as_opaque (list->dv) != dv_as_opaque (dv));
3835 		  }
3836 	      }
3837 	    else if (dv_as_opaque (list->dv) == dv_as_opaque (cdv))
3838 	      {
3839 		for (listp = &list->next; (list = *listp); listp = &list->next)
3840 		  {
3841 		    if (list->offset)
3842 		      continue;
3843 
3844 		    if (dv_as_opaque (list->dv) == dv_as_opaque (dv))
3845 		      {
3846 			*listp = list->next;
3847 			delete list;
3848 			list = *listp;
3849 			break;
3850 		      }
3851 
3852 		    gcc_assert (dv_as_opaque (list->dv) != dv_as_opaque (cdv));
3853 		  }
3854 	      }
3855 	    else
3856 	      gcc_unreachable ();
3857 
3858 	    if (flag_checking)
3859 	      while (list)
3860 		{
3861 		  if (list->offset == 0
3862 		      && (dv_as_opaque (list->dv) == dv_as_opaque (dv)
3863 			  || dv_as_opaque (list->dv) == dv_as_opaque (cdv)))
3864 		    gcc_unreachable ();
3865 
3866 		  list = list->next;
3867 		}
3868 	  }
3869       }
3870 
3871   if (val)
3872     set_slot_part (set, val, cslot, cdv, 0,
3873 		   VAR_INIT_STATUS_INITIALIZED, NULL_RTX);
3874 
3875   slot = clobber_slot_part (set, cval, slot, 0, NULL);
3876 
3877   /* Variable may have been unshared.  */
3878   var = *slot;
3879   gcc_checking_assert (var->n_var_parts && var->var_part[0].loc_chain->loc == cval
3880 		       && var->var_part[0].loc_chain->next == NULL);
3881 
3882   if (VALUE_RECURSED_INTO (cval))
3883     goto restart_with_cval;
3884 
3885   return 1;
3886 }
3887 
3888 /* Bind one-part variables to the canonical value in an equivalence
3889    set.  Not doing this causes dataflow convergence failure in rare
3890    circumstances, see PR42873.  Unfortunately we can't do this
3891    efficiently as part of canonicalize_values_star, since we may not
3892    have determined or even seen the canonical value of a set when we
3893    get to a variable that references another member of the set.  */
3894 
3895 int
3896 canonicalize_vars_star (variable **slot, dataflow_set *set)
3897 {
3898   variable *var = *slot;
3899   decl_or_value dv = var->dv;
3900   location_chain *node;
3901   rtx cval;
3902   decl_or_value cdv;
3903   variable **cslot;
3904   variable *cvar;
3905   location_chain *cnode;
3906 
3907   if (!var->onepart || var->onepart == ONEPART_VALUE)
3908     return 1;
3909 
3910   gcc_assert (var->n_var_parts == 1);
3911 
3912   node = var->var_part[0].loc_chain;
3913 
3914   if (GET_CODE (node->loc) != VALUE)
3915     return 1;
3916 
3917   gcc_assert (!node->next);
3918   cval = node->loc;
3919 
3920   /* Push values to the canonical one.  */
3921   cdv = dv_from_value (cval);
3922   cslot = shared_hash_find_slot_noinsert (set->vars, cdv);
3923   if (!cslot)
3924     return 1;
3925   cvar = *cslot;
3926   gcc_assert (cvar->n_var_parts == 1);
3927 
3928   cnode = cvar->var_part[0].loc_chain;
3929 
3930   /* CVAL is canonical if its value list contains non-VALUEs or VALUEs
3931      that are not “more canonical” than it.  */
3932   if (GET_CODE (cnode->loc) != VALUE
3933       || !canon_value_cmp (cnode->loc, cval))
3934     return 1;
3935 
3936   /* CVAL was found to be non-canonical.  Change the variable to point
3937      to the canonical VALUE.  */
3938   gcc_assert (!cnode->next);
3939   cval = cnode->loc;
3940 
3941   slot = set_slot_part (set, cval, slot, dv, 0,
3942 			node->init, node->set_src);
3943   clobber_slot_part (set, cval, slot, 0, node->set_src);
3944 
3945   return 1;
3946 }
3947 
3948 /* Combine variable or value in *S1SLOT (in DSM->cur) with the
3949    corresponding entry in DSM->src.  Multi-part variables are combined
3950    with variable_union, whereas onepart dvs are combined with
3951    intersection.  */
3952 
3953 static int
3954 variable_merge_over_cur (variable *s1var, struct dfset_merge *dsm)
3955 {
3956   dataflow_set *dst = dsm->dst;
3957   variable **dstslot;
3958   variable *s2var, *dvar = NULL;
3959   decl_or_value dv = s1var->dv;
3960   onepart_enum onepart = s1var->onepart;
3961   rtx val;
3962   hashval_t dvhash;
3963   location_chain *node, **nodep;
3964 
3965   /* If the incoming onepart variable has an empty location list, then
3966      the intersection will be just as empty.  For other variables,
3967      it's always union.  */
3968   gcc_checking_assert (s1var->n_var_parts
3969 		       && s1var->var_part[0].loc_chain);
3970 
3971   if (!onepart)
3972     return variable_union (s1var, dst);
3973 
3974   gcc_checking_assert (s1var->n_var_parts == 1);
3975 
3976   dvhash = dv_htab_hash (dv);
3977   if (dv_is_value_p (dv))
3978     val = dv_as_value (dv);
3979   else
3980     val = NULL;
3981 
3982   s2var = shared_hash_find_1 (dsm->src->vars, dv, dvhash);
3983   if (!s2var)
3984     {
3985       dst_can_be_shared = false;
3986       return 1;
3987     }
3988 
3989   dsm->src_onepart_cnt--;
3990   gcc_assert (s2var->var_part[0].loc_chain
3991 	      && s2var->onepart == onepart
3992 	      && s2var->n_var_parts == 1);
3993 
3994   dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3995   if (dstslot)
3996     {
3997       dvar = *dstslot;
3998       gcc_assert (dvar->refcount == 1
3999 		  && dvar->onepart == onepart
4000 		  && dvar->n_var_parts == 1);
4001       nodep = &dvar->var_part[0].loc_chain;
4002     }
4003   else
4004     {
4005       nodep = &node;
4006       node = NULL;
4007     }
4008 
4009   if (!dstslot && !onepart_variable_different_p (s1var, s2var))
4010     {
4011       dstslot = shared_hash_find_slot_unshare_1 (&dst->vars, dv,
4012 						 dvhash, INSERT);
4013       *dstslot = dvar = s2var;
4014       dvar->refcount++;
4015     }
4016   else
4017     {
4018       dst_can_be_shared = false;
4019 
4020       intersect_loc_chains (val, nodep, dsm,
4021 			    s1var->var_part[0].loc_chain, s2var);
4022 
4023       if (!dstslot)
4024 	{
4025 	  if (node)
4026 	    {
4027 	      dvar = onepart_pool_allocate (onepart);
4028 	      dvar->dv = dv;
4029 	      dvar->refcount = 1;
4030 	      dvar->n_var_parts = 1;
4031 	      dvar->onepart = onepart;
4032 	      dvar->in_changed_variables = false;
4033 	      dvar->var_part[0].loc_chain = node;
4034 	      dvar->var_part[0].cur_loc = NULL;
4035 	      if (onepart)
4036 		VAR_LOC_1PAUX (dvar) = NULL;
4037 	      else
4038 		VAR_PART_OFFSET (dvar, 0) = 0;
4039 
4040 	      dstslot
4041 		= shared_hash_find_slot_unshare_1 (&dst->vars, dv, dvhash,
4042 						   INSERT);
4043 	      gcc_assert (!*dstslot);
4044 	      *dstslot = dvar;
4045 	    }
4046 	  else
4047 	    return 1;
4048 	}
4049     }
4050 
4051   nodep = &dvar->var_part[0].loc_chain;
4052   while ((node = *nodep))
4053     {
4054       location_chain **nextp = &node->next;
4055 
4056       if (GET_CODE (node->loc) == REG)
4057 	{
4058 	  attrs *list;
4059 
4060 	  for (list = dst->regs[REGNO (node->loc)]; list; list = list->next)
4061 	    if (GET_MODE (node->loc) == GET_MODE (list->loc)
4062 		&& dv_is_value_p (list->dv))
4063 	      break;
4064 
4065 	  if (!list)
4066 	    attrs_list_insert (&dst->regs[REGNO (node->loc)],
4067 			       dv, 0, node->loc);
4068 	  /* If this value became canonical for another value that had
4069 	     this register, we want to leave it alone.  */
4070 	  else if (dv_as_value (list->dv) != val)
4071 	    {
4072 	      dstslot = set_slot_part (dst, dv_as_value (list->dv),
4073 				       dstslot, dv, 0,
4074 				       node->init, NULL_RTX);
4075 	      dstslot = delete_slot_part (dst, node->loc, dstslot, 0);
4076 
4077 	      /* Since nextp points into the removed node, we can't
4078 		 use it.  The pointer to the next node moved to nodep.
4079 		 However, if the variable we're walking is unshared
4080 		 during our walk, we'll keep walking the location list
4081 		 of the previously-shared variable, in which case the
4082 		 node won't have been removed, and we'll want to skip
4083 		 it.  That's why we test *nodep here.  */
4084 	      if (*nodep != node)
4085 		nextp = nodep;
4086 	    }
4087 	}
4088       else
4089 	/* Canonicalization puts registers first, so we don't have to
4090 	   walk it all.  */
4091 	break;
4092       nodep = nextp;
4093     }
4094 
4095   if (dvar != *dstslot)
4096     dvar = *dstslot;
4097   nodep = &dvar->var_part[0].loc_chain;
4098 
4099   if (val)
4100     {
4101       /* Mark all referenced nodes for canonicalization, and make sure
4102 	 we have mutual equivalence links.  */
4103       VALUE_RECURSED_INTO (val) = true;
4104       for (node = *nodep; node; node = node->next)
4105 	if (GET_CODE (node->loc) == VALUE)
4106 	  {
4107 	    VALUE_RECURSED_INTO (node->loc) = true;
4108 	    set_variable_part (dst, val, dv_from_value (node->loc), 0,
4109 			       node->init, NULL, INSERT);
4110 	  }
4111 
4112       dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
4113       gcc_assert (*dstslot == dvar);
4114       canonicalize_values_star (dstslot, dst);
4115       gcc_checking_assert (dstslot
4116 			   == shared_hash_find_slot_noinsert_1 (dst->vars,
4117 								dv, dvhash));
4118       dvar = *dstslot;
4119     }
4120   else
4121     {
4122       bool has_value = false, has_other = false;
4123 
4124       /* If we have one value and anything else, we're going to
4125 	 canonicalize this, so make sure all values have an entry in
4126 	 the table and are marked for canonicalization.  */
4127       for (node = *nodep; node; node = node->next)
4128 	{
4129 	  if (GET_CODE (node->loc) == VALUE)
4130 	    {
4131 	      /* If this was marked during register canonicalization,
4132 		 we know we have to canonicalize values.  */
4133 	      if (has_value)
4134 		has_other = true;
4135 	      has_value = true;
4136 	      if (has_other)
4137 		break;
4138 	    }
4139 	  else
4140 	    {
4141 	      has_other = true;
4142 	      if (has_value)
4143 		break;
4144 	    }
4145 	}
4146 
4147       if (has_value && has_other)
4148 	{
4149 	  for (node = *nodep; node; node = node->next)
4150 	    {
4151 	      if (GET_CODE (node->loc) == VALUE)
4152 		{
4153 		  decl_or_value dv = dv_from_value (node->loc);
4154 		  variable **slot = NULL;
4155 
4156 		  if (shared_hash_shared (dst->vars))
4157 		    slot = shared_hash_find_slot_noinsert (dst->vars, dv);
4158 		  if (!slot)
4159 		    slot = shared_hash_find_slot_unshare (&dst->vars, dv,
4160 							  INSERT);
4161 		  if (!*slot)
4162 		    {
4163 		      variable *var = onepart_pool_allocate (ONEPART_VALUE);
4164 		      var->dv = dv;
4165 		      var->refcount = 1;
4166 		      var->n_var_parts = 1;
4167 		      var->onepart = ONEPART_VALUE;
4168 		      var->in_changed_variables = false;
4169 		      var->var_part[0].loc_chain = NULL;
4170 		      var->var_part[0].cur_loc = NULL;
4171 		      VAR_LOC_1PAUX (var) = NULL;
4172 		      *slot = var;
4173 		    }
4174 
4175 		  VALUE_RECURSED_INTO (node->loc) = true;
4176 		}
4177 	    }
4178 
4179 	  dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
4180 	  gcc_assert (*dstslot == dvar);
4181 	  canonicalize_values_star (dstslot, dst);
4182 	  gcc_checking_assert (dstslot
4183 			       == shared_hash_find_slot_noinsert_1 (dst->vars,
4184 								    dv, dvhash));
4185 	  dvar = *dstslot;
4186 	}
4187     }
4188 
4189   if (!onepart_variable_different_p (dvar, s2var))
4190     {
4191       variable_htab_free (dvar);
4192       *dstslot = dvar = s2var;
4193       dvar->refcount++;
4194     }
4195   else if (s2var != s1var && !onepart_variable_different_p (dvar, s1var))
4196     {
4197       variable_htab_free (dvar);
4198       *dstslot = dvar = s1var;
4199       dvar->refcount++;
4200       dst_can_be_shared = false;
4201     }
4202   else
4203     dst_can_be_shared = false;
4204 
4205   return 1;
4206 }
4207 
4208 /* Copy s2slot (in DSM->src) to DSM->dst if the variable is a
4209    multi-part variable.  Unions of multi-part variables and
4210    intersections of one-part ones will be handled in
4211    variable_merge_over_cur().  */
4212 
4213 static int
4214 variable_merge_over_src (variable *s2var, struct dfset_merge *dsm)
4215 {
4216   dataflow_set *dst = dsm->dst;
4217   decl_or_value dv = s2var->dv;
4218 
4219   if (!s2var->onepart)
4220     {
4221       variable **dstp = shared_hash_find_slot (dst->vars, dv);
4222       *dstp = s2var;
4223       s2var->refcount++;
4224       return 1;
4225     }
4226 
4227   dsm->src_onepart_cnt++;
4228   return 1;
4229 }
4230 
4231 /* Combine dataflow set information from SRC2 into DST, using PDST
4232    to carry over information across passes.  */
4233 
4234 static void
4235 dataflow_set_merge (dataflow_set *dst, dataflow_set *src2)
4236 {
4237   dataflow_set cur = *dst;
4238   dataflow_set *src1 = &cur;
4239   struct dfset_merge dsm;
4240   int i;
4241   size_t src1_elems, src2_elems;
4242   variable_iterator_type hi;
4243   variable *var;
4244 
4245   src1_elems = shared_hash_htab (src1->vars)->elements ();
4246   src2_elems = shared_hash_htab (src2->vars)->elements ();
4247   dataflow_set_init (dst);
4248   dst->stack_adjust = cur.stack_adjust;
4249   shared_hash_destroy (dst->vars);
4250   dst->vars = new shared_hash;
4251   dst->vars->refcount = 1;
4252   dst->vars->htab = new variable_table_type (MAX (src1_elems, src2_elems));
4253 
4254   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4255     attrs_list_mpdv_union (&dst->regs[i], src1->regs[i], src2->regs[i]);
4256 
4257   dsm.dst = dst;
4258   dsm.src = src2;
4259   dsm.cur = src1;
4260   dsm.src_onepart_cnt = 0;
4261 
4262   FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (dsm.src->vars),
4263 			       var, variable, hi)
4264     variable_merge_over_src (var, &dsm);
4265   FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (dsm.cur->vars),
4266 			       var, variable, hi)
4267     variable_merge_over_cur (var, &dsm);
4268 
4269   if (dsm.src_onepart_cnt)
4270     dst_can_be_shared = false;
4271 
4272   dataflow_set_destroy (src1);
4273 }
4274 
4275 /* Mark register equivalences.  */
4276 
4277 static void
4278 dataflow_set_equiv_regs (dataflow_set *set)
4279 {
4280   int i;
4281   attrs *list, **listp;
4282 
4283   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4284     {
4285       rtx canon[NUM_MACHINE_MODES];
4286 
4287       /* If the list is empty or one entry, no need to canonicalize
4288 	 anything.  */
4289       if (set->regs[i] == NULL || set->regs[i]->next == NULL)
4290 	continue;
4291 
4292       memset (canon, 0, sizeof (canon));
4293 
4294       for (list = set->regs[i]; list; list = list->next)
4295 	if (list->offset == 0 && dv_is_value_p (list->dv))
4296 	  {
4297 	    rtx val = dv_as_value (list->dv);
4298 	    rtx *cvalp = &canon[(int)GET_MODE (val)];
4299 	    rtx cval = *cvalp;
4300 
4301 	    if (canon_value_cmp (val, cval))
4302 	      *cvalp = val;
4303 	  }
4304 
4305       for (list = set->regs[i]; list; list = list->next)
4306 	if (list->offset == 0 && dv_onepart_p (list->dv))
4307 	  {
4308 	    rtx cval = canon[(int)GET_MODE (list->loc)];
4309 
4310 	    if (!cval)
4311 	      continue;
4312 
4313 	    if (dv_is_value_p (list->dv))
4314 	      {
4315 		rtx val = dv_as_value (list->dv);
4316 
4317 		if (val == cval)
4318 		  continue;
4319 
4320 		VALUE_RECURSED_INTO (val) = true;
4321 		set_variable_part (set, val, dv_from_value (cval), 0,
4322 				   VAR_INIT_STATUS_INITIALIZED,
4323 				   NULL, NO_INSERT);
4324 	      }
4325 
4326 	    VALUE_RECURSED_INTO (cval) = true;
4327 	    set_variable_part (set, cval, list->dv, 0,
4328 			       VAR_INIT_STATUS_INITIALIZED, NULL, NO_INSERT);
4329 	  }
4330 
4331       for (listp = &set->regs[i]; (list = *listp);
4332 	   listp = list ? &list->next : listp)
4333 	if (list->offset == 0 && dv_onepart_p (list->dv))
4334 	  {
4335 	    rtx cval = canon[(int)GET_MODE (list->loc)];
4336 	    variable **slot;
4337 
4338 	    if (!cval)
4339 	      continue;
4340 
4341 	    if (dv_is_value_p (list->dv))
4342 	      {
4343 		rtx val = dv_as_value (list->dv);
4344 		if (!VALUE_RECURSED_INTO (val))
4345 		  continue;
4346 	      }
4347 
4348 	    slot = shared_hash_find_slot_noinsert (set->vars, list->dv);
4349 	    canonicalize_values_star (slot, set);
4350 	    if (*listp != list)
4351 	      list = NULL;
4352 	  }
4353     }
4354 }
4355 
4356 /* Remove any redundant values in the location list of VAR, which must
4357    be unshared and 1-part.  */
4358 
4359 static void
4360 remove_duplicate_values (variable *var)
4361 {
4362   location_chain *node, **nodep;
4363 
4364   gcc_assert (var->onepart);
4365   gcc_assert (var->n_var_parts == 1);
4366   gcc_assert (var->refcount == 1);
4367 
4368   for (nodep = &var->var_part[0].loc_chain; (node = *nodep); )
4369     {
4370       if (GET_CODE (node->loc) == VALUE)
4371 	{
4372 	  if (VALUE_RECURSED_INTO (node->loc))
4373 	    {
4374 	      /* Remove duplicate value node.  */
4375 	      *nodep = node->next;
4376 	      delete node;
4377 	      continue;
4378 	    }
4379 	  else
4380 	    VALUE_RECURSED_INTO (node->loc) = true;
4381 	}
4382       nodep = &node->next;
4383     }
4384 
4385   for (node = var->var_part[0].loc_chain; node; node = node->next)
4386     if (GET_CODE (node->loc) == VALUE)
4387       {
4388 	gcc_assert (VALUE_RECURSED_INTO (node->loc));
4389 	VALUE_RECURSED_INTO (node->loc) = false;
4390       }
4391 }
4392 
4393 
4394 /* Hash table iteration argument passed to variable_post_merge.  */
4395 struct dfset_post_merge
4396 {
4397   /* The new input set for the current block.  */
4398   dataflow_set *set;
4399   /* Pointer to the permanent input set for the current block, or
4400      NULL.  */
4401   dataflow_set **permp;
4402 };
4403 
4404 /* Create values for incoming expressions associated with one-part
4405    variables that don't have value numbers for them.  */
4406 
4407 int
4408 variable_post_merge_new_vals (variable **slot, dfset_post_merge *dfpm)
4409 {
4410   dataflow_set *set = dfpm->set;
4411   variable *var = *slot;
4412   location_chain *node;
4413 
4414   if (!var->onepart || !var->n_var_parts)
4415     return 1;
4416 
4417   gcc_assert (var->n_var_parts == 1);
4418 
4419   if (dv_is_decl_p (var->dv))
4420     {
4421       bool check_dupes = false;
4422 
4423     restart:
4424       for (node = var->var_part[0].loc_chain; node; node = node->next)
4425 	{
4426 	  if (GET_CODE (node->loc) == VALUE)
4427 	    gcc_assert (!VALUE_RECURSED_INTO (node->loc));
4428 	  else if (GET_CODE (node->loc) == REG)
4429 	    {
4430 	      attrs *att, **attp, **curp = NULL;
4431 
4432 	      if (var->refcount != 1)
4433 		{
4434 		  slot = unshare_variable (set, slot, var,
4435 					   VAR_INIT_STATUS_INITIALIZED);
4436 		  var = *slot;
4437 		  goto restart;
4438 		}
4439 
4440 	      for (attp = &set->regs[REGNO (node->loc)]; (att = *attp);
4441 		   attp = &att->next)
4442 		if (att->offset == 0
4443 		    && GET_MODE (att->loc) == GET_MODE (node->loc))
4444 		  {
4445 		    if (dv_is_value_p (att->dv))
4446 		      {
4447 			rtx cval = dv_as_value (att->dv);
4448 			node->loc = cval;
4449 			check_dupes = true;
4450 			break;
4451 		      }
4452 		    else if (dv_as_opaque (att->dv) == dv_as_opaque (var->dv))
4453 		      curp = attp;
4454 		  }
4455 
4456 	      if (!curp)
4457 		{
4458 		  curp = attp;
4459 		  while (*curp)
4460 		    if ((*curp)->offset == 0
4461 			&& GET_MODE ((*curp)->loc) == GET_MODE (node->loc)
4462 			&& dv_as_opaque ((*curp)->dv) == dv_as_opaque (var->dv))
4463 		      break;
4464 		    else
4465 		      curp = &(*curp)->next;
4466 		  gcc_assert (*curp);
4467 		}
4468 
4469 	      if (!att)
4470 		{
4471 		  decl_or_value cdv;
4472 		  rtx cval;
4473 
4474 		  if (!*dfpm->permp)
4475 		    {
4476 		      *dfpm->permp = XNEW (dataflow_set);
4477 		      dataflow_set_init (*dfpm->permp);
4478 		    }
4479 
4480 		  for (att = (*dfpm->permp)->regs[REGNO (node->loc)];
4481 		       att; att = att->next)
4482 		    if (GET_MODE (att->loc) == GET_MODE (node->loc))
4483 		      {
4484 			gcc_assert (att->offset == 0
4485 				    && dv_is_value_p (att->dv));
4486 			val_reset (set, att->dv);
4487 			break;
4488 		      }
4489 
4490 		  if (att)
4491 		    {
4492 		      cdv = att->dv;
4493 		      cval = dv_as_value (cdv);
4494 		    }
4495 		  else
4496 		    {
4497 		      /* Create a unique value to hold this register,
4498 			 that ought to be found and reused in
4499 			 subsequent rounds.  */
4500 		      cselib_val *v;
4501 		      gcc_assert (!cselib_lookup (node->loc,
4502 						  GET_MODE (node->loc), 0,
4503 						  VOIDmode));
4504 		      v = cselib_lookup (node->loc, GET_MODE (node->loc), 1,
4505 					 VOIDmode);
4506 		      cselib_preserve_value (v);
4507 		      cselib_invalidate_rtx (node->loc);
4508 		      cval = v->val_rtx;
4509 		      cdv = dv_from_value (cval);
4510 		      if (dump_file)
4511 			fprintf (dump_file,
4512 				 "Created new value %u:%u for reg %i\n",
4513 				 v->uid, v->hash, REGNO (node->loc));
4514 		    }
4515 
4516 		  var_reg_decl_set (*dfpm->permp, node->loc,
4517 				    VAR_INIT_STATUS_INITIALIZED,
4518 				    cdv, 0, NULL, INSERT);
4519 
4520 		  node->loc = cval;
4521 		  check_dupes = true;
4522 		}
4523 
4524 	      /* Remove attribute referring to the decl, which now
4525 		 uses the value for the register, already existing or
4526 		 to be added when we bring perm in.  */
4527 	      att = *curp;
4528 	      *curp = att->next;
4529 	      delete att;
4530 	    }
4531 	}
4532 
4533       if (check_dupes)
4534 	remove_duplicate_values (var);
4535     }
4536 
4537   return 1;
4538 }
4539 
4540 /* Reset values in the permanent set that are not associated with the
4541    chosen expression.  */
4542 
4543 int
4544 variable_post_merge_perm_vals (variable **pslot, dfset_post_merge *dfpm)
4545 {
4546   dataflow_set *set = dfpm->set;
4547   variable *pvar = *pslot, *var;
4548   location_chain *pnode;
4549   decl_or_value dv;
4550   attrs *att;
4551 
4552   gcc_assert (dv_is_value_p (pvar->dv)
4553 	      && pvar->n_var_parts == 1);
4554   pnode = pvar->var_part[0].loc_chain;
4555   gcc_assert (pnode
4556 	      && !pnode->next
4557 	      && REG_P (pnode->loc));
4558 
4559   dv = pvar->dv;
4560 
4561   var = shared_hash_find (set->vars, dv);
4562   if (var)
4563     {
4564       /* Although variable_post_merge_new_vals may have made decls
4565 	 non-star-canonical, values that pre-existed in canonical form
4566 	 remain canonical, and newly-created values reference a single
4567 	 REG, so they are canonical as well.  Since VAR has the
4568 	 location list for a VALUE, using find_loc_in_1pdv for it is
4569 	 fine, since VALUEs don't map back to DECLs.  */
4570       if (find_loc_in_1pdv (pnode->loc, var, shared_hash_htab (set->vars)))
4571 	return 1;
4572       val_reset (set, dv);
4573     }
4574 
4575   for (att = set->regs[REGNO (pnode->loc)]; att; att = att->next)
4576     if (att->offset == 0
4577 	&& GET_MODE (att->loc) == GET_MODE (pnode->loc)
4578 	&& dv_is_value_p (att->dv))
4579       break;
4580 
4581   /* If there is a value associated with this register already, create
4582      an equivalence.  */
4583   if (att && dv_as_value (att->dv) != dv_as_value (dv))
4584     {
4585       rtx cval = dv_as_value (att->dv);
4586       set_variable_part (set, cval, dv, 0, pnode->init, NULL, INSERT);
4587       set_variable_part (set, dv_as_value (dv), att->dv, 0, pnode->init,
4588 			 NULL, INSERT);
4589     }
4590   else if (!att)
4591     {
4592       attrs_list_insert (&set->regs[REGNO (pnode->loc)],
4593 			 dv, 0, pnode->loc);
4594       variable_union (pvar, set);
4595     }
4596 
4597   return 1;
4598 }
4599 
4600 /* Just checking stuff and registering register attributes for
4601    now.  */
4602 
4603 static void
4604 dataflow_post_merge_adjust (dataflow_set *set, dataflow_set **permp)
4605 {
4606   struct dfset_post_merge dfpm;
4607 
4608   dfpm.set = set;
4609   dfpm.permp = permp;
4610 
4611   shared_hash_htab (set->vars)
4612     ->traverse <dfset_post_merge*, variable_post_merge_new_vals> (&dfpm);
4613   if (*permp)
4614     shared_hash_htab ((*permp)->vars)
4615       ->traverse <dfset_post_merge*, variable_post_merge_perm_vals> (&dfpm);
4616   shared_hash_htab (set->vars)
4617     ->traverse <dataflow_set *, canonicalize_values_star> (set);
4618   shared_hash_htab (set->vars)
4619     ->traverse <dataflow_set *, canonicalize_vars_star> (set);
4620 }
4621 
4622 /* Return a node whose loc is a MEM that refers to EXPR in the
4623    location list of a one-part variable or value VAR, or in that of
4624    any values recursively mentioned in the location lists.  */
4625 
4626 static location_chain *
4627 find_mem_expr_in_1pdv (tree expr, rtx val, variable_table_type *vars)
4628 {
4629   location_chain *node;
4630   decl_or_value dv;
4631   variable *var;
4632   location_chain *where = NULL;
4633 
4634   if (!val)
4635     return NULL;
4636 
4637   gcc_assert (GET_CODE (val) == VALUE
4638 	      && !VALUE_RECURSED_INTO (val));
4639 
4640   dv = dv_from_value (val);
4641   var = vars->find_with_hash (dv, dv_htab_hash (dv));
4642 
4643   if (!var)
4644     return NULL;
4645 
4646   gcc_assert (var->onepart);
4647 
4648   if (!var->n_var_parts)
4649     return NULL;
4650 
4651   VALUE_RECURSED_INTO (val) = true;
4652 
4653   for (node = var->var_part[0].loc_chain; node; node = node->next)
4654     if (MEM_P (node->loc)
4655 	&& MEM_EXPR (node->loc) == expr
4656 	&& int_mem_offset (node->loc) == 0)
4657       {
4658 	where = node;
4659 	break;
4660       }
4661     else if (GET_CODE (node->loc) == VALUE
4662 	     && !VALUE_RECURSED_INTO (node->loc)
4663 	     && (where = find_mem_expr_in_1pdv (expr, node->loc, vars)))
4664       break;
4665 
4666   VALUE_RECURSED_INTO (val) = false;
4667 
4668   return where;
4669 }
4670 
4671 /* Return TRUE if the value of MEM may vary across a call.  */
4672 
4673 static bool
4674 mem_dies_at_call (rtx mem)
4675 {
4676   tree expr = MEM_EXPR (mem);
4677   tree decl;
4678 
4679   if (!expr)
4680     return true;
4681 
4682   decl = get_base_address (expr);
4683 
4684   if (!decl)
4685     return true;
4686 
4687   if (!DECL_P (decl))
4688     return true;
4689 
4690   return (may_be_aliased (decl)
4691 	  || (!TREE_READONLY (decl) && is_global_var (decl)));
4692 }
4693 
4694 /* Remove all MEMs from the location list of a hash table entry for a
4695    one-part variable, except those whose MEM attributes map back to
4696    the variable itself, directly or within a VALUE.  */
4697 
4698 int
4699 dataflow_set_preserve_mem_locs (variable **slot, dataflow_set *set)
4700 {
4701   variable *var = *slot;
4702 
4703   if (var->onepart == ONEPART_VDECL || var->onepart == ONEPART_DEXPR)
4704     {
4705       tree decl = dv_as_decl (var->dv);
4706       location_chain *loc, **locp;
4707       bool changed = false;
4708 
4709       if (!var->n_var_parts)
4710 	return 1;
4711 
4712       gcc_assert (var->n_var_parts == 1);
4713 
4714       if (shared_var_p (var, set->vars))
4715 	{
4716 	  for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
4717 	    {
4718 	      /* We want to remove dying MEMs that don't refer to DECL.  */
4719 	      if (GET_CODE (loc->loc) == MEM
4720 		  && (MEM_EXPR (loc->loc) != decl
4721 		      || int_mem_offset (loc->loc) != 0)
4722 		  && mem_dies_at_call (loc->loc))
4723 		break;
4724 	      /* We want to move here MEMs that do refer to DECL.  */
4725 	      else if (GET_CODE (loc->loc) == VALUE
4726 		       && find_mem_expr_in_1pdv (decl, loc->loc,
4727 						 shared_hash_htab (set->vars)))
4728 		break;
4729 	    }
4730 
4731 	  if (!loc)
4732 	    return 1;
4733 
4734 	  slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
4735 	  var = *slot;
4736 	  gcc_assert (var->n_var_parts == 1);
4737 	}
4738 
4739       for (locp = &var->var_part[0].loc_chain, loc = *locp;
4740 	   loc; loc = *locp)
4741 	{
4742 	  rtx old_loc = loc->loc;
4743 	  if (GET_CODE (old_loc) == VALUE)
4744 	    {
4745 	      location_chain *mem_node
4746 		= find_mem_expr_in_1pdv (decl, loc->loc,
4747 					 shared_hash_htab (set->vars));
4748 
4749 	      /* ??? This picks up only one out of multiple MEMs that
4750 		 refer to the same variable.  Do we ever need to be
4751 		 concerned about dealing with more than one, or, given
4752 		 that they should all map to the same variable
4753 		 location, their addresses will have been merged and
4754 		 they will be regarded as equivalent?  */
4755 	      if (mem_node)
4756 		{
4757 		  loc->loc = mem_node->loc;
4758 		  loc->set_src = mem_node->set_src;
4759 		  loc->init = MIN (loc->init, mem_node->init);
4760 		}
4761 	    }
4762 
4763 	  if (GET_CODE (loc->loc) != MEM
4764 	      || (MEM_EXPR (loc->loc) == decl
4765 		  && int_mem_offset (loc->loc) == 0)
4766 	      || !mem_dies_at_call (loc->loc))
4767 	    {
4768 	      if (old_loc != loc->loc && emit_notes)
4769 		{
4770 		  if (old_loc == var->var_part[0].cur_loc)
4771 		    {
4772 		      changed = true;
4773 		      var->var_part[0].cur_loc = NULL;
4774 		    }
4775 		}
4776 	      locp = &loc->next;
4777 	      continue;
4778 	    }
4779 
4780 	  if (emit_notes)
4781 	    {
4782 	      if (old_loc == var->var_part[0].cur_loc)
4783 		{
4784 		  changed = true;
4785 		  var->var_part[0].cur_loc = NULL;
4786 		}
4787 	    }
4788 	  *locp = loc->next;
4789 	  delete loc;
4790 	}
4791 
4792       if (!var->var_part[0].loc_chain)
4793 	{
4794 	  var->n_var_parts--;
4795 	  changed = true;
4796 	}
4797       if (changed)
4798 	variable_was_changed (var, set);
4799     }
4800 
4801   return 1;
4802 }
4803 
4804 /* Remove all MEMs from the location list of a hash table entry for a
4805    onepart variable.  */
4806 
4807 int
4808 dataflow_set_remove_mem_locs (variable **slot, dataflow_set *set)
4809 {
4810   variable *var = *slot;
4811 
4812   if (var->onepart != NOT_ONEPART)
4813     {
4814       location_chain *loc, **locp;
4815       bool changed = false;
4816       rtx cur_loc;
4817 
4818       gcc_assert (var->n_var_parts == 1);
4819 
4820       if (shared_var_p (var, set->vars))
4821 	{
4822 	  for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
4823 	    if (GET_CODE (loc->loc) == MEM
4824 		&& mem_dies_at_call (loc->loc))
4825 	      break;
4826 
4827 	  if (!loc)
4828 	    return 1;
4829 
4830 	  slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
4831 	  var = *slot;
4832 	  gcc_assert (var->n_var_parts == 1);
4833 	}
4834 
4835       if (VAR_LOC_1PAUX (var))
4836 	cur_loc = VAR_LOC_FROM (var);
4837       else
4838 	cur_loc = var->var_part[0].cur_loc;
4839 
4840       for (locp = &var->var_part[0].loc_chain, loc = *locp;
4841 	   loc; loc = *locp)
4842 	{
4843 	  if (GET_CODE (loc->loc) != MEM
4844 	      || !mem_dies_at_call (loc->loc))
4845 	    {
4846 	      locp = &loc->next;
4847 	      continue;
4848 	    }
4849 
4850 	  *locp = loc->next;
4851 	  /* If we have deleted the location which was last emitted
4852 	     we have to emit new location so add the variable to set
4853 	     of changed variables.  */
4854 	  if (cur_loc == loc->loc)
4855 	    {
4856 	      changed = true;
4857 	      var->var_part[0].cur_loc = NULL;
4858 	      if (VAR_LOC_1PAUX (var))
4859 		VAR_LOC_FROM (var) = NULL;
4860 	    }
4861 	  delete loc;
4862 	}
4863 
4864       if (!var->var_part[0].loc_chain)
4865 	{
4866 	  var->n_var_parts--;
4867 	  changed = true;
4868 	}
4869       if (changed)
4870 	variable_was_changed (var, set);
4871     }
4872 
4873   return 1;
4874 }
4875 
4876 /* Remove all variable-location information about call-clobbered
4877    registers, as well as associations between MEMs and VALUEs.  */
4878 
4879 static void
4880 dataflow_set_clear_at_call (dataflow_set *set, rtx_insn *call_insn)
4881 {
4882   unsigned int r;
4883   hard_reg_set_iterator hrsi;
4884   HARD_REG_SET invalidated_regs;
4885 
4886   get_call_reg_set_usage (call_insn, &invalidated_regs,
4887 			  regs_invalidated_by_call);
4888 
4889   EXECUTE_IF_SET_IN_HARD_REG_SET (invalidated_regs, 0, r, hrsi)
4890     var_regno_delete (set, r);
4891 
4892   if (MAY_HAVE_DEBUG_BIND_INSNS)
4893     {
4894       set->traversed_vars = set->vars;
4895       shared_hash_htab (set->vars)
4896 	->traverse <dataflow_set *, dataflow_set_preserve_mem_locs> (set);
4897       set->traversed_vars = set->vars;
4898       shared_hash_htab (set->vars)
4899 	->traverse <dataflow_set *, dataflow_set_remove_mem_locs> (set);
4900       set->traversed_vars = NULL;
4901     }
4902 }
4903 
4904 static bool
4905 variable_part_different_p (variable_part *vp1, variable_part *vp2)
4906 {
4907   location_chain *lc1, *lc2;
4908 
4909   for (lc1 = vp1->loc_chain; lc1; lc1 = lc1->next)
4910     {
4911       for (lc2 = vp2->loc_chain; lc2; lc2 = lc2->next)
4912 	{
4913 	  if (REG_P (lc1->loc) && REG_P (lc2->loc))
4914 	    {
4915 	      if (REGNO (lc1->loc) == REGNO (lc2->loc))
4916 		break;
4917 	    }
4918 	  if (rtx_equal_p (lc1->loc, lc2->loc))
4919 	    break;
4920 	}
4921       if (!lc2)
4922 	return true;
4923     }
4924   return false;
4925 }
4926 
4927 /* Return true if one-part variables VAR1 and VAR2 are different.
4928    They must be in canonical order.  */
4929 
4930 static bool
4931 onepart_variable_different_p (variable *var1, variable *var2)
4932 {
4933   location_chain *lc1, *lc2;
4934 
4935   if (var1 == var2)
4936     return false;
4937 
4938   gcc_assert (var1->n_var_parts == 1
4939 	      && var2->n_var_parts == 1);
4940 
4941   lc1 = var1->var_part[0].loc_chain;
4942   lc2 = var2->var_part[0].loc_chain;
4943 
4944   gcc_assert (lc1 && lc2);
4945 
4946   while (lc1 && lc2)
4947     {
4948       if (loc_cmp (lc1->loc, lc2->loc))
4949 	return true;
4950       lc1 = lc1->next;
4951       lc2 = lc2->next;
4952     }
4953 
4954   return lc1 != lc2;
4955 }
4956 
4957 /* Return true if one-part variables VAR1 and VAR2 are different.
4958    They must be in canonical order.  */
4959 
4960 static void
4961 dump_onepart_variable_differences (variable *var1, variable *var2)
4962 {
4963   location_chain *lc1, *lc2;
4964 
4965   gcc_assert (var1 != var2);
4966   gcc_assert (dump_file);
4967   gcc_assert (dv_as_opaque (var1->dv) == dv_as_opaque (var2->dv));
4968   gcc_assert (var1->n_var_parts == 1
4969 	      && var2->n_var_parts == 1);
4970 
4971   lc1 = var1->var_part[0].loc_chain;
4972   lc2 = var2->var_part[0].loc_chain;
4973 
4974   gcc_assert (lc1 && lc2);
4975 
4976   while (lc1 && lc2)
4977     {
4978       switch (loc_cmp (lc1->loc, lc2->loc))
4979 	{
4980 	case -1:
4981 	  fprintf (dump_file, "removed: ");
4982 	  print_rtl_single (dump_file, lc1->loc);
4983 	  lc1 = lc1->next;
4984 	  continue;
4985 	case 0:
4986 	  break;
4987 	case 1:
4988 	  fprintf (dump_file, "added: ");
4989 	  print_rtl_single (dump_file, lc2->loc);
4990 	  lc2 = lc2->next;
4991 	  continue;
4992 	default:
4993 	  gcc_unreachable ();
4994 	}
4995       lc1 = lc1->next;
4996       lc2 = lc2->next;
4997     }
4998 
4999   while (lc1)
5000     {
5001       fprintf (dump_file, "removed: ");
5002       print_rtl_single (dump_file, lc1->loc);
5003       lc1 = lc1->next;
5004     }
5005 
5006   while (lc2)
5007     {
5008       fprintf (dump_file, "added: ");
5009       print_rtl_single (dump_file, lc2->loc);
5010       lc2 = lc2->next;
5011     }
5012 }
5013 
5014 /* Return true if variables VAR1 and VAR2 are different.  */
5015 
5016 static bool
5017 variable_different_p (variable *var1, variable *var2)
5018 {
5019   int i;
5020 
5021   if (var1 == var2)
5022     return false;
5023 
5024   if (var1->onepart != var2->onepart)
5025     return true;
5026 
5027   if (var1->n_var_parts != var2->n_var_parts)
5028     return true;
5029 
5030   if (var1->onepart && var1->n_var_parts)
5031     {
5032       gcc_checking_assert (dv_as_opaque (var1->dv) == dv_as_opaque (var2->dv)
5033 			   && var1->n_var_parts == 1);
5034       /* One-part values have locations in a canonical order.  */
5035       return onepart_variable_different_p (var1, var2);
5036     }
5037 
5038   for (i = 0; i < var1->n_var_parts; i++)
5039     {
5040       if (VAR_PART_OFFSET (var1, i) != VAR_PART_OFFSET (var2, i))
5041 	return true;
5042       if (variable_part_different_p (&var1->var_part[i], &var2->var_part[i]))
5043 	return true;
5044       if (variable_part_different_p (&var2->var_part[i], &var1->var_part[i]))
5045 	return true;
5046     }
5047   return false;
5048 }
5049 
5050 /* Return true if dataflow sets OLD_SET and NEW_SET differ.  */
5051 
5052 static bool
5053 dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
5054 {
5055   variable_iterator_type hi;
5056   variable *var1;
5057   bool diffound = false;
5058   bool details = (dump_file && (dump_flags & TDF_DETAILS));
5059 
5060 #define RETRUE					\
5061   do						\
5062     {						\
5063       if (!details)				\
5064 	return true;				\
5065       else					\
5066 	diffound = true;			\
5067     }						\
5068   while (0)
5069 
5070   if (old_set->vars == new_set->vars)
5071     return false;
5072 
5073   if (shared_hash_htab (old_set->vars)->elements ()
5074       != shared_hash_htab (new_set->vars)->elements ())
5075     RETRUE;
5076 
5077   FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (old_set->vars),
5078 			       var1, variable, hi)
5079     {
5080       variable_table_type *htab = shared_hash_htab (new_set->vars);
5081       variable *var2 = htab->find_with_hash (var1->dv, dv_htab_hash (var1->dv));
5082 
5083       if (!var2)
5084 	{
5085 	  if (dump_file && (dump_flags & TDF_DETAILS))
5086 	    {
5087 	      fprintf (dump_file, "dataflow difference found: removal of:\n");
5088 	      dump_var (var1);
5089 	    }
5090 	  RETRUE;
5091 	}
5092       else if (variable_different_p (var1, var2))
5093 	{
5094 	  if (details)
5095 	    {
5096 	      fprintf (dump_file, "dataflow difference found: "
5097 		       "old and new follow:\n");
5098 	      dump_var (var1);
5099 	      if (dv_onepart_p (var1->dv))
5100 		dump_onepart_variable_differences (var1, var2);
5101 	      dump_var (var2);
5102 	    }
5103 	  RETRUE;
5104 	}
5105     }
5106 
5107   /* There's no need to traverse the second hashtab unless we want to
5108      print the details.  If both have the same number of elements and
5109      the second one had all entries found in the first one, then the
5110      second can't have any extra entries.  */
5111   if (!details)
5112     return diffound;
5113 
5114   FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (new_set->vars),
5115 			       var1, variable, hi)
5116     {
5117       variable_table_type *htab = shared_hash_htab (old_set->vars);
5118       variable *var2 = htab->find_with_hash (var1->dv, dv_htab_hash (var1->dv));
5119       if (!var2)
5120 	{
5121 	  if (details)
5122 	    {
5123 	      fprintf (dump_file, "dataflow difference found: addition of:\n");
5124 	      dump_var (var1);
5125 	    }
5126 	  RETRUE;
5127 	}
5128     }
5129 
5130 #undef RETRUE
5131 
5132   return diffound;
5133 }
5134 
5135 /* Free the contents of dataflow set SET.  */
5136 
5137 static void
5138 dataflow_set_destroy (dataflow_set *set)
5139 {
5140   int i;
5141 
5142   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
5143     attrs_list_clear (&set->regs[i]);
5144 
5145   shared_hash_destroy (set->vars);
5146   set->vars = NULL;
5147 }
5148 
5149 /* Return true if T is a tracked parameter with non-degenerate record type.  */
5150 
5151 static bool
5152 tracked_record_parameter_p (tree t)
5153 {
5154   if (TREE_CODE (t) != PARM_DECL)
5155     return false;
5156 
5157   if (DECL_MODE (t) == BLKmode)
5158     return false;
5159 
5160   tree type = TREE_TYPE (t);
5161   if (TREE_CODE (type) != RECORD_TYPE)
5162     return false;
5163 
5164   if (TYPE_FIELDS (type) == NULL_TREE
5165       || DECL_CHAIN (TYPE_FIELDS (type)) == NULL_TREE)
5166     return false;
5167 
5168   return true;
5169 }
5170 
5171 /* Shall EXPR be tracked?  */
5172 
5173 static bool
5174 track_expr_p (tree expr, bool need_rtl)
5175 {
5176   rtx decl_rtl;
5177   tree realdecl;
5178 
5179   if (TREE_CODE (expr) == DEBUG_EXPR_DECL)
5180     return DECL_RTL_SET_P (expr);
5181 
5182   /* If EXPR is not a parameter or a variable do not track it.  */
5183   if (!VAR_P (expr) && TREE_CODE (expr) != PARM_DECL)
5184     return 0;
5185 
5186   /* It also must have a name...  */
5187   if (!DECL_NAME (expr) && need_rtl)
5188     return 0;
5189 
5190   /* ... and a RTL assigned to it.  */
5191   decl_rtl = DECL_RTL_IF_SET (expr);
5192   if (!decl_rtl && need_rtl)
5193     return 0;
5194 
5195   /* If this expression is really a debug alias of some other declaration, we
5196      don't need to track this expression if the ultimate declaration is
5197      ignored.  */
5198   realdecl = expr;
5199   if (VAR_P (realdecl) && DECL_HAS_DEBUG_EXPR_P (realdecl))
5200     {
5201       realdecl = DECL_DEBUG_EXPR (realdecl);
5202       if (!DECL_P (realdecl))
5203 	{
5204 	  if (handled_component_p (realdecl)
5205 	      || (TREE_CODE (realdecl) == MEM_REF
5206 		  && TREE_CODE (TREE_OPERAND (realdecl, 0)) == ADDR_EXPR))
5207 	    {
5208 	      HOST_WIDE_INT bitsize, bitpos;
5209 	      bool reverse;
5210 	      tree innerdecl
5211 		= get_ref_base_and_extent_hwi (realdecl, &bitpos,
5212 					       &bitsize, &reverse);
5213 	      if (!innerdecl
5214 		  || !DECL_P (innerdecl)
5215 		  || DECL_IGNORED_P (innerdecl)
5216 		  /* Do not track declarations for parts of tracked record
5217 		     parameters since we want to track them as a whole.  */
5218 		  || tracked_record_parameter_p (innerdecl)
5219 		  || TREE_STATIC (innerdecl)
5220 		  || bitsize == 0
5221 		  || bitpos + bitsize > 256)
5222 		return 0;
5223 	      else
5224 		realdecl = expr;
5225 	    }
5226 	  else
5227 	    return 0;
5228 	}
5229     }
5230 
5231   /* Do not track EXPR if REALDECL it should be ignored for debugging
5232      purposes.  */
5233   if (DECL_IGNORED_P (realdecl))
5234     return 0;
5235 
5236   /* Do not track global variables until we are able to emit correct location
5237      list for them.  */
5238   if (TREE_STATIC (realdecl))
5239     return 0;
5240 
5241   /* When the EXPR is a DECL for alias of some variable (see example)
5242      the TREE_STATIC flag is not used.  Disable tracking all DECLs whose
5243      DECL_RTL contains SYMBOL_REF.
5244 
5245      Example:
5246      extern char **_dl_argv_internal __attribute__ ((alias ("_dl_argv")));
5247      char **_dl_argv;
5248   */
5249   if (decl_rtl && MEM_P (decl_rtl)
5250       && contains_symbol_ref_p (XEXP (decl_rtl, 0)))
5251     return 0;
5252 
5253   /* If RTX is a memory it should not be very large (because it would be
5254      an array or struct).  */
5255   if (decl_rtl && MEM_P (decl_rtl))
5256     {
5257       /* Do not track structures and arrays.  */
5258       if ((GET_MODE (decl_rtl) == BLKmode
5259 	   || AGGREGATE_TYPE_P (TREE_TYPE (realdecl)))
5260 	  && !tracked_record_parameter_p (realdecl))
5261 	return 0;
5262       if (MEM_SIZE_KNOWN_P (decl_rtl)
5263 	  && maybe_gt (MEM_SIZE (decl_rtl), MAX_VAR_PARTS))
5264 	return 0;
5265     }
5266 
5267   DECL_CHANGED (expr) = 0;
5268   DECL_CHANGED (realdecl) = 0;
5269   return 1;
5270 }
5271 
5272 /* Determine whether a given LOC refers to the same variable part as
5273    EXPR+OFFSET.  */
5274 
5275 static bool
5276 same_variable_part_p (rtx loc, tree expr, poly_int64 offset)
5277 {
5278   tree expr2;
5279   poly_int64 offset2;
5280 
5281   if (! DECL_P (expr))
5282     return false;
5283 
5284   if (REG_P (loc))
5285     {
5286       expr2 = REG_EXPR (loc);
5287       offset2 = REG_OFFSET (loc);
5288     }
5289   else if (MEM_P (loc))
5290     {
5291       expr2 = MEM_EXPR (loc);
5292       offset2 = int_mem_offset (loc);
5293     }
5294   else
5295     return false;
5296 
5297   if (! expr2 || ! DECL_P (expr2))
5298     return false;
5299 
5300   expr = var_debug_decl (expr);
5301   expr2 = var_debug_decl (expr2);
5302 
5303   return (expr == expr2 && known_eq (offset, offset2));
5304 }
5305 
5306 /* LOC is a REG or MEM that we would like to track if possible.
5307    If EXPR is null, we don't know what expression LOC refers to,
5308    otherwise it refers to EXPR + OFFSET.  STORE_REG_P is true if
5309    LOC is an lvalue register.
5310 
5311    Return true if EXPR is nonnull and if LOC, or some lowpart of it,
5312    is something we can track.  When returning true, store the mode of
5313    the lowpart we can track in *MODE_OUT (if nonnull) and its offset
5314    from EXPR in *OFFSET_OUT (if nonnull).  */
5315 
5316 static bool
5317 track_loc_p (rtx loc, tree expr, poly_int64 offset, bool store_reg_p,
5318 	     machine_mode *mode_out, HOST_WIDE_INT *offset_out)
5319 {
5320   machine_mode mode;
5321 
5322   if (expr == NULL || !track_expr_p (expr, true))
5323     return false;
5324 
5325   /* If REG was a paradoxical subreg, its REG_ATTRS will describe the
5326      whole subreg, but only the old inner part is really relevant.  */
5327   mode = GET_MODE (loc);
5328   if (REG_P (loc) && !HARD_REGISTER_NUM_P (ORIGINAL_REGNO (loc)))
5329     {
5330       machine_mode pseudo_mode;
5331 
5332       pseudo_mode = PSEUDO_REGNO_MODE (ORIGINAL_REGNO (loc));
5333       if (paradoxical_subreg_p (mode, pseudo_mode))
5334 	{
5335 	  offset += byte_lowpart_offset (pseudo_mode, mode);
5336 	  mode = pseudo_mode;
5337 	}
5338     }
5339 
5340   /* If LOC is a paradoxical lowpart of EXPR, refer to EXPR itself.
5341      Do the same if we are storing to a register and EXPR occupies
5342      the whole of register LOC; in that case, the whole of EXPR is
5343      being changed.  We exclude complex modes from the second case
5344      because the real and imaginary parts are represented as separate
5345      pseudo registers, even if the whole complex value fits into one
5346      hard register.  */
5347   if ((paradoxical_subreg_p (mode, DECL_MODE (expr))
5348        || (store_reg_p
5349 	   && !COMPLEX_MODE_P (DECL_MODE (expr))
5350 	   && hard_regno_nregs (REGNO (loc), DECL_MODE (expr)) == 1))
5351       && known_eq (offset + byte_lowpart_offset (DECL_MODE (expr), mode), 0))
5352     {
5353       mode = DECL_MODE (expr);
5354       offset = 0;
5355     }
5356 
5357   HOST_WIDE_INT const_offset;
5358   if (!track_offset_p (offset, &const_offset))
5359     return false;
5360 
5361   if (mode_out)
5362     *mode_out = mode;
5363   if (offset_out)
5364     *offset_out = const_offset;
5365   return true;
5366 }
5367 
5368 /* Return the MODE lowpart of LOC, or null if LOC is not something we
5369    want to track.  When returning nonnull, make sure that the attributes
5370    on the returned value are updated.  */
5371 
5372 static rtx
5373 var_lowpart (machine_mode mode, rtx loc)
5374 {
5375   unsigned int regno;
5376 
5377   if (GET_MODE (loc) == mode)
5378     return loc;
5379 
5380   if (!REG_P (loc) && !MEM_P (loc))
5381     return NULL;
5382 
5383   poly_uint64 offset = byte_lowpart_offset (mode, GET_MODE (loc));
5384 
5385   if (MEM_P (loc))
5386     return adjust_address_nv (loc, mode, offset);
5387 
5388   poly_uint64 reg_offset = subreg_lowpart_offset (mode, GET_MODE (loc));
5389   regno = REGNO (loc) + subreg_regno_offset (REGNO (loc), GET_MODE (loc),
5390 					     reg_offset, mode);
5391   return gen_rtx_REG_offset (loc, mode, regno, offset);
5392 }
5393 
5394 /* Carry information about uses and stores while walking rtx.  */
5395 
5396 struct count_use_info
5397 {
5398   /* The insn where the RTX is.  */
5399   rtx_insn *insn;
5400 
5401   /* The basic block where insn is.  */
5402   basic_block bb;
5403 
5404   /* The array of n_sets sets in the insn, as determined by cselib.  */
5405   struct cselib_set *sets;
5406   int n_sets;
5407 
5408   /* True if we're counting stores, false otherwise.  */
5409   bool store_p;
5410 };
5411 
5412 /* Find a VALUE corresponding to X.   */
5413 
5414 static inline cselib_val *
5415 find_use_val (rtx x, machine_mode mode, struct count_use_info *cui)
5416 {
5417   int i;
5418 
5419   if (cui->sets)
5420     {
5421       /* This is called after uses are set up and before stores are
5422 	 processed by cselib, so it's safe to look up srcs, but not
5423 	 dsts.  So we look up expressions that appear in srcs or in
5424 	 dest expressions, but we search the sets array for dests of
5425 	 stores.  */
5426       if (cui->store_p)
5427 	{
5428 	  /* Some targets represent memset and memcpy patterns
5429 	     by (set (mem:BLK ...) (reg:[QHSD]I ...)) or
5430 	     (set (mem:BLK ...) (const_int ...)) or
5431 	     (set (mem:BLK ...) (mem:BLK ...)).  Don't return anything
5432 	     in that case, otherwise we end up with mode mismatches.  */
5433 	  if (mode == BLKmode && MEM_P (x))
5434 	    return NULL;
5435 	  for (i = 0; i < cui->n_sets; i++)
5436 	    if (cui->sets[i].dest == x)
5437 	      return cui->sets[i].src_elt;
5438 	}
5439       else
5440 	return cselib_lookup (x, mode, 0, VOIDmode);
5441     }
5442 
5443   return NULL;
5444 }
5445 
5446 /* Replace all registers and addresses in an expression with VALUE
5447    expressions that map back to them, unless the expression is a
5448    register.  If no mapping is or can be performed, returns NULL.  */
5449 
5450 static rtx
5451 replace_expr_with_values (rtx loc)
5452 {
5453   if (REG_P (loc) || GET_CODE (loc) == ENTRY_VALUE)
5454     return NULL;
5455   else if (MEM_P (loc))
5456     {
5457       cselib_val *addr = cselib_lookup (XEXP (loc, 0),
5458 					get_address_mode (loc), 0,
5459 					GET_MODE (loc));
5460       if (addr)
5461 	return replace_equiv_address_nv (loc, addr->val_rtx);
5462       else
5463 	return NULL;
5464     }
5465   else
5466     return cselib_subst_to_values (loc, VOIDmode);
5467 }
5468 
5469 /* Return true if X contains a DEBUG_EXPR.  */
5470 
5471 static bool
5472 rtx_debug_expr_p (const_rtx x)
5473 {
5474   subrtx_iterator::array_type array;
5475   FOR_EACH_SUBRTX (iter, array, x, ALL)
5476     if (GET_CODE (*iter) == DEBUG_EXPR)
5477       return true;
5478   return false;
5479 }
5480 
5481 /* Determine what kind of micro operation to choose for a USE.  Return
5482    MO_CLOBBER if no micro operation is to be generated.  */
5483 
5484 static enum micro_operation_type
5485 use_type (rtx loc, struct count_use_info *cui, machine_mode *modep)
5486 {
5487   tree expr;
5488 
5489   if (cui && cui->sets)
5490     {
5491       if (GET_CODE (loc) == VAR_LOCATION)
5492 	{
5493 	  if (track_expr_p (PAT_VAR_LOCATION_DECL (loc), false))
5494 	    {
5495 	      rtx ploc = PAT_VAR_LOCATION_LOC (loc);
5496 	      if (! VAR_LOC_UNKNOWN_P (ploc))
5497 		{
5498 		  cselib_val *val = cselib_lookup (ploc, GET_MODE (loc), 1,
5499 						   VOIDmode);
5500 
5501 		  /* ??? flag_float_store and volatile mems are never
5502 		     given values, but we could in theory use them for
5503 		     locations.  */
5504 		  gcc_assert (val || 1);
5505 		}
5506 	      return MO_VAL_LOC;
5507 	    }
5508 	  else
5509 	    return MO_CLOBBER;
5510 	}
5511 
5512       if (REG_P (loc) || MEM_P (loc))
5513 	{
5514 	  if (modep)
5515 	    *modep = GET_MODE (loc);
5516 	  if (cui->store_p)
5517 	    {
5518 	      if (REG_P (loc)
5519 		  || (find_use_val (loc, GET_MODE (loc), cui)
5520 		      && cselib_lookup (XEXP (loc, 0),
5521 					get_address_mode (loc), 0,
5522 					GET_MODE (loc))))
5523 		return MO_VAL_SET;
5524 	    }
5525 	  else
5526 	    {
5527 	      cselib_val *val = find_use_val (loc, GET_MODE (loc), cui);
5528 
5529 	      if (val && !cselib_preserved_value_p (val))
5530 		return MO_VAL_USE;
5531 	    }
5532 	}
5533     }
5534 
5535   if (REG_P (loc))
5536     {
5537       gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
5538 
5539       if (loc == cfa_base_rtx)
5540 	return MO_CLOBBER;
5541       expr = REG_EXPR (loc);
5542 
5543       if (!expr)
5544 	return MO_USE_NO_VAR;
5545       else if (target_for_debug_bind (var_debug_decl (expr)))
5546 	return MO_CLOBBER;
5547       else if (track_loc_p (loc, expr, REG_OFFSET (loc),
5548 			    false, modep, NULL))
5549 	return MO_USE;
5550       else
5551 	return MO_USE_NO_VAR;
5552     }
5553   else if (MEM_P (loc))
5554     {
5555       expr = MEM_EXPR (loc);
5556 
5557       if (!expr)
5558 	return MO_CLOBBER;
5559       else if (target_for_debug_bind (var_debug_decl (expr)))
5560 	return MO_CLOBBER;
5561       else if (track_loc_p (loc, expr, int_mem_offset (loc),
5562 			    false, modep, NULL)
5563 	       /* Multi-part variables shouldn't refer to one-part
5564 		  variable names such as VALUEs (never happens) or
5565 		  DEBUG_EXPRs (only happens in the presence of debug
5566 		  insns).  */
5567 	       && (!MAY_HAVE_DEBUG_BIND_INSNS
5568 		   || !rtx_debug_expr_p (XEXP (loc, 0))))
5569 	return MO_USE;
5570       else
5571 	return MO_CLOBBER;
5572     }
5573 
5574   return MO_CLOBBER;
5575 }
5576 
5577 /* Log to OUT information about micro-operation MOPT involving X in
5578    INSN of BB.  */
5579 
5580 static inline void
5581 log_op_type (rtx x, basic_block bb, rtx_insn *insn,
5582 	     enum micro_operation_type mopt, FILE *out)
5583 {
5584   fprintf (out, "bb %i op %i insn %i %s ",
5585 	   bb->index, VTI (bb)->mos.length (),
5586 	   INSN_UID (insn), micro_operation_type_name[mopt]);
5587   print_inline_rtx (out, x, 2);
5588   fputc ('\n', out);
5589 }
5590 
5591 /* Tell whether the CONCAT used to holds a VALUE and its location
5592    needs value resolution, i.e., an attempt of mapping the location
5593    back to other incoming values.  */
5594 #define VAL_NEEDS_RESOLUTION(x) \
5595   (RTL_FLAG_CHECK1 ("VAL_NEEDS_RESOLUTION", (x), CONCAT)->volatil)
5596 /* Whether the location in the CONCAT is a tracked expression, that
5597    should also be handled like a MO_USE.  */
5598 #define VAL_HOLDS_TRACK_EXPR(x) \
5599   (RTL_FLAG_CHECK1 ("VAL_HOLDS_TRACK_EXPR", (x), CONCAT)->used)
5600 /* Whether the location in the CONCAT should be handled like a MO_COPY
5601    as well.  */
5602 #define VAL_EXPR_IS_COPIED(x) \
5603   (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_COPIED", (x), CONCAT)->jump)
5604 /* Whether the location in the CONCAT should be handled like a
5605    MO_CLOBBER as well.  */
5606 #define VAL_EXPR_IS_CLOBBERED(x) \
5607   (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_CLOBBERED", (x), CONCAT)->unchanging)
5608 
5609 /* All preserved VALUEs.  */
5610 static vec<rtx> preserved_values;
5611 
5612 /* Ensure VAL is preserved and remember it in a vector for vt_emit_notes.  */
5613 
5614 static void
5615 preserve_value (cselib_val *val)
5616 {
5617   cselib_preserve_value (val);
5618   preserved_values.safe_push (val->val_rtx);
5619 }
5620 
5621 /* Helper function for MO_VAL_LOC handling.  Return non-zero if
5622    any rtxes not suitable for CONST use not replaced by VALUEs
5623    are discovered.  */
5624 
5625 static bool
5626 non_suitable_const (const_rtx x)
5627 {
5628   subrtx_iterator::array_type array;
5629   FOR_EACH_SUBRTX (iter, array, x, ALL)
5630     {
5631       const_rtx x = *iter;
5632       switch (GET_CODE (x))
5633 	{
5634 	case REG:
5635 	case DEBUG_EXPR:
5636 	case PC:
5637 	case SCRATCH:
5638 	case CC0:
5639 	case ASM_INPUT:
5640 	case ASM_OPERANDS:
5641 	  return true;
5642 	case MEM:
5643 	  if (!MEM_READONLY_P (x))
5644 	    return true;
5645 	  break;
5646 	default:
5647 	  break;
5648 	}
5649     }
5650   return false;
5651 }
5652 
5653 /* Add uses (register and memory references) LOC which will be tracked
5654    to VTI (bb)->mos.  */
5655 
5656 static void
5657 add_uses (rtx loc, struct count_use_info *cui)
5658 {
5659   machine_mode mode = VOIDmode;
5660   enum micro_operation_type type = use_type (loc, cui, &mode);
5661 
5662   if (type != MO_CLOBBER)
5663     {
5664       basic_block bb = cui->bb;
5665       micro_operation mo;
5666 
5667       mo.type = type;
5668       mo.u.loc = type == MO_USE ? var_lowpart (mode, loc) : loc;
5669       mo.insn = cui->insn;
5670 
5671       if (type == MO_VAL_LOC)
5672 	{
5673 	  rtx oloc = loc;
5674 	  rtx vloc = PAT_VAR_LOCATION_LOC (oloc);
5675 	  cselib_val *val;
5676 
5677 	  gcc_assert (cui->sets);
5678 
5679 	  if (MEM_P (vloc)
5680 	      && !REG_P (XEXP (vloc, 0))
5681 	      && !MEM_P (XEXP (vloc, 0)))
5682 	    {
5683 	      rtx mloc = vloc;
5684 	      machine_mode address_mode = get_address_mode (mloc);
5685 	      cselib_val *val
5686 		= cselib_lookup (XEXP (mloc, 0), address_mode, 0,
5687 				 GET_MODE (mloc));
5688 
5689 	      if (val && !cselib_preserved_value_p (val))
5690 		preserve_value (val);
5691 	    }
5692 
5693 	  if (CONSTANT_P (vloc)
5694 	      && (GET_CODE (vloc) != CONST || non_suitable_const (vloc)))
5695 	    /* For constants don't look up any value.  */;
5696 	  else if (!VAR_LOC_UNKNOWN_P (vloc) && !unsuitable_loc (vloc)
5697 		   && (val = find_use_val (vloc, GET_MODE (oloc), cui)))
5698 	    {
5699 	      machine_mode mode2;
5700 	      enum micro_operation_type type2;
5701 	      rtx nloc = NULL;
5702 	      bool resolvable = REG_P (vloc) || MEM_P (vloc);
5703 
5704 	      if (resolvable)
5705 		nloc = replace_expr_with_values (vloc);
5706 
5707 	      if (nloc)
5708 		{
5709 		  oloc = shallow_copy_rtx (oloc);
5710 		  PAT_VAR_LOCATION_LOC (oloc) = nloc;
5711 		}
5712 
5713 	      oloc = gen_rtx_CONCAT (mode, val->val_rtx, oloc);
5714 
5715 	      type2 = use_type (vloc, 0, &mode2);
5716 
5717 	      gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
5718 			  || type2 == MO_CLOBBER);
5719 
5720 	      if (type2 == MO_CLOBBER
5721 		  && !cselib_preserved_value_p (val))
5722 		{
5723 		  VAL_NEEDS_RESOLUTION (oloc) = resolvable;
5724 		  preserve_value (val);
5725 		}
5726 	    }
5727 	  else if (!VAR_LOC_UNKNOWN_P (vloc))
5728 	    {
5729 	      oloc = shallow_copy_rtx (oloc);
5730 	      PAT_VAR_LOCATION_LOC (oloc) = gen_rtx_UNKNOWN_VAR_LOC ();
5731 	    }
5732 
5733 	  mo.u.loc = oloc;
5734 	}
5735       else if (type == MO_VAL_USE)
5736 	{
5737 	  machine_mode mode2 = VOIDmode;
5738 	  enum micro_operation_type type2;
5739 	  cselib_val *val = find_use_val (loc, GET_MODE (loc), cui);
5740 	  rtx vloc, oloc = loc, nloc;
5741 
5742 	  gcc_assert (cui->sets);
5743 
5744 	  if (MEM_P (oloc)
5745 	      && !REG_P (XEXP (oloc, 0))
5746 	      && !MEM_P (XEXP (oloc, 0)))
5747 	    {
5748 	      rtx mloc = oloc;
5749 	      machine_mode address_mode = get_address_mode (mloc);
5750 	      cselib_val *val
5751 		= cselib_lookup (XEXP (mloc, 0), address_mode, 0,
5752 				 GET_MODE (mloc));
5753 
5754 	      if (val && !cselib_preserved_value_p (val))
5755 		preserve_value (val);
5756 	    }
5757 
5758 	  type2 = use_type (loc, 0, &mode2);
5759 
5760 	  gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
5761 		      || type2 == MO_CLOBBER);
5762 
5763 	  if (type2 == MO_USE)
5764 	    vloc = var_lowpart (mode2, loc);
5765 	  else
5766 	    vloc = oloc;
5767 
5768 	  /* The loc of a MO_VAL_USE may have two forms:
5769 
5770 	     (concat val src): val is at src, a value-based
5771 	     representation.
5772 
5773 	     (concat (concat val use) src): same as above, with use as
5774 	     the MO_USE tracked value, if it differs from src.
5775 
5776 	  */
5777 
5778 	  gcc_checking_assert (REG_P (loc) || MEM_P (loc));
5779 	  nloc = replace_expr_with_values (loc);
5780 	  if (!nloc)
5781 	    nloc = oloc;
5782 
5783 	  if (vloc != nloc)
5784 	    oloc = gen_rtx_CONCAT (mode2, val->val_rtx, vloc);
5785 	  else
5786 	    oloc = val->val_rtx;
5787 
5788 	  mo.u.loc = gen_rtx_CONCAT (mode, oloc, nloc);
5789 
5790 	  if (type2 == MO_USE)
5791 	    VAL_HOLDS_TRACK_EXPR (mo.u.loc) = 1;
5792 	  if (!cselib_preserved_value_p (val))
5793 	    {
5794 	      VAL_NEEDS_RESOLUTION (mo.u.loc) = 1;
5795 	      preserve_value (val);
5796 	    }
5797 	}
5798       else
5799 	gcc_assert (type == MO_USE || type == MO_USE_NO_VAR);
5800 
5801       if (dump_file && (dump_flags & TDF_DETAILS))
5802 	log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
5803       VTI (bb)->mos.safe_push (mo);
5804     }
5805 }
5806 
5807 /* Helper function for finding all uses of REG/MEM in X in insn INSN.  */
5808 
5809 static void
5810 add_uses_1 (rtx *x, void *cui)
5811 {
5812   subrtx_var_iterator::array_type array;
5813   FOR_EACH_SUBRTX_VAR (iter, array, *x, NONCONST)
5814     add_uses (*iter, (struct count_use_info *) cui);
5815 }
5816 
5817 /* This is the value used during expansion of locations.  We want it
5818    to be unbounded, so that variables expanded deep in a recursion
5819    nest are fully evaluated, so that their values are cached
5820    correctly.  We avoid recursion cycles through other means, and we
5821    don't unshare RTL, so excess complexity is not a problem.  */
5822 #define EXPR_DEPTH (INT_MAX)
5823 /* We use this to keep too-complex expressions from being emitted as
5824    location notes, and then to debug information.  Users can trade
5825    compile time for ridiculously complex expressions, although they're
5826    seldom useful, and they may often have to be discarded as not
5827    representable anyway.  */
5828 #define EXPR_USE_DEPTH (PARAM_VALUE (PARAM_MAX_VARTRACK_EXPR_DEPTH))
5829 
5830 /* Attempt to reverse the EXPR operation in the debug info and record
5831    it in the cselib table.  Say for reg1 = reg2 + 6 even when reg2 is
5832    no longer live we can express its value as VAL - 6.  */
5833 
5834 static void
5835 reverse_op (rtx val, const_rtx expr, rtx_insn *insn)
5836 {
5837   rtx src, arg, ret;
5838   cselib_val *v;
5839   struct elt_loc_list *l;
5840   enum rtx_code code;
5841   int count;
5842 
5843   if (GET_CODE (expr) != SET)
5844     return;
5845 
5846   if (!REG_P (SET_DEST (expr)) || GET_MODE (val) != GET_MODE (SET_DEST (expr)))
5847     return;
5848 
5849   src = SET_SRC (expr);
5850   switch (GET_CODE (src))
5851     {
5852     case PLUS:
5853     case MINUS:
5854     case XOR:
5855     case NOT:
5856     case NEG:
5857       if (!REG_P (XEXP (src, 0)))
5858 	return;
5859       break;
5860     case SIGN_EXTEND:
5861     case ZERO_EXTEND:
5862       if (!REG_P (XEXP (src, 0)) && !MEM_P (XEXP (src, 0)))
5863 	return;
5864       break;
5865     default:
5866       return;
5867     }
5868 
5869   if (!SCALAR_INT_MODE_P (GET_MODE (src)) || XEXP (src, 0) == cfa_base_rtx)
5870     return;
5871 
5872   v = cselib_lookup (XEXP (src, 0), GET_MODE (XEXP (src, 0)), 0, VOIDmode);
5873   if (!v || !cselib_preserved_value_p (v))
5874     return;
5875 
5876   /* Use canonical V to avoid creating multiple redundant expressions
5877      for different VALUES equivalent to V.  */
5878   v = canonical_cselib_val (v);
5879 
5880   /* Adding a reverse op isn't useful if V already has an always valid
5881      location.  Ignore ENTRY_VALUE, while it is always constant, we should
5882      prefer non-ENTRY_VALUE locations whenever possible.  */
5883   for (l = v->locs, count = 0; l; l = l->next, count++)
5884     if (CONSTANT_P (l->loc)
5885 	&& (GET_CODE (l->loc) != CONST || !references_value_p (l->loc, 0)))
5886       return;
5887     /* Avoid creating too large locs lists.  */
5888     else if (count == PARAM_VALUE (PARAM_MAX_VARTRACK_REVERSE_OP_SIZE))
5889       return;
5890 
5891   switch (GET_CODE (src))
5892     {
5893     case NOT:
5894     case NEG:
5895       if (GET_MODE (v->val_rtx) != GET_MODE (val))
5896 	return;
5897       ret = gen_rtx_fmt_e (GET_CODE (src), GET_MODE (val), val);
5898       break;
5899     case SIGN_EXTEND:
5900     case ZERO_EXTEND:
5901       ret = gen_lowpart_SUBREG (GET_MODE (v->val_rtx), val);
5902       break;
5903     case XOR:
5904       code = XOR;
5905       goto binary;
5906     case PLUS:
5907       code = MINUS;
5908       goto binary;
5909     case MINUS:
5910       code = PLUS;
5911       goto binary;
5912     binary:
5913       if (GET_MODE (v->val_rtx) != GET_MODE (val))
5914 	return;
5915       arg = XEXP (src, 1);
5916       if (!CONST_INT_P (arg) && GET_CODE (arg) != SYMBOL_REF)
5917 	{
5918 	  arg = cselib_expand_value_rtx (arg, scratch_regs, 5);
5919 	  if (arg == NULL_RTX)
5920 	    return;
5921 	  if (!CONST_INT_P (arg) && GET_CODE (arg) != SYMBOL_REF)
5922 	    return;
5923 	}
5924       ret = simplify_gen_binary (code, GET_MODE (val), val, arg);
5925       break;
5926     default:
5927       gcc_unreachable ();
5928     }
5929 
5930   cselib_add_permanent_equiv (v, ret, insn);
5931 }
5932 
5933 /* Add stores (register and memory references) LOC which will be tracked
5934    to VTI (bb)->mos.  EXPR is the RTL expression containing the store.
5935    CUIP->insn is instruction which the LOC is part of.  */
5936 
5937 static void
5938 add_stores (rtx loc, const_rtx expr, void *cuip)
5939 {
5940   machine_mode mode = VOIDmode, mode2;
5941   struct count_use_info *cui = (struct count_use_info *)cuip;
5942   basic_block bb = cui->bb;
5943   micro_operation mo;
5944   rtx oloc = loc, nloc, src = NULL;
5945   enum micro_operation_type type = use_type (loc, cui, &mode);
5946   bool track_p = false;
5947   cselib_val *v;
5948   bool resolve, preserve;
5949 
5950   if (type == MO_CLOBBER)
5951     return;
5952 
5953   mode2 = mode;
5954 
5955   if (REG_P (loc))
5956     {
5957       gcc_assert (loc != cfa_base_rtx);
5958       if ((GET_CODE (expr) == CLOBBER && type != MO_VAL_SET)
5959 	  || !(track_p = use_type (loc, NULL, &mode2) == MO_USE)
5960 	  || GET_CODE (expr) == CLOBBER)
5961 	{
5962 	  mo.type = MO_CLOBBER;
5963 	  mo.u.loc = loc;
5964 	  if (GET_CODE (expr) == SET
5965 	      && (SET_DEST (expr) == loc
5966 		  || (GET_CODE (SET_DEST (expr)) == STRICT_LOW_PART
5967 		      && XEXP (SET_DEST (expr), 0) == loc))
5968 	      && !unsuitable_loc (SET_SRC (expr))
5969 	      && find_use_val (loc, mode, cui))
5970 	    {
5971 	      gcc_checking_assert (type == MO_VAL_SET);
5972 	      mo.u.loc = gen_rtx_SET (loc, SET_SRC (expr));
5973 	    }
5974 	}
5975       else
5976 	{
5977 	  if (GET_CODE (expr) == SET
5978 	      && SET_DEST (expr) == loc
5979 	      && GET_CODE (SET_SRC (expr)) != ASM_OPERANDS)
5980 	    src = var_lowpart (mode2, SET_SRC (expr));
5981 	  loc = var_lowpart (mode2, loc);
5982 
5983 	  if (src == NULL)
5984 	    {
5985 	      mo.type = MO_SET;
5986 	      mo.u.loc = loc;
5987 	    }
5988 	  else
5989 	    {
5990 	      rtx xexpr = gen_rtx_SET (loc, src);
5991 	      if (same_variable_part_p (src, REG_EXPR (loc), REG_OFFSET (loc)))
5992 		{
5993 		  /* If this is an instruction copying (part of) a parameter
5994 		     passed by invisible reference to its register location,
5995 		     pretend it's a SET so that the initial memory location
5996 		     is discarded, as the parameter register can be reused
5997 		     for other purposes and we do not track locations based
5998 		     on generic registers.  */
5999 		  if (MEM_P (src)
6000 		      && REG_EXPR (loc)
6001 		      && TREE_CODE (REG_EXPR (loc)) == PARM_DECL
6002 		      && DECL_MODE (REG_EXPR (loc)) != BLKmode
6003 		      && MEM_P (DECL_INCOMING_RTL (REG_EXPR (loc)))
6004 		      && XEXP (DECL_INCOMING_RTL (REG_EXPR (loc)), 0)
6005 			 != arg_pointer_rtx)
6006 		    mo.type = MO_SET;
6007 		  else
6008 		    mo.type = MO_COPY;
6009 		}
6010 	      else
6011 		mo.type = MO_SET;
6012 	      mo.u.loc = xexpr;
6013 	    }
6014 	}
6015       mo.insn = cui->insn;
6016     }
6017   else if (MEM_P (loc)
6018 	   && ((track_p = use_type (loc, NULL, &mode2) == MO_USE)
6019 	       || cui->sets))
6020     {
6021       if (MEM_P (loc) && type == MO_VAL_SET
6022 	  && !REG_P (XEXP (loc, 0))
6023 	  && !MEM_P (XEXP (loc, 0)))
6024 	{
6025 	  rtx mloc = loc;
6026 	  machine_mode address_mode = get_address_mode (mloc);
6027 	  cselib_val *val = cselib_lookup (XEXP (mloc, 0),
6028 					   address_mode, 0,
6029 					   GET_MODE (mloc));
6030 
6031 	  if (val && !cselib_preserved_value_p (val))
6032 	    preserve_value (val);
6033 	}
6034 
6035       if (GET_CODE (expr) == CLOBBER || !track_p)
6036 	{
6037 	  mo.type = MO_CLOBBER;
6038 	  mo.u.loc = track_p ? var_lowpart (mode2, loc) : loc;
6039 	}
6040       else
6041 	{
6042 	  if (GET_CODE (expr) == SET
6043 	      && SET_DEST (expr) == loc
6044 	      && GET_CODE (SET_SRC (expr)) != ASM_OPERANDS)
6045 	    src = var_lowpart (mode2, SET_SRC (expr));
6046 	  loc = var_lowpart (mode2, loc);
6047 
6048 	  if (src == NULL)
6049 	    {
6050 	      mo.type = MO_SET;
6051 	      mo.u.loc = loc;
6052 	    }
6053 	  else
6054 	    {
6055 	      rtx xexpr = gen_rtx_SET (loc, src);
6056 	      if (same_variable_part_p (SET_SRC (xexpr),
6057 					MEM_EXPR (loc),
6058 					int_mem_offset (loc)))
6059 		mo.type = MO_COPY;
6060 	      else
6061 		mo.type = MO_SET;
6062 	      mo.u.loc = xexpr;
6063 	    }
6064 	}
6065       mo.insn = cui->insn;
6066     }
6067   else
6068     return;
6069 
6070   if (type != MO_VAL_SET)
6071     goto log_and_return;
6072 
6073   v = find_use_val (oloc, mode, cui);
6074 
6075   if (!v)
6076     goto log_and_return;
6077 
6078   resolve = preserve = !cselib_preserved_value_p (v);
6079 
6080   /* We cannot track values for multiple-part variables, so we track only
6081      locations for tracked record parameters.  */
6082   if (track_p
6083       && REG_P (loc)
6084       && REG_EXPR (loc)
6085       && tracked_record_parameter_p (REG_EXPR (loc)))
6086     {
6087       /* Although we don't use the value here, it could be used later by the
6088 	 mere virtue of its existence as the operand of the reverse operation
6089 	 that gave rise to it (typically extension/truncation).  Make sure it
6090 	 is preserved as required by vt_expand_var_loc_chain.  */
6091       if (preserve)
6092 	preserve_value (v);
6093       goto log_and_return;
6094     }
6095 
6096   if (loc == stack_pointer_rtx
6097       && hard_frame_pointer_adjustment != -1
6098       && preserve)
6099     cselib_set_value_sp_based (v);
6100 
6101   nloc = replace_expr_with_values (oloc);
6102   if (nloc)
6103     oloc = nloc;
6104 
6105   if (GET_CODE (PATTERN (cui->insn)) == COND_EXEC)
6106     {
6107       cselib_val *oval = cselib_lookup (oloc, GET_MODE (oloc), 0, VOIDmode);
6108 
6109       if (oval == v)
6110 	return;
6111       gcc_assert (REG_P (oloc) || MEM_P (oloc));
6112 
6113       if (oval && !cselib_preserved_value_p (oval))
6114 	{
6115 	  micro_operation moa;
6116 
6117 	  preserve_value (oval);
6118 
6119 	  moa.type = MO_VAL_USE;
6120 	  moa.u.loc = gen_rtx_CONCAT (mode, oval->val_rtx, oloc);
6121 	  VAL_NEEDS_RESOLUTION (moa.u.loc) = 1;
6122 	  moa.insn = cui->insn;
6123 
6124 	  if (dump_file && (dump_flags & TDF_DETAILS))
6125 	    log_op_type (moa.u.loc, cui->bb, cui->insn,
6126 			 moa.type, dump_file);
6127 	  VTI (bb)->mos.safe_push (moa);
6128 	}
6129 
6130       resolve = false;
6131     }
6132   else if (resolve && GET_CODE (mo.u.loc) == SET)
6133     {
6134       if (REG_P (SET_SRC (expr)) || MEM_P (SET_SRC (expr)))
6135 	nloc = replace_expr_with_values (SET_SRC (expr));
6136       else
6137 	nloc = NULL_RTX;
6138 
6139       /* Avoid the mode mismatch between oexpr and expr.  */
6140       if (!nloc && mode != mode2)
6141 	{
6142 	  nloc = SET_SRC (expr);
6143 	  gcc_assert (oloc == SET_DEST (expr));
6144 	}
6145 
6146       if (nloc && nloc != SET_SRC (mo.u.loc))
6147 	oloc = gen_rtx_SET (oloc, nloc);
6148       else
6149 	{
6150 	  if (oloc == SET_DEST (mo.u.loc))
6151 	    /* No point in duplicating.  */
6152 	    oloc = mo.u.loc;
6153 	  if (!REG_P (SET_SRC (mo.u.loc)))
6154 	    resolve = false;
6155 	}
6156     }
6157   else if (!resolve)
6158     {
6159       if (GET_CODE (mo.u.loc) == SET
6160 	  && oloc == SET_DEST (mo.u.loc))
6161 	/* No point in duplicating.  */
6162 	oloc = mo.u.loc;
6163     }
6164   else
6165     resolve = false;
6166 
6167   loc = gen_rtx_CONCAT (mode, v->val_rtx, oloc);
6168 
6169   if (mo.u.loc != oloc)
6170     loc = gen_rtx_CONCAT (GET_MODE (mo.u.loc), loc, mo.u.loc);
6171 
6172   /* The loc of a MO_VAL_SET may have various forms:
6173 
6174      (concat val dst): dst now holds val
6175 
6176      (concat val (set dst src)): dst now holds val, copied from src
6177 
6178      (concat (concat val dstv) dst): dst now holds val; dstv is dst
6179      after replacing mems and non-top-level regs with values.
6180 
6181      (concat (concat val dstv) (set dst src)): dst now holds val,
6182      copied from src.  dstv is a value-based representation of dst, if
6183      it differs from dst.  If resolution is needed, src is a REG, and
6184      its mode is the same as that of val.
6185 
6186      (concat (concat val (set dstv srcv)) (set dst src)): src
6187      copied to dst, holding val.  dstv and srcv are value-based
6188      representations of dst and src, respectively.
6189 
6190   */
6191 
6192   if (GET_CODE (PATTERN (cui->insn)) != COND_EXEC)
6193     reverse_op (v->val_rtx, expr, cui->insn);
6194 
6195   mo.u.loc = loc;
6196 
6197   if (track_p)
6198     VAL_HOLDS_TRACK_EXPR (loc) = 1;
6199   if (preserve)
6200     {
6201       VAL_NEEDS_RESOLUTION (loc) = resolve;
6202       preserve_value (v);
6203     }
6204   if (mo.type == MO_CLOBBER)
6205     VAL_EXPR_IS_CLOBBERED (loc) = 1;
6206   if (mo.type == MO_COPY)
6207     VAL_EXPR_IS_COPIED (loc) = 1;
6208 
6209   mo.type = MO_VAL_SET;
6210 
6211  log_and_return:
6212   if (dump_file && (dump_flags & TDF_DETAILS))
6213     log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
6214   VTI (bb)->mos.safe_push (mo);
6215 }
6216 
6217 /* Arguments to the call.  */
6218 static rtx call_arguments;
6219 
6220 /* Compute call_arguments.  */
6221 
6222 static void
6223 prepare_call_arguments (basic_block bb, rtx_insn *insn)
6224 {
6225   rtx link, x, call;
6226   rtx prev, cur, next;
6227   rtx this_arg = NULL_RTX;
6228   tree type = NULL_TREE, t, fndecl = NULL_TREE;
6229   tree obj_type_ref = NULL_TREE;
6230   CUMULATIVE_ARGS args_so_far_v;
6231   cumulative_args_t args_so_far;
6232 
6233   memset (&args_so_far_v, 0, sizeof (args_so_far_v));
6234   args_so_far = pack_cumulative_args (&args_so_far_v);
6235   call = get_call_rtx_from (insn);
6236   if (call)
6237     {
6238       if (GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
6239 	{
6240 	  rtx symbol = XEXP (XEXP (call, 0), 0);
6241 	  if (SYMBOL_REF_DECL (symbol))
6242 	    fndecl = SYMBOL_REF_DECL (symbol);
6243 	}
6244       if (fndecl == NULL_TREE)
6245 	fndecl = MEM_EXPR (XEXP (call, 0));
6246       if (fndecl
6247 	  && TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE
6248 	  && TREE_CODE (TREE_TYPE (fndecl)) != METHOD_TYPE)
6249 	fndecl = NULL_TREE;
6250       if (fndecl && TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
6251 	type = TREE_TYPE (fndecl);
6252       if (fndecl && TREE_CODE (fndecl) != FUNCTION_DECL)
6253 	{
6254 	  if (TREE_CODE (fndecl) == INDIRECT_REF
6255 	      && TREE_CODE (TREE_OPERAND (fndecl, 0)) == OBJ_TYPE_REF)
6256 	    obj_type_ref = TREE_OPERAND (fndecl, 0);
6257 	  fndecl = NULL_TREE;
6258 	}
6259       if (type)
6260 	{
6261 	  for (t = TYPE_ARG_TYPES (type); t && t != void_list_node;
6262 	       t = TREE_CHAIN (t))
6263 	    if (TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
6264 		&& INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (t))))
6265 	      break;
6266 	  if ((t == NULL || t == void_list_node) && obj_type_ref == NULL_TREE)
6267 	    type = NULL;
6268 	  else
6269 	    {
6270 	      int nargs ATTRIBUTE_UNUSED = list_length (TYPE_ARG_TYPES (type));
6271 	      link = CALL_INSN_FUNCTION_USAGE (insn);
6272 #ifndef PCC_STATIC_STRUCT_RETURN
6273 	      if (aggregate_value_p (TREE_TYPE (type), type)
6274 		  && targetm.calls.struct_value_rtx (type, 0) == 0)
6275 		{
6276 		  tree struct_addr = build_pointer_type (TREE_TYPE (type));
6277 		  machine_mode mode = TYPE_MODE (struct_addr);
6278 		  rtx reg;
6279 		  INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
6280 					nargs + 1);
6281 		  reg = targetm.calls.function_arg (args_so_far, mode,
6282 						    struct_addr, true);
6283 		  targetm.calls.function_arg_advance (args_so_far, mode,
6284 						      struct_addr, true);
6285 		  if (reg == NULL_RTX)
6286 		    {
6287 		      for (; link; link = XEXP (link, 1))
6288 			if (GET_CODE (XEXP (link, 0)) == USE
6289 			    && MEM_P (XEXP (XEXP (link, 0), 0)))
6290 			  {
6291 			    link = XEXP (link, 1);
6292 			    break;
6293 			  }
6294 		    }
6295 		}
6296 	      else
6297 #endif
6298 		INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
6299 				      nargs);
6300 	      if (obj_type_ref && TYPE_ARG_TYPES (type) != void_list_node)
6301 		{
6302 		  machine_mode mode;
6303 		  t = TYPE_ARG_TYPES (type);
6304 		  mode = TYPE_MODE (TREE_VALUE (t));
6305 		  this_arg = targetm.calls.function_arg (args_so_far, mode,
6306 							 TREE_VALUE (t), true);
6307 		  if (this_arg && !REG_P (this_arg))
6308 		    this_arg = NULL_RTX;
6309 		  else if (this_arg == NULL_RTX)
6310 		    {
6311 		      for (; link; link = XEXP (link, 1))
6312 			if (GET_CODE (XEXP (link, 0)) == USE
6313 			    && MEM_P (XEXP (XEXP (link, 0), 0)))
6314 			  {
6315 			    this_arg = XEXP (XEXP (link, 0), 0);
6316 			    break;
6317 			  }
6318 		    }
6319 		}
6320 	    }
6321 	}
6322     }
6323   t = type ? TYPE_ARG_TYPES (type) : NULL_TREE;
6324 
6325   for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
6326     if (GET_CODE (XEXP (link, 0)) == USE)
6327       {
6328 	rtx item = NULL_RTX;
6329 	x = XEXP (XEXP (link, 0), 0);
6330 	if (GET_MODE (link) == VOIDmode
6331 	    || GET_MODE (link) == BLKmode
6332 	    || (GET_MODE (link) != GET_MODE (x)
6333 		&& ((GET_MODE_CLASS (GET_MODE (link)) != MODE_INT
6334 		     && GET_MODE_CLASS (GET_MODE (link)) != MODE_PARTIAL_INT)
6335 		    || (GET_MODE_CLASS (GET_MODE (x)) != MODE_INT
6336 			&& GET_MODE_CLASS (GET_MODE (x)) != MODE_PARTIAL_INT))))
6337 	  /* Can't do anything for these, if the original type mode
6338 	     isn't known or can't be converted.  */;
6339 	else if (REG_P (x))
6340 	  {
6341 	    cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
6342 	    scalar_int_mode mode;
6343 	    if (val && cselib_preserved_value_p (val))
6344 	      item = val->val_rtx;
6345 	    else if (is_a <scalar_int_mode> (GET_MODE (x), &mode))
6346 	      {
6347 		opt_scalar_int_mode mode_iter;
6348 		FOR_EACH_WIDER_MODE (mode_iter, mode)
6349 		  {
6350 		    mode = mode_iter.require ();
6351 		    if (GET_MODE_BITSIZE (mode) > BITS_PER_WORD)
6352 		      break;
6353 
6354 		    rtx reg = simplify_subreg (mode, x, GET_MODE (x), 0);
6355 		    if (reg == NULL_RTX || !REG_P (reg))
6356 		      continue;
6357 		    val = cselib_lookup (reg, mode, 0, VOIDmode);
6358 		    if (val && cselib_preserved_value_p (val))
6359 		      {
6360 			item = val->val_rtx;
6361 			break;
6362 		      }
6363 		  }
6364 	      }
6365 	  }
6366 	else if (MEM_P (x))
6367 	  {
6368 	    rtx mem = x;
6369 	    cselib_val *val;
6370 
6371 	    if (!frame_pointer_needed)
6372 	      {
6373 		struct adjust_mem_data amd;
6374 		amd.mem_mode = VOIDmode;
6375 		amd.stack_adjust = -VTI (bb)->out.stack_adjust;
6376 		amd.store = true;
6377 		mem = simplify_replace_fn_rtx (mem, NULL_RTX, adjust_mems,
6378 					       &amd);
6379 		gcc_assert (amd.side_effects.is_empty ());
6380 	      }
6381 	    val = cselib_lookup (mem, GET_MODE (mem), 0, VOIDmode);
6382 	    if (val && cselib_preserved_value_p (val))
6383 	      item = val->val_rtx;
6384 	    else if (GET_MODE_CLASS (GET_MODE (mem)) != MODE_INT
6385 		     && GET_MODE_CLASS (GET_MODE (mem)) != MODE_PARTIAL_INT)
6386 	      {
6387 		/* For non-integer stack argument see also if they weren't
6388 		   initialized by integers.  */
6389 		scalar_int_mode imode;
6390 		if (int_mode_for_mode (GET_MODE (mem)).exists (&imode)
6391 		    && imode != GET_MODE (mem))
6392 		  {
6393 		    val = cselib_lookup (adjust_address_nv (mem, imode, 0),
6394 					 imode, 0, VOIDmode);
6395 		    if (val && cselib_preserved_value_p (val))
6396 		      item = lowpart_subreg (GET_MODE (x), val->val_rtx,
6397 					     imode);
6398 		  }
6399 	      }
6400 	  }
6401 	if (item)
6402 	  {
6403 	    rtx x2 = x;
6404 	    if (GET_MODE (item) != GET_MODE (link))
6405 	      item = lowpart_subreg (GET_MODE (link), item, GET_MODE (item));
6406 	    if (GET_MODE (x2) != GET_MODE (link))
6407 	      x2 = lowpart_subreg (GET_MODE (link), x2, GET_MODE (x2));
6408 	    item = gen_rtx_CONCAT (GET_MODE (link), x2, item);
6409 	    call_arguments
6410 	      = gen_rtx_EXPR_LIST (VOIDmode, item, call_arguments);
6411 	  }
6412 	if (t && t != void_list_node)
6413 	  {
6414 	    tree argtype = TREE_VALUE (t);
6415 	    machine_mode mode = TYPE_MODE (argtype);
6416 	    rtx reg;
6417 	    if (pass_by_reference (&args_so_far_v, mode, argtype, true))
6418 	      {
6419 		argtype = build_pointer_type (argtype);
6420 		mode = TYPE_MODE (argtype);
6421 	      }
6422 	    reg = targetm.calls.function_arg (args_so_far, mode,
6423 					      argtype, true);
6424 	    if (TREE_CODE (argtype) == REFERENCE_TYPE
6425 		&& INTEGRAL_TYPE_P (TREE_TYPE (argtype))
6426 		&& reg
6427 		&& REG_P (reg)
6428 		&& GET_MODE (reg) == mode
6429 		&& (GET_MODE_CLASS (mode) == MODE_INT
6430 		    || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
6431 		&& REG_P (x)
6432 		&& REGNO (x) == REGNO (reg)
6433 		&& GET_MODE (x) == mode
6434 		&& item)
6435 	      {
6436 		machine_mode indmode
6437 		  = TYPE_MODE (TREE_TYPE (argtype));
6438 		rtx mem = gen_rtx_MEM (indmode, x);
6439 		cselib_val *val = cselib_lookup (mem, indmode, 0, VOIDmode);
6440 		if (val && cselib_preserved_value_p (val))
6441 		  {
6442 		    item = gen_rtx_CONCAT (indmode, mem, val->val_rtx);
6443 		    call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
6444 							call_arguments);
6445 		  }
6446 		else
6447 		  {
6448 		    struct elt_loc_list *l;
6449 		    tree initial;
6450 
6451 		    /* Try harder, when passing address of a constant
6452 		       pool integer it can be easily read back.  */
6453 		    item = XEXP (item, 1);
6454 		    if (GET_CODE (item) == SUBREG)
6455 		      item = SUBREG_REG (item);
6456 		    gcc_assert (GET_CODE (item) == VALUE);
6457 		    val = CSELIB_VAL_PTR (item);
6458 		    for (l = val->locs; l; l = l->next)
6459 		      if (GET_CODE (l->loc) == SYMBOL_REF
6460 			  && TREE_CONSTANT_POOL_ADDRESS_P (l->loc)
6461 			  && SYMBOL_REF_DECL (l->loc)
6462 			  && DECL_INITIAL (SYMBOL_REF_DECL (l->loc)))
6463 			{
6464 			  initial = DECL_INITIAL (SYMBOL_REF_DECL (l->loc));
6465 			  if (tree_fits_shwi_p (initial))
6466 			    {
6467 			      item = GEN_INT (tree_to_shwi (initial));
6468 			      item = gen_rtx_CONCAT (indmode, mem, item);
6469 			      call_arguments
6470 				= gen_rtx_EXPR_LIST (VOIDmode, item,
6471 						     call_arguments);
6472 			    }
6473 			  break;
6474 			}
6475 		  }
6476 	      }
6477 	    targetm.calls.function_arg_advance (args_so_far, mode,
6478 						argtype, true);
6479 	    t = TREE_CHAIN (t);
6480 	  }
6481       }
6482 
6483   /* Add debug arguments.  */
6484   if (fndecl
6485       && TREE_CODE (fndecl) == FUNCTION_DECL
6486       && DECL_HAS_DEBUG_ARGS_P (fndecl))
6487     {
6488       vec<tree, va_gc> **debug_args = decl_debug_args_lookup (fndecl);
6489       if (debug_args)
6490 	{
6491 	  unsigned int ix;
6492 	  tree param;
6493 	  for (ix = 0; vec_safe_iterate (*debug_args, ix, &param); ix += 2)
6494 	    {
6495 	      rtx item;
6496 	      tree dtemp = (**debug_args)[ix + 1];
6497 	      machine_mode mode = DECL_MODE (dtemp);
6498 	      item = gen_rtx_DEBUG_PARAMETER_REF (mode, param);
6499 	      item = gen_rtx_CONCAT (mode, item, DECL_RTL_KNOWN_SET (dtemp));
6500 	      call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
6501 						  call_arguments);
6502 	    }
6503 	}
6504     }
6505 
6506   /* Reverse call_arguments chain.  */
6507   prev = NULL_RTX;
6508   for (cur = call_arguments; cur; cur = next)
6509     {
6510       next = XEXP (cur, 1);
6511       XEXP (cur, 1) = prev;
6512       prev = cur;
6513     }
6514   call_arguments = prev;
6515 
6516   x = get_call_rtx_from (insn);
6517   if (x)
6518     {
6519       x = XEXP (XEXP (x, 0), 0);
6520       if (GET_CODE (x) == SYMBOL_REF)
6521 	/* Don't record anything.  */;
6522       else if (CONSTANT_P (x))
6523 	{
6524 	  x = gen_rtx_CONCAT (GET_MODE (x) == VOIDmode ? Pmode : GET_MODE (x),
6525 			      pc_rtx, x);
6526 	  call_arguments
6527 	    = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
6528 	}
6529       else
6530 	{
6531 	  cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
6532 	  if (val && cselib_preserved_value_p (val))
6533 	    {
6534 	      x = gen_rtx_CONCAT (GET_MODE (x), pc_rtx, val->val_rtx);
6535 	      call_arguments
6536 		= gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
6537 	    }
6538 	}
6539     }
6540   if (this_arg)
6541     {
6542       machine_mode mode
6543 	= TYPE_MODE (TREE_TYPE (OBJ_TYPE_REF_EXPR (obj_type_ref)));
6544       rtx clobbered = gen_rtx_MEM (mode, this_arg);
6545       HOST_WIDE_INT token
6546 	= tree_to_shwi (OBJ_TYPE_REF_TOKEN (obj_type_ref));
6547       if (token)
6548 	clobbered = plus_constant (mode, clobbered,
6549 				   token * GET_MODE_SIZE (mode));
6550       clobbered = gen_rtx_MEM (mode, clobbered);
6551       x = gen_rtx_CONCAT (mode, gen_rtx_CLOBBER (VOIDmode, pc_rtx), clobbered);
6552       call_arguments
6553 	= gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
6554     }
6555 }
6556 
6557 /* Callback for cselib_record_sets_hook, that records as micro
6558    operations uses and stores in an insn after cselib_record_sets has
6559    analyzed the sets in an insn, but before it modifies the stored
6560    values in the internal tables, unless cselib_record_sets doesn't
6561    call it directly (perhaps because we're not doing cselib in the
6562    first place, in which case sets and n_sets will be 0).  */
6563 
6564 static void
6565 add_with_sets (rtx_insn *insn, struct cselib_set *sets, int n_sets)
6566 {
6567   basic_block bb = BLOCK_FOR_INSN (insn);
6568   int n1, n2;
6569   struct count_use_info cui;
6570   micro_operation *mos;
6571 
6572   cselib_hook_called = true;
6573 
6574   cui.insn = insn;
6575   cui.bb = bb;
6576   cui.sets = sets;
6577   cui.n_sets = n_sets;
6578 
6579   n1 = VTI (bb)->mos.length ();
6580   cui.store_p = false;
6581   note_uses (&PATTERN (insn), add_uses_1, &cui);
6582   n2 = VTI (bb)->mos.length () - 1;
6583   mos = VTI (bb)->mos.address ();
6584 
6585   /* Order the MO_USEs to be before MO_USE_NO_VARs and MO_VAL_USE, and
6586      MO_VAL_LOC last.  */
6587   while (n1 < n2)
6588     {
6589       while (n1 < n2 && mos[n1].type == MO_USE)
6590 	n1++;
6591       while (n1 < n2 && mos[n2].type != MO_USE)
6592 	n2--;
6593       if (n1 < n2)
6594 	std::swap (mos[n1], mos[n2]);
6595     }
6596 
6597   n2 = VTI (bb)->mos.length () - 1;
6598   while (n1 < n2)
6599     {
6600       while (n1 < n2 && mos[n1].type != MO_VAL_LOC)
6601 	n1++;
6602       while (n1 < n2 && mos[n2].type == MO_VAL_LOC)
6603 	n2--;
6604       if (n1 < n2)
6605 	std::swap (mos[n1], mos[n2]);
6606     }
6607 
6608   if (CALL_P (insn))
6609     {
6610       micro_operation mo;
6611 
6612       mo.type = MO_CALL;
6613       mo.insn = insn;
6614       mo.u.loc = call_arguments;
6615       call_arguments = NULL_RTX;
6616 
6617       if (dump_file && (dump_flags & TDF_DETAILS))
6618 	log_op_type (PATTERN (insn), bb, insn, mo.type, dump_file);
6619       VTI (bb)->mos.safe_push (mo);
6620     }
6621 
6622   n1 = VTI (bb)->mos.length ();
6623   /* This will record NEXT_INSN (insn), such that we can
6624      insert notes before it without worrying about any
6625      notes that MO_USEs might emit after the insn.  */
6626   cui.store_p = true;
6627   note_stores (PATTERN (insn), add_stores, &cui);
6628   n2 = VTI (bb)->mos.length () - 1;
6629   mos = VTI (bb)->mos.address ();
6630 
6631   /* Order the MO_VAL_USEs first (note_stores does nothing
6632      on DEBUG_INSNs, so there are no MO_VAL_LOCs from this
6633      insn), then MO_CLOBBERs, then MO_SET/MO_COPY/MO_VAL_SET.  */
6634   while (n1 < n2)
6635     {
6636       while (n1 < n2 && mos[n1].type == MO_VAL_USE)
6637 	n1++;
6638       while (n1 < n2 && mos[n2].type != MO_VAL_USE)
6639 	n2--;
6640       if (n1 < n2)
6641 	std::swap (mos[n1], mos[n2]);
6642     }
6643 
6644   n2 = VTI (bb)->mos.length () - 1;
6645   while (n1 < n2)
6646     {
6647       while (n1 < n2 && mos[n1].type == MO_CLOBBER)
6648 	n1++;
6649       while (n1 < n2 && mos[n2].type != MO_CLOBBER)
6650 	n2--;
6651       if (n1 < n2)
6652 	std::swap (mos[n1], mos[n2]);
6653     }
6654 }
6655 
6656 static enum var_init_status
6657 find_src_status (dataflow_set *in, rtx src)
6658 {
6659   tree decl = NULL_TREE;
6660   enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
6661 
6662   if (! flag_var_tracking_uninit)
6663     status = VAR_INIT_STATUS_INITIALIZED;
6664 
6665   if (src && REG_P (src))
6666     decl = var_debug_decl (REG_EXPR (src));
6667   else if (src && MEM_P (src))
6668     decl = var_debug_decl (MEM_EXPR (src));
6669 
6670   if (src && decl)
6671     status = get_init_value (in, src, dv_from_decl (decl));
6672 
6673   return status;
6674 }
6675 
6676 /* SRC is the source of an assignment.  Use SET to try to find what
6677    was ultimately assigned to SRC.  Return that value if known,
6678    otherwise return SRC itself.  */
6679 
6680 static rtx
6681 find_src_set_src (dataflow_set *set, rtx src)
6682 {
6683   tree decl = NULL_TREE;   /* The variable being copied around.          */
6684   rtx set_src = NULL_RTX;  /* The value for "decl" stored in "src".      */
6685   variable *var;
6686   location_chain *nextp;
6687   int i;
6688   bool found;
6689 
6690   if (src && REG_P (src))
6691     decl = var_debug_decl (REG_EXPR (src));
6692   else if (src && MEM_P (src))
6693     decl = var_debug_decl (MEM_EXPR (src));
6694 
6695   if (src && decl)
6696     {
6697       decl_or_value dv = dv_from_decl (decl);
6698 
6699       var = shared_hash_find (set->vars, dv);
6700       if (var)
6701 	{
6702 	  found = false;
6703 	  for (i = 0; i < var->n_var_parts && !found; i++)
6704 	    for (nextp = var->var_part[i].loc_chain; nextp && !found;
6705 		 nextp = nextp->next)
6706 	      if (rtx_equal_p (nextp->loc, src))
6707 		{
6708 		  set_src = nextp->set_src;
6709 		  found = true;
6710 		}
6711 
6712 	}
6713     }
6714 
6715   return set_src;
6716 }
6717 
6718 /* Compute the changes of variable locations in the basic block BB.  */
6719 
6720 static bool
6721 compute_bb_dataflow (basic_block bb)
6722 {
6723   unsigned int i;
6724   micro_operation *mo;
6725   bool changed;
6726   dataflow_set old_out;
6727   dataflow_set *in = &VTI (bb)->in;
6728   dataflow_set *out = &VTI (bb)->out;
6729 
6730   dataflow_set_init (&old_out);
6731   dataflow_set_copy (&old_out, out);
6732   dataflow_set_copy (out, in);
6733 
6734   if (MAY_HAVE_DEBUG_BIND_INSNS)
6735     local_get_addr_cache = new hash_map<rtx, rtx>;
6736 
6737   FOR_EACH_VEC_ELT (VTI (bb)->mos, i, mo)
6738     {
6739       rtx_insn *insn = mo->insn;
6740 
6741       switch (mo->type)
6742 	{
6743 	  case MO_CALL:
6744 	    dataflow_set_clear_at_call (out, insn);
6745 	    break;
6746 
6747 	  case MO_USE:
6748 	    {
6749 	      rtx loc = mo->u.loc;
6750 
6751 	      if (REG_P (loc))
6752 		var_reg_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6753 	      else if (MEM_P (loc))
6754 		var_mem_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6755 	    }
6756 	    break;
6757 
6758 	  case MO_VAL_LOC:
6759 	    {
6760 	      rtx loc = mo->u.loc;
6761 	      rtx val, vloc;
6762 	      tree var;
6763 
6764 	      if (GET_CODE (loc) == CONCAT)
6765 		{
6766 		  val = XEXP (loc, 0);
6767 		  vloc = XEXP (loc, 1);
6768 		}
6769 	      else
6770 		{
6771 		  val = NULL_RTX;
6772 		  vloc = loc;
6773 		}
6774 
6775 	      var = PAT_VAR_LOCATION_DECL (vloc);
6776 
6777 	      clobber_variable_part (out, NULL_RTX,
6778 				     dv_from_decl (var), 0, NULL_RTX);
6779 	      if (val)
6780 		{
6781 		  if (VAL_NEEDS_RESOLUTION (loc))
6782 		    val_resolve (out, val, PAT_VAR_LOCATION_LOC (vloc), insn);
6783 		  set_variable_part (out, val, dv_from_decl (var), 0,
6784 				     VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
6785 				     INSERT);
6786 		}
6787 	      else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
6788 		set_variable_part (out, PAT_VAR_LOCATION_LOC (vloc),
6789 				   dv_from_decl (var), 0,
6790 				   VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
6791 				   INSERT);
6792 	    }
6793 	    break;
6794 
6795 	  case MO_VAL_USE:
6796 	    {
6797 	      rtx loc = mo->u.loc;
6798 	      rtx val, vloc, uloc;
6799 
6800 	      vloc = uloc = XEXP (loc, 1);
6801 	      val = XEXP (loc, 0);
6802 
6803 	      if (GET_CODE (val) == CONCAT)
6804 		{
6805 		  uloc = XEXP (val, 1);
6806 		  val = XEXP (val, 0);
6807 		}
6808 
6809 	      if (VAL_NEEDS_RESOLUTION (loc))
6810 		val_resolve (out, val, vloc, insn);
6811 	      else
6812 		val_store (out, val, uloc, insn, false);
6813 
6814 	      if (VAL_HOLDS_TRACK_EXPR (loc))
6815 		{
6816 		  if (GET_CODE (uloc) == REG)
6817 		    var_reg_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6818 				 NULL);
6819 		  else if (GET_CODE (uloc) == MEM)
6820 		    var_mem_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6821 				 NULL);
6822 		}
6823 	    }
6824 	    break;
6825 
6826 	  case MO_VAL_SET:
6827 	    {
6828 	      rtx loc = mo->u.loc;
6829 	      rtx val, vloc, uloc;
6830 	      rtx dstv, srcv;
6831 
6832 	      vloc = loc;
6833 	      uloc = XEXP (vloc, 1);
6834 	      val = XEXP (vloc, 0);
6835 	      vloc = uloc;
6836 
6837 	      if (GET_CODE (uloc) == SET)
6838 		{
6839 		  dstv = SET_DEST (uloc);
6840 		  srcv = SET_SRC (uloc);
6841 		}
6842 	      else
6843 		{
6844 		  dstv = uloc;
6845 		  srcv = NULL;
6846 		}
6847 
6848 	      if (GET_CODE (val) == CONCAT)
6849 		{
6850 		  dstv = vloc = XEXP (val, 1);
6851 		  val = XEXP (val, 0);
6852 		}
6853 
6854 	      if (GET_CODE (vloc) == SET)
6855 		{
6856 		  srcv = SET_SRC (vloc);
6857 
6858 		  gcc_assert (val != srcv);
6859 		  gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
6860 
6861 		  dstv = vloc = SET_DEST (vloc);
6862 
6863 		  if (VAL_NEEDS_RESOLUTION (loc))
6864 		    val_resolve (out, val, srcv, insn);
6865 		}
6866 	      else if (VAL_NEEDS_RESOLUTION (loc))
6867 		{
6868 		  gcc_assert (GET_CODE (uloc) == SET
6869 			      && GET_CODE (SET_SRC (uloc)) == REG);
6870 		  val_resolve (out, val, SET_SRC (uloc), insn);
6871 		}
6872 
6873 	      if (VAL_HOLDS_TRACK_EXPR (loc))
6874 		{
6875 		  if (VAL_EXPR_IS_CLOBBERED (loc))
6876 		    {
6877 		      if (REG_P (uloc))
6878 			var_reg_delete (out, uloc, true);
6879 		      else if (MEM_P (uloc))
6880 			{
6881 			  gcc_assert (MEM_P (dstv));
6882 			  gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (uloc));
6883 			  var_mem_delete (out, dstv, true);
6884 			}
6885 		    }
6886 		  else
6887 		    {
6888 		      bool copied_p = VAL_EXPR_IS_COPIED (loc);
6889 		      rtx src = NULL, dst = uloc;
6890 		      enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
6891 
6892 		      if (GET_CODE (uloc) == SET)
6893 			{
6894 			  src = SET_SRC (uloc);
6895 			  dst = SET_DEST (uloc);
6896 			}
6897 
6898 		      if (copied_p)
6899 			{
6900 			  if (flag_var_tracking_uninit)
6901 			    {
6902 			      status = find_src_status (in, src);
6903 
6904 			      if (status == VAR_INIT_STATUS_UNKNOWN)
6905 				status = find_src_status (out, src);
6906 			    }
6907 
6908 			  src = find_src_set_src (in, src);
6909 			}
6910 
6911 		      if (REG_P (dst))
6912 			var_reg_delete_and_set (out, dst, !copied_p,
6913 						status, srcv);
6914 		      else if (MEM_P (dst))
6915 			{
6916 			  gcc_assert (MEM_P (dstv));
6917 			  gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (dst));
6918 			  var_mem_delete_and_set (out, dstv, !copied_p,
6919 						  status, srcv);
6920 			}
6921 		    }
6922 		}
6923 	      else if (REG_P (uloc))
6924 		var_regno_delete (out, REGNO (uloc));
6925 	      else if (MEM_P (uloc))
6926 		{
6927 		  gcc_checking_assert (GET_CODE (vloc) == MEM);
6928 		  gcc_checking_assert (dstv == vloc);
6929 		  if (dstv != vloc)
6930 		    clobber_overlapping_mems (out, vloc);
6931 		}
6932 
6933 	      val_store (out, val, dstv, insn, true);
6934 	    }
6935 	    break;
6936 
6937 	  case MO_SET:
6938 	    {
6939 	      rtx loc = mo->u.loc;
6940 	      rtx set_src = NULL;
6941 
6942 	      if (GET_CODE (loc) == SET)
6943 		{
6944 		  set_src = SET_SRC (loc);
6945 		  loc = SET_DEST (loc);
6946 		}
6947 
6948 	      if (REG_P (loc))
6949 		var_reg_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
6950 					set_src);
6951 	      else if (MEM_P (loc))
6952 		var_mem_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
6953 					set_src);
6954 	    }
6955 	    break;
6956 
6957 	  case MO_COPY:
6958 	    {
6959 	      rtx loc = mo->u.loc;
6960 	      enum var_init_status src_status;
6961 	      rtx set_src = NULL;
6962 
6963 	      if (GET_CODE (loc) == SET)
6964 		{
6965 		  set_src = SET_SRC (loc);
6966 		  loc = SET_DEST (loc);
6967 		}
6968 
6969 	      if (! flag_var_tracking_uninit)
6970 		src_status = VAR_INIT_STATUS_INITIALIZED;
6971 	      else
6972 		{
6973 		  src_status = find_src_status (in, set_src);
6974 
6975 		  if (src_status == VAR_INIT_STATUS_UNKNOWN)
6976 		    src_status = find_src_status (out, set_src);
6977 		}
6978 
6979 	      set_src = find_src_set_src (in, set_src);
6980 
6981 	      if (REG_P (loc))
6982 		var_reg_delete_and_set (out, loc, false, src_status, set_src);
6983 	      else if (MEM_P (loc))
6984 		var_mem_delete_and_set (out, loc, false, src_status, set_src);
6985 	    }
6986 	    break;
6987 
6988 	  case MO_USE_NO_VAR:
6989 	    {
6990 	      rtx loc = mo->u.loc;
6991 
6992 	      if (REG_P (loc))
6993 		var_reg_delete (out, loc, false);
6994 	      else if (MEM_P (loc))
6995 		var_mem_delete (out, loc, false);
6996 	    }
6997 	    break;
6998 
6999 	  case MO_CLOBBER:
7000 	    {
7001 	      rtx loc = mo->u.loc;
7002 
7003 	      if (REG_P (loc))
7004 		var_reg_delete (out, loc, true);
7005 	      else if (MEM_P (loc))
7006 		var_mem_delete (out, loc, true);
7007 	    }
7008 	    break;
7009 
7010 	  case MO_ADJUST:
7011 	    out->stack_adjust += mo->u.adjust;
7012 	    break;
7013 	}
7014     }
7015 
7016   if (MAY_HAVE_DEBUG_BIND_INSNS)
7017     {
7018       delete local_get_addr_cache;
7019       local_get_addr_cache = NULL;
7020 
7021       dataflow_set_equiv_regs (out);
7022       shared_hash_htab (out->vars)
7023 	->traverse <dataflow_set *, canonicalize_values_mark> (out);
7024       shared_hash_htab (out->vars)
7025 	->traverse <dataflow_set *, canonicalize_values_star> (out);
7026       if (flag_checking)
7027 	shared_hash_htab (out->vars)
7028 	  ->traverse <dataflow_set *, canonicalize_loc_order_check> (out);
7029     }
7030   changed = dataflow_set_different (&old_out, out);
7031   dataflow_set_destroy (&old_out);
7032   return changed;
7033 }
7034 
7035 /* Find the locations of variables in the whole function.  */
7036 
7037 static bool
7038 vt_find_locations (void)
7039 {
7040   bb_heap_t *worklist = new bb_heap_t (LONG_MIN);
7041   bb_heap_t *pending = new bb_heap_t (LONG_MIN);
7042   sbitmap in_worklist, in_pending;
7043   basic_block bb;
7044   edge e;
7045   int *bb_order;
7046   int *rc_order;
7047   int i;
7048   int htabsz = 0;
7049   int htabmax = PARAM_VALUE (PARAM_MAX_VARTRACK_SIZE);
7050   bool success = true;
7051 
7052   timevar_push (TV_VAR_TRACKING_DATAFLOW);
7053   /* Compute reverse completion order of depth first search of the CFG
7054      so that the data-flow runs faster.  */
7055   rc_order = XNEWVEC (int, n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS);
7056   bb_order = XNEWVEC (int, last_basic_block_for_fn (cfun));
7057   pre_and_rev_post_order_compute (NULL, rc_order, false);
7058   for (i = 0; i < n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS; i++)
7059     bb_order[rc_order[i]] = i;
7060   free (rc_order);
7061 
7062   auto_sbitmap visited (last_basic_block_for_fn (cfun));
7063   in_worklist = sbitmap_alloc (last_basic_block_for_fn (cfun));
7064   in_pending = sbitmap_alloc (last_basic_block_for_fn (cfun));
7065   bitmap_clear (in_worklist);
7066 
7067   FOR_EACH_BB_FN (bb, cfun)
7068     pending->insert (bb_order[bb->index], bb);
7069   bitmap_ones (in_pending);
7070 
7071   while (success && !pending->empty ())
7072     {
7073       std::swap (worklist, pending);
7074       std::swap (in_worklist, in_pending);
7075 
7076       bitmap_clear (visited);
7077 
7078       while (!worklist->empty ())
7079 	{
7080 	  bb = worklist->extract_min ();
7081 	  bitmap_clear_bit (in_worklist, bb->index);
7082 	  gcc_assert (!bitmap_bit_p (visited, bb->index));
7083 	  if (!bitmap_bit_p (visited, bb->index))
7084 	    {
7085 	      bool changed;
7086 	      edge_iterator ei;
7087 	      int oldinsz, oldoutsz;
7088 
7089 	      bitmap_set_bit (visited, bb->index);
7090 
7091 	      if (VTI (bb)->in.vars)
7092 		{
7093 		  htabsz
7094 		    -= shared_hash_htab (VTI (bb)->in.vars)->size ()
7095 			+ shared_hash_htab (VTI (bb)->out.vars)->size ();
7096 		  oldinsz = shared_hash_htab (VTI (bb)->in.vars)->elements ();
7097 		  oldoutsz
7098 		    = shared_hash_htab (VTI (bb)->out.vars)->elements ();
7099 		}
7100 	      else
7101 		oldinsz = oldoutsz = 0;
7102 
7103 	      if (MAY_HAVE_DEBUG_BIND_INSNS)
7104 		{
7105 		  dataflow_set *in = &VTI (bb)->in, *first_out = NULL;
7106 		  bool first = true, adjust = false;
7107 
7108 		  /* Calculate the IN set as the intersection of
7109 		     predecessor OUT sets.  */
7110 
7111 		  dataflow_set_clear (in);
7112 		  dst_can_be_shared = true;
7113 
7114 		  FOR_EACH_EDGE (e, ei, bb->preds)
7115 		    if (!VTI (e->src)->flooded)
7116 		      gcc_assert (bb_order[bb->index]
7117 				  <= bb_order[e->src->index]);
7118 		    else if (first)
7119 		      {
7120 			dataflow_set_copy (in, &VTI (e->src)->out);
7121 			first_out = &VTI (e->src)->out;
7122 			first = false;
7123 		      }
7124 		    else
7125 		      {
7126 			dataflow_set_merge (in, &VTI (e->src)->out);
7127 			adjust = true;
7128 		      }
7129 
7130 		  if (adjust)
7131 		    {
7132 		      dataflow_post_merge_adjust (in, &VTI (bb)->permp);
7133 
7134 		      if (flag_checking)
7135 			/* Merge and merge_adjust should keep entries in
7136 			   canonical order.  */
7137 			shared_hash_htab (in->vars)
7138 			  ->traverse <dataflow_set *,
7139 				      canonicalize_loc_order_check> (in);
7140 
7141 		      if (dst_can_be_shared)
7142 			{
7143 			  shared_hash_destroy (in->vars);
7144 			  in->vars = shared_hash_copy (first_out->vars);
7145 			}
7146 		    }
7147 
7148 		  VTI (bb)->flooded = true;
7149 		}
7150 	      else
7151 		{
7152 		  /* Calculate the IN set as union of predecessor OUT sets.  */
7153 		  dataflow_set_clear (&VTI (bb)->in);
7154 		  FOR_EACH_EDGE (e, ei, bb->preds)
7155 		    dataflow_set_union (&VTI (bb)->in, &VTI (e->src)->out);
7156 		}
7157 
7158 	      changed = compute_bb_dataflow (bb);
7159 	      htabsz += shared_hash_htab (VTI (bb)->in.vars)->size ()
7160 			 + shared_hash_htab (VTI (bb)->out.vars)->size ();
7161 
7162 	      if (htabmax && htabsz > htabmax)
7163 		{
7164 		  if (MAY_HAVE_DEBUG_BIND_INSNS)
7165 		    inform (DECL_SOURCE_LOCATION (cfun->decl),
7166 			    "variable tracking size limit exceeded with "
7167 			    "-fvar-tracking-assignments, retrying without");
7168 		  else
7169 		    inform (DECL_SOURCE_LOCATION (cfun->decl),
7170 			    "variable tracking size limit exceeded");
7171 		  success = false;
7172 		  break;
7173 		}
7174 
7175 	      if (changed)
7176 		{
7177 		  FOR_EACH_EDGE (e, ei, bb->succs)
7178 		    {
7179 		      if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
7180 			continue;
7181 
7182 		      if (bitmap_bit_p (visited, e->dest->index))
7183 			{
7184 			  if (!bitmap_bit_p (in_pending, e->dest->index))
7185 			    {
7186 			      /* Send E->DEST to next round.  */
7187 			      bitmap_set_bit (in_pending, e->dest->index);
7188 			      pending->insert (bb_order[e->dest->index],
7189 					       e->dest);
7190 			    }
7191 			}
7192 		      else if (!bitmap_bit_p (in_worklist, e->dest->index))
7193 			{
7194 			  /* Add E->DEST to current round.  */
7195 			  bitmap_set_bit (in_worklist, e->dest->index);
7196 			  worklist->insert (bb_order[e->dest->index],
7197 					    e->dest);
7198 			}
7199 		    }
7200 		}
7201 
7202 	      if (dump_file)
7203 		fprintf (dump_file,
7204 			 "BB %i: in %i (was %i), out %i (was %i), rem %i + %i, tsz %i\n",
7205 			 bb->index,
7206 			 (int)shared_hash_htab (VTI (bb)->in.vars)->size (),
7207 			 oldinsz,
7208 			 (int)shared_hash_htab (VTI (bb)->out.vars)->size (),
7209 			 oldoutsz,
7210 			 (int)worklist->nodes (), (int)pending->nodes (),
7211 			 htabsz);
7212 
7213 	      if (dump_file && (dump_flags & TDF_DETAILS))
7214 		{
7215 		  fprintf (dump_file, "BB %i IN:\n", bb->index);
7216 		  dump_dataflow_set (&VTI (bb)->in);
7217 		  fprintf (dump_file, "BB %i OUT:\n", bb->index);
7218 		  dump_dataflow_set (&VTI (bb)->out);
7219 		}
7220 	    }
7221 	}
7222     }
7223 
7224   if (success && MAY_HAVE_DEBUG_BIND_INSNS)
7225     FOR_EACH_BB_FN (bb, cfun)
7226       gcc_assert (VTI (bb)->flooded);
7227 
7228   free (bb_order);
7229   delete worklist;
7230   delete pending;
7231   sbitmap_free (in_worklist);
7232   sbitmap_free (in_pending);
7233 
7234   timevar_pop (TV_VAR_TRACKING_DATAFLOW);
7235   return success;
7236 }
7237 
7238 /* Print the content of the LIST to dump file.  */
7239 
7240 static void
7241 dump_attrs_list (attrs *list)
7242 {
7243   for (; list; list = list->next)
7244     {
7245       if (dv_is_decl_p (list->dv))
7246 	print_mem_expr (dump_file, dv_as_decl (list->dv));
7247       else
7248 	print_rtl_single (dump_file, dv_as_value (list->dv));
7249       fprintf (dump_file, "+" HOST_WIDE_INT_PRINT_DEC, list->offset);
7250     }
7251   fprintf (dump_file, "\n");
7252 }
7253 
7254 /* Print the information about variable *SLOT to dump file.  */
7255 
7256 int
7257 dump_var_tracking_slot (variable **slot, void *data ATTRIBUTE_UNUSED)
7258 {
7259   variable *var = *slot;
7260 
7261   dump_var (var);
7262 
7263   /* Continue traversing the hash table.  */
7264   return 1;
7265 }
7266 
7267 /* Print the information about variable VAR to dump file.  */
7268 
7269 static void
7270 dump_var (variable *var)
7271 {
7272   int i;
7273   location_chain *node;
7274 
7275   if (dv_is_decl_p (var->dv))
7276     {
7277       const_tree decl = dv_as_decl (var->dv);
7278 
7279       if (DECL_NAME (decl))
7280 	{
7281 	  fprintf (dump_file, "  name: %s",
7282 		   IDENTIFIER_POINTER (DECL_NAME (decl)));
7283 	  if (dump_flags & TDF_UID)
7284 	    fprintf (dump_file, "D.%u", DECL_UID (decl));
7285 	}
7286       else if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
7287 	fprintf (dump_file, "  name: D#%u", DEBUG_TEMP_UID (decl));
7288       else
7289 	fprintf (dump_file, "  name: D.%u", DECL_UID (decl));
7290       fprintf (dump_file, "\n");
7291     }
7292   else
7293     {
7294       fputc (' ', dump_file);
7295       print_rtl_single (dump_file, dv_as_value (var->dv));
7296     }
7297 
7298   for (i = 0; i < var->n_var_parts; i++)
7299     {
7300       fprintf (dump_file, "    offset %ld\n",
7301 	       (long)(var->onepart ? 0 : VAR_PART_OFFSET (var, i)));
7302       for (node = var->var_part[i].loc_chain; node; node = node->next)
7303 	{
7304 	  fprintf (dump_file, "      ");
7305 	  if (node->init == VAR_INIT_STATUS_UNINITIALIZED)
7306 	    fprintf (dump_file, "[uninit]");
7307 	  print_rtl_single (dump_file, node->loc);
7308 	}
7309     }
7310 }
7311 
7312 /* Print the information about variables from hash table VARS to dump file.  */
7313 
7314 static void
7315 dump_vars (variable_table_type *vars)
7316 {
7317   if (vars->elements () > 0)
7318     {
7319       fprintf (dump_file, "Variables:\n");
7320       vars->traverse <void *, dump_var_tracking_slot> (NULL);
7321     }
7322 }
7323 
7324 /* Print the dataflow set SET to dump file.  */
7325 
7326 static void
7327 dump_dataflow_set (dataflow_set *set)
7328 {
7329   int i;
7330 
7331   fprintf (dump_file, "Stack adjustment: " HOST_WIDE_INT_PRINT_DEC "\n",
7332 	   set->stack_adjust);
7333   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
7334     {
7335       if (set->regs[i])
7336 	{
7337 	  fprintf (dump_file, "Reg %d:", i);
7338 	  dump_attrs_list (set->regs[i]);
7339 	}
7340     }
7341   dump_vars (shared_hash_htab (set->vars));
7342   fprintf (dump_file, "\n");
7343 }
7344 
7345 /* Print the IN and OUT sets for each basic block to dump file.  */
7346 
7347 static void
7348 dump_dataflow_sets (void)
7349 {
7350   basic_block bb;
7351 
7352   FOR_EACH_BB_FN (bb, cfun)
7353     {
7354       fprintf (dump_file, "\nBasic block %d:\n", bb->index);
7355       fprintf (dump_file, "IN:\n");
7356       dump_dataflow_set (&VTI (bb)->in);
7357       fprintf (dump_file, "OUT:\n");
7358       dump_dataflow_set (&VTI (bb)->out);
7359     }
7360 }
7361 
7362 /* Return the variable for DV in dropped_values, inserting one if
7363    requested with INSERT.  */
7364 
7365 static inline variable *
7366 variable_from_dropped (decl_or_value dv, enum insert_option insert)
7367 {
7368   variable **slot;
7369   variable *empty_var;
7370   onepart_enum onepart;
7371 
7372   slot = dropped_values->find_slot_with_hash (dv, dv_htab_hash (dv), insert);
7373 
7374   if (!slot)
7375     return NULL;
7376 
7377   if (*slot)
7378     return *slot;
7379 
7380   gcc_checking_assert (insert == INSERT);
7381 
7382   onepart = dv_onepart_p (dv);
7383 
7384   gcc_checking_assert (onepart == ONEPART_VALUE || onepart == ONEPART_DEXPR);
7385 
7386   empty_var = onepart_pool_allocate (onepart);
7387   empty_var->dv = dv;
7388   empty_var->refcount = 1;
7389   empty_var->n_var_parts = 0;
7390   empty_var->onepart = onepart;
7391   empty_var->in_changed_variables = false;
7392   empty_var->var_part[0].loc_chain = NULL;
7393   empty_var->var_part[0].cur_loc = NULL;
7394   VAR_LOC_1PAUX (empty_var) = NULL;
7395   set_dv_changed (dv, true);
7396 
7397   *slot = empty_var;
7398 
7399   return empty_var;
7400 }
7401 
7402 /* Recover the one-part aux from dropped_values.  */
7403 
7404 static struct onepart_aux *
7405 recover_dropped_1paux (variable *var)
7406 {
7407   variable *dvar;
7408 
7409   gcc_checking_assert (var->onepart);
7410 
7411   if (VAR_LOC_1PAUX (var))
7412     return VAR_LOC_1PAUX (var);
7413 
7414   if (var->onepart == ONEPART_VDECL)
7415     return NULL;
7416 
7417   dvar = variable_from_dropped (var->dv, NO_INSERT);
7418 
7419   if (!dvar)
7420     return NULL;
7421 
7422   VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (dvar);
7423   VAR_LOC_1PAUX (dvar) = NULL;
7424 
7425   return VAR_LOC_1PAUX (var);
7426 }
7427 
7428 /* Add variable VAR to the hash table of changed variables and
7429    if it has no locations delete it from SET's hash table.  */
7430 
7431 static void
7432 variable_was_changed (variable *var, dataflow_set *set)
7433 {
7434   hashval_t hash = dv_htab_hash (var->dv);
7435 
7436   if (emit_notes)
7437     {
7438       variable **slot;
7439 
7440       /* Remember this decl or VALUE has been added to changed_variables.  */
7441       set_dv_changed (var->dv, true);
7442 
7443       slot = changed_variables->find_slot_with_hash (var->dv, hash, INSERT);
7444 
7445       if (*slot)
7446 	{
7447 	  variable *old_var = *slot;
7448 	  gcc_assert (old_var->in_changed_variables);
7449 	  old_var->in_changed_variables = false;
7450 	  if (var != old_var && var->onepart)
7451 	    {
7452 	      /* Restore the auxiliary info from an empty variable
7453 		 previously created for changed_variables, so it is
7454 		 not lost.  */
7455 	      gcc_checking_assert (!VAR_LOC_1PAUX (var));
7456 	      VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (old_var);
7457 	      VAR_LOC_1PAUX (old_var) = NULL;
7458 	    }
7459 	  variable_htab_free (*slot);
7460 	}
7461 
7462       if (set && var->n_var_parts == 0)
7463 	{
7464 	  onepart_enum onepart = var->onepart;
7465 	  variable *empty_var = NULL;
7466 	  variable **dslot = NULL;
7467 
7468 	  if (onepart == ONEPART_VALUE || onepart == ONEPART_DEXPR)
7469 	    {
7470 	      dslot = dropped_values->find_slot_with_hash (var->dv,
7471 							   dv_htab_hash (var->dv),
7472 							   INSERT);
7473 	      empty_var = *dslot;
7474 
7475 	      if (empty_var)
7476 		{
7477 		  gcc_checking_assert (!empty_var->in_changed_variables);
7478 		  if (!VAR_LOC_1PAUX (var))
7479 		    {
7480 		      VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (empty_var);
7481 		      VAR_LOC_1PAUX (empty_var) = NULL;
7482 		    }
7483 		  else
7484 		    gcc_checking_assert (!VAR_LOC_1PAUX (empty_var));
7485 		}
7486 	    }
7487 
7488 	  if (!empty_var)
7489 	    {
7490 	      empty_var = onepart_pool_allocate (onepart);
7491 	      empty_var->dv = var->dv;
7492 	      empty_var->refcount = 1;
7493 	      empty_var->n_var_parts = 0;
7494 	      empty_var->onepart = onepart;
7495 	      if (dslot)
7496 		{
7497 		  empty_var->refcount++;
7498 		  *dslot = empty_var;
7499 		}
7500 	    }
7501 	  else
7502 	    empty_var->refcount++;
7503 	  empty_var->in_changed_variables = true;
7504 	  *slot = empty_var;
7505 	  if (onepart)
7506 	    {
7507 	      empty_var->var_part[0].loc_chain = NULL;
7508 	      empty_var->var_part[0].cur_loc = NULL;
7509 	      VAR_LOC_1PAUX (empty_var) = VAR_LOC_1PAUX (var);
7510 	      VAR_LOC_1PAUX (var) = NULL;
7511 	    }
7512 	  goto drop_var;
7513 	}
7514       else
7515 	{
7516 	  if (var->onepart && !VAR_LOC_1PAUX (var))
7517 	    recover_dropped_1paux (var);
7518 	  var->refcount++;
7519 	  var->in_changed_variables = true;
7520 	  *slot = var;
7521 	}
7522     }
7523   else
7524     {
7525       gcc_assert (set);
7526       if (var->n_var_parts == 0)
7527 	{
7528 	  variable **slot;
7529 
7530 	drop_var:
7531 	  slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
7532 	  if (slot)
7533 	    {
7534 	      if (shared_hash_shared (set->vars))
7535 		slot = shared_hash_find_slot_unshare (&set->vars, var->dv,
7536 						      NO_INSERT);
7537 	      shared_hash_htab (set->vars)->clear_slot (slot);
7538 	    }
7539 	}
7540     }
7541 }
7542 
7543 /* Look for the index in VAR->var_part corresponding to OFFSET.
7544    Return -1 if not found.  If INSERTION_POINT is non-NULL, the
7545    referenced int will be set to the index that the part has or should
7546    have, if it should be inserted.  */
7547 
7548 static inline int
7549 find_variable_location_part (variable *var, HOST_WIDE_INT offset,
7550 			     int *insertion_point)
7551 {
7552   int pos, low, high;
7553 
7554   if (var->onepart)
7555     {
7556       if (offset != 0)
7557 	return -1;
7558 
7559       if (insertion_point)
7560 	*insertion_point = 0;
7561 
7562       return var->n_var_parts - 1;
7563     }
7564 
7565   /* Find the location part.  */
7566   low = 0;
7567   high = var->n_var_parts;
7568   while (low != high)
7569     {
7570       pos = (low + high) / 2;
7571       if (VAR_PART_OFFSET (var, pos) < offset)
7572 	low = pos + 1;
7573       else
7574 	high = pos;
7575     }
7576   pos = low;
7577 
7578   if (insertion_point)
7579     *insertion_point = pos;
7580 
7581   if (pos < var->n_var_parts && VAR_PART_OFFSET (var, pos) == offset)
7582     return pos;
7583 
7584   return -1;
7585 }
7586 
7587 static variable **
7588 set_slot_part (dataflow_set *set, rtx loc, variable **slot,
7589 	       decl_or_value dv, HOST_WIDE_INT offset,
7590 	       enum var_init_status initialized, rtx set_src)
7591 {
7592   int pos;
7593   location_chain *node, *next;
7594   location_chain **nextp;
7595   variable *var;
7596   onepart_enum onepart;
7597 
7598   var = *slot;
7599 
7600   if (var)
7601     onepart = var->onepart;
7602   else
7603     onepart = dv_onepart_p (dv);
7604 
7605   gcc_checking_assert (offset == 0 || !onepart);
7606   gcc_checking_assert (loc != dv_as_opaque (dv));
7607 
7608   if (! flag_var_tracking_uninit)
7609     initialized = VAR_INIT_STATUS_INITIALIZED;
7610 
7611   if (!var)
7612     {
7613       /* Create new variable information.  */
7614       var = onepart_pool_allocate (onepart);
7615       var->dv = dv;
7616       var->refcount = 1;
7617       var->n_var_parts = 1;
7618       var->onepart = onepart;
7619       var->in_changed_variables = false;
7620       if (var->onepart)
7621 	VAR_LOC_1PAUX (var) = NULL;
7622       else
7623 	VAR_PART_OFFSET (var, 0) = offset;
7624       var->var_part[0].loc_chain = NULL;
7625       var->var_part[0].cur_loc = NULL;
7626       *slot = var;
7627       pos = 0;
7628       nextp = &var->var_part[0].loc_chain;
7629     }
7630   else if (onepart)
7631     {
7632       int r = -1, c = 0;
7633 
7634       gcc_assert (dv_as_opaque (var->dv) == dv_as_opaque (dv));
7635 
7636       pos = 0;
7637 
7638       if (GET_CODE (loc) == VALUE)
7639 	{
7640 	  for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7641 	       nextp = &node->next)
7642 	    if (GET_CODE (node->loc) == VALUE)
7643 	      {
7644 		if (node->loc == loc)
7645 		  {
7646 		    r = 0;
7647 		    break;
7648 		  }
7649 		if (canon_value_cmp (node->loc, loc))
7650 		  c++;
7651 		else
7652 		  {
7653 		    r = 1;
7654 		    break;
7655 		  }
7656 	      }
7657 	    else if (REG_P (node->loc) || MEM_P (node->loc))
7658 	      c++;
7659 	    else
7660 	      {
7661 		r = 1;
7662 		break;
7663 	      }
7664 	}
7665       else if (REG_P (loc))
7666 	{
7667 	  for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7668 	       nextp = &node->next)
7669 	    if (REG_P (node->loc))
7670 	      {
7671 		if (REGNO (node->loc) < REGNO (loc))
7672 		  c++;
7673 		else
7674 		  {
7675 		    if (REGNO (node->loc) == REGNO (loc))
7676 		      r = 0;
7677 		    else
7678 		      r = 1;
7679 		    break;
7680 		  }
7681 	      }
7682 	    else
7683 	      {
7684 		r = 1;
7685 		break;
7686 	      }
7687 	}
7688       else if (MEM_P (loc))
7689 	{
7690 	  for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7691 	       nextp = &node->next)
7692 	    if (REG_P (node->loc))
7693 	      c++;
7694 	    else if (MEM_P (node->loc))
7695 	      {
7696 		if ((r = loc_cmp (XEXP (node->loc, 0), XEXP (loc, 0))) >= 0)
7697 		  break;
7698 		else
7699 		  c++;
7700 	      }
7701 	    else
7702 	      {
7703 		r = 1;
7704 		break;
7705 	      }
7706 	}
7707       else
7708 	for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7709 	     nextp = &node->next)
7710 	  if ((r = loc_cmp (node->loc, loc)) >= 0)
7711 	    break;
7712 	  else
7713 	    c++;
7714 
7715       if (r == 0)
7716 	return slot;
7717 
7718       if (shared_var_p (var, set->vars))
7719 	{
7720 	  slot = unshare_variable (set, slot, var, initialized);
7721 	  var = *slot;
7722 	  for (nextp = &var->var_part[0].loc_chain; c;
7723 	       nextp = &(*nextp)->next)
7724 	    c--;
7725 	  gcc_assert ((!node && !*nextp) || node->loc == (*nextp)->loc);
7726 	}
7727     }
7728   else
7729     {
7730       int inspos = 0;
7731 
7732       gcc_assert (dv_as_decl (var->dv) == dv_as_decl (dv));
7733 
7734       pos = find_variable_location_part (var, offset, &inspos);
7735 
7736       if (pos >= 0)
7737 	{
7738 	  node = var->var_part[pos].loc_chain;
7739 
7740 	  if (node
7741 	      && ((REG_P (node->loc) && REG_P (loc)
7742 		   && REGNO (node->loc) == REGNO (loc))
7743 		  || rtx_equal_p (node->loc, loc)))
7744 	    {
7745 	      /* LOC is in the beginning of the chain so we have nothing
7746 		 to do.  */
7747 	      if (node->init < initialized)
7748 		node->init = initialized;
7749 	      if (set_src != NULL)
7750 		node->set_src = set_src;
7751 
7752 	      return slot;
7753 	    }
7754 	  else
7755 	    {
7756 	      /* We have to make a copy of a shared variable.  */
7757 	      if (shared_var_p (var, set->vars))
7758 		{
7759 		  slot = unshare_variable (set, slot, var, initialized);
7760 		  var = *slot;
7761 		}
7762 	    }
7763 	}
7764       else
7765 	{
7766 	  /* We have not found the location part, new one will be created.  */
7767 
7768 	  /* We have to make a copy of the shared variable.  */
7769 	  if (shared_var_p (var, set->vars))
7770 	    {
7771 	      slot = unshare_variable (set, slot, var, initialized);
7772 	      var = *slot;
7773 	    }
7774 
7775 	  /* We track only variables whose size is <= MAX_VAR_PARTS bytes
7776 	     thus there are at most MAX_VAR_PARTS different offsets.  */
7777 	  gcc_assert (var->n_var_parts < MAX_VAR_PARTS
7778 		      && (!var->n_var_parts || !onepart));
7779 
7780 	  /* We have to move the elements of array starting at index
7781 	     inspos to the next position.  */
7782 	  for (pos = var->n_var_parts; pos > inspos; pos--)
7783 	    var->var_part[pos] = var->var_part[pos - 1];
7784 
7785 	  var->n_var_parts++;
7786 	  gcc_checking_assert (!onepart);
7787 	  VAR_PART_OFFSET (var, pos) = offset;
7788 	  var->var_part[pos].loc_chain = NULL;
7789 	  var->var_part[pos].cur_loc = NULL;
7790 	}
7791 
7792       /* Delete the location from the list.  */
7793       nextp = &var->var_part[pos].loc_chain;
7794       for (node = var->var_part[pos].loc_chain; node; node = next)
7795 	{
7796 	  next = node->next;
7797 	  if ((REG_P (node->loc) && REG_P (loc)
7798 	       && REGNO (node->loc) == REGNO (loc))
7799 	      || rtx_equal_p (node->loc, loc))
7800 	    {
7801 	      /* Save these values, to assign to the new node, before
7802 		 deleting this one.  */
7803 	      if (node->init > initialized)
7804 		initialized = node->init;
7805 	      if (node->set_src != NULL && set_src == NULL)
7806 		set_src = node->set_src;
7807 	      if (var->var_part[pos].cur_loc == node->loc)
7808 		var->var_part[pos].cur_loc = NULL;
7809 	      delete node;
7810 	      *nextp = next;
7811 	      break;
7812 	    }
7813 	  else
7814 	    nextp = &node->next;
7815 	}
7816 
7817       nextp = &var->var_part[pos].loc_chain;
7818     }
7819 
7820   /* Add the location to the beginning.  */
7821   node = new location_chain;
7822   node->loc = loc;
7823   node->init = initialized;
7824   node->set_src = set_src;
7825   node->next = *nextp;
7826   *nextp = node;
7827 
7828   /* If no location was emitted do so.  */
7829   if (var->var_part[pos].cur_loc == NULL)
7830     variable_was_changed (var, set);
7831 
7832   return slot;
7833 }
7834 
7835 /* Set the part of variable's location in the dataflow set SET.  The
7836    variable part is specified by variable's declaration in DV and
7837    offset OFFSET and the part's location by LOC.  IOPT should be
7838    NO_INSERT if the variable is known to be in SET already and the
7839    variable hash table must not be resized, and INSERT otherwise.  */
7840 
7841 static void
7842 set_variable_part (dataflow_set *set, rtx loc,
7843 		   decl_or_value dv, HOST_WIDE_INT offset,
7844 		   enum var_init_status initialized, rtx set_src,
7845 		   enum insert_option iopt)
7846 {
7847   variable **slot;
7848 
7849   if (iopt == NO_INSERT)
7850     slot = shared_hash_find_slot_noinsert (set->vars, dv);
7851   else
7852     {
7853       slot = shared_hash_find_slot (set->vars, dv);
7854       if (!slot)
7855 	slot = shared_hash_find_slot_unshare (&set->vars, dv, iopt);
7856     }
7857   set_slot_part (set, loc, slot, dv, offset, initialized, set_src);
7858 }
7859 
7860 /* Remove all recorded register locations for the given variable part
7861    from dataflow set SET, except for those that are identical to loc.
7862    The variable part is specified by variable's declaration or value
7863    DV and offset OFFSET.  */
7864 
7865 static variable **
7866 clobber_slot_part (dataflow_set *set, rtx loc, variable **slot,
7867 		   HOST_WIDE_INT offset, rtx set_src)
7868 {
7869   variable *var = *slot;
7870   int pos = find_variable_location_part (var, offset, NULL);
7871 
7872   if (pos >= 0)
7873     {
7874       location_chain *node, *next;
7875 
7876       /* Remove the register locations from the dataflow set.  */
7877       next = var->var_part[pos].loc_chain;
7878       for (node = next; node; node = next)
7879 	{
7880 	  next = node->next;
7881 	  if (node->loc != loc
7882 	      && (!flag_var_tracking_uninit
7883 		  || !set_src
7884 		  || MEM_P (set_src)
7885 		  || !rtx_equal_p (set_src, node->set_src)))
7886 	    {
7887 	      if (REG_P (node->loc))
7888 		{
7889 		  attrs *anode, *anext;
7890 		  attrs **anextp;
7891 
7892 		  /* Remove the variable part from the register's
7893 		     list, but preserve any other variable parts
7894 		     that might be regarded as live in that same
7895 		     register.  */
7896 		  anextp = &set->regs[REGNO (node->loc)];
7897 		  for (anode = *anextp; anode; anode = anext)
7898 		    {
7899 		      anext = anode->next;
7900 		      if (dv_as_opaque (anode->dv) == dv_as_opaque (var->dv)
7901 			  && anode->offset == offset)
7902 			{
7903 			  delete anode;
7904 			  *anextp = anext;
7905 			}
7906 		      else
7907 			anextp = &anode->next;
7908 		    }
7909 		}
7910 
7911 	      slot = delete_slot_part (set, node->loc, slot, offset);
7912 	    }
7913 	}
7914     }
7915 
7916   return slot;
7917 }
7918 
7919 /* Remove all recorded register locations for the given variable part
7920    from dataflow set SET, except for those that are identical to loc.
7921    The variable part is specified by variable's declaration or value
7922    DV and offset OFFSET.  */
7923 
7924 static void
7925 clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
7926 		       HOST_WIDE_INT offset, rtx set_src)
7927 {
7928   variable **slot;
7929 
7930   if (!dv_as_opaque (dv)
7931       || (!dv_is_value_p (dv) && ! DECL_P (dv_as_decl (dv))))
7932     return;
7933 
7934   slot = shared_hash_find_slot_noinsert (set->vars, dv);
7935   if (!slot)
7936     return;
7937 
7938   clobber_slot_part (set, loc, slot, offset, set_src);
7939 }
7940 
7941 /* Delete the part of variable's location from dataflow set SET.  The
7942    variable part is specified by its SET->vars slot SLOT and offset
7943    OFFSET and the part's location by LOC.  */
7944 
7945 static variable **
7946 delete_slot_part (dataflow_set *set, rtx loc, variable **slot,
7947 		  HOST_WIDE_INT offset)
7948 {
7949   variable *var = *slot;
7950   int pos = find_variable_location_part (var, offset, NULL);
7951 
7952   if (pos >= 0)
7953     {
7954       location_chain *node, *next;
7955       location_chain **nextp;
7956       bool changed;
7957       rtx cur_loc;
7958 
7959       if (shared_var_p (var, set->vars))
7960 	{
7961 	  /* If the variable contains the location part we have to
7962 	     make a copy of the variable.  */
7963 	  for (node = var->var_part[pos].loc_chain; node;
7964 	       node = node->next)
7965 	    {
7966 	      if ((REG_P (node->loc) && REG_P (loc)
7967 		   && REGNO (node->loc) == REGNO (loc))
7968 		  || rtx_equal_p (node->loc, loc))
7969 		{
7970 		  slot = unshare_variable (set, slot, var,
7971 					   VAR_INIT_STATUS_UNKNOWN);
7972 		  var = *slot;
7973 		  break;
7974 		}
7975 	    }
7976 	}
7977 
7978       if (pos == 0 && var->onepart && VAR_LOC_1PAUX (var))
7979 	cur_loc = VAR_LOC_FROM (var);
7980       else
7981 	cur_loc = var->var_part[pos].cur_loc;
7982 
7983       /* Delete the location part.  */
7984       changed = false;
7985       nextp = &var->var_part[pos].loc_chain;
7986       for (node = *nextp; node; node = next)
7987 	{
7988 	  next = node->next;
7989 	  if ((REG_P (node->loc) && REG_P (loc)
7990 	       && REGNO (node->loc) == REGNO (loc))
7991 	      || rtx_equal_p (node->loc, loc))
7992 	    {
7993 	      /* If we have deleted the location which was last emitted
7994 		 we have to emit new location so add the variable to set
7995 		 of changed variables.  */
7996 	      if (cur_loc == node->loc)
7997 		{
7998 		  changed = true;
7999 		  var->var_part[pos].cur_loc = NULL;
8000 		  if (pos == 0 && var->onepart && VAR_LOC_1PAUX (var))
8001 		    VAR_LOC_FROM (var) = NULL;
8002 		}
8003 	      delete node;
8004 	      *nextp = next;
8005 	      break;
8006 	    }
8007 	  else
8008 	    nextp = &node->next;
8009 	}
8010 
8011       if (var->var_part[pos].loc_chain == NULL)
8012 	{
8013 	  changed = true;
8014 	  var->n_var_parts--;
8015 	  while (pos < var->n_var_parts)
8016 	    {
8017 	      var->var_part[pos] = var->var_part[pos + 1];
8018 	      pos++;
8019 	    }
8020 	}
8021       if (changed)
8022 	variable_was_changed (var, set);
8023     }
8024 
8025   return slot;
8026 }
8027 
8028 /* Delete the part of variable's location from dataflow set SET.  The
8029    variable part is specified by variable's declaration or value DV
8030    and offset OFFSET and the part's location by LOC.  */
8031 
8032 static void
8033 delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
8034 		      HOST_WIDE_INT offset)
8035 {
8036   variable **slot = shared_hash_find_slot_noinsert (set->vars, dv);
8037   if (!slot)
8038     return;
8039 
8040   delete_slot_part (set, loc, slot, offset);
8041 }
8042 
8043 
8044 /* Structure for passing some other parameters to function
8045    vt_expand_loc_callback.  */
8046 struct expand_loc_callback_data
8047 {
8048   /* The variables and values active at this point.  */
8049   variable_table_type *vars;
8050 
8051   /* Stack of values and debug_exprs under expansion, and their
8052      children.  */
8053   auto_vec<rtx, 4> expanding;
8054 
8055   /* Stack of values and debug_exprs whose expansion hit recursion
8056      cycles.  They will have VALUE_RECURSED_INTO marked when added to
8057      this list.  This flag will be cleared if any of its dependencies
8058      resolves to a valid location.  So, if the flag remains set at the
8059      end of the search, we know no valid location for this one can
8060      possibly exist.  */
8061   auto_vec<rtx, 4> pending;
8062 
8063   /* The maximum depth among the sub-expressions under expansion.
8064      Zero indicates no expansion so far.  */
8065   expand_depth depth;
8066 };
8067 
8068 /* Allocate the one-part auxiliary data structure for VAR, with enough
8069    room for COUNT dependencies.  */
8070 
8071 static void
8072 loc_exp_dep_alloc (variable *var, int count)
8073 {
8074   size_t allocsize;
8075 
8076   gcc_checking_assert (var->onepart);
8077 
8078   /* We can be called with COUNT == 0 to allocate the data structure
8079      without any dependencies, e.g. for the backlinks only.  However,
8080      if we are specifying a COUNT, then the dependency list must have
8081      been emptied before.  It would be possible to adjust pointers or
8082      force it empty here, but this is better done at an earlier point
8083      in the algorithm, so we instead leave an assertion to catch
8084      errors.  */
8085   gcc_checking_assert (!count
8086 		       || VAR_LOC_DEP_VEC (var) == NULL
8087 		       || VAR_LOC_DEP_VEC (var)->is_empty ());
8088 
8089   if (VAR_LOC_1PAUX (var) && VAR_LOC_DEP_VEC (var)->space (count))
8090     return;
8091 
8092   allocsize = offsetof (struct onepart_aux, deps)
8093 	      + vec<loc_exp_dep, va_heap, vl_embed>::embedded_size (count);
8094 
8095   if (VAR_LOC_1PAUX (var))
8096     {
8097       VAR_LOC_1PAUX (var) = XRESIZEVAR (struct onepart_aux,
8098 					VAR_LOC_1PAUX (var), allocsize);
8099       /* If the reallocation moves the onepaux structure, the
8100 	 back-pointer to BACKLINKS in the first list member will still
8101 	 point to its old location.  Adjust it.  */
8102       if (VAR_LOC_DEP_LST (var))
8103 	VAR_LOC_DEP_LST (var)->pprev = VAR_LOC_DEP_LSTP (var);
8104     }
8105   else
8106     {
8107       VAR_LOC_1PAUX (var) = XNEWVAR (struct onepart_aux, allocsize);
8108       *VAR_LOC_DEP_LSTP (var) = NULL;
8109       VAR_LOC_FROM (var) = NULL;
8110       VAR_LOC_DEPTH (var).complexity = 0;
8111       VAR_LOC_DEPTH (var).entryvals = 0;
8112     }
8113   VAR_LOC_DEP_VEC (var)->embedded_init (count);
8114 }
8115 
8116 /* Remove all entries from the vector of active dependencies of VAR,
8117    removing them from the back-links lists too.  */
8118 
8119 static void
8120 loc_exp_dep_clear (variable *var)
8121 {
8122   while (VAR_LOC_DEP_VEC (var) && !VAR_LOC_DEP_VEC (var)->is_empty ())
8123     {
8124       loc_exp_dep *led = &VAR_LOC_DEP_VEC (var)->last ();
8125       if (led->next)
8126 	led->next->pprev = led->pprev;
8127       if (led->pprev)
8128 	*led->pprev = led->next;
8129       VAR_LOC_DEP_VEC (var)->pop ();
8130     }
8131 }
8132 
8133 /* Insert an active dependency from VAR on X to the vector of
8134    dependencies, and add the corresponding back-link to X's list of
8135    back-links in VARS.  */
8136 
8137 static void
8138 loc_exp_insert_dep (variable *var, rtx x, variable_table_type *vars)
8139 {
8140   decl_or_value dv;
8141   variable *xvar;
8142   loc_exp_dep *led;
8143 
8144   dv = dv_from_rtx (x);
8145 
8146   /* ??? Build a vector of variables parallel to EXPANDING, to avoid
8147      an additional look up?  */
8148   xvar = vars->find_with_hash (dv, dv_htab_hash (dv));
8149 
8150   if (!xvar)
8151     {
8152       xvar = variable_from_dropped (dv, NO_INSERT);
8153       gcc_checking_assert (xvar);
8154     }
8155 
8156   /* No point in adding the same backlink more than once.  This may
8157      arise if say the same value appears in two complex expressions in
8158      the same loc_list, or even more than once in a single
8159      expression.  */
8160   if (VAR_LOC_DEP_LST (xvar) && VAR_LOC_DEP_LST (xvar)->dv == var->dv)
8161     return;
8162 
8163   if (var->onepart == NOT_ONEPART)
8164     led = new loc_exp_dep;
8165   else
8166     {
8167       loc_exp_dep empty;
8168       memset (&empty, 0, sizeof (empty));
8169       VAR_LOC_DEP_VEC (var)->quick_push (empty);
8170       led = &VAR_LOC_DEP_VEC (var)->last ();
8171     }
8172   led->dv = var->dv;
8173   led->value = x;
8174 
8175   loc_exp_dep_alloc (xvar, 0);
8176   led->pprev = VAR_LOC_DEP_LSTP (xvar);
8177   led->next = *led->pprev;
8178   if (led->next)
8179     led->next->pprev = &led->next;
8180   *led->pprev = led;
8181 }
8182 
8183 /* Create active dependencies of VAR on COUNT values starting at
8184    VALUE, and corresponding back-links to the entries in VARS.  Return
8185    true if we found any pending-recursion results.  */
8186 
8187 static bool
8188 loc_exp_dep_set (variable *var, rtx result, rtx *value, int count,
8189 		 variable_table_type *vars)
8190 {
8191   bool pending_recursion = false;
8192 
8193   gcc_checking_assert (VAR_LOC_DEP_VEC (var) == NULL
8194 		       || VAR_LOC_DEP_VEC (var)->is_empty ());
8195 
8196   /* Set up all dependencies from last_child (as set up at the end of
8197      the loop above) to the end.  */
8198   loc_exp_dep_alloc (var, count);
8199 
8200   while (count--)
8201     {
8202       rtx x = *value++;
8203 
8204       if (!pending_recursion)
8205 	pending_recursion = !result && VALUE_RECURSED_INTO (x);
8206 
8207       loc_exp_insert_dep (var, x, vars);
8208     }
8209 
8210   return pending_recursion;
8211 }
8212 
8213 /* Notify the back-links of IVAR that are pending recursion that we
8214    have found a non-NIL value for it, so they are cleared for another
8215    attempt to compute a current location.  */
8216 
8217 static void
8218 notify_dependents_of_resolved_value (variable *ivar, variable_table_type *vars)
8219 {
8220   loc_exp_dep *led, *next;
8221 
8222   for (led = VAR_LOC_DEP_LST (ivar); led; led = next)
8223     {
8224       decl_or_value dv = led->dv;
8225       variable *var;
8226 
8227       next = led->next;
8228 
8229       if (dv_is_value_p (dv))
8230 	{
8231 	  rtx value = dv_as_value (dv);
8232 
8233 	  /* If we have already resolved it, leave it alone.  */
8234 	  if (!VALUE_RECURSED_INTO (value))
8235 	    continue;
8236 
8237 	  /* Check that VALUE_RECURSED_INTO, true from the test above,
8238 	     implies NO_LOC_P.  */
8239 	  gcc_checking_assert (NO_LOC_P (value));
8240 
8241 	  /* We won't notify variables that are being expanded,
8242 	     because their dependency list is cleared before
8243 	     recursing.  */
8244 	  NO_LOC_P (value) = false;
8245 	  VALUE_RECURSED_INTO (value) = false;
8246 
8247 	  gcc_checking_assert (dv_changed_p (dv));
8248 	}
8249       else
8250 	{
8251 	  gcc_checking_assert (dv_onepart_p (dv) != NOT_ONEPART);
8252 	  if (!dv_changed_p (dv))
8253 	    continue;
8254       }
8255 
8256       var = vars->find_with_hash (dv, dv_htab_hash (dv));
8257 
8258       if (!var)
8259 	var = variable_from_dropped (dv, NO_INSERT);
8260 
8261       if (var)
8262 	notify_dependents_of_resolved_value (var, vars);
8263 
8264       if (next)
8265 	next->pprev = led->pprev;
8266       if (led->pprev)
8267 	*led->pprev = next;
8268       led->next = NULL;
8269       led->pprev = NULL;
8270     }
8271 }
8272 
8273 static rtx vt_expand_loc_callback (rtx x, bitmap regs,
8274 				   int max_depth, void *data);
8275 
8276 /* Return the combined depth, when one sub-expression evaluated to
8277    BEST_DEPTH and the previous known depth was SAVED_DEPTH.  */
8278 
8279 static inline expand_depth
8280 update_depth (expand_depth saved_depth, expand_depth best_depth)
8281 {
8282   /* If we didn't find anything, stick with what we had.  */
8283   if (!best_depth.complexity)
8284     return saved_depth;
8285 
8286   /* If we found hadn't found anything, use the depth of the current
8287      expression.  Do NOT add one extra level, we want to compute the
8288      maximum depth among sub-expressions.  We'll increment it later,
8289      if appropriate.  */
8290   if (!saved_depth.complexity)
8291     return best_depth;
8292 
8293   /* Combine the entryval count so that regardless of which one we
8294      return, the entryval count is accurate.  */
8295   best_depth.entryvals = saved_depth.entryvals
8296     = best_depth.entryvals + saved_depth.entryvals;
8297 
8298   if (saved_depth.complexity < best_depth.complexity)
8299     return best_depth;
8300   else
8301     return saved_depth;
8302 }
8303 
8304 /* Expand VAR to a location RTX, updating its cur_loc.  Use REGS and
8305    DATA for cselib expand callback.  If PENDRECP is given, indicate in
8306    it whether any sub-expression couldn't be fully evaluated because
8307    it is pending recursion resolution.  */
8308 
8309 static inline rtx
8310 vt_expand_var_loc_chain (variable *var, bitmap regs, void *data,
8311 			 bool *pendrecp)
8312 {
8313   struct expand_loc_callback_data *elcd
8314     = (struct expand_loc_callback_data *) data;
8315   location_chain *loc, *next;
8316   rtx result = NULL;
8317   int first_child, result_first_child, last_child;
8318   bool pending_recursion;
8319   rtx loc_from = NULL;
8320   struct elt_loc_list *cloc = NULL;
8321   expand_depth depth = { 0, 0 }, saved_depth = elcd->depth;
8322   int wanted_entryvals, found_entryvals = 0;
8323 
8324   /* Clear all backlinks pointing at this, so that we're not notified
8325      while we're active.  */
8326   loc_exp_dep_clear (var);
8327 
8328  retry:
8329   if (var->onepart == ONEPART_VALUE)
8330     {
8331       cselib_val *val = CSELIB_VAL_PTR (dv_as_value (var->dv));
8332 
8333       gcc_checking_assert (cselib_preserved_value_p (val));
8334 
8335       cloc = val->locs;
8336     }
8337 
8338   first_child = result_first_child = last_child
8339     = elcd->expanding.length ();
8340 
8341   wanted_entryvals = found_entryvals;
8342 
8343   /* Attempt to expand each available location in turn.  */
8344   for (next = loc = var->n_var_parts ? var->var_part[0].loc_chain : NULL;
8345        loc || cloc; loc = next)
8346     {
8347       result_first_child = last_child;
8348 
8349       if (!loc)
8350 	{
8351 	  loc_from = cloc->loc;
8352 	  next = loc;
8353 	  cloc = cloc->next;
8354 	  if (unsuitable_loc (loc_from))
8355 	    continue;
8356 	}
8357       else
8358 	{
8359 	  loc_from = loc->loc;
8360 	  next = loc->next;
8361 	}
8362 
8363       gcc_checking_assert (!unsuitable_loc (loc_from));
8364 
8365       elcd->depth.complexity = elcd->depth.entryvals = 0;
8366       result = cselib_expand_value_rtx_cb (loc_from, regs, EXPR_DEPTH,
8367 					   vt_expand_loc_callback, data);
8368       last_child = elcd->expanding.length ();
8369 
8370       if (result)
8371 	{
8372 	  depth = elcd->depth;
8373 
8374 	  gcc_checking_assert (depth.complexity
8375 			       || result_first_child == last_child);
8376 
8377 	  if (last_child - result_first_child != 1)
8378 	    {
8379 	      if (!depth.complexity && GET_CODE (result) == ENTRY_VALUE)
8380 		depth.entryvals++;
8381 	      depth.complexity++;
8382 	    }
8383 
8384 	  if (depth.complexity <= EXPR_USE_DEPTH)
8385 	    {
8386 	      if (depth.entryvals <= wanted_entryvals)
8387 		break;
8388 	      else if (!found_entryvals || depth.entryvals < found_entryvals)
8389 		found_entryvals = depth.entryvals;
8390 	    }
8391 
8392 	  result = NULL;
8393 	}
8394 
8395       /* Set it up in case we leave the loop.  */
8396       depth.complexity = depth.entryvals = 0;
8397       loc_from = NULL;
8398       result_first_child = first_child;
8399     }
8400 
8401   if (!loc_from && wanted_entryvals < found_entryvals)
8402     {
8403       /* We found entries with ENTRY_VALUEs and skipped them.  Since
8404 	 we could not find any expansions without ENTRY_VALUEs, but we
8405 	 found at least one with them, go back and get an entry with
8406 	 the minimum number ENTRY_VALUE count that we found.  We could
8407 	 avoid looping, but since each sub-loc is already resolved,
8408 	 the re-expansion should be trivial.  ??? Should we record all
8409 	 attempted locs as dependencies, so that we retry the
8410 	 expansion should any of them change, in the hope it can give
8411 	 us a new entry without an ENTRY_VALUE?  */
8412       elcd->expanding.truncate (first_child);
8413       goto retry;
8414     }
8415 
8416   /* Register all encountered dependencies as active.  */
8417   pending_recursion = loc_exp_dep_set
8418     (var, result, elcd->expanding.address () + result_first_child,
8419      last_child - result_first_child, elcd->vars);
8420 
8421   elcd->expanding.truncate (first_child);
8422 
8423   /* Record where the expansion came from.  */
8424   gcc_checking_assert (!result || !pending_recursion);
8425   VAR_LOC_FROM (var) = loc_from;
8426   VAR_LOC_DEPTH (var) = depth;
8427 
8428   gcc_checking_assert (!depth.complexity == !result);
8429 
8430   elcd->depth = update_depth (saved_depth, depth);
8431 
8432   /* Indicate whether any of the dependencies are pending recursion
8433      resolution.  */
8434   if (pendrecp)
8435     *pendrecp = pending_recursion;
8436 
8437   if (!pendrecp || !pending_recursion)
8438     var->var_part[0].cur_loc = result;
8439 
8440   return result;
8441 }
8442 
8443 /* Callback for cselib_expand_value, that looks for expressions
8444    holding the value in the var-tracking hash tables.  Return X for
8445    standard processing, anything else is to be used as-is.  */
8446 
8447 static rtx
8448 vt_expand_loc_callback (rtx x, bitmap regs,
8449 			int max_depth ATTRIBUTE_UNUSED,
8450 			void *data)
8451 {
8452   struct expand_loc_callback_data *elcd
8453     = (struct expand_loc_callback_data *) data;
8454   decl_or_value dv;
8455   variable *var;
8456   rtx result, subreg;
8457   bool pending_recursion = false;
8458   bool from_empty = false;
8459 
8460   switch (GET_CODE (x))
8461     {
8462     case SUBREG:
8463       subreg = cselib_expand_value_rtx_cb (SUBREG_REG (x), regs,
8464 					   EXPR_DEPTH,
8465 					   vt_expand_loc_callback, data);
8466 
8467       if (!subreg)
8468 	return NULL;
8469 
8470       result = simplify_gen_subreg (GET_MODE (x), subreg,
8471 				    GET_MODE (SUBREG_REG (x)),
8472 				    SUBREG_BYTE (x));
8473 
8474       /* Invalid SUBREGs are ok in debug info.  ??? We could try
8475 	 alternate expansions for the VALUE as well.  */
8476       if (!result)
8477 	result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));
8478 
8479       return result;
8480 
8481     case DEBUG_EXPR:
8482     case VALUE:
8483       dv = dv_from_rtx (x);
8484       break;
8485 
8486     default:
8487       return x;
8488     }
8489 
8490   elcd->expanding.safe_push (x);
8491 
8492   /* Check that VALUE_RECURSED_INTO implies NO_LOC_P.  */
8493   gcc_checking_assert (!VALUE_RECURSED_INTO (x) || NO_LOC_P (x));
8494 
8495   if (NO_LOC_P (x))
8496     {
8497       gcc_checking_assert (VALUE_RECURSED_INTO (x) || !dv_changed_p (dv));
8498       return NULL;
8499     }
8500 
8501   var = elcd->vars->find_with_hash (dv, dv_htab_hash (dv));
8502 
8503   if (!var)
8504     {
8505       from_empty = true;
8506       var = variable_from_dropped (dv, INSERT);
8507     }
8508 
8509   gcc_checking_assert (var);
8510 
8511   if (!dv_changed_p (dv))
8512     {
8513       gcc_checking_assert (!NO_LOC_P (x));
8514       gcc_checking_assert (var->var_part[0].cur_loc);
8515       gcc_checking_assert (VAR_LOC_1PAUX (var));
8516       gcc_checking_assert (VAR_LOC_1PAUX (var)->depth.complexity);
8517 
8518       elcd->depth = update_depth (elcd->depth, VAR_LOC_1PAUX (var)->depth);
8519 
8520       return var->var_part[0].cur_loc;
8521     }
8522 
8523   VALUE_RECURSED_INTO (x) = true;
8524   /* This is tentative, but it makes some tests simpler.  */
8525   NO_LOC_P (x) = true;
8526 
8527   gcc_checking_assert (var->n_var_parts == 1 || from_empty);
8528 
8529   result = vt_expand_var_loc_chain (var, regs, data, &pending_recursion);
8530 
8531   if (pending_recursion)
8532     {
8533       gcc_checking_assert (!result);
8534       elcd->pending.safe_push (x);
8535     }
8536   else
8537     {
8538       NO_LOC_P (x) = !result;
8539       VALUE_RECURSED_INTO (x) = false;
8540       set_dv_changed (dv, false);
8541 
8542       if (result)
8543 	notify_dependents_of_resolved_value (var, elcd->vars);
8544     }
8545 
8546   return result;
8547 }
8548 
8549 /* While expanding variables, we may encounter recursion cycles
8550    because of mutual (possibly indirect) dependencies between two
8551    particular variables (or values), say A and B.  If we're trying to
8552    expand A when we get to B, which in turn attempts to expand A, if
8553    we can't find any other expansion for B, we'll add B to this
8554    pending-recursion stack, and tentatively return NULL for its
8555    location.  This tentative value will be used for any other
8556    occurrences of B, unless A gets some other location, in which case
8557    it will notify B that it is worth another try at computing a
8558    location for it, and it will use the location computed for A then.
8559    At the end of the expansion, the tentative NULL locations become
8560    final for all members of PENDING that didn't get a notification.
8561    This function performs this finalization of NULL locations.  */
8562 
8563 static void
8564 resolve_expansions_pending_recursion (vec<rtx, va_heap> *pending)
8565 {
8566   while (!pending->is_empty ())
8567     {
8568       rtx x = pending->pop ();
8569       decl_or_value dv;
8570 
8571       if (!VALUE_RECURSED_INTO (x))
8572 	continue;
8573 
8574       gcc_checking_assert (NO_LOC_P (x));
8575       VALUE_RECURSED_INTO (x) = false;
8576       dv = dv_from_rtx (x);
8577       gcc_checking_assert (dv_changed_p (dv));
8578       set_dv_changed (dv, false);
8579     }
8580 }
8581 
8582 /* Initialize expand_loc_callback_data D with variable hash table V.
8583    It must be a macro because of alloca (vec stack).  */
8584 #define INIT_ELCD(d, v)						\
8585   do								\
8586     {								\
8587       (d).vars = (v);						\
8588       (d).depth.complexity = (d).depth.entryvals = 0;		\
8589     }								\
8590   while (0)
8591 /* Finalize expand_loc_callback_data D, resolved to location L.  */
8592 #define FINI_ELCD(d, l)						\
8593   do								\
8594     {								\
8595       resolve_expansions_pending_recursion (&(d).pending);	\
8596       (d).pending.release ();					\
8597       (d).expanding.release ();					\
8598 								\
8599       if ((l) && MEM_P (l))					\
8600 	(l) = targetm.delegitimize_address (l);			\
8601     }								\
8602   while (0)
8603 
8604 /* Expand VALUEs and DEBUG_EXPRs in LOC to a location, using the
8605    equivalences in VARS, updating their CUR_LOCs in the process.  */
8606 
8607 static rtx
8608 vt_expand_loc (rtx loc, variable_table_type *vars)
8609 {
8610   struct expand_loc_callback_data data;
8611   rtx result;
8612 
8613   if (!MAY_HAVE_DEBUG_BIND_INSNS)
8614     return loc;
8615 
8616   INIT_ELCD (data, vars);
8617 
8618   result = cselib_expand_value_rtx_cb (loc, scratch_regs, EXPR_DEPTH,
8619 				       vt_expand_loc_callback, &data);
8620 
8621   FINI_ELCD (data, result);
8622 
8623   return result;
8624 }
8625 
8626 /* Expand the one-part VARiable to a location, using the equivalences
8627    in VARS, updating their CUR_LOCs in the process.  */
8628 
8629 static rtx
8630 vt_expand_1pvar (variable *var, variable_table_type *vars)
8631 {
8632   struct expand_loc_callback_data data;
8633   rtx loc;
8634 
8635   gcc_checking_assert (var->onepart && var->n_var_parts == 1);
8636 
8637   if (!dv_changed_p (var->dv))
8638     return var->var_part[0].cur_loc;
8639 
8640   INIT_ELCD (data, vars);
8641 
8642   loc = vt_expand_var_loc_chain (var, scratch_regs, &data, NULL);
8643 
8644   gcc_checking_assert (data.expanding.is_empty ());
8645 
8646   FINI_ELCD (data, loc);
8647 
8648   return loc;
8649 }
8650 
8651 /* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP.  DATA contains
8652    additional parameters: WHERE specifies whether the note shall be emitted
8653    before or after instruction INSN.  */
8654 
8655 int
8656 emit_note_insn_var_location (variable **varp, emit_note_data *data)
8657 {
8658   variable *var = *varp;
8659   rtx_insn *insn = data->insn;
8660   enum emit_note_where where = data->where;
8661   variable_table_type *vars = data->vars;
8662   rtx_note *note;
8663   rtx note_vl;
8664   int i, j, n_var_parts;
8665   bool complete;
8666   enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED;
8667   HOST_WIDE_INT last_limit;
8668   tree type_size_unit;
8669   HOST_WIDE_INT offsets[MAX_VAR_PARTS];
8670   rtx loc[MAX_VAR_PARTS];
8671   tree decl;
8672   location_chain *lc;
8673 
8674   gcc_checking_assert (var->onepart == NOT_ONEPART
8675 		       || var->onepart == ONEPART_VDECL);
8676 
8677   decl = dv_as_decl (var->dv);
8678 
8679   complete = true;
8680   last_limit = 0;
8681   n_var_parts = 0;
8682   if (!var->onepart)
8683     for (i = 0; i < var->n_var_parts; i++)
8684       if (var->var_part[i].cur_loc == NULL && var->var_part[i].loc_chain)
8685 	var->var_part[i].cur_loc = var->var_part[i].loc_chain->loc;
8686   for (i = 0; i < var->n_var_parts; i++)
8687     {
8688       machine_mode mode, wider_mode;
8689       rtx loc2;
8690       HOST_WIDE_INT offset, size, wider_size;
8691 
8692       if (i == 0 && var->onepart)
8693 	{
8694 	  gcc_checking_assert (var->n_var_parts == 1);
8695 	  offset = 0;
8696 	  initialized = VAR_INIT_STATUS_INITIALIZED;
8697 	  loc2 = vt_expand_1pvar (var, vars);
8698 	}
8699       else
8700 	{
8701 	  if (last_limit < VAR_PART_OFFSET (var, i))
8702 	    {
8703 	      complete = false;
8704 	      break;
8705 	    }
8706 	  else if (last_limit > VAR_PART_OFFSET (var, i))
8707 	    continue;
8708 	  offset = VAR_PART_OFFSET (var, i);
8709 	  loc2 = var->var_part[i].cur_loc;
8710 	  if (loc2 && GET_CODE (loc2) == MEM
8711 	      && GET_CODE (XEXP (loc2, 0)) == VALUE)
8712 	    {
8713 	      rtx depval = XEXP (loc2, 0);
8714 
8715 	      loc2 = vt_expand_loc (loc2, vars);
8716 
8717 	      if (loc2)
8718 		loc_exp_insert_dep (var, depval, vars);
8719 	    }
8720 	  if (!loc2)
8721 	    {
8722 	      complete = false;
8723 	      continue;
8724 	    }
8725 	  gcc_checking_assert (GET_CODE (loc2) != VALUE);
8726 	  for (lc = var->var_part[i].loc_chain; lc; lc = lc->next)
8727 	    if (var->var_part[i].cur_loc == lc->loc)
8728 	      {
8729 		initialized = lc->init;
8730 		break;
8731 	      }
8732 	  gcc_assert (lc);
8733 	}
8734 
8735       offsets[n_var_parts] = offset;
8736       if (!loc2)
8737 	{
8738 	  complete = false;
8739 	  continue;
8740 	}
8741       loc[n_var_parts] = loc2;
8742       mode = GET_MODE (var->var_part[i].cur_loc);
8743       if (mode == VOIDmode && var->onepart)
8744 	mode = DECL_MODE (decl);
8745       /* We ony track subparts of constant-sized objects, since at present
8746 	 there's no representation for polynomial pieces.  */
8747       if (!GET_MODE_SIZE (mode).is_constant (&size))
8748 	{
8749 	  complete = false;
8750 	  continue;
8751 	}
8752       last_limit = offsets[n_var_parts] + size;
8753 
8754       /* Attempt to merge adjacent registers or memory.  */
8755       for (j = i + 1; j < var->n_var_parts; j++)
8756 	if (last_limit <= VAR_PART_OFFSET (var, j))
8757 	  break;
8758       if (j < var->n_var_parts
8759 	  && GET_MODE_WIDER_MODE (mode).exists (&wider_mode)
8760 	  && GET_MODE_SIZE (wider_mode).is_constant (&wider_size)
8761 	  && var->var_part[j].cur_loc
8762 	  && mode == GET_MODE (var->var_part[j].cur_loc)
8763 	  && (REG_P (loc[n_var_parts]) || MEM_P (loc[n_var_parts]))
8764 	  && last_limit == (var->onepart ? 0 : VAR_PART_OFFSET (var, j))
8765 	  && (loc2 = vt_expand_loc (var->var_part[j].cur_loc, vars))
8766 	  && GET_CODE (loc[n_var_parts]) == GET_CODE (loc2))
8767 	{
8768 	  rtx new_loc = NULL;
8769 
8770 	  if (REG_P (loc[n_var_parts])
8771 	      && hard_regno_nregs (REGNO (loc[n_var_parts]), mode) * 2
8772 		 == hard_regno_nregs (REGNO (loc[n_var_parts]), wider_mode)
8773 	      && end_hard_regno (mode, REGNO (loc[n_var_parts]))
8774 		 == REGNO (loc2))
8775 	    {
8776 	      if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
8777 		new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
8778 					   mode, 0);
8779 	      else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
8780 		new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
8781 	      if (new_loc)
8782 		{
8783 		  if (!REG_P (new_loc)
8784 		      || REGNO (new_loc) != REGNO (loc[n_var_parts]))
8785 		    new_loc = NULL;
8786 		  else
8787 		    REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
8788 		}
8789 	    }
8790 	  else if (MEM_P (loc[n_var_parts])
8791 		   && GET_CODE (XEXP (loc2, 0)) == PLUS
8792 		   && REG_P (XEXP (XEXP (loc2, 0), 0))
8793 		   && CONST_INT_P (XEXP (XEXP (loc2, 0), 1)))
8794 	    {
8795 	      if ((REG_P (XEXP (loc[n_var_parts], 0))
8796 		   && rtx_equal_p (XEXP (loc[n_var_parts], 0),
8797 				   XEXP (XEXP (loc2, 0), 0))
8798 		   && INTVAL (XEXP (XEXP (loc2, 0), 1)) == size)
8799 		  || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
8800 		      && CONST_INT_P (XEXP (XEXP (loc[n_var_parts], 0), 1))
8801 		      && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
8802 				      XEXP (XEXP (loc2, 0), 0))
8803 		      && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1)) + size
8804 			 == INTVAL (XEXP (XEXP (loc2, 0), 1))))
8805 		new_loc = adjust_address_nv (loc[n_var_parts],
8806 					     wider_mode, 0);
8807 	    }
8808 
8809 	  if (new_loc)
8810 	    {
8811 	      loc[n_var_parts] = new_loc;
8812 	      mode = wider_mode;
8813 	      last_limit = offsets[n_var_parts] + wider_size;
8814 	      i = j;
8815 	    }
8816 	}
8817       ++n_var_parts;
8818     }
8819   type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8820   if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
8821     complete = false;
8822 
8823   if (! flag_var_tracking_uninit)
8824     initialized = VAR_INIT_STATUS_INITIALIZED;
8825 
8826   note_vl = NULL_RTX;
8827   if (!complete)
8828     note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, NULL_RTX, initialized);
8829   else if (n_var_parts == 1)
8830     {
8831       rtx expr_list;
8832 
8833       if (offsets[0] || GET_CODE (loc[0]) == PARALLEL)
8834 	expr_list = gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
8835       else
8836 	expr_list = loc[0];
8837 
8838       note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, expr_list, initialized);
8839     }
8840   else if (n_var_parts)
8841     {
8842       rtx parallel;
8843 
8844       for (i = 0; i < n_var_parts; i++)
8845 	loc[i]
8846 	  = gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));
8847 
8848       parallel = gen_rtx_PARALLEL (VOIDmode,
8849 				   gen_rtvec_v (n_var_parts, loc));
8850       note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl,
8851 				      parallel, initialized);
8852     }
8853 
8854   if (where != EMIT_NOTE_BEFORE_INSN)
8855     {
8856       note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
8857       if (where == EMIT_NOTE_AFTER_CALL_INSN)
8858 	NOTE_DURING_CALL_P (note) = true;
8859     }
8860   else
8861     {
8862       /* Make sure that the call related notes come first.  */
8863       while (NEXT_INSN (insn)
8864 	     && NOTE_P (insn)
8865 	     && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
8866 	     && NOTE_DURING_CALL_P (insn))
8867 	insn = NEXT_INSN (insn);
8868       if (NOTE_P (insn)
8869 	  && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
8870 	  && NOTE_DURING_CALL_P (insn))
8871 	note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
8872       else
8873 	note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
8874     }
8875   NOTE_VAR_LOCATION (note) = note_vl;
8876 
8877   set_dv_changed (var->dv, false);
8878   gcc_assert (var->in_changed_variables);
8879   var->in_changed_variables = false;
8880   changed_variables->clear_slot (varp);
8881 
8882   /* Continue traversing the hash table.  */
8883   return 1;
8884 }
8885 
8886 /* While traversing changed_variables, push onto DATA (a stack of RTX
8887    values) entries that aren't user variables.  */
8888 
8889 int
8890 var_track_values_to_stack (variable **slot,
8891 			   vec<rtx, va_heap> *changed_values_stack)
8892 {
8893   variable *var = *slot;
8894 
8895   if (var->onepart == ONEPART_VALUE)
8896     changed_values_stack->safe_push (dv_as_value (var->dv));
8897   else if (var->onepart == ONEPART_DEXPR)
8898     changed_values_stack->safe_push (DECL_RTL_KNOWN_SET (dv_as_decl (var->dv)));
8899 
8900   return 1;
8901 }
8902 
8903 /* Remove from changed_variables the entry whose DV corresponds to
8904    value or debug_expr VAL.  */
8905 static void
8906 remove_value_from_changed_variables (rtx val)
8907 {
8908   decl_or_value dv = dv_from_rtx (val);
8909   variable **slot;
8910   variable *var;
8911 
8912   slot = changed_variables->find_slot_with_hash (dv, dv_htab_hash (dv),
8913 						NO_INSERT);
8914   var = *slot;
8915   var->in_changed_variables = false;
8916   changed_variables->clear_slot (slot);
8917 }
8918 
8919 /* If VAL (a value or debug_expr) has backlinks to variables actively
8920    dependent on it in HTAB or in CHANGED_VARIABLES, mark them as
8921    changed, adding to CHANGED_VALUES_STACK any dependencies that may
8922    have dependencies of their own to notify.  */
8923 
8924 static void
8925 notify_dependents_of_changed_value (rtx val, variable_table_type *htab,
8926 				    vec<rtx, va_heap> *changed_values_stack)
8927 {
8928   variable **slot;
8929   variable *var;
8930   loc_exp_dep *led;
8931   decl_or_value dv = dv_from_rtx (val);
8932 
8933   slot = changed_variables->find_slot_with_hash (dv, dv_htab_hash (dv),
8934 						NO_INSERT);
8935   if (!slot)
8936     slot = htab->find_slot_with_hash (dv, dv_htab_hash (dv), NO_INSERT);
8937   if (!slot)
8938     slot = dropped_values->find_slot_with_hash (dv, dv_htab_hash (dv),
8939 						NO_INSERT);
8940   var = *slot;
8941 
8942   while ((led = VAR_LOC_DEP_LST (var)))
8943     {
8944       decl_or_value ldv = led->dv;
8945       variable *ivar;
8946 
8947       /* Deactivate and remove the backlink, as it was “used up”.  It
8948 	 makes no sense to attempt to notify the same entity again:
8949 	 either it will be recomputed and re-register an active
8950 	 dependency, or it will still have the changed mark.  */
8951       if (led->next)
8952 	led->next->pprev = led->pprev;
8953       if (led->pprev)
8954 	*led->pprev = led->next;
8955       led->next = NULL;
8956       led->pprev = NULL;
8957 
8958       if (dv_changed_p (ldv))
8959 	continue;
8960 
8961       switch (dv_onepart_p (ldv))
8962 	{
8963 	case ONEPART_VALUE:
8964 	case ONEPART_DEXPR:
8965 	  set_dv_changed (ldv, true);
8966 	  changed_values_stack->safe_push (dv_as_rtx (ldv));
8967 	  break;
8968 
8969 	case ONEPART_VDECL:
8970 	  ivar = htab->find_with_hash (ldv, dv_htab_hash (ldv));
8971 	  gcc_checking_assert (!VAR_LOC_DEP_LST (ivar));
8972 	  variable_was_changed (ivar, NULL);
8973 	  break;
8974 
8975 	case NOT_ONEPART:
8976 	  delete led;
8977 	  ivar = htab->find_with_hash (ldv, dv_htab_hash (ldv));
8978 	  if (ivar)
8979 	    {
8980 	      int i = ivar->n_var_parts;
8981 	      while (i--)
8982 		{
8983 		  rtx loc = ivar->var_part[i].cur_loc;
8984 
8985 		  if (loc && GET_CODE (loc) == MEM
8986 		      && XEXP (loc, 0) == val)
8987 		    {
8988 		      variable_was_changed (ivar, NULL);
8989 		      break;
8990 		    }
8991 		}
8992 	    }
8993 	  break;
8994 
8995 	default:
8996 	  gcc_unreachable ();
8997 	}
8998     }
8999 }
9000 
9001 /* Take out of changed_variables any entries that don't refer to use
9002    variables.  Back-propagate change notifications from values and
9003    debug_exprs to their active dependencies in HTAB or in
9004    CHANGED_VARIABLES.  */
9005 
9006 static void
9007 process_changed_values (variable_table_type *htab)
9008 {
9009   int i, n;
9010   rtx val;
9011   auto_vec<rtx, 20> changed_values_stack;
9012 
9013   /* Move values from changed_variables to changed_values_stack.  */
9014   changed_variables
9015     ->traverse <vec<rtx, va_heap>*, var_track_values_to_stack>
9016       (&changed_values_stack);
9017 
9018   /* Back-propagate change notifications in values while popping
9019      them from the stack.  */
9020   for (n = i = changed_values_stack.length ();
9021        i > 0; i = changed_values_stack.length ())
9022     {
9023       val = changed_values_stack.pop ();
9024       notify_dependents_of_changed_value (val, htab, &changed_values_stack);
9025 
9026       /* This condition will hold when visiting each of the entries
9027 	 originally in changed_variables.  We can't remove them
9028 	 earlier because this could drop the backlinks before we got a
9029 	 chance to use them.  */
9030       if (i == n)
9031 	{
9032 	  remove_value_from_changed_variables (val);
9033 	  n--;
9034 	}
9035     }
9036 }
9037 
9038 /* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
9039    CHANGED_VARIABLES and delete this chain.  WHERE specifies whether
9040    the notes shall be emitted before of after instruction INSN.  */
9041 
9042 static void
9043 emit_notes_for_changes (rtx_insn *insn, enum emit_note_where where,
9044 			shared_hash *vars)
9045 {
9046   emit_note_data data;
9047   variable_table_type *htab = shared_hash_htab (vars);
9048 
9049   if (!changed_variables->elements ())
9050     return;
9051 
9052   if (MAY_HAVE_DEBUG_BIND_INSNS)
9053     process_changed_values (htab);
9054 
9055   data.insn = insn;
9056   data.where = where;
9057   data.vars = htab;
9058 
9059   changed_variables
9060     ->traverse <emit_note_data*, emit_note_insn_var_location> (&data);
9061 }
9062 
9063 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
9064    same variable in hash table DATA or is not there at all.  */
9065 
9066 int
9067 emit_notes_for_differences_1 (variable **slot, variable_table_type *new_vars)
9068 {
9069   variable *old_var, *new_var;
9070 
9071   old_var = *slot;
9072   new_var = new_vars->find_with_hash (old_var->dv, dv_htab_hash (old_var->dv));
9073 
9074   if (!new_var)
9075     {
9076       /* Variable has disappeared.  */
9077       variable *empty_var = NULL;
9078 
9079       if (old_var->onepart == ONEPART_VALUE
9080 	  || old_var->onepart == ONEPART_DEXPR)
9081 	{
9082 	  empty_var = variable_from_dropped (old_var->dv, NO_INSERT);
9083 	  if (empty_var)
9084 	    {
9085 	      gcc_checking_assert (!empty_var->in_changed_variables);
9086 	      if (!VAR_LOC_1PAUX (old_var))
9087 		{
9088 		  VAR_LOC_1PAUX (old_var) = VAR_LOC_1PAUX (empty_var);
9089 		  VAR_LOC_1PAUX (empty_var) = NULL;
9090 		}
9091 	      else
9092 		gcc_checking_assert (!VAR_LOC_1PAUX (empty_var));
9093 	    }
9094 	}
9095 
9096       if (!empty_var)
9097 	{
9098 	  empty_var = onepart_pool_allocate (old_var->onepart);
9099 	  empty_var->dv = old_var->dv;
9100 	  empty_var->refcount = 0;
9101 	  empty_var->n_var_parts = 0;
9102 	  empty_var->onepart = old_var->onepart;
9103 	  empty_var->in_changed_variables = false;
9104 	}
9105 
9106       if (empty_var->onepart)
9107 	{
9108 	  /* Propagate the auxiliary data to (ultimately)
9109 	     changed_variables.  */
9110 	  empty_var->var_part[0].loc_chain = NULL;
9111 	  empty_var->var_part[0].cur_loc = NULL;
9112 	  VAR_LOC_1PAUX (empty_var) = VAR_LOC_1PAUX (old_var);
9113 	  VAR_LOC_1PAUX (old_var) = NULL;
9114 	}
9115       variable_was_changed (empty_var, NULL);
9116       /* Continue traversing the hash table.  */
9117       return 1;
9118     }
9119   /* Update cur_loc and one-part auxiliary data, before new_var goes
9120      through variable_was_changed.  */
9121   if (old_var != new_var && new_var->onepart)
9122     {
9123       gcc_checking_assert (VAR_LOC_1PAUX (new_var) == NULL);
9124       VAR_LOC_1PAUX (new_var) = VAR_LOC_1PAUX (old_var);
9125       VAR_LOC_1PAUX (old_var) = NULL;
9126       new_var->var_part[0].cur_loc = old_var->var_part[0].cur_loc;
9127     }
9128   if (variable_different_p (old_var, new_var))
9129     variable_was_changed (new_var, NULL);
9130 
9131   /* Continue traversing the hash table.  */
9132   return 1;
9133 }
9134 
9135 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
9136    table DATA.  */
9137 
9138 int
9139 emit_notes_for_differences_2 (variable **slot, variable_table_type *old_vars)
9140 {
9141   variable *old_var, *new_var;
9142 
9143   new_var = *slot;
9144   old_var = old_vars->find_with_hash (new_var->dv, dv_htab_hash (new_var->dv));
9145   if (!old_var)
9146     {
9147       int i;
9148       for (i = 0; i < new_var->n_var_parts; i++)
9149 	new_var->var_part[i].cur_loc = NULL;
9150       variable_was_changed (new_var, NULL);
9151     }
9152 
9153   /* Continue traversing the hash table.  */
9154   return 1;
9155 }
9156 
9157 /* Emit notes before INSN for differences between dataflow sets OLD_SET and
9158    NEW_SET.  */
9159 
9160 static void
9161 emit_notes_for_differences (rtx_insn *insn, dataflow_set *old_set,
9162 			    dataflow_set *new_set)
9163 {
9164   shared_hash_htab (old_set->vars)
9165     ->traverse <variable_table_type *, emit_notes_for_differences_1>
9166       (shared_hash_htab (new_set->vars));
9167   shared_hash_htab (new_set->vars)
9168     ->traverse <variable_table_type *, emit_notes_for_differences_2>
9169       (shared_hash_htab (old_set->vars));
9170   emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, new_set->vars);
9171 }
9172 
9173 /* Return the next insn after INSN that is not a NOTE_INSN_VAR_LOCATION.  */
9174 
9175 static rtx_insn *
9176 next_non_note_insn_var_location (rtx_insn *insn)
9177 {
9178   while (insn)
9179     {
9180       insn = NEXT_INSN (insn);
9181       if (insn == 0
9182 	  || !NOTE_P (insn)
9183 	  || NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION)
9184 	break;
9185     }
9186 
9187   return insn;
9188 }
9189 
9190 /* Emit the notes for changes of location parts in the basic block BB.  */
9191 
9192 static void
9193 emit_notes_in_bb (basic_block bb, dataflow_set *set)
9194 {
9195   unsigned int i;
9196   micro_operation *mo;
9197 
9198   dataflow_set_clear (set);
9199   dataflow_set_copy (set, &VTI (bb)->in);
9200 
9201   FOR_EACH_VEC_ELT (VTI (bb)->mos, i, mo)
9202     {
9203       rtx_insn *insn = mo->insn;
9204       rtx_insn *next_insn = next_non_note_insn_var_location (insn);
9205 
9206       switch (mo->type)
9207 	{
9208 	  case MO_CALL:
9209 	    dataflow_set_clear_at_call (set, insn);
9210 	    emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars);
9211 	    {
9212 	      rtx arguments = mo->u.loc, *p = &arguments;
9213 	      while (*p)
9214 		{
9215 		  XEXP (XEXP (*p, 0), 1)
9216 		    = vt_expand_loc (XEXP (XEXP (*p, 0), 1),
9217 				     shared_hash_htab (set->vars));
9218 		  /* If expansion is successful, keep it in the list.  */
9219 		  if (XEXP (XEXP (*p, 0), 1))
9220 		    {
9221 		      XEXP (XEXP (*p, 0), 1)
9222 			= copy_rtx_if_shared (XEXP (XEXP (*p, 0), 1));
9223 		      p = &XEXP (*p, 1);
9224 		    }
9225 		  /* Otherwise, if the following item is data_value for it,
9226 		     drop it too too.  */
9227 		  else if (XEXP (*p, 1)
9228 			   && REG_P (XEXP (XEXP (*p, 0), 0))
9229 			   && MEM_P (XEXP (XEXP (XEXP (*p, 1), 0), 0))
9230 			   && REG_P (XEXP (XEXP (XEXP (XEXP (*p, 1), 0), 0),
9231 					   0))
9232 			   && REGNO (XEXP (XEXP (*p, 0), 0))
9233 			      == REGNO (XEXP (XEXP (XEXP (XEXP (*p, 1), 0),
9234 						    0), 0)))
9235 		    *p = XEXP (XEXP (*p, 1), 1);
9236 		  /* Just drop this item.  */
9237 		  else
9238 		    *p = XEXP (*p, 1);
9239 		}
9240 	      add_reg_note (insn, REG_CALL_ARG_LOCATION, arguments);
9241 	    }
9242 	    break;
9243 
9244 	  case MO_USE:
9245 	    {
9246 	      rtx loc = mo->u.loc;
9247 
9248 	      if (REG_P (loc))
9249 		var_reg_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
9250 	      else
9251 		var_mem_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
9252 
9253 	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
9254 	    }
9255 	    break;
9256 
9257 	  case MO_VAL_LOC:
9258 	    {
9259 	      rtx loc = mo->u.loc;
9260 	      rtx val, vloc;
9261 	      tree var;
9262 
9263 	      if (GET_CODE (loc) == CONCAT)
9264 		{
9265 		  val = XEXP (loc, 0);
9266 		  vloc = XEXP (loc, 1);
9267 		}
9268 	      else
9269 		{
9270 		  val = NULL_RTX;
9271 		  vloc = loc;
9272 		}
9273 
9274 	      var = PAT_VAR_LOCATION_DECL (vloc);
9275 
9276 	      clobber_variable_part (set, NULL_RTX,
9277 				     dv_from_decl (var), 0, NULL_RTX);
9278 	      if (val)
9279 		{
9280 		  if (VAL_NEEDS_RESOLUTION (loc))
9281 		    val_resolve (set, val, PAT_VAR_LOCATION_LOC (vloc), insn);
9282 		  set_variable_part (set, val, dv_from_decl (var), 0,
9283 				     VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
9284 				     INSERT);
9285 		}
9286 	      else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
9287 		set_variable_part (set, PAT_VAR_LOCATION_LOC (vloc),
9288 				   dv_from_decl (var), 0,
9289 				   VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
9290 				   INSERT);
9291 
9292 	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
9293 	    }
9294 	    break;
9295 
9296 	  case MO_VAL_USE:
9297 	    {
9298 	      rtx loc = mo->u.loc;
9299 	      rtx val, vloc, uloc;
9300 
9301 	      vloc = uloc = XEXP (loc, 1);
9302 	      val = XEXP (loc, 0);
9303 
9304 	      if (GET_CODE (val) == CONCAT)
9305 		{
9306 		  uloc = XEXP (val, 1);
9307 		  val = XEXP (val, 0);
9308 		}
9309 
9310 	      if (VAL_NEEDS_RESOLUTION (loc))
9311 		val_resolve (set, val, vloc, insn);
9312 	      else
9313 		val_store (set, val, uloc, insn, false);
9314 
9315 	      if (VAL_HOLDS_TRACK_EXPR (loc))
9316 		{
9317 		  if (GET_CODE (uloc) == REG)
9318 		    var_reg_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
9319 				 NULL);
9320 		  else if (GET_CODE (uloc) == MEM)
9321 		    var_mem_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
9322 				 NULL);
9323 		}
9324 
9325 	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
9326 	    }
9327 	    break;
9328 
9329 	  case MO_VAL_SET:
9330 	    {
9331 	      rtx loc = mo->u.loc;
9332 	      rtx val, vloc, uloc;
9333 	      rtx dstv, srcv;
9334 
9335 	      vloc = loc;
9336 	      uloc = XEXP (vloc, 1);
9337 	      val = XEXP (vloc, 0);
9338 	      vloc = uloc;
9339 
9340 	      if (GET_CODE (uloc) == SET)
9341 		{
9342 		  dstv = SET_DEST (uloc);
9343 		  srcv = SET_SRC (uloc);
9344 		}
9345 	      else
9346 		{
9347 		  dstv = uloc;
9348 		  srcv = NULL;
9349 		}
9350 
9351 	      if (GET_CODE (val) == CONCAT)
9352 		{
9353 		  dstv = vloc = XEXP (val, 1);
9354 		  val = XEXP (val, 0);
9355 		}
9356 
9357 	      if (GET_CODE (vloc) == SET)
9358 		{
9359 		  srcv = SET_SRC (vloc);
9360 
9361 		  gcc_assert (val != srcv);
9362 		  gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
9363 
9364 		  dstv = vloc = SET_DEST (vloc);
9365 
9366 		  if (VAL_NEEDS_RESOLUTION (loc))
9367 		    val_resolve (set, val, srcv, insn);
9368 		}
9369 	      else if (VAL_NEEDS_RESOLUTION (loc))
9370 		{
9371 		  gcc_assert (GET_CODE (uloc) == SET
9372 			      && GET_CODE (SET_SRC (uloc)) == REG);
9373 		  val_resolve (set, val, SET_SRC (uloc), insn);
9374 		}
9375 
9376 	      if (VAL_HOLDS_TRACK_EXPR (loc))
9377 		{
9378 		  if (VAL_EXPR_IS_CLOBBERED (loc))
9379 		    {
9380 		      if (REG_P (uloc))
9381 			var_reg_delete (set, uloc, true);
9382 		      else if (MEM_P (uloc))
9383 			{
9384 			  gcc_assert (MEM_P (dstv));
9385 			  gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (uloc));
9386 			  var_mem_delete (set, dstv, true);
9387 			}
9388 		    }
9389 		  else
9390 		    {
9391 		      bool copied_p = VAL_EXPR_IS_COPIED (loc);
9392 		      rtx src = NULL, dst = uloc;
9393 		      enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
9394 
9395 		      if (GET_CODE (uloc) == SET)
9396 			{
9397 			  src = SET_SRC (uloc);
9398 			  dst = SET_DEST (uloc);
9399 			}
9400 
9401 		      if (copied_p)
9402 			{
9403 			  status = find_src_status (set, src);
9404 
9405 			  src = find_src_set_src (set, src);
9406 			}
9407 
9408 		      if (REG_P (dst))
9409 			var_reg_delete_and_set (set, dst, !copied_p,
9410 						status, srcv);
9411 		      else if (MEM_P (dst))
9412 			{
9413 			  gcc_assert (MEM_P (dstv));
9414 			  gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (dst));
9415 			  var_mem_delete_and_set (set, dstv, !copied_p,
9416 						  status, srcv);
9417 			}
9418 		    }
9419 		}
9420 	      else if (REG_P (uloc))
9421 		var_regno_delete (set, REGNO (uloc));
9422 	      else if (MEM_P (uloc))
9423 		{
9424 		  gcc_checking_assert (GET_CODE (vloc) == MEM);
9425 		  gcc_checking_assert (vloc == dstv);
9426 		  if (vloc != dstv)
9427 		    clobber_overlapping_mems (set, vloc);
9428 		}
9429 
9430 	      val_store (set, val, dstv, insn, true);
9431 
9432 	      emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
9433 				      set->vars);
9434 	    }
9435 	    break;
9436 
9437 	  case MO_SET:
9438 	    {
9439 	      rtx loc = mo->u.loc;
9440 	      rtx set_src = NULL;
9441 
9442 	      if (GET_CODE (loc) == SET)
9443 		{
9444 		  set_src = SET_SRC (loc);
9445 		  loc = SET_DEST (loc);
9446 		}
9447 
9448 	      if (REG_P (loc))
9449 		var_reg_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
9450 					set_src);
9451 	      else
9452 		var_mem_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
9453 					set_src);
9454 
9455 	      emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
9456 				      set->vars);
9457 	    }
9458 	    break;
9459 
9460 	  case MO_COPY:
9461 	    {
9462 	      rtx loc = mo->u.loc;
9463 	      enum var_init_status src_status;
9464 	      rtx set_src = NULL;
9465 
9466 	      if (GET_CODE (loc) == SET)
9467 		{
9468 		  set_src = SET_SRC (loc);
9469 		  loc = SET_DEST (loc);
9470 		}
9471 
9472 	      src_status = find_src_status (set, set_src);
9473 	      set_src = find_src_set_src (set, set_src);
9474 
9475 	      if (REG_P (loc))
9476 		var_reg_delete_and_set (set, loc, false, src_status, set_src);
9477 	      else
9478 		var_mem_delete_and_set (set, loc, false, src_status, set_src);
9479 
9480 	      emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
9481 				      set->vars);
9482 	    }
9483 	    break;
9484 
9485 	  case MO_USE_NO_VAR:
9486 	    {
9487 	      rtx loc = mo->u.loc;
9488 
9489 	      if (REG_P (loc))
9490 		var_reg_delete (set, loc, false);
9491 	      else
9492 		var_mem_delete (set, loc, false);
9493 
9494 	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
9495 	    }
9496 	    break;
9497 
9498 	  case MO_CLOBBER:
9499 	    {
9500 	      rtx loc = mo->u.loc;
9501 
9502 	      if (REG_P (loc))
9503 		var_reg_delete (set, loc, true);
9504 	      else
9505 		var_mem_delete (set, loc, true);
9506 
9507 	      emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
9508 				      set->vars);
9509 	    }
9510 	    break;
9511 
9512 	  case MO_ADJUST:
9513 	    set->stack_adjust += mo->u.adjust;
9514 	    break;
9515 	}
9516     }
9517 }
9518 
9519 /* Emit notes for the whole function.  */
9520 
9521 static void
9522 vt_emit_notes (void)
9523 {
9524   basic_block bb;
9525   dataflow_set cur;
9526 
9527   gcc_assert (!changed_variables->elements ());
9528 
9529   /* Free memory occupied by the out hash tables, as they aren't used
9530      anymore.  */
9531   FOR_EACH_BB_FN (bb, cfun)
9532     dataflow_set_clear (&VTI (bb)->out);
9533 
9534   /* Enable emitting notes by functions (mainly by set_variable_part and
9535      delete_variable_part).  */
9536   emit_notes = true;
9537 
9538   if (MAY_HAVE_DEBUG_BIND_INSNS)
9539     dropped_values = new variable_table_type (cselib_get_next_uid () * 2);
9540 
9541   dataflow_set_init (&cur);
9542 
9543   FOR_EACH_BB_FN (bb, cfun)
9544     {
9545       /* Emit the notes for changes of variable locations between two
9546 	 subsequent basic blocks.  */
9547       emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
9548 
9549       if (MAY_HAVE_DEBUG_BIND_INSNS)
9550 	local_get_addr_cache = new hash_map<rtx, rtx>;
9551 
9552       /* Emit the notes for the changes in the basic block itself.  */
9553       emit_notes_in_bb (bb, &cur);
9554 
9555       if (MAY_HAVE_DEBUG_BIND_INSNS)
9556 	delete local_get_addr_cache;
9557       local_get_addr_cache = NULL;
9558 
9559       /* Free memory occupied by the in hash table, we won't need it
9560 	 again.  */
9561       dataflow_set_clear (&VTI (bb)->in);
9562     }
9563 
9564   if (flag_checking)
9565     shared_hash_htab (cur.vars)
9566       ->traverse <variable_table_type *, emit_notes_for_differences_1>
9567 	(shared_hash_htab (empty_shared_hash));
9568 
9569   dataflow_set_destroy (&cur);
9570 
9571   if (MAY_HAVE_DEBUG_BIND_INSNS)
9572     delete dropped_values;
9573   dropped_values = NULL;
9574 
9575   emit_notes = false;
9576 }
9577 
9578 /* If there is a declaration and offset associated with register/memory RTL
9579    assign declaration to *DECLP and offset to *OFFSETP, and return true.  */
9580 
9581 static bool
9582 vt_get_decl_and_offset (rtx rtl, tree *declp, poly_int64 *offsetp)
9583 {
9584   if (REG_P (rtl))
9585     {
9586       if (REG_ATTRS (rtl))
9587 	{
9588 	  *declp = REG_EXPR (rtl);
9589 	  *offsetp = REG_OFFSET (rtl);
9590 	  return true;
9591 	}
9592     }
9593   else if (GET_CODE (rtl) == PARALLEL)
9594     {
9595       tree decl = NULL_TREE;
9596       HOST_WIDE_INT offset = MAX_VAR_PARTS;
9597       int len = XVECLEN (rtl, 0), i;
9598 
9599       for (i = 0; i < len; i++)
9600 	{
9601 	  rtx reg = XEXP (XVECEXP (rtl, 0, i), 0);
9602 	  if (!REG_P (reg) || !REG_ATTRS (reg))
9603 	    break;
9604 	  if (!decl)
9605 	    decl = REG_EXPR (reg);
9606 	  if (REG_EXPR (reg) != decl)
9607 	    break;
9608 	  HOST_WIDE_INT this_offset;
9609 	  if (!track_offset_p (REG_OFFSET (reg), &this_offset))
9610 	    break;
9611 	  offset = MIN (offset, this_offset);
9612 	}
9613 
9614       if (i == len)
9615 	{
9616 	  *declp = decl;
9617 	  *offsetp = offset;
9618 	  return true;
9619 	}
9620     }
9621   else if (MEM_P (rtl))
9622     {
9623       if (MEM_ATTRS (rtl))
9624 	{
9625 	  *declp = MEM_EXPR (rtl);
9626 	  *offsetp = int_mem_offset (rtl);
9627 	  return true;
9628 	}
9629     }
9630   return false;
9631 }
9632 
9633 /* Record the value for the ENTRY_VALUE of RTL as a global equivalence
9634    of VAL.  */
9635 
9636 static void
9637 record_entry_value (cselib_val *val, rtx rtl)
9638 {
9639   rtx ev = gen_rtx_ENTRY_VALUE (GET_MODE (rtl));
9640 
9641   ENTRY_VALUE_EXP (ev) = rtl;
9642 
9643   cselib_add_permanent_equiv (val, ev, get_insns ());
9644 }
9645 
9646 /* Insert function parameter PARM in IN and OUT sets of ENTRY_BLOCK.  */
9647 
9648 static void
9649 vt_add_function_parameter (tree parm)
9650 {
9651   rtx decl_rtl = DECL_RTL_IF_SET (parm);
9652   rtx incoming = DECL_INCOMING_RTL (parm);
9653   tree decl;
9654   machine_mode mode;
9655   poly_int64 offset;
9656   dataflow_set *out;
9657   decl_or_value dv;
9658   bool incoming_ok = true;
9659 
9660   if (TREE_CODE (parm) != PARM_DECL)
9661     return;
9662 
9663   if (!decl_rtl || !incoming)
9664     return;
9665 
9666   if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
9667     return;
9668 
9669   /* If there is a DRAP register or a pseudo in internal_arg_pointer,
9670      rewrite the incoming location of parameters passed on the stack
9671      into MEMs based on the argument pointer, so that incoming doesn't
9672      depend on a pseudo.  */
9673   if (MEM_P (incoming)
9674       && (XEXP (incoming, 0) == crtl->args.internal_arg_pointer
9675 	  || (GET_CODE (XEXP (incoming, 0)) == PLUS
9676 	      && XEXP (XEXP (incoming, 0), 0)
9677 		 == crtl->args.internal_arg_pointer
9678 	      && CONST_INT_P (XEXP (XEXP (incoming, 0), 1)))))
9679     {
9680       HOST_WIDE_INT off = -FIRST_PARM_OFFSET (current_function_decl);
9681       if (GET_CODE (XEXP (incoming, 0)) == PLUS)
9682 	off += INTVAL (XEXP (XEXP (incoming, 0), 1));
9683       incoming
9684 	= replace_equiv_address_nv (incoming,
9685 				    plus_constant (Pmode,
9686 						   arg_pointer_rtx, off));
9687     }
9688 
9689 #ifdef HAVE_window_save
9690   /* DECL_INCOMING_RTL uses the INCOMING_REGNO of parameter registers.
9691      If the target machine has an explicit window save instruction, the
9692      actual entry value is the corresponding OUTGOING_REGNO instead.  */
9693   if (HAVE_window_save && !crtl->uses_only_leaf_regs)
9694     {
9695       if (REG_P (incoming)
9696 	  && HARD_REGISTER_P (incoming)
9697 	  && OUTGOING_REGNO (REGNO (incoming)) != REGNO (incoming))
9698 	{
9699 	  parm_reg p;
9700 	  p.incoming = incoming;
9701 	  incoming
9702 	    = gen_rtx_REG_offset (incoming, GET_MODE (incoming),
9703 				  OUTGOING_REGNO (REGNO (incoming)), 0);
9704 	  p.outgoing = incoming;
9705 	  vec_safe_push (windowed_parm_regs, p);
9706 	}
9707       else if (GET_CODE (incoming) == PARALLEL)
9708 	{
9709 	  rtx outgoing
9710 	    = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (XVECLEN (incoming, 0)));
9711 	  int i;
9712 
9713 	  for (i = 0; i < XVECLEN (incoming, 0); i++)
9714 	    {
9715 	      rtx reg = XEXP (XVECEXP (incoming, 0, i), 0);
9716 	      parm_reg p;
9717 	      p.incoming = reg;
9718 	      reg = gen_rtx_REG_offset (reg, GET_MODE (reg),
9719 					OUTGOING_REGNO (REGNO (reg)), 0);
9720 	      p.outgoing = reg;
9721 	      XVECEXP (outgoing, 0, i)
9722 		= gen_rtx_EXPR_LIST (VOIDmode, reg,
9723 				     XEXP (XVECEXP (incoming, 0, i), 1));
9724 	      vec_safe_push (windowed_parm_regs, p);
9725 	    }
9726 
9727 	  incoming = outgoing;
9728 	}
9729       else if (MEM_P (incoming)
9730 	       && REG_P (XEXP (incoming, 0))
9731 	       && HARD_REGISTER_P (XEXP (incoming, 0)))
9732 	{
9733 	  rtx reg = XEXP (incoming, 0);
9734 	  if (OUTGOING_REGNO (REGNO (reg)) != REGNO (reg))
9735 	    {
9736 	      parm_reg p;
9737 	      p.incoming = reg;
9738 	      reg = gen_raw_REG (GET_MODE (reg), OUTGOING_REGNO (REGNO (reg)));
9739 	      p.outgoing = reg;
9740 	      vec_safe_push (windowed_parm_regs, p);
9741 	      incoming = replace_equiv_address_nv (incoming, reg);
9742 	    }
9743 	}
9744     }
9745 #endif
9746 
9747   if (!vt_get_decl_and_offset (incoming, &decl, &offset))
9748     {
9749       incoming_ok = false;
9750       if (MEM_P (incoming))
9751 	{
9752 	  /* This means argument is passed by invisible reference.  */
9753 	  offset = 0;
9754 	  decl = parm;
9755 	}
9756       else
9757 	{
9758 	  if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
9759 	    return;
9760 	  offset += byte_lowpart_offset (GET_MODE (incoming),
9761 					 GET_MODE (decl_rtl));
9762 	}
9763     }
9764 
9765   if (!decl)
9766     return;
9767 
9768   if (parm != decl)
9769     {
9770       /* If that DECL_RTL wasn't a pseudo that got spilled to
9771 	 memory, bail out.  Otherwise, the spill slot sharing code
9772 	 will force the memory to reference spill_slot_decl (%sfp),
9773 	 so we don't match above.  That's ok, the pseudo must have
9774 	 referenced the entire parameter, so just reset OFFSET.  */
9775       if (decl != get_spill_slot_decl (false))
9776         return;
9777       offset = 0;
9778     }
9779 
9780   HOST_WIDE_INT const_offset;
9781   if (!track_loc_p (incoming, parm, offset, false, &mode, &const_offset))
9782     return;
9783 
9784   out = &VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->out;
9785 
9786   dv = dv_from_decl (parm);
9787 
9788   if (target_for_debug_bind (parm)
9789       /* We can't deal with these right now, because this kind of
9790 	 variable is single-part.  ??? We could handle parallels
9791 	 that describe multiple locations for the same single
9792 	 value, but ATM we don't.  */
9793       && GET_CODE (incoming) != PARALLEL)
9794     {
9795       cselib_val *val;
9796       rtx lowpart;
9797 
9798       /* ??? We shouldn't ever hit this, but it may happen because
9799 	 arguments passed by invisible reference aren't dealt with
9800 	 above: incoming-rtl will have Pmode rather than the
9801 	 expected mode for the type.  */
9802       if (const_offset)
9803 	return;
9804 
9805       lowpart = var_lowpart (mode, incoming);
9806       if (!lowpart)
9807 	return;
9808 
9809       val = cselib_lookup_from_insn (lowpart, mode, true,
9810 				     VOIDmode, get_insns ());
9811 
9812       /* ??? Float-typed values in memory are not handled by
9813 	 cselib.  */
9814       if (val)
9815 	{
9816 	  preserve_value (val);
9817 	  set_variable_part (out, val->val_rtx, dv, const_offset,
9818 			     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9819 	  dv = dv_from_value (val->val_rtx);
9820 	}
9821 
9822       if (MEM_P (incoming))
9823 	{
9824 	  val = cselib_lookup_from_insn (XEXP (incoming, 0), mode, true,
9825 					 VOIDmode, get_insns ());
9826 	  if (val)
9827 	    {
9828 	      preserve_value (val);
9829 	      incoming = replace_equiv_address_nv (incoming, val->val_rtx);
9830 	    }
9831 	}
9832     }
9833 
9834   if (REG_P (incoming))
9835     {
9836       incoming = var_lowpart (mode, incoming);
9837       gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
9838       attrs_list_insert (&out->regs[REGNO (incoming)], dv, const_offset,
9839 			 incoming);
9840       set_variable_part (out, incoming, dv, const_offset,
9841 			 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9842       if (dv_is_value_p (dv))
9843 	{
9844 	  record_entry_value (CSELIB_VAL_PTR (dv_as_value (dv)), incoming);
9845 	  if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE
9846 	      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (parm))))
9847 	    {
9848 	      machine_mode indmode
9849 		= TYPE_MODE (TREE_TYPE (TREE_TYPE (parm)));
9850 	      rtx mem = gen_rtx_MEM (indmode, incoming);
9851 	      cselib_val *val = cselib_lookup_from_insn (mem, indmode, true,
9852 							 VOIDmode,
9853 							 get_insns ());
9854 	      if (val)
9855 		{
9856 		  preserve_value (val);
9857 		  record_entry_value (val, mem);
9858 		  set_variable_part (out, mem, dv_from_value (val->val_rtx), 0,
9859 				     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9860 		}
9861 	    }
9862 	}
9863     }
9864   else if (GET_CODE (incoming) == PARALLEL && !dv_onepart_p (dv))
9865     {
9866       int i;
9867 
9868       /* The following code relies on vt_get_decl_and_offset returning true for
9869 	 incoming, which might not be always the case.  */
9870       if (!incoming_ok)
9871 	return;
9872       for (i = 0; i < XVECLEN (incoming, 0); i++)
9873 	{
9874 	  rtx reg = XEXP (XVECEXP (incoming, 0, i), 0);
9875 	  /* vt_get_decl_and_offset has already checked that the offset
9876 	     is a valid variable part.  */
9877 	  const_offset = get_tracked_reg_offset (reg);
9878 	  gcc_assert (REGNO (reg) < FIRST_PSEUDO_REGISTER);
9879 	  attrs_list_insert (&out->regs[REGNO (reg)], dv, const_offset, reg);
9880 	  set_variable_part (out, reg, dv, const_offset,
9881 			     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9882 	}
9883     }
9884   else if (MEM_P (incoming))
9885     {
9886       incoming = var_lowpart (mode, incoming);
9887       set_variable_part (out, incoming, dv, const_offset,
9888 			 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9889     }
9890 }
9891 
9892 /* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */
9893 
9894 static void
9895 vt_add_function_parameters (void)
9896 {
9897   tree parm;
9898 
9899   for (parm = DECL_ARGUMENTS (current_function_decl);
9900        parm; parm = DECL_CHAIN (parm))
9901     if (!POINTER_BOUNDS_P (parm))
9902       vt_add_function_parameter (parm);
9903 
9904   if (DECL_HAS_VALUE_EXPR_P (DECL_RESULT (current_function_decl)))
9905     {
9906       tree vexpr = DECL_VALUE_EXPR (DECL_RESULT (current_function_decl));
9907 
9908       if (TREE_CODE (vexpr) == INDIRECT_REF)
9909 	vexpr = TREE_OPERAND (vexpr, 0);
9910 
9911       if (TREE_CODE (vexpr) == PARM_DECL
9912 	  && DECL_ARTIFICIAL (vexpr)
9913 	  && !DECL_IGNORED_P (vexpr)
9914 	  && DECL_NAMELESS (vexpr))
9915 	vt_add_function_parameter (vexpr);
9916     }
9917 }
9918 
9919 /* Initialize cfa_base_rtx, create a preserved VALUE for it and
9920    ensure it isn't flushed during cselib_reset_table.
9921    Can be called only if frame_pointer_rtx resp. arg_pointer_rtx
9922    has been eliminated.  */
9923 
9924 static void
9925 vt_init_cfa_base (void)
9926 {
9927   cselib_val *val;
9928 
9929 #ifdef FRAME_POINTER_CFA_OFFSET
9930   cfa_base_rtx = frame_pointer_rtx;
9931   cfa_base_offset = -FRAME_POINTER_CFA_OFFSET (current_function_decl);
9932 #else
9933   cfa_base_rtx = arg_pointer_rtx;
9934   cfa_base_offset = -ARG_POINTER_CFA_OFFSET (current_function_decl);
9935 #endif
9936   if (cfa_base_rtx == hard_frame_pointer_rtx
9937       || !fixed_regs[REGNO (cfa_base_rtx)])
9938     {
9939       cfa_base_rtx = NULL_RTX;
9940       return;
9941     }
9942   if (!MAY_HAVE_DEBUG_BIND_INSNS)
9943     return;
9944 
9945   /* Tell alias analysis that cfa_base_rtx should share
9946      find_base_term value with stack pointer or hard frame pointer.  */
9947   if (!frame_pointer_needed)
9948     vt_equate_reg_base_value (cfa_base_rtx, stack_pointer_rtx);
9949   else if (!crtl->stack_realign_tried)
9950     vt_equate_reg_base_value (cfa_base_rtx, hard_frame_pointer_rtx);
9951 
9952   val = cselib_lookup_from_insn (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1,
9953 				 VOIDmode, get_insns ());
9954   preserve_value (val);
9955   cselib_preserve_cfa_base_value (val, REGNO (cfa_base_rtx));
9956 }
9957 
9958 /* Reemit INSN, a MARKER_DEBUG_INSN, as a note.  */
9959 
9960 static rtx_insn *
9961 reemit_marker_as_note (rtx_insn *insn)
9962 {
9963   gcc_checking_assert (DEBUG_MARKER_INSN_P (insn));
9964 
9965   enum insn_note kind = INSN_DEBUG_MARKER_KIND (insn);
9966 
9967   switch (kind)
9968     {
9969     case NOTE_INSN_BEGIN_STMT:
9970     case NOTE_INSN_INLINE_ENTRY:
9971       {
9972 	rtx_insn *note = NULL;
9973 	if (cfun->debug_nonbind_markers)
9974 	  {
9975 	    note = emit_note_before (kind, insn);
9976 	    NOTE_MARKER_LOCATION (note) = INSN_LOCATION (insn);
9977 	  }
9978 	delete_insn (insn);
9979 	return note;
9980       }
9981 
9982     default:
9983       gcc_unreachable ();
9984     }
9985 }
9986 
9987 /* Allocate and initialize the data structures for variable tracking
9988    and parse the RTL to get the micro operations.  */
9989 
9990 static bool
9991 vt_initialize (void)
9992 {
9993   basic_block bb;
9994   HOST_WIDE_INT fp_cfa_offset = -1;
9995 
9996   alloc_aux_for_blocks (sizeof (variable_tracking_info));
9997 
9998   empty_shared_hash = shared_hash_pool.allocate ();
9999   empty_shared_hash->refcount = 1;
10000   empty_shared_hash->htab = new variable_table_type (1);
10001   changed_variables = new variable_table_type (10);
10002 
10003   /* Init the IN and OUT sets.  */
10004   FOR_ALL_BB_FN (bb, cfun)
10005     {
10006       VTI (bb)->visited = false;
10007       VTI (bb)->flooded = false;
10008       dataflow_set_init (&VTI (bb)->in);
10009       dataflow_set_init (&VTI (bb)->out);
10010       VTI (bb)->permp = NULL;
10011     }
10012 
10013   if (MAY_HAVE_DEBUG_BIND_INSNS)
10014     {
10015       cselib_init (CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS);
10016       scratch_regs = BITMAP_ALLOC (NULL);
10017       preserved_values.create (256);
10018       global_get_addr_cache = new hash_map<rtx, rtx>;
10019     }
10020   else
10021     {
10022       scratch_regs = NULL;
10023       global_get_addr_cache = NULL;
10024     }
10025 
10026   if (MAY_HAVE_DEBUG_BIND_INSNS)
10027     {
10028       rtx reg, expr;
10029       int ofst;
10030       cselib_val *val;
10031 
10032 #ifdef FRAME_POINTER_CFA_OFFSET
10033       reg = frame_pointer_rtx;
10034       ofst = FRAME_POINTER_CFA_OFFSET (current_function_decl);
10035 #else
10036       reg = arg_pointer_rtx;
10037       ofst = ARG_POINTER_CFA_OFFSET (current_function_decl);
10038 #endif
10039 
10040       ofst -= INCOMING_FRAME_SP_OFFSET;
10041 
10042       val = cselib_lookup_from_insn (reg, GET_MODE (reg), 1,
10043 				     VOIDmode, get_insns ());
10044       preserve_value (val);
10045       if (reg != hard_frame_pointer_rtx && fixed_regs[REGNO (reg)])
10046 	cselib_preserve_cfa_base_value (val, REGNO (reg));
10047       expr = plus_constant (GET_MODE (stack_pointer_rtx),
10048 			    stack_pointer_rtx, -ofst);
10049       cselib_add_permanent_equiv (val, expr, get_insns ());
10050 
10051       if (ofst)
10052 	{
10053 	  val = cselib_lookup_from_insn (stack_pointer_rtx,
10054 					 GET_MODE (stack_pointer_rtx), 1,
10055 					 VOIDmode, get_insns ());
10056 	  preserve_value (val);
10057 	  expr = plus_constant (GET_MODE (reg), reg, ofst);
10058 	  cselib_add_permanent_equiv (val, expr, get_insns ());
10059 	}
10060     }
10061 
10062   /* In order to factor out the adjustments made to the stack pointer or to
10063      the hard frame pointer and thus be able to use DW_OP_fbreg operations
10064      instead of individual location lists, we're going to rewrite MEMs based
10065      on them into MEMs based on the CFA by de-eliminating stack_pointer_rtx
10066      or hard_frame_pointer_rtx to the virtual CFA pointer frame_pointer_rtx
10067      resp. arg_pointer_rtx.  We can do this either when there is no frame
10068      pointer in the function and stack adjustments are consistent for all
10069      basic blocks or when there is a frame pointer and no stack realignment.
10070      But we first have to check that frame_pointer_rtx resp. arg_pointer_rtx
10071      has been eliminated.  */
10072   if (!frame_pointer_needed)
10073     {
10074       rtx reg, elim;
10075 
10076       if (!vt_stack_adjustments ())
10077 	return false;
10078 
10079 #ifdef FRAME_POINTER_CFA_OFFSET
10080       reg = frame_pointer_rtx;
10081 #else
10082       reg = arg_pointer_rtx;
10083 #endif
10084       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
10085       if (elim != reg)
10086 	{
10087 	  if (GET_CODE (elim) == PLUS)
10088 	    elim = XEXP (elim, 0);
10089 	  if (elim == stack_pointer_rtx)
10090 	    vt_init_cfa_base ();
10091 	}
10092     }
10093   else if (!crtl->stack_realign_tried)
10094     {
10095       rtx reg, elim;
10096 
10097 #ifdef FRAME_POINTER_CFA_OFFSET
10098       reg = frame_pointer_rtx;
10099       fp_cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
10100 #else
10101       reg = arg_pointer_rtx;
10102       fp_cfa_offset = ARG_POINTER_CFA_OFFSET (current_function_decl);
10103 #endif
10104       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
10105       if (elim != reg)
10106 	{
10107 	  if (GET_CODE (elim) == PLUS)
10108 	    {
10109 	      fp_cfa_offset -= INTVAL (XEXP (elim, 1));
10110 	      elim = XEXP (elim, 0);
10111 	    }
10112 	  if (elim != hard_frame_pointer_rtx)
10113 	    fp_cfa_offset = -1;
10114 	}
10115       else
10116 	fp_cfa_offset = -1;
10117     }
10118 
10119   /* If the stack is realigned and a DRAP register is used, we're going to
10120      rewrite MEMs based on it representing incoming locations of parameters
10121      passed on the stack into MEMs based on the argument pointer.  Although
10122      we aren't going to rewrite other MEMs, we still need to initialize the
10123      virtual CFA pointer in order to ensure that the argument pointer will
10124      be seen as a constant throughout the function.
10125 
10126      ??? This doesn't work if FRAME_POINTER_CFA_OFFSET is defined.  */
10127   else if (stack_realign_drap)
10128     {
10129       rtx reg, elim;
10130 
10131 #ifdef FRAME_POINTER_CFA_OFFSET
10132       reg = frame_pointer_rtx;
10133 #else
10134       reg = arg_pointer_rtx;
10135 #endif
10136       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
10137       if (elim != reg)
10138 	{
10139 	  if (GET_CODE (elim) == PLUS)
10140 	    elim = XEXP (elim, 0);
10141 	  if (elim == hard_frame_pointer_rtx)
10142 	    vt_init_cfa_base ();
10143 	}
10144     }
10145 
10146   hard_frame_pointer_adjustment = -1;
10147 
10148   vt_add_function_parameters ();
10149 
10150   FOR_EACH_BB_FN (bb, cfun)
10151     {
10152       rtx_insn *insn;
10153       HOST_WIDE_INT pre, post = 0;
10154       basic_block first_bb, last_bb;
10155 
10156       if (MAY_HAVE_DEBUG_BIND_INSNS)
10157 	{
10158 	  cselib_record_sets_hook = add_with_sets;
10159 	  if (dump_file && (dump_flags & TDF_DETAILS))
10160 	    fprintf (dump_file, "first value: %i\n",
10161 		     cselib_get_next_uid ());
10162 	}
10163 
10164       first_bb = bb;
10165       for (;;)
10166 	{
10167 	  edge e;
10168 	  if (bb->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
10169 	      || ! single_pred_p (bb->next_bb))
10170 	    break;
10171 	  e = find_edge (bb, bb->next_bb);
10172 	  if (! e || (e->flags & EDGE_FALLTHRU) == 0)
10173 	    break;
10174 	  bb = bb->next_bb;
10175 	}
10176       last_bb = bb;
10177 
10178       /* Add the micro-operations to the vector.  */
10179       FOR_BB_BETWEEN (bb, first_bb, last_bb->next_bb, next_bb)
10180 	{
10181 	  HOST_WIDE_INT offset = VTI (bb)->out.stack_adjust;
10182 	  VTI (bb)->out.stack_adjust = VTI (bb)->in.stack_adjust;
10183 
10184 	  rtx_insn *next;
10185 	  FOR_BB_INSNS_SAFE (bb, insn, next)
10186 	    {
10187 	      if (INSN_P (insn))
10188 		{
10189 		  if (!frame_pointer_needed)
10190 		    {
10191 		      insn_stack_adjust_offset_pre_post (insn, &pre, &post);
10192 		      if (pre)
10193 			{
10194 			  micro_operation mo;
10195 			  mo.type = MO_ADJUST;
10196 			  mo.u.adjust = pre;
10197 			  mo.insn = insn;
10198 			  if (dump_file && (dump_flags & TDF_DETAILS))
10199 			    log_op_type (PATTERN (insn), bb, insn,
10200 					 MO_ADJUST, dump_file);
10201 			  VTI (bb)->mos.safe_push (mo);
10202 			  VTI (bb)->out.stack_adjust += pre;
10203 			}
10204 		    }
10205 
10206 		  cselib_hook_called = false;
10207 		  adjust_insn (bb, insn);
10208 		  if (DEBUG_MARKER_INSN_P (insn))
10209 		    {
10210 		      reemit_marker_as_note (insn);
10211 		      continue;
10212 		    }
10213 
10214 		  if (MAY_HAVE_DEBUG_BIND_INSNS)
10215 		    {
10216 		      if (CALL_P (insn))
10217 			prepare_call_arguments (bb, insn);
10218 		      cselib_process_insn (insn);
10219 		      if (dump_file && (dump_flags & TDF_DETAILS))
10220 			{
10221 			  print_rtl_single (dump_file, insn);
10222 			  dump_cselib_table (dump_file);
10223 			}
10224 		    }
10225 		  if (!cselib_hook_called)
10226 		    add_with_sets (insn, 0, 0);
10227 		  cancel_changes (0);
10228 
10229 		  if (!frame_pointer_needed && post)
10230 		    {
10231 		      micro_operation mo;
10232 		      mo.type = MO_ADJUST;
10233 		      mo.u.adjust = post;
10234 		      mo.insn = insn;
10235 		      if (dump_file && (dump_flags & TDF_DETAILS))
10236 			log_op_type (PATTERN (insn), bb, insn,
10237 				     MO_ADJUST, dump_file);
10238 		      VTI (bb)->mos.safe_push (mo);
10239 		      VTI (bb)->out.stack_adjust += post;
10240 		    }
10241 
10242 		  if (fp_cfa_offset != -1
10243 		      && hard_frame_pointer_adjustment == -1
10244 		      && fp_setter_insn (insn))
10245 		    {
10246 		      vt_init_cfa_base ();
10247 		      hard_frame_pointer_adjustment = fp_cfa_offset;
10248 		      /* Disassociate sp from fp now.  */
10249 		      if (MAY_HAVE_DEBUG_BIND_INSNS)
10250 			{
10251 			  cselib_val *v;
10252 			  cselib_invalidate_rtx (stack_pointer_rtx);
10253 			  v = cselib_lookup (stack_pointer_rtx, Pmode, 1,
10254 					     VOIDmode);
10255 			  if (v && !cselib_preserved_value_p (v))
10256 			    {
10257 			      cselib_set_value_sp_based (v);
10258 			      preserve_value (v);
10259 			    }
10260 			}
10261 		    }
10262 		}
10263 	    }
10264 	  gcc_assert (offset == VTI (bb)->out.stack_adjust);
10265 	}
10266 
10267       bb = last_bb;
10268 
10269       if (MAY_HAVE_DEBUG_BIND_INSNS)
10270 	{
10271 	  cselib_preserve_only_values ();
10272 	  cselib_reset_table (cselib_get_next_uid ());
10273 	  cselib_record_sets_hook = NULL;
10274 	}
10275     }
10276 
10277   hard_frame_pointer_adjustment = -1;
10278   VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->flooded = true;
10279   cfa_base_rtx = NULL_RTX;
10280   return true;
10281 }
10282 
10283 /* This is *not* reset after each function.  It gives each
10284    NOTE_INSN_DELETED_DEBUG_LABEL in the entire compilation
10285    a unique label number.  */
10286 
10287 static int debug_label_num = 1;
10288 
10289 /* Remove from the insn stream a single debug insn used for
10290    variable tracking at assignments.  */
10291 
10292 static inline void
10293 delete_vta_debug_insn (rtx_insn *insn)
10294 {
10295   if (DEBUG_MARKER_INSN_P (insn))
10296     {
10297       reemit_marker_as_note (insn);
10298       return;
10299     }
10300 
10301   tree decl = INSN_VAR_LOCATION_DECL (insn);
10302   if (TREE_CODE (decl) == LABEL_DECL
10303       && DECL_NAME (decl)
10304       && !DECL_RTL_SET_P (decl))
10305     {
10306       PUT_CODE (insn, NOTE);
10307       NOTE_KIND (insn) = NOTE_INSN_DELETED_DEBUG_LABEL;
10308       NOTE_DELETED_LABEL_NAME (insn)
10309 	= IDENTIFIER_POINTER (DECL_NAME (decl));
10310       SET_DECL_RTL (decl, insn);
10311       CODE_LABEL_NUMBER (insn) = debug_label_num++;
10312     }
10313   else
10314     delete_insn (insn);
10315 }
10316 
10317 /* Remove from the insn stream all debug insns used for variable
10318    tracking at assignments.  USE_CFG should be false if the cfg is no
10319    longer usable.  */
10320 
10321 void
10322 delete_vta_debug_insns (bool use_cfg)
10323 {
10324   basic_block bb;
10325   rtx_insn *insn, *next;
10326 
10327   if (!MAY_HAVE_DEBUG_INSNS)
10328     return;
10329 
10330   if (use_cfg)
10331     FOR_EACH_BB_FN (bb, cfun)
10332       {
10333 	FOR_BB_INSNS_SAFE (bb, insn, next)
10334 	  if (DEBUG_INSN_P (insn))
10335 	    delete_vta_debug_insn (insn);
10336       }
10337   else
10338     for (insn = get_insns (); insn; insn = next)
10339       {
10340 	next = NEXT_INSN (insn);
10341 	if (DEBUG_INSN_P (insn))
10342 	  delete_vta_debug_insn (insn);
10343       }
10344 }
10345 
10346 /* Run a fast, BB-local only version of var tracking, to take care of
10347    information that we don't do global analysis on, such that not all
10348    information is lost.  If SKIPPED holds, we're skipping the global
10349    pass entirely, so we should try to use information it would have
10350    handled as well..  */
10351 
10352 static void
10353 vt_debug_insns_local (bool skipped ATTRIBUTE_UNUSED)
10354 {
10355   /* ??? Just skip it all for now.  */
10356   delete_vta_debug_insns (true);
10357 }
10358 
10359 /* Free the data structures needed for variable tracking.  */
10360 
10361 static void
10362 vt_finalize (void)
10363 {
10364   basic_block bb;
10365 
10366   FOR_EACH_BB_FN (bb, cfun)
10367     {
10368       VTI (bb)->mos.release ();
10369     }
10370 
10371   FOR_ALL_BB_FN (bb, cfun)
10372     {
10373       dataflow_set_destroy (&VTI (bb)->in);
10374       dataflow_set_destroy (&VTI (bb)->out);
10375       if (VTI (bb)->permp)
10376 	{
10377 	  dataflow_set_destroy (VTI (bb)->permp);
10378 	  XDELETE (VTI (bb)->permp);
10379 	}
10380     }
10381   free_aux_for_blocks ();
10382   delete empty_shared_hash->htab;
10383   empty_shared_hash->htab = NULL;
10384   delete changed_variables;
10385   changed_variables = NULL;
10386   attrs_pool.release ();
10387   var_pool.release ();
10388   location_chain_pool.release ();
10389   shared_hash_pool.release ();
10390 
10391   if (MAY_HAVE_DEBUG_BIND_INSNS)
10392     {
10393       if (global_get_addr_cache)
10394 	delete global_get_addr_cache;
10395       global_get_addr_cache = NULL;
10396       loc_exp_dep_pool.release ();
10397       valvar_pool.release ();
10398       preserved_values.release ();
10399       cselib_finish ();
10400       BITMAP_FREE (scratch_regs);
10401       scratch_regs = NULL;
10402     }
10403 
10404 #ifdef HAVE_window_save
10405   vec_free (windowed_parm_regs);
10406 #endif
10407 
10408   if (vui_vec)
10409     XDELETEVEC (vui_vec);
10410   vui_vec = NULL;
10411   vui_allocated = 0;
10412 }
10413 
10414 /* The entry point to variable tracking pass.  */
10415 
10416 static inline unsigned int
10417 variable_tracking_main_1 (void)
10418 {
10419   bool success;
10420 
10421   /* We won't be called as a separate pass if flag_var_tracking is not
10422      set, but final may call us to turn debug markers into notes.  */
10423   if ((!flag_var_tracking && MAY_HAVE_DEBUG_INSNS)
10424       || flag_var_tracking_assignments < 0
10425       /* Var-tracking right now assumes the IR doesn't contain
10426 	 any pseudos at this point.  */
10427       || targetm.no_register_allocation)
10428     {
10429       delete_vta_debug_insns (true);
10430       return 0;
10431     }
10432 
10433   if (!flag_var_tracking)
10434     return 0;
10435 
10436   if (n_basic_blocks_for_fn (cfun) > 500
10437       && n_edges_for_fn (cfun) / n_basic_blocks_for_fn (cfun) >= 20)
10438     {
10439       vt_debug_insns_local (true);
10440       return 0;
10441     }
10442 
10443   mark_dfs_back_edges ();
10444   if (!vt_initialize ())
10445     {
10446       vt_finalize ();
10447       vt_debug_insns_local (true);
10448       return 0;
10449     }
10450 
10451   success = vt_find_locations ();
10452 
10453   if (!success && flag_var_tracking_assignments > 0)
10454     {
10455       vt_finalize ();
10456 
10457       delete_vta_debug_insns (true);
10458 
10459       /* This is later restored by our caller.  */
10460       flag_var_tracking_assignments = 0;
10461 
10462       success = vt_initialize ();
10463       gcc_assert (success);
10464 
10465       success = vt_find_locations ();
10466     }
10467 
10468   if (!success)
10469     {
10470       vt_finalize ();
10471       vt_debug_insns_local (false);
10472       return 0;
10473     }
10474 
10475   if (dump_file && (dump_flags & TDF_DETAILS))
10476     {
10477       dump_dataflow_sets ();
10478       dump_reg_info (dump_file);
10479       dump_flow_info (dump_file, dump_flags);
10480     }
10481 
10482   timevar_push (TV_VAR_TRACKING_EMIT);
10483   vt_emit_notes ();
10484   timevar_pop (TV_VAR_TRACKING_EMIT);
10485 
10486   vt_finalize ();
10487   vt_debug_insns_local (false);
10488   return 0;
10489 }
10490 
10491 unsigned int
10492 variable_tracking_main (void)
10493 {
10494   unsigned int ret;
10495   int save = flag_var_tracking_assignments;
10496 
10497   ret = variable_tracking_main_1 ();
10498 
10499   flag_var_tracking_assignments = save;
10500 
10501   return ret;
10502 }
10503 
10504 namespace {
10505 
10506 const pass_data pass_data_variable_tracking =
10507 {
10508   RTL_PASS, /* type */
10509   "vartrack", /* name */
10510   OPTGROUP_NONE, /* optinfo_flags */
10511   TV_VAR_TRACKING, /* tv_id */
10512   0, /* properties_required */
10513   0, /* properties_provided */
10514   0, /* properties_destroyed */
10515   0, /* todo_flags_start */
10516   0, /* todo_flags_finish */
10517 };
10518 
10519 class pass_variable_tracking : public rtl_opt_pass
10520 {
10521 public:
10522   pass_variable_tracking (gcc::context *ctxt)
10523     : rtl_opt_pass (pass_data_variable_tracking, ctxt)
10524   {}
10525 
10526   /* opt_pass methods: */
10527   virtual bool gate (function *)
10528     {
10529       return (flag_var_tracking && !targetm.delay_vartrack);
10530     }
10531 
10532   virtual unsigned int execute (function *)
10533     {
10534       return variable_tracking_main ();
10535     }
10536 
10537 }; // class pass_variable_tracking
10538 
10539 } // anon namespace
10540 
10541 rtl_opt_pass *
10542 make_pass_variable_tracking (gcc::context *ctxt)
10543 {
10544   return new pass_variable_tracking (ctxt);
10545 }
10546