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