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