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