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