gimple.h: Remove all includes.
[platform/upstream/gcc.git] / gcc / var-tracking.c
1 /* Variable tracking routines for the GNU compiler.
2    Copyright (C) 2002-2013 Free Software Foundation, Inc.
3
4    This file is part of GCC.
5
6    GCC is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10
11    GCC is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GCC; see the file COPYING3.  If not see
18    <http://www.gnu.org/licenses/>.  */
19
20 /* This file contains the variable tracking pass.  It computes where
21    variables are located (which registers or where in memory) at each position
22    in instruction stream and emits notes describing the locations.
23    Debug information (DWARF2 location lists) is finally generated from
24    these notes.
25    With this debug information, it is possible to show variables
26    even when debugging optimized code.
27
28    How does the variable tracking pass work?
29
30    First, it scans RTL code for uses, stores and clobbers (register/memory
31    references in instructions), for call insns and for stack adjustments
32    separately for each basic block and saves them to an array of micro
33    operations.
34    The micro operations of one instruction are ordered so that
35    pre-modifying stack adjustment < use < use with no var < call insn <
36      < clobber < set < post-modifying stack adjustment
37
38    Then, a forward dataflow analysis is performed to find out how locations
39    of variables change through code and to propagate the variable locations
40    along control flow graph.
41    The IN set for basic block BB is computed as a union of OUT sets of BB's
42    predecessors, the OUT set for BB is copied from the IN set for BB and
43    is changed according to micro operations in BB.
44
45    The IN and OUT sets for basic blocks consist of a current stack adjustment
46    (used for adjusting offset of variables addressed using stack pointer),
47    the table of structures describing the locations of parts of a variable
48    and for each physical register a linked list for each physical register.
49    The linked list is a list of variable parts stored in the register,
50    i.e. it is a list of triplets (reg, decl, offset) where decl is
51    REG_EXPR (reg) and offset is REG_OFFSET (reg).  The linked list is used for
52    effective deleting appropriate variable parts when we set or clobber the
53    register.
54
55    There may be more than one variable part in a register.  The linked lists
56    should be pretty short so it is a good data structure here.
57    For example in the following code, register allocator may assign same
58    register to variables A and B, and both of them are stored in the same
59    register in CODE:
60
61      if (cond)
62        set A;
63      else
64        set B;
65      CODE;
66      if (cond)
67        use A;
68      else
69        use B;
70
71    Finally, the NOTE_INSN_VAR_LOCATION notes describing the variable locations
72    are emitted to appropriate positions in RTL code.  Each such a note describes
73    the location of one variable at the point in instruction stream where the
74    note is.  There is no need to emit a note for each variable before each
75    instruction, we only emit these notes where the location of variable changes
76    (this means that we also emit notes for changes between the OUT set of the
77    previous block and the IN set of the current block).
78
79    The notes consist of two parts:
80    1. the declaration (from REG_EXPR or MEM_EXPR)
81    2. the location of a variable - it is either a simple register/memory
82       reference (for simple variables, for example int),
83       or a parallel of register/memory references (for a large variables
84       which consist of several parts, for example long long).
85
86 */
87
88 #include "config.h"
89 #include "system.h"
90 #include "coretypes.h"
91 #include "tm.h"
92 #include "rtl.h"
93 #include "tree.h"
94 #include "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 (vt_get_canonicalize_base ((rtx)*slot) == x)
2485     *slot = NULL;
2486   return true;
2487 }
2488
2489 /* Reset this node, detaching all its equivalences.  Return the slot
2490    in the variable hash table that holds dv, if there is one.  */
2491
2492 static void
2493 val_reset (dataflow_set *set, decl_or_value dv)
2494 {
2495   variable var = shared_hash_find (set->vars, dv) ;
2496   location_chain node;
2497   rtx cval;
2498
2499   if (!var || !var->n_var_parts)
2500     return;
2501
2502   gcc_assert (var->n_var_parts == 1);
2503
2504   if (var->onepart == ONEPART_VALUE)
2505     {
2506       rtx x = dv_as_value (dv);
2507       void **slot;
2508       
2509       /* Relationships in the global cache don't change, so reset the
2510          local cache entry only.  */
2511       slot = pointer_map_contains (local_get_addr_cache, x);
2512       if (slot)
2513         {
2514           /* If the value resolved back to itself, odds are that other
2515              values may have cached it too.  These entries now refer
2516              to the old X, so detach them too.  Entries that used the
2517              old X but resolved to something else remain ok as long as
2518              that something else isn't also reset.  */
2519           if (*slot == x)
2520             pointer_map_traverse (local_get_addr_cache,
2521                                   local_get_addr_clear_given_value, x);
2522           *slot = NULL;
2523         }
2524     }
2525
2526   cval = NULL;
2527   for (node = var->var_part[0].loc_chain; node; node = node->next)
2528     if (GET_CODE (node->loc) == VALUE
2529         && canon_value_cmp (node->loc, cval))
2530       cval = node->loc;
2531
2532   for (node = var->var_part[0].loc_chain; node; node = node->next)
2533     if (GET_CODE (node->loc) == VALUE && cval != node->loc)
2534       {
2535         /* Redirect the equivalence link to the new canonical
2536            value, or simply remove it if it would point at
2537            itself.  */
2538         if (cval)
2539           set_variable_part (set, cval, dv_from_value (node->loc),
2540                              0, node->init, node->set_src, NO_INSERT);
2541         delete_variable_part (set, dv_as_value (dv),
2542                               dv_from_value (node->loc), 0);
2543       }
2544
2545   if (cval)
2546     {
2547       decl_or_value cdv = dv_from_value (cval);
2548
2549       /* Keep the remaining values connected, accummulating links
2550          in the canonical value.  */
2551       for (node = var->var_part[0].loc_chain; node; node = node->next)
2552         {
2553           if (node->loc == cval)
2554             continue;
2555           else if (GET_CODE (node->loc) == REG)
2556             var_reg_decl_set (set, node->loc, node->init, cdv, 0,
2557                               node->set_src, NO_INSERT);
2558           else if (GET_CODE (node->loc) == MEM)
2559             var_mem_decl_set (set, node->loc, node->init, cdv, 0,
2560                               node->set_src, NO_INSERT);
2561           else
2562             set_variable_part (set, node->loc, cdv, 0,
2563                                node->init, node->set_src, NO_INSERT);
2564         }
2565     }
2566
2567   /* We remove this last, to make sure that the canonical value is not
2568      removed to the point of requiring reinsertion.  */
2569   if (cval)
2570     delete_variable_part (set, dv_as_value (dv), dv_from_value (cval), 0);
2571
2572   clobber_variable_part (set, NULL, dv, 0, NULL);
2573 }
2574
2575 /* Find the values in a given location and map the val to another
2576    value, if it is unique, or add the location as one holding the
2577    value.  */
2578
2579 static void
2580 val_resolve (dataflow_set *set, rtx val, rtx loc, rtx insn)
2581 {
2582   decl_or_value dv = dv_from_value (val);
2583
2584   if (dump_file && (dump_flags & TDF_DETAILS))
2585     {
2586       if (insn)
2587         fprintf (dump_file, "%i: ", INSN_UID (insn));
2588       else
2589         fprintf (dump_file, "head: ");
2590       print_inline_rtx (dump_file, val, 0);
2591       fputs (" is at ", dump_file);
2592       print_inline_rtx (dump_file, loc, 0);
2593       fputc ('\n', dump_file);
2594     }
2595
2596   val_reset (set, dv);
2597
2598   gcc_checking_assert (!unsuitable_loc (loc));
2599
2600   if (REG_P (loc))
2601     {
2602       attrs node, found = NULL;
2603
2604       for (node = set->regs[REGNO (loc)]; node; node = node->next)
2605         if (dv_is_value_p (node->dv)
2606             && GET_MODE (dv_as_value (node->dv)) == GET_MODE (loc))
2607           {
2608             found = node;
2609
2610             /* Map incoming equivalences.  ??? Wouldn't it be nice if
2611              we just started sharing the location lists?  Maybe a
2612              circular list ending at the value itself or some
2613              such.  */
2614             set_variable_part (set, dv_as_value (node->dv),
2615                                dv_from_value (val), node->offset,
2616                                VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
2617             set_variable_part (set, val, node->dv, node->offset,
2618                                VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
2619           }
2620
2621       /* If we didn't find any equivalence, we need to remember that
2622          this value is held in the named register.  */
2623       if (found)
2624         return;
2625     }
2626   /* ??? Attempt to find and merge equivalent MEMs or other
2627      expressions too.  */
2628
2629   val_bind (set, val, loc, false);
2630 }
2631
2632 /* Initialize dataflow set SET to be empty.
2633    VARS_SIZE is the initial size of hash table VARS.  */
2634
2635 static void
2636 dataflow_set_init (dataflow_set *set)
2637 {
2638   init_attrs_list_set (set->regs);
2639   set->vars = shared_hash_copy (empty_shared_hash);
2640   set->stack_adjust = 0;
2641   set->traversed_vars = NULL;
2642 }
2643
2644 /* Delete the contents of dataflow set SET.  */
2645
2646 static void
2647 dataflow_set_clear (dataflow_set *set)
2648 {
2649   int i;
2650
2651   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2652     attrs_list_clear (&set->regs[i]);
2653
2654   shared_hash_destroy (set->vars);
2655   set->vars = shared_hash_copy (empty_shared_hash);
2656 }
2657
2658 /* Copy the contents of dataflow set SRC to DST.  */
2659
2660 static void
2661 dataflow_set_copy (dataflow_set *dst, dataflow_set *src)
2662 {
2663   int i;
2664
2665   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2666     attrs_list_copy (&dst->regs[i], src->regs[i]);
2667
2668   shared_hash_destroy (dst->vars);
2669   dst->vars = shared_hash_copy (src->vars);
2670   dst->stack_adjust = src->stack_adjust;
2671 }
2672
2673 /* Information for merging lists of locations for a given offset of variable.
2674  */
2675 struct variable_union_info
2676 {
2677   /* Node of the location chain.  */
2678   location_chain lc;
2679
2680   /* The sum of positions in the input chains.  */
2681   int pos;
2682
2683   /* The position in the chain of DST dataflow set.  */
2684   int pos_dst;
2685 };
2686
2687 /* Buffer for location list sorting and its allocated size.  */
2688 static struct variable_union_info *vui_vec;
2689 static int vui_allocated;
2690
2691 /* Compare function for qsort, order the structures by POS element.  */
2692
2693 static int
2694 variable_union_info_cmp_pos (const void *n1, const void *n2)
2695 {
2696   const struct variable_union_info *const i1 =
2697     (const struct variable_union_info *) n1;
2698   const struct variable_union_info *const i2 =
2699     ( const struct variable_union_info *) n2;
2700
2701   if (i1->pos != i2->pos)
2702     return i1->pos - i2->pos;
2703
2704   return (i1->pos_dst - i2->pos_dst);
2705 }
2706
2707 /* Compute union of location parts of variable *SLOT and the same variable
2708    from hash table DATA.  Compute "sorted" union of the location chains
2709    for common offsets, i.e. the locations of a variable part are sorted by
2710    a priority where the priority is the sum of the positions in the 2 chains
2711    (if a location is only in one list the position in the second list is
2712    defined to be larger than the length of the chains).
2713    When we are updating the location parts the newest location is in the
2714    beginning of the chain, so when we do the described "sorted" union
2715    we keep the newest locations in the beginning.  */
2716
2717 static int
2718 variable_union (variable src, dataflow_set *set)
2719 {
2720   variable dst;
2721   variable_def **dstp;
2722   int i, j, k;
2723
2724   dstp = shared_hash_find_slot (set->vars, src->dv);
2725   if (!dstp || !*dstp)
2726     {
2727       src->refcount++;
2728
2729       dst_can_be_shared = false;
2730       if (!dstp)
2731         dstp = shared_hash_find_slot_unshare (&set->vars, src->dv, INSERT);
2732
2733       *dstp = src;
2734
2735       /* Continue traversing the hash table.  */
2736       return 1;
2737     }
2738   else
2739     dst = *dstp;
2740
2741   gcc_assert (src->n_var_parts);
2742   gcc_checking_assert (src->onepart == dst->onepart);
2743
2744   /* We can combine one-part variables very efficiently, because their
2745      entries are in canonical order.  */
2746   if (src->onepart)
2747     {
2748       location_chain *nodep, dnode, snode;
2749
2750       gcc_assert (src->n_var_parts == 1
2751                   && dst->n_var_parts == 1);
2752
2753       snode = src->var_part[0].loc_chain;
2754       gcc_assert (snode);
2755
2756     restart_onepart_unshared:
2757       nodep = &dst->var_part[0].loc_chain;
2758       dnode = *nodep;
2759       gcc_assert (dnode);
2760
2761       while (snode)
2762         {
2763           int r = dnode ? loc_cmp (dnode->loc, snode->loc) : 1;
2764
2765           if (r > 0)
2766             {
2767               location_chain nnode;
2768
2769               if (shared_var_p (dst, set->vars))
2770                 {
2771                   dstp = unshare_variable (set, dstp, dst,
2772                                            VAR_INIT_STATUS_INITIALIZED);
2773                   dst = *dstp;
2774                   goto restart_onepart_unshared;
2775                 }
2776
2777               *nodep = nnode = (location_chain) pool_alloc (loc_chain_pool);
2778               nnode->loc = snode->loc;
2779               nnode->init = snode->init;
2780               if (!snode->set_src || MEM_P (snode->set_src))
2781                 nnode->set_src = NULL;
2782               else
2783                 nnode->set_src = snode->set_src;
2784               nnode->next = dnode;
2785               dnode = nnode;
2786             }
2787           else if (r == 0)
2788             gcc_checking_assert (rtx_equal_p (dnode->loc, snode->loc));
2789
2790           if (r >= 0)
2791             snode = snode->next;
2792
2793           nodep = &dnode->next;
2794           dnode = *nodep;
2795         }
2796
2797       return 1;
2798     }
2799
2800   gcc_checking_assert (!src->onepart);
2801
2802   /* Count the number of location parts, result is K.  */
2803   for (i = 0, j = 0, k = 0;
2804        i < src->n_var_parts && j < dst->n_var_parts; k++)
2805     {
2806       if (VAR_PART_OFFSET (src, i) == VAR_PART_OFFSET (dst, j))
2807         {
2808           i++;
2809           j++;
2810         }
2811       else if (VAR_PART_OFFSET (src, i) < VAR_PART_OFFSET (dst, j))
2812         i++;
2813       else
2814         j++;
2815     }
2816   k += src->n_var_parts - i;
2817   k += dst->n_var_parts - j;
2818
2819   /* We track only variables whose size is <= MAX_VAR_PARTS bytes
2820      thus there are at most MAX_VAR_PARTS different offsets.  */
2821   gcc_checking_assert (dst->onepart ? k == 1 : k <= MAX_VAR_PARTS);
2822
2823   if (dst->n_var_parts != k && shared_var_p (dst, set->vars))
2824     {
2825       dstp = unshare_variable (set, dstp, dst, VAR_INIT_STATUS_UNKNOWN);
2826       dst = *dstp;
2827     }
2828
2829   i = src->n_var_parts - 1;
2830   j = dst->n_var_parts - 1;
2831   dst->n_var_parts = k;
2832
2833   for (k--; k >= 0; k--)
2834     {
2835       location_chain node, node2;
2836
2837       if (i >= 0 && j >= 0
2838           && VAR_PART_OFFSET (src, i) == VAR_PART_OFFSET (dst, j))
2839         {
2840           /* Compute the "sorted" union of the chains, i.e. the locations which
2841              are in both chains go first, they are sorted by the sum of
2842              positions in the chains.  */
2843           int dst_l, src_l;
2844           int ii, jj, n;
2845           struct variable_union_info *vui;
2846
2847           /* If DST is shared compare the location chains.
2848              If they are different we will modify the chain in DST with
2849              high probability so make a copy of DST.  */
2850           if (shared_var_p (dst, set->vars))
2851             {
2852               for (node = src->var_part[i].loc_chain,
2853                    node2 = dst->var_part[j].loc_chain; node && node2;
2854                    node = node->next, node2 = node2->next)
2855                 {
2856                   if (!((REG_P (node2->loc)
2857                          && REG_P (node->loc)
2858                          && REGNO (node2->loc) == REGNO (node->loc))
2859                         || rtx_equal_p (node2->loc, node->loc)))
2860                     {
2861                       if (node2->init < node->init)
2862                         node2->init = node->init;
2863                       break;
2864                     }
2865                 }
2866               if (node || node2)
2867                 {
2868                   dstp = unshare_variable (set, dstp, dst,
2869                                            VAR_INIT_STATUS_UNKNOWN);
2870                   dst = (variable)*dstp;
2871                 }
2872             }
2873
2874           src_l = 0;
2875           for (node = src->var_part[i].loc_chain; node; node = node->next)
2876             src_l++;
2877           dst_l = 0;
2878           for (node = dst->var_part[j].loc_chain; node; node = node->next)
2879             dst_l++;
2880
2881           if (dst_l == 1)
2882             {
2883               /* The most common case, much simpler, no qsort is needed.  */
2884               location_chain dstnode = dst->var_part[j].loc_chain;
2885               dst->var_part[k].loc_chain = dstnode;
2886               VAR_PART_OFFSET (dst, k) = VAR_PART_OFFSET (dst, j);
2887               node2 = dstnode;
2888               for (node = src->var_part[i].loc_chain; node; node = node->next)
2889                 if (!((REG_P (dstnode->loc)
2890                        && REG_P (node->loc)
2891                        && REGNO (dstnode->loc) == REGNO (node->loc))
2892                       || rtx_equal_p (dstnode->loc, node->loc)))
2893                   {
2894                     location_chain new_node;
2895
2896                     /* Copy the location from SRC.  */
2897                     new_node = (location_chain) pool_alloc (loc_chain_pool);
2898                     new_node->loc = node->loc;
2899                     new_node->init = node->init;
2900                     if (!node->set_src || MEM_P (node->set_src))
2901                       new_node->set_src = NULL;
2902                     else
2903                       new_node->set_src = node->set_src;
2904                     node2->next = new_node;
2905                     node2 = new_node;
2906                   }
2907               node2->next = NULL;
2908             }
2909           else
2910             {
2911               if (src_l + dst_l > vui_allocated)
2912                 {
2913                   vui_allocated = MAX (vui_allocated * 2, src_l + dst_l);
2914                   vui_vec = XRESIZEVEC (struct variable_union_info, vui_vec,
2915                                         vui_allocated);
2916                 }
2917               vui = vui_vec;
2918
2919               /* Fill in the locations from DST.  */
2920               for (node = dst->var_part[j].loc_chain, jj = 0; node;
2921                    node = node->next, jj++)
2922                 {
2923                   vui[jj].lc = node;
2924                   vui[jj].pos_dst = jj;
2925
2926                   /* Pos plus value larger than a sum of 2 valid positions.  */
2927                   vui[jj].pos = jj + src_l + dst_l;
2928                 }
2929
2930               /* Fill in the locations from SRC.  */
2931               n = dst_l;
2932               for (node = src->var_part[i].loc_chain, ii = 0; node;
2933                    node = node->next, ii++)
2934                 {
2935                   /* Find location from NODE.  */
2936                   for (jj = 0; jj < dst_l; jj++)
2937                     {
2938                       if ((REG_P (vui[jj].lc->loc)
2939                            && REG_P (node->loc)
2940                            && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
2941                           || rtx_equal_p (vui[jj].lc->loc, node->loc))
2942                         {
2943                           vui[jj].pos = jj + ii;
2944                           break;
2945                         }
2946                     }
2947                   if (jj >= dst_l)      /* The location has not been found.  */
2948                     {
2949                       location_chain new_node;
2950
2951                       /* Copy the location from SRC.  */
2952                       new_node = (location_chain) pool_alloc (loc_chain_pool);
2953                       new_node->loc = node->loc;
2954                       new_node->init = node->init;
2955                       if (!node->set_src || MEM_P (node->set_src))
2956                         new_node->set_src = NULL;
2957                       else
2958                         new_node->set_src = node->set_src;
2959                       vui[n].lc = new_node;
2960                       vui[n].pos_dst = src_l + dst_l;
2961                       vui[n].pos = ii + src_l + dst_l;
2962                       n++;
2963                     }
2964                 }
2965
2966               if (dst_l == 2)
2967                 {
2968                   /* Special case still very common case.  For dst_l == 2
2969                      all entries dst_l ... n-1 are sorted, with for i >= dst_l
2970                      vui[i].pos == i + src_l + dst_l.  */
2971                   if (vui[0].pos > vui[1].pos)
2972                     {
2973                       /* Order should be 1, 0, 2... */
2974                       dst->var_part[k].loc_chain = vui[1].lc;
2975                       vui[1].lc->next = vui[0].lc;
2976                       if (n >= 3)
2977                         {
2978                           vui[0].lc->next = vui[2].lc;
2979                           vui[n - 1].lc->next = NULL;
2980                         }
2981                       else
2982                         vui[0].lc->next = NULL;
2983                       ii = 3;
2984                     }
2985                   else
2986                     {
2987                       dst->var_part[k].loc_chain = vui[0].lc;
2988                       if (n >= 3 && vui[2].pos < vui[1].pos)
2989                         {
2990                           /* Order should be 0, 2, 1, 3... */
2991                           vui[0].lc->next = vui[2].lc;
2992                           vui[2].lc->next = vui[1].lc;
2993                           if (n >= 4)
2994                             {
2995                               vui[1].lc->next = vui[3].lc;
2996                               vui[n - 1].lc->next = NULL;
2997                             }
2998                           else
2999                             vui[1].lc->next = NULL;
3000                           ii = 4;
3001                         }
3002                       else
3003                         {
3004                           /* Order should be 0, 1, 2... */
3005                           ii = 1;
3006                           vui[n - 1].lc->next = NULL;
3007                         }
3008                     }
3009                   for (; ii < n; ii++)
3010                     vui[ii - 1].lc->next = vui[ii].lc;
3011                 }
3012               else
3013                 {
3014                   qsort (vui, n, sizeof (struct variable_union_info),
3015                          variable_union_info_cmp_pos);
3016
3017                   /* Reconnect the nodes in sorted order.  */
3018                   for (ii = 1; ii < n; ii++)
3019                     vui[ii - 1].lc->next = vui[ii].lc;
3020                   vui[n - 1].lc->next = NULL;
3021                   dst->var_part[k].loc_chain = vui[0].lc;
3022                 }
3023
3024               VAR_PART_OFFSET (dst, k) = VAR_PART_OFFSET (dst, j);
3025             }
3026           i--;
3027           j--;
3028         }
3029       else if ((i >= 0 && j >= 0
3030                 && VAR_PART_OFFSET (src, i) < VAR_PART_OFFSET (dst, j))
3031                || i < 0)
3032         {
3033           dst->var_part[k] = dst->var_part[j];
3034           j--;
3035         }
3036       else if ((i >= 0 && j >= 0
3037                 && VAR_PART_OFFSET (src, i) > VAR_PART_OFFSET (dst, j))
3038                || j < 0)
3039         {
3040           location_chain *nextp;
3041
3042           /* Copy the chain from SRC.  */
3043           nextp = &dst->var_part[k].loc_chain;
3044           for (node = src->var_part[i].loc_chain; node; node = node->next)
3045             {
3046               location_chain new_lc;
3047
3048               new_lc = (location_chain) pool_alloc (loc_chain_pool);
3049               new_lc->next = NULL;
3050               new_lc->init = node->init;
3051               if (!node->set_src || MEM_P (node->set_src))
3052                 new_lc->set_src = NULL;
3053               else
3054                 new_lc->set_src = node->set_src;
3055               new_lc->loc = node->loc;
3056
3057               *nextp = new_lc;
3058               nextp = &new_lc->next;
3059             }
3060
3061           VAR_PART_OFFSET (dst, k) = VAR_PART_OFFSET (src, i);
3062           i--;
3063         }
3064       dst->var_part[k].cur_loc = NULL;
3065     }
3066
3067   if (flag_var_tracking_uninit)
3068     for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
3069       {
3070         location_chain node, node2;
3071         for (node = src->var_part[i].loc_chain; node; node = node->next)
3072           for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
3073             if (rtx_equal_p (node->loc, node2->loc))
3074               {
3075                 if (node->init > node2->init)
3076                   node2->init = node->init;
3077               }
3078       }
3079
3080   /* Continue traversing the hash table.  */
3081   return 1;
3082 }
3083
3084 /* Compute union of dataflow sets SRC and DST and store it to DST.  */
3085
3086 static void
3087 dataflow_set_union (dataflow_set *dst, dataflow_set *src)
3088 {
3089   int i;
3090
3091   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3092     attrs_list_union (&dst->regs[i], src->regs[i]);
3093
3094   if (dst->vars == empty_shared_hash)
3095     {
3096       shared_hash_destroy (dst->vars);
3097       dst->vars = shared_hash_copy (src->vars);
3098     }
3099   else
3100     {
3101       variable_iterator_type hi;
3102       variable var;
3103
3104       FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (src->vars),
3105                                    var, variable, hi)
3106         variable_union (var, dst);
3107     }
3108 }
3109
3110 /* Whether the value is currently being expanded.  */
3111 #define VALUE_RECURSED_INTO(x) \
3112   (RTL_FLAG_CHECK2 ("VALUE_RECURSED_INTO", (x), VALUE, DEBUG_EXPR)->used)
3113
3114 /* Whether no expansion was found, saving useless lookups.
3115    It must only be set when VALUE_CHANGED is clear.  */
3116 #define NO_LOC_P(x) \
3117   (RTL_FLAG_CHECK2 ("NO_LOC_P", (x), VALUE, DEBUG_EXPR)->return_val)
3118
3119 /* Whether cur_loc in the value needs to be (re)computed.  */
3120 #define VALUE_CHANGED(x) \
3121   (RTL_FLAG_CHECK1 ("VALUE_CHANGED", (x), VALUE)->frame_related)
3122 /* Whether cur_loc in the decl needs to be (re)computed.  */
3123 #define DECL_CHANGED(x) TREE_VISITED (x)
3124
3125 /* Record (if NEWV) that DV needs to have its cur_loc recomputed.  For
3126    user DECLs, this means they're in changed_variables.  Values and
3127    debug exprs may be left with this flag set if no user variable
3128    requires them to be evaluated.  */
3129
3130 static inline void
3131 set_dv_changed (decl_or_value dv, bool newv)
3132 {
3133   switch (dv_onepart_p (dv))
3134     {
3135     case ONEPART_VALUE:
3136       if (newv)
3137         NO_LOC_P (dv_as_value (dv)) = false;
3138       VALUE_CHANGED (dv_as_value (dv)) = newv;
3139       break;
3140
3141     case ONEPART_DEXPR:
3142       if (newv)
3143         NO_LOC_P (DECL_RTL_KNOWN_SET (dv_as_decl (dv))) = false;
3144       /* Fall through...  */
3145
3146     default:
3147       DECL_CHANGED (dv_as_decl (dv)) = newv;
3148       break;
3149     }
3150 }
3151
3152 /* Return true if DV needs to have its cur_loc recomputed.  */
3153
3154 static inline bool
3155 dv_changed_p (decl_or_value dv)
3156 {
3157   return (dv_is_value_p (dv)
3158           ? VALUE_CHANGED (dv_as_value (dv))
3159           : DECL_CHANGED (dv_as_decl (dv)));
3160 }
3161
3162 /* Return a location list node whose loc is rtx_equal to LOC, in the
3163    location list of a one-part variable or value VAR, or in that of
3164    any values recursively mentioned in the location lists.  VARS must
3165    be in star-canonical form.  */
3166
3167 static location_chain
3168 find_loc_in_1pdv (rtx loc, variable var, variable_table_type vars)
3169 {
3170   location_chain node;
3171   enum rtx_code loc_code;
3172
3173   if (!var)
3174     return NULL;
3175
3176   gcc_checking_assert (var->onepart);
3177
3178   if (!var->n_var_parts)
3179     return NULL;
3180
3181   gcc_checking_assert (loc != dv_as_opaque (var->dv));
3182
3183   loc_code = GET_CODE (loc);
3184   for (node = var->var_part[0].loc_chain; node; node = node->next)
3185     {
3186       decl_or_value dv;
3187       variable rvar;
3188
3189       if (GET_CODE (node->loc) != loc_code)
3190         {
3191           if (GET_CODE (node->loc) != VALUE)
3192             continue;
3193         }
3194       else if (loc == node->loc)
3195         return node;
3196       else if (loc_code != VALUE)
3197         {
3198           if (rtx_equal_p (loc, node->loc))
3199             return node;
3200           continue;
3201         }
3202
3203       /* Since we're in star-canonical form, we don't need to visit
3204          non-canonical nodes: one-part variables and non-canonical
3205          values would only point back to the canonical node.  */
3206       if (dv_is_value_p (var->dv)
3207           && !canon_value_cmp (node->loc, dv_as_value (var->dv)))
3208         {
3209           /* Skip all subsequent VALUEs.  */
3210           while (node->next && GET_CODE (node->next->loc) == VALUE)
3211             {
3212               node = node->next;
3213               gcc_checking_assert (!canon_value_cmp (node->loc,
3214                                                      dv_as_value (var->dv)));
3215               if (loc == node->loc)
3216                 return node;
3217             }
3218           continue;
3219         }
3220
3221       gcc_checking_assert (node == var->var_part[0].loc_chain);
3222       gcc_checking_assert (!node->next);
3223
3224       dv = dv_from_value (node->loc);
3225       rvar = vars.find_with_hash (dv, dv_htab_hash (dv));
3226       return find_loc_in_1pdv (loc, rvar, vars);
3227     }
3228
3229   /* ??? Gotta look in cselib_val locations too.  */
3230
3231   return NULL;
3232 }
3233
3234 /* Hash table iteration argument passed to variable_merge.  */
3235 struct dfset_merge
3236 {
3237   /* The set in which the merge is to be inserted.  */
3238   dataflow_set *dst;
3239   /* The set that we're iterating in.  */
3240   dataflow_set *cur;
3241   /* The set that may contain the other dv we are to merge with.  */
3242   dataflow_set *src;
3243   /* Number of onepart dvs in src.  */
3244   int src_onepart_cnt;
3245 };
3246
3247 /* Insert LOC in *DNODE, if it's not there yet.  The list must be in
3248    loc_cmp order, and it is maintained as such.  */
3249
3250 static void
3251 insert_into_intersection (location_chain *nodep, rtx loc,
3252                           enum var_init_status status)
3253 {
3254   location_chain node;
3255   int r;
3256
3257   for (node = *nodep; node; nodep = &node->next, node = *nodep)
3258     if ((r = loc_cmp (node->loc, loc)) == 0)
3259       {
3260         node->init = MIN (node->init, status);
3261         return;
3262       }
3263     else if (r > 0)
3264       break;
3265
3266   node = (location_chain) pool_alloc (loc_chain_pool);
3267
3268   node->loc = loc;
3269   node->set_src = NULL;
3270   node->init = status;
3271   node->next = *nodep;
3272   *nodep = node;
3273 }
3274
3275 /* Insert in DEST the intersection of the locations present in both
3276    S1NODE and S2VAR, directly or indirectly.  S1NODE is from a
3277    variable in DSM->cur, whereas S2VAR is from DSM->src.  dvar is in
3278    DSM->dst.  */
3279
3280 static void
3281 intersect_loc_chains (rtx val, location_chain *dest, struct dfset_merge *dsm,
3282                       location_chain s1node, variable s2var)
3283 {
3284   dataflow_set *s1set = dsm->cur;
3285   dataflow_set *s2set = dsm->src;
3286   location_chain found;
3287
3288   if (s2var)
3289     {
3290       location_chain s2node;
3291
3292       gcc_checking_assert (s2var->onepart);
3293
3294       if (s2var->n_var_parts)
3295         {
3296           s2node = s2var->var_part[0].loc_chain;
3297
3298           for (; s1node && s2node;
3299                s1node = s1node->next, s2node = s2node->next)
3300             if (s1node->loc != s2node->loc)
3301               break;
3302             else if (s1node->loc == val)
3303               continue;
3304             else
3305               insert_into_intersection (dest, s1node->loc,
3306                                         MIN (s1node->init, s2node->init));
3307         }
3308     }
3309
3310   for (; s1node; s1node = s1node->next)
3311     {
3312       if (s1node->loc == val)
3313         continue;
3314
3315       if ((found = find_loc_in_1pdv (s1node->loc, s2var,
3316                                      shared_hash_htab (s2set->vars))))
3317         {
3318           insert_into_intersection (dest, s1node->loc,
3319                                     MIN (s1node->init, found->init));
3320           continue;
3321         }
3322
3323       if (GET_CODE (s1node->loc) == VALUE
3324           && !VALUE_RECURSED_INTO (s1node->loc))
3325         {
3326           decl_or_value dv = dv_from_value (s1node->loc);
3327           variable svar = shared_hash_find (s1set->vars, dv);
3328           if (svar)
3329             {
3330               if (svar->n_var_parts == 1)
3331                 {
3332                   VALUE_RECURSED_INTO (s1node->loc) = true;
3333                   intersect_loc_chains (val, dest, dsm,
3334                                         svar->var_part[0].loc_chain,
3335                                         s2var);
3336                   VALUE_RECURSED_INTO (s1node->loc) = false;
3337                 }
3338             }
3339         }
3340
3341       /* ??? gotta look in cselib_val locations too.  */
3342
3343       /* ??? if the location is equivalent to any location in src,
3344          searched recursively
3345
3346            add to dst the values needed to represent the equivalence
3347
3348      telling whether locations S is equivalent to another dv's
3349      location list:
3350
3351        for each location D in the list
3352
3353          if S and D satisfy rtx_equal_p, then it is present
3354
3355          else if D is a value, recurse without cycles
3356
3357          else if S and D have the same CODE and MODE
3358
3359            for each operand oS and the corresponding oD
3360
3361              if oS and oD are not equivalent, then S an D are not equivalent
3362
3363              else if they are RTX vectors
3364
3365                if any vector oS element is not equivalent to its respective oD,
3366                then S and D are not equivalent
3367
3368    */
3369
3370
3371     }
3372 }
3373
3374 /* Return -1 if X should be before Y in a location list for a 1-part
3375    variable, 1 if Y should be before X, and 0 if they're equivalent
3376    and should not appear in the list.  */
3377
3378 static int
3379 loc_cmp (rtx x, rtx y)
3380 {
3381   int i, j, r;
3382   RTX_CODE code = GET_CODE (x);
3383   const char *fmt;
3384
3385   if (x == y)
3386     return 0;
3387
3388   if (REG_P (x))
3389     {
3390       if (!REG_P (y))
3391         return -1;
3392       gcc_assert (GET_MODE (x) == GET_MODE (y));
3393       if (REGNO (x) == REGNO (y))
3394         return 0;
3395       else if (REGNO (x) < REGNO (y))
3396         return -1;
3397       else
3398         return 1;
3399     }
3400
3401   if (REG_P (y))
3402     return 1;
3403
3404   if (MEM_P (x))
3405     {
3406       if (!MEM_P (y))
3407         return -1;
3408       gcc_assert (GET_MODE (x) == GET_MODE (y));
3409       return loc_cmp (XEXP (x, 0), XEXP (y, 0));
3410     }
3411
3412   if (MEM_P (y))
3413     return 1;
3414
3415   if (GET_CODE (x) == VALUE)
3416     {
3417       if (GET_CODE (y) != VALUE)
3418         return -1;
3419       /* Don't assert the modes are the same, that is true only
3420          when not recursing.  (subreg:QI (value:SI 1:1) 0)
3421          and (subreg:QI (value:DI 2:2) 0) can be compared,
3422          even when the modes are different.  */
3423       if (canon_value_cmp (x, y))
3424         return -1;
3425       else
3426         return 1;
3427     }
3428
3429   if (GET_CODE (y) == VALUE)
3430     return 1;
3431
3432   /* Entry value is the least preferable kind of expression.  */
3433   if (GET_CODE (x) == ENTRY_VALUE)
3434     {
3435       if (GET_CODE (y) != ENTRY_VALUE)
3436         return 1;
3437       gcc_assert (GET_MODE (x) == GET_MODE (y));
3438       return loc_cmp (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
3439     }
3440
3441   if (GET_CODE (y) == ENTRY_VALUE)
3442     return -1;
3443
3444   if (GET_CODE (x) == GET_CODE (y))
3445     /* Compare operands below.  */;
3446   else if (GET_CODE (x) < GET_CODE (y))
3447     return -1;
3448   else
3449     return 1;
3450
3451   gcc_assert (GET_MODE (x) == GET_MODE (y));
3452
3453   if (GET_CODE (x) == DEBUG_EXPR)
3454     {
3455       if (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x))
3456           < DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y)))
3457         return -1;
3458       gcc_checking_assert (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x))
3459                            > DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y)));
3460       return 1;
3461     }
3462
3463   fmt = GET_RTX_FORMAT (code);
3464   for (i = 0; i < GET_RTX_LENGTH (code); i++)
3465     switch (fmt[i])
3466       {
3467       case 'w':
3468         if (XWINT (x, i) == XWINT (y, i))
3469           break;
3470         else if (XWINT (x, i) < XWINT (y, i))
3471           return -1;
3472         else
3473           return 1;
3474
3475       case 'n':
3476       case 'i':
3477         if (XINT (x, i) == XINT (y, i))
3478           break;
3479         else if (XINT (x, i) < XINT (y, i))
3480           return -1;
3481         else
3482           return 1;
3483
3484       case 'V':
3485       case 'E':
3486         /* Compare the vector length first.  */
3487         if (XVECLEN (x, i) == XVECLEN (y, i))
3488           /* Compare the vectors elements.  */;
3489         else if (XVECLEN (x, i) < XVECLEN (y, i))
3490           return -1;
3491         else
3492           return 1;
3493
3494         for (j = 0; j < XVECLEN (x, i); j++)
3495           if ((r = loc_cmp (XVECEXP (x, i, j),
3496                             XVECEXP (y, i, j))))
3497             return r;
3498         break;
3499
3500       case 'e':
3501         if ((r = loc_cmp (XEXP (x, i), XEXP (y, i))))
3502           return r;
3503         break;
3504
3505       case 'S':
3506       case 's':
3507         if (XSTR (x, i) == XSTR (y, i))
3508           break;
3509         if (!XSTR (x, i))
3510           return -1;
3511         if (!XSTR (y, i))
3512           return 1;
3513         if ((r = strcmp (XSTR (x, i), XSTR (y, i))) == 0)
3514           break;
3515         else if (r < 0)
3516           return -1;
3517         else
3518           return 1;
3519
3520       case 'u':
3521         /* These are just backpointers, so they don't matter.  */
3522         break;
3523
3524       case '0':
3525       case 't':
3526         break;
3527
3528         /* It is believed that rtx's at this level will never
3529            contain anything but integers and other rtx's,
3530            except for within LABEL_REFs and SYMBOL_REFs.  */
3531       default:
3532         gcc_unreachable ();
3533       }
3534
3535   return 0;
3536 }
3537
3538 #if ENABLE_CHECKING
3539 /* Check the order of entries in one-part variables.   */
3540
3541 int
3542 canonicalize_loc_order_check (variable_def **slot,
3543                               dataflow_set *data ATTRIBUTE_UNUSED)
3544 {
3545   variable var = *slot;
3546   location_chain node, next;
3547
3548 #ifdef ENABLE_RTL_CHECKING
3549   int i;
3550   for (i = 0; i < var->n_var_parts; i++)
3551     gcc_assert (var->var_part[0].cur_loc == NULL);
3552   gcc_assert (!var->in_changed_variables);
3553 #endif
3554
3555   if (!var->onepart)
3556     return 1;
3557
3558   gcc_assert (var->n_var_parts == 1);
3559   node = var->var_part[0].loc_chain;
3560   gcc_assert (node);
3561
3562   while ((next = node->next))
3563     {
3564       gcc_assert (loc_cmp (node->loc, next->loc) < 0);
3565       node = next;
3566     }
3567
3568   return 1;
3569 }
3570 #endif
3571
3572 /* Mark with VALUE_RECURSED_INTO values that have neighbors that are
3573    more likely to be chosen as canonical for an equivalence set.
3574    Ensure less likely values can reach more likely neighbors, making
3575    the connections bidirectional.  */
3576
3577 int
3578 canonicalize_values_mark (variable_def **slot, dataflow_set *set)
3579 {
3580   variable var = *slot;
3581   decl_or_value dv = var->dv;
3582   rtx val;
3583   location_chain node;
3584
3585   if (!dv_is_value_p (dv))
3586     return 1;
3587
3588   gcc_checking_assert (var->n_var_parts == 1);
3589
3590   val = dv_as_value (dv);
3591
3592   for (node = var->var_part[0].loc_chain; node; node = node->next)
3593     if (GET_CODE (node->loc) == VALUE)
3594       {
3595         if (canon_value_cmp (node->loc, val))
3596           VALUE_RECURSED_INTO (val) = true;
3597         else
3598           {
3599             decl_or_value odv = dv_from_value (node->loc);
3600             variable_def **oslot;
3601             oslot = shared_hash_find_slot_noinsert (set->vars, odv);
3602
3603             set_slot_part (set, val, oslot, odv, 0,
3604                            node->init, NULL_RTX);
3605
3606             VALUE_RECURSED_INTO (node->loc) = true;
3607           }
3608       }
3609
3610   return 1;
3611 }
3612
3613 /* Remove redundant entries from equivalence lists in onepart
3614    variables, canonicalizing equivalence sets into star shapes.  */
3615
3616 int
3617 canonicalize_values_star (variable_def **slot, dataflow_set *set)
3618 {
3619   variable var = *slot;
3620   decl_or_value dv = var->dv;
3621   location_chain node;
3622   decl_or_value cdv;
3623   rtx val, cval;
3624   variable_def **cslot;
3625   bool has_value;
3626   bool has_marks;
3627
3628   if (!var->onepart)
3629     return 1;
3630
3631   gcc_checking_assert (var->n_var_parts == 1);
3632
3633   if (dv_is_value_p (dv))
3634     {
3635       cval = dv_as_value (dv);
3636       if (!VALUE_RECURSED_INTO (cval))
3637         return 1;
3638       VALUE_RECURSED_INTO (cval) = false;
3639     }
3640   else
3641     cval = NULL_RTX;
3642
3643  restart:
3644   val = cval;
3645   has_value = false;
3646   has_marks = false;
3647
3648   gcc_assert (var->n_var_parts == 1);
3649
3650   for (node = var->var_part[0].loc_chain; node; node = node->next)
3651     if (GET_CODE (node->loc) == VALUE)
3652       {
3653         has_value = true;
3654         if (VALUE_RECURSED_INTO (node->loc))
3655           has_marks = true;
3656         if (canon_value_cmp (node->loc, cval))
3657           cval = node->loc;
3658       }
3659
3660   if (!has_value)
3661     return 1;
3662
3663   if (cval == val)
3664     {
3665       if (!has_marks || dv_is_decl_p (dv))
3666         return 1;
3667
3668       /* Keep it marked so that we revisit it, either after visiting a
3669          child node, or after visiting a new parent that might be
3670          found out.  */
3671       VALUE_RECURSED_INTO (val) = true;
3672
3673       for (node = var->var_part[0].loc_chain; node; node = node->next)
3674         if (GET_CODE (node->loc) == VALUE
3675             && VALUE_RECURSED_INTO (node->loc))
3676           {
3677             cval = node->loc;
3678           restart_with_cval:
3679             VALUE_RECURSED_INTO (cval) = false;
3680             dv = dv_from_value (cval);
3681             slot = shared_hash_find_slot_noinsert (set->vars, dv);
3682             if (!slot)
3683               {
3684                 gcc_assert (dv_is_decl_p (var->dv));
3685                 /* The canonical value was reset and dropped.
3686                    Remove it.  */
3687                 clobber_variable_part (set, NULL, var->dv, 0, NULL);
3688                 return 1;
3689               }
3690             var = *slot;
3691             gcc_assert (dv_is_value_p (var->dv));
3692             if (var->n_var_parts == 0)
3693               return 1;
3694             gcc_assert (var->n_var_parts == 1);
3695             goto restart;
3696           }
3697
3698       VALUE_RECURSED_INTO (val) = false;
3699
3700       return 1;
3701     }
3702
3703   /* Push values to the canonical one.  */
3704   cdv = dv_from_value (cval);
3705   cslot = shared_hash_find_slot_noinsert (set->vars, cdv);
3706
3707   for (node = var->var_part[0].loc_chain; node; node = node->next)
3708     if (node->loc != cval)
3709       {
3710         cslot = set_slot_part (set, node->loc, cslot, cdv, 0,
3711                                node->init, NULL_RTX);
3712         if (GET_CODE (node->loc) == VALUE)
3713           {
3714             decl_or_value ndv = dv_from_value (node->loc);
3715
3716             set_variable_part (set, cval, ndv, 0, node->init, NULL_RTX,
3717                                NO_INSERT);
3718
3719             if (canon_value_cmp (node->loc, val))
3720               {
3721                 /* If it could have been a local minimum, it's not any more,
3722                    since it's now neighbor to cval, so it may have to push
3723                    to it.  Conversely, if it wouldn't have prevailed over
3724                    val, then whatever mark it has is fine: if it was to
3725                    push, it will now push to a more canonical node, but if
3726                    it wasn't, then it has already pushed any values it might
3727                    have to.  */
3728                 VALUE_RECURSED_INTO (node->loc) = true;
3729                 /* Make sure we visit node->loc by ensuring we cval is
3730                    visited too.  */
3731                 VALUE_RECURSED_INTO (cval) = true;
3732               }
3733             else if (!VALUE_RECURSED_INTO (node->loc))
3734               /* If we have no need to "recurse" into this node, it's
3735                  already "canonicalized", so drop the link to the old
3736                  parent.  */
3737               clobber_variable_part (set, cval, ndv, 0, NULL);
3738           }
3739         else if (GET_CODE (node->loc) == REG)
3740           {
3741             attrs list = set->regs[REGNO (node->loc)], *listp;
3742
3743             /* Change an existing attribute referring to dv so that it
3744                refers to cdv, removing any duplicate this might
3745                introduce, and checking that no previous duplicates
3746                existed, all in a single pass.  */
3747
3748             while (list)
3749               {
3750                 if (list->offset == 0
3751                     && (dv_as_opaque (list->dv) == dv_as_opaque (dv)
3752                         || dv_as_opaque (list->dv) == dv_as_opaque (cdv)))
3753                   break;
3754
3755                 list = list->next;
3756               }
3757
3758             gcc_assert (list);
3759             if (dv_as_opaque (list->dv) == dv_as_opaque (dv))
3760               {
3761                 list->dv = cdv;
3762                 for (listp = &list->next; (list = *listp); listp = &list->next)
3763                   {
3764                     if (list->offset)
3765                       continue;
3766
3767                     if (dv_as_opaque (list->dv) == dv_as_opaque (cdv))
3768                       {
3769                         *listp = list->next;
3770                         pool_free (attrs_pool, list);
3771                         list = *listp;
3772                         break;
3773                       }
3774
3775                     gcc_assert (dv_as_opaque (list->dv) != dv_as_opaque (dv));
3776                   }
3777               }
3778             else if (dv_as_opaque (list->dv) == dv_as_opaque (cdv))
3779               {
3780                 for (listp = &list->next; (list = *listp); listp = &list->next)
3781                   {
3782                     if (list->offset)
3783                       continue;
3784
3785                     if (dv_as_opaque (list->dv) == dv_as_opaque (dv))
3786                       {
3787                         *listp = list->next;
3788                         pool_free (attrs_pool, list);
3789                         list = *listp;
3790                         break;
3791                       }
3792
3793                     gcc_assert (dv_as_opaque (list->dv) != dv_as_opaque (cdv));
3794                   }
3795               }
3796             else
3797               gcc_unreachable ();
3798
3799 #if ENABLE_CHECKING
3800             while (list)
3801               {
3802                 if (list->offset == 0
3803                     && (dv_as_opaque (list->dv) == dv_as_opaque (dv)
3804                         || dv_as_opaque (list->dv) == dv_as_opaque (cdv)))
3805                   gcc_unreachable ();
3806
3807                 list = list->next;
3808               }
3809 #endif
3810           }
3811       }
3812
3813   if (val)
3814     set_slot_part (set, val, cslot, cdv, 0,
3815                    VAR_INIT_STATUS_INITIALIZED, NULL_RTX);
3816
3817   slot = clobber_slot_part (set, cval, slot, 0, NULL);
3818
3819   /* Variable may have been unshared.  */
3820   var = *slot;
3821   gcc_checking_assert (var->n_var_parts && var->var_part[0].loc_chain->loc == cval
3822                        && var->var_part[0].loc_chain->next == NULL);
3823
3824   if (VALUE_RECURSED_INTO (cval))
3825     goto restart_with_cval;
3826
3827   return 1;
3828 }
3829
3830 /* Bind one-part variables to the canonical value in an equivalence
3831    set.  Not doing this causes dataflow convergence failure in rare
3832    circumstances, see PR42873.  Unfortunately we can't do this
3833    efficiently as part of canonicalize_values_star, since we may not
3834    have determined or even seen the canonical value of a set when we
3835    get to a variable that references another member of the set.  */
3836
3837 int
3838 canonicalize_vars_star (variable_def **slot, dataflow_set *set)
3839 {
3840   variable var = *slot;
3841   decl_or_value dv = var->dv;
3842   location_chain node;
3843   rtx cval;
3844   decl_or_value cdv;
3845   variable_def **cslot;
3846   variable cvar;
3847   location_chain cnode;
3848
3849   if (!var->onepart || var->onepart == ONEPART_VALUE)
3850     return 1;
3851
3852   gcc_assert (var->n_var_parts == 1);
3853
3854   node = var->var_part[0].loc_chain;
3855
3856   if (GET_CODE (node->loc) != VALUE)
3857     return 1;
3858
3859   gcc_assert (!node->next);
3860   cval = node->loc;
3861
3862   /* Push values to the canonical one.  */
3863   cdv = dv_from_value (cval);
3864   cslot = shared_hash_find_slot_noinsert (set->vars, cdv);
3865   if (!cslot)
3866     return 1;
3867   cvar = *cslot;
3868   gcc_assert (cvar->n_var_parts == 1);
3869
3870   cnode = cvar->var_part[0].loc_chain;
3871
3872   /* CVAL is canonical if its value list contains non-VALUEs or VALUEs
3873      that are not “more canonical” than it.  */
3874   if (GET_CODE (cnode->loc) != VALUE
3875       || !canon_value_cmp (cnode->loc, cval))
3876     return 1;
3877
3878   /* CVAL was found to be non-canonical.  Change the variable to point
3879      to the canonical VALUE.  */
3880   gcc_assert (!cnode->next);
3881   cval = cnode->loc;
3882
3883   slot = set_slot_part (set, cval, slot, dv, 0,
3884                         node->init, node->set_src);
3885   clobber_slot_part (set, cval, slot, 0, node->set_src);
3886
3887   return 1;
3888 }
3889
3890 /* Combine variable or value in *S1SLOT (in DSM->cur) with the
3891    corresponding entry in DSM->src.  Multi-part variables are combined
3892    with variable_union, whereas onepart dvs are combined with
3893    intersection.  */
3894
3895 static int
3896 variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
3897 {
3898   dataflow_set *dst = dsm->dst;
3899   variable_def **dstslot;
3900   variable s2var, dvar = NULL;
3901   decl_or_value dv = s1var->dv;
3902   onepart_enum_t onepart = s1var->onepart;
3903   rtx val;
3904   hashval_t dvhash;
3905   location_chain node, *nodep;
3906
3907   /* If the incoming onepart variable has an empty location list, then
3908      the intersection will be just as empty.  For other variables,
3909      it's always union.  */
3910   gcc_checking_assert (s1var->n_var_parts
3911                        && s1var->var_part[0].loc_chain);
3912
3913   if (!onepart)
3914     return variable_union (s1var, dst);
3915
3916   gcc_checking_assert (s1var->n_var_parts == 1);
3917
3918   dvhash = dv_htab_hash (dv);
3919   if (dv_is_value_p (dv))
3920     val = dv_as_value (dv);
3921   else
3922     val = NULL;
3923
3924   s2var = shared_hash_find_1 (dsm->src->vars, dv, dvhash);
3925   if (!s2var)
3926     {
3927       dst_can_be_shared = false;
3928       return 1;
3929     }
3930
3931   dsm->src_onepart_cnt--;
3932   gcc_assert (s2var->var_part[0].loc_chain
3933               && s2var->onepart == onepart
3934               && s2var->n_var_parts == 1);
3935
3936   dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3937   if (dstslot)
3938     {
3939       dvar = *dstslot;
3940       gcc_assert (dvar->refcount == 1
3941                   && dvar->onepart == onepart
3942                   && dvar->n_var_parts == 1);
3943       nodep = &dvar->var_part[0].loc_chain;
3944     }
3945   else
3946     {
3947       nodep = &node;
3948       node = NULL;
3949     }
3950
3951   if (!dstslot && !onepart_variable_different_p (s1var, s2var))
3952     {
3953       dstslot = shared_hash_find_slot_unshare_1 (&dst->vars, dv,
3954                                                  dvhash, INSERT);
3955       *dstslot = dvar = s2var;
3956       dvar->refcount++;
3957     }
3958   else
3959     {
3960       dst_can_be_shared = false;
3961
3962       intersect_loc_chains (val, nodep, dsm,
3963                             s1var->var_part[0].loc_chain, s2var);
3964
3965       if (!dstslot)
3966         {
3967           if (node)
3968             {
3969               dvar = (variable) pool_alloc (onepart_pool (onepart));
3970               dvar->dv = dv;
3971               dvar->refcount = 1;
3972               dvar->n_var_parts = 1;
3973               dvar->onepart = onepart;
3974               dvar->in_changed_variables = false;
3975               dvar->var_part[0].loc_chain = node;
3976               dvar->var_part[0].cur_loc = NULL;
3977               if (onepart)
3978                 VAR_LOC_1PAUX (dvar) = NULL;
3979               else
3980                 VAR_PART_OFFSET (dvar, 0) = 0;
3981
3982               dstslot
3983                 = shared_hash_find_slot_unshare_1 (&dst->vars, dv, dvhash,
3984                                                    INSERT);
3985               gcc_assert (!*dstslot);
3986               *dstslot = dvar;
3987             }
3988           else
3989             return 1;
3990         }
3991     }
3992
3993   nodep = &dvar->var_part[0].loc_chain;
3994   while ((node = *nodep))
3995     {
3996       location_chain *nextp = &node->next;
3997
3998       if (GET_CODE (node->loc) == REG)
3999         {
4000           attrs list;
4001
4002           for (list = dst->regs[REGNO (node->loc)]; list; list = list->next)
4003             if (GET_MODE (node->loc) == GET_MODE (list->loc)
4004                 && dv_is_value_p (list->dv))
4005               break;
4006
4007           if (!list)
4008             attrs_list_insert (&dst->regs[REGNO (node->loc)],
4009                                dv, 0, node->loc);
4010           /* If this value became canonical for another value that had
4011              this register, we want to leave it alone.  */
4012           else if (dv_as_value (list->dv) != val)
4013             {
4014               dstslot = set_slot_part (dst, dv_as_value (list->dv),
4015                                        dstslot, dv, 0,
4016                                        node->init, NULL_RTX);
4017               dstslot = delete_slot_part (dst, node->loc, dstslot, 0);
4018
4019               /* Since nextp points into the removed node, we can't
4020                  use it.  The pointer to the next node moved to nodep.
4021                  However, if the variable we're walking is unshared
4022                  during our walk, we'll keep walking the location list
4023                  of the previously-shared variable, in which case the
4024                  node won't have been removed, and we'll want to skip
4025                  it.  That's why we test *nodep here.  */
4026               if (*nodep != node)
4027                 nextp = nodep;
4028             }
4029         }
4030       else
4031         /* Canonicalization puts registers first, so we don't have to
4032            walk it all.  */
4033         break;
4034       nodep = nextp;
4035     }
4036
4037   if (dvar != *dstslot)
4038     dvar = *dstslot;
4039   nodep = &dvar->var_part[0].loc_chain;
4040
4041   if (val)
4042     {
4043       /* Mark all referenced nodes for canonicalization, and make sure
4044          we have mutual equivalence links.  */
4045       VALUE_RECURSED_INTO (val) = true;
4046       for (node = *nodep; node; node = node->next)
4047         if (GET_CODE (node->loc) == VALUE)
4048           {
4049             VALUE_RECURSED_INTO (node->loc) = true;
4050             set_variable_part (dst, val, dv_from_value (node->loc), 0,
4051                                node->init, NULL, INSERT);
4052           }
4053
4054       dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
4055       gcc_assert (*dstslot == dvar);
4056       canonicalize_values_star (dstslot, dst);
4057       gcc_checking_assert (dstslot
4058                            == shared_hash_find_slot_noinsert_1 (dst->vars,
4059                                                                 dv, dvhash));
4060       dvar = *dstslot;
4061     }
4062   else
4063     {
4064       bool has_value = false, has_other = false;
4065
4066       /* If we have one value and anything else, we're going to
4067          canonicalize this, so make sure all values have an entry in
4068          the table and are marked for canonicalization.  */
4069       for (node = *nodep; node; node = node->next)
4070         {
4071           if (GET_CODE (node->loc) == VALUE)
4072             {
4073               /* If this was marked during register canonicalization,
4074                  we know we have to canonicalize values.  */
4075               if (has_value)
4076                 has_other = true;
4077               has_value = true;
4078               if (has_other)
4079                 break;
4080             }
4081           else
4082             {
4083               has_other = true;
4084               if (has_value)
4085                 break;
4086             }
4087         }
4088
4089       if (has_value && has_other)
4090         {
4091           for (node = *nodep; node; node = node->next)
4092             {
4093               if (GET_CODE (node->loc) == VALUE)
4094                 {
4095                   decl_or_value dv = dv_from_value (node->loc);
4096                   variable_def **slot = NULL;
4097
4098                   if (shared_hash_shared (dst->vars))
4099                     slot = shared_hash_find_slot_noinsert (dst->vars, dv);
4100                   if (!slot)
4101                     slot = shared_hash_find_slot_unshare (&dst->vars, dv,
4102                                                           INSERT);
4103                   if (!*slot)
4104                     {
4105                       variable var = (variable) pool_alloc (onepart_pool
4106                                                             (ONEPART_VALUE));
4107                       var->dv = dv;
4108                       var->refcount = 1;
4109                       var->n_var_parts = 1;
4110                       var->onepart = ONEPART_VALUE;
4111                       var->in_changed_variables = false;
4112                       var->var_part[0].loc_chain = NULL;
4113                       var->var_part[0].cur_loc = NULL;
4114                       VAR_LOC_1PAUX (var) = NULL;
4115                       *slot = var;
4116                     }
4117
4118                   VALUE_RECURSED_INTO (node->loc) = true;
4119                 }
4120             }
4121
4122           dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
4123           gcc_assert (*dstslot == dvar);
4124           canonicalize_values_star (dstslot, dst);
4125           gcc_checking_assert (dstslot
4126                                == shared_hash_find_slot_noinsert_1 (dst->vars,
4127                                                                     dv, dvhash));
4128           dvar = *dstslot;
4129         }
4130     }
4131
4132   if (!onepart_variable_different_p (dvar, s2var))
4133     {
4134       variable_htab_free (dvar);
4135       *dstslot = dvar = s2var;
4136       dvar->refcount++;
4137     }
4138   else if (s2var != s1var && !onepart_variable_different_p (dvar, s1var))
4139     {
4140       variable_htab_free (dvar);
4141       *dstslot = dvar = s1var;
4142       dvar->refcount++;
4143       dst_can_be_shared = false;
4144     }
4145   else
4146     dst_can_be_shared = false;
4147
4148   return 1;
4149 }
4150
4151 /* Copy s2slot (in DSM->src) to DSM->dst if the variable is a
4152    multi-part variable.  Unions of multi-part variables and
4153    intersections of one-part ones will be handled in
4154    variable_merge_over_cur().  */
4155
4156 static int
4157 variable_merge_over_src (variable s2var, struct dfset_merge *dsm)
4158 {
4159   dataflow_set *dst = dsm->dst;
4160   decl_or_value dv = s2var->dv;
4161
4162   if (!s2var->onepart)
4163     {
4164       variable_def **dstp = shared_hash_find_slot (dst->vars, dv);
4165       *dstp = s2var;
4166       s2var->refcount++;
4167       return 1;
4168     }
4169
4170   dsm->src_onepart_cnt++;
4171   return 1;
4172 }
4173
4174 /* Combine dataflow set information from SRC2 into DST, using PDST
4175    to carry over information across passes.  */
4176
4177 static void
4178 dataflow_set_merge (dataflow_set *dst, dataflow_set *src2)
4179 {
4180   dataflow_set cur = *dst;
4181   dataflow_set *src1 = &cur;
4182   struct dfset_merge dsm;
4183   int i;
4184   size_t src1_elems, src2_elems;
4185   variable_iterator_type hi;
4186   variable var;
4187
4188   src1_elems = shared_hash_htab (src1->vars).elements ();
4189   src2_elems = shared_hash_htab (src2->vars).elements ();
4190   dataflow_set_init (dst);
4191   dst->stack_adjust = cur.stack_adjust;
4192   shared_hash_destroy (dst->vars);
4193   dst->vars = (shared_hash) pool_alloc (shared_hash_pool);
4194   dst->vars->refcount = 1;
4195   dst->vars->htab.create (MAX (src1_elems, src2_elems));
4196
4197   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4198     attrs_list_mpdv_union (&dst->regs[i], src1->regs[i], src2->regs[i]);
4199
4200   dsm.dst = dst;
4201   dsm.src = src2;
4202   dsm.cur = src1;
4203   dsm.src_onepart_cnt = 0;
4204
4205   FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (dsm.src->vars),
4206                                var, variable, hi)
4207     variable_merge_over_src (var, &dsm);
4208   FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (dsm.cur->vars),
4209                                var, variable, hi)
4210     variable_merge_over_cur (var, &dsm);
4211
4212   if (dsm.src_onepart_cnt)
4213     dst_can_be_shared = false;
4214
4215   dataflow_set_destroy (src1);
4216 }
4217
4218 /* Mark register equivalences.  */
4219
4220 static void
4221 dataflow_set_equiv_regs (dataflow_set *set)
4222 {
4223   int i;
4224   attrs list, *listp;
4225
4226   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4227     {
4228       rtx canon[NUM_MACHINE_MODES];
4229
4230       /* If the list is empty or one entry, no need to canonicalize
4231          anything.  */
4232       if (set->regs[i] == NULL || set->regs[i]->next == NULL)
4233         continue;
4234
4235       memset (canon, 0, sizeof (canon));
4236
4237       for (list = set->regs[i]; list; list = list->next)
4238         if (list->offset == 0 && dv_is_value_p (list->dv))
4239           {
4240             rtx val = dv_as_value (list->dv);
4241             rtx *cvalp = &canon[(int)GET_MODE (val)];
4242             rtx cval = *cvalp;
4243
4244             if (canon_value_cmp (val, cval))
4245               *cvalp = val;
4246           }
4247
4248       for (list = set->regs[i]; list; list = list->next)
4249         if (list->offset == 0 && dv_onepart_p (list->dv))
4250           {
4251             rtx cval = canon[(int)GET_MODE (list->loc)];
4252
4253             if (!cval)
4254               continue;
4255
4256             if (dv_is_value_p (list->dv))
4257               {
4258                 rtx val = dv_as_value (list->dv);
4259
4260                 if (val == cval)
4261                   continue;
4262
4263                 VALUE_RECURSED_INTO (val) = true;
4264                 set_variable_part (set, val, dv_from_value (cval), 0,
4265                                    VAR_INIT_STATUS_INITIALIZED,
4266                                    NULL, NO_INSERT);
4267               }
4268
4269             VALUE_RECURSED_INTO (cval) = true;
4270             set_variable_part (set, cval, list->dv, 0,
4271                                VAR_INIT_STATUS_INITIALIZED, NULL, NO_INSERT);
4272           }
4273
4274       for (listp = &set->regs[i]; (list = *listp);
4275            listp = list ? &list->next : listp)
4276         if (list->offset == 0 && dv_onepart_p (list->dv))
4277           {
4278             rtx cval = canon[(int)GET_MODE (list->loc)];
4279             variable_def **slot;
4280
4281             if (!cval)
4282               continue;
4283
4284             if (dv_is_value_p (list->dv))
4285               {
4286                 rtx val = dv_as_value (list->dv);
4287                 if (!VALUE_RECURSED_INTO (val))
4288                   continue;
4289               }
4290
4291             slot = shared_hash_find_slot_noinsert (set->vars, list->dv);
4292             canonicalize_values_star (slot, set);
4293             if (*listp != list)
4294               list = NULL;
4295           }
4296     }
4297 }
4298
4299 /* Remove any redundant values in the location list of VAR, which must
4300    be unshared and 1-part.  */
4301
4302 static void
4303 remove_duplicate_values (variable var)
4304 {
4305   location_chain node, *nodep;
4306
4307   gcc_assert (var->onepart);
4308   gcc_assert (var->n_var_parts == 1);
4309   gcc_assert (var->refcount == 1);
4310
4311   for (nodep = &var->var_part[0].loc_chain; (node = *nodep); )
4312     {
4313       if (GET_CODE (node->loc) == VALUE)
4314         {
4315           if (VALUE_RECURSED_INTO (node->loc))
4316             {
4317               /* Remove duplicate value node.  */
4318               *nodep = node->next;
4319               pool_free (loc_chain_pool, node);
4320               continue;
4321             }
4322           else
4323             VALUE_RECURSED_INTO (node->loc) = true;
4324         }
4325       nodep = &node->next;
4326     }
4327
4328   for (node = var->var_part[0].loc_chain; node; node = node->next)
4329     if (GET_CODE (node->loc) == VALUE)
4330       {
4331         gcc_assert (VALUE_RECURSED_INTO (node->loc));
4332         VALUE_RECURSED_INTO (node->loc) = false;
4333       }
4334 }
4335
4336
4337 /* Hash table iteration argument passed to variable_post_merge.  */
4338 struct dfset_post_merge
4339 {
4340   /* The new input set for the current block.  */
4341   dataflow_set *set;
4342   /* Pointer to the permanent input set for the current block, or
4343      NULL.  */
4344   dataflow_set **permp;
4345 };
4346
4347 /* Create values for incoming expressions associated with one-part
4348    variables that don't have value numbers for them.  */
4349
4350 int
4351 variable_post_merge_new_vals (variable_def **slot, dfset_post_merge *dfpm)
4352 {
4353   dataflow_set *set = dfpm->set;
4354   variable var = *slot;
4355   location_chain node;
4356
4357   if (!var->onepart || !var->n_var_parts)
4358     return 1;
4359
4360   gcc_assert (var->n_var_parts == 1);
4361
4362   if (dv_is_decl_p (var->dv))
4363     {
4364       bool check_dupes = false;
4365
4366     restart:
4367       for (node = var->var_part[0].loc_chain; node; node = node->next)
4368         {
4369           if (GET_CODE (node->loc) == VALUE)
4370             gcc_assert (!VALUE_RECURSED_INTO (node->loc));
4371           else if (GET_CODE (node->loc) == REG)
4372             {
4373               attrs att, *attp, *curp = NULL;
4374
4375               if (var->refcount != 1)
4376                 {
4377                   slot = unshare_variable (set, slot, var,
4378                                            VAR_INIT_STATUS_INITIALIZED);
4379                   var = *slot;
4380                   goto restart;
4381                 }
4382
4383               for (attp = &set->regs[REGNO (node->loc)]; (att = *attp);
4384                    attp = &att->next)
4385                 if (att->offset == 0
4386                     && GET_MODE (att->loc) == GET_MODE (node->loc))
4387                   {
4388                     if (dv_is_value_p (att->dv))
4389                       {
4390                         rtx cval = dv_as_value (att->dv);
4391                         node->loc = cval;
4392                         check_dupes = true;
4393                         break;
4394                       }
4395                     else if (dv_as_opaque (att->dv) == dv_as_opaque (var->dv))
4396                       curp = attp;
4397                   }
4398
4399               if (!curp)
4400                 {
4401                   curp = attp;
4402                   while (*curp)
4403                     if ((*curp)->offset == 0
4404                         && GET_MODE ((*curp)->loc) == GET_MODE (node->loc)
4405                         && dv_as_opaque ((*curp)->dv) == dv_as_opaque (var->dv))
4406                       break;
4407                     else
4408                       curp = &(*curp)->next;
4409                   gcc_assert (*curp);
4410                 }
4411
4412               if (!att)
4413                 {
4414                   decl_or_value cdv;
4415                   rtx cval;
4416
4417                   if (!*dfpm->permp)
4418                     {
4419                       *dfpm->permp = XNEW (dataflow_set);
4420                       dataflow_set_init (*dfpm->permp);
4421                     }
4422
4423                   for (att = (*dfpm->permp)->regs[REGNO (node->loc)];
4424                        att; att = att->next)
4425                     if (GET_MODE (att->loc) == GET_MODE (node->loc))
4426                       {
4427                         gcc_assert (att->offset == 0
4428                                     && dv_is_value_p (att->dv));
4429                         val_reset (set, att->dv);
4430                         break;
4431                       }
4432
4433                   if (att)
4434                     {
4435                       cdv = att->dv;
4436                       cval = dv_as_value (cdv);
4437                     }
4438                   else
4439                     {
4440                       /* Create a unique value to hold this register,
4441                          that ought to be found and reused in
4442                          subsequent rounds.  */
4443                       cselib_val *v;
4444                       gcc_assert (!cselib_lookup (node->loc,
4445                                                   GET_MODE (node->loc), 0,
4446                                                   VOIDmode));
4447                       v = cselib_lookup (node->loc, GET_MODE (node->loc), 1,
4448                                          VOIDmode);
4449                       cselib_preserve_value (v);
4450                       cselib_invalidate_rtx (node->loc);
4451                       cval = v->val_rtx;
4452                       cdv = dv_from_value (cval);
4453                       if (dump_file)
4454                         fprintf (dump_file,
4455                                  "Created new value %u:%u for reg %i\n",
4456                                  v->uid, v->hash, REGNO (node->loc));
4457                     }
4458
4459                   var_reg_decl_set (*dfpm->permp, node->loc,
4460                                     VAR_INIT_STATUS_INITIALIZED,
4461                                     cdv, 0, NULL, INSERT);
4462
4463                   node->loc = cval;
4464                   check_dupes = true;
4465                 }
4466
4467               /* Remove attribute referring to the decl, which now
4468                  uses the value for the register, already existing or
4469                  to be added when we bring perm in.  */
4470               att = *curp;
4471               *curp = att->next;
4472               pool_free (attrs_pool, att);
4473             }
4474         }
4475
4476       if (check_dupes)
4477         remove_duplicate_values (var);
4478     }
4479
4480   return 1;
4481 }
4482
4483 /* Reset values in the permanent set that are not associated with the
4484    chosen expression.  */
4485
4486 int
4487 variable_post_merge_perm_vals (variable_def **pslot, dfset_post_merge *dfpm)
4488 {
4489   dataflow_set *set = dfpm->set;
4490   variable pvar = *pslot, var;
4491   location_chain pnode;
4492   decl_or_value dv;
4493   attrs att;
4494
4495   gcc_assert (dv_is_value_p (pvar->dv)
4496               && pvar->n_var_parts == 1);
4497   pnode = pvar->var_part[0].loc_chain;
4498   gcc_assert (pnode
4499               && !pnode->next
4500               && REG_P (pnode->loc));
4501
4502   dv = pvar->dv;
4503
4504   var = shared_hash_find (set->vars, dv);
4505   if (var)
4506     {
4507       /* Although variable_post_merge_new_vals may have made decls
4508          non-star-canonical, values that pre-existed in canonical form
4509          remain canonical, and newly-created values reference a single
4510          REG, so they are canonical as well.  Since VAR has the
4511          location list for a VALUE, using find_loc_in_1pdv for it is
4512          fine, since VALUEs don't map back to DECLs.  */
4513       if (find_loc_in_1pdv (pnode->loc, var, shared_hash_htab (set->vars)))
4514         return 1;
4515       val_reset (set, dv);
4516     }
4517
4518   for (att = set->regs[REGNO (pnode->loc)]; att; att = att->next)
4519     if (att->offset == 0
4520         && GET_MODE (att->loc) == GET_MODE (pnode->loc)
4521         && dv_is_value_p (att->dv))
4522       break;
4523
4524   /* If there is a value associated with this register already, create
4525      an equivalence.  */
4526   if (att && dv_as_value (att->dv) != dv_as_value (dv))
4527     {
4528       rtx cval = dv_as_value (att->dv);
4529       set_variable_part (set, cval, dv, 0, pnode->init, NULL, INSERT);
4530       set_variable_part (set, dv_as_value (dv), att->dv, 0, pnode->init,
4531                          NULL, INSERT);
4532     }
4533   else if (!att)
4534     {
4535       attrs_list_insert (&set->regs[REGNO (pnode->loc)],
4536                          dv, 0, pnode->loc);
4537       variable_union (pvar, set);
4538     }
4539
4540   return 1;
4541 }
4542
4543 /* Just checking stuff and registering register attributes for
4544    now.  */
4545
4546 static void
4547 dataflow_post_merge_adjust (dataflow_set *set, dataflow_set **permp)
4548 {
4549   struct dfset_post_merge dfpm;
4550
4551   dfpm.set = set;
4552   dfpm.permp = permp;
4553
4554   shared_hash_htab (set->vars)
4555     .traverse <dfset_post_merge*, variable_post_merge_new_vals> (&dfpm);
4556   if (*permp)
4557     shared_hash_htab ((*permp)->vars)
4558       .traverse <dfset_post_merge*, variable_post_merge_perm_vals> (&dfpm);
4559   shared_hash_htab (set->vars)
4560     .traverse <dataflow_set *, canonicalize_values_star> (set);
4561   shared_hash_htab (set->vars)
4562     .traverse <dataflow_set *, canonicalize_vars_star> (set);
4563 }
4564
4565 /* Return a node whose loc is a MEM that refers to EXPR in the
4566    location list of a one-part variable or value VAR, or in that of
4567    any values recursively mentioned in the location lists.  */
4568
4569 static location_chain
4570 find_mem_expr_in_1pdv (tree expr, rtx val, variable_table_type vars)
4571 {
4572   location_chain node;
4573   decl_or_value dv;
4574   variable var;
4575   location_chain where = NULL;
4576
4577   if (!val)
4578     return NULL;
4579
4580   gcc_assert (GET_CODE (val) == VALUE
4581               && !VALUE_RECURSED_INTO (val));
4582
4583   dv = dv_from_value (val);
4584   var = vars.find_with_hash (dv, dv_htab_hash (dv));
4585
4586   if (!var)
4587     return NULL;
4588
4589   gcc_assert (var->onepart);
4590
4591   if (!var->n_var_parts)
4592     return NULL;
4593
4594   VALUE_RECURSED_INTO (val) = true;
4595
4596   for (node = var->var_part[0].loc_chain; node; node = node->next)
4597     if (MEM_P (node->loc)
4598         && MEM_EXPR (node->loc) == expr
4599         && INT_MEM_OFFSET (node->loc) == 0)
4600       {
4601         where = node;
4602         break;
4603       }
4604     else if (GET_CODE (node->loc) == VALUE
4605              && !VALUE_RECURSED_INTO (node->loc)
4606              && (where = find_mem_expr_in_1pdv (expr, node->loc, vars)))
4607       break;
4608
4609   VALUE_RECURSED_INTO (val) = false;
4610
4611   return where;
4612 }
4613
4614 /* Return TRUE if the value of MEM may vary across a call.  */
4615
4616 static bool
4617 mem_dies_at_call (rtx mem)
4618 {
4619   tree expr = MEM_EXPR (mem);
4620   tree decl;
4621
4622   if (!expr)
4623     return true;
4624
4625   decl = get_base_address (expr);
4626
4627   if (!decl)
4628     return true;
4629
4630   if (!DECL_P (decl))
4631     return true;
4632
4633   return (may_be_aliased (decl)
4634           || (!TREE_READONLY (decl) && is_global_var (decl)));
4635 }
4636
4637 /* Remove all MEMs from the location list of a hash table entry for a
4638    one-part variable, except those whose MEM attributes map back to
4639    the variable itself, directly or within a VALUE.  */
4640
4641 int
4642 dataflow_set_preserve_mem_locs (variable_def **slot, dataflow_set *set)
4643 {
4644   variable var = *slot;
4645
4646   if (var->onepart == ONEPART_VDECL || var->onepart == ONEPART_DEXPR)
4647     {
4648       tree decl = dv_as_decl (var->dv);
4649       location_chain loc, *locp;
4650       bool changed = false;
4651
4652       if (!var->n_var_parts)
4653         return 1;
4654
4655       gcc_assert (var->n_var_parts == 1);
4656
4657       if (shared_var_p (var, set->vars))
4658         {
4659           for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
4660             {
4661               /* We want to remove dying MEMs that doesn't refer to DECL.  */
4662               if (GET_CODE (loc->loc) == MEM
4663                   && (MEM_EXPR (loc->loc) != decl
4664                       || INT_MEM_OFFSET (loc->loc) != 0)
4665                   && !mem_dies_at_call (loc->loc))
4666                 break;
4667               /* We want to move here MEMs that do refer to DECL.  */
4668               else if (GET_CODE (loc->loc) == VALUE
4669                        && find_mem_expr_in_1pdv (decl, loc->loc,
4670                                                  shared_hash_htab (set->vars)))
4671                 break;
4672             }
4673
4674           if (!loc)
4675             return 1;
4676
4677           slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
4678           var = *slot;
4679           gcc_assert (var->n_var_parts == 1);
4680         }
4681
4682       for (locp = &var->var_part[0].loc_chain, loc = *locp;
4683            loc; loc = *locp)
4684         {
4685           rtx old_loc = loc->loc;
4686           if (GET_CODE (old_loc) == VALUE)
4687             {
4688               location_chain mem_node
4689                 = find_mem_expr_in_1pdv (decl, loc->loc,
4690                                          shared_hash_htab (set->vars));
4691
4692               /* ??? This picks up only one out of multiple MEMs that
4693                  refer to the same variable.  Do we ever need to be
4694                  concerned about dealing with more than one, or, given
4695                  that they should all map to the same variable
4696                  location, their addresses will have been merged and
4697                  they will be regarded as equivalent?  */
4698               if (mem_node)
4699                 {
4700                   loc->loc = mem_node->loc;
4701                   loc->set_src = mem_node->set_src;
4702                   loc->init = MIN (loc->init, mem_node->init);
4703                 }
4704             }
4705
4706           if (GET_CODE (loc->loc) != MEM
4707               || (MEM_EXPR (loc->loc) == decl
4708                   && INT_MEM_OFFSET (loc->loc) == 0)
4709               || !mem_dies_at_call (loc->loc))
4710             {
4711               if (old_loc != loc->loc && emit_notes)
4712                 {
4713                   if (old_loc == var->var_part[0].cur_loc)
4714                     {
4715                       changed = true;
4716                       var->var_part[0].cur_loc = NULL;
4717                     }
4718                 }
4719               locp = &loc->next;
4720               continue;
4721             }
4722
4723           if (emit_notes)
4724             {
4725               if (old_loc == var->var_part[0].cur_loc)
4726                 {
4727                   changed = true;
4728                   var->var_part[0].cur_loc = NULL;
4729                 }
4730             }
4731           *locp = loc->next;
4732           pool_free (loc_chain_pool, loc);
4733         }
4734
4735       if (!var->var_part[0].loc_chain)
4736         {
4737           var->n_var_parts--;
4738           changed = true;
4739         }
4740       if (changed)
4741         variable_was_changed (var, set);
4742     }
4743
4744   return 1;
4745 }
4746
4747 /* Remove all MEMs from the location list of a hash table entry for a
4748    value.  */
4749
4750 int
4751 dataflow_set_remove_mem_locs (variable_def **slot, dataflow_set *set)
4752 {
4753   variable var = *slot;
4754
4755   if (var->onepart == ONEPART_VALUE)
4756     {
4757       location_chain loc, *locp;
4758       bool changed = false;
4759       rtx cur_loc;
4760
4761       gcc_assert (var->n_var_parts == 1);
4762
4763       if (shared_var_p (var, set->vars))
4764         {
4765           for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
4766             if (GET_CODE (loc->loc) == MEM
4767                 && mem_dies_at_call (loc->loc))
4768               break;
4769
4770           if (!loc)
4771             return 1;
4772
4773           slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
4774           var = *slot;
4775           gcc_assert (var->n_var_parts == 1);
4776         }
4777
4778       if (VAR_LOC_1PAUX (var))
4779         cur_loc = VAR_LOC_FROM (var);
4780       else
4781         cur_loc = var->var_part[0].cur_loc;
4782
4783       for (locp = &var->var_part[0].loc_chain, loc = *locp;
4784            loc; loc = *locp)
4785         {
4786           if (GET_CODE (loc->loc) != MEM
4787               || !mem_dies_at_call (loc->loc))
4788             {
4789               locp = &loc->next;
4790               continue;
4791             }
4792
4793           *locp = loc->next;
4794           /* If we have deleted the location which was last emitted
4795              we have to emit new location so add the variable to set
4796              of changed variables.  */
4797           if (cur_loc == loc->loc)
4798             {
4799               changed = true;
4800               var->var_part[0].cur_loc = NULL;
4801               if (VAR_LOC_1PAUX (var))
4802                 VAR_LOC_FROM (var) = NULL;
4803             }
4804           pool_free (loc_chain_pool, loc);
4805         }
4806
4807       if (!var->var_part[0].loc_chain)
4808         {
4809           var->n_var_parts--;
4810           changed = true;
4811         }
4812       if (changed)
4813         variable_was_changed (var, set);
4814     }
4815
4816   return 1;
4817 }
4818
4819 /* Remove all variable-location information about call-clobbered
4820    registers, as well as associations between MEMs and VALUEs.  */
4821
4822 static void
4823 dataflow_set_clear_at_call (dataflow_set *set)
4824 {
4825   unsigned int r;
4826   hard_reg_set_iterator hrsi;
4827
4828   EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, r, hrsi)
4829     var_regno_delete (set, r);
4830
4831   if (MAY_HAVE_DEBUG_INSNS)
4832     {
4833       set->traversed_vars = set->vars;
4834       shared_hash_htab (set->vars)
4835         .traverse <dataflow_set *, dataflow_set_preserve_mem_locs> (set);
4836       set->traversed_vars = set->vars;
4837       shared_hash_htab (set->vars)
4838         .traverse <dataflow_set *, dataflow_set_remove_mem_locs> (set);
4839       set->traversed_vars = NULL;
4840     }
4841 }
4842
4843 static bool
4844 variable_part_different_p (variable_part *vp1, variable_part *vp2)
4845 {
4846   location_chain lc1, lc2;
4847
4848   for (lc1 = vp1->loc_chain; lc1; lc1 = lc1->next)
4849     {
4850       for (lc2 = vp2->loc_chain; lc2; lc2 = lc2->next)
4851         {
4852           if (REG_P (lc1->loc) && REG_P (lc2->loc))
4853             {
4854               if (REGNO (lc1->loc) == REGNO (lc2->loc))
4855                 break;
4856             }
4857           if (rtx_equal_p (lc1->loc, lc2->loc))
4858             break;
4859         }
4860       if (!lc2)
4861         return true;
4862     }
4863   return false;
4864 }
4865
4866 /* Return true if one-part variables VAR1 and VAR2 are different.
4867    They must be in canonical order.  */
4868
4869 static bool
4870 onepart_variable_different_p (variable var1, variable var2)
4871 {
4872   location_chain lc1, lc2;
4873
4874   if (var1 == var2)
4875     return false;
4876
4877   gcc_assert (var1->n_var_parts == 1
4878               && var2->n_var_parts == 1);
4879
4880   lc1 = var1->var_part[0].loc_chain;
4881   lc2 = var2->var_part[0].loc_chain;
4882
4883   gcc_assert (lc1 && lc2);
4884
4885   while (lc1 && lc2)
4886     {
4887       if (loc_cmp (lc1->loc, lc2->loc))
4888         return true;
4889       lc1 = lc1->next;
4890       lc2 = lc2->next;
4891     }
4892
4893   return lc1 != lc2;
4894 }
4895
4896 /* Return true if variables VAR1 and VAR2 are different.  */
4897
4898 static bool
4899 variable_different_p (variable var1, variable var2)
4900 {
4901   int i;
4902
4903   if (var1 == var2)
4904     return false;
4905
4906   if (var1->onepart != var2->onepart)
4907     return true;
4908
4909   if (var1->n_var_parts != var2->n_var_parts)
4910     return true;
4911
4912   if (var1->onepart && var1->n_var_parts)
4913     {
4914       gcc_checking_assert (dv_as_opaque (var1->dv) == dv_as_opaque (var2->dv)
4915                            && var1->n_var_parts == 1);
4916       /* One-part values have locations in a canonical order.  */
4917       return onepart_variable_different_p (var1, var2);
4918     }
4919
4920   for (i = 0; i < var1->n_var_parts; i++)
4921     {
4922       if (VAR_PART_OFFSET (var1, i) != VAR_PART_OFFSET (var2, i))
4923         return true;
4924       if (variable_part_different_p (&var1->var_part[i], &var2->var_part[i]))
4925         return true;
4926       if (variable_part_different_p (&var2->var_part[i], &var1->var_part[i]))
4927         return true;
4928     }
4929   return false;
4930 }
4931
4932 /* Return true if dataflow sets OLD_SET and NEW_SET differ.  */
4933
4934 static bool
4935 dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
4936 {
4937   variable_iterator_type hi;
4938   variable var1;
4939
4940   if (old_set->vars == new_set->vars)
4941     return false;
4942
4943   if (shared_hash_htab (old_set->vars).elements ()
4944       != shared_hash_htab (new_set->vars).elements ())
4945     return true;
4946
4947   FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (old_set->vars),
4948                                var1, variable, hi)
4949     {
4950       variable_table_type htab = shared_hash_htab (new_set->vars);
4951       variable var2 = htab.find_with_hash (var1->dv, dv_htab_hash (var1->dv));
4952       if (!var2)
4953         {
4954           if (dump_file && (dump_flags & TDF_DETAILS))
4955             {
4956               fprintf (dump_file, "dataflow difference found: removal of:\n");
4957               dump_var (var1);
4958             }
4959           return true;
4960         }
4961
4962       if (variable_different_p (var1, var2))
4963         {
4964           if (dump_file && (dump_flags & TDF_DETAILS))
4965             {
4966               fprintf (dump_file, "dataflow difference found: "
4967                        "old and new follow:\n");
4968               dump_var (var1);
4969               dump_var (var2);
4970             }
4971           return true;
4972         }
4973     }
4974
4975   /* No need to traverse the second hashtab, if both have the same number
4976      of elements and the second one had all entries found in the first one,
4977      then it can't have any extra entries.  */
4978   return false;
4979 }
4980
4981 /* Free the contents of dataflow set SET.  */
4982
4983 static void
4984 dataflow_set_destroy (dataflow_set *set)
4985 {
4986   int i;
4987
4988   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4989     attrs_list_clear (&set->regs[i]);
4990
4991   shared_hash_destroy (set->vars);
4992   set->vars = NULL;
4993 }
4994
4995 /* Return true if RTL X contains a SYMBOL_REF.  */
4996
4997 static bool
4998 contains_symbol_ref (rtx x)
4999 {
5000   const char *fmt;
5001   RTX_CODE code;
5002   int i;
5003
5004   if (!x)
5005     return false;
5006
5007   code = GET_CODE (x);
5008   if (code == SYMBOL_REF)
5009     return true;
5010
5011   fmt = GET_RTX_FORMAT (code);
5012   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
5013     {
5014       if (fmt[i] == 'e')
5015         {
5016           if (contains_symbol_ref (XEXP (x, i)))
5017             return true;
5018         }
5019       else if (fmt[i] == 'E')
5020         {
5021           int j;
5022           for (j = 0; j < XVECLEN (x, i); j++)
5023             if (contains_symbol_ref (XVECEXP (x, i, j)))
5024               return true;
5025         }
5026     }
5027
5028   return false;
5029 }
5030
5031 /* Shall EXPR be tracked?  */
5032
5033 static bool
5034 track_expr_p (tree expr, bool need_rtl)
5035 {
5036   rtx decl_rtl;
5037   tree realdecl;
5038
5039   if (TREE_CODE (expr) == DEBUG_EXPR_DECL)
5040     return DECL_RTL_SET_P (expr);
5041
5042   /* If EXPR is not a parameter or a variable do not track it.  */
5043   if (TREE_CODE (expr) != VAR_DECL && TREE_CODE (expr) != PARM_DECL)
5044     return 0;
5045
5046   /* It also must have a name...  */
5047   if (!DECL_NAME (expr) && need_rtl)
5048     return 0;
5049
5050   /* ... and a RTL assigned to it.  */
5051   decl_rtl = DECL_RTL_IF_SET (expr);
5052   if (!decl_rtl && need_rtl)
5053     return 0;
5054
5055   /* If this expression is really a debug alias of some other declaration, we
5056      don't need to track this expression if the ultimate declaration is
5057      ignored.  */
5058   realdecl = expr;
5059   if (TREE_CODE (realdecl) == VAR_DECL && DECL_HAS_DEBUG_EXPR_P (realdecl))
5060     {
5061       realdecl = DECL_DEBUG_EXPR (realdecl);
5062       if (!DECL_P (realdecl))
5063         {
5064           if (handled_component_p (realdecl)
5065               || (TREE_CODE (realdecl) == MEM_REF
5066                   && TREE_CODE (TREE_OPERAND (realdecl, 0)) == ADDR_EXPR))
5067             {
5068               HOST_WIDE_INT bitsize, bitpos, maxsize;
5069               tree innerdecl
5070                 = get_ref_base_and_extent (realdecl, &bitpos, &bitsize,
5071                                            &maxsize);
5072               if (!DECL_P (innerdecl)
5073                   || DECL_IGNORED_P (innerdecl)
5074                   || TREE_STATIC (innerdecl)
5075                   || bitsize <= 0
5076                   || bitpos + bitsize > 256
5077                   || bitsize != maxsize)
5078                 return 0;
5079               else
5080                 realdecl = expr;
5081             }
5082           else
5083             return 0;
5084         }
5085     }
5086
5087   /* Do not track EXPR if REALDECL it should be ignored for debugging
5088      purposes.  */
5089   if (DECL_IGNORED_P (realdecl))
5090     return 0;
5091
5092   /* Do not track global variables until we are able to emit correct location
5093      list for them.  */
5094   if (TREE_STATIC (realdecl))
5095     return 0;
5096
5097   /* When the EXPR is a DECL for alias of some variable (see example)
5098      the TREE_STATIC flag is not used.  Disable tracking all DECLs whose
5099      DECL_RTL contains SYMBOL_REF.
5100
5101      Example:
5102      extern char **_dl_argv_internal __attribute__ ((alias ("_dl_argv")));
5103      char **_dl_argv;
5104   */
5105   if (decl_rtl && MEM_P (decl_rtl)
5106       && contains_symbol_ref (XEXP (decl_rtl, 0)))
5107     return 0;
5108
5109   /* If RTX is a memory it should not be very large (because it would be
5110      an array or struct).  */
5111   if (decl_rtl && MEM_P (decl_rtl))
5112     {
5113       /* Do not track structures and arrays.  */
5114       if (GET_MODE (decl_rtl) == BLKmode
5115           || AGGREGATE_TYPE_P (TREE_TYPE (realdecl)))
5116         return 0;
5117       if (MEM_SIZE_KNOWN_P (decl_rtl)
5118           && MEM_SIZE (decl_rtl) > MAX_VAR_PARTS)
5119         return 0;
5120     }
5121
5122   DECL_CHANGED (expr) = 0;
5123   DECL_CHANGED (realdecl) = 0;
5124   return 1;
5125 }
5126
5127 /* Determine whether a given LOC refers to the same variable part as
5128    EXPR+OFFSET.  */
5129
5130 static bool
5131 same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset)
5132 {
5133   tree expr2;
5134   HOST_WIDE_INT offset2;
5135
5136   if (! DECL_P (expr))
5137     return false;
5138
5139   if (REG_P (loc))
5140     {
5141       expr2 = REG_EXPR (loc);
5142       offset2 = REG_OFFSET (loc);
5143     }
5144   else if (MEM_P (loc))
5145     {
5146       expr2 = MEM_EXPR (loc);
5147       offset2 = INT_MEM_OFFSET (loc);
5148     }
5149   else
5150     return false;
5151
5152   if (! expr2 || ! DECL_P (expr2))
5153     return false;
5154
5155   expr = var_debug_decl (expr);
5156   expr2 = var_debug_decl (expr2);
5157
5158   return (expr == expr2 && offset == offset2);
5159 }
5160
5161 /* LOC is a REG or MEM that we would like to track if possible.
5162    If EXPR is null, we don't know what expression LOC refers to,
5163    otherwise it refers to EXPR + OFFSET.  STORE_REG_P is true if
5164    LOC is an lvalue register.
5165
5166    Return true if EXPR is nonnull and if LOC, or some lowpart of it,
5167    is something we can track.  When returning true, store the mode of
5168    the lowpart we can track in *MODE_OUT (if nonnull) and its offset
5169    from EXPR in *OFFSET_OUT (if nonnull).  */
5170
5171 static bool
5172 track_loc_p (rtx loc, tree expr, HOST_WIDE_INT offset, bool store_reg_p,
5173              enum machine_mode *mode_out, HOST_WIDE_INT *offset_out)
5174 {
5175   enum machine_mode mode;
5176
5177   if (expr == NULL || !track_expr_p (expr, true))
5178     return false;
5179
5180   /* If REG was a paradoxical subreg, its REG_ATTRS will describe the
5181      whole subreg, but only the old inner part is really relevant.  */
5182   mode = GET_MODE (loc);
5183   if (REG_P (loc) && !HARD_REGISTER_NUM_P (ORIGINAL_REGNO (loc)))
5184     {
5185       enum machine_mode pseudo_mode;
5186
5187       pseudo_mode = PSEUDO_REGNO_MODE (ORIGINAL_REGNO (loc));
5188       if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (pseudo_mode))
5189         {
5190           offset += byte_lowpart_offset (pseudo_mode, mode);
5191           mode = pseudo_mode;
5192         }
5193     }
5194
5195   /* If LOC is a paradoxical lowpart of EXPR, refer to EXPR itself.
5196      Do the same if we are storing to a register and EXPR occupies
5197      the whole of register LOC; in that case, the whole of EXPR is
5198      being changed.  We exclude complex modes from the second case
5199      because the real and imaginary parts are represented as separate
5200      pseudo registers, even if the whole complex value fits into one
5201      hard register.  */
5202   if ((GET_MODE_SIZE (mode) > GET_MODE_SIZE (DECL_MODE (expr))
5203        || (store_reg_p
5204            && !COMPLEX_MODE_P (DECL_MODE (expr))
5205            && hard_regno_nregs[REGNO (loc)][DECL_MODE (expr)] == 1))
5206       && offset + byte_lowpart_offset (DECL_MODE (expr), mode) == 0)
5207     {
5208       mode = DECL_MODE (expr);
5209       offset = 0;
5210     }
5211
5212   if (offset < 0 || offset >= MAX_VAR_PARTS)
5213     return false;
5214
5215   if (mode_out)
5216     *mode_out = mode;
5217   if (offset_out)
5218     *offset_out = offset;
5219   return true;
5220 }
5221
5222 /* Return the MODE lowpart of LOC, or null if LOC is not something we
5223    want to track.  When returning nonnull, make sure that the attributes
5224    on the returned value are updated.  */
5225
5226 static rtx
5227 var_lowpart (enum machine_mode mode, rtx loc)
5228 {
5229   unsigned int offset, reg_offset, regno;
5230
5231   if (GET_MODE (loc) == mode)
5232     return loc;
5233
5234   if (!REG_P (loc) && !MEM_P (loc))
5235     return NULL;
5236
5237   offset = byte_lowpart_offset (mode, GET_MODE (loc));
5238
5239   if (MEM_P (loc))
5240     return adjust_address_nv (loc, mode, offset);
5241
5242   reg_offset = subreg_lowpart_offset (mode, GET_MODE (loc));
5243   regno = REGNO (loc) + subreg_regno_offset (REGNO (loc), GET_MODE (loc),
5244                                              reg_offset, mode);
5245   return gen_rtx_REG_offset (loc, mode, regno, offset);
5246 }
5247
5248 /* Carry information about uses and stores while walking rtx.  */
5249
5250 struct count_use_info
5251 {
5252   /* The insn where the RTX is.  */
5253   rtx insn;
5254
5255   /* The basic block where insn is.  */
5256   basic_block bb;
5257
5258   /* The array of n_sets sets in the insn, as determined by cselib.  */
5259   struct cselib_set *sets;
5260   int n_sets;
5261
5262   /* True if we're counting stores, false otherwise.  */
5263   bool store_p;
5264 };
5265
5266 /* Find a VALUE corresponding to X.   */
5267
5268 static inline cselib_val *
5269 find_use_val (rtx x, enum machine_mode mode, struct count_use_info *cui)
5270 {
5271   int i;
5272
5273   if (cui->sets)
5274     {
5275       /* This is called after uses are set up and before stores are
5276          processed by cselib, so it's safe to look up srcs, but not
5277          dsts.  So we look up expressions that appear in srcs or in
5278          dest expressions, but we search the sets array for dests of
5279          stores.  */
5280       if (cui->store_p)
5281         {
5282           /* Some targets represent memset and memcpy patterns
5283              by (set (mem:BLK ...) (reg:[QHSD]I ...)) or
5284              (set (mem:BLK ...) (const_int ...)) or
5285              (set (mem:BLK ...) (mem:BLK ...)).  Don't return anything
5286              in that case, otherwise we end up with mode mismatches.  */
5287           if (mode == BLKmode && MEM_P (x))
5288             return NULL;
5289           for (i = 0; i < cui->n_sets; i++)
5290             if (cui->sets[i].dest == x)
5291               return cui->sets[i].src_elt;
5292         }
5293       else
5294         return cselib_lookup (x, mode, 0, VOIDmode);
5295     }
5296
5297   return NULL;
5298 }
5299
5300 /* Replace all registers and addresses in an expression with VALUE
5301    expressions that map back to them, unless the expression is a
5302    register.  If no mapping is or can be performed, returns NULL.  */
5303
5304 static rtx
5305 replace_expr_with_values (rtx loc)
5306 {
5307   if (REG_P (loc) || GET_CODE (loc) == ENTRY_VALUE)
5308     return NULL;
5309   else if (MEM_P (loc))
5310     {
5311       cselib_val *addr = cselib_lookup (XEXP (loc, 0),
5312                                         get_address_mode (loc), 0,
5313                                         GET_MODE (loc));
5314       if (addr)
5315         return replace_equiv_address_nv (loc, addr->val_rtx);
5316       else
5317         return NULL;
5318     }
5319   else
5320     return cselib_subst_to_values (loc, VOIDmode);
5321 }
5322
5323 /* Return true if *X is a DEBUG_EXPR.  Usable as an argument to
5324    for_each_rtx to tell whether there are any DEBUG_EXPRs within
5325    RTX.  */
5326
5327 static int
5328 rtx_debug_expr_p (rtx *x, void *data ATTRIBUTE_UNUSED)
5329 {
5330   rtx loc = *x;
5331
5332   return GET_CODE (loc) == DEBUG_EXPR;
5333 }
5334
5335 /* Determine what kind of micro operation to choose for a USE.  Return
5336    MO_CLOBBER if no micro operation is to be generated.  */
5337
5338 static enum micro_operation_type
5339 use_type (rtx loc, struct count_use_info *cui, enum machine_mode *modep)
5340 {
5341   tree expr;
5342
5343   if (cui && cui->sets)
5344     {
5345       if (GET_CODE (loc) == VAR_LOCATION)
5346         {
5347           if (track_expr_p (PAT_VAR_LOCATION_DECL (loc), false))
5348             {
5349               rtx ploc = PAT_VAR_LOCATION_LOC (loc);
5350               if (! VAR_LOC_UNKNOWN_P (ploc))
5351                 {
5352                   cselib_val *val = cselib_lookup (ploc, GET_MODE (loc), 1,
5353                                                    VOIDmode);
5354
5355                   /* ??? flag_float_store and volatile mems are never
5356                      given values, but we could in theory use them for
5357                      locations.  */
5358                   gcc_assert (val || 1);
5359                 }
5360               return MO_VAL_LOC;
5361             }
5362           else
5363             return MO_CLOBBER;
5364         }
5365
5366       if (REG_P (loc) || MEM_P (loc))
5367         {
5368           if (modep)
5369             *modep = GET_MODE (loc);
5370           if (cui->store_p)
5371             {
5372               if (REG_P (loc)
5373                   || (find_use_val (loc, GET_MODE (loc), cui)
5374                       && cselib_lookup (XEXP (loc, 0),
5375                                         get_address_mode (loc), 0,
5376                                         GET_MODE (loc))))
5377                 return MO_VAL_SET;
5378             }
5379           else
5380             {
5381               cselib_val *val = find_use_val (loc, GET_MODE (loc), cui);
5382
5383               if (val && !cselib_preserved_value_p (val))
5384                 return MO_VAL_USE;
5385             }
5386         }
5387     }
5388
5389   if (REG_P (loc))
5390     {
5391       gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
5392
5393       if (loc == cfa_base_rtx)
5394         return MO_CLOBBER;
5395       expr = REG_EXPR (loc);
5396
5397       if (!expr)
5398         return MO_USE_NO_VAR;
5399       else if (target_for_debug_bind (var_debug_decl (expr)))
5400         return MO_CLOBBER;
5401       else if (track_loc_p (loc, expr, REG_OFFSET (loc),
5402                             false, modep, NULL))
5403         return MO_USE;
5404       else
5405         return MO_USE_NO_VAR;
5406     }
5407   else if (MEM_P (loc))
5408     {
5409       expr = MEM_EXPR (loc);
5410
5411       if (!expr)
5412         return MO_CLOBBER;
5413       else if (target_for_debug_bind (var_debug_decl (expr)))
5414         return MO_CLOBBER;
5415       else if (track_loc_p (loc, expr, INT_MEM_OFFSET (loc),
5416                             false, modep, NULL)
5417                /* Multi-part variables shouldn't refer to one-part
5418                   variable names such as VALUEs (never happens) or
5419                   DEBUG_EXPRs (only happens in the presence of debug
5420                   insns).  */
5421                && (!MAY_HAVE_DEBUG_INSNS
5422                    || !for_each_rtx (&XEXP (loc, 0), rtx_debug_expr_p, NULL)))
5423         return MO_USE;
5424       else
5425         return MO_CLOBBER;
5426     }
5427
5428   return MO_CLOBBER;
5429 }
5430
5431 /* Log to OUT information about micro-operation MOPT involving X in
5432    INSN of BB.  */
5433
5434 static inline void
5435 log_op_type (rtx x, basic_block bb, rtx insn,
5436              enum micro_operation_type mopt, FILE *out)
5437 {
5438   fprintf (out, "bb %i op %i insn %i %s ",
5439            bb->index, VTI (bb)->mos.length (),
5440            INSN_UID (insn), micro_operation_type_name[mopt]);
5441   print_inline_rtx (out, x, 2);
5442   fputc ('\n', out);
5443 }
5444
5445 /* Tell whether the CONCAT used to holds a VALUE and its location
5446    needs value resolution, i.e., an attempt of mapping the location
5447    back to other incoming values.  */
5448 #define VAL_NEEDS_RESOLUTION(x) \
5449   (RTL_FLAG_CHECK1 ("VAL_NEEDS_RESOLUTION", (x), CONCAT)->volatil)
5450 /* Whether the location in the CONCAT is a tracked expression, that
5451    should also be handled like a MO_USE.  */
5452 #define VAL_HOLDS_TRACK_EXPR(x) \
5453   (RTL_FLAG_CHECK1 ("VAL_HOLDS_TRACK_EXPR", (x), CONCAT)->used)
5454 /* Whether the location in the CONCAT should be handled like a MO_COPY
5455    as well.  */
5456 #define VAL_EXPR_IS_COPIED(x) \
5457   (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_COPIED", (x), CONCAT)->jump)
5458 /* Whether the location in the CONCAT should be handled like a
5459    MO_CLOBBER as well.  */
5460 #define VAL_EXPR_IS_CLOBBERED(x) \
5461   (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_CLOBBERED", (x), CONCAT)->unchanging)
5462
5463 /* All preserved VALUEs.  */
5464 static vec<rtx> preserved_values;
5465
5466 /* Ensure VAL is preserved and remember it in a vector for vt_emit_notes.  */
5467
5468 static void
5469 preserve_value (cselib_val *val)
5470 {
5471   cselib_preserve_value (val);
5472   preserved_values.safe_push (val->val_rtx);
5473 }
5474
5475 /* Helper function for MO_VAL_LOC handling.  Return non-zero if
5476    any rtxes not suitable for CONST use not replaced by VALUEs
5477    are discovered.  */
5478
5479 static int
5480 non_suitable_const (rtx *x, void *data ATTRIBUTE_UNUSED)
5481 {
5482   if (*x == NULL_RTX)
5483     return 0;
5484
5485   switch (GET_CODE (*x))
5486     {
5487     case REG:
5488     case DEBUG_EXPR:
5489     case PC:
5490     case SCRATCH:
5491     case CC0:
5492     case ASM_INPUT:
5493     case ASM_OPERANDS:
5494       return 1;
5495     case MEM:
5496       return !MEM_READONLY_P (*x);
5497     default:
5498       return 0;
5499     }
5500 }
5501
5502 /* Add uses (register and memory references) LOC which will be tracked
5503    to VTI (bb)->mos.  INSN is instruction which the LOC is part of.  */
5504
5505 static int
5506 add_uses (rtx *ploc, void *data)
5507 {
5508   rtx loc = *ploc;
5509   enum machine_mode mode = VOIDmode;
5510   struct count_use_info *cui = (struct count_use_info *)data;
5511   enum micro_operation_type type = use_type (loc, cui, &mode);
5512
5513   if (type != MO_CLOBBER)
5514     {
5515       basic_block bb = cui->bb;
5516       micro_operation mo;
5517
5518       mo.type = type;
5519       mo.u.loc = type == MO_USE ? var_lowpart (mode, loc) : loc;
5520       mo.insn = cui->insn;
5521
5522       if (type == MO_VAL_LOC)
5523         {
5524           rtx oloc = loc;
5525           rtx vloc = PAT_VAR_LOCATION_LOC (oloc);
5526           cselib_val *val;
5527
5528           gcc_assert (cui->sets);
5529
5530           if (MEM_P (vloc)
5531               && !REG_P (XEXP (vloc, 0))
5532               && !MEM_P (XEXP (vloc, 0)))
5533             {
5534               rtx mloc = vloc;
5535               enum machine_mode address_mode = get_address_mode (mloc);
5536               cselib_val *val
5537                 = cselib_lookup (XEXP (mloc, 0), address_mode, 0,
5538                                  GET_MODE (mloc));
5539
5540               if (val && !cselib_preserved_value_p (val))
5541                 preserve_value (val);
5542             }
5543
5544           if (CONSTANT_P (vloc)
5545               && (GET_CODE (vloc) != CONST
5546                   || for_each_rtx (&vloc, non_suitable_const, NULL)))
5547             /* For constants don't look up any value.  */;
5548           else if (!VAR_LOC_UNKNOWN_P (vloc) && !unsuitable_loc (vloc)
5549                    && (val = find_use_val (vloc, GET_MODE (oloc), cui)))
5550             {
5551               enum machine_mode mode2;
5552               enum micro_operation_type type2;
5553               rtx nloc = NULL;
5554               bool resolvable = REG_P (vloc) || MEM_P (vloc);
5555
5556               if (resolvable)
5557                 nloc = replace_expr_with_values (vloc);
5558
5559               if (nloc)
5560                 {
5561                   oloc = shallow_copy_rtx (oloc);
5562                   PAT_VAR_LOCATION_LOC (oloc) = nloc;
5563                 }
5564
5565               oloc = gen_rtx_CONCAT (mode, val->val_rtx, oloc);
5566
5567               type2 = use_type (vloc, 0, &mode2);
5568
5569               gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
5570                           || type2 == MO_CLOBBER);
5571
5572               if (type2 == MO_CLOBBER
5573                   && !cselib_preserved_value_p (val))
5574                 {
5575                   VAL_NEEDS_RESOLUTION (oloc) = resolvable;
5576                   preserve_value (val);
5577                 }
5578             }
5579           else if (!VAR_LOC_UNKNOWN_P (vloc))
5580             {
5581               oloc = shallow_copy_rtx (oloc);
5582               PAT_VAR_LOCATION_LOC (oloc) = gen_rtx_UNKNOWN_VAR_LOC ();
5583             }
5584
5585           mo.u.loc = oloc;
5586         }
5587       else if (type == MO_VAL_USE)
5588         {
5589           enum machine_mode mode2 = VOIDmode;
5590           enum micro_operation_type type2;
5591           cselib_val *val = find_use_val (loc, GET_MODE (loc), cui);
5592           rtx vloc, oloc = loc, nloc;
5593
5594           gcc_assert (cui->sets);
5595
5596           if (MEM_P (oloc)
5597               && !REG_P (XEXP (oloc, 0))
5598               && !MEM_P (XEXP (oloc, 0)))
5599             {
5600               rtx mloc = oloc;
5601               enum machine_mode address_mode = get_address_mode (mloc);
5602               cselib_val *val
5603                 = cselib_lookup (XEXP (mloc, 0), address_mode, 0,
5604                                  GET_MODE (mloc));
5605
5606               if (val && !cselib_preserved_value_p (val))
5607                 preserve_value (val);
5608             }
5609
5610           type2 = use_type (loc, 0, &mode2);
5611
5612           gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
5613                       || type2 == MO_CLOBBER);
5614
5615           if (type2 == MO_USE)
5616             vloc = var_lowpart (mode2, loc);
5617           else
5618             vloc = oloc;
5619
5620           /* The loc of a MO_VAL_USE may have two forms:
5621
5622              (concat val src): val is at src, a value-based
5623              representation.
5624
5625              (concat (concat val use) src): same as above, with use as
5626              the MO_USE tracked value, if it differs from src.
5627
5628           */
5629
5630           gcc_checking_assert (REG_P (loc) || MEM_P (loc));
5631           nloc = replace_expr_with_values (loc);
5632           if (!nloc)
5633             nloc = oloc;
5634
5635           if (vloc != nloc)
5636             oloc = gen_rtx_CONCAT (mode2, val->val_rtx, vloc);
5637           else
5638             oloc = val->val_rtx;
5639
5640           mo.u.loc = gen_rtx_CONCAT (mode, oloc, nloc);
5641
5642           if (type2 == MO_USE)
5643             VAL_HOLDS_TRACK_EXPR (mo.u.loc) = 1;
5644           if (!cselib_preserved_value_p (val))
5645             {
5646               VAL_NEEDS_RESOLUTION (mo.u.loc) = 1;
5647               preserve_value (val);
5648             }
5649         }
5650       else
5651         gcc_assert (type == MO_USE || type == MO_USE_NO_VAR);
5652
5653       if (dump_file && (dump_flags & TDF_DETAILS))
5654         log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
5655       VTI (bb)->mos.safe_push (mo);
5656     }
5657
5658   return 0;
5659 }
5660
5661 /* Helper function for finding all uses of REG/MEM in X in insn INSN.  */
5662
5663 static void
5664 add_uses_1 (rtx *x, void *cui)
5665 {
5666   for_each_rtx (x, add_uses, cui);
5667 }
5668
5669 /* This is the value used during expansion of locations.  We want it
5670    to be unbounded, so that variables expanded deep in a recursion
5671    nest are fully evaluated, so that their values are cached
5672    correctly.  We avoid recursion cycles through other means, and we
5673    don't unshare RTL, so excess complexity is not a problem.  */
5674 #define EXPR_DEPTH (INT_MAX)
5675 /* We use this to keep too-complex expressions from being emitted as
5676    location notes, and then to debug information.  Users can trade
5677    compile time for ridiculously complex expressions, although they're
5678    seldom useful, and they may often have to be discarded as not
5679    representable anyway.  */
5680 #define EXPR_USE_DEPTH (PARAM_VALUE (PARAM_MAX_VARTRACK_EXPR_DEPTH))
5681
5682 /* Attempt to reverse the EXPR operation in the debug info and record
5683    it in the cselib table.  Say for reg1 = reg2 + 6 even when reg2 is
5684    no longer live we can express its value as VAL - 6.  */
5685
5686 static void
5687 reverse_op (rtx val, const_rtx expr, rtx insn)
5688 {
5689   rtx src, arg, ret;
5690   cselib_val *v;
5691   struct elt_loc_list *l;
5692   enum rtx_code code;
5693   int count;
5694
5695   if (GET_CODE (expr) != SET)
5696     return;
5697
5698   if (!REG_P (SET_DEST (expr)) || GET_MODE (val) != GET_MODE (SET_DEST (expr)))
5699     return;
5700
5701   src = SET_SRC (expr);
5702   switch (GET_CODE (src))
5703     {
5704     case PLUS:
5705     case MINUS:
5706     case XOR:
5707     case NOT:
5708     case NEG:
5709       if (!REG_P (XEXP (src, 0)))
5710         return;
5711       break;
5712     case SIGN_EXTEND:
5713     case ZERO_EXTEND:
5714       if (!REG_P (XEXP (src, 0)) && !MEM_P (XEXP (src, 0)))
5715         return;
5716       break;
5717     default:
5718       return;
5719     }
5720
5721   if (!SCALAR_INT_MODE_P (GET_MODE (src)) || XEXP (src, 0) == cfa_base_rtx)
5722     return;
5723
5724   v = cselib_lookup (XEXP (src, 0), GET_MODE (XEXP (src, 0)), 0, VOIDmode);
5725   if (!v || !cselib_preserved_value_p (v))
5726     return;
5727
5728   /* Use canonical V to avoid creating multiple redundant expressions
5729      for different VALUES equivalent to V.  */
5730   v = canonical_cselib_val (v);
5731
5732   /* Adding a reverse op isn't useful if V already has an always valid
5733      location.  Ignore ENTRY_VALUE, while it is always constant, we should
5734      prefer non-ENTRY_VALUE locations whenever possible.  */
5735   for (l = v->locs, count = 0; l; l = l->next, count++)
5736     if (CONSTANT_P (l->loc)
5737         && (GET_CODE (l->loc) != CONST || !references_value_p (l->loc, 0)))
5738       return;
5739     /* Avoid creating too large locs lists.  */
5740     else if (count == PARAM_VALUE (PARAM_MAX_VARTRACK_REVERSE_OP_SIZE))
5741       return;
5742
5743   switch (GET_CODE (src))
5744     {
5745     case NOT:
5746     case NEG:
5747       if (GET_MODE (v->val_rtx) != GET_MODE (val))
5748         return;
5749       ret = gen_rtx_fmt_e (GET_CODE (src), GET_MODE (val), val);
5750       break;
5751     case SIGN_EXTEND:
5752     case ZERO_EXTEND:
5753       ret = gen_lowpart_SUBREG (GET_MODE (v->val_rtx), val);
5754       break;
5755     case XOR:
5756       code = XOR;
5757       goto binary;
5758     case PLUS:
5759       code = MINUS;
5760       goto binary;
5761     case MINUS:
5762       code = PLUS;
5763       goto binary;
5764     binary:
5765       if (GET_MODE (v->val_rtx) != GET_MODE (val))
5766         return;
5767       arg = XEXP (src, 1);
5768       if (!CONST_INT_P (arg) && GET_CODE (arg) != SYMBOL_REF)
5769         {
5770           arg = cselib_expand_value_rtx (arg, scratch_regs, 5);
5771           if (arg == NULL_RTX)
5772             return;
5773           if (!CONST_INT_P (arg) && GET_CODE (arg) != SYMBOL_REF)
5774             return;
5775         }
5776       ret = simplify_gen_binary (code, GET_MODE (val), val, arg);
5777       if (ret == val)
5778         /* Ensure ret isn't VALUE itself (which can happen e.g. for
5779            (plus (reg1) (reg2)) when reg2 is known to be 0), as that
5780            breaks a lot of routines during var-tracking.  */
5781         ret = gen_rtx_fmt_ee (PLUS, GET_MODE (val), val, const0_rtx);
5782       break;
5783     default:
5784       gcc_unreachable ();
5785     }
5786
5787   cselib_add_permanent_equiv (v, ret, insn);
5788 }
5789
5790 /* Add stores (register and memory references) LOC which will be tracked
5791    to VTI (bb)->mos.  EXPR is the RTL expression containing the store.
5792    CUIP->insn is instruction which the LOC is part of.  */
5793
5794 static void
5795 add_stores (rtx loc, const_rtx expr, void *cuip)
5796 {
5797   enum machine_mode mode = VOIDmode, mode2;
5798   struct count_use_info *cui = (struct count_use_info *)cuip;
5799   basic_block bb = cui->bb;
5800   micro_operation mo;
5801   rtx oloc = loc, nloc, src = NULL;
5802   enum micro_operation_type type = use_type (loc, cui, &mode);
5803   bool track_p = false;
5804   cselib_val *v;
5805   bool resolve, preserve;
5806
5807   if (type == MO_CLOBBER)
5808     return;
5809
5810   mode2 = mode;
5811
5812   if (REG_P (loc))
5813     {
5814       gcc_assert (loc != cfa_base_rtx);
5815       if ((GET_CODE (expr) == CLOBBER && type != MO_VAL_SET)
5816           || !(track_p = use_type (loc, NULL, &mode2) == MO_USE)
5817           || GET_CODE (expr) == CLOBBER)
5818         {
5819           mo.type = MO_CLOBBER;
5820           mo.u.loc = loc;
5821           if (GET_CODE (expr) == SET
5822               && SET_DEST (expr) == loc
5823               && !unsuitable_loc (SET_SRC (expr))
5824               && find_use_val (loc, mode, cui))
5825             {
5826               gcc_checking_assert (type == MO_VAL_SET);
5827               mo.u.loc = gen_rtx_SET (VOIDmode, loc, SET_SRC (expr));
5828             }
5829         }
5830       else
5831         {
5832           if (GET_CODE (expr) == SET
5833               && SET_DEST (expr) == loc
5834               && GET_CODE (SET_SRC (expr)) != ASM_OPERANDS)
5835             src = var_lowpart (mode2, SET_SRC (expr));
5836           loc = var_lowpart (mode2, loc);
5837
5838           if (src == NULL)
5839             {
5840               mo.type = MO_SET;
5841               mo.u.loc = loc;
5842             }
5843           else
5844             {
5845               rtx xexpr = gen_rtx_SET (VOIDmode, loc, src);
5846               if (same_variable_part_p (src, REG_EXPR (loc), REG_OFFSET (loc)))
5847                 {
5848                   /* If this is an instruction copying (part of) a parameter
5849                      passed by invisible reference to its register location,
5850                      pretend it's a SET so that the initial memory location
5851                      is discarded, as the parameter register can be reused
5852                      for other purposes and we do not track locations based
5853                      on generic registers.  */
5854                   if (MEM_P (src)
5855                       && REG_EXPR (loc)
5856                       && TREE_CODE (REG_EXPR (loc)) == PARM_DECL
5857                       && DECL_MODE (REG_EXPR (loc)) != BLKmode
5858                       && MEM_P (DECL_INCOMING_RTL (REG_EXPR (loc)))
5859                       && XEXP (DECL_INCOMING_RTL (REG_EXPR (loc)), 0)
5860                          != arg_pointer_rtx)
5861                     mo.type = MO_SET;
5862                   else
5863                     mo.type = MO_COPY;
5864                 }
5865               else
5866                 mo.type = MO_SET;
5867               mo.u.loc = xexpr;
5868             }
5869         }
5870       mo.insn = cui->insn;
5871     }
5872   else if (MEM_P (loc)
5873            && ((track_p = use_type (loc, NULL, &mode2) == MO_USE)
5874                || cui->sets))
5875     {
5876       if (MEM_P (loc) && type == MO_VAL_SET
5877           && !REG_P (XEXP (loc, 0))
5878           && !MEM_P (XEXP (loc, 0)))
5879         {
5880           rtx mloc = loc;
5881           enum machine_mode address_mode = get_address_mode (mloc);
5882           cselib_val *val = cselib_lookup (XEXP (mloc, 0),
5883                                            address_mode, 0,
5884                                            GET_MODE (mloc));
5885
5886           if (val && !cselib_preserved_value_p (val))
5887             preserve_value (val);
5888         }
5889
5890       if (GET_CODE (expr) == CLOBBER || !track_p)
5891         {
5892           mo.type = MO_CLOBBER;
5893           mo.u.loc = track_p ? var_lowpart (mode2, loc) : loc;
5894         }
5895       else
5896         {
5897           if (GET_CODE (expr) == SET
5898               && SET_DEST (expr) == loc
5899               && GET_CODE (SET_SRC (expr)) != ASM_OPERANDS)
5900             src = var_lowpart (mode2, SET_SRC (expr));
5901           loc = var_lowpart (mode2, loc);
5902
5903           if (src == NULL)
5904             {
5905               mo.type = MO_SET;
5906               mo.u.loc = loc;
5907             }
5908           else
5909             {
5910               rtx xexpr = gen_rtx_SET (VOIDmode, loc, src);
5911               if (same_variable_part_p (SET_SRC (xexpr),
5912                                         MEM_EXPR (loc),
5913                                         INT_MEM_OFFSET (loc)))
5914                 mo.type = MO_COPY;
5915               else
5916                 mo.type = MO_SET;
5917               mo.u.loc = xexpr;
5918             }
5919         }
5920       mo.insn = cui->insn;
5921     }
5922   else
5923     return;
5924
5925   if (type != MO_VAL_SET)
5926     goto log_and_return;
5927
5928   v = find_use_val (oloc, mode, cui);
5929
5930   if (!v)
5931     goto log_and_return;
5932
5933   resolve = preserve = !cselib_preserved_value_p (v);
5934
5935   if (loc == stack_pointer_rtx
5936       && hard_frame_pointer_adjustment != -1
5937       && preserve)
5938     cselib_set_value_sp_based (v);
5939
5940   nloc = replace_expr_with_values (oloc);
5941   if (nloc)
5942     oloc = nloc;
5943
5944   if (GET_CODE (PATTERN (cui->insn)) == COND_EXEC)
5945     {
5946       cselib_val *oval = cselib_lookup (oloc, GET_MODE (oloc), 0, VOIDmode);
5947
5948       gcc_assert (oval != v);
5949       gcc_assert (REG_P (oloc) || MEM_P (oloc));
5950
5951       if (oval && !cselib_preserved_value_p (oval))
5952         {
5953           micro_operation moa;
5954
5955           preserve_value (oval);
5956
5957           moa.type = MO_VAL_USE;
5958           moa.u.loc = gen_rtx_CONCAT (mode, oval->val_rtx, oloc);
5959           VAL_NEEDS_RESOLUTION (moa.u.loc) = 1;
5960           moa.insn = cui->insn;
5961
5962           if (dump_file && (dump_flags & TDF_DETAILS))
5963             log_op_type (moa.u.loc, cui->bb, cui->insn,
5964                          moa.type, dump_file);
5965           VTI (bb)->mos.safe_push (moa);
5966         }
5967
5968       resolve = false;
5969     }
5970   else if (resolve && GET_CODE (mo.u.loc) == SET)
5971     {
5972       if (REG_P (SET_SRC (expr)) || MEM_P (SET_SRC (expr)))
5973         nloc = replace_expr_with_values (SET_SRC (expr));
5974       else
5975         nloc = NULL_RTX;
5976
5977       /* Avoid the mode mismatch between oexpr and expr.  */
5978       if (!nloc && mode != mode2)
5979         {
5980           nloc = SET_SRC (expr);
5981           gcc_assert (oloc == SET_DEST (expr));
5982         }
5983
5984       if (nloc && nloc != SET_SRC (mo.u.loc))
5985         oloc = gen_rtx_SET (GET_MODE (mo.u.loc), oloc, nloc);
5986       else
5987         {
5988           if (oloc == SET_DEST (mo.u.loc))
5989             /* No point in duplicating.  */
5990             oloc = mo.u.loc;
5991           if (!REG_P (SET_SRC (mo.u.loc)))
5992             resolve = false;
5993         }
5994     }
5995   else if (!resolve)
5996     {
5997       if (GET_CODE (mo.u.loc) == SET
5998           && oloc == SET_DEST (mo.u.loc))
5999         /* No point in duplicating.  */
6000         oloc = mo.u.loc;
6001     }
6002   else
6003     resolve = false;
6004
6005   loc = gen_rtx_CONCAT (mode, v->val_rtx, oloc);
6006
6007   if (mo.u.loc != oloc)
6008     loc = gen_rtx_CONCAT (GET_MODE (mo.u.loc), loc, mo.u.loc);
6009
6010   /* The loc of a MO_VAL_SET may have various forms:
6011
6012      (concat val dst): dst now holds val
6013
6014      (concat val (set dst src)): dst now holds val, copied from src
6015
6016      (concat (concat val dstv) dst): dst now holds val; dstv is dst
6017      after replacing mems and non-top-level regs with values.
6018
6019      (concat (concat val dstv) (set dst src)): dst now holds val,
6020      copied from src.  dstv is a value-based representation of dst, if
6021      it differs from dst.  If resolution is needed, src is a REG, and
6022      its mode is the same as that of val.
6023
6024      (concat (concat val (set dstv srcv)) (set dst src)): src
6025      copied to dst, holding val.  dstv and srcv are value-based
6026      representations of dst and src, respectively.
6027
6028   */
6029
6030   if (GET_CODE (PATTERN (cui->insn)) != COND_EXEC)
6031     reverse_op (v->val_rtx, expr, cui->insn);
6032
6033   mo.u.loc = loc;
6034
6035   if (track_p)
6036     VAL_HOLDS_TRACK_EXPR (loc) = 1;
6037   if (preserve)
6038     {
6039       VAL_NEEDS_RESOLUTION (loc) = resolve;
6040       preserve_value (v);
6041     }
6042   if (mo.type == MO_CLOBBER)
6043     VAL_EXPR_IS_CLOBBERED (loc) = 1;
6044   if (mo.type == MO_COPY)
6045     VAL_EXPR_IS_COPIED (loc) = 1;
6046
6047   mo.type = MO_VAL_SET;
6048
6049  log_and_return:
6050   if (dump_file && (dump_flags & TDF_DETAILS))
6051     log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
6052   VTI (bb)->mos.safe_push (mo);
6053 }
6054
6055 /* Arguments to the call.  */
6056 static rtx call_arguments;
6057
6058 /* Compute call_arguments.  */
6059
6060 static void
6061 prepare_call_arguments (basic_block bb, rtx insn)
6062 {
6063   rtx link, x, call;
6064   rtx prev, cur, next;
6065   rtx this_arg = NULL_RTX;
6066   tree type = NULL_TREE, t, fndecl = NULL_TREE;
6067   tree obj_type_ref = NULL_TREE;
6068   CUMULATIVE_ARGS args_so_far_v;
6069   cumulative_args_t args_so_far;
6070
6071   memset (&args_so_far_v, 0, sizeof (args_so_far_v));
6072   args_so_far = pack_cumulative_args (&args_so_far_v);
6073   call = get_call_rtx_from (insn);
6074   if (call)
6075     {
6076       if (GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
6077         {
6078           rtx symbol = XEXP (XEXP (call, 0), 0);
6079           if (SYMBOL_REF_DECL (symbol))
6080             fndecl = SYMBOL_REF_DECL (symbol);
6081         }
6082       if (fndecl == NULL_TREE)
6083         fndecl = MEM_EXPR (XEXP (call, 0));
6084       if (fndecl
6085           && TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE
6086           && TREE_CODE (TREE_TYPE (fndecl)) != METHOD_TYPE)
6087         fndecl = NULL_TREE;
6088       if (fndecl && TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
6089         type = TREE_TYPE (fndecl);
6090       if (fndecl && TREE_CODE (fndecl) != FUNCTION_DECL)
6091         {
6092           if (TREE_CODE (fndecl) == INDIRECT_REF
6093               && TREE_CODE (TREE_OPERAND (fndecl, 0)) == OBJ_TYPE_REF)
6094             obj_type_ref = TREE_OPERAND (fndecl, 0);
6095           fndecl = NULL_TREE;
6096         }
6097       if (type)
6098         {
6099           for (t = TYPE_ARG_TYPES (type); t && t != void_list_node;
6100                t = TREE_CHAIN (t))
6101             if (TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
6102                 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (t))))
6103               break;
6104           if ((t == NULL || t == void_list_node) && obj_type_ref == NULL_TREE)
6105             type = NULL;
6106           else
6107             {
6108               int nargs ATTRIBUTE_UNUSED = list_length (TYPE_ARG_TYPES (type));
6109               link = CALL_INSN_FUNCTION_USAGE (insn);
6110 #ifndef PCC_STATIC_STRUCT_RETURN
6111               if (aggregate_value_p (TREE_TYPE (type), type)
6112                   && targetm.calls.struct_value_rtx (type, 0) == 0)
6113                 {
6114                   tree struct_addr = build_pointer_type (TREE_TYPE (type));
6115                   enum machine_mode mode = TYPE_MODE (struct_addr);
6116                   rtx reg;
6117                   INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
6118                                         nargs + 1);
6119                   reg = targetm.calls.function_arg (args_so_far, mode,
6120                                                     struct_addr, true);
6121                   targetm.calls.function_arg_advance (args_so_far, mode,
6122                                                       struct_addr, true);
6123                   if (reg == NULL_RTX)
6124                     {
6125                       for (; link; link = XEXP (link, 1))
6126                         if (GET_CODE (XEXP (link, 0)) == USE
6127                             && MEM_P (XEXP (XEXP (link, 0), 0)))
6128                           {
6129                             link = XEXP (link, 1);
6130                             break;
6131                           }
6132                     }
6133                 }
6134               else
6135 #endif
6136                 INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
6137                                       nargs);
6138               if (obj_type_ref && TYPE_ARG_TYPES (type) != void_list_node)
6139                 {
6140                   enum machine_mode mode;
6141                   t = TYPE_ARG_TYPES (type);
6142                   mode = TYPE_MODE (TREE_VALUE (t));
6143                   this_arg = targetm.calls.function_arg (args_so_far, mode,
6144                                                          TREE_VALUE (t), true);
6145                   if (this_arg && !REG_P (this_arg))
6146                     this_arg = NULL_RTX;
6147                   else if (this_arg == NULL_RTX)
6148                     {
6149                       for (; link; link = XEXP (link, 1))
6150                         if (GET_CODE (XEXP (link, 0)) == USE
6151                             && MEM_P (XEXP (XEXP (link, 0), 0)))
6152                           {
6153                             this_arg = XEXP (XEXP (link, 0), 0);
6154                             break;
6155                           }
6156                     }
6157                 }
6158             }
6159         }
6160     }
6161   t = type ? TYPE_ARG_TYPES (type) : NULL_TREE;
6162
6163   for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
6164     if (GET_CODE (XEXP (link, 0)) == USE)
6165       {
6166         rtx item = NULL_RTX;
6167         x = XEXP (XEXP (link, 0), 0);
6168         if (GET_MODE (link) == VOIDmode
6169             || GET_MODE (link) == BLKmode
6170             || (GET_MODE (link) != GET_MODE (x)
6171                 && (GET_MODE_CLASS (GET_MODE (link)) != MODE_INT
6172                     || GET_MODE_CLASS (GET_MODE (x)) != MODE_INT)))
6173           /* Can't do anything for these, if the original type mode
6174              isn't known or can't be converted.  */;
6175         else if (REG_P (x))
6176           {
6177             cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
6178             if (val && cselib_preserved_value_p (val))
6179               item = val->val_rtx;
6180             else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
6181               {
6182                 enum machine_mode mode = GET_MODE (x);
6183
6184                 while ((mode = GET_MODE_WIDER_MODE (mode)) != VOIDmode
6185                        && GET_MODE_BITSIZE (mode) <= BITS_PER_WORD)
6186                   {
6187                     rtx reg = simplify_subreg (mode, x, GET_MODE (x), 0);
6188
6189                     if (reg == NULL_RTX || !REG_P (reg))
6190                       continue;
6191                     val = cselib_lookup (reg, mode, 0, VOIDmode);
6192                     if (val && cselib_preserved_value_p (val))
6193                       {
6194                         item = val->val_rtx;
6195                         break;
6196                       }
6197                   }
6198               }
6199           }
6200         else if (MEM_P (x))
6201           {
6202             rtx mem = x;
6203             cselib_val *val;
6204
6205             if (!frame_pointer_needed)
6206               {
6207                 struct adjust_mem_data amd;
6208                 amd.mem_mode = VOIDmode;
6209                 amd.stack_adjust = -VTI (bb)->out.stack_adjust;
6210                 amd.side_effects = NULL_RTX;
6211                 amd.store = true;
6212                 mem = simplify_replace_fn_rtx (mem, NULL_RTX, adjust_mems,
6213                                                &amd);
6214                 gcc_assert (amd.side_effects == NULL_RTX);
6215               }
6216             val = cselib_lookup (mem, GET_MODE (mem), 0, VOIDmode);
6217             if (val && cselib_preserved_value_p (val))
6218               item = val->val_rtx;
6219             else if (GET_MODE_CLASS (GET_MODE (mem)) != MODE_INT)
6220               {
6221                 /* For non-integer stack argument see also if they weren't
6222                    initialized by integers.  */
6223                 enum machine_mode imode = int_mode_for_mode (GET_MODE (mem));
6224                 if (imode != GET_MODE (mem) && imode != BLKmode)
6225                   {
6226                     val = cselib_lookup (adjust_address_nv (mem, imode, 0),
6227                                          imode, 0, VOIDmode);
6228                     if (val && cselib_preserved_value_p (val))
6229                       item = lowpart_subreg (GET_MODE (x), val->val_rtx,
6230                                              imode);
6231                   }
6232               }
6233           }
6234         if (item)
6235           {
6236             rtx x2 = x;
6237             if (GET_MODE (item) != GET_MODE (link))
6238               item = lowpart_subreg (GET_MODE (link), item, GET_MODE (item));
6239             if (GET_MODE (x2) != GET_MODE (link))
6240               x2 = lowpart_subreg (GET_MODE (link), x2, GET_MODE (x2));
6241             item = gen_rtx_CONCAT (GET_MODE (link), x2, item);
6242             call_arguments
6243               = gen_rtx_EXPR_LIST (VOIDmode, item, call_arguments);
6244           }
6245         if (t && t != void_list_node)
6246           {
6247             tree argtype = TREE_VALUE (t);
6248             enum machine_mode mode = TYPE_MODE (argtype);
6249             rtx reg;
6250             if (pass_by_reference (&args_so_far_v, mode, argtype, true))
6251               {
6252                 argtype = build_pointer_type (argtype);
6253                 mode = TYPE_MODE (argtype);
6254               }
6255             reg = targetm.calls.function_arg (args_so_far, mode,
6256                                               argtype, true);
6257             if (TREE_CODE (argtype) == REFERENCE_TYPE
6258                 && INTEGRAL_TYPE_P (TREE_TYPE (argtype))
6259                 && reg
6260                 && REG_P (reg)
6261                 && GET_MODE (reg) == mode
6262                 && GET_MODE_CLASS (mode) == MODE_INT
6263                 && REG_P (x)
6264                 && REGNO (x) == REGNO (reg)
6265                 && GET_MODE (x) == mode
6266                 && item)
6267               {
6268                 enum machine_mode indmode
6269                   = TYPE_MODE (TREE_TYPE (argtype));
6270                 rtx mem = gen_rtx_MEM (indmode, x);
6271                 cselib_val *val = cselib_lookup (mem, indmode, 0, VOIDmode);
6272                 if (val && cselib_preserved_value_p (val))
6273                   {
6274                     item = gen_rtx_CONCAT (indmode, mem, val->val_rtx);
6275                     call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
6276                                                         call_arguments);
6277                   }
6278                 else
6279                   {
6280                     struct elt_loc_list *l;
6281                     tree initial;
6282
6283                     /* Try harder, when passing address of a constant
6284                        pool integer it can be easily read back.  */
6285                     item = XEXP (item, 1);
6286                     if (GET_CODE (item) == SUBREG)
6287                       item = SUBREG_REG (item);
6288                     gcc_assert (GET_CODE (item) == VALUE);
6289                     val = CSELIB_VAL_PTR (item);
6290                     for (l = val->locs; l; l = l->next)
6291                       if (GET_CODE (l->loc) == SYMBOL_REF
6292                           && TREE_CONSTANT_POOL_ADDRESS_P (l->loc)
6293                           && SYMBOL_REF_DECL (l->loc)
6294                           && DECL_INITIAL (SYMBOL_REF_DECL (l->loc)))
6295                         {
6296                           initial = DECL_INITIAL (SYMBOL_REF_DECL (l->loc));
6297                           if (tree_fits_shwi_p (initial))
6298                             {
6299                               item = GEN_INT (tree_to_shwi (initial));
6300                               item = gen_rtx_CONCAT (indmode, mem, item);
6301                               call_arguments
6302                                 = gen_rtx_EXPR_LIST (VOIDmode, item,
6303                                                      call_arguments);
6304                             }
6305                           break;
6306                         }
6307                   }
6308               }
6309             targetm.calls.function_arg_advance (args_so_far, mode,
6310                                                 argtype, true);
6311             t = TREE_CHAIN (t);
6312           }
6313       }
6314
6315   /* Add debug arguments.  */
6316   if (fndecl
6317       && TREE_CODE (fndecl) == FUNCTION_DECL
6318       && DECL_HAS_DEBUG_ARGS_P (fndecl))
6319     {
6320       vec<tree, va_gc> **debug_args = decl_debug_args_lookup (fndecl);
6321       if (debug_args)
6322         {
6323           unsigned int ix;
6324           tree param;
6325           for (ix = 0; vec_safe_iterate (*debug_args, ix, &param); ix += 2)
6326             {
6327               rtx item;
6328               tree dtemp = (**debug_args)[ix + 1];
6329               enum machine_mode mode = DECL_MODE (dtemp);
6330               item = gen_rtx_DEBUG_PARAMETER_REF (mode, param);
6331               item = gen_rtx_CONCAT (mode, item, DECL_RTL_KNOWN_SET (dtemp));
6332               call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
6333                                                   call_arguments);
6334             }
6335         }
6336     }
6337
6338   /* Reverse call_arguments chain.  */
6339   prev = NULL_RTX;
6340   for (cur = call_arguments; cur; cur = next)
6341     {
6342       next = XEXP (cur, 1);
6343       XEXP (cur, 1) = prev;
6344       prev = cur;
6345     }
6346   call_arguments = prev;
6347
6348   x = get_call_rtx_from (insn);
6349   if (x)
6350     {
6351       x = XEXP (XEXP (x, 0), 0);
6352       if (GET_CODE (x) == SYMBOL_REF)
6353         /* Don't record anything.  */;
6354       else if (CONSTANT_P (x))
6355         {
6356           x = gen_rtx_CONCAT (GET_MODE (x) == VOIDmode ? Pmode : GET_MODE (x),
6357                               pc_rtx, x);
6358           call_arguments
6359             = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
6360         }
6361       else
6362         {
6363           cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
6364           if (val && cselib_preserved_value_p (val))
6365             {
6366               x = gen_rtx_CONCAT (GET_MODE (x), pc_rtx, val->val_rtx);
6367               call_arguments
6368                 = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
6369             }
6370         }
6371     }
6372   if (this_arg)
6373     {
6374       enum machine_mode mode
6375         = TYPE_MODE (TREE_TYPE (OBJ_TYPE_REF_EXPR (obj_type_ref)));
6376       rtx clobbered = gen_rtx_MEM (mode, this_arg);
6377       HOST_WIDE_INT token
6378         = tree_to_shwi (OBJ_TYPE_REF_TOKEN (obj_type_ref));
6379       if (token)
6380         clobbered = plus_constant (mode, clobbered,
6381                                    token * GET_MODE_SIZE (mode));
6382       clobbered = gen_rtx_MEM (mode, clobbered);
6383       x = gen_rtx_CONCAT (mode, gen_rtx_CLOBBER (VOIDmode, pc_rtx), clobbered);
6384       call_arguments
6385         = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
6386     }
6387 }
6388
6389 /* Callback for cselib_record_sets_hook, that records as micro
6390    operations uses and stores in an insn after cselib_record_sets has
6391    analyzed the sets in an insn, but before it modifies the stored
6392    values in the internal tables, unless cselib_record_sets doesn't
6393    call it directly (perhaps because we're not doing cselib in the
6394    first place, in which case sets and n_sets will be 0).  */
6395
6396 static void
6397 add_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
6398 {
6399   basic_block bb = BLOCK_FOR_INSN (insn);
6400   int n1, n2;
6401   struct count_use_info cui;
6402   micro_operation *mos;
6403
6404   cselib_hook_called = true;
6405
6406   cui.insn = insn;
6407   cui.bb = bb;
6408   cui.sets = sets;
6409   cui.n_sets = n_sets;
6410
6411   n1 = VTI (bb)->mos.length ();
6412   cui.store_p = false;
6413   note_uses (&PATTERN (insn), add_uses_1, &cui);
6414   n2 = VTI (bb)->mos.length () - 1;
6415   mos = VTI (bb)->mos.address ();
6416
6417   /* Order the MO_USEs to be before MO_USE_NO_VARs and MO_VAL_USE, and
6418      MO_VAL_LOC last.  */
6419   while (n1 < n2)
6420     {
6421       while (n1 < n2 && mos[n1].type == MO_USE)
6422         n1++;
6423       while (n1 < n2 && mos[n2].type != MO_USE)
6424         n2--;
6425       if (n1 < n2)
6426         {
6427           micro_operation sw;
6428
6429           sw = mos[n1];
6430           mos[n1] = mos[n2];
6431           mos[n2] = sw;
6432         }
6433     }
6434
6435   n2 = VTI (bb)->mos.length () - 1;
6436   while (n1 < n2)
6437     {
6438       while (n1 < n2 && mos[n1].type != MO_VAL_LOC)
6439         n1++;
6440       while (n1 < n2 && mos[n2].type == MO_VAL_LOC)
6441         n2--;
6442       if (n1 < n2)
6443         {
6444           micro_operation sw;
6445
6446           sw = mos[n1];
6447           mos[n1] = mos[n2];
6448           mos[n2] = sw;
6449         }
6450     }
6451
6452   if (CALL_P (insn))
6453     {
6454       micro_operation mo;
6455
6456       mo.type = MO_CALL;
6457       mo.insn = insn;
6458       mo.u.loc = call_arguments;
6459       call_arguments = NULL_RTX;
6460
6461       if (dump_file && (dump_flags & TDF_DETAILS))
6462         log_op_type (PATTERN (insn), bb, insn, mo.type, dump_file);
6463       VTI (bb)->mos.safe_push (mo);
6464     }
6465
6466   n1 = VTI (bb)->mos.length ();
6467   /* This will record NEXT_INSN (insn), such that we can
6468      insert notes before it without worrying about any
6469      notes that MO_USEs might emit after the insn.  */
6470   cui.store_p = true;
6471   note_stores (PATTERN (insn), add_stores, &cui);
6472   n2 = VTI (bb)->mos.length () - 1;
6473   mos = VTI (bb)->mos.address ();
6474
6475   /* Order the MO_VAL_USEs first (note_stores does nothing
6476      on DEBUG_INSNs, so there are no MO_VAL_LOCs from this
6477      insn), then MO_CLOBBERs, then MO_SET/MO_COPY/MO_VAL_SET.  */
6478   while (n1 < n2)
6479     {
6480       while (n1 < n2 && mos[n1].type == MO_VAL_USE)
6481         n1++;
6482       while (n1 < n2 && mos[n2].type != MO_VAL_USE)
6483         n2--;
6484       if (n1 < n2)
6485         {
6486           micro_operation sw;
6487
6488           sw = mos[n1];
6489           mos[n1] = mos[n2];
6490           mos[n2] = sw;
6491         }
6492     }
6493
6494   n2 = VTI (bb)->mos.length () - 1;
6495   while (n1 < n2)
6496     {
6497       while (n1 < n2 && mos[n1].type == MO_CLOBBER)
6498         n1++;
6499       while (n1 < n2 && mos[n2].type != MO_CLOBBER)
6500         n2--;
6501       if (n1 < n2)
6502         {
6503           micro_operation sw;
6504
6505           sw = mos[n1];
6506           mos[n1] = mos[n2];
6507           mos[n2] = sw;
6508         }
6509     }
6510 }
6511
6512 static enum var_init_status
6513 find_src_status (dataflow_set *in, rtx src)
6514 {
6515   tree decl = NULL_TREE;
6516   enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
6517
6518   if (! flag_var_tracking_uninit)
6519     status = VAR_INIT_STATUS_INITIALIZED;
6520
6521   if (src && REG_P (src))
6522     decl = var_debug_decl (REG_EXPR (src));
6523   else if (src && MEM_P (src))
6524     decl = var_debug_decl (MEM_EXPR (src));
6525
6526   if (src && decl)
6527     status = get_init_value (in, src, dv_from_decl (decl));
6528
6529   return status;
6530 }
6531
6532 /* SRC is the source of an assignment.  Use SET to try to find what
6533    was ultimately assigned to SRC.  Return that value if known,
6534    otherwise return SRC itself.  */
6535
6536 static rtx
6537 find_src_set_src (dataflow_set *set, rtx src)
6538 {
6539   tree decl = NULL_TREE;   /* The variable being copied around.          */
6540   rtx set_src = NULL_RTX;  /* The value for "decl" stored in "src".      */
6541   variable var;
6542   location_chain nextp;
6543   int i;
6544   bool found;
6545
6546   if (src && REG_P (src))
6547     decl = var_debug_decl (REG_EXPR (src));
6548   else if (src && MEM_P (src))
6549     decl = var_debug_decl (MEM_EXPR (src));
6550
6551   if (src && decl)
6552     {
6553       decl_or_value dv = dv_from_decl (decl);
6554
6555       var = shared_hash_find (set->vars, dv);
6556       if (var)
6557         {
6558           found = false;
6559           for (i = 0; i < var->n_var_parts && !found; i++)
6560             for (nextp = var->var_part[i].loc_chain; nextp && !found;
6561                  nextp = nextp->next)
6562               if (rtx_equal_p (nextp->loc, src))
6563                 {
6564                   set_src = nextp->set_src;
6565                   found = true;
6566                 }
6567
6568         }
6569     }
6570
6571   return set_src;
6572 }
6573
6574 /* Compute the changes of variable locations in the basic block BB.  */
6575
6576 static bool
6577 compute_bb_dataflow (basic_block bb)
6578 {
6579   unsigned int i;
6580   micro_operation *mo;
6581   bool changed;
6582   dataflow_set old_out;
6583   dataflow_set *in = &VTI (bb)->in;
6584   dataflow_set *out = &VTI (bb)->out;
6585
6586   dataflow_set_init (&old_out);
6587   dataflow_set_copy (&old_out, out);
6588   dataflow_set_copy (out, in);
6589
6590   if (MAY_HAVE_DEBUG_INSNS)
6591     local_get_addr_cache = pointer_map_create ();
6592
6593   FOR_EACH_VEC_ELT (VTI (bb)->mos, i, mo)
6594     {
6595       rtx insn = mo->insn;
6596
6597       switch (mo->type)
6598         {
6599           case MO_CALL:
6600             dataflow_set_clear_at_call (out);
6601             break;
6602
6603           case MO_USE:
6604             {
6605               rtx loc = mo->u.loc;
6606
6607               if (REG_P (loc))
6608                 var_reg_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6609               else if (MEM_P (loc))
6610                 var_mem_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6611             }
6612             break;
6613
6614           case MO_VAL_LOC:
6615             {
6616               rtx loc = mo->u.loc;
6617               rtx val, vloc;
6618               tree var;
6619
6620               if (GET_CODE (loc) == CONCAT)
6621                 {
6622                   val = XEXP (loc, 0);
6623                   vloc = XEXP (loc, 1);
6624                 }
6625               else
6626                 {
6627                   val = NULL_RTX;
6628                   vloc = loc;
6629                 }
6630
6631               var = PAT_VAR_LOCATION_DECL (vloc);
6632
6633               clobber_variable_part (out, NULL_RTX,
6634                                      dv_from_decl (var), 0, NULL_RTX);
6635               if (val)
6636                 {
6637                   if (VAL_NEEDS_RESOLUTION (loc))
6638                     val_resolve (out, val, PAT_VAR_LOCATION_LOC (vloc), insn);
6639                   set_variable_part (out, val, dv_from_decl (var), 0,
6640                                      VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
6641                                      INSERT);
6642                 }
6643               else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
6644                 set_variable_part (out, PAT_VAR_LOCATION_LOC (vloc),
6645                                    dv_from_decl (var), 0,
6646                                    VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
6647                                    INSERT);
6648             }
6649             break;
6650
6651           case MO_VAL_USE:
6652             {
6653               rtx loc = mo->u.loc;
6654               rtx val, vloc, uloc;
6655
6656               vloc = uloc = XEXP (loc, 1);
6657               val = XEXP (loc, 0);
6658
6659               if (GET_CODE (val) == CONCAT)
6660                 {
6661                   uloc = XEXP (val, 1);
6662                   val = XEXP (val, 0);
6663                 }
6664
6665               if (VAL_NEEDS_RESOLUTION (loc))
6666                 val_resolve (out, val, vloc, insn);
6667               else
6668                 val_store (out, val, uloc, insn, false);
6669
6670               if (VAL_HOLDS_TRACK_EXPR (loc))
6671                 {
6672                   if (GET_CODE (uloc) == REG)
6673                     var_reg_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6674                                  NULL);
6675                   else if (GET_CODE (uloc) == MEM)
6676                     var_mem_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6677                                  NULL);
6678                 }
6679             }
6680             break;
6681
6682           case MO_VAL_SET:
6683             {
6684               rtx loc = mo->u.loc;
6685               rtx val, vloc, uloc;
6686               rtx dstv, srcv;
6687
6688               vloc = loc;
6689               uloc = XEXP (vloc, 1);
6690               val = XEXP (vloc, 0);
6691               vloc = uloc;
6692
6693               if (GET_CODE (uloc) == SET)
6694                 {
6695                   dstv = SET_DEST (uloc);
6696                   srcv = SET_SRC (uloc);
6697                 }
6698               else
6699                 {
6700                   dstv = uloc;
6701                   srcv = NULL;
6702                 }
6703
6704               if (GET_CODE (val) == CONCAT)
6705                 {
6706                   dstv = vloc = XEXP (val, 1);
6707                   val = XEXP (val, 0);
6708                 }
6709
6710               if (GET_CODE (vloc) == SET)
6711                 {
6712                   srcv = SET_SRC (vloc);
6713
6714                   gcc_assert (val != srcv);
6715                   gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
6716
6717                   dstv = vloc = SET_DEST (vloc);
6718
6719                   if (VAL_NEEDS_RESOLUTION (loc))
6720                     val_resolve (out, val, srcv, insn);
6721                 }
6722               else if (VAL_NEEDS_RESOLUTION (loc))
6723                 {
6724                   gcc_assert (GET_CODE (uloc) == SET
6725                               && GET_CODE (SET_SRC (uloc)) == REG);
6726                   val_resolve (out, val, SET_SRC (uloc), insn);
6727                 }
6728
6729               if (VAL_HOLDS_TRACK_EXPR (loc))
6730                 {
6731                   if (VAL_EXPR_IS_CLOBBERED (loc))
6732                     {
6733                       if (REG_P (uloc))
6734                         var_reg_delete (out, uloc, true);
6735                       else if (MEM_P (uloc))
6736                         {
6737                           gcc_assert (MEM_P (dstv));
6738                           gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (uloc));
6739                           var_mem_delete (out, dstv, true);
6740                         }
6741                     }
6742                   else
6743                     {
6744                       bool copied_p = VAL_EXPR_IS_COPIED (loc);
6745                       rtx src = NULL, dst = uloc;
6746                       enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
6747
6748                       if (GET_CODE (uloc) == SET)
6749                         {
6750                           src = SET_SRC (uloc);
6751                           dst = SET_DEST (uloc);
6752                         }
6753
6754                       if (copied_p)
6755                         {
6756                           if (flag_var_tracking_uninit)
6757                             {
6758                               status = find_src_status (in, src);
6759
6760                               if (status == VAR_INIT_STATUS_UNKNOWN)
6761                                 status = find_src_status (out, src);
6762                             }
6763
6764                           src = find_src_set_src (in, src);
6765                         }
6766
6767                       if (REG_P (dst))
6768                         var_reg_delete_and_set (out, dst, !copied_p,
6769                                                 status, srcv);
6770                       else if (MEM_P (dst))
6771                         {
6772                           gcc_assert (MEM_P (dstv));
6773                           gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (dst));
6774                           var_mem_delete_and_set (out, dstv, !copied_p,
6775                                                   status, srcv);
6776                         }
6777                     }
6778                 }
6779               else if (REG_P (uloc))
6780                 var_regno_delete (out, REGNO (uloc));
6781               else if (MEM_P (uloc))
6782                 {
6783                   gcc_checking_assert (GET_CODE (vloc) == MEM);
6784                   gcc_checking_assert (dstv == vloc);
6785                   if (dstv != vloc)
6786                     clobber_overlapping_mems (out, vloc);
6787                 }
6788
6789               val_store (out, val, dstv, insn, true);
6790             }
6791             break;
6792
6793           case MO_SET:
6794             {
6795               rtx loc = mo->u.loc;
6796               rtx set_src = NULL;
6797
6798               if (GET_CODE (loc) == SET)
6799                 {
6800                   set_src = SET_SRC (loc);
6801                   loc = SET_DEST (loc);
6802                 }
6803
6804               if (REG_P (loc))
6805                 var_reg_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
6806                                         set_src);
6807               else if (MEM_P (loc))
6808                 var_mem_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
6809                                         set_src);
6810             }
6811             break;
6812
6813           case MO_COPY:
6814             {
6815               rtx loc = mo->u.loc;
6816               enum var_init_status src_status;
6817               rtx set_src = NULL;
6818
6819               if (GET_CODE (loc) == SET)
6820                 {
6821                   set_src = SET_SRC (loc);
6822                   loc = SET_DEST (loc);
6823                 }
6824
6825               if (! flag_var_tracking_uninit)
6826                 src_status = VAR_INIT_STATUS_INITIALIZED;
6827               else
6828                 {
6829                   src_status = find_src_status (in, set_src);
6830
6831                   if (src_status == VAR_INIT_STATUS_UNKNOWN)
6832                     src_status = find_src_status (out, set_src);
6833                 }
6834
6835               set_src = find_src_set_src (in, set_src);
6836
6837               if (REG_P (loc))
6838                 var_reg_delete_and_set (out, loc, false, src_status, set_src);
6839               else if (MEM_P (loc))
6840                 var_mem_delete_and_set (out, loc, false, src_status, set_src);
6841             }
6842             break;
6843
6844           case MO_USE_NO_VAR:
6845             {
6846               rtx loc = mo->u.loc;
6847
6848               if (REG_P (loc))
6849                 var_reg_delete (out, loc, false);
6850               else if (MEM_P (loc))
6851                 var_mem_delete (out, loc, false);
6852             }
6853             break;
6854
6855           case MO_CLOBBER:
6856             {
6857               rtx loc = mo->u.loc;
6858
6859               if (REG_P (loc))
6860                 var_reg_delete (out, loc, true);
6861               else if (MEM_P (loc))
6862                 var_mem_delete (out, loc, true);
6863             }
6864             break;
6865
6866           case MO_ADJUST:
6867             out->stack_adjust += mo->u.adjust;
6868             break;
6869         }
6870     }
6871
6872   if (MAY_HAVE_DEBUG_INSNS)
6873     {
6874       pointer_map_destroy (local_get_addr_cache);
6875       local_get_addr_cache = NULL;
6876
6877       dataflow_set_equiv_regs (out);
6878       shared_hash_htab (out->vars)
6879         .traverse <dataflow_set *, canonicalize_values_mark> (out);
6880       shared_hash_htab (out->vars)
6881         .traverse <dataflow_set *, canonicalize_values_star> (out);
6882 #if ENABLE_CHECKING
6883       shared_hash_htab (out->vars)
6884         .traverse <dataflow_set *, canonicalize_loc_order_check> (out);
6885 #endif
6886     }
6887   changed = dataflow_set_different (&old_out, out);
6888   dataflow_set_destroy (&old_out);
6889   return changed;
6890 }
6891
6892 /* Find the locations of variables in the whole function.  */
6893
6894 static bool
6895 vt_find_locations (void)
6896 {
6897   fibheap_t worklist, pending, fibheap_swap;
6898   sbitmap visited, in_worklist, in_pending, sbitmap_swap;
6899   basic_block bb;
6900   edge e;
6901   int *bb_order;
6902   int *rc_order;
6903   int i;
6904   int htabsz = 0;
6905   int htabmax = PARAM_VALUE (PARAM_MAX_VARTRACK_SIZE);
6906   bool success = true;
6907
6908   timevar_push (TV_VAR_TRACKING_DATAFLOW);
6909   /* Compute reverse completion order of depth first search of the CFG
6910      so that the data-flow runs faster.  */
6911   rc_order = XNEWVEC (int, n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS);
6912   bb_order = XNEWVEC (int, last_basic_block);
6913   pre_and_rev_post_order_compute (NULL, rc_order, false);
6914   for (i = 0; i < n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS; i++)
6915     bb_order[rc_order[i]] = i;
6916   free (rc_order);
6917
6918   worklist = fibheap_new ();
6919   pending = fibheap_new ();
6920   visited = sbitmap_alloc (last_basic_block);
6921   in_worklist = sbitmap_alloc (last_basic_block);
6922   in_pending = sbitmap_alloc (last_basic_block);
6923   bitmap_clear (in_worklist);
6924
6925   FOR_EACH_BB (bb)
6926     fibheap_insert (pending, bb_order[bb->index], bb);
6927   bitmap_ones (in_pending);
6928
6929   while (success && !fibheap_empty (pending))
6930     {
6931       fibheap_swap = pending;
6932       pending = worklist;
6933       worklist = fibheap_swap;
6934       sbitmap_swap = in_pending;
6935       in_pending = in_worklist;
6936       in_worklist = sbitmap_swap;
6937
6938       bitmap_clear (visited);
6939
6940       while (!fibheap_empty (worklist))
6941         {
6942           bb = (basic_block) fibheap_extract_min (worklist);
6943           bitmap_clear_bit (in_worklist, bb->index);
6944           gcc_assert (!bitmap_bit_p (visited, bb->index));
6945           if (!bitmap_bit_p (visited, bb->index))
6946             {
6947               bool changed;
6948               edge_iterator ei;
6949               int oldinsz, oldoutsz;
6950
6951               bitmap_set_bit (visited, bb->index);
6952
6953               if (VTI (bb)->in.vars)
6954                 {
6955                   htabsz
6956                     -= shared_hash_htab (VTI (bb)->in.vars).size ()
6957                         + shared_hash_htab (VTI (bb)->out.vars).size ();
6958                   oldinsz = shared_hash_htab (VTI (bb)->in.vars).elements ();
6959                   oldoutsz = shared_hash_htab (VTI (bb)->out.vars).elements ();
6960                 }
6961               else
6962                 oldinsz = oldoutsz = 0;
6963
6964               if (MAY_HAVE_DEBUG_INSNS)
6965                 {
6966                   dataflow_set *in = &VTI (bb)->in, *first_out = NULL;
6967                   bool first = true, adjust = false;
6968
6969                   /* Calculate the IN set as the intersection of
6970                      predecessor OUT sets.  */
6971
6972                   dataflow_set_clear (in);
6973                   dst_can_be_shared = true;
6974
6975                   FOR_EACH_EDGE (e, ei, bb->preds)
6976                     if (!VTI (e->src)->flooded)
6977                       gcc_assert (bb_order[bb->index]
6978                                   <= bb_order[e->src->index]);
6979                     else if (first)
6980                       {
6981                         dataflow_set_copy (in, &VTI (e->src)->out);
6982                         first_out = &VTI (e->src)->out;
6983                         first = false;
6984                       }
6985                     else
6986                       {
6987                         dataflow_set_merge (in, &VTI (e->src)->out);
6988                         adjust = true;
6989                       }
6990
6991                   if (adjust)
6992                     {
6993                       dataflow_post_merge_adjust (in, &VTI (bb)->permp);
6994 #if ENABLE_CHECKING
6995                       /* Merge and merge_adjust should keep entries in
6996                          canonical order.  */
6997                       shared_hash_htab (in->vars)
6998                         .traverse <dataflow_set *,
6999                                    canonicalize_loc_order_check> (in);
7000 #endif
7001                       if (dst_can_be_shared)
7002                         {
7003                           shared_hash_destroy (in->vars);
7004                           in->vars = shared_hash_copy (first_out->vars);
7005                         }
7006                     }
7007
7008                   VTI (bb)->flooded = true;
7009                 }
7010               else
7011                 {
7012                   /* Calculate the IN set as union of predecessor OUT sets.  */
7013                   dataflow_set_clear (&VTI (bb)->in);
7014                   FOR_EACH_EDGE (e, ei, bb->preds)
7015                     dataflow_set_union (&VTI (bb)->in, &VTI (e->src)->out);
7016                 }
7017
7018               changed = compute_bb_dataflow (bb);
7019               htabsz += shared_hash_htab (VTI (bb)->in.vars).size ()
7020                          + shared_hash_htab (VTI (bb)->out.vars).size ();
7021
7022               if (htabmax && htabsz > htabmax)
7023                 {
7024                   if (MAY_HAVE_DEBUG_INSNS)
7025                     inform (DECL_SOURCE_LOCATION (cfun->decl),
7026                             "variable tracking size limit exceeded with "
7027                             "-fvar-tracking-assignments, retrying without");
7028                   else
7029                     inform (DECL_SOURCE_LOCATION (cfun->decl),
7030                             "variable tracking size limit exceeded");
7031                   success = false;
7032                   break;
7033                 }
7034
7035               if (changed)
7036                 {
7037                   FOR_EACH_EDGE (e, ei, bb->succs)
7038                     {
7039                       if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
7040                         continue;
7041
7042                       if (bitmap_bit_p (visited, e->dest->index))
7043                         {
7044                           if (!bitmap_bit_p (in_pending, e->dest->index))
7045                             {
7046                               /* Send E->DEST to next round.  */
7047                               bitmap_set_bit (in_pending, e->dest->index);
7048                               fibheap_insert (pending,
7049                                               bb_order[e->dest->index],
7050                                               e->dest);
7051                             }
7052                         }
7053                       else if (!bitmap_bit_p (in_worklist, e->dest->index))
7054                         {
7055                           /* Add E->DEST to current round.  */
7056                           bitmap_set_bit (in_worklist, e->dest->index);
7057                           fibheap_insert (worklist, bb_order[e->dest->index],
7058                                           e->dest);
7059                         }
7060                     }
7061                 }
7062
7063               if (dump_file)
7064                 fprintf (dump_file,
7065                          "BB %i: in %i (was %i), out %i (was %i), rem %i + %i, tsz %i\n",
7066                          bb->index,
7067                          (int)shared_hash_htab (VTI (bb)->in.vars).size (),
7068                          oldinsz,
7069                          (int)shared_hash_htab (VTI (bb)->out.vars).size (),
7070                          oldoutsz,
7071                          (int)worklist->nodes, (int)pending->nodes, htabsz);
7072
7073               if (dump_file && (dump_flags & TDF_DETAILS))
7074                 {
7075                   fprintf (dump_file, "BB %i IN:\n", bb->index);
7076                   dump_dataflow_set (&VTI (bb)->in);
7077                   fprintf (dump_file, "BB %i OUT:\n", bb->index);
7078                   dump_dataflow_set (&VTI (bb)->out);
7079                 }
7080             }
7081         }
7082     }
7083
7084   if (success && MAY_HAVE_DEBUG_INSNS)
7085     FOR_EACH_BB (bb)
7086       gcc_assert (VTI (bb)->flooded);
7087
7088   free (bb_order);
7089   fibheap_delete (worklist);
7090   fibheap_delete (pending);
7091   sbitmap_free (visited);
7092   sbitmap_free (in_worklist);
7093   sbitmap_free (in_pending);
7094
7095   timevar_pop (TV_VAR_TRACKING_DATAFLOW);
7096   return success;
7097 }
7098
7099 /* Print the content of the LIST to dump file.  */
7100
7101 static void
7102 dump_attrs_list (attrs list)
7103 {
7104   for (; list; list = list->next)
7105     {
7106       if (dv_is_decl_p (list->dv))
7107         print_mem_expr (dump_file, dv_as_decl (list->dv));
7108       else
7109         print_rtl_single (dump_file, dv_as_value (list->dv));
7110       fprintf (dump_file, "+" HOST_WIDE_INT_PRINT_DEC, list->offset);
7111     }
7112   fprintf (dump_file, "\n");
7113 }
7114
7115 /* Print the information about variable *SLOT to dump file.  */
7116
7117 int
7118 dump_var_tracking_slot (variable_def **slot, void *data ATTRIBUTE_UNUSED)
7119 {
7120   variable var = *slot;
7121
7122   dump_var (var);
7123
7124   /* Continue traversing the hash table.  */
7125   return 1;
7126 }
7127
7128 /* Print the information about variable VAR to dump file.  */
7129
7130 static void
7131 dump_var (variable var)
7132 {
7133   int i;
7134   location_chain node;
7135
7136   if (dv_is_decl_p (var->dv))
7137     {
7138       const_tree decl = dv_as_decl (var->dv);
7139
7140       if (DECL_NAME (decl))
7141         {
7142           fprintf (dump_file, "  name: %s",
7143                    IDENTIFIER_POINTER (DECL_NAME (decl)));
7144           if (dump_flags & TDF_UID)
7145             fprintf (dump_file, "D.%u", DECL_UID (decl));
7146         }
7147       else if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
7148         fprintf (dump_file, "  name: D#%u", DEBUG_TEMP_UID (decl));
7149       else
7150         fprintf (dump_file, "  name: D.%u", DECL_UID (decl));
7151       fprintf (dump_file, "\n");
7152     }
7153   else
7154     {
7155       fputc (' ', dump_file);
7156       print_rtl_single (dump_file, dv_as_value (var->dv));
7157     }
7158
7159   for (i = 0; i < var->n_var_parts; i++)
7160     {
7161       fprintf (dump_file, "    offset %ld\n",
7162                (long)(var->onepart ? 0 : VAR_PART_OFFSET (var, i)));
7163       for (node = var->var_part[i].loc_chain; node; node = node->next)
7164         {
7165           fprintf (dump_file, "      ");
7166           if (node->init == VAR_INIT_STATUS_UNINITIALIZED)
7167             fprintf (dump_file, "[uninit]");
7168           print_rtl_single (dump_file, node->loc);
7169         }
7170     }
7171 }
7172
7173 /* Print the information about variables from hash table VARS to dump file.  */
7174
7175 static void
7176 dump_vars (variable_table_type vars)
7177 {
7178   if (vars.elements () > 0)
7179     {
7180       fprintf (dump_file, "Variables:\n");
7181       vars.traverse <void *, dump_var_tracking_slot> (NULL);
7182     }
7183 }
7184
7185 /* Print the dataflow set SET to dump file.  */
7186
7187 static void
7188 dump_dataflow_set (dataflow_set *set)
7189 {
7190   int i;
7191
7192   fprintf (dump_file, "Stack adjustment: " HOST_WIDE_INT_PRINT_DEC "\n",
7193            set->stack_adjust);
7194   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
7195     {
7196       if (set->regs[i])
7197         {
7198           fprintf (dump_file, "Reg %d:", i);
7199           dump_attrs_list (set->regs[i]);
7200         }
7201     }
7202   dump_vars (shared_hash_htab (set->vars));
7203   fprintf (dump_file, "\n");
7204 }
7205
7206 /* Print the IN and OUT sets for each basic block to dump file.  */
7207
7208 static void
7209 dump_dataflow_sets (void)
7210 {
7211   basic_block bb;
7212
7213   FOR_EACH_BB (bb)
7214     {
7215       fprintf (dump_file, "\nBasic block %d:\n", bb->index);
7216       fprintf (dump_file, "IN:\n");
7217       dump_dataflow_set (&VTI (bb)->in);
7218       fprintf (dump_file, "OUT:\n");
7219       dump_dataflow_set (&VTI (bb)->out);
7220     }
7221 }
7222
7223 /* Return the variable for DV in dropped_values, inserting one if
7224    requested with INSERT.  */
7225
7226 static inline variable
7227 variable_from_dropped (decl_or_value dv, enum insert_option insert)
7228 {
7229   variable_def **slot;
7230   variable empty_var;
7231   onepart_enum_t onepart;
7232
7233   slot = dropped_values.find_slot_with_hash (dv, dv_htab_hash (dv), insert);
7234
7235   if (!slot)
7236     return NULL;
7237
7238   if (*slot)
7239     return *slot;
7240
7241   gcc_checking_assert (insert == INSERT);
7242
7243   onepart = dv_onepart_p (dv);
7244
7245   gcc_checking_assert (onepart == ONEPART_VALUE || onepart == ONEPART_DEXPR);
7246
7247   empty_var = (variable) pool_alloc (onepart_pool (onepart));
7248   empty_var->dv = dv;
7249   empty_var->refcount = 1;
7250   empty_var->n_var_parts = 0;
7251   empty_var->onepart = onepart;
7252   empty_var->in_changed_variables = false;
7253   empty_var->var_part[0].loc_chain = NULL;
7254   empty_var->var_part[0].cur_loc = NULL;
7255   VAR_LOC_1PAUX (empty_var) = NULL;
7256   set_dv_changed (dv, true);
7257
7258   *slot = empty_var;
7259
7260   return empty_var;
7261 }
7262
7263 /* Recover the one-part aux from dropped_values.  */
7264
7265 static struct onepart_aux *
7266 recover_dropped_1paux (variable var)
7267 {
7268   variable dvar;
7269
7270   gcc_checking_assert (var->onepart);
7271
7272   if (VAR_LOC_1PAUX (var))
7273     return VAR_LOC_1PAUX (var);
7274
7275   if (var->onepart == ONEPART_VDECL)
7276     return NULL;
7277
7278   dvar = variable_from_dropped (var->dv, NO_INSERT);
7279
7280   if (!dvar)
7281     return NULL;
7282
7283   VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (dvar);
7284   VAR_LOC_1PAUX (dvar) = NULL;
7285
7286   return VAR_LOC_1PAUX (var);
7287 }
7288
7289 /* Add variable VAR to the hash table of changed variables and
7290    if it has no locations delete it from SET's hash table.  */
7291
7292 static void
7293 variable_was_changed (variable var, dataflow_set *set)
7294 {
7295   hashval_t hash = dv_htab_hash (var->dv);
7296
7297   if (emit_notes)
7298     {
7299       variable_def **slot;
7300
7301       /* Remember this decl or VALUE has been added to changed_variables.  */
7302       set_dv_changed (var->dv, true);
7303
7304       slot = changed_variables.find_slot_with_hash (var->dv, hash, INSERT);
7305
7306       if (*slot)
7307         {
7308           variable old_var = *slot;
7309           gcc_assert (old_var->in_changed_variables);
7310           old_var->in_changed_variables = false;
7311           if (var != old_var && var->onepart)
7312             {
7313               /* Restore the auxiliary info from an empty variable
7314                  previously created for changed_variables, so it is
7315                  not lost.  */
7316               gcc_checking_assert (!VAR_LOC_1PAUX (var));
7317               VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (old_var);
7318               VAR_LOC_1PAUX (old_var) = NULL;
7319             }
7320           variable_htab_free (*slot);
7321         }
7322
7323       if (set && var->n_var_parts == 0)
7324         {
7325           onepart_enum_t onepart = var->onepart;
7326           variable empty_var = NULL;
7327           variable_def **dslot = NULL;
7328
7329           if (onepart == ONEPART_VALUE || onepart == ONEPART_DEXPR)
7330             {
7331               dslot = dropped_values.find_slot_with_hash (var->dv,
7332                                                 dv_htab_hash (var->dv),
7333                                                 INSERT);
7334               empty_var = *dslot;
7335
7336               if (empty_var)
7337                 {
7338                   gcc_checking_assert (!empty_var->in_changed_variables);
7339                   if (!VAR_LOC_1PAUX (var))
7340                     {
7341                       VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (empty_var);
7342                       VAR_LOC_1PAUX (empty_var) = NULL;
7343                     }
7344                   else
7345                     gcc_checking_assert (!VAR_LOC_1PAUX (empty_var));
7346                 }
7347             }
7348
7349           if (!empty_var)
7350             {
7351               empty_var = (variable) pool_alloc (onepart_pool (onepart));
7352               empty_var->dv = var->dv;
7353               empty_var->refcount = 1;
7354               empty_var->n_var_parts = 0;
7355               empty_var->onepart = onepart;
7356               if (dslot)
7357                 {
7358                   empty_var->refcount++;
7359                   *dslot = empty_var;
7360                 }
7361             }
7362           else
7363             empty_var->refcount++;
7364           empty_var->in_changed_variables = true;
7365           *slot = empty_var;
7366           if (onepart)
7367             {
7368               empty_var->var_part[0].loc_chain = NULL;
7369               empty_var->var_part[0].cur_loc = NULL;
7370               VAR_LOC_1PAUX (empty_var) = VAR_LOC_1PAUX (var);
7371               VAR_LOC_1PAUX (var) = NULL;
7372             }
7373           goto drop_var;
7374         }
7375       else
7376         {
7377           if (var->onepart && !VAR_LOC_1PAUX (var))
7378             recover_dropped_1paux (var);
7379           var->refcount++;
7380           var->in_changed_variables = true;
7381           *slot = var;
7382         }
7383     }
7384   else
7385     {
7386       gcc_assert (set);
7387       if (var->n_var_parts == 0)
7388         {
7389           variable_def **slot;
7390
7391         drop_var:
7392           slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
7393           if (slot)
7394             {
7395               if (shared_hash_shared (set->vars))
7396                 slot = shared_hash_find_slot_unshare (&set->vars, var->dv,
7397                                                       NO_INSERT);
7398               shared_hash_htab (set->vars).clear_slot (slot);
7399             }
7400         }
7401     }
7402 }
7403
7404 /* Look for the index in VAR->var_part corresponding to OFFSET.
7405    Return -1 if not found.  If INSERTION_POINT is non-NULL, the
7406    referenced int will be set to the index that the part has or should
7407    have, if it should be inserted.  */
7408
7409 static inline int
7410 find_variable_location_part (variable var, HOST_WIDE_INT offset,
7411                              int *insertion_point)
7412 {
7413   int pos, low, high;
7414
7415   if (var->onepart)
7416     {
7417       if (offset != 0)
7418         return -1;
7419
7420       if (insertion_point)
7421         *insertion_point = 0;
7422
7423       return var->n_var_parts - 1;
7424     }
7425
7426   /* Find the location part.  */
7427   low = 0;
7428   high = var->n_var_parts;
7429   while (low != high)
7430     {
7431       pos = (low + high) / 2;
7432       if (VAR_PART_OFFSET (var, pos) < offset)
7433         low = pos + 1;
7434       else
7435         high = pos;
7436     }
7437   pos = low;
7438
7439   if (insertion_point)
7440     *insertion_point = pos;
7441
7442   if (pos < var->n_var_parts && VAR_PART_OFFSET (var, pos) == offset)
7443     return pos;
7444
7445   return -1;
7446 }
7447
7448 static variable_def **
7449 set_slot_part (dataflow_set *set, rtx loc, variable_def **slot,
7450                decl_or_value dv, HOST_WIDE_INT offset,
7451                enum var_init_status initialized, rtx set_src)
7452 {
7453   int pos;
7454   location_chain node, next;
7455   location_chain *nextp;
7456   variable var;
7457   onepart_enum_t onepart;
7458
7459   var = *slot;
7460
7461   if (var)
7462     onepart = var->onepart;
7463   else
7464     onepart = dv_onepart_p (dv);
7465
7466   gcc_checking_assert (offset == 0 || !onepart);
7467   gcc_checking_assert (loc != dv_as_opaque (dv));
7468
7469   if (! flag_var_tracking_uninit)
7470     initialized = VAR_INIT_STATUS_INITIALIZED;
7471
7472   if (!var)
7473     {
7474       /* Create new variable information.  */
7475       var = (variable) pool_alloc (onepart_pool (onepart));
7476       var->dv = dv;
7477       var->refcount = 1;
7478       var->n_var_parts = 1;
7479       var->onepart = onepart;
7480       var->in_changed_variables = false;
7481       if (var->onepart)
7482         VAR_LOC_1PAUX (var) = NULL;
7483       else
7484         VAR_PART_OFFSET (var, 0) = offset;
7485       var->var_part[0].loc_chain = NULL;
7486       var->var_part[0].cur_loc = NULL;
7487       *slot = var;
7488       pos = 0;
7489       nextp = &var->var_part[0].loc_chain;
7490     }
7491   else if (onepart)
7492     {
7493       int r = -1, c = 0;
7494
7495       gcc_assert (dv_as_opaque (var->dv) == dv_as_opaque (dv));
7496
7497       pos = 0;
7498
7499       if (GET_CODE (loc) == VALUE)
7500         {
7501           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7502                nextp = &node->next)
7503             if (GET_CODE (node->loc) == VALUE)
7504               {
7505                 if (node->loc == loc)
7506                   {
7507                     r = 0;
7508                     break;
7509                   }
7510                 if (canon_value_cmp (node->loc, loc))
7511                   c++;
7512                 else
7513                   {
7514                     r = 1;
7515                     break;
7516                   }
7517               }
7518             else if (REG_P (node->loc) || MEM_P (node->loc))
7519               c++;
7520             else
7521               {
7522                 r = 1;
7523                 break;
7524               }
7525         }
7526       else if (REG_P (loc))
7527         {
7528           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7529                nextp = &node->next)
7530             if (REG_P (node->loc))
7531               {
7532                 if (REGNO (node->loc) < REGNO (loc))
7533                   c++;
7534                 else
7535                   {
7536                     if (REGNO (node->loc) == REGNO (loc))
7537                       r = 0;
7538                     else
7539                       r = 1;
7540                     break;
7541                   }
7542               }
7543             else
7544               {
7545                 r = 1;
7546                 break;
7547               }
7548         }
7549       else if (MEM_P (loc))
7550         {
7551           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7552                nextp = &node->next)
7553             if (REG_P (node->loc))
7554               c++;
7555             else if (MEM_P (node->loc))
7556               {
7557                 if ((r = loc_cmp (XEXP (node->loc, 0), XEXP (loc, 0))) >= 0)
7558                   break;
7559                 else
7560                   c++;
7561               }
7562             else
7563               {
7564                 r = 1;
7565                 break;
7566               }
7567         }
7568       else
7569         for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7570              nextp = &node->next)
7571           if ((r = loc_cmp (node->loc, loc)) >= 0)
7572             break;
7573           else
7574             c++;
7575
7576       if (r == 0)
7577         return slot;
7578
7579       if (shared_var_p (var, set->vars))
7580         {
7581           slot = unshare_variable (set, slot, var, initialized);
7582           var = *slot;
7583           for (nextp = &var->var_part[0].loc_chain; c;
7584                nextp = &(*nextp)->next)
7585             c--;
7586           gcc_assert ((!node && !*nextp) || node->loc == (*nextp)->loc);
7587         }
7588     }
7589   else
7590     {
7591       int inspos = 0;
7592
7593       gcc_assert (dv_as_decl (var->dv) == dv_as_decl (dv));
7594
7595       pos = find_variable_location_part (var, offset, &inspos);
7596
7597       if (pos >= 0)
7598         {
7599           node = var->var_part[pos].loc_chain;
7600
7601           if (node
7602               && ((REG_P (node->loc) && REG_P (loc)
7603                    && REGNO (node->loc) == REGNO (loc))
7604                   || rtx_equal_p (node->loc, loc)))
7605             {
7606               /* LOC is in the beginning of the chain so we have nothing
7607                  to do.  */
7608               if (node->init < initialized)
7609                 node->init = initialized;
7610               if (set_src != NULL)
7611                 node->set_src = set_src;
7612
7613               return slot;
7614             }
7615           else
7616             {
7617               /* We have to make a copy of a shared variable.  */
7618               if (shared_var_p (var, set->vars))
7619                 {
7620                   slot = unshare_variable (set, slot, var, initialized);
7621                   var = *slot;
7622                 }
7623             }
7624         }
7625       else
7626         {
7627           /* We have not found the location part, new one will be created.  */
7628
7629           /* We have to make a copy of the shared variable.  */
7630           if (shared_var_p (var, set->vars))
7631             {
7632               slot = unshare_variable (set, slot, var, initialized);
7633               var = *slot;
7634             }
7635
7636           /* We track only variables whose size is <= MAX_VAR_PARTS bytes
7637              thus there are at most MAX_VAR_PARTS different offsets.  */
7638           gcc_assert (var->n_var_parts < MAX_VAR_PARTS
7639                       && (!var->n_var_parts || !onepart));
7640
7641           /* We have to move the elements of array starting at index
7642              inspos to the next position.  */
7643           for (pos = var->n_var_parts; pos > inspos; pos--)
7644             var->var_part[pos] = var->var_part[pos - 1];
7645
7646           var->n_var_parts++;
7647           gcc_checking_assert (!onepart);
7648           VAR_PART_OFFSET (var, pos) = offset;
7649           var->var_part[pos].loc_chain = NULL;
7650           var->var_part[pos].cur_loc = NULL;
7651         }
7652
7653       /* Delete the location from the list.  */
7654       nextp = &var->var_part[pos].loc_chain;
7655       for (node = var->var_part[pos].loc_chain; node; node = next)
7656         {
7657           next = node->next;
7658           if ((REG_P (node->loc) && REG_P (loc)
7659                && REGNO (node->loc) == REGNO (loc))
7660               || rtx_equal_p (node->loc, loc))
7661             {
7662               /* Save these values, to assign to the new node, before
7663                  deleting this one.  */
7664               if (node->init > initialized)
7665                 initialized = node->init;
7666               if (node->set_src != NULL && set_src == NULL)
7667                 set_src = node->set_src;
7668               if (var->var_part[pos].cur_loc == node->loc)
7669                 var->var_part[pos].cur_loc = NULL;
7670               pool_free (loc_chain_pool, node);
7671               *nextp = next;
7672               break;
7673             }
7674           else
7675             nextp = &node->next;
7676         }
7677
7678       nextp = &var->var_part[pos].loc_chain;
7679     }
7680
7681   /* Add the location to the beginning.  */
7682   node = (location_chain) pool_alloc (loc_chain_pool);
7683   node->loc = loc;
7684   node->init = initialized;
7685   node->set_src = set_src;
7686   node->next = *nextp;
7687   *nextp = node;
7688
7689   /* If no location was emitted do so.  */
7690   if (var->var_part[pos].cur_loc == NULL)
7691     variable_was_changed (var, set);
7692
7693   return slot;
7694 }
7695
7696 /* Set the part of variable's location in the dataflow set SET.  The
7697    variable part is specified by variable's declaration in DV and
7698    offset OFFSET and the part's location by LOC.  IOPT should be
7699    NO_INSERT if the variable is known to be in SET already and the
7700    variable hash table must not be resized, and INSERT otherwise.  */
7701
7702 static void
7703 set_variable_part (dataflow_set *set, rtx loc,
7704                    decl_or_value dv, HOST_WIDE_INT offset,
7705                    enum var_init_status initialized, rtx set_src,
7706                    enum insert_option iopt)
7707 {
7708   variable_def **slot;
7709
7710   if (iopt == NO_INSERT)
7711     slot = shared_hash_find_slot_noinsert (set->vars, dv);
7712   else
7713     {
7714       slot = shared_hash_find_slot (set->vars, dv);
7715       if (!slot)
7716         slot = shared_hash_find_slot_unshare (&set->vars, dv, iopt);
7717     }
7718   set_slot_part (set, loc, slot, dv, offset, initialized, set_src);
7719 }
7720
7721 /* Remove all recorded register locations for the given variable part
7722    from dataflow set SET, except for those that are identical to loc.
7723    The variable part is specified by variable's declaration or value
7724    DV and offset OFFSET.  */
7725
7726 static variable_def **
7727 clobber_slot_part (dataflow_set *set, rtx loc, variable_def **slot,
7728                    HOST_WIDE_INT offset, rtx set_src)
7729 {
7730   variable var = *slot;
7731   int pos = find_variable_location_part (var, offset, NULL);
7732
7733   if (pos >= 0)
7734     {
7735       location_chain node, next;
7736
7737       /* Remove the register locations from the dataflow set.  */
7738       next = var->var_part[pos].loc_chain;
7739       for (node = next; node; node = next)
7740         {
7741           next = node->next;
7742           if (node->loc != loc
7743               && (!flag_var_tracking_uninit
7744                   || !set_src
7745                   || MEM_P (set_src)
7746                   || !rtx_equal_p (set_src, node->set_src)))
7747             {
7748               if (REG_P (node->loc))
7749                 {
7750                   attrs anode, anext;
7751                   attrs *anextp;
7752
7753                   /* Remove the variable part from the register's
7754                      list, but preserve any other variable parts
7755                      that might be regarded as live in that same
7756                      register.  */
7757                   anextp = &set->regs[REGNO (node->loc)];
7758                   for (anode = *anextp; anode; anode = anext)
7759                     {
7760                       anext = anode->next;
7761                       if (dv_as_opaque (anode->dv) == dv_as_opaque (var->dv)
7762                           && anode->offset == offset)
7763                         {
7764                           pool_free (attrs_pool, anode);
7765                           *anextp = anext;
7766                         }
7767                       else
7768                         anextp = &anode->next;
7769                     }
7770                 }
7771
7772               slot = delete_slot_part (set, node->loc, slot, offset);
7773             }
7774         }
7775     }
7776
7777   return slot;
7778 }
7779
7780 /* Remove all recorded register locations for the given variable part
7781    from dataflow set SET, except for those that are identical to loc.
7782    The variable part is specified by variable's declaration or value
7783    DV and offset OFFSET.  */
7784
7785 static void
7786 clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
7787                        HOST_WIDE_INT offset, rtx set_src)
7788 {
7789   variable_def **slot;
7790
7791   if (!dv_as_opaque (dv)
7792       || (!dv_is_value_p (dv) && ! DECL_P (dv_as_decl (dv))))
7793     return;
7794
7795   slot = shared_hash_find_slot_noinsert (set->vars, dv);
7796   if (!slot)
7797     return;
7798
7799   clobber_slot_part (set, loc, slot, offset, set_src);
7800 }
7801
7802 /* Delete the part of variable's location from dataflow set SET.  The
7803    variable part is specified by its SET->vars slot SLOT and offset
7804    OFFSET and the part's location by LOC.  */
7805
7806 static variable_def **
7807 delete_slot_part (dataflow_set *set, rtx loc, variable_def **slot,
7808                   HOST_WIDE_INT offset)
7809 {
7810   variable var = *slot;
7811   int pos = find_variable_location_part (var, offset, NULL);
7812
7813   if (pos >= 0)
7814     {
7815       location_chain node, next;
7816       location_chain *nextp;
7817       bool changed;
7818       rtx cur_loc;
7819
7820       if (shared_var_p (var, set->vars))
7821         {
7822           /* If the variable contains the location part we have to
7823              make a copy of the variable.  */
7824           for (node = var->var_part[pos].loc_chain; node;
7825                node = node->next)
7826             {
7827               if ((REG_P (node->loc) && REG_P (loc)
7828                    && REGNO (node->loc) == REGNO (loc))
7829                   || rtx_equal_p (node->loc, loc))
7830                 {
7831                   slot = unshare_variable (set, slot, var,
7832                                            VAR_INIT_STATUS_UNKNOWN);
7833                   var = *slot;
7834                   break;
7835                 }
7836             }
7837         }
7838
7839       if (pos == 0 && var->onepart && VAR_LOC_1PAUX (var))
7840         cur_loc = VAR_LOC_FROM (var);
7841       else
7842         cur_loc = var->var_part[pos].cur_loc;
7843
7844       /* Delete the location part.  */
7845       changed = false;
7846       nextp = &var->var_part[pos].loc_chain;
7847       for (node = *nextp; node; node = next)
7848         {
7849           next = node->next;
7850           if ((REG_P (node->loc) && REG_P (loc)
7851                && REGNO (node->loc) == REGNO (loc))
7852               || rtx_equal_p (node->loc, loc))
7853             {
7854               /* If we have deleted the location which was last emitted
7855                  we have to emit new location so add the variable to set
7856                  of changed variables.  */
7857               if (cur_loc == node->loc)
7858                 {
7859                   changed = true;
7860                   var->var_part[pos].cur_loc = NULL;
7861                   if (pos == 0 && var->onepart && VAR_LOC_1PAUX (var))
7862                     VAR_LOC_FROM (var) = NULL;
7863                 }
7864               pool_free (loc_chain_pool, node);
7865               *nextp = next;
7866               break;
7867             }
7868           else
7869             nextp = &node->next;
7870         }
7871
7872       if (var->var_part[pos].loc_chain == NULL)
7873         {
7874           changed = true;
7875           var->n_var_parts--;
7876           while (pos < var->n_var_parts)
7877             {
7878               var->var_part[pos] = var->var_part[pos + 1];
7879               pos++;
7880             }
7881         }
7882       if (changed)
7883         variable_was_changed (var, set);
7884     }
7885
7886   return slot;
7887 }
7888
7889 /* Delete the part of variable's location from dataflow set SET.  The
7890    variable part is specified by variable's declaration or value DV
7891    and offset OFFSET and the part's location by LOC.  */
7892
7893 static void
7894 delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
7895                       HOST_WIDE_INT offset)
7896 {
7897   variable_def **slot = shared_hash_find_slot_noinsert (set->vars, dv);
7898   if (!slot)
7899     return;
7900
7901   delete_slot_part (set, loc, slot, offset);
7902 }
7903
7904
7905 /* Structure for passing some other parameters to function
7906    vt_expand_loc_callback.  */
7907 struct expand_loc_callback_data
7908 {
7909   /* The variables and values active at this point.  */
7910   variable_table_type vars;
7911
7912   /* Stack of values and debug_exprs under expansion, and their
7913      children.  */
7914   stack_vec<rtx, 4> expanding;
7915
7916   /* Stack of values and debug_exprs whose expansion hit recursion
7917      cycles.  They will have VALUE_RECURSED_INTO marked when added to
7918      this list.  This flag will be cleared if any of its dependencies
7919      resolves to a valid location.  So, if the flag remains set at the
7920      end of the search, we know no valid location for this one can
7921      possibly exist.  */
7922   stack_vec<rtx, 4> pending;
7923
7924   /* The maximum depth among the sub-expressions under expansion.
7925      Zero indicates no expansion so far.  */
7926   expand_depth depth;
7927 };
7928
7929 /* Allocate the one-part auxiliary data structure for VAR, with enough
7930    room for COUNT dependencies.  */
7931
7932 static void
7933 loc_exp_dep_alloc (variable var, int count)
7934 {
7935   size_t allocsize;
7936
7937   gcc_checking_assert (var->onepart);
7938
7939   /* We can be called with COUNT == 0 to allocate the data structure
7940      without any dependencies, e.g. for the backlinks only.  However,
7941      if we are specifying a COUNT, then the dependency list must have
7942      been emptied before.  It would be possible to adjust pointers or
7943      force it empty here, but this is better done at an earlier point
7944      in the algorithm, so we instead leave an assertion to catch
7945      errors.  */
7946   gcc_checking_assert (!count
7947                        || VAR_LOC_DEP_VEC (var) == NULL
7948                        || VAR_LOC_DEP_VEC (var)->is_empty ());
7949
7950   if (VAR_LOC_1PAUX (var) && VAR_LOC_DEP_VEC (var)->space (count))
7951     return;
7952
7953   allocsize = offsetof (struct onepart_aux, deps)
7954               + vec<loc_exp_dep, va_heap, vl_embed>::embedded_size (count);
7955
7956   if (VAR_LOC_1PAUX (var))
7957     {
7958       VAR_LOC_1PAUX (var) = XRESIZEVAR (struct onepart_aux,
7959                                         VAR_LOC_1PAUX (var), allocsize);
7960       /* If the reallocation moves the onepaux structure, the
7961          back-pointer to BACKLINKS in the first list member will still
7962          point to its old location.  Adjust it.  */
7963       if (VAR_LOC_DEP_LST (var))
7964         VAR_LOC_DEP_LST (var)->pprev = VAR_LOC_DEP_LSTP (var);
7965     }
7966   else
7967     {
7968       VAR_LOC_1PAUX (var) = XNEWVAR (struct onepart_aux, allocsize);
7969       *VAR_LOC_DEP_LSTP (var) = NULL;
7970       VAR_LOC_FROM (var) = NULL;
7971       VAR_LOC_DEPTH (var).complexity = 0;
7972       VAR_LOC_DEPTH (var).entryvals = 0;
7973     }
7974   VAR_LOC_DEP_VEC (var)->embedded_init (count);
7975 }
7976
7977 /* Remove all entries from the vector of active dependencies of VAR,
7978    removing them from the back-links lists too.  */
7979
7980 static void
7981 loc_exp_dep_clear (variable var)
7982 {
7983   while (VAR_LOC_DEP_VEC (var) && !VAR_LOC_DEP_VEC (var)->is_empty ())
7984     {
7985       loc_exp_dep *led = &VAR_LOC_DEP_VEC (var)->last ();
7986       if (led->next)
7987         led->next->pprev = led->pprev;
7988       if (led->pprev)
7989         *led->pprev = led->next;
7990       VAR_LOC_DEP_VEC (var)->pop ();
7991     }
7992 }
7993
7994 /* Insert an active dependency from VAR on X to the vector of
7995    dependencies, and add the corresponding back-link to X's list of
7996    back-links in VARS.  */
7997
7998 static void
7999 loc_exp_insert_dep (variable var, rtx x, variable_table_type vars)
8000 {
8001   decl_or_value dv;
8002   variable xvar;
8003   loc_exp_dep *led;
8004
8005   dv = dv_from_rtx (x);
8006
8007   /* ??? Build a vector of variables parallel to EXPANDING, to avoid
8008      an additional look up?  */
8009   xvar = vars.find_with_hash (dv, dv_htab_hash (dv));
8010
8011   if (!xvar)
8012     {
8013       xvar = variable_from_dropped (dv, NO_INSERT);
8014       gcc_checking_assert (xvar);
8015     }
8016
8017   /* No point in adding the same backlink more than once.  This may
8018      arise if say the same value appears in two complex expressions in
8019      the same loc_list, or even more than once in a single
8020      expression.  */
8021   if (VAR_LOC_DEP_LST (xvar) && VAR_LOC_DEP_LST (xvar)->dv == var->dv)
8022     return;
8023
8024   if (var->onepart == NOT_ONEPART)
8025     led = (loc_exp_dep *) pool_alloc (loc_exp_dep_pool);
8026   else
8027     {
8028       loc_exp_dep empty;
8029       memset (&empty, 0, sizeof (empty));
8030       VAR_LOC_DEP_VEC (var)->quick_push (empty);
8031       led = &VAR_LOC_DEP_VEC (var)->last ();
8032     }
8033   led->dv = var->dv;
8034   led->value = x;
8035
8036   loc_exp_dep_alloc (xvar, 0);
8037   led->pprev = VAR_LOC_DEP_LSTP (xvar);
8038   led->next = *led->pprev;
8039   if (led->next)
8040     led->next->pprev = &led->next;
8041   *led->pprev = led;
8042 }
8043
8044 /* Create active dependencies of VAR on COUNT values starting at
8045    VALUE, and corresponding back-links to the entries in VARS.  Return
8046    true if we found any pending-recursion results.  */
8047
8048 static bool
8049 loc_exp_dep_set (variable var, rtx result, rtx *value, int count,
8050                  variable_table_type vars)
8051 {
8052   bool pending_recursion = false;
8053
8054   gcc_checking_assert (VAR_LOC_DEP_VEC (var) == NULL
8055                        || VAR_LOC_DEP_VEC (var)->is_empty ());
8056
8057   /* Set up all dependencies from last_child (as set up at the end of
8058      the loop above) to the end.  */
8059   loc_exp_dep_alloc (var, count);
8060
8061   while (count--)
8062     {
8063       rtx x = *value++;
8064
8065       if (!pending_recursion)
8066         pending_recursion = !result && VALUE_RECURSED_INTO (x);
8067
8068       loc_exp_insert_dep (var, x, vars);
8069     }
8070
8071   return pending_recursion;
8072 }
8073
8074 /* Notify the back-links of IVAR that are pending recursion that we
8075    have found a non-NIL value for it, so they are cleared for another
8076    attempt to compute a current location.  */
8077
8078 static void
8079 notify_dependents_of_resolved_value (variable ivar, variable_table_type vars)
8080 {
8081   loc_exp_dep *led, *next;
8082
8083   for (led = VAR_LOC_DEP_LST (ivar); led; led = next)
8084     {
8085       decl_or_value dv = led->dv;
8086       variable var;
8087
8088       next = led->next;
8089
8090       if (dv_is_value_p (dv))
8091         {
8092           rtx value = dv_as_value (dv);
8093
8094           /* If we have already resolved it, leave it alone.  */
8095           if (!VALUE_RECURSED_INTO (value))
8096             continue;
8097
8098           /* Check that VALUE_RECURSED_INTO, true from the test above,
8099              implies NO_LOC_P.  */
8100           gcc_checking_assert (NO_LOC_P (value));
8101
8102           /* We won't notify variables that are being expanded,
8103              because their dependency list is cleared before
8104              recursing.  */
8105           NO_LOC_P (value) = false;
8106           VALUE_RECURSED_INTO (value) = false;
8107
8108           gcc_checking_assert (dv_changed_p (dv));
8109         }
8110       else
8111         {
8112           gcc_checking_assert (dv_onepart_p (dv) != NOT_ONEPART);
8113           if (!dv_changed_p (dv))
8114             continue;
8115       }
8116
8117       var = vars.find_with_hash (dv, dv_htab_hash (dv));
8118
8119       if (!var)
8120         var = variable_from_dropped (dv, NO_INSERT);
8121
8122       if (var)
8123         notify_dependents_of_resolved_value (var, vars);
8124
8125       if (next)
8126         next->pprev = led->pprev;
8127       if (led->pprev)
8128         *led->pprev = next;
8129       led->next = NULL;
8130       led->pprev = NULL;
8131     }
8132 }
8133
8134 static rtx vt_expand_loc_callback (rtx x, bitmap regs,
8135                                    int max_depth, void *data);
8136
8137 /* Return the combined depth, when one sub-expression evaluated to
8138    BEST_DEPTH and the previous known depth was SAVED_DEPTH.  */
8139
8140 static inline expand_depth
8141 update_depth (expand_depth saved_depth, expand_depth best_depth)
8142 {
8143   /* If we didn't find anything, stick with what we had.  */
8144   if (!best_depth.complexity)
8145     return saved_depth;
8146
8147   /* If we found hadn't found anything, use the depth of the current
8148      expression.  Do NOT add one extra level, we want to compute the
8149      maximum depth among sub-expressions.  We'll increment it later,
8150      if appropriate.  */
8151   if (!saved_depth.complexity)
8152     return best_depth;
8153
8154   /* Combine the entryval count so that regardless of which one we
8155      return, the entryval count is accurate.  */
8156   best_depth.entryvals = saved_depth.entryvals
8157     = best_depth.entryvals + saved_depth.entryvals;
8158
8159   if (saved_depth.complexity < best_depth.complexity)
8160     return best_depth;
8161   else
8162     return saved_depth;
8163 }
8164
8165 /* Expand VAR to a location RTX, updating its cur_loc.  Use REGS and
8166    DATA for cselib expand callback.  If PENDRECP is given, indicate in
8167    it whether any sub-expression couldn't be fully evaluated because
8168    it is pending recursion resolution.  */
8169
8170 static inline rtx
8171 vt_expand_var_loc_chain (variable var, bitmap regs, void *data, bool *pendrecp)
8172 {
8173   struct expand_loc_callback_data *elcd
8174     = (struct expand_loc_callback_data *) data;
8175   location_chain loc, next;
8176   rtx result = NULL;
8177   int first_child, result_first_child, last_child;
8178   bool pending_recursion;
8179   rtx loc_from = NULL;
8180   struct elt_loc_list *cloc = NULL;
8181   expand_depth depth = { 0, 0 }, saved_depth = elcd->depth;
8182   int wanted_entryvals, found_entryvals = 0;
8183
8184   /* Clear all backlinks pointing at this, so that we're not notified
8185      while we're active.  */
8186   loc_exp_dep_clear (var);
8187
8188  retry:
8189   if (var->onepart == ONEPART_VALUE)
8190     {
8191       cselib_val *val = CSELIB_VAL_PTR (dv_as_value (var->dv));
8192
8193       gcc_checking_assert (cselib_preserved_value_p (val));
8194
8195       cloc = val->locs;
8196     }
8197
8198   first_child = result_first_child = last_child
8199     = elcd->expanding.length ();
8200
8201   wanted_entryvals = found_entryvals;
8202
8203   /* Attempt to expand each available location in turn.  */
8204   for (next = loc = var->n_var_parts ? var->var_part[0].loc_chain : NULL;
8205        loc || cloc; loc = next)
8206     {
8207       result_first_child = last_child;
8208
8209       if (!loc)
8210         {
8211           loc_from = cloc->loc;
8212           next = loc;
8213           cloc = cloc->next;
8214           if (unsuitable_loc (loc_from))
8215             continue;
8216         }
8217       else
8218         {
8219           loc_from = loc->loc;
8220           next = loc->next;
8221         }
8222
8223       gcc_checking_assert (!unsuitable_loc (loc_from));
8224
8225       elcd->depth.complexity = elcd->depth.entryvals = 0;
8226       result = cselib_expand_value_rtx_cb (loc_from, regs, EXPR_DEPTH,
8227                                            vt_expand_loc_callback, data);
8228       last_child = elcd->expanding.length ();
8229
8230       if (result)
8231         {
8232           depth = elcd->depth;
8233
8234           gcc_checking_assert (depth.complexity
8235                                || result_first_child == last_child);
8236
8237           if (last_child - result_first_child != 1)
8238             {
8239               if (!depth.complexity && GET_CODE (result) == ENTRY_VALUE)
8240                 depth.entryvals++;
8241               depth.complexity++;
8242             }
8243
8244           if (depth.complexity <= EXPR_USE_DEPTH)
8245             {
8246               if (depth.entryvals <= wanted_entryvals)
8247                 break;
8248               else if (!found_entryvals || depth.entryvals < found_entryvals)
8249                 found_entryvals = depth.entryvals;
8250             }
8251
8252           result = NULL;
8253         }
8254
8255       /* Set it up in case we leave the loop.  */
8256       depth.complexity = depth.entryvals = 0;
8257       loc_from = NULL;
8258       result_first_child = first_child;
8259     }
8260
8261   if (!loc_from && wanted_entryvals < found_entryvals)
8262     {
8263       /* We found entries with ENTRY_VALUEs and skipped them.  Since
8264          we could not find any expansions without ENTRY_VALUEs, but we
8265          found at least one with them, go back and get an entry with
8266          the minimum number ENTRY_VALUE count that we found.  We could
8267          avoid looping, but since each sub-loc is already resolved,
8268          the re-expansion should be trivial.  ??? Should we record all
8269          attempted locs as dependencies, so that we retry the
8270          expansion should any of them change, in the hope it can give
8271          us a new entry without an ENTRY_VALUE?  */
8272       elcd->expanding.truncate (first_child);
8273       goto retry;
8274     }
8275
8276   /* Register all encountered dependencies as active.  */
8277   pending_recursion = loc_exp_dep_set
8278     (var, result, elcd->expanding.address () + result_first_child,
8279      last_child - result_first_child, elcd->vars);
8280
8281   elcd->expanding.truncate (first_child);
8282
8283   /* Record where the expansion came from.  */
8284   gcc_checking_assert (!result || !pending_recursion);
8285   VAR_LOC_FROM (var) = loc_from;
8286   VAR_LOC_DEPTH (var) = depth;
8287
8288   gcc_checking_assert (!depth.complexity == !result);
8289
8290   elcd->depth = update_depth (saved_depth, depth);
8291
8292   /* Indicate whether any of the dependencies are pending recursion
8293      resolution.  */
8294   if (pendrecp)
8295     *pendrecp = pending_recursion;
8296
8297   if (!pendrecp || !pending_recursion)
8298     var->var_part[0].cur_loc = result;
8299
8300   return result;
8301 }
8302
8303 /* Callback for cselib_expand_value, that looks for expressions
8304    holding the value in the var-tracking hash tables.  Return X for
8305    standard processing, anything else is to be used as-is.  */
8306
8307 static rtx
8308 vt_expand_loc_callback (rtx x, bitmap regs,
8309                         int max_depth ATTRIBUTE_UNUSED,
8310                         void *data)
8311 {
8312   struct expand_loc_callback_data *elcd
8313     = (struct expand_loc_callback_data *) data;
8314   decl_or_value dv;
8315   variable var;
8316   rtx result, subreg;
8317   bool pending_recursion = false;
8318   bool from_empty = false;
8319
8320   switch (GET_CODE (x))
8321     {
8322     case SUBREG:
8323       subreg = cselib_expand_value_rtx_cb (SUBREG_REG (x), regs,
8324                                            EXPR_DEPTH,
8325                                            vt_expand_loc_callback, data);
8326
8327       if (!subreg)
8328         return NULL;
8329
8330       result = simplify_gen_subreg (GET_MODE (x), subreg,
8331                                     GET_MODE (SUBREG_REG (x)),
8332                                     SUBREG_BYTE (x));
8333
8334       /* Invalid SUBREGs are ok in debug info.  ??? We could try
8335          alternate expansions for the VALUE as well.  */
8336       if (!result)
8337         result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));
8338
8339       return result;
8340
8341     case DEBUG_EXPR:
8342     case VALUE:
8343       dv = dv_from_rtx (x);
8344       break;
8345
8346     default:
8347       return x;
8348     }
8349
8350   elcd->expanding.safe_push (x);
8351
8352   /* Check that VALUE_RECURSED_INTO implies NO_LOC_P.  */
8353   gcc_checking_assert (!VALUE_RECURSED_INTO (x) || NO_LOC_P (x));
8354
8355   if (NO_LOC_P (x))
8356     {
8357       gcc_checking_assert (VALUE_RECURSED_INTO (x) || !dv_changed_p (dv));
8358       return NULL;
8359     }
8360
8361   var = elcd->vars.find_with_hash (dv, dv_htab_hash (dv));
8362
8363   if (!var)
8364     {
8365       from_empty = true;
8366       var = variable_from_dropped (dv, INSERT);
8367     }
8368
8369   gcc_checking_assert (var);
8370
8371   if (!dv_changed_p (dv))
8372     {
8373       gcc_checking_assert (!NO_LOC_P (x));
8374       gcc_checking_assert (var->var_part[0].cur_loc);
8375       gcc_checking_assert (VAR_LOC_1PAUX (var));
8376       gcc_checking_assert (VAR_LOC_1PAUX (var)->depth.complexity);
8377
8378       elcd->depth = update_depth (elcd->depth, VAR_LOC_1PAUX (var)->depth);
8379
8380       return var->var_part[0].cur_loc;
8381     }
8382
8383   VALUE_RECURSED_INTO (x) = true;
8384   /* This is tentative, but it makes some tests simpler.  */
8385   NO_LOC_P (x) = true;
8386
8387   gcc_checking_assert (var->n_var_parts == 1 || from_empty);
8388
8389   result = vt_expand_var_loc_chain (var, regs, data, &pending_recursion);
8390
8391   if (pending_recursion)
8392     {
8393       gcc_checking_assert (!result);
8394       elcd->pending.safe_push (x);
8395     }
8396   else
8397     {
8398       NO_LOC_P (x) = !result;
8399       VALUE_RECURSED_INTO (x) = false;
8400       set_dv_changed (dv, false);
8401
8402       if (result)
8403         notify_dependents_of_resolved_value (var, elcd->vars);
8404     }
8405
8406   return result;
8407 }
8408
8409 /* While expanding variables, we may encounter recursion cycles
8410    because of mutual (possibly indirect) dependencies between two
8411    particular variables (or values), say A and B.  If we're trying to
8412    expand A when we get to B, which in turn attempts to expand A, if
8413    we can't find any other expansion for B, we'll add B to this
8414    pending-recursion stack, and tentatively return NULL for its
8415    location.  This tentative value will be used for any other
8416    occurrences of B, unless A gets some other location, in which case
8417    it will notify B that it is worth another try at computing a
8418    location for it, and it will use the location computed for A then.
8419    At the end of the expansion, the tentative NULL locations become
8420    final for all members of PENDING that didn't get a notification.
8421    This function performs this finalization of NULL locations.  */
8422
8423 static void
8424 resolve_expansions_pending_recursion (vec<rtx, va_heap> *pending)
8425 {
8426   while (!pending->is_empty ())
8427     {
8428       rtx x = pending->pop ();
8429       decl_or_value dv;
8430
8431       if (!VALUE_RECURSED_INTO (x))
8432         continue;
8433
8434       gcc_checking_assert (NO_LOC_P (x));
8435       VALUE_RECURSED_INTO (x) = false;
8436       dv = dv_from_rtx (x);
8437       gcc_checking_assert (dv_changed_p (dv));
8438       set_dv_changed (dv, false);
8439     }
8440 }
8441
8442 /* Initialize expand_loc_callback_data D with variable hash table V.
8443    It must be a macro because of alloca (vec stack).  */
8444 #define INIT_ELCD(d, v)                                         \
8445   do                                                            \
8446     {                                                           \
8447       (d).vars = (v);                                           \
8448       (d).depth.complexity = (d).depth.entryvals = 0;           \
8449     }                                                           \
8450   while (0)
8451 /* Finalize expand_loc_callback_data D, resolved to location L.  */
8452 #define FINI_ELCD(d, l)                                         \
8453   do                                                            \
8454     {                                                           \
8455       resolve_expansions_pending_recursion (&(d).pending);      \
8456       (d).pending.release ();                                   \
8457       (d).expanding.release ();                                 \
8458                                                                 \
8459       if ((l) && MEM_P (l))                                     \
8460         (l) = targetm.delegitimize_address (l);                 \
8461     }                                                           \
8462   while (0)
8463
8464 /* Expand VALUEs and DEBUG_EXPRs in LOC to a location, using the
8465    equivalences in VARS, updating their CUR_LOCs in the process.  */
8466
8467 static rtx
8468 vt_expand_loc (rtx loc, variable_table_type vars)
8469 {
8470   struct expand_loc_callback_data data;
8471   rtx result;
8472
8473   if (!MAY_HAVE_DEBUG_INSNS)
8474     return loc;
8475
8476   INIT_ELCD (data, vars);
8477
8478   result = cselib_expand_value_rtx_cb (loc, scratch_regs, EXPR_DEPTH,
8479                                        vt_expand_loc_callback, &data);
8480
8481   FINI_ELCD (data, result);
8482
8483   return result;
8484 }
8485
8486 /* Expand the one-part VARiable to a location, using the equivalences
8487    in VARS, updating their CUR_LOCs in the process.  */
8488
8489 static rtx
8490 vt_expand_1pvar (variable var, variable_table_type vars)
8491 {
8492   struct expand_loc_callback_data data;
8493   rtx loc;
8494
8495   gcc_checking_assert (var->onepart && var->n_var_parts == 1);
8496
8497   if (!dv_changed_p (var->dv))
8498     return var->var_part[0].cur_loc;
8499
8500   INIT_ELCD (data, vars);
8501
8502   loc = vt_expand_var_loc_chain (var, scratch_regs, &data, NULL);
8503
8504   gcc_checking_assert (data.expanding.is_empty ());
8505
8506   FINI_ELCD (data, loc);
8507
8508   return loc;
8509 }
8510
8511 /* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP.  DATA contains
8512    additional parameters: WHERE specifies whether the note shall be emitted
8513    before or after instruction INSN.  */
8514
8515 int
8516 emit_note_insn_var_location (variable_def **varp, emit_note_data *data)
8517 {
8518   variable var = *varp;
8519   rtx insn = data->insn;
8520   enum emit_note_where where = data->where;
8521   variable_table_type vars = data->vars;
8522   rtx note, note_vl;
8523   int i, j, n_var_parts;
8524   bool complete;
8525   enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED;
8526   HOST_WIDE_INT last_limit;
8527   tree type_size_unit;
8528   HOST_WIDE_INT offsets[MAX_VAR_PARTS];
8529   rtx loc[MAX_VAR_PARTS];
8530   tree decl;
8531   location_chain lc;
8532
8533   gcc_checking_assert (var->onepart == NOT_ONEPART
8534                        || var->onepart == ONEPART_VDECL);
8535
8536   decl = dv_as_decl (var->dv);
8537
8538   complete = true;
8539   last_limit = 0;
8540   n_var_parts = 0;
8541   if (!var->onepart)
8542     for (i = 0; i < var->n_var_parts; i++)
8543       if (var->var_part[i].cur_loc == NULL && var->var_part[i].loc_chain)
8544         var->var_part[i].cur_loc = var->var_part[i].loc_chain->loc;
8545   for (i = 0; i < var->n_var_parts; i++)
8546     {
8547       enum machine_mode mode, wider_mode;
8548       rtx loc2;
8549       HOST_WIDE_INT offset;
8550
8551       if (i == 0 && var->onepart)
8552         {
8553           gcc_checking_assert (var->n_var_parts == 1);
8554           offset = 0;
8555           initialized = VAR_INIT_STATUS_INITIALIZED;
8556           loc2 = vt_expand_1pvar (var, vars);
8557         }
8558       else
8559         {
8560           if (last_limit < VAR_PART_OFFSET (var, i))
8561             {
8562               complete = false;
8563               break;
8564             }
8565           else if (last_limit > VAR_PART_OFFSET (var, i))
8566             continue;
8567           offset = VAR_PART_OFFSET (var, i);
8568           loc2 = var->var_part[i].cur_loc;
8569           if (loc2 && GET_CODE (loc2) == MEM
8570               && GET_CODE (XEXP (loc2, 0)) == VALUE)
8571             {
8572               rtx depval = XEXP (loc2, 0);
8573
8574               loc2 = vt_expand_loc (loc2, vars);
8575
8576               if (loc2)
8577                 loc_exp_insert_dep (var, depval, vars);
8578             }
8579           if (!loc2)
8580             {
8581               complete = false;
8582               continue;
8583             }
8584           gcc_checking_assert (GET_CODE (loc2) != VALUE);
8585           for (lc = var->var_part[i].loc_chain; lc; lc = lc->next)
8586             if (var->var_part[i].cur_loc == lc->loc)
8587               {
8588                 initialized = lc->init;
8589                 break;
8590               }
8591           gcc_assert (lc);
8592         }
8593
8594       offsets[n_var_parts] = offset;
8595       if (!loc2)
8596         {
8597           complete = false;
8598           continue;
8599         }
8600       loc[n_var_parts] = loc2;
8601       mode = GET_MODE (var->var_part[i].cur_loc);
8602       if (mode == VOIDmode && var->onepart)
8603         mode = DECL_MODE (decl);
8604       last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
8605
8606       /* Attempt to merge adjacent registers or memory.  */
8607       wider_mode = GET_MODE_WIDER_MODE (mode);
8608       for (j = i + 1; j < var->n_var_parts; j++)
8609         if (last_limit <= VAR_PART_OFFSET (var, j))
8610           break;
8611       if (j < var->n_var_parts
8612           && wider_mode != VOIDmode
8613           && var->var_part[j].cur_loc
8614           && mode == GET_MODE (var->var_part[j].cur_loc)
8615           && (REG_P (loc[n_var_parts]) || MEM_P (loc[n_var_parts]))
8616           && last_limit == (var->onepart ? 0 : VAR_PART_OFFSET (var, j))
8617           && (loc2 = vt_expand_loc (var->var_part[j].cur_loc, vars))
8618           && GET_CODE (loc[n_var_parts]) == GET_CODE (loc2))
8619         {
8620           rtx new_loc = NULL;
8621
8622           if (REG_P (loc[n_var_parts])
8623               && hard_regno_nregs[REGNO (loc[n_var_parts])][mode] * 2
8624                  == hard_regno_nregs[REGNO (loc[n_var_parts])][wider_mode]
8625               && end_hard_regno (mode, REGNO (loc[n_var_parts]))
8626                  == REGNO (loc2))
8627             {
8628               if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
8629                 new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
8630                                            mode, 0);
8631               else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
8632                 new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
8633               if (new_loc)
8634                 {
8635                   if (!REG_P (new_loc)
8636                       || REGNO (new_loc) != REGNO (loc[n_var_parts]))
8637                     new_loc = NULL;
8638                   else
8639                     REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
8640                 }
8641             }
8642           else if (MEM_P (loc[n_var_parts])
8643                    && GET_CODE (XEXP (loc2, 0)) == PLUS
8644                    && REG_P (XEXP (XEXP (loc2, 0), 0))
8645                    && CONST_INT_P (XEXP (XEXP (loc2, 0), 1)))
8646             {
8647               if ((REG_P (XEXP (loc[n_var_parts], 0))
8648                    && rtx_equal_p (XEXP (loc[n_var_parts], 0),
8649                                    XEXP (XEXP (loc2, 0), 0))
8650                    && INTVAL (XEXP (XEXP (loc2, 0), 1))
8651                       == GET_MODE_SIZE (mode))
8652                   || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
8653                       && CONST_INT_P (XEXP (XEXP (loc[n_var_parts], 0), 1))
8654                       && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
8655                                       XEXP (XEXP (loc2, 0), 0))
8656                       && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
8657                          + GET_MODE_SIZE (mode)
8658                          == INTVAL (XEXP (XEXP (loc2, 0), 1))))
8659                 new_loc = adjust_address_nv (loc[n_var_parts],
8660                                              wider_mode, 0);
8661             }
8662
8663           if (new_loc)
8664             {
8665               loc[n_var_parts] = new_loc;
8666               mode = wider_mode;
8667               last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
8668               i = j;
8669             }
8670         }
8671       ++n_var_parts;
8672     }
8673   type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8674   if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
8675     complete = false;
8676
8677   if (! flag_var_tracking_uninit)
8678     initialized = VAR_INIT_STATUS_INITIALIZED;
8679
8680   note_vl = NULL_RTX;
8681   if (!complete)
8682     note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, NULL_RTX,
8683                                     (int) initialized);
8684   else if (n_var_parts == 1)
8685     {
8686       rtx expr_list;
8687
8688       if (offsets[0] || GET_CODE (loc[0]) == PARALLEL)
8689         expr_list = gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
8690       else
8691         expr_list = loc[0];
8692
8693       note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, expr_list,
8694                                       (int) initialized);
8695     }
8696   else if (n_var_parts)
8697     {
8698       rtx parallel;
8699
8700       for (i = 0; i < n_var_parts; i++)
8701         loc[i]
8702           = gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));
8703
8704       parallel = gen_rtx_PARALLEL (VOIDmode,
8705                                    gen_rtvec_v (n_var_parts, loc));
8706       note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl,
8707                                       parallel, (int) initialized);
8708     }
8709
8710   if (where != EMIT_NOTE_BEFORE_INSN)
8711     {
8712       note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
8713       if (where == EMIT_NOTE_AFTER_CALL_INSN)
8714         NOTE_DURING_CALL_P (note) = true;
8715     }
8716   else
8717     {
8718       /* Make sure that the call related notes come first.  */
8719       while (NEXT_INSN (insn)
8720              && NOTE_P (insn)
8721              && ((NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
8722                   && NOTE_DURING_CALL_P (insn))
8723                  || NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
8724         insn = NEXT_INSN (insn);
8725       if (NOTE_P (insn)
8726           && ((NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
8727                && NOTE_DURING_CALL_P (insn))
8728               || NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
8729         note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
8730       else
8731         note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
8732     }
8733   NOTE_VAR_LOCATION (note) = note_vl;
8734
8735   set_dv_changed (var->dv, false);
8736   gcc_assert (var->in_changed_variables);
8737   var->in_changed_variables = false;
8738   changed_variables.clear_slot (varp);
8739
8740   /* Continue traversing the hash table.  */
8741   return 1;
8742 }
8743
8744 /* While traversing changed_variables, push onto DATA (a stack of RTX
8745    values) entries that aren't user variables.  */
8746
8747 int
8748 var_track_values_to_stack (variable_def **slot,
8749                            vec<rtx, va_heap> *changed_values_stack)
8750 {
8751   variable var = *slot;
8752
8753   if (var->onepart == ONEPART_VALUE)
8754     changed_values_stack->safe_push (dv_as_value (var->dv));
8755   else if (var->onepart == ONEPART_DEXPR)
8756     changed_values_stack->safe_push (DECL_RTL_KNOWN_SET (dv_as_decl (var->dv)));
8757
8758   return 1;
8759 }
8760
8761 /* Remove from changed_variables the entry whose DV corresponds to
8762    value or debug_expr VAL.  */
8763 static void
8764 remove_value_from_changed_variables (rtx val)
8765 {
8766   decl_or_value dv = dv_from_rtx (val);
8767   variable_def **slot;
8768   variable var;
8769
8770   slot = changed_variables.find_slot_with_hash (dv, dv_htab_hash (dv),
8771                                                 NO_INSERT);
8772   var = *slot;
8773   var->in_changed_variables = false;
8774   changed_variables.clear_slot (slot);
8775 }
8776
8777 /* If VAL (a value or debug_expr) has backlinks to variables actively
8778    dependent on it in HTAB or in CHANGED_VARIABLES, mark them as
8779    changed, adding to CHANGED_VALUES_STACK any dependencies that may
8780    have dependencies of their own to notify.  */
8781
8782 static void
8783 notify_dependents_of_changed_value (rtx val, variable_table_type htab,
8784                                     vec<rtx, va_heap> *changed_values_stack)
8785 {
8786   variable_def **slot;
8787   variable var;
8788   loc_exp_dep *led;
8789   decl_or_value dv = dv_from_rtx (val);
8790
8791   slot = changed_variables.find_slot_with_hash (dv, dv_htab_hash (dv),
8792                                                 NO_INSERT);
8793   if (!slot)
8794     slot = htab.find_slot_with_hash (dv, dv_htab_hash (dv), NO_INSERT);
8795   if (!slot)
8796     slot = dropped_values.find_slot_with_hash (dv, dv_htab_hash (dv),
8797                                                NO_INSERT);
8798   var = *slot;
8799
8800   while ((led = VAR_LOC_DEP_LST (var)))
8801     {
8802       decl_or_value ldv = led->dv;
8803       variable ivar;
8804
8805       /* Deactivate and remove the backlink, as it was “used up”.  It
8806          makes no sense to attempt to notify the same entity again:
8807          either it will be recomputed and re-register an active
8808          dependency, or it will still have the changed mark.  */
8809       if (led->next)
8810         led->next->pprev = led->pprev;
8811       if (led->pprev)
8812         *led->pprev = led->next;
8813       led->next = NULL;
8814       led->pprev = NULL;
8815
8816       if (dv_changed_p (ldv))
8817         continue;
8818
8819       switch (dv_onepart_p (ldv))
8820         {
8821         case ONEPART_VALUE:
8822         case ONEPART_DEXPR:
8823           set_dv_changed (ldv, true);
8824           changed_values_stack->safe_push (dv_as_rtx (ldv));
8825           break;
8826
8827         case ONEPART_VDECL:
8828           ivar = htab.find_with_hash (ldv, dv_htab_hash (ldv));
8829           gcc_checking_assert (!VAR_LOC_DEP_LST (ivar));
8830           variable_was_changed (ivar, NULL);
8831           break;
8832
8833         case NOT_ONEPART:
8834           pool_free (loc_exp_dep_pool, led);
8835           ivar = htab.find_with_hash (ldv, dv_htab_hash (ldv));
8836           if (ivar)
8837             {
8838               int i = ivar->n_var_parts;
8839               while (i--)
8840                 {
8841                   rtx loc = ivar->var_part[i].cur_loc;
8842
8843                   if (loc && GET_CODE (loc) == MEM
8844                       && XEXP (loc, 0) == val)
8845                     {
8846                       variable_was_changed (ivar, NULL);
8847                       break;
8848                     }
8849                 }
8850             }
8851           break;
8852
8853         default:
8854           gcc_unreachable ();
8855         }
8856     }
8857 }
8858
8859 /* Take out of changed_variables any entries that don't refer to use
8860    variables.  Back-propagate change notifications from values and
8861    debug_exprs to their active dependencies in HTAB or in
8862    CHANGED_VARIABLES.  */
8863
8864 static void
8865 process_changed_values (variable_table_type htab)
8866 {
8867   int i, n;
8868   rtx val;
8869   stack_vec<rtx, 20> changed_values_stack;
8870
8871   /* Move values from changed_variables to changed_values_stack.  */
8872   changed_variables
8873     .traverse <vec<rtx, va_heap>*, var_track_values_to_stack>
8874       (&changed_values_stack);
8875
8876   /* Back-propagate change notifications in values while popping
8877      them from the stack.  */
8878   for (n = i = changed_values_stack.length ();
8879        i > 0; i = changed_values_stack.length ())
8880     {
8881       val = changed_values_stack.pop ();
8882       notify_dependents_of_changed_value (val, htab, &changed_values_stack);
8883
8884       /* This condition will hold when visiting each of the entries
8885          originally in changed_variables.  We can't remove them
8886          earlier because this could drop the backlinks before we got a
8887          chance to use them.  */
8888       if (i == n)
8889         {
8890           remove_value_from_changed_variables (val);
8891           n--;
8892         }
8893     }
8894 }
8895
8896 /* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
8897    CHANGED_VARIABLES and delete this chain.  WHERE specifies whether
8898    the notes shall be emitted before of after instruction INSN.  */
8899
8900 static void
8901 emit_notes_for_changes (rtx insn, enum emit_note_where where,
8902                         shared_hash vars)
8903 {
8904   emit_note_data data;
8905   variable_table_type htab = shared_hash_htab (vars);
8906
8907   if (!changed_variables.elements ())
8908     return;
8909
8910   if (MAY_HAVE_DEBUG_INSNS)
8911     process_changed_values (htab);
8912
8913   data.insn = insn;
8914   data.where = where;
8915   data.vars = htab;
8916
8917   changed_variables
8918     .traverse <emit_note_data*, emit_note_insn_var_location> (&data);
8919 }
8920
8921 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
8922    same variable in hash table DATA or is not there at all.  */
8923
8924 int
8925 emit_notes_for_differences_1 (variable_def **slot, variable_table_type new_vars)
8926 {
8927   variable old_var, new_var;
8928
8929   old_var = *slot;
8930   new_var = new_vars.find_with_hash (old_var->dv, dv_htab_hash (old_var->dv));
8931
8932   if (!new_var)
8933     {
8934       /* Variable has disappeared.  */
8935       variable empty_var = NULL;
8936
8937       if (old_var->onepart == ONEPART_VALUE
8938           || old_var->onepart == ONEPART_DEXPR)
8939         {
8940           empty_var = variable_from_dropped (old_var->dv, NO_INSERT);
8941           if (empty_var)
8942             {
8943               gcc_checking_assert (!empty_var->in_changed_variables);
8944               if (!VAR_LOC_1PAUX (old_var))
8945                 {
8946                   VAR_LOC_1PAUX (old_var) = VAR_LOC_1PAUX (empty_var);
8947                   VAR_LOC_1PAUX (empty_var) = NULL;
8948                 }
8949               else
8950                 gcc_checking_assert (!VAR_LOC_1PAUX (empty_var));
8951             }
8952         }
8953
8954       if (!empty_var)
8955         {
8956           empty_var = (variable) pool_alloc (onepart_pool (old_var->onepart));
8957           empty_var->dv = old_var->dv;
8958           empty_var->refcount = 0;
8959           empty_var->n_var_parts = 0;
8960           empty_var->onepart = old_var->onepart;
8961           empty_var->in_changed_variables = false;
8962         }
8963
8964       if (empty_var->onepart)
8965         {
8966           /* Propagate the auxiliary data to (ultimately)
8967              changed_variables.  */
8968           empty_var->var_part[0].loc_chain = NULL;
8969           empty_var->var_part[0].cur_loc = NULL;
8970           VAR_LOC_1PAUX (empty_var) = VAR_LOC_1PAUX (old_var);
8971           VAR_LOC_1PAUX (old_var) = NULL;
8972         }
8973       variable_was_changed (empty_var, NULL);
8974       /* Continue traversing the hash table.  */
8975       return 1;
8976     }
8977   /* Update cur_loc and one-part auxiliary data, before new_var goes
8978      through variable_was_changed.  */
8979   if (old_var != new_var && new_var->onepart)
8980     {
8981       gcc_checking_assert (VAR_LOC_1PAUX (new_var) == NULL);
8982       VAR_LOC_1PAUX (new_var) = VAR_LOC_1PAUX (old_var);
8983       VAR_LOC_1PAUX (old_var) = NULL;
8984       new_var->var_part[0].cur_loc = old_var->var_part[0].cur_loc;
8985     }
8986   if (variable_different_p (old_var, new_var))
8987     variable_was_changed (new_var, NULL);
8988
8989   /* Continue traversing the hash table.  */
8990   return 1;
8991 }
8992
8993 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
8994    table DATA.  */
8995
8996 int
8997 emit_notes_for_differences_2 (variable_def **slot, variable_table_type old_vars)
8998 {
8999   variable old_var, new_var;
9000
9001   new_var = *slot;
9002   old_var = old_vars.find_with_hash (new_var->dv, dv_htab_hash (new_var->dv));
9003   if (!old_var)
9004     {
9005       int i;
9006       for (i = 0; i < new_var->n_var_parts; i++)
9007         new_var->var_part[i].cur_loc = NULL;
9008       variable_was_changed (new_var, NULL);
9009     }
9010
9011   /* Continue traversing the hash table.  */
9012   return 1;
9013 }
9014
9015 /* Emit notes before INSN for differences between dataflow sets OLD_SET and
9016    NEW_SET.  */
9017
9018 static void
9019 emit_notes_for_differences (rtx insn, dataflow_set *old_set,
9020                             dataflow_set *new_set)
9021 {
9022   shared_hash_htab (old_set->vars)
9023     .traverse <variable_table_type, emit_notes_for_differences_1>
9024       (shared_hash_htab (new_set->vars));
9025   shared_hash_htab (new_set->vars)
9026     .traverse <variable_table_type, emit_notes_for_differences_2>
9027       (shared_hash_htab (old_set->vars));
9028   emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, new_set->vars);
9029 }
9030
9031 /* Return the next insn after INSN that is not a NOTE_INSN_VAR_LOCATION.  */
9032
9033 static rtx
9034 next_non_note_insn_var_location (rtx insn)
9035 {
9036   while (insn)
9037     {
9038       insn = NEXT_INSN (insn);
9039       if (insn == 0
9040           || !NOTE_P (insn)
9041           || NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION)
9042         break;
9043     }
9044
9045   return insn;
9046 }
9047
9048 /* Emit the notes for changes of location parts in the basic block BB.  */
9049
9050 static void
9051 emit_notes_in_bb (basic_block bb, dataflow_set *set)
9052 {
9053   unsigned int i;
9054   micro_operation *mo;
9055
9056   dataflow_set_clear (set);
9057   dataflow_set_copy (set, &VTI (bb)->in);
9058
9059   FOR_EACH_VEC_ELT (VTI (bb)->mos, i, mo)
9060     {
9061       rtx insn = mo->insn;
9062       rtx next_insn = next_non_note_insn_var_location (insn);
9063
9064       switch (mo->type)
9065         {
9066           case MO_CALL:
9067             dataflow_set_clear_at_call (set);
9068             emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars);
9069             {
9070               rtx arguments = mo->u.loc, *p = &arguments, note;
9071               while (*p)
9072                 {
9073                   XEXP (XEXP (*p, 0), 1)
9074                     = vt_expand_loc (XEXP (XEXP (*p, 0), 1),
9075                                      shared_hash_htab (set->vars));
9076                   /* If expansion is successful, keep it in the list.  */
9077                   if (XEXP (XEXP (*p, 0), 1))
9078                     p = &XEXP (*p, 1);
9079                   /* Otherwise, if the following item is data_value for it,
9080                      drop it too too.  */
9081                   else if (XEXP (*p, 1)
9082                            && REG_P (XEXP (XEXP (*p, 0), 0))
9083                            && MEM_P (XEXP (XEXP (XEXP (*p, 1), 0), 0))
9084                            && REG_P (XEXP (XEXP (XEXP (XEXP (*p, 1), 0), 0),
9085                                            0))
9086                            && REGNO (XEXP (XEXP (*p, 0), 0))
9087                               == REGNO (XEXP (XEXP (XEXP (XEXP (*p, 1), 0),
9088                                                     0), 0)))
9089                     *p = XEXP (XEXP (*p, 1), 1);
9090                   /* Just drop this item.  */
9091                   else
9092                     *p = XEXP (*p, 1);
9093                 }
9094               note = emit_note_after (NOTE_INSN_CALL_ARG_LOCATION, insn);
9095               NOTE_VAR_LOCATION (note) = arguments;
9096             }
9097             break;
9098
9099           case MO_USE:
9100             {
9101               rtx loc = mo->u.loc;
9102
9103               if (REG_P (loc))
9104                 var_reg_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
9105               else
9106                 var_mem_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
9107
9108               emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
9109             }
9110             break;
9111
9112           case MO_VAL_LOC:
9113             {
9114               rtx loc = mo->u.loc;
9115               rtx val, vloc;
9116               tree var;
9117
9118               if (GET_CODE (loc) == CONCAT)
9119                 {
9120                   val = XEXP (loc, 0);
9121                   vloc = XEXP (loc, 1);
9122                 }
9123               else
9124                 {
9125                   val = NULL_RTX;
9126                   vloc = loc;
9127                 }
9128
9129               var = PAT_VAR_LOCATION_DECL (vloc);
9130
9131               clobber_variable_part (set, NULL_RTX,
9132                                      dv_from_decl (var), 0, NULL_RTX);
9133               if (val)
9134                 {
9135                   if (VAL_NEEDS_RESOLUTION (loc))
9136                     val_resolve (set, val, PAT_VAR_LOCATION_LOC (vloc), insn);
9137                   set_variable_part (set, val, dv_from_decl (var), 0,
9138                                      VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
9139                                      INSERT);
9140                 }
9141               else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
9142                 set_variable_part (set, PAT_VAR_LOCATION_LOC (vloc),
9143                                    dv_from_decl (var), 0,
9144                                    VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
9145                                    INSERT);
9146
9147               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
9148             }
9149             break;
9150
9151           case MO_VAL_USE:
9152             {
9153               rtx loc = mo->u.loc;
9154               rtx val, vloc, uloc;
9155
9156               vloc = uloc = XEXP (loc, 1);
9157               val = XEXP (loc, 0);
9158
9159               if (GET_CODE (val) == CONCAT)
9160                 {
9161                   uloc = XEXP (val, 1);
9162                   val = XEXP (val, 0);
9163                 }
9164
9165               if (VAL_NEEDS_RESOLUTION (loc))
9166                 val_resolve (set, val, vloc, insn);
9167               else
9168                 val_store (set, val, uloc, insn, false);
9169
9170               if (VAL_HOLDS_TRACK_EXPR (loc))
9171                 {
9172                   if (GET_CODE (uloc) == REG)
9173                     var_reg_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
9174                                  NULL);
9175                   else if (GET_CODE (uloc) == MEM)
9176                     var_mem_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
9177                                  NULL);
9178                 }
9179
9180               emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
9181             }
9182             break;
9183
9184           case MO_VAL_SET:
9185             {
9186               rtx loc = mo->u.loc;
9187               rtx val, vloc, uloc;
9188               rtx dstv, srcv;
9189
9190               vloc = loc;
9191               uloc = XEXP (vloc, 1);
9192               val = XEXP (vloc, 0);
9193               vloc = uloc;
9194
9195               if (GET_CODE (uloc) == SET)
9196                 {
9197                   dstv = SET_DEST (uloc);
9198                   srcv = SET_SRC (uloc);
9199                 }
9200               else
9201                 {
9202                   dstv = uloc;
9203                   srcv = NULL;
9204                 }
9205
9206               if (GET_CODE (val) == CONCAT)
9207                 {
9208                   dstv = vloc = XEXP (val, 1);
9209                   val = XEXP (val, 0);
9210                 }
9211
9212               if (GET_CODE (vloc) == SET)
9213                 {
9214                   srcv = SET_SRC (vloc);
9215
9216                   gcc_assert (val != srcv);
9217                   gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
9218
9219                   dstv = vloc = SET_DEST (vloc);
9220
9221                   if (VAL_NEEDS_RESOLUTION (loc))
9222                     val_resolve (set, val, srcv, insn);
9223                 }
9224               else if (VAL_NEEDS_RESOLUTION (loc))
9225                 {
9226                   gcc_assert (GET_CODE (uloc) == SET
9227                               && GET_CODE (SET_SRC (uloc)) == REG);
9228                   val_resolve (set, val, SET_SRC (uloc), insn);
9229                 }
9230
9231               if (VAL_HOLDS_TRACK_EXPR (loc))
9232                 {
9233                   if (VAL_EXPR_IS_CLOBBERED (loc))
9234                     {
9235                       if (REG_P (uloc))
9236                         var_reg_delete (set, uloc, true);
9237                       else if (MEM_P (uloc))
9238                         {
9239                           gcc_assert (MEM_P (dstv));
9240                           gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (uloc));
9241                           var_mem_delete (set, dstv, true);
9242                         }
9243                     }
9244                   else
9245                     {
9246                       bool copied_p = VAL_EXPR_IS_COPIED (loc);
9247                       rtx src = NULL, dst = uloc;
9248                       enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
9249
9250                       if (GET_CODE (uloc) == SET)
9251                         {
9252                           src = SET_SRC (uloc);
9253                           dst = SET_DEST (uloc);
9254                         }
9255
9256                       if (copied_p)
9257                         {
9258                           status = find_src_status (set, src);
9259
9260                           src = find_src_set_src (set, src);
9261                         }
9262
9263                       if (REG_P (dst))
9264                         var_reg_delete_and_set (set, dst, !copied_p,
9265                                                 status, srcv);
9266                       else if (MEM_P (dst))
9267                         {
9268                           gcc_assert (MEM_P (dstv));
9269                           gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (dst));
9270                           var_mem_delete_and_set (set, dstv, !copied_p,
9271                                                   status, srcv);
9272                         }
9273                     }
9274                 }
9275               else if (REG_P (uloc))
9276                 var_regno_delete (set, REGNO (uloc));
9277               else if (MEM_P (uloc))
9278                 {
9279                   gcc_checking_assert (GET_CODE (vloc) == MEM);
9280                   gcc_checking_assert (vloc == dstv);
9281                   if (vloc != dstv)
9282                     clobber_overlapping_mems (set, vloc);
9283                 }
9284
9285               val_store (set, val, dstv, insn, true);
9286
9287               emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
9288                                       set->vars);
9289             }
9290             break;
9291
9292           case MO_SET:
9293             {
9294               rtx loc = mo->u.loc;
9295               rtx set_src = NULL;
9296
9297               if (GET_CODE (loc) == SET)
9298                 {
9299                   set_src = SET_SRC (loc);
9300                   loc = SET_DEST (loc);
9301                 }
9302
9303               if (REG_P (loc))
9304                 var_reg_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
9305                                         set_src);
9306               else
9307                 var_mem_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
9308                                         set_src);
9309
9310               emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
9311                                       set->vars);
9312             }
9313             break;
9314
9315           case MO_COPY:
9316             {
9317               rtx loc = mo->u.loc;
9318               enum var_init_status src_status;
9319               rtx set_src = NULL;
9320
9321               if (GET_CODE (loc) == SET)
9322                 {
9323                   set_src = SET_SRC (loc);
9324                   loc = SET_DEST (loc);
9325                 }
9326
9327               src_status = find_src_status (set, set_src);
9328               set_src = find_src_set_src (set, set_src);
9329
9330               if (REG_P (loc))
9331                 var_reg_delete_and_set (set, loc, false, src_status, set_src);
9332               else
9333                 var_mem_delete_and_set (set, loc, false, src_status, set_src);
9334
9335               emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
9336                                       set->vars);
9337             }
9338             break;
9339
9340           case MO_USE_NO_VAR:
9341             {
9342               rtx loc = mo->u.loc;
9343
9344               if (REG_P (loc))
9345                 var_reg_delete (set, loc, false);
9346               else
9347                 var_mem_delete (set, loc, false);
9348
9349               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
9350             }
9351             break;
9352
9353           case MO_CLOBBER:
9354             {
9355               rtx loc = mo->u.loc;
9356
9357               if (REG_P (loc))
9358                 var_reg_delete (set, loc, true);
9359               else
9360                 var_mem_delete (set, loc, true);
9361
9362               emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
9363                                       set->vars);
9364             }
9365             break;
9366
9367           case MO_ADJUST:
9368             set->stack_adjust += mo->u.adjust;
9369             break;
9370         }
9371     }
9372 }
9373
9374 /* Emit notes for the whole function.  */
9375
9376 static void
9377 vt_emit_notes (void)
9378 {
9379   basic_block bb;
9380   dataflow_set cur;
9381
9382   gcc_assert (!changed_variables.elements ());
9383
9384   /* Free memory occupied by the out hash tables, as they aren't used
9385      anymore.  */
9386   FOR_EACH_BB (bb)
9387     dataflow_set_clear (&VTI (bb)->out);
9388
9389   /* Enable emitting notes by functions (mainly by set_variable_part and
9390      delete_variable_part).  */
9391   emit_notes = true;
9392
9393   if (MAY_HAVE_DEBUG_INSNS)
9394     {
9395       dropped_values.create (cselib_get_next_uid () * 2);
9396       loc_exp_dep_pool = create_alloc_pool ("loc_exp_dep pool",
9397                                             sizeof (loc_exp_dep), 64);
9398     }
9399
9400   dataflow_set_init (&cur);
9401
9402   FOR_EACH_BB (bb)
9403     {
9404       /* Emit the notes for changes of variable locations between two
9405          subsequent basic blocks.  */
9406       emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
9407
9408       if (MAY_HAVE_DEBUG_INSNS)
9409         local_get_addr_cache = pointer_map_create ();
9410
9411       /* Emit the notes for the changes in the basic block itself.  */
9412       emit_notes_in_bb (bb, &cur);
9413
9414       if (MAY_HAVE_DEBUG_INSNS)
9415         pointer_map_destroy (local_get_addr_cache);
9416       local_get_addr_cache = NULL;
9417
9418       /* Free memory occupied by the in hash table, we won't need it
9419          again.  */
9420       dataflow_set_clear (&VTI (bb)->in);
9421     }
9422 #ifdef ENABLE_CHECKING
9423   shared_hash_htab (cur.vars)
9424     .traverse <variable_table_type, emit_notes_for_differences_1>
9425       (shared_hash_htab (empty_shared_hash));
9426 #endif
9427   dataflow_set_destroy (&cur);
9428
9429   if (MAY_HAVE_DEBUG_INSNS)
9430     dropped_values.dispose ();
9431
9432   emit_notes = false;
9433 }
9434
9435 /* If there is a declaration and offset associated with register/memory RTL
9436    assign declaration to *DECLP and offset to *OFFSETP, and return true.  */
9437
9438 static bool
9439 vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
9440 {
9441   if (REG_P (rtl))
9442     {
9443       if (REG_ATTRS (rtl))
9444         {
9445           *declp = REG_EXPR (rtl);
9446           *offsetp = REG_OFFSET (rtl);
9447           return true;
9448         }
9449     }
9450   else if (MEM_P (rtl))
9451     {
9452       if (MEM_ATTRS (rtl))
9453         {
9454           *declp = MEM_EXPR (rtl);
9455           *offsetp = INT_MEM_OFFSET (rtl);
9456           return true;
9457         }
9458     }
9459   return false;
9460 }
9461
9462 /* Record the value for the ENTRY_VALUE of RTL as a global equivalence
9463    of VAL.  */
9464
9465 static void
9466 record_entry_value (cselib_val *val, rtx rtl)
9467 {
9468   rtx ev = gen_rtx_ENTRY_VALUE (GET_MODE (rtl));
9469
9470   ENTRY_VALUE_EXP (ev) = rtl;
9471
9472   cselib_add_permanent_equiv (val, ev, get_insns ());
9473 }
9474
9475 /* Insert function parameter PARM in IN and OUT sets of ENTRY_BLOCK.  */
9476
9477 static void
9478 vt_add_function_parameter (tree parm)
9479 {
9480   rtx decl_rtl = DECL_RTL_IF_SET (parm);
9481   rtx incoming = DECL_INCOMING_RTL (parm);
9482   tree decl;
9483   enum machine_mode mode;
9484   HOST_WIDE_INT offset;
9485   dataflow_set *out;
9486   decl_or_value dv;
9487
9488   if (TREE_CODE (parm) != PARM_DECL)
9489     return;
9490
9491   if (!decl_rtl || !incoming)
9492     return;
9493
9494   if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
9495     return;
9496
9497   /* If there is a DRAP register or a pseudo in internal_arg_pointer,
9498      rewrite the incoming location of parameters passed on the stack
9499      into MEMs based on the argument pointer, so that incoming doesn't
9500      depend on a pseudo.  */
9501   if (MEM_P (incoming)
9502       && (XEXP (incoming, 0) == crtl->args.internal_arg_pointer
9503           || (GET_CODE (XEXP (incoming, 0)) == PLUS
9504               && XEXP (XEXP (incoming, 0), 0)
9505                  == crtl->args.internal_arg_pointer
9506               && CONST_INT_P (XEXP (XEXP (incoming, 0), 1)))))
9507     {
9508       HOST_WIDE_INT off = -FIRST_PARM_OFFSET (current_function_decl);
9509       if (GET_CODE (XEXP (incoming, 0)) == PLUS)
9510         off += INTVAL (XEXP (XEXP (incoming, 0), 1));
9511       incoming
9512         = replace_equiv_address_nv (incoming,
9513                                     plus_constant (Pmode,
9514                                                    arg_pointer_rtx, off));
9515     }
9516
9517 #ifdef HAVE_window_save
9518   /* DECL_INCOMING_RTL uses the INCOMING_REGNO of parameter registers.
9519      If the target machine has an explicit window save instruction, the
9520      actual entry value is the corresponding OUTGOING_REGNO instead.  */
9521   if (HAVE_window_save && !crtl->uses_only_leaf_regs)
9522     {
9523       if (REG_P (incoming)
9524           && HARD_REGISTER_P (incoming)
9525           && OUTGOING_REGNO (REGNO (incoming)) != REGNO (incoming))
9526         {
9527           parm_reg_t p;
9528           p.incoming = incoming;
9529           incoming
9530             = gen_rtx_REG_offset (incoming, GET_MODE (incoming),
9531                                   OUTGOING_REGNO (REGNO (incoming)), 0);
9532           p.outgoing = incoming;
9533           vec_safe_push (windowed_parm_regs, p);
9534         }
9535       else if (MEM_P (incoming)
9536                && REG_P (XEXP (incoming, 0))
9537                && HARD_REGISTER_P (XEXP (incoming, 0)))
9538         {
9539           rtx reg = XEXP (incoming, 0);
9540           if (OUTGOING_REGNO (REGNO (reg)) != REGNO (reg))
9541             {
9542               parm_reg_t p;
9543               p.incoming = reg;
9544               reg = gen_raw_REG (GET_MODE (reg), OUTGOING_REGNO (REGNO (reg)));
9545               p.outgoing = reg;
9546               vec_safe_push (windowed_parm_regs, p);
9547               incoming = replace_equiv_address_nv (incoming, reg);
9548             }
9549         }
9550     }
9551 #endif
9552
9553   if (!vt_get_decl_and_offset (incoming, &decl, &offset))
9554     {
9555       if (MEM_P (incoming))
9556         {
9557           /* This means argument is passed by invisible reference.  */
9558           offset = 0;
9559           decl = parm;
9560         }
9561       else
9562         {
9563           if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
9564             return;
9565           offset += byte_lowpart_offset (GET_MODE (incoming),
9566                                          GET_MODE (decl_rtl));
9567         }
9568     }
9569
9570   if (!decl)
9571     return;
9572
9573   if (parm != decl)
9574     {
9575       /* If that DECL_RTL wasn't a pseudo that got spilled to
9576          memory, bail out.  Otherwise, the spill slot sharing code
9577          will force the memory to reference spill_slot_decl (%sfp),
9578          so we don't match above.  That's ok, the pseudo must have
9579          referenced the entire parameter, so just reset OFFSET.  */
9580       if (decl != get_spill_slot_decl (false))
9581         return;
9582       offset = 0;
9583     }
9584
9585   if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
9586     return;
9587
9588   out = &VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->out;
9589
9590   dv = dv_from_decl (parm);
9591
9592   if (target_for_debug_bind (parm)
9593       /* We can't deal with these right now, because this kind of
9594          variable is single-part.  ??? We could handle parallels
9595          that describe multiple locations for the same single
9596          value, but ATM we don't.  */
9597       && GET_CODE (incoming) != PARALLEL)
9598     {
9599       cselib_val *val;
9600       rtx lowpart;
9601
9602       /* ??? We shouldn't ever hit this, but it may happen because
9603          arguments passed by invisible reference aren't dealt with
9604          above: incoming-rtl will have Pmode rather than the
9605          expected mode for the type.  */
9606       if (offset)
9607         return;
9608
9609       lowpart = var_lowpart (mode, incoming);
9610       if (!lowpart)
9611         return;
9612
9613       val = cselib_lookup_from_insn (lowpart, mode, true,
9614                                      VOIDmode, get_insns ());
9615
9616       /* ??? Float-typed values in memory are not handled by
9617          cselib.  */
9618       if (val)
9619         {
9620           preserve_value (val);
9621           set_variable_part (out, val->val_rtx, dv, offset,
9622                              VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9623           dv = dv_from_value (val->val_rtx);
9624         }
9625
9626       if (MEM_P (incoming))
9627         {
9628           val = cselib_lookup_from_insn (XEXP (incoming, 0), mode, true,
9629                                          VOIDmode, get_insns ());
9630           if (val)
9631             {
9632               preserve_value (val);
9633               incoming = replace_equiv_address_nv (incoming, val->val_rtx);
9634             }
9635         }
9636     }
9637
9638   if (REG_P (incoming))
9639     {
9640       incoming = var_lowpart (mode, incoming);
9641       gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
9642       attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
9643                          incoming);
9644       set_variable_part (out, incoming, dv, offset,
9645                          VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9646       if (dv_is_value_p (dv))
9647         {
9648           record_entry_value (CSELIB_VAL_PTR (dv_as_value (dv)), incoming);
9649           if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE
9650               && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (parm))))
9651             {
9652               enum machine_mode indmode
9653                 = TYPE_MODE (TREE_TYPE (TREE_TYPE (parm)));
9654               rtx mem = gen_rtx_MEM (indmode, incoming);
9655               cselib_val *val = cselib_lookup_from_insn (mem, indmode, true,
9656                                                          VOIDmode,
9657                                                          get_insns ());
9658               if (val)
9659                 {
9660                   preserve_value (val);
9661                   record_entry_value (val, mem);
9662                   set_variable_part (out, mem, dv_from_value (val->val_rtx), 0,
9663                                      VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9664                 }
9665             }
9666         }
9667     }
9668   else if (MEM_P (incoming))
9669     {
9670       incoming = var_lowpart (mode, incoming);
9671       set_variable_part (out, incoming, dv, offset,
9672                          VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9673     }
9674 }
9675
9676 /* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */
9677
9678 static void
9679 vt_add_function_parameters (void)
9680 {
9681   tree parm;
9682
9683   for (parm = DECL_ARGUMENTS (current_function_decl);
9684        parm; parm = DECL_CHAIN (parm))
9685     vt_add_function_parameter (parm);
9686
9687   if (DECL_HAS_VALUE_EXPR_P (DECL_RESULT (current_function_decl)))
9688     {
9689       tree vexpr = DECL_VALUE_EXPR (DECL_RESULT (current_function_decl));
9690
9691       if (TREE_CODE (vexpr) == INDIRECT_REF)
9692         vexpr = TREE_OPERAND (vexpr, 0);
9693
9694       if (TREE_CODE (vexpr) == PARM_DECL
9695           && DECL_ARTIFICIAL (vexpr)
9696           && !DECL_IGNORED_P (vexpr)
9697           && DECL_NAMELESS (vexpr))
9698         vt_add_function_parameter (vexpr);
9699     }
9700 }
9701
9702 /* Initialize cfa_base_rtx, create a preserved VALUE for it and
9703    ensure it isn't flushed during cselib_reset_table.
9704    Can be called only if frame_pointer_rtx resp. arg_pointer_rtx
9705    has been eliminated.  */
9706
9707 static void
9708 vt_init_cfa_base (void)
9709 {
9710   cselib_val *val;
9711
9712 #ifdef FRAME_POINTER_CFA_OFFSET
9713   cfa_base_rtx = frame_pointer_rtx;
9714   cfa_base_offset = -FRAME_POINTER_CFA_OFFSET (current_function_decl);
9715 #else
9716   cfa_base_rtx = arg_pointer_rtx;
9717   cfa_base_offset = -ARG_POINTER_CFA_OFFSET (current_function_decl);
9718 #endif
9719   if (cfa_base_rtx == hard_frame_pointer_rtx
9720       || !fixed_regs[REGNO (cfa_base_rtx)])
9721     {
9722       cfa_base_rtx = NULL_RTX;
9723       return;
9724     }
9725   if (!MAY_HAVE_DEBUG_INSNS)
9726     return;
9727
9728   /* Tell alias analysis that cfa_base_rtx should share
9729      find_base_term value with stack pointer or hard frame pointer.  */
9730   if (!frame_pointer_needed)
9731     vt_equate_reg_base_value (cfa_base_rtx, stack_pointer_rtx);
9732   else if (!crtl->stack_realign_tried)
9733     vt_equate_reg_base_value (cfa_base_rtx, hard_frame_pointer_rtx);
9734
9735   val = cselib_lookup_from_insn (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1,
9736                                  VOIDmode, get_insns ());
9737   preserve_value (val);
9738   cselib_preserve_cfa_base_value (val, REGNO (cfa_base_rtx));
9739 }
9740
9741 /* Allocate and initialize the data structures for variable tracking
9742    and parse the RTL to get the micro operations.  */
9743
9744 static bool
9745 vt_initialize (void)
9746 {
9747   basic_block bb;
9748   HOST_WIDE_INT fp_cfa_offset = -1;
9749
9750   alloc_aux_for_blocks (sizeof (struct variable_tracking_info_def));
9751
9752   attrs_pool = create_alloc_pool ("attrs_def pool",
9753                                   sizeof (struct attrs_def), 1024);
9754   var_pool = create_alloc_pool ("variable_def pool",
9755                                 sizeof (struct variable_def)
9756                                 + (MAX_VAR_PARTS - 1)
9757                                 * sizeof (((variable)NULL)->var_part[0]), 64);
9758   loc_chain_pool = create_alloc_pool ("location_chain_def pool",
9759                                       sizeof (struct location_chain_def),
9760                                       1024);
9761   shared_hash_pool = create_alloc_pool ("shared_hash_def pool",
9762                                         sizeof (struct shared_hash_def), 256);
9763   empty_shared_hash = (shared_hash) pool_alloc (shared_hash_pool);
9764   empty_shared_hash->refcount = 1;
9765   empty_shared_hash->htab.create (1);
9766   changed_variables.create (10);
9767
9768   /* Init the IN and OUT sets.  */
9769   FOR_ALL_BB (bb)
9770     {
9771       VTI (bb)->visited = false;
9772       VTI (bb)->flooded = false;
9773       dataflow_set_init (&VTI (bb)->in);
9774       dataflow_set_init (&VTI (bb)->out);
9775       VTI (bb)->permp = NULL;
9776     }
9777
9778   if (MAY_HAVE_DEBUG_INSNS)
9779     {
9780       cselib_init (CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS);
9781       scratch_regs = BITMAP_ALLOC (NULL);
9782       valvar_pool = create_alloc_pool ("small variable_def pool",
9783                                        sizeof (struct variable_def), 256);
9784       preserved_values.create (256);
9785       global_get_addr_cache = pointer_map_create ();
9786     }
9787   else
9788     {
9789       scratch_regs = NULL;
9790       valvar_pool = NULL;
9791       global_get_addr_cache = NULL;
9792     }
9793
9794   if (MAY_HAVE_DEBUG_INSNS)
9795     {
9796       rtx reg, expr;
9797       int ofst;
9798       cselib_val *val;
9799
9800 #ifdef FRAME_POINTER_CFA_OFFSET
9801       reg = frame_pointer_rtx;
9802       ofst = FRAME_POINTER_CFA_OFFSET (current_function_decl);
9803 #else
9804       reg = arg_pointer_rtx;
9805       ofst = ARG_POINTER_CFA_OFFSET (current_function_decl);
9806 #endif
9807
9808       ofst -= INCOMING_FRAME_SP_OFFSET;
9809
9810       val = cselib_lookup_from_insn (reg, GET_MODE (reg), 1,
9811                                      VOIDmode, get_insns ());
9812       preserve_value (val);
9813       cselib_preserve_cfa_base_value (val, REGNO (reg));
9814       expr = plus_constant (GET_MODE (stack_pointer_rtx),
9815                             stack_pointer_rtx, -ofst);
9816       cselib_add_permanent_equiv (val, expr, get_insns ());
9817
9818       if (ofst)
9819         {
9820           val = cselib_lookup_from_insn (stack_pointer_rtx,
9821                                          GET_MODE (stack_pointer_rtx), 1,
9822                                          VOIDmode, get_insns ());
9823           preserve_value (val);
9824           expr = plus_constant (GET_MODE (reg), reg, ofst);
9825           cselib_add_permanent_equiv (val, expr, get_insns ());
9826         }
9827     }
9828
9829   /* In order to factor out the adjustments made to the stack pointer or to
9830      the hard frame pointer and thus be able to use DW_OP_fbreg operations
9831      instead of individual location lists, we're going to rewrite MEMs based
9832      on them into MEMs based on the CFA by de-eliminating stack_pointer_rtx
9833      or hard_frame_pointer_rtx to the virtual CFA pointer frame_pointer_rtx
9834      resp. arg_pointer_rtx.  We can do this either when there is no frame
9835      pointer in the function and stack adjustments are consistent for all
9836      basic blocks or when there is a frame pointer and no stack realignment.
9837      But we first have to check that frame_pointer_rtx resp. arg_pointer_rtx
9838      has been eliminated.  */
9839   if (!frame_pointer_needed)
9840     {
9841       rtx reg, elim;
9842
9843       if (!vt_stack_adjustments ())
9844         return false;
9845
9846 #ifdef FRAME_POINTER_CFA_OFFSET
9847       reg = frame_pointer_rtx;
9848 #else
9849       reg = arg_pointer_rtx;
9850 #endif
9851       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
9852       if (elim != reg)
9853         {
9854           if (GET_CODE (elim) == PLUS)
9855             elim = XEXP (elim, 0);
9856           if (elim == stack_pointer_rtx)
9857             vt_init_cfa_base ();
9858         }
9859     }
9860   else if (!crtl->stack_realign_tried)
9861     {
9862       rtx reg, elim;
9863
9864 #ifdef FRAME_POINTER_CFA_OFFSET
9865       reg = frame_pointer_rtx;
9866       fp_cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
9867 #else
9868       reg = arg_pointer_rtx;
9869       fp_cfa_offset = ARG_POINTER_CFA_OFFSET (current_function_decl);
9870 #endif
9871       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
9872       if (elim != reg)
9873         {
9874           if (GET_CODE (elim) == PLUS)
9875             {
9876               fp_cfa_offset -= INTVAL (XEXP (elim, 1));
9877               elim = XEXP (elim, 0);
9878             }
9879           if (elim != hard_frame_pointer_rtx)
9880             fp_cfa_offset = -1;
9881         }
9882       else
9883         fp_cfa_offset = -1;
9884     }
9885
9886   /* If the stack is realigned and a DRAP register is used, we're going to
9887      rewrite MEMs based on it representing incoming locations of parameters
9888      passed on the stack into MEMs based on the argument pointer.  Although
9889      we aren't going to rewrite other MEMs, we still need to initialize the
9890      virtual CFA pointer in order to ensure that the argument pointer will
9891      be seen as a constant throughout the function.
9892
9893      ??? This doesn't work if FRAME_POINTER_CFA_OFFSET is defined.  */
9894   else if (stack_realign_drap)
9895     {
9896       rtx reg, elim;
9897
9898 #ifdef FRAME_POINTER_CFA_OFFSET
9899       reg = frame_pointer_rtx;
9900 #else
9901       reg = arg_pointer_rtx;
9902 #endif
9903       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
9904       if (elim != reg)
9905         {
9906           if (GET_CODE (elim) == PLUS)
9907             elim = XEXP (elim, 0);
9908           if (elim == hard_frame_pointer_rtx)
9909             vt_init_cfa_base ();
9910         }
9911     }
9912
9913   hard_frame_pointer_adjustment = -1;
9914
9915   vt_add_function_parameters ();
9916
9917   FOR_EACH_BB (bb)
9918     {
9919       rtx insn;
9920       HOST_WIDE_INT pre, post = 0;
9921       basic_block first_bb, last_bb;
9922
9923       if (MAY_HAVE_DEBUG_INSNS)
9924         {
9925           cselib_record_sets_hook = add_with_sets;
9926           if (dump_file && (dump_flags & TDF_DETAILS))
9927             fprintf (dump_file, "first value: %i\n",
9928                      cselib_get_next_uid ());
9929         }
9930
9931       first_bb = bb;
9932       for (;;)
9933         {
9934           edge e;
9935           if (bb->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
9936               || ! single_pred_p (bb->next_bb))
9937             break;
9938           e = find_edge (bb, bb->next_bb);
9939           if (! e || (e->flags & EDGE_FALLTHRU) == 0)
9940             break;
9941           bb = bb->next_bb;
9942         }
9943       last_bb = bb;
9944
9945       /* Add the micro-operations to the vector.  */
9946       FOR_BB_BETWEEN (bb, first_bb, last_bb->next_bb, next_bb)
9947         {
9948           HOST_WIDE_INT offset = VTI (bb)->out.stack_adjust;
9949           VTI (bb)->out.stack_adjust = VTI (bb)->in.stack_adjust;
9950           for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
9951                insn = NEXT_INSN (insn))
9952             {
9953               if (INSN_P (insn))
9954                 {
9955                   if (!frame_pointer_needed)
9956                     {
9957                       insn_stack_adjust_offset_pre_post (insn, &pre, &post);
9958                       if (pre)
9959                         {
9960                           micro_operation mo;
9961                           mo.type = MO_ADJUST;
9962                           mo.u.adjust = pre;
9963                           mo.insn = insn;
9964                           if (dump_file && (dump_flags & TDF_DETAILS))
9965                             log_op_type (PATTERN (insn), bb, insn,
9966                                          MO_ADJUST, dump_file);
9967                           VTI (bb)->mos.safe_push (mo);
9968                           VTI (bb)->out.stack_adjust += pre;
9969                         }
9970                     }
9971
9972                   cselib_hook_called = false;
9973                   adjust_insn (bb, insn);
9974                   if (MAY_HAVE_DEBUG_INSNS)
9975                     {
9976                       if (CALL_P (insn))
9977                         prepare_call_arguments (bb, insn);
9978                       cselib_process_insn (insn);
9979                       if (dump_file && (dump_flags & TDF_DETAILS))
9980                         {
9981                           print_rtl_single (dump_file, insn);
9982                           dump_cselib_table (dump_file);
9983                         }
9984                     }
9985                   if (!cselib_hook_called)
9986                     add_with_sets (insn, 0, 0);
9987                   cancel_changes (0);
9988
9989                   if (!frame_pointer_needed && post)
9990                     {
9991                       micro_operation mo;
9992                       mo.type = MO_ADJUST;
9993                       mo.u.adjust = post;
9994                       mo.insn = insn;
9995                       if (dump_file && (dump_flags & TDF_DETAILS))
9996                         log_op_type (PATTERN (insn), bb, insn,
9997                                      MO_ADJUST, dump_file);
9998                       VTI (bb)->mos.safe_push (mo);
9999                       VTI (bb)->out.stack_adjust += post;
10000                     }
10001
10002                   if (fp_cfa_offset != -1
10003                       && hard_frame_pointer_adjustment == -1
10004                       && fp_setter_insn (insn))
10005                     {
10006                       vt_init_cfa_base ();
10007                       hard_frame_pointer_adjustment = fp_cfa_offset;
10008                       /* Disassociate sp from fp now.  */
10009                       if (MAY_HAVE_DEBUG_INSNS)
10010                         {
10011                           cselib_val *v;
10012                           cselib_invalidate_rtx (stack_pointer_rtx);
10013                           v = cselib_lookup (stack_pointer_rtx, Pmode, 1,
10014                                              VOIDmode);
10015                           if (v && !cselib_preserved_value_p (v))
10016                             {
10017                               cselib_set_value_sp_based (v);
10018                               preserve_value (v);
10019                             }
10020                         }
10021                     }
10022                 }
10023             }
10024           gcc_assert (offset == VTI (bb)->out.stack_adjust);
10025         }
10026
10027       bb = last_bb;
10028
10029       if (MAY_HAVE_DEBUG_INSNS)
10030         {
10031           cselib_preserve_only_values ();
10032           cselib_reset_table (cselib_get_next_uid ());
10033           cselib_record_sets_hook = NULL;
10034         }
10035     }
10036
10037   hard_frame_pointer_adjustment = -1;
10038   VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->flooded = true;
10039   cfa_base_rtx = NULL_RTX;
10040   return true;
10041 }
10042
10043 /* This is *not* reset after each function.  It gives each
10044    NOTE_INSN_DELETED_DEBUG_LABEL in the entire compilation
10045    a unique label number.  */
10046
10047 static int debug_label_num = 1;
10048
10049 /* Get rid of all debug insns from the insn stream.  */
10050
10051 static void
10052 delete_debug_insns (void)
10053 {
10054   basic_block bb;
10055   rtx insn, next;
10056
10057   if (!MAY_HAVE_DEBUG_INSNS)
10058     return;
10059
10060   FOR_EACH_BB (bb)
10061     {
10062       FOR_BB_INSNS_SAFE (bb, insn, next)
10063         if (DEBUG_INSN_P (insn))
10064           {
10065             tree decl = INSN_VAR_LOCATION_DECL (insn);
10066             if (TREE_CODE (decl) == LABEL_DECL
10067                 && DECL_NAME (decl)
10068                 && !DECL_RTL_SET_P (decl))
10069               {
10070                 PUT_CODE (insn, NOTE);
10071                 NOTE_KIND (insn) = NOTE_INSN_DELETED_DEBUG_LABEL;
10072                 NOTE_DELETED_LABEL_NAME (insn)
10073                   = IDENTIFIER_POINTER (DECL_NAME (decl));
10074                 SET_DECL_RTL (decl, insn);
10075                 CODE_LABEL_NUMBER (insn) = debug_label_num++;
10076               }
10077             else
10078               delete_insn (insn);
10079           }
10080     }
10081 }
10082
10083 /* Run a fast, BB-local only version of var tracking, to take care of
10084    information that we don't do global analysis on, such that not all
10085    information is lost.  If SKIPPED holds, we're skipping the global
10086    pass entirely, so we should try to use information it would have
10087    handled as well..  */
10088
10089 static void
10090 vt_debug_insns_local (bool skipped ATTRIBUTE_UNUSED)
10091 {
10092   /* ??? Just skip it all for now.  */
10093   delete_debug_insns ();
10094 }
10095
10096 /* Free the data structures needed for variable tracking.  */
10097
10098 static void
10099 vt_finalize (void)
10100 {
10101   basic_block bb;
10102
10103   FOR_EACH_BB (bb)
10104     {
10105       VTI (bb)->mos.release ();
10106     }
10107
10108   FOR_ALL_BB (bb)
10109     {
10110       dataflow_set_destroy (&VTI (bb)->in);
10111       dataflow_set_destroy (&VTI (bb)->out);
10112       if (VTI (bb)->permp)
10113         {
10114           dataflow_set_destroy (VTI (bb)->permp);
10115           XDELETE (VTI (bb)->permp);
10116         }
10117     }
10118   free_aux_for_blocks ();
10119   empty_shared_hash->htab.dispose ();
10120   changed_variables.dispose ();
10121   free_alloc_pool (attrs_pool);
10122   free_alloc_pool (var_pool);
10123   free_alloc_pool (loc_chain_pool);
10124   free_alloc_pool (shared_hash_pool);
10125
10126   if (MAY_HAVE_DEBUG_INSNS)
10127     {
10128       if (global_get_addr_cache)
10129         pointer_map_destroy (global_get_addr_cache);
10130       global_get_addr_cache = NULL;
10131       if (loc_exp_dep_pool)
10132         free_alloc_pool (loc_exp_dep_pool);
10133       loc_exp_dep_pool = NULL;
10134       free_alloc_pool (valvar_pool);
10135       preserved_values.release ();
10136       cselib_finish ();
10137       BITMAP_FREE (scratch_regs);
10138       scratch_regs = NULL;
10139     }
10140
10141 #ifdef HAVE_window_save
10142   vec_free (windowed_parm_regs);
10143 #endif
10144
10145   if (vui_vec)
10146     XDELETEVEC (vui_vec);
10147   vui_vec = NULL;
10148   vui_allocated = 0;
10149 }
10150
10151 /* The entry point to variable tracking pass.  */
10152
10153 static inline unsigned int
10154 variable_tracking_main_1 (void)
10155 {
10156   bool success;
10157
10158   if (flag_var_tracking_assignments < 0)
10159     {
10160       delete_debug_insns ();
10161       return 0;
10162     }
10163
10164   if (n_basic_blocks_for_fn (cfun) > 500 &&
10165       n_edges_for_fn (cfun) / n_basic_blocks_for_fn (cfun) >= 20)
10166     {
10167       vt_debug_insns_local (true);
10168       return 0;
10169     }
10170
10171   mark_dfs_back_edges ();
10172   if (!vt_initialize ())
10173     {
10174       vt_finalize ();
10175       vt_debug_insns_local (true);
10176       return 0;
10177     }
10178
10179   success = vt_find_locations ();
10180
10181   if (!success && flag_var_tracking_assignments > 0)
10182     {
10183       vt_finalize ();
10184
10185       delete_debug_insns ();
10186
10187       /* This is later restored by our caller.  */
10188       flag_var_tracking_assignments = 0;
10189
10190       success = vt_initialize ();
10191       gcc_assert (success);
10192
10193       success = vt_find_locations ();
10194     }
10195
10196   if (!success)
10197     {
10198       vt_finalize ();
10199       vt_debug_insns_local (false);
10200       return 0;
10201     }
10202
10203   if (dump_file && (dump_flags & TDF_DETAILS))
10204     {
10205       dump_dataflow_sets ();
10206       dump_reg_info (dump_file);
10207       dump_flow_info (dump_file, dump_flags);
10208     }
10209
10210   timevar_push (TV_VAR_TRACKING_EMIT);
10211   vt_emit_notes ();
10212   timevar_pop (TV_VAR_TRACKING_EMIT);
10213
10214   vt_finalize ();
10215   vt_debug_insns_local (false);
10216   return 0;
10217 }
10218
10219 unsigned int
10220 variable_tracking_main (void)
10221 {
10222   unsigned int ret;
10223   int save = flag_var_tracking_assignments;
10224
10225   ret = variable_tracking_main_1 ();
10226
10227   flag_var_tracking_assignments = save;
10228
10229   return ret;
10230 }
10231 \f
10232 static bool
10233 gate_handle_var_tracking (void)
10234 {
10235   return (flag_var_tracking && !targetm.delay_vartrack);
10236 }
10237
10238
10239
10240 namespace {
10241
10242 const pass_data pass_data_variable_tracking =
10243 {
10244   RTL_PASS, /* type */
10245   "vartrack", /* name */
10246   OPTGROUP_NONE, /* optinfo_flags */
10247   true, /* has_gate */
10248   true, /* has_execute */
10249   TV_VAR_TRACKING, /* tv_id */
10250   0, /* properties_required */
10251   0, /* properties_provided */
10252   0, /* properties_destroyed */
10253   0, /* todo_flags_start */
10254   ( TODO_verify_rtl_sharing | TODO_verify_flow ), /* todo_flags_finish */
10255 };
10256
10257 class pass_variable_tracking : public rtl_opt_pass
10258 {
10259 public:
10260   pass_variable_tracking (gcc::context *ctxt)
10261     : rtl_opt_pass (pass_data_variable_tracking, ctxt)
10262   {}
10263
10264   /* opt_pass methods: */
10265   bool gate () { return gate_handle_var_tracking (); }
10266   unsigned int execute () { return variable_tracking_main (); }
10267
10268 }; // class pass_variable_tracking
10269
10270 } // anon namespace
10271
10272 rtl_opt_pass *
10273 make_pass_variable_tracking (gcc::context *ctxt)
10274 {
10275   return new pass_variable_tracking (ctxt);
10276 }