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