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