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