gcc80: Handle TZ specific "%+" format in strftime.
[dragonfly.git] / contrib / gcc-8.0 / gcc / var-tracking.c
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 \f
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 }