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