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