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