rtl.h (get_call_rtx_from): New prototype.
[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             {
4926               HOST_WIDE_INT bitsize, bitpos, maxsize;
4927               tree innerdecl
4928                 = get_ref_base_and_extent (realdecl, &bitpos, &bitsize,
4929                                            &maxsize);
4930               if (!DECL_P (innerdecl)
4931                   || DECL_IGNORED_P (innerdecl)
4932                   || TREE_STATIC (innerdecl)
4933                   || bitsize <= 0
4934                   || bitpos + bitsize > 256
4935                   || bitsize != maxsize)
4936                 return 0;
4937               else
4938                 realdecl = expr;
4939             }
4940           else
4941             return 0;
4942         }
4943     }
4944
4945   /* Do not track EXPR if REALDECL it should be ignored for debugging
4946      purposes.  */
4947   if (DECL_IGNORED_P (realdecl))
4948     return 0;
4949
4950   /* Do not track global variables until we are able to emit correct location
4951      list for them.  */
4952   if (TREE_STATIC (realdecl))
4953     return 0;
4954
4955   /* When the EXPR is a DECL for alias of some variable (see example)
4956      the TREE_STATIC flag is not used.  Disable tracking all DECLs whose
4957      DECL_RTL contains SYMBOL_REF.
4958
4959      Example:
4960      extern char **_dl_argv_internal __attribute__ ((alias ("_dl_argv")));
4961      char **_dl_argv;
4962   */
4963   if (decl_rtl && MEM_P (decl_rtl)
4964       && contains_symbol_ref (XEXP (decl_rtl, 0)))
4965     return 0;
4966
4967   /* If RTX is a memory it should not be very large (because it would be
4968      an array or struct).  */
4969   if (decl_rtl && MEM_P (decl_rtl))
4970     {
4971       /* Do not track structures and arrays.  */
4972       if (GET_MODE (decl_rtl) == BLKmode
4973           || AGGREGATE_TYPE_P (TREE_TYPE (realdecl)))
4974         return 0;
4975       if (MEM_SIZE_KNOWN_P (decl_rtl)
4976           && MEM_SIZE (decl_rtl) > MAX_VAR_PARTS)
4977         return 0;
4978     }
4979
4980   DECL_CHANGED (expr) = 0;
4981   DECL_CHANGED (realdecl) = 0;
4982   return 1;
4983 }
4984
4985 /* Determine whether a given LOC refers to the same variable part as
4986    EXPR+OFFSET.  */
4987
4988 static bool
4989 same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset)
4990 {
4991   tree expr2;
4992   HOST_WIDE_INT offset2;
4993
4994   if (! DECL_P (expr))
4995     return false;
4996
4997   if (REG_P (loc))
4998     {
4999       expr2 = REG_EXPR (loc);
5000       offset2 = REG_OFFSET (loc);
5001     }
5002   else if (MEM_P (loc))
5003     {
5004       expr2 = MEM_EXPR (loc);
5005       offset2 = INT_MEM_OFFSET (loc);
5006     }
5007   else
5008     return false;
5009
5010   if (! expr2 || ! DECL_P (expr2))
5011     return false;
5012
5013   expr = var_debug_decl (expr);
5014   expr2 = var_debug_decl (expr2);
5015
5016   return (expr == expr2 && offset == offset2);
5017 }
5018
5019 /* LOC is a REG or MEM that we would like to track if possible.
5020    If EXPR is null, we don't know what expression LOC refers to,
5021    otherwise it refers to EXPR + OFFSET.  STORE_REG_P is true if
5022    LOC is an lvalue register.
5023
5024    Return true if EXPR is nonnull and if LOC, or some lowpart of it,
5025    is something we can track.  When returning true, store the mode of
5026    the lowpart we can track in *MODE_OUT (if nonnull) and its offset
5027    from EXPR in *OFFSET_OUT (if nonnull).  */
5028
5029 static bool
5030 track_loc_p (rtx loc, tree expr, HOST_WIDE_INT offset, bool store_reg_p,
5031              enum machine_mode *mode_out, HOST_WIDE_INT *offset_out)
5032 {
5033   enum machine_mode mode;
5034
5035   if (expr == NULL || !track_expr_p (expr, true))
5036     return false;
5037
5038   /* If REG was a paradoxical subreg, its REG_ATTRS will describe the
5039      whole subreg, but only the old inner part is really relevant.  */
5040   mode = GET_MODE (loc);
5041   if (REG_P (loc) && !HARD_REGISTER_NUM_P (ORIGINAL_REGNO (loc)))
5042     {
5043       enum machine_mode pseudo_mode;
5044
5045       pseudo_mode = PSEUDO_REGNO_MODE (ORIGINAL_REGNO (loc));
5046       if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (pseudo_mode))
5047         {
5048           offset += byte_lowpart_offset (pseudo_mode, mode);
5049           mode = pseudo_mode;
5050         }
5051     }
5052
5053   /* If LOC is a paradoxical lowpart of EXPR, refer to EXPR itself.
5054      Do the same if we are storing to a register and EXPR occupies
5055      the whole of register LOC; in that case, the whole of EXPR is
5056      being changed.  We exclude complex modes from the second case
5057      because the real and imaginary parts are represented as separate
5058      pseudo registers, even if the whole complex value fits into one
5059      hard register.  */
5060   if ((GET_MODE_SIZE (mode) > GET_MODE_SIZE (DECL_MODE (expr))
5061        || (store_reg_p
5062            && !COMPLEX_MODE_P (DECL_MODE (expr))
5063            && hard_regno_nregs[REGNO (loc)][DECL_MODE (expr)] == 1))
5064       && offset + byte_lowpart_offset (DECL_MODE (expr), mode) == 0)
5065     {
5066       mode = DECL_MODE (expr);
5067       offset = 0;
5068     }
5069
5070   if (offset < 0 || offset >= MAX_VAR_PARTS)
5071     return false;
5072
5073   if (mode_out)
5074     *mode_out = mode;
5075   if (offset_out)
5076     *offset_out = offset;
5077   return true;
5078 }
5079
5080 /* Return the MODE lowpart of LOC, or null if LOC is not something we
5081    want to track.  When returning nonnull, make sure that the attributes
5082    on the returned value are updated.  */
5083
5084 static rtx
5085 var_lowpart (enum machine_mode mode, rtx loc)
5086 {
5087   unsigned int offset, reg_offset, regno;
5088
5089   if (GET_MODE (loc) == mode)
5090     return loc;
5091
5092   if (!REG_P (loc) && !MEM_P (loc))
5093     return NULL;
5094
5095   offset = byte_lowpart_offset (mode, GET_MODE (loc));
5096
5097   if (MEM_P (loc))
5098     return adjust_address_nv (loc, mode, offset);
5099
5100   reg_offset = subreg_lowpart_offset (mode, GET_MODE (loc));
5101   regno = REGNO (loc) + subreg_regno_offset (REGNO (loc), GET_MODE (loc),
5102                                              reg_offset, mode);
5103   return gen_rtx_REG_offset (loc, mode, regno, offset);
5104 }
5105
5106 /* Carry information about uses and stores while walking rtx.  */
5107
5108 struct count_use_info
5109 {
5110   /* The insn where the RTX is.  */
5111   rtx insn;
5112
5113   /* The basic block where insn is.  */
5114   basic_block bb;
5115
5116   /* The array of n_sets sets in the insn, as determined by cselib.  */
5117   struct cselib_set *sets;
5118   int n_sets;
5119
5120   /* True if we're counting stores, false otherwise.  */
5121   bool store_p;
5122 };
5123
5124 /* Find a VALUE corresponding to X.   */
5125
5126 static inline cselib_val *
5127 find_use_val (rtx x, enum machine_mode mode, struct count_use_info *cui)
5128 {
5129   int i;
5130
5131   if (cui->sets)
5132     {
5133       /* This is called after uses are set up and before stores are
5134          processed by cselib, so it's safe to look up srcs, but not
5135          dsts.  So we look up expressions that appear in srcs or in
5136          dest expressions, but we search the sets array for dests of
5137          stores.  */
5138       if (cui->store_p)
5139         {
5140           /* Some targets represent memset and memcpy patterns
5141              by (set (mem:BLK ...) (reg:[QHSD]I ...)) or
5142              (set (mem:BLK ...) (const_int ...)) or
5143              (set (mem:BLK ...) (mem:BLK ...)).  Don't return anything
5144              in that case, otherwise we end up with mode mismatches.  */
5145           if (mode == BLKmode && MEM_P (x))
5146             return NULL;
5147           for (i = 0; i < cui->n_sets; i++)
5148             if (cui->sets[i].dest == x)
5149               return cui->sets[i].src_elt;
5150         }
5151       else
5152         return cselib_lookup (x, mode, 0, VOIDmode);
5153     }
5154
5155   return NULL;
5156 }
5157
5158 /* Replace all registers and addresses in an expression with VALUE
5159    expressions that map back to them, unless the expression is a
5160    register.  If no mapping is or can be performed, returns NULL.  */
5161
5162 static rtx
5163 replace_expr_with_values (rtx loc)
5164 {
5165   if (REG_P (loc) || GET_CODE (loc) == ENTRY_VALUE)
5166     return NULL;
5167   else if (MEM_P (loc))
5168     {
5169       cselib_val *addr = cselib_lookup (XEXP (loc, 0),
5170                                         get_address_mode (loc), 0,
5171                                         GET_MODE (loc));
5172       if (addr)
5173         return replace_equiv_address_nv (loc, addr->val_rtx);
5174       else
5175         return NULL;
5176     }
5177   else
5178     return cselib_subst_to_values (loc, VOIDmode);
5179 }
5180
5181 /* Return true if *X is a DEBUG_EXPR.  Usable as an argument to
5182    for_each_rtx to tell whether there are any DEBUG_EXPRs within
5183    RTX.  */
5184
5185 static int
5186 rtx_debug_expr_p (rtx *x, void *data ATTRIBUTE_UNUSED)
5187 {
5188   rtx loc = *x;
5189
5190   return GET_CODE (loc) == DEBUG_EXPR;
5191 }
5192
5193 /* Determine what kind of micro operation to choose for a USE.  Return
5194    MO_CLOBBER if no micro operation is to be generated.  */
5195
5196 static enum micro_operation_type
5197 use_type (rtx loc, struct count_use_info *cui, enum machine_mode *modep)
5198 {
5199   tree expr;
5200
5201   if (cui && cui->sets)
5202     {
5203       if (GET_CODE (loc) == VAR_LOCATION)
5204         {
5205           if (track_expr_p (PAT_VAR_LOCATION_DECL (loc), false))
5206             {
5207               rtx ploc = PAT_VAR_LOCATION_LOC (loc);
5208               if (! VAR_LOC_UNKNOWN_P (ploc))
5209                 {
5210                   cselib_val *val = cselib_lookup (ploc, GET_MODE (loc), 1,
5211                                                    VOIDmode);
5212
5213                   /* ??? flag_float_store and volatile mems are never
5214                      given values, but we could in theory use them for
5215                      locations.  */
5216                   gcc_assert (val || 1);
5217                 }
5218               return MO_VAL_LOC;
5219             }
5220           else
5221             return MO_CLOBBER;
5222         }
5223
5224       if (REG_P (loc) || MEM_P (loc))
5225         {
5226           if (modep)
5227             *modep = GET_MODE (loc);
5228           if (cui->store_p)
5229             {
5230               if (REG_P (loc)
5231                   || (find_use_val (loc, GET_MODE (loc), cui)
5232                       && cselib_lookup (XEXP (loc, 0),
5233                                         get_address_mode (loc), 0,
5234                                         GET_MODE (loc))))
5235                 return MO_VAL_SET;
5236             }
5237           else
5238             {
5239               cselib_val *val = find_use_val (loc, GET_MODE (loc), cui);
5240
5241               if (val && !cselib_preserved_value_p (val))
5242                 return MO_VAL_USE;
5243             }
5244         }
5245     }
5246
5247   if (REG_P (loc))
5248     {
5249       gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
5250
5251       if (loc == cfa_base_rtx)
5252         return MO_CLOBBER;
5253       expr = REG_EXPR (loc);
5254
5255       if (!expr)
5256         return MO_USE_NO_VAR;
5257       else if (target_for_debug_bind (var_debug_decl (expr)))
5258         return MO_CLOBBER;
5259       else if (track_loc_p (loc, expr, REG_OFFSET (loc),
5260                             false, modep, NULL))
5261         return MO_USE;
5262       else
5263         return MO_USE_NO_VAR;
5264     }
5265   else if (MEM_P (loc))
5266     {
5267       expr = MEM_EXPR (loc);
5268
5269       if (!expr)
5270         return MO_CLOBBER;
5271       else if (target_for_debug_bind (var_debug_decl (expr)))
5272         return MO_CLOBBER;
5273       else if (track_loc_p (loc, expr, INT_MEM_OFFSET (loc),
5274                             false, modep, NULL)
5275                /* Multi-part variables shouldn't refer to one-part
5276                   variable names such as VALUEs (never happens) or
5277                   DEBUG_EXPRs (only happens in the presence of debug
5278                   insns).  */
5279                && (!MAY_HAVE_DEBUG_INSNS
5280                    || !for_each_rtx (&XEXP (loc, 0), rtx_debug_expr_p, NULL)))
5281         return MO_USE;
5282       else
5283         return MO_CLOBBER;
5284     }
5285
5286   return MO_CLOBBER;
5287 }
5288
5289 /* Log to OUT information about micro-operation MOPT involving X in
5290    INSN of BB.  */
5291
5292 static inline void
5293 log_op_type (rtx x, basic_block bb, rtx insn,
5294              enum micro_operation_type mopt, FILE *out)
5295 {
5296   fprintf (out, "bb %i op %i insn %i %s ",
5297            bb->index, VEC_length (micro_operation, VTI (bb)->mos),
5298            INSN_UID (insn), micro_operation_type_name[mopt]);
5299   print_inline_rtx (out, x, 2);
5300   fputc ('\n', out);
5301 }
5302
5303 /* Tell whether the CONCAT used to holds a VALUE and its location
5304    needs value resolution, i.e., an attempt of mapping the location
5305    back to other incoming values.  */
5306 #define VAL_NEEDS_RESOLUTION(x) \
5307   (RTL_FLAG_CHECK1 ("VAL_NEEDS_RESOLUTION", (x), CONCAT)->volatil)
5308 /* Whether the location in the CONCAT is a tracked expression, that
5309    should also be handled like a MO_USE.  */
5310 #define VAL_HOLDS_TRACK_EXPR(x) \
5311   (RTL_FLAG_CHECK1 ("VAL_HOLDS_TRACK_EXPR", (x), CONCAT)->used)
5312 /* Whether the location in the CONCAT should be handled like a MO_COPY
5313    as well.  */
5314 #define VAL_EXPR_IS_COPIED(x) \
5315   (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_COPIED", (x), CONCAT)->jump)
5316 /* Whether the location in the CONCAT should be handled like a
5317    MO_CLOBBER as well.  */
5318 #define VAL_EXPR_IS_CLOBBERED(x) \
5319   (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_CLOBBERED", (x), CONCAT)->unchanging)
5320
5321 /* All preserved VALUEs.  */
5322 static VEC (rtx, heap) *preserved_values;
5323
5324 /* Ensure VAL is preserved and remember it in a vector for vt_emit_notes.  */
5325
5326 static void
5327 preserve_value (cselib_val *val)
5328 {
5329   cselib_preserve_value (val);
5330   VEC_safe_push (rtx, heap, preserved_values, val->val_rtx);
5331 }
5332
5333 /* Helper function for MO_VAL_LOC handling.  Return non-zero if
5334    any rtxes not suitable for CONST use not replaced by VALUEs
5335    are discovered.  */
5336
5337 static int
5338 non_suitable_const (rtx *x, void *data ATTRIBUTE_UNUSED)
5339 {
5340   if (*x == NULL_RTX)
5341     return 0;
5342
5343   switch (GET_CODE (*x))
5344     {
5345     case REG:
5346     case DEBUG_EXPR:
5347     case PC:
5348     case SCRATCH:
5349     case CC0:
5350     case ASM_INPUT:
5351     case ASM_OPERANDS:
5352       return 1;
5353     case MEM:
5354       return !MEM_READONLY_P (*x);
5355     default:
5356       return 0;
5357     }
5358 }
5359
5360 /* Add uses (register and memory references) LOC which will be tracked
5361    to VTI (bb)->mos.  INSN is instruction which the LOC is part of.  */
5362
5363 static int
5364 add_uses (rtx *ploc, void *data)
5365 {
5366   rtx loc = *ploc;
5367   enum machine_mode mode = VOIDmode;
5368   struct count_use_info *cui = (struct count_use_info *)data;
5369   enum micro_operation_type type = use_type (loc, cui, &mode);
5370
5371   if (type != MO_CLOBBER)
5372     {
5373       basic_block bb = cui->bb;
5374       micro_operation mo;
5375
5376       mo.type = type;
5377       mo.u.loc = type == MO_USE ? var_lowpart (mode, loc) : loc;
5378       mo.insn = cui->insn;
5379
5380       if (type == MO_VAL_LOC)
5381         {
5382           rtx oloc = loc;
5383           rtx vloc = PAT_VAR_LOCATION_LOC (oloc);
5384           cselib_val *val;
5385
5386           gcc_assert (cui->sets);
5387
5388           if (MEM_P (vloc)
5389               && !REG_P (XEXP (vloc, 0))
5390               && !MEM_P (XEXP (vloc, 0)))
5391             {
5392               rtx mloc = vloc;
5393               enum machine_mode address_mode = get_address_mode (mloc);
5394               cselib_val *val
5395                 = cselib_lookup (XEXP (mloc, 0), address_mode, 0,
5396                                  GET_MODE (mloc));
5397
5398               if (val && !cselib_preserved_value_p (val))
5399                 preserve_value (val);
5400             }
5401
5402           if (CONSTANT_P (vloc)
5403               && (GET_CODE (vloc) != CONST
5404                   || for_each_rtx (&vloc, non_suitable_const, NULL)))
5405             /* For constants don't look up any value.  */;
5406           else if (!VAR_LOC_UNKNOWN_P (vloc) && !unsuitable_loc (vloc)
5407                    && (val = find_use_val (vloc, GET_MODE (oloc), cui)))
5408             {
5409               enum machine_mode mode2;
5410               enum micro_operation_type type2;
5411               rtx nloc = NULL;
5412               bool resolvable = REG_P (vloc) || MEM_P (vloc);
5413
5414               if (resolvable)
5415                 nloc = replace_expr_with_values (vloc);
5416
5417               if (nloc)
5418                 {
5419                   oloc = shallow_copy_rtx (oloc);
5420                   PAT_VAR_LOCATION_LOC (oloc) = nloc;
5421                 }
5422
5423               oloc = gen_rtx_CONCAT (mode, val->val_rtx, oloc);
5424
5425               type2 = use_type (vloc, 0, &mode2);
5426
5427               gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
5428                           || type2 == MO_CLOBBER);
5429
5430               if (type2 == MO_CLOBBER
5431                   && !cselib_preserved_value_p (val))
5432                 {
5433                   VAL_NEEDS_RESOLUTION (oloc) = resolvable;
5434                   preserve_value (val);
5435                 }
5436             }
5437           else if (!VAR_LOC_UNKNOWN_P (vloc))
5438             {
5439               oloc = shallow_copy_rtx (oloc);
5440               PAT_VAR_LOCATION_LOC (oloc) = gen_rtx_UNKNOWN_VAR_LOC ();
5441             }
5442
5443           mo.u.loc = oloc;
5444         }
5445       else if (type == MO_VAL_USE)
5446         {
5447           enum machine_mode mode2 = VOIDmode;
5448           enum micro_operation_type type2;
5449           cselib_val *val = find_use_val (loc, GET_MODE (loc), cui);
5450           rtx vloc, oloc = loc, nloc;
5451
5452           gcc_assert (cui->sets);
5453
5454           if (MEM_P (oloc)
5455               && !REG_P (XEXP (oloc, 0))
5456               && !MEM_P (XEXP (oloc, 0)))
5457             {
5458               rtx mloc = oloc;
5459               enum machine_mode address_mode = get_address_mode (mloc);
5460               cselib_val *val
5461                 = cselib_lookup (XEXP (mloc, 0), address_mode, 0,
5462                                  GET_MODE (mloc));
5463
5464               if (val && !cselib_preserved_value_p (val))
5465                 preserve_value (val);
5466             }
5467
5468           type2 = use_type (loc, 0, &mode2);
5469
5470           gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
5471                       || type2 == MO_CLOBBER);
5472
5473           if (type2 == MO_USE)
5474             vloc = var_lowpart (mode2, loc);
5475           else
5476             vloc = oloc;
5477
5478           /* The loc of a MO_VAL_USE may have two forms:
5479
5480              (concat val src): val is at src, a value-based
5481              representation.
5482
5483              (concat (concat val use) src): same as above, with use as
5484              the MO_USE tracked value, if it differs from src.
5485
5486           */
5487
5488           gcc_checking_assert (REG_P (loc) || MEM_P (loc));
5489           nloc = replace_expr_with_values (loc);
5490           if (!nloc)
5491             nloc = oloc;
5492
5493           if (vloc != nloc)
5494             oloc = gen_rtx_CONCAT (mode2, val->val_rtx, vloc);
5495           else
5496             oloc = val->val_rtx;
5497
5498           mo.u.loc = gen_rtx_CONCAT (mode, oloc, nloc);
5499
5500           if (type2 == MO_USE)
5501             VAL_HOLDS_TRACK_EXPR (mo.u.loc) = 1;
5502           if (!cselib_preserved_value_p (val))
5503             {
5504               VAL_NEEDS_RESOLUTION (mo.u.loc) = 1;
5505               preserve_value (val);
5506             }
5507         }
5508       else
5509         gcc_assert (type == MO_USE || type == MO_USE_NO_VAR);
5510
5511       if (dump_file && (dump_flags & TDF_DETAILS))
5512         log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
5513       VEC_safe_push (micro_operation, heap, VTI (bb)->mos, mo);
5514     }
5515
5516   return 0;
5517 }
5518
5519 /* Helper function for finding all uses of REG/MEM in X in insn INSN.  */
5520
5521 static void
5522 add_uses_1 (rtx *x, void *cui)
5523 {
5524   for_each_rtx (x, add_uses, cui);
5525 }
5526
5527 /* This is the value used during expansion of locations.  We want it
5528    to be unbounded, so that variables expanded deep in a recursion
5529    nest are fully evaluated, so that their values are cached
5530    correctly.  We avoid recursion cycles through other means, and we
5531    don't unshare RTL, so excess complexity is not a problem.  */
5532 #define EXPR_DEPTH (INT_MAX)
5533 /* We use this to keep too-complex expressions from being emitted as
5534    location notes, and then to debug information.  Users can trade
5535    compile time for ridiculously complex expressions, although they're
5536    seldom useful, and they may often have to be discarded as not
5537    representable anyway.  */
5538 #define EXPR_USE_DEPTH (PARAM_VALUE (PARAM_MAX_VARTRACK_EXPR_DEPTH))
5539
5540 /* Attempt to reverse the EXPR operation in the debug info and record
5541    it in the cselib table.  Say for reg1 = reg2 + 6 even when reg2 is
5542    no longer live we can express its value as VAL - 6.  */
5543
5544 static void
5545 reverse_op (rtx val, const_rtx expr, rtx insn)
5546 {
5547   rtx src, arg, ret;
5548   cselib_val *v;
5549   struct elt_loc_list *l;
5550   enum rtx_code code;
5551
5552   if (GET_CODE (expr) != SET)
5553     return;
5554
5555   if (!REG_P (SET_DEST (expr)) || GET_MODE (val) != GET_MODE (SET_DEST (expr)))
5556     return;
5557
5558   src = SET_SRC (expr);
5559   switch (GET_CODE (src))
5560     {
5561     case PLUS:
5562     case MINUS:
5563     case XOR:
5564     case NOT:
5565     case NEG:
5566       if (!REG_P (XEXP (src, 0)))
5567         return;
5568       break;
5569     case SIGN_EXTEND:
5570     case ZERO_EXTEND:
5571       if (!REG_P (XEXP (src, 0)) && !MEM_P (XEXP (src, 0)))
5572         return;
5573       break;
5574     default:
5575       return;
5576     }
5577
5578   if (!SCALAR_INT_MODE_P (GET_MODE (src)) || XEXP (src, 0) == cfa_base_rtx)
5579     return;
5580
5581   v = cselib_lookup (XEXP (src, 0), GET_MODE (XEXP (src, 0)), 0, VOIDmode);
5582   if (!v || !cselib_preserved_value_p (v))
5583     return;
5584
5585   /* Use canonical V to avoid creating multiple redundant expressions
5586      for different VALUES equivalent to V.  */
5587   v = canonical_cselib_val (v);
5588
5589   /* Adding a reverse op isn't useful if V already has an always valid
5590      location.  Ignore ENTRY_VALUE, while it is always constant, we should
5591      prefer non-ENTRY_VALUE locations whenever possible.  */
5592   for (l = v->locs; l; l = l->next)
5593     if (CONSTANT_P (l->loc)
5594         && (GET_CODE (l->loc) != CONST || !references_value_p (l->loc, 0)))
5595       return;
5596
5597   switch (GET_CODE (src))
5598     {
5599     case NOT:
5600     case NEG:
5601       if (GET_MODE (v->val_rtx) != GET_MODE (val))
5602         return;
5603       ret = gen_rtx_fmt_e (GET_CODE (src), GET_MODE (val), val);
5604       break;
5605     case SIGN_EXTEND:
5606     case ZERO_EXTEND:
5607       ret = gen_lowpart_SUBREG (GET_MODE (v->val_rtx), val);
5608       break;
5609     case XOR:
5610       code = XOR;
5611       goto binary;
5612     case PLUS:
5613       code = MINUS;
5614       goto binary;
5615     case MINUS:
5616       code = PLUS;
5617       goto binary;
5618     binary:
5619       if (GET_MODE (v->val_rtx) != GET_MODE (val))
5620         return;
5621       arg = XEXP (src, 1);
5622       if (!CONST_INT_P (arg) && GET_CODE (arg) != SYMBOL_REF)
5623         {
5624           arg = cselib_expand_value_rtx (arg, scratch_regs, 5);
5625           if (arg == NULL_RTX)
5626             return;
5627           if (!CONST_INT_P (arg) && GET_CODE (arg) != SYMBOL_REF)
5628             return;
5629         }
5630       ret = simplify_gen_binary (code, GET_MODE (val), val, arg);
5631       if (ret == val)
5632         /* Ensure ret isn't VALUE itself (which can happen e.g. for
5633            (plus (reg1) (reg2)) when reg2 is known to be 0), as that
5634            breaks a lot of routines during var-tracking.  */
5635         ret = gen_rtx_fmt_ee (PLUS, GET_MODE (val), val, const0_rtx);
5636       break;
5637     default:
5638       gcc_unreachable ();
5639     }
5640
5641   cselib_add_permanent_equiv (v, ret, insn);
5642 }
5643
5644 /* Add stores (register and memory references) LOC which will be tracked
5645    to VTI (bb)->mos.  EXPR is the RTL expression containing the store.
5646    CUIP->insn is instruction which the LOC is part of.  */
5647
5648 static void
5649 add_stores (rtx loc, const_rtx expr, void *cuip)
5650 {
5651   enum machine_mode mode = VOIDmode, mode2;
5652   struct count_use_info *cui = (struct count_use_info *)cuip;
5653   basic_block bb = cui->bb;
5654   micro_operation mo;
5655   rtx oloc = loc, nloc, src = NULL;
5656   enum micro_operation_type type = use_type (loc, cui, &mode);
5657   bool track_p = false;
5658   cselib_val *v;
5659   bool resolve, preserve;
5660
5661   if (type == MO_CLOBBER)
5662     return;
5663
5664   mode2 = mode;
5665
5666   if (REG_P (loc))
5667     {
5668       gcc_assert (loc != cfa_base_rtx);
5669       if ((GET_CODE (expr) == CLOBBER && type != MO_VAL_SET)
5670           || !(track_p = use_type (loc, NULL, &mode2) == MO_USE)
5671           || GET_CODE (expr) == CLOBBER)
5672         {
5673           mo.type = MO_CLOBBER;
5674           mo.u.loc = loc;
5675           if (GET_CODE (expr) == SET
5676               && SET_DEST (expr) == loc
5677               && !unsuitable_loc (SET_SRC (expr))
5678               && find_use_val (loc, mode, cui))
5679             {
5680               gcc_checking_assert (type == MO_VAL_SET);
5681               mo.u.loc = gen_rtx_SET (VOIDmode, loc, SET_SRC (expr));
5682             }
5683         }
5684       else
5685         {
5686           if (GET_CODE (expr) == SET
5687               && SET_DEST (expr) == loc
5688               && GET_CODE (SET_SRC (expr)) != ASM_OPERANDS)
5689             src = var_lowpart (mode2, SET_SRC (expr));
5690           loc = var_lowpart (mode2, loc);
5691
5692           if (src == NULL)
5693             {
5694               mo.type = MO_SET;
5695               mo.u.loc = loc;
5696             }
5697           else
5698             {
5699               rtx xexpr = gen_rtx_SET (VOIDmode, loc, src);
5700               if (same_variable_part_p (src, REG_EXPR (loc), REG_OFFSET (loc)))
5701                 mo.type = MO_COPY;
5702               else
5703                 mo.type = MO_SET;
5704               mo.u.loc = xexpr;
5705             }
5706         }
5707       mo.insn = cui->insn;
5708     }
5709   else if (MEM_P (loc)
5710            && ((track_p = use_type (loc, NULL, &mode2) == MO_USE)
5711                || cui->sets))
5712     {
5713       if (MEM_P (loc) && type == MO_VAL_SET
5714           && !REG_P (XEXP (loc, 0))
5715           && !MEM_P (XEXP (loc, 0)))
5716         {
5717           rtx mloc = loc;
5718           enum machine_mode address_mode = get_address_mode (mloc);
5719           cselib_val *val = cselib_lookup (XEXP (mloc, 0),
5720                                            address_mode, 0,
5721                                            GET_MODE (mloc));
5722
5723           if (val && !cselib_preserved_value_p (val))
5724             preserve_value (val);
5725         }
5726
5727       if (GET_CODE (expr) == CLOBBER || !track_p)
5728         {
5729           mo.type = MO_CLOBBER;
5730           mo.u.loc = track_p ? var_lowpart (mode2, loc) : loc;
5731         }
5732       else
5733         {
5734           if (GET_CODE (expr) == SET
5735               && SET_DEST (expr) == loc
5736               && GET_CODE (SET_SRC (expr)) != ASM_OPERANDS)
5737             src = var_lowpart (mode2, SET_SRC (expr));
5738           loc = var_lowpart (mode2, loc);
5739
5740           if (src == NULL)
5741             {
5742               mo.type = MO_SET;
5743               mo.u.loc = loc;
5744             }
5745           else
5746             {
5747               rtx xexpr = gen_rtx_SET (VOIDmode, loc, src);
5748               if (same_variable_part_p (SET_SRC (xexpr),
5749                                         MEM_EXPR (loc),
5750                                         INT_MEM_OFFSET (loc)))
5751                 mo.type = MO_COPY;
5752               else
5753                 mo.type = MO_SET;
5754               mo.u.loc = xexpr;
5755             }
5756         }
5757       mo.insn = cui->insn;
5758     }
5759   else
5760     return;
5761
5762   if (type != MO_VAL_SET)
5763     goto log_and_return;
5764
5765   v = find_use_val (oloc, mode, cui);
5766
5767   if (!v)
5768     goto log_and_return;
5769
5770   resolve = preserve = !cselib_preserved_value_p (v);
5771
5772   if (loc == stack_pointer_rtx
5773       && hard_frame_pointer_adjustment != -1
5774       && preserve)
5775     cselib_set_value_sp_based (v);
5776
5777   nloc = replace_expr_with_values (oloc);
5778   if (nloc)
5779     oloc = nloc;
5780
5781   if (GET_CODE (PATTERN (cui->insn)) == COND_EXEC)
5782     {
5783       cselib_val *oval = cselib_lookup (oloc, GET_MODE (oloc), 0, VOIDmode);
5784
5785       gcc_assert (oval != v);
5786       gcc_assert (REG_P (oloc) || MEM_P (oloc));
5787
5788       if (oval && !cselib_preserved_value_p (oval))
5789         {
5790           micro_operation moa;
5791
5792           preserve_value (oval);
5793
5794           moa.type = MO_VAL_USE;
5795           moa.u.loc = gen_rtx_CONCAT (mode, oval->val_rtx, oloc);
5796           VAL_NEEDS_RESOLUTION (moa.u.loc) = 1;
5797           moa.insn = cui->insn;
5798
5799           if (dump_file && (dump_flags & TDF_DETAILS))
5800             log_op_type (moa.u.loc, cui->bb, cui->insn,
5801                          moa.type, dump_file);
5802           VEC_safe_push (micro_operation, heap, VTI (bb)->mos, moa);
5803         }
5804
5805       resolve = false;
5806     }
5807   else if (resolve && GET_CODE (mo.u.loc) == SET)
5808     {
5809       if (REG_P (SET_SRC (expr)) || MEM_P (SET_SRC (expr)))
5810         nloc = replace_expr_with_values (SET_SRC (expr));
5811       else
5812         nloc = NULL_RTX;
5813
5814       /* Avoid the mode mismatch between oexpr and expr.  */
5815       if (!nloc && mode != mode2)
5816         {
5817           nloc = SET_SRC (expr);
5818           gcc_assert (oloc == SET_DEST (expr));
5819         }
5820
5821       if (nloc && nloc != SET_SRC (mo.u.loc))
5822         oloc = gen_rtx_SET (GET_MODE (mo.u.loc), oloc, nloc);
5823       else
5824         {
5825           if (oloc == SET_DEST (mo.u.loc))
5826             /* No point in duplicating.  */
5827             oloc = mo.u.loc;
5828           if (!REG_P (SET_SRC (mo.u.loc)))
5829             resolve = false;
5830         }
5831     }
5832   else if (!resolve)
5833     {
5834       if (GET_CODE (mo.u.loc) == SET
5835           && oloc == SET_DEST (mo.u.loc))
5836         /* No point in duplicating.  */
5837         oloc = mo.u.loc;
5838     }
5839   else
5840     resolve = false;
5841
5842   loc = gen_rtx_CONCAT (mode, v->val_rtx, oloc);
5843
5844   if (mo.u.loc != oloc)
5845     loc = gen_rtx_CONCAT (GET_MODE (mo.u.loc), loc, mo.u.loc);
5846
5847   /* The loc of a MO_VAL_SET may have various forms:
5848
5849      (concat val dst): dst now holds val
5850
5851      (concat val (set dst src)): dst now holds val, copied from src
5852
5853      (concat (concat val dstv) dst): dst now holds val; dstv is dst
5854      after replacing mems and non-top-level regs with values.
5855
5856      (concat (concat val dstv) (set dst src)): dst now holds val,
5857      copied from src.  dstv is a value-based representation of dst, if
5858      it differs from dst.  If resolution is needed, src is a REG, and
5859      its mode is the same as that of val.
5860
5861      (concat (concat val (set dstv srcv)) (set dst src)): src
5862      copied to dst, holding val.  dstv and srcv are value-based
5863      representations of dst and src, respectively.
5864
5865   */
5866
5867   if (GET_CODE (PATTERN (cui->insn)) != COND_EXEC)
5868     reverse_op (v->val_rtx, expr, cui->insn);
5869
5870   mo.u.loc = loc;
5871
5872   if (track_p)
5873     VAL_HOLDS_TRACK_EXPR (loc) = 1;
5874   if (preserve)
5875     {
5876       VAL_NEEDS_RESOLUTION (loc) = resolve;
5877       preserve_value (v);
5878     }
5879   if (mo.type == MO_CLOBBER)
5880     VAL_EXPR_IS_CLOBBERED (loc) = 1;
5881   if (mo.type == MO_COPY)
5882     VAL_EXPR_IS_COPIED (loc) = 1;
5883
5884   mo.type = MO_VAL_SET;
5885
5886  log_and_return:
5887   if (dump_file && (dump_flags & TDF_DETAILS))
5888     log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
5889   VEC_safe_push (micro_operation, heap, VTI (bb)->mos, mo);
5890 }
5891
5892 /* Arguments to the call.  */
5893 static rtx call_arguments;
5894
5895 /* Compute call_arguments.  */
5896
5897 static void
5898 prepare_call_arguments (basic_block bb, rtx insn)
5899 {
5900   rtx link, x, call;
5901   rtx prev, cur, next;
5902   rtx this_arg = NULL_RTX;
5903   tree type = NULL_TREE, t, fndecl = NULL_TREE;
5904   tree obj_type_ref = NULL_TREE;
5905   CUMULATIVE_ARGS args_so_far_v;
5906   cumulative_args_t args_so_far;
5907
5908   memset (&args_so_far_v, 0, sizeof (args_so_far_v));
5909   args_so_far = pack_cumulative_args (&args_so_far_v);
5910   call = get_call_rtx_from (insn);
5911   if (call)
5912     {
5913       if (GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
5914         {
5915           rtx symbol = XEXP (XEXP (call, 0), 0);
5916           if (SYMBOL_REF_DECL (symbol))
5917             fndecl = SYMBOL_REF_DECL (symbol);
5918         }
5919       if (fndecl == NULL_TREE)
5920         fndecl = MEM_EXPR (XEXP (call, 0));
5921       if (fndecl
5922           && TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE
5923           && TREE_CODE (TREE_TYPE (fndecl)) != METHOD_TYPE)
5924         fndecl = NULL_TREE;
5925       if (fndecl && TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
5926         type = TREE_TYPE (fndecl);
5927       if (fndecl && TREE_CODE (fndecl) != FUNCTION_DECL)
5928         {
5929           if (TREE_CODE (fndecl) == INDIRECT_REF
5930               && TREE_CODE (TREE_OPERAND (fndecl, 0)) == OBJ_TYPE_REF)
5931             obj_type_ref = TREE_OPERAND (fndecl, 0);
5932           fndecl = NULL_TREE;
5933         }
5934       if (type)
5935         {
5936           for (t = TYPE_ARG_TYPES (type); t && t != void_list_node;
5937                t = TREE_CHAIN (t))
5938             if (TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
5939                 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (t))))
5940               break;
5941           if ((t == NULL || t == void_list_node) && obj_type_ref == NULL_TREE)
5942             type = NULL;
5943           else
5944             {
5945               int nargs ATTRIBUTE_UNUSED = list_length (TYPE_ARG_TYPES (type));
5946               link = CALL_INSN_FUNCTION_USAGE (insn);
5947 #ifndef PCC_STATIC_STRUCT_RETURN
5948               if (aggregate_value_p (TREE_TYPE (type), type)
5949                   && targetm.calls.struct_value_rtx (type, 0) == 0)
5950                 {
5951                   tree struct_addr = build_pointer_type (TREE_TYPE (type));
5952                   enum machine_mode mode = TYPE_MODE (struct_addr);
5953                   rtx reg;
5954                   INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
5955                                         nargs + 1);
5956                   reg = targetm.calls.function_arg (args_so_far, mode,
5957                                                     struct_addr, true);
5958                   targetm.calls.function_arg_advance (args_so_far, mode,
5959                                                       struct_addr, true);
5960                   if (reg == NULL_RTX)
5961                     {
5962                       for (; link; link = XEXP (link, 1))
5963                         if (GET_CODE (XEXP (link, 0)) == USE
5964                             && MEM_P (XEXP (XEXP (link, 0), 0)))
5965                           {
5966                             link = XEXP (link, 1);
5967                             break;
5968                           }
5969                     }
5970                 }
5971               else
5972 #endif
5973                 INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
5974                                       nargs);
5975               if (obj_type_ref && TYPE_ARG_TYPES (type) != void_list_node)
5976                 {
5977                   enum machine_mode mode;
5978                   t = TYPE_ARG_TYPES (type);
5979                   mode = TYPE_MODE (TREE_VALUE (t));
5980                   this_arg = targetm.calls.function_arg (args_so_far, mode,
5981                                                          TREE_VALUE (t), true);
5982                   if (this_arg && !REG_P (this_arg))
5983                     this_arg = NULL_RTX;
5984                   else if (this_arg == NULL_RTX)
5985                     {
5986                       for (; link; link = XEXP (link, 1))
5987                         if (GET_CODE (XEXP (link, 0)) == USE
5988                             && MEM_P (XEXP (XEXP (link, 0), 0)))
5989                           {
5990                             this_arg = XEXP (XEXP (link, 0), 0);
5991                             break;
5992                           }
5993                     }
5994                 }
5995             }
5996         }
5997     }
5998   t = type ? TYPE_ARG_TYPES (type) : NULL_TREE;
5999
6000   for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
6001     if (GET_CODE (XEXP (link, 0)) == USE)
6002       {
6003         rtx item = NULL_RTX;
6004         x = XEXP (XEXP (link, 0), 0);
6005         if (GET_MODE (link) == VOIDmode
6006             || GET_MODE (link) == BLKmode
6007             || (GET_MODE (link) != GET_MODE (x)
6008                 && (GET_MODE_CLASS (GET_MODE (link)) != MODE_INT
6009                     || GET_MODE_CLASS (GET_MODE (x)) != MODE_INT)))
6010           /* Can't do anything for these, if the original type mode
6011              isn't known or can't be converted.  */;
6012         else if (REG_P (x))
6013           {
6014             cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
6015             if (val && cselib_preserved_value_p (val))
6016               item = val->val_rtx;
6017             else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
6018               {
6019                 enum machine_mode mode = GET_MODE (x);
6020
6021                 while ((mode = GET_MODE_WIDER_MODE (mode)) != VOIDmode
6022                        && GET_MODE_BITSIZE (mode) <= BITS_PER_WORD)
6023                   {
6024                     rtx reg = simplify_subreg (mode, x, GET_MODE (x), 0);
6025
6026                     if (reg == NULL_RTX || !REG_P (reg))
6027                       continue;
6028                     val = cselib_lookup (reg, mode, 0, VOIDmode);
6029                     if (val && cselib_preserved_value_p (val))
6030                       {
6031                         item = val->val_rtx;
6032                         break;
6033                       }
6034                   }
6035               }
6036           }
6037         else if (MEM_P (x))
6038           {
6039             rtx mem = x;
6040             cselib_val *val;
6041
6042             if (!frame_pointer_needed)
6043               {
6044                 struct adjust_mem_data amd;
6045                 amd.mem_mode = VOIDmode;
6046                 amd.stack_adjust = -VTI (bb)->out.stack_adjust;
6047                 amd.side_effects = NULL_RTX;
6048                 amd.store = true;
6049                 mem = simplify_replace_fn_rtx (mem, NULL_RTX, adjust_mems,
6050                                                &amd);
6051                 gcc_assert (amd.side_effects == NULL_RTX);
6052               }
6053             val = cselib_lookup (mem, GET_MODE (mem), 0, VOIDmode);
6054             if (val && cselib_preserved_value_p (val))
6055               item = val->val_rtx;
6056             else if (GET_MODE_CLASS (GET_MODE (mem)) != MODE_INT)
6057               {
6058                 /* For non-integer stack argument see also if they weren't
6059                    initialized by integers.  */
6060                 enum machine_mode imode = int_mode_for_mode (GET_MODE (mem));
6061                 if (imode != GET_MODE (mem) && imode != BLKmode)
6062                   {
6063                     val = cselib_lookup (adjust_address_nv (mem, imode, 0),
6064                                          imode, 0, VOIDmode);
6065                     if (val && cselib_preserved_value_p (val))
6066                       item = lowpart_subreg (GET_MODE (x), val->val_rtx,
6067                                              imode);
6068                   }
6069               }
6070           }
6071         if (item)
6072           {
6073             rtx x2 = x;
6074             if (GET_MODE (item) != GET_MODE (link))
6075               item = lowpart_subreg (GET_MODE (link), item, GET_MODE (item));
6076             if (GET_MODE (x2) != GET_MODE (link))
6077               x2 = lowpart_subreg (GET_MODE (link), x2, GET_MODE (x2));
6078             item = gen_rtx_CONCAT (GET_MODE (link), x2, item);
6079             call_arguments
6080               = gen_rtx_EXPR_LIST (VOIDmode, item, call_arguments);
6081           }
6082         if (t && t != void_list_node)
6083           {
6084             tree argtype = TREE_VALUE (t);
6085             enum machine_mode mode = TYPE_MODE (argtype);
6086             rtx reg;
6087             if (pass_by_reference (&args_so_far_v, mode, argtype, true))
6088               {
6089                 argtype = build_pointer_type (argtype);
6090                 mode = TYPE_MODE (argtype);
6091               }
6092             reg = targetm.calls.function_arg (args_so_far, mode,
6093                                               argtype, true);
6094             if (TREE_CODE (argtype) == REFERENCE_TYPE
6095                 && INTEGRAL_TYPE_P (TREE_TYPE (argtype))
6096                 && reg
6097                 && REG_P (reg)
6098                 && GET_MODE (reg) == mode
6099                 && GET_MODE_CLASS (mode) == MODE_INT
6100                 && REG_P (x)
6101                 && REGNO (x) == REGNO (reg)
6102                 && GET_MODE (x) == mode
6103                 && item)
6104               {
6105                 enum machine_mode indmode
6106                   = TYPE_MODE (TREE_TYPE (argtype));
6107                 rtx mem = gen_rtx_MEM (indmode, x);
6108                 cselib_val *val = cselib_lookup (mem, indmode, 0, VOIDmode);
6109                 if (val && cselib_preserved_value_p (val))
6110                   {
6111                     item = gen_rtx_CONCAT (indmode, mem, val->val_rtx);
6112                     call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
6113                                                         call_arguments);
6114                   }
6115                 else
6116                   {
6117                     struct elt_loc_list *l;
6118                     tree initial;
6119
6120                     /* Try harder, when passing address of a constant
6121                        pool integer it can be easily read back.  */
6122                     item = XEXP (item, 1);
6123                     if (GET_CODE (item) == SUBREG)
6124                       item = SUBREG_REG (item);
6125                     gcc_assert (GET_CODE (item) == VALUE);
6126                     val = CSELIB_VAL_PTR (item);
6127                     for (l = val->locs; l; l = l->next)
6128                       if (GET_CODE (l->loc) == SYMBOL_REF
6129                           && TREE_CONSTANT_POOL_ADDRESS_P (l->loc)
6130                           && SYMBOL_REF_DECL (l->loc)
6131                           && DECL_INITIAL (SYMBOL_REF_DECL (l->loc)))
6132                         {
6133                           initial = DECL_INITIAL (SYMBOL_REF_DECL (l->loc));
6134                           if (host_integerp (initial, 0))
6135                             {
6136                               item = GEN_INT (tree_low_cst (initial, 0));
6137                               item = gen_rtx_CONCAT (indmode, mem, item);
6138                               call_arguments
6139                                 = gen_rtx_EXPR_LIST (VOIDmode, item,
6140                                                      call_arguments);
6141                             }
6142                           break;
6143                         }
6144                   }
6145               }
6146             targetm.calls.function_arg_advance (args_so_far, mode,
6147                                                 argtype, true);
6148             t = TREE_CHAIN (t);
6149           }
6150       }
6151
6152   /* Add debug arguments.  */
6153   if (fndecl
6154       && TREE_CODE (fndecl) == FUNCTION_DECL
6155       && DECL_HAS_DEBUG_ARGS_P (fndecl))
6156     {
6157       VEC(tree, gc) **debug_args = decl_debug_args_lookup (fndecl);
6158       if (debug_args)
6159         {
6160           unsigned int ix;
6161           tree param;
6162           for (ix = 0; VEC_iterate (tree, *debug_args, ix, param); ix += 2)
6163             {
6164               rtx item;
6165               tree dtemp = VEC_index (tree, *debug_args, ix + 1);
6166               enum machine_mode mode = DECL_MODE (dtemp);
6167               item = gen_rtx_DEBUG_PARAMETER_REF (mode, param);
6168               item = gen_rtx_CONCAT (mode, item, DECL_RTL_KNOWN_SET (dtemp));
6169               call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
6170                                                   call_arguments);
6171             }
6172         }
6173     }
6174
6175   /* Reverse call_arguments chain.  */
6176   prev = NULL_RTX;
6177   for (cur = call_arguments; cur; cur = next)
6178     {
6179       next = XEXP (cur, 1);
6180       XEXP (cur, 1) = prev;
6181       prev = cur;
6182     }
6183   call_arguments = prev;
6184
6185   x = get_call_rtx_from (insn);
6186   if (x)
6187     {
6188       x = XEXP (XEXP (x, 0), 0);
6189       if (GET_CODE (x) == SYMBOL_REF)
6190         /* Don't record anything.  */;
6191       else if (CONSTANT_P (x))
6192         {
6193           x = gen_rtx_CONCAT (GET_MODE (x) == VOIDmode ? Pmode : GET_MODE (x),
6194                               pc_rtx, x);
6195           call_arguments
6196             = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
6197         }
6198       else
6199         {
6200           cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
6201           if (val && cselib_preserved_value_p (val))
6202             {
6203               x = gen_rtx_CONCAT (GET_MODE (x), pc_rtx, val->val_rtx);
6204               call_arguments
6205                 = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
6206             }
6207         }
6208     }
6209   if (this_arg)
6210     {
6211       enum machine_mode mode
6212         = TYPE_MODE (TREE_TYPE (OBJ_TYPE_REF_EXPR (obj_type_ref)));
6213       rtx clobbered = gen_rtx_MEM (mode, this_arg);
6214       HOST_WIDE_INT token
6215         = tree_low_cst (OBJ_TYPE_REF_TOKEN (obj_type_ref), 0);
6216       if (token)
6217         clobbered = plus_constant (mode, clobbered,
6218                                    token * GET_MODE_SIZE (mode));
6219       clobbered = gen_rtx_MEM (mode, clobbered);
6220       x = gen_rtx_CONCAT (mode, gen_rtx_CLOBBER (VOIDmode, pc_rtx), clobbered);
6221       call_arguments
6222         = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
6223     }
6224 }
6225
6226 /* Callback for cselib_record_sets_hook, that records as micro
6227    operations uses and stores in an insn after cselib_record_sets has
6228    analyzed the sets in an insn, but before it modifies the stored
6229    values in the internal tables, unless cselib_record_sets doesn't
6230    call it directly (perhaps because we're not doing cselib in the
6231    first place, in which case sets and n_sets will be 0).  */
6232
6233 static void
6234 add_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
6235 {
6236   basic_block bb = BLOCK_FOR_INSN (insn);
6237   int n1, n2;
6238   struct count_use_info cui;
6239   micro_operation *mos;
6240
6241   cselib_hook_called = true;
6242
6243   cui.insn = insn;
6244   cui.bb = bb;
6245   cui.sets = sets;
6246   cui.n_sets = n_sets;
6247
6248   n1 = VEC_length (micro_operation, VTI (bb)->mos);
6249   cui.store_p = false;
6250   note_uses (&PATTERN (insn), add_uses_1, &cui);
6251   n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
6252   mos = VEC_address (micro_operation, VTI (bb)->mos);
6253
6254   /* Order the MO_USEs to be before MO_USE_NO_VARs and MO_VAL_USE, and
6255      MO_VAL_LOC last.  */
6256   while (n1 < n2)
6257     {
6258       while (n1 < n2 && mos[n1].type == MO_USE)
6259         n1++;
6260       while (n1 < n2 && mos[n2].type != MO_USE)
6261         n2--;
6262       if (n1 < n2)
6263         {
6264           micro_operation sw;
6265
6266           sw = mos[n1];
6267           mos[n1] = mos[n2];
6268           mos[n2] = sw;
6269         }
6270     }
6271
6272   n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
6273   while (n1 < n2)
6274     {
6275       while (n1 < n2 && mos[n1].type != MO_VAL_LOC)
6276         n1++;
6277       while (n1 < n2 && mos[n2].type == MO_VAL_LOC)
6278         n2--;
6279       if (n1 < n2)
6280         {
6281           micro_operation sw;
6282
6283           sw = mos[n1];
6284           mos[n1] = mos[n2];
6285           mos[n2] = sw;
6286         }
6287     }
6288
6289   if (CALL_P (insn))
6290     {
6291       micro_operation mo;
6292
6293       mo.type = MO_CALL;
6294       mo.insn = insn;
6295       mo.u.loc = call_arguments;
6296       call_arguments = NULL_RTX;
6297
6298       if (dump_file && (dump_flags & TDF_DETAILS))
6299         log_op_type (PATTERN (insn), bb, insn, mo.type, dump_file);
6300       VEC_safe_push (micro_operation, heap, VTI (bb)->mos, mo);
6301     }
6302
6303   n1 = VEC_length (micro_operation, VTI (bb)->mos);
6304   /* This will record NEXT_INSN (insn), such that we can
6305      insert notes before it without worrying about any
6306      notes that MO_USEs might emit after the insn.  */
6307   cui.store_p = true;
6308   note_stores (PATTERN (insn), add_stores, &cui);
6309   n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
6310   mos = VEC_address (micro_operation, VTI (bb)->mos);
6311
6312   /* Order the MO_VAL_USEs first (note_stores does nothing
6313      on DEBUG_INSNs, so there are no MO_VAL_LOCs from this
6314      insn), then MO_CLOBBERs, then MO_SET/MO_COPY/MO_VAL_SET.  */
6315   while (n1 < n2)
6316     {
6317       while (n1 < n2 && mos[n1].type == MO_VAL_USE)
6318         n1++;
6319       while (n1 < n2 && mos[n2].type != MO_VAL_USE)
6320         n2--;
6321       if (n1 < n2)
6322         {
6323           micro_operation sw;
6324
6325           sw = mos[n1];
6326           mos[n1] = mos[n2];
6327           mos[n2] = sw;
6328         }
6329     }
6330
6331   n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
6332   while (n1 < n2)
6333     {
6334       while (n1 < n2 && mos[n1].type == MO_CLOBBER)
6335         n1++;
6336       while (n1 < n2 && mos[n2].type != MO_CLOBBER)
6337         n2--;
6338       if (n1 < n2)
6339         {
6340           micro_operation sw;
6341
6342           sw = mos[n1];
6343           mos[n1] = mos[n2];
6344           mos[n2] = sw;
6345         }
6346     }
6347 }
6348
6349 static enum var_init_status
6350 find_src_status (dataflow_set *in, rtx src)
6351 {
6352   tree decl = NULL_TREE;
6353   enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
6354
6355   if (! flag_var_tracking_uninit)
6356     status = VAR_INIT_STATUS_INITIALIZED;
6357
6358   if (src && REG_P (src))
6359     decl = var_debug_decl (REG_EXPR (src));
6360   else if (src && MEM_P (src))
6361     decl = var_debug_decl (MEM_EXPR (src));
6362
6363   if (src && decl)
6364     status = get_init_value (in, src, dv_from_decl (decl));
6365
6366   return status;
6367 }
6368
6369 /* SRC is the source of an assignment.  Use SET to try to find what
6370    was ultimately assigned to SRC.  Return that value if known,
6371    otherwise return SRC itself.  */
6372
6373 static rtx
6374 find_src_set_src (dataflow_set *set, rtx src)
6375 {
6376   tree decl = NULL_TREE;   /* The variable being copied around.          */
6377   rtx set_src = NULL_RTX;  /* The value for "decl" stored in "src".      */
6378   variable var;
6379   location_chain nextp;
6380   int i;
6381   bool found;
6382
6383   if (src && REG_P (src))
6384     decl = var_debug_decl (REG_EXPR (src));
6385   else if (src && MEM_P (src))
6386     decl = var_debug_decl (MEM_EXPR (src));
6387
6388   if (src && decl)
6389     {
6390       decl_or_value dv = dv_from_decl (decl);
6391
6392       var = shared_hash_find (set->vars, dv);
6393       if (var)
6394         {
6395           found = false;
6396           for (i = 0; i < var->n_var_parts && !found; i++)
6397             for (nextp = var->var_part[i].loc_chain; nextp && !found;
6398                  nextp = nextp->next)
6399               if (rtx_equal_p (nextp->loc, src))
6400                 {
6401                   set_src = nextp->set_src;
6402                   found = true;
6403                 }
6404
6405         }
6406     }
6407
6408   return set_src;
6409 }
6410
6411 /* Compute the changes of variable locations in the basic block BB.  */
6412
6413 static bool
6414 compute_bb_dataflow (basic_block bb)
6415 {
6416   unsigned int i;
6417   micro_operation *mo;
6418   bool changed;
6419   dataflow_set old_out;
6420   dataflow_set *in = &VTI (bb)->in;
6421   dataflow_set *out = &VTI (bb)->out;
6422
6423   dataflow_set_init (&old_out);
6424   dataflow_set_copy (&old_out, out);
6425   dataflow_set_copy (out, in);
6426
6427   FOR_EACH_VEC_ELT (micro_operation, VTI (bb)->mos, i, mo)
6428     {
6429       rtx insn = mo->insn;
6430
6431       switch (mo->type)
6432         {
6433           case MO_CALL:
6434             dataflow_set_clear_at_call (out);
6435             break;
6436
6437           case MO_USE:
6438             {
6439               rtx loc = mo->u.loc;
6440
6441               if (REG_P (loc))
6442                 var_reg_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6443               else if (MEM_P (loc))
6444                 var_mem_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6445             }
6446             break;
6447
6448           case MO_VAL_LOC:
6449             {
6450               rtx loc = mo->u.loc;
6451               rtx val, vloc;
6452               tree var;
6453
6454               if (GET_CODE (loc) == CONCAT)
6455                 {
6456                   val = XEXP (loc, 0);
6457                   vloc = XEXP (loc, 1);
6458                 }
6459               else
6460                 {
6461                   val = NULL_RTX;
6462                   vloc = loc;
6463                 }
6464
6465               var = PAT_VAR_LOCATION_DECL (vloc);
6466
6467               clobber_variable_part (out, NULL_RTX,
6468                                      dv_from_decl (var), 0, NULL_RTX);
6469               if (val)
6470                 {
6471                   if (VAL_NEEDS_RESOLUTION (loc))
6472                     val_resolve (out, val, PAT_VAR_LOCATION_LOC (vloc), insn);
6473                   set_variable_part (out, val, dv_from_decl (var), 0,
6474                                      VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
6475                                      INSERT);
6476                 }
6477               else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
6478                 set_variable_part (out, PAT_VAR_LOCATION_LOC (vloc),
6479                                    dv_from_decl (var), 0,
6480                                    VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
6481                                    INSERT);
6482             }
6483             break;
6484
6485           case MO_VAL_USE:
6486             {
6487               rtx loc = mo->u.loc;
6488               rtx val, vloc, uloc;
6489
6490               vloc = uloc = XEXP (loc, 1);
6491               val = XEXP (loc, 0);
6492
6493               if (GET_CODE (val) == CONCAT)
6494                 {
6495                   uloc = XEXP (val, 1);
6496                   val = XEXP (val, 0);
6497                 }
6498
6499               if (VAL_NEEDS_RESOLUTION (loc))
6500                 val_resolve (out, val, vloc, insn);
6501               else
6502                 val_store (out, val, uloc, insn, false);
6503
6504               if (VAL_HOLDS_TRACK_EXPR (loc))
6505                 {
6506                   if (GET_CODE (uloc) == REG)
6507                     var_reg_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6508                                  NULL);
6509                   else if (GET_CODE (uloc) == MEM)
6510                     var_mem_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6511                                  NULL);
6512                 }
6513             }
6514             break;
6515
6516           case MO_VAL_SET:
6517             {
6518               rtx loc = mo->u.loc;
6519               rtx val, vloc, uloc;
6520               rtx dstv, srcv;
6521
6522               vloc = loc;
6523               uloc = XEXP (vloc, 1);
6524               val = XEXP (vloc, 0);
6525               vloc = uloc;
6526
6527               if (GET_CODE (uloc) == SET)
6528                 {
6529                   dstv = SET_DEST (uloc);
6530                   srcv = SET_SRC (uloc);
6531                 }
6532               else
6533                 {
6534                   dstv = uloc;
6535                   srcv = NULL;
6536                 }
6537
6538               if (GET_CODE (val) == CONCAT)
6539                 {
6540                   dstv = vloc = XEXP (val, 1);
6541                   val = XEXP (val, 0);
6542                 }
6543
6544               if (GET_CODE (vloc) == SET)
6545                 {
6546                   srcv = SET_SRC (vloc);
6547
6548                   gcc_assert (val != srcv);
6549                   gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
6550
6551                   dstv = vloc = SET_DEST (vloc);
6552
6553                   if (VAL_NEEDS_RESOLUTION (loc))
6554                     val_resolve (out, val, srcv, insn);
6555                 }
6556               else if (VAL_NEEDS_RESOLUTION (loc))
6557                 {
6558                   gcc_assert (GET_CODE (uloc) == SET
6559                               && GET_CODE (SET_SRC (uloc)) == REG);
6560                   val_resolve (out, val, SET_SRC (uloc), insn);
6561                 }
6562
6563               if (VAL_HOLDS_TRACK_EXPR (loc))
6564                 {
6565                   if (VAL_EXPR_IS_CLOBBERED (loc))
6566                     {
6567                       if (REG_P (uloc))
6568                         var_reg_delete (out, uloc, true);
6569                       else if (MEM_P (uloc))
6570                         {
6571                           gcc_assert (MEM_P (dstv));
6572                           gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (uloc));
6573                           var_mem_delete (out, dstv, true);
6574                         }
6575                     }
6576                   else
6577                     {
6578                       bool copied_p = VAL_EXPR_IS_COPIED (loc);
6579                       rtx src = NULL, dst = uloc;
6580                       enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
6581
6582                       if (GET_CODE (uloc) == SET)
6583                         {
6584                           src = SET_SRC (uloc);
6585                           dst = SET_DEST (uloc);
6586                         }
6587
6588                       if (copied_p)
6589                         {
6590                           if (flag_var_tracking_uninit)
6591                             {
6592                               status = find_src_status (in, src);
6593
6594                               if (status == VAR_INIT_STATUS_UNKNOWN)
6595                                 status = find_src_status (out, src);
6596                             }
6597
6598                           src = find_src_set_src (in, src);
6599                         }
6600
6601                       if (REG_P (dst))
6602                         var_reg_delete_and_set (out, dst, !copied_p,
6603                                                 status, srcv);
6604                       else if (MEM_P (dst))
6605                         {
6606                           gcc_assert (MEM_P (dstv));
6607                           gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (dst));
6608                           var_mem_delete_and_set (out, dstv, !copied_p,
6609                                                   status, srcv);
6610                         }
6611                     }
6612                 }
6613               else if (REG_P (uloc))
6614                 var_regno_delete (out, REGNO (uloc));
6615               else if (MEM_P (uloc))
6616                 clobber_overlapping_mems (out, uloc);
6617
6618               val_store (out, val, dstv, insn, true);
6619             }
6620             break;
6621
6622           case MO_SET:
6623             {
6624               rtx loc = mo->u.loc;
6625               rtx set_src = NULL;
6626
6627               if (GET_CODE (loc) == SET)
6628                 {
6629                   set_src = SET_SRC (loc);
6630                   loc = SET_DEST (loc);
6631                 }
6632
6633               if (REG_P (loc))
6634                 var_reg_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
6635                                         set_src);
6636               else if (MEM_P (loc))
6637                 var_mem_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
6638                                         set_src);
6639             }
6640             break;
6641
6642           case MO_COPY:
6643             {
6644               rtx loc = mo->u.loc;
6645               enum var_init_status src_status;
6646               rtx set_src = NULL;
6647
6648               if (GET_CODE (loc) == SET)
6649                 {
6650                   set_src = SET_SRC (loc);
6651                   loc = SET_DEST (loc);
6652                 }
6653
6654               if (! flag_var_tracking_uninit)
6655                 src_status = VAR_INIT_STATUS_INITIALIZED;
6656               else
6657                 {
6658                   src_status = find_src_status (in, set_src);
6659
6660                   if (src_status == VAR_INIT_STATUS_UNKNOWN)
6661                     src_status = find_src_status (out, set_src);
6662                 }
6663
6664               set_src = find_src_set_src (in, set_src);
6665
6666               if (REG_P (loc))
6667                 var_reg_delete_and_set (out, loc, false, src_status, set_src);
6668               else if (MEM_P (loc))
6669                 var_mem_delete_and_set (out, loc, false, src_status, set_src);
6670             }
6671             break;
6672
6673           case MO_USE_NO_VAR:
6674             {
6675               rtx loc = mo->u.loc;
6676
6677               if (REG_P (loc))
6678                 var_reg_delete (out, loc, false);
6679               else if (MEM_P (loc))
6680                 var_mem_delete (out, loc, false);
6681             }
6682             break;
6683
6684           case MO_CLOBBER:
6685             {
6686               rtx loc = mo->u.loc;
6687
6688               if (REG_P (loc))
6689                 var_reg_delete (out, loc, true);
6690               else if (MEM_P (loc))
6691                 var_mem_delete (out, loc, true);
6692             }
6693             break;
6694
6695           case MO_ADJUST:
6696             out->stack_adjust += mo->u.adjust;
6697             break;
6698         }
6699     }
6700
6701   if (MAY_HAVE_DEBUG_INSNS)
6702     {
6703       dataflow_set_equiv_regs (out);
6704       htab_traverse (shared_hash_htab (out->vars), canonicalize_values_mark,
6705                      out);
6706       htab_traverse (shared_hash_htab (out->vars), canonicalize_values_star,
6707                      out);
6708 #if ENABLE_CHECKING
6709       htab_traverse (shared_hash_htab (out->vars),
6710                      canonicalize_loc_order_check, out);
6711 #endif
6712     }
6713   changed = dataflow_set_different (&old_out, out);
6714   dataflow_set_destroy (&old_out);
6715   return changed;
6716 }
6717
6718 /* Find the locations of variables in the whole function.  */
6719
6720 static bool
6721 vt_find_locations (void)
6722 {
6723   fibheap_t worklist, pending, fibheap_swap;
6724   sbitmap visited, in_worklist, in_pending, sbitmap_swap;
6725   basic_block bb;
6726   edge e;
6727   int *bb_order;
6728   int *rc_order;
6729   int i;
6730   int htabsz = 0;
6731   int htabmax = PARAM_VALUE (PARAM_MAX_VARTRACK_SIZE);
6732   bool success = true;
6733
6734   timevar_push (TV_VAR_TRACKING_DATAFLOW);
6735   /* Compute reverse completion order of depth first search of the CFG
6736      so that the data-flow runs faster.  */
6737   rc_order = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
6738   bb_order = XNEWVEC (int, last_basic_block);
6739   pre_and_rev_post_order_compute (NULL, rc_order, false);
6740   for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
6741     bb_order[rc_order[i]] = i;
6742   free (rc_order);
6743
6744   worklist = fibheap_new ();
6745   pending = fibheap_new ();
6746   visited = sbitmap_alloc (last_basic_block);
6747   in_worklist = sbitmap_alloc (last_basic_block);
6748   in_pending = sbitmap_alloc (last_basic_block);
6749   sbitmap_zero (in_worklist);
6750
6751   FOR_EACH_BB (bb)
6752     fibheap_insert (pending, bb_order[bb->index], bb);
6753   sbitmap_ones (in_pending);
6754
6755   while (success && !fibheap_empty (pending))
6756     {
6757       fibheap_swap = pending;
6758       pending = worklist;
6759       worklist = fibheap_swap;
6760       sbitmap_swap = in_pending;
6761       in_pending = in_worklist;
6762       in_worklist = sbitmap_swap;
6763
6764       sbitmap_zero (visited);
6765
6766       while (!fibheap_empty (worklist))
6767         {
6768           bb = (basic_block) fibheap_extract_min (worklist);
6769           RESET_BIT (in_worklist, bb->index);
6770           gcc_assert (!TEST_BIT (visited, bb->index));
6771           if (!TEST_BIT (visited, bb->index))
6772             {
6773               bool changed;
6774               edge_iterator ei;
6775               int oldinsz, oldoutsz;
6776
6777               SET_BIT (visited, bb->index);
6778
6779               if (VTI (bb)->in.vars)
6780                 {
6781                   htabsz
6782                     -= (htab_size (shared_hash_htab (VTI (bb)->in.vars))
6783                         + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
6784                   oldinsz
6785                     = htab_elements (shared_hash_htab (VTI (bb)->in.vars));
6786                   oldoutsz
6787                     = htab_elements (shared_hash_htab (VTI (bb)->out.vars));
6788                 }
6789               else
6790                 oldinsz = oldoutsz = 0;
6791
6792               if (MAY_HAVE_DEBUG_INSNS)
6793                 {
6794                   dataflow_set *in = &VTI (bb)->in, *first_out = NULL;
6795                   bool first = true, adjust = false;
6796
6797                   /* Calculate the IN set as the intersection of
6798                      predecessor OUT sets.  */
6799
6800                   dataflow_set_clear (in);
6801                   dst_can_be_shared = true;
6802
6803                   FOR_EACH_EDGE (e, ei, bb->preds)
6804                     if (!VTI (e->src)->flooded)
6805                       gcc_assert (bb_order[bb->index]
6806                                   <= bb_order[e->src->index]);
6807                     else if (first)
6808                       {
6809                         dataflow_set_copy (in, &VTI (e->src)->out);
6810                         first_out = &VTI (e->src)->out;
6811                         first = false;
6812                       }
6813                     else
6814                       {
6815                         dataflow_set_merge (in, &VTI (e->src)->out);
6816                         adjust = true;
6817                       }
6818
6819                   if (adjust)
6820                     {
6821                       dataflow_post_merge_adjust (in, &VTI (bb)->permp);
6822 #if ENABLE_CHECKING
6823                       /* Merge and merge_adjust should keep entries in
6824                          canonical order.  */
6825                       htab_traverse (shared_hash_htab (in->vars),
6826                                      canonicalize_loc_order_check,
6827                                      in);
6828 #endif
6829                       if (dst_can_be_shared)
6830                         {
6831                           shared_hash_destroy (in->vars);
6832                           in->vars = shared_hash_copy (first_out->vars);
6833                         }
6834                     }
6835
6836                   VTI (bb)->flooded = true;
6837                 }
6838               else
6839                 {
6840                   /* Calculate the IN set as union of predecessor OUT sets.  */
6841                   dataflow_set_clear (&VTI (bb)->in);
6842                   FOR_EACH_EDGE (e, ei, bb->preds)
6843                     dataflow_set_union (&VTI (bb)->in, &VTI (e->src)->out);
6844                 }
6845
6846               changed = compute_bb_dataflow (bb);
6847               htabsz += (htab_size (shared_hash_htab (VTI (bb)->in.vars))
6848                          + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
6849
6850               if (htabmax && htabsz > htabmax)
6851                 {
6852                   if (MAY_HAVE_DEBUG_INSNS)
6853                     inform (DECL_SOURCE_LOCATION (cfun->decl),
6854                             "variable tracking size limit exceeded with "
6855                             "-fvar-tracking-assignments, retrying without");
6856                   else
6857                     inform (DECL_SOURCE_LOCATION (cfun->decl),
6858                             "variable tracking size limit exceeded");
6859                   success = false;
6860                   break;
6861                 }
6862
6863               if (changed)
6864                 {
6865                   FOR_EACH_EDGE (e, ei, bb->succs)
6866                     {
6867                       if (e->dest == EXIT_BLOCK_PTR)
6868                         continue;
6869
6870                       if (TEST_BIT (visited, e->dest->index))
6871                         {
6872                           if (!TEST_BIT (in_pending, e->dest->index))
6873                             {
6874                               /* Send E->DEST to next round.  */
6875                               SET_BIT (in_pending, e->dest->index);
6876                               fibheap_insert (pending,
6877                                               bb_order[e->dest->index],
6878                                               e->dest);
6879                             }
6880                         }
6881                       else if (!TEST_BIT (in_worklist, e->dest->index))
6882                         {
6883                           /* Add E->DEST to current round.  */
6884                           SET_BIT (in_worklist, e->dest->index);
6885                           fibheap_insert (worklist, bb_order[e->dest->index],
6886                                           e->dest);
6887                         }
6888                     }
6889                 }
6890
6891               if (dump_file)
6892                 fprintf (dump_file,
6893                          "BB %i: in %i (was %i), out %i (was %i), rem %i + %i, tsz %i\n",
6894                          bb->index,
6895                          (int)htab_elements (shared_hash_htab (VTI (bb)->in.vars)),
6896                          oldinsz,
6897                          (int)htab_elements (shared_hash_htab (VTI (bb)->out.vars)),
6898                          oldoutsz,
6899                          (int)worklist->nodes, (int)pending->nodes, htabsz);
6900
6901               if (dump_file && (dump_flags & TDF_DETAILS))
6902                 {
6903                   fprintf (dump_file, "BB %i IN:\n", bb->index);
6904                   dump_dataflow_set (&VTI (bb)->in);
6905                   fprintf (dump_file, "BB %i OUT:\n", bb->index);
6906                   dump_dataflow_set (&VTI (bb)->out);
6907                 }
6908             }
6909         }
6910     }
6911
6912   if (success && MAY_HAVE_DEBUG_INSNS)
6913     FOR_EACH_BB (bb)
6914       gcc_assert (VTI (bb)->flooded);
6915
6916   free (bb_order);
6917   fibheap_delete (worklist);
6918   fibheap_delete (pending);
6919   sbitmap_free (visited);
6920   sbitmap_free (in_worklist);
6921   sbitmap_free (in_pending);
6922
6923   timevar_pop (TV_VAR_TRACKING_DATAFLOW);
6924   return success;
6925 }
6926
6927 /* Print the content of the LIST to dump file.  */
6928
6929 static void
6930 dump_attrs_list (attrs list)
6931 {
6932   for (; list; list = list->next)
6933     {
6934       if (dv_is_decl_p (list->dv))
6935         print_mem_expr (dump_file, dv_as_decl (list->dv));
6936       else
6937         print_rtl_single (dump_file, dv_as_value (list->dv));
6938       fprintf (dump_file, "+" HOST_WIDE_INT_PRINT_DEC, list->offset);
6939     }
6940   fprintf (dump_file, "\n");
6941 }
6942
6943 /* Print the information about variable *SLOT to dump file.  */
6944
6945 static int
6946 dump_var_slot (void **slot, void *data ATTRIBUTE_UNUSED)
6947 {
6948   variable var = (variable) *slot;
6949
6950   dump_var (var);
6951
6952   /* Continue traversing the hash table.  */
6953   return 1;
6954 }
6955
6956 /* Print the information about variable VAR to dump file.  */
6957
6958 static void
6959 dump_var (variable var)
6960 {
6961   int i;
6962   location_chain node;
6963
6964   if (dv_is_decl_p (var->dv))
6965     {
6966       const_tree decl = dv_as_decl (var->dv);
6967
6968       if (DECL_NAME (decl))
6969         {
6970           fprintf (dump_file, "  name: %s",
6971                    IDENTIFIER_POINTER (DECL_NAME (decl)));
6972           if (dump_flags & TDF_UID)
6973             fprintf (dump_file, "D.%u", DECL_UID (decl));
6974         }
6975       else if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
6976         fprintf (dump_file, "  name: D#%u", DEBUG_TEMP_UID (decl));
6977       else
6978         fprintf (dump_file, "  name: D.%u", DECL_UID (decl));
6979       fprintf (dump_file, "\n");
6980     }
6981   else
6982     {
6983       fputc (' ', dump_file);
6984       print_rtl_single (dump_file, dv_as_value (var->dv));
6985     }
6986
6987   for (i = 0; i < var->n_var_parts; i++)
6988     {
6989       fprintf (dump_file, "    offset %ld\n",
6990                (long)(var->onepart ? 0 : VAR_PART_OFFSET (var, i)));
6991       for (node = var->var_part[i].loc_chain; node; node = node->next)
6992         {
6993           fprintf (dump_file, "      ");
6994           if (node->init == VAR_INIT_STATUS_UNINITIALIZED)
6995             fprintf (dump_file, "[uninit]");
6996           print_rtl_single (dump_file, node->loc);
6997         }
6998     }
6999 }
7000
7001 /* Print the information about variables from hash table VARS to dump file.  */
7002
7003 static void
7004 dump_vars (htab_t vars)
7005 {
7006   if (htab_elements (vars) > 0)
7007     {
7008       fprintf (dump_file, "Variables:\n");
7009       htab_traverse (vars, dump_var_slot, NULL);
7010     }
7011 }
7012
7013 /* Print the dataflow set SET to dump file.  */
7014
7015 static void
7016 dump_dataflow_set (dataflow_set *set)
7017 {
7018   int i;
7019
7020   fprintf (dump_file, "Stack adjustment: " HOST_WIDE_INT_PRINT_DEC "\n",
7021            set->stack_adjust);
7022   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
7023     {
7024       if (set->regs[i])
7025         {
7026           fprintf (dump_file, "Reg %d:", i);
7027           dump_attrs_list (set->regs[i]);
7028         }
7029     }
7030   dump_vars (shared_hash_htab (set->vars));
7031   fprintf (dump_file, "\n");
7032 }
7033
7034 /* Print the IN and OUT sets for each basic block to dump file.  */
7035
7036 static void
7037 dump_dataflow_sets (void)
7038 {
7039   basic_block bb;
7040
7041   FOR_EACH_BB (bb)
7042     {
7043       fprintf (dump_file, "\nBasic block %d:\n", bb->index);
7044       fprintf (dump_file, "IN:\n");
7045       dump_dataflow_set (&VTI (bb)->in);
7046       fprintf (dump_file, "OUT:\n");
7047       dump_dataflow_set (&VTI (bb)->out);
7048     }
7049 }
7050
7051 /* Return the variable for DV in dropped_values, inserting one if
7052    requested with INSERT.  */
7053
7054 static inline variable
7055 variable_from_dropped (decl_or_value dv, enum insert_option insert)
7056 {
7057   void **slot;
7058   variable empty_var;
7059   onepart_enum_t onepart;
7060
7061   slot = htab_find_slot_with_hash (dropped_values, dv, dv_htab_hash (dv),
7062                                    insert);
7063
7064   if (!slot)
7065     return NULL;
7066
7067   if (*slot)
7068     return (variable) *slot;
7069
7070   gcc_checking_assert (insert == INSERT);
7071
7072   onepart = dv_onepart_p (dv);
7073
7074   gcc_checking_assert (onepart == ONEPART_VALUE || onepart == ONEPART_DEXPR);
7075
7076   empty_var = (variable) pool_alloc (onepart_pool (onepart));
7077   empty_var->dv = dv;
7078   empty_var->refcount = 1;
7079   empty_var->n_var_parts = 0;
7080   empty_var->onepart = onepart;
7081   empty_var->in_changed_variables = false;
7082   empty_var->var_part[0].loc_chain = NULL;
7083   empty_var->var_part[0].cur_loc = NULL;
7084   VAR_LOC_1PAUX (empty_var) = NULL;
7085   set_dv_changed (dv, true);
7086
7087   *slot = empty_var;
7088
7089   return empty_var;
7090 }
7091
7092 /* Recover the one-part aux from dropped_values.  */
7093
7094 static struct onepart_aux *
7095 recover_dropped_1paux (variable var)
7096 {
7097   variable dvar;
7098
7099   gcc_checking_assert (var->onepart);
7100
7101   if (VAR_LOC_1PAUX (var))
7102     return VAR_LOC_1PAUX (var);
7103
7104   if (var->onepart == ONEPART_VDECL)
7105     return NULL;
7106
7107   dvar = variable_from_dropped (var->dv, NO_INSERT);
7108
7109   if (!dvar)
7110     return NULL;
7111
7112   VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (dvar);
7113   VAR_LOC_1PAUX (dvar) = NULL;
7114
7115   return VAR_LOC_1PAUX (var);
7116 }
7117
7118 /* Add variable VAR to the hash table of changed variables and
7119    if it has no locations delete it from SET's hash table.  */
7120
7121 static void
7122 variable_was_changed (variable var, dataflow_set *set)
7123 {
7124   hashval_t hash = dv_htab_hash (var->dv);
7125
7126   if (emit_notes)
7127     {
7128       void **slot;
7129
7130       /* Remember this decl or VALUE has been added to changed_variables.  */
7131       set_dv_changed (var->dv, true);
7132
7133       slot = htab_find_slot_with_hash (changed_variables,
7134                                        var->dv,
7135                                        hash, INSERT);
7136
7137       if (*slot)
7138         {
7139           variable old_var = (variable) *slot;
7140           gcc_assert (old_var->in_changed_variables);
7141           old_var->in_changed_variables = false;
7142           if (var != old_var && var->onepart)
7143             {
7144               /* Restore the auxiliary info from an empty variable
7145                  previously created for changed_variables, so it is
7146                  not lost.  */
7147               gcc_checking_assert (!VAR_LOC_1PAUX (var));
7148               VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (old_var);
7149               VAR_LOC_1PAUX (old_var) = NULL;
7150             }
7151           variable_htab_free (*slot);
7152         }
7153
7154       if (set && var->n_var_parts == 0)
7155         {
7156           onepart_enum_t onepart = var->onepart;
7157           variable empty_var = NULL;
7158           void **dslot = NULL;
7159
7160           if (onepart == ONEPART_VALUE || onepart == ONEPART_DEXPR)
7161             {
7162               dslot = htab_find_slot_with_hash (dropped_values, var->dv,
7163                                                 dv_htab_hash (var->dv),
7164                                                 INSERT);
7165               empty_var = (variable) *dslot;
7166
7167               if (empty_var)
7168                 {
7169                   gcc_checking_assert (!empty_var->in_changed_variables);
7170                   if (!VAR_LOC_1PAUX (var))
7171                     {
7172                       VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (empty_var);
7173                       VAR_LOC_1PAUX (empty_var) = NULL;
7174                     }
7175                   else
7176                     gcc_checking_assert (!VAR_LOC_1PAUX (empty_var));
7177                 }
7178             }
7179
7180           if (!empty_var)
7181             {
7182               empty_var = (variable) pool_alloc (onepart_pool (onepart));
7183               empty_var->dv = var->dv;
7184               empty_var->refcount = 1;
7185               empty_var->n_var_parts = 0;
7186               empty_var->onepart = onepart;
7187               if (dslot)
7188                 {
7189                   empty_var->refcount++;
7190                   *dslot = empty_var;
7191                 }
7192             }
7193           else
7194             empty_var->refcount++;
7195           empty_var->in_changed_variables = true;
7196           *slot = empty_var;
7197           if (onepart)
7198             {
7199               empty_var->var_part[0].loc_chain = NULL;
7200               empty_var->var_part[0].cur_loc = NULL;
7201               VAR_LOC_1PAUX (empty_var) = VAR_LOC_1PAUX (var);
7202               VAR_LOC_1PAUX (var) = NULL;
7203             }
7204           goto drop_var;
7205         }
7206       else
7207         {
7208           if (var->onepart && !VAR_LOC_1PAUX (var))
7209             recover_dropped_1paux (var);
7210           var->refcount++;
7211           var->in_changed_variables = true;
7212           *slot = var;
7213         }
7214     }
7215   else
7216     {
7217       gcc_assert (set);
7218       if (var->n_var_parts == 0)
7219         {
7220           void **slot;
7221
7222         drop_var:
7223           slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
7224           if (slot)
7225             {
7226               if (shared_hash_shared (set->vars))
7227                 slot = shared_hash_find_slot_unshare (&set->vars, var->dv,
7228                                                       NO_INSERT);
7229               htab_clear_slot (shared_hash_htab (set->vars), slot);
7230             }
7231         }
7232     }
7233 }
7234
7235 /* Look for the index in VAR->var_part corresponding to OFFSET.
7236    Return -1 if not found.  If INSERTION_POINT is non-NULL, the
7237    referenced int will be set to the index that the part has or should
7238    have, if it should be inserted.  */
7239
7240 static inline int
7241 find_variable_location_part (variable var, HOST_WIDE_INT offset,
7242                              int *insertion_point)
7243 {
7244   int pos, low, high;
7245
7246   if (var->onepart)
7247     {
7248       if (offset != 0)
7249         return -1;
7250
7251       if (insertion_point)
7252         *insertion_point = 0;
7253
7254       return var->n_var_parts - 1;
7255     }
7256
7257   /* Find the location part.  */
7258   low = 0;
7259   high = var->n_var_parts;
7260   while (low != high)
7261     {
7262       pos = (low + high) / 2;
7263       if (VAR_PART_OFFSET (var, pos) < offset)
7264         low = pos + 1;
7265       else
7266         high = pos;
7267     }
7268   pos = low;
7269
7270   if (insertion_point)
7271     *insertion_point = pos;
7272
7273   if (pos < var->n_var_parts && VAR_PART_OFFSET (var, pos) == offset)
7274     return pos;
7275
7276   return -1;
7277 }
7278
7279 static void **
7280 set_slot_part (dataflow_set *set, rtx loc, void **slot,
7281                decl_or_value dv, HOST_WIDE_INT offset,
7282                enum var_init_status initialized, rtx set_src)
7283 {
7284   int pos;
7285   location_chain node, next;
7286   location_chain *nextp;
7287   variable var;
7288   onepart_enum_t onepart;
7289
7290   var = (variable) *slot;
7291
7292   if (var)
7293     onepart = var->onepart;
7294   else
7295     onepart = dv_onepart_p (dv);
7296
7297   gcc_checking_assert (offset == 0 || !onepart);
7298   gcc_checking_assert (loc != dv_as_opaque (dv));
7299
7300   if (! flag_var_tracking_uninit)
7301     initialized = VAR_INIT_STATUS_INITIALIZED;
7302
7303   if (!var)
7304     {
7305       /* Create new variable information.  */
7306       var = (variable) pool_alloc (onepart_pool (onepart));
7307       var->dv = dv;
7308       var->refcount = 1;
7309       var->n_var_parts = 1;
7310       var->onepart = onepart;
7311       var->in_changed_variables = false;
7312       if (var->onepart)
7313         VAR_LOC_1PAUX (var) = NULL;
7314       else
7315         VAR_PART_OFFSET (var, 0) = offset;
7316       var->var_part[0].loc_chain = NULL;
7317       var->var_part[0].cur_loc = NULL;
7318       *slot = var;
7319       pos = 0;
7320       nextp = &var->var_part[0].loc_chain;
7321     }
7322   else if (onepart)
7323     {
7324       int r = -1, c = 0;
7325
7326       gcc_assert (dv_as_opaque (var->dv) == dv_as_opaque (dv));
7327
7328       pos = 0;
7329
7330       if (GET_CODE (loc) == VALUE)
7331         {
7332           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7333                nextp = &node->next)
7334             if (GET_CODE (node->loc) == VALUE)
7335               {
7336                 if (node->loc == loc)
7337                   {
7338                     r = 0;
7339                     break;
7340                   }
7341                 if (canon_value_cmp (node->loc, loc))
7342                   c++;
7343                 else
7344                   {
7345                     r = 1;
7346                     break;
7347                   }
7348               }
7349             else if (REG_P (node->loc) || MEM_P (node->loc))
7350               c++;
7351             else
7352               {
7353                 r = 1;
7354                 break;
7355               }
7356         }
7357       else if (REG_P (loc))
7358         {
7359           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7360                nextp = &node->next)
7361             if (REG_P (node->loc))
7362               {
7363                 if (REGNO (node->loc) < REGNO (loc))
7364                   c++;
7365                 else
7366                   {
7367                     if (REGNO (node->loc) == REGNO (loc))
7368                       r = 0;
7369                     else
7370                       r = 1;
7371                     break;
7372                   }
7373               }
7374             else
7375               {
7376                 r = 1;
7377                 break;
7378               }
7379         }
7380       else if (MEM_P (loc))
7381         {
7382           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7383                nextp = &node->next)
7384             if (REG_P (node->loc))
7385               c++;
7386             else if (MEM_P (node->loc))
7387               {
7388                 if ((r = loc_cmp (XEXP (node->loc, 0), XEXP (loc, 0))) >= 0)
7389                   break;
7390                 else
7391                   c++;
7392               }
7393             else
7394               {
7395                 r = 1;
7396                 break;
7397               }
7398         }
7399       else
7400         for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7401              nextp = &node->next)
7402           if ((r = loc_cmp (node->loc, loc)) >= 0)
7403             break;
7404           else
7405             c++;
7406
7407       if (r == 0)
7408         return slot;
7409
7410       if (shared_var_p (var, set->vars))
7411         {
7412           slot = unshare_variable (set, slot, var, initialized);
7413           var = (variable)*slot;
7414           for (nextp = &var->var_part[0].loc_chain; c;
7415                nextp = &(*nextp)->next)
7416             c--;
7417           gcc_assert ((!node && !*nextp) || node->loc == (*nextp)->loc);
7418         }
7419     }
7420   else
7421     {
7422       int inspos = 0;
7423
7424       gcc_assert (dv_as_decl (var->dv) == dv_as_decl (dv));
7425
7426       pos = find_variable_location_part (var, offset, &inspos);
7427
7428       if (pos >= 0)
7429         {
7430           node = var->var_part[pos].loc_chain;
7431
7432           if (node
7433               && ((REG_P (node->loc) && REG_P (loc)
7434                    && REGNO (node->loc) == REGNO (loc))
7435                   || rtx_equal_p (node->loc, loc)))
7436             {
7437               /* LOC is in the beginning of the chain so we have nothing
7438                  to do.  */
7439               if (node->init < initialized)
7440                 node->init = initialized;
7441               if (set_src != NULL)
7442                 node->set_src = set_src;
7443
7444               return slot;
7445             }
7446           else
7447             {
7448               /* We have to make a copy of a shared variable.  */
7449               if (shared_var_p (var, set->vars))
7450                 {
7451                   slot = unshare_variable (set, slot, var, initialized);
7452                   var = (variable)*slot;
7453                 }
7454             }
7455         }
7456       else
7457         {
7458           /* We have not found the location part, new one will be created.  */
7459
7460           /* We have to make a copy of the shared variable.  */
7461           if (shared_var_p (var, set->vars))
7462             {
7463               slot = unshare_variable (set, slot, var, initialized);
7464               var = (variable)*slot;
7465             }
7466
7467           /* We track only variables whose size is <= MAX_VAR_PARTS bytes
7468              thus there are at most MAX_VAR_PARTS different offsets.  */
7469           gcc_assert (var->n_var_parts < MAX_VAR_PARTS
7470                       && (!var->n_var_parts || !onepart));
7471
7472           /* We have to move the elements of array starting at index
7473              inspos to the next position.  */
7474           for (pos = var->n_var_parts; pos > inspos; pos--)
7475             var->var_part[pos] = var->var_part[pos - 1];
7476
7477           var->n_var_parts++;
7478           gcc_checking_assert (!onepart);
7479           VAR_PART_OFFSET (var, pos) = offset;
7480           var->var_part[pos].loc_chain = NULL;
7481           var->var_part[pos].cur_loc = NULL;
7482         }
7483
7484       /* Delete the location from the list.  */
7485       nextp = &var->var_part[pos].loc_chain;
7486       for (node = var->var_part[pos].loc_chain; node; node = next)
7487         {
7488           next = node->next;
7489           if ((REG_P (node->loc) && REG_P (loc)
7490                && REGNO (node->loc) == REGNO (loc))
7491               || rtx_equal_p (node->loc, loc))
7492             {
7493               /* Save these values, to assign to the new node, before
7494                  deleting this one.  */
7495               if (node->init > initialized)
7496                 initialized = node->init;
7497               if (node->set_src != NULL && set_src == NULL)
7498                 set_src = node->set_src;
7499               if (var->var_part[pos].cur_loc == node->loc)
7500                 var->var_part[pos].cur_loc = NULL;
7501               pool_free (loc_chain_pool, node);
7502               *nextp = next;
7503               break;
7504             }
7505           else
7506             nextp = &node->next;
7507         }
7508
7509       nextp = &var->var_part[pos].loc_chain;
7510     }
7511
7512   /* Add the location to the beginning.  */
7513   node = (location_chain) pool_alloc (loc_chain_pool);
7514   node->loc = loc;
7515   node->init = initialized;
7516   node->set_src = set_src;
7517   node->next = *nextp;
7518   *nextp = node;
7519
7520   /* If no location was emitted do so.  */
7521   if (var->var_part[pos].cur_loc == NULL)
7522     variable_was_changed (var, set);
7523
7524   return slot;
7525 }
7526
7527 /* Set the part of variable's location in the dataflow set SET.  The
7528    variable part is specified by variable's declaration in DV and
7529    offset OFFSET and the part's location by LOC.  IOPT should be
7530    NO_INSERT if the variable is known to be in SET already and the
7531    variable hash table must not be resized, and INSERT otherwise.  */
7532
7533 static void
7534 set_variable_part (dataflow_set *set, rtx loc,
7535                    decl_or_value dv, HOST_WIDE_INT offset,
7536                    enum var_init_status initialized, rtx set_src,
7537                    enum insert_option iopt)
7538 {
7539   void **slot;
7540
7541   if (iopt == NO_INSERT)
7542     slot = shared_hash_find_slot_noinsert (set->vars, dv);
7543   else
7544     {
7545       slot = shared_hash_find_slot (set->vars, dv);
7546       if (!slot)
7547         slot = shared_hash_find_slot_unshare (&set->vars, dv, iopt);
7548     }
7549   set_slot_part (set, loc, slot, dv, offset, initialized, set_src);
7550 }
7551
7552 /* Remove all recorded register locations for the given variable part
7553    from dataflow set SET, except for those that are identical to loc.
7554    The variable part is specified by variable's declaration or value
7555    DV and offset OFFSET.  */
7556
7557 static void **
7558 clobber_slot_part (dataflow_set *set, rtx loc, void **slot,
7559                    HOST_WIDE_INT offset, rtx set_src)
7560 {
7561   variable var = (variable) *slot;
7562   int pos = find_variable_location_part (var, offset, NULL);
7563
7564   if (pos >= 0)
7565     {
7566       location_chain node, next;
7567
7568       /* Remove the register locations from the dataflow set.  */
7569       next = var->var_part[pos].loc_chain;
7570       for (node = next; node; node = next)
7571         {
7572           next = node->next;
7573           if (node->loc != loc
7574               && (!flag_var_tracking_uninit
7575                   || !set_src
7576                   || MEM_P (set_src)
7577                   || !rtx_equal_p (set_src, node->set_src)))
7578             {
7579               if (REG_P (node->loc))
7580                 {
7581                   attrs anode, anext;
7582                   attrs *anextp;
7583
7584                   /* Remove the variable part from the register's
7585                      list, but preserve any other variable parts
7586                      that might be regarded as live in that same
7587                      register.  */
7588                   anextp = &set->regs[REGNO (node->loc)];
7589                   for (anode = *anextp; anode; anode = anext)
7590                     {
7591                       anext = anode->next;
7592                       if (dv_as_opaque (anode->dv) == dv_as_opaque (var->dv)
7593                           && anode->offset == offset)
7594                         {
7595                           pool_free (attrs_pool, anode);
7596                           *anextp = anext;
7597                         }
7598                       else
7599                         anextp = &anode->next;
7600                     }
7601                 }
7602
7603               slot = delete_slot_part (set, node->loc, slot, offset);
7604             }
7605         }
7606     }
7607
7608   return slot;
7609 }
7610
7611 /* Remove all recorded register locations for the given variable part
7612    from dataflow set SET, except for those that are identical to loc.
7613    The variable part is specified by variable's declaration or value
7614    DV and offset OFFSET.  */
7615
7616 static void
7617 clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
7618                        HOST_WIDE_INT offset, rtx set_src)
7619 {
7620   void **slot;
7621
7622   if (!dv_as_opaque (dv)
7623       || (!dv_is_value_p (dv) && ! DECL_P (dv_as_decl (dv))))
7624     return;
7625
7626   slot = shared_hash_find_slot_noinsert (set->vars, dv);
7627   if (!slot)
7628     return;
7629
7630   clobber_slot_part (set, loc, slot, offset, set_src);
7631 }
7632
7633 /* Delete the part of variable's location from dataflow set SET.  The
7634    variable part is specified by its SET->vars slot SLOT and offset
7635    OFFSET and the part's location by LOC.  */
7636
7637 static void **
7638 delete_slot_part (dataflow_set *set, rtx loc, void **slot,
7639                   HOST_WIDE_INT offset)
7640 {
7641   variable var = (variable) *slot;
7642   int pos = find_variable_location_part (var, offset, NULL);
7643
7644   if (pos >= 0)
7645     {
7646       location_chain node, next;
7647       location_chain *nextp;
7648       bool changed;
7649       rtx cur_loc;
7650
7651       if (shared_var_p (var, set->vars))
7652         {
7653           /* If the variable contains the location part we have to
7654              make a copy of the variable.  */
7655           for (node = var->var_part[pos].loc_chain; node;
7656                node = node->next)
7657             {
7658               if ((REG_P (node->loc) && REG_P (loc)
7659                    && REGNO (node->loc) == REGNO (loc))
7660                   || rtx_equal_p (node->loc, loc))
7661                 {
7662                   slot = unshare_variable (set, slot, var,
7663                                            VAR_INIT_STATUS_UNKNOWN);
7664                   var = (variable)*slot;
7665                   break;
7666                 }
7667             }
7668         }
7669
7670       if (pos == 0 && var->onepart && VAR_LOC_1PAUX (var))
7671         cur_loc = VAR_LOC_FROM (var);
7672       else
7673         cur_loc = var->var_part[pos].cur_loc;
7674
7675       /* Delete the location part.  */
7676       changed = false;
7677       nextp = &var->var_part[pos].loc_chain;
7678       for (node = *nextp; node; node = next)
7679         {
7680           next = node->next;
7681           if ((REG_P (node->loc) && REG_P (loc)
7682                && REGNO (node->loc) == REGNO (loc))
7683               || rtx_equal_p (node->loc, loc))
7684             {
7685               /* If we have deleted the location which was last emitted
7686                  we have to emit new location so add the variable to set
7687                  of changed variables.  */
7688               if (cur_loc == node->loc)
7689                 {
7690                   changed = true;
7691                   var->var_part[pos].cur_loc = NULL;
7692                   if (pos == 0 && var->onepart && VAR_LOC_1PAUX (var))
7693                     VAR_LOC_FROM (var) = NULL;
7694                 }
7695               pool_free (loc_chain_pool, node);
7696               *nextp = next;
7697               break;
7698             }
7699           else
7700             nextp = &node->next;
7701         }
7702
7703       if (var->var_part[pos].loc_chain == NULL)
7704         {
7705           changed = true;
7706           var->n_var_parts--;
7707           while (pos < var->n_var_parts)
7708             {
7709               var->var_part[pos] = var->var_part[pos + 1];
7710               pos++;
7711             }
7712         }
7713       if (changed)
7714         variable_was_changed (var, set);
7715     }
7716
7717   return slot;
7718 }
7719
7720 /* Delete the part of variable's location from dataflow set SET.  The
7721    variable part is specified by variable's declaration or value DV
7722    and offset OFFSET and the part's location by LOC.  */
7723
7724 static void
7725 delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
7726                       HOST_WIDE_INT offset)
7727 {
7728   void **slot = shared_hash_find_slot_noinsert (set->vars, dv);
7729   if (!slot)
7730     return;
7731
7732   delete_slot_part (set, loc, slot, offset);
7733 }
7734
7735 DEF_VEC_P (variable);
7736 DEF_VEC_ALLOC_P (variable, heap);
7737
7738 DEF_VEC_ALLOC_P_STACK (rtx);
7739 #define VEC_rtx_stack_alloc(alloc) VEC_stack_alloc (rtx, alloc)
7740
7741 /* Structure for passing some other parameters to function
7742    vt_expand_loc_callback.  */
7743 struct expand_loc_callback_data
7744 {
7745   /* The variables and values active at this point.  */
7746   htab_t vars;
7747
7748   /* Stack of values and debug_exprs under expansion, and their
7749      children.  */
7750   VEC (rtx, stack) *expanding;
7751
7752   /* Stack of values and debug_exprs whose expansion hit recursion
7753      cycles.  They will have VALUE_RECURSED_INTO marked when added to
7754      this list.  This flag will be cleared if any of its dependencies
7755      resolves to a valid location.  So, if the flag remains set at the
7756      end of the search, we know no valid location for this one can
7757      possibly exist.  */
7758   VEC (rtx, stack) *pending;
7759
7760   /* The maximum depth among the sub-expressions under expansion.
7761      Zero indicates no expansion so far.  */
7762   expand_depth depth;
7763 };
7764
7765 /* Allocate the one-part auxiliary data structure for VAR, with enough
7766    room for COUNT dependencies.  */
7767
7768 static void
7769 loc_exp_dep_alloc (variable var, int count)
7770 {
7771   size_t allocsize;
7772
7773   gcc_checking_assert (var->onepart);
7774
7775   /* We can be called with COUNT == 0 to allocate the data structure
7776      without any dependencies, e.g. for the backlinks only.  However,
7777      if we are specifying a COUNT, then the dependency list must have
7778      been emptied before.  It would be possible to adjust pointers or
7779      force it empty here, but this is better done at an earlier point
7780      in the algorithm, so we instead leave an assertion to catch
7781      errors.  */
7782   gcc_checking_assert (!count
7783                        || VEC_empty (loc_exp_dep, VAR_LOC_DEP_VEC (var)));
7784
7785   if (VAR_LOC_1PAUX (var)
7786       && VEC_space (loc_exp_dep, VAR_LOC_DEP_VEC (var), count))
7787     return;
7788
7789   allocsize = offsetof (struct onepart_aux, deps)
7790     + VEC_embedded_size (loc_exp_dep, count);
7791
7792   if (VAR_LOC_1PAUX (var))
7793     {
7794       VAR_LOC_1PAUX (var) = XRESIZEVAR (struct onepart_aux,
7795                                         VAR_LOC_1PAUX (var), allocsize);
7796       /* If the reallocation moves the onepaux structure, the
7797          back-pointer to BACKLINKS in the first list member will still
7798          point to its old location.  Adjust it.  */
7799       if (VAR_LOC_DEP_LST (var))
7800         VAR_LOC_DEP_LST (var)->pprev = VAR_LOC_DEP_LSTP (var);
7801     }
7802   else
7803     {
7804       VAR_LOC_1PAUX (var) = XNEWVAR (struct onepart_aux, allocsize);
7805       *VAR_LOC_DEP_LSTP (var) = NULL;
7806       VAR_LOC_FROM (var) = NULL;
7807       VAR_LOC_DEPTH (var).complexity = 0;
7808       VAR_LOC_DEPTH (var).entryvals = 0;
7809     }
7810   VEC_embedded_init (loc_exp_dep, VAR_LOC_DEP_VEC (var), count);
7811 }
7812
7813 /* Remove all entries from the vector of active dependencies of VAR,
7814    removing them from the back-links lists too.  */
7815
7816 static void
7817 loc_exp_dep_clear (variable var)
7818 {
7819   while (!VEC_empty (loc_exp_dep, VAR_LOC_DEP_VEC (var)))
7820     {
7821       loc_exp_dep *led = &VEC_last (loc_exp_dep, VAR_LOC_DEP_VEC (var));
7822       if (led->next)
7823         led->next->pprev = led->pprev;
7824       if (led->pprev)
7825         *led->pprev = led->next;
7826       VEC_pop (loc_exp_dep, VAR_LOC_DEP_VEC (var));
7827     }
7828 }
7829
7830 /* Insert an active dependency from VAR on X to the vector of
7831    dependencies, and add the corresponding back-link to X's list of
7832    back-links in VARS.  */
7833
7834 static void
7835 loc_exp_insert_dep (variable var, rtx x, htab_t vars)
7836 {
7837   decl_or_value dv;
7838   variable xvar;
7839   loc_exp_dep *led;
7840
7841   dv = dv_from_rtx (x);
7842
7843   /* ??? Build a vector of variables parallel to EXPANDING, to avoid
7844      an additional look up?  */
7845   xvar = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
7846
7847   if (!xvar)
7848     {
7849       xvar = variable_from_dropped (dv, NO_INSERT);
7850       gcc_checking_assert (xvar);
7851     }
7852
7853   /* No point in adding the same backlink more than once.  This may
7854      arise if say the same value appears in two complex expressions in
7855      the same loc_list, or even more than once in a single
7856      expression.  */
7857   if (VAR_LOC_DEP_LST (xvar) && VAR_LOC_DEP_LST (xvar)->dv == var->dv)
7858     return;
7859
7860   if (var->onepart == NOT_ONEPART)
7861     led = (loc_exp_dep *) pool_alloc (loc_exp_dep_pool);
7862   else
7863     {
7864       loc_exp_dep empty;
7865       memset (&empty, 0, sizeof (empty));
7866       VEC_quick_push (loc_exp_dep, VAR_LOC_DEP_VEC (var), empty);
7867       led = &VEC_last (loc_exp_dep, VAR_LOC_DEP_VEC (var));
7868     }
7869   led->dv = var->dv;
7870   led->value = x;
7871
7872   loc_exp_dep_alloc (xvar, 0);
7873   led->pprev = VAR_LOC_DEP_LSTP (xvar);
7874   led->next = *led->pprev;
7875   if (led->next)
7876     led->next->pprev = &led->next;
7877   *led->pprev = led;
7878 }
7879
7880 /* Create active dependencies of VAR on COUNT values starting at
7881    VALUE, and corresponding back-links to the entries in VARS.  Return
7882    true if we found any pending-recursion results.  */
7883
7884 static bool
7885 loc_exp_dep_set (variable var, rtx result, rtx *value, int count, htab_t vars)
7886 {
7887   bool pending_recursion = false;
7888
7889   gcc_checking_assert (VEC_empty (loc_exp_dep, VAR_LOC_DEP_VEC (var)));
7890
7891   /* Set up all dependencies from last_child (as set up at the end of
7892      the loop above) to the end.  */
7893   loc_exp_dep_alloc (var, count);
7894
7895   while (count--)
7896     {
7897       rtx x = *value++;
7898
7899       if (!pending_recursion)
7900         pending_recursion = !result && VALUE_RECURSED_INTO (x);
7901
7902       loc_exp_insert_dep (var, x, vars);
7903     }
7904
7905   return pending_recursion;
7906 }
7907
7908 /* Notify the back-links of IVAR that are pending recursion that we
7909    have found a non-NIL value for it, so they are cleared for another
7910    attempt to compute a current location.  */
7911
7912 static void
7913 notify_dependents_of_resolved_value (variable ivar, htab_t vars)
7914 {
7915   loc_exp_dep *led, *next;
7916
7917   for (led = VAR_LOC_DEP_LST (ivar); led; led = next)
7918     {
7919       decl_or_value dv = led->dv;
7920       variable var;
7921
7922       next = led->next;
7923
7924       if (dv_is_value_p (dv))
7925         {
7926           rtx value = dv_as_value (dv);
7927
7928           /* If we have already resolved it, leave it alone.  */
7929           if (!VALUE_RECURSED_INTO (value))
7930             continue;
7931
7932           /* Check that VALUE_RECURSED_INTO, true from the test above,
7933              implies NO_LOC_P.  */
7934           gcc_checking_assert (NO_LOC_P (value));
7935
7936           /* We won't notify variables that are being expanded,
7937              because their dependency list is cleared before
7938              recursing.  */
7939           NO_LOC_P (value) = false;
7940           VALUE_RECURSED_INTO (value) = false;
7941
7942           gcc_checking_assert (dv_changed_p (dv));
7943         }
7944       else
7945         {
7946           gcc_checking_assert (dv_onepart_p (dv) != NOT_ONEPART);
7947           if (!dv_changed_p (dv))
7948             continue;
7949       }
7950
7951       var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
7952
7953       if (!var)
7954         var = variable_from_dropped (dv, NO_INSERT);
7955
7956       if (var)
7957         notify_dependents_of_resolved_value (var, vars);
7958
7959       if (next)
7960         next->pprev = led->pprev;
7961       if (led->pprev)
7962         *led->pprev = next;
7963       led->next = NULL;
7964       led->pprev = NULL;
7965     }
7966 }
7967
7968 static rtx vt_expand_loc_callback (rtx x, bitmap regs,
7969                                    int max_depth, void *data);
7970
7971 /* Return the combined depth, when one sub-expression evaluated to
7972    BEST_DEPTH and the previous known depth was SAVED_DEPTH.  */
7973
7974 static inline expand_depth
7975 update_depth (expand_depth saved_depth, expand_depth best_depth)
7976 {
7977   /* If we didn't find anything, stick with what we had.  */
7978   if (!best_depth.complexity)
7979     return saved_depth;
7980
7981   /* If we found hadn't found anything, use the depth of the current
7982      expression.  Do NOT add one extra level, we want to compute the
7983      maximum depth among sub-expressions.  We'll increment it later,
7984      if appropriate.  */
7985   if (!saved_depth.complexity)
7986     return best_depth;
7987
7988   /* Combine the entryval count so that regardless of which one we
7989      return, the entryval count is accurate.  */
7990   best_depth.entryvals = saved_depth.entryvals
7991     = best_depth.entryvals + saved_depth.entryvals;
7992
7993   if (saved_depth.complexity < best_depth.complexity)
7994     return best_depth;
7995   else
7996     return saved_depth;
7997 }
7998
7999 /* Expand VAR to a location RTX, updating its cur_loc.  Use REGS and
8000    DATA for cselib expand callback.  If PENDRECP is given, indicate in
8001    it whether any sub-expression couldn't be fully evaluated because
8002    it is pending recursion resolution.  */
8003
8004 static inline rtx
8005 vt_expand_var_loc_chain (variable var, bitmap regs, void *data, bool *pendrecp)
8006 {
8007   struct expand_loc_callback_data *elcd
8008     = (struct expand_loc_callback_data *) data;
8009   location_chain loc, next;
8010   rtx result = NULL;
8011   int first_child, result_first_child, last_child;
8012   bool pending_recursion;
8013   rtx loc_from = NULL;
8014   struct elt_loc_list *cloc = NULL;
8015   expand_depth depth = { 0, 0 }, saved_depth = elcd->depth;
8016   int wanted_entryvals, found_entryvals = 0;
8017
8018   /* Clear all backlinks pointing at this, so that we're not notified
8019      while we're active.  */
8020   loc_exp_dep_clear (var);
8021
8022  retry:
8023   if (var->onepart == ONEPART_VALUE)
8024     {
8025       cselib_val *val = CSELIB_VAL_PTR (dv_as_value (var->dv));
8026
8027       gcc_checking_assert (cselib_preserved_value_p (val));
8028
8029       cloc = val->locs;
8030     }
8031
8032   first_child = result_first_child = last_child
8033     = VEC_length (rtx, elcd->expanding);
8034
8035   wanted_entryvals = found_entryvals;
8036
8037   /* Attempt to expand each available location in turn.  */
8038   for (next = loc = var->n_var_parts ? var->var_part[0].loc_chain : NULL;
8039        loc || cloc; loc = next)
8040     {
8041       result_first_child = last_child;
8042
8043       if (!loc)
8044         {
8045           loc_from = cloc->loc;
8046           next = loc;
8047           cloc = cloc->next;
8048           if (unsuitable_loc (loc_from))
8049             continue;
8050         }
8051       else
8052         {
8053           loc_from = loc->loc;
8054           next = loc->next;
8055         }
8056
8057       gcc_checking_assert (!unsuitable_loc (loc_from));
8058
8059       elcd->depth.complexity = elcd->depth.entryvals = 0;
8060       result = cselib_expand_value_rtx_cb (loc_from, regs, EXPR_DEPTH,
8061                                            vt_expand_loc_callback, data);
8062       last_child = VEC_length (rtx, elcd->expanding);
8063
8064       if (result)
8065         {
8066           depth = elcd->depth;
8067
8068           gcc_checking_assert (depth.complexity
8069                                || result_first_child == last_child);
8070
8071           if (last_child - result_first_child != 1)
8072             {
8073               if (!depth.complexity && GET_CODE (result) == ENTRY_VALUE)
8074                 depth.entryvals++;
8075               depth.complexity++;
8076             }
8077
8078           if (depth.complexity <= EXPR_USE_DEPTH)
8079             {
8080               if (depth.entryvals <= wanted_entryvals)
8081                 break;
8082               else if (!found_entryvals || depth.entryvals < found_entryvals)
8083                 found_entryvals = depth.entryvals;
8084             }
8085
8086           result = NULL;
8087         }
8088
8089       /* Set it up in case we leave the loop.  */
8090       depth.complexity = depth.entryvals = 0;
8091       loc_from = NULL;
8092       result_first_child = first_child;
8093     }
8094
8095   if (!loc_from && wanted_entryvals < found_entryvals)
8096     {
8097       /* We found entries with ENTRY_VALUEs and skipped them.  Since
8098          we could not find any expansions without ENTRY_VALUEs, but we
8099          found at least one with them, go back and get an entry with
8100          the minimum number ENTRY_VALUE count that we found.  We could
8101          avoid looping, but since each sub-loc is already resolved,
8102          the re-expansion should be trivial.  ??? Should we record all
8103          attempted locs as dependencies, so that we retry the
8104          expansion should any of them change, in the hope it can give
8105          us a new entry without an ENTRY_VALUE?  */
8106       VEC_truncate (rtx, elcd->expanding, first_child);
8107       goto retry;
8108     }
8109
8110   /* Register all encountered dependencies as active.  */
8111   pending_recursion = loc_exp_dep_set
8112     (var, result, VEC_address (rtx, elcd->expanding) + result_first_child,
8113      last_child - result_first_child, elcd->vars);
8114
8115   VEC_truncate (rtx, elcd->expanding, first_child);
8116
8117   /* Record where the expansion came from.  */
8118   gcc_checking_assert (!result || !pending_recursion);
8119   VAR_LOC_FROM (var) = loc_from;
8120   VAR_LOC_DEPTH (var) = depth;
8121
8122   gcc_checking_assert (!depth.complexity == !result);
8123
8124   elcd->depth = update_depth (saved_depth, depth);
8125
8126   /* Indicate whether any of the dependencies are pending recursion
8127      resolution.  */
8128   if (pendrecp)
8129     *pendrecp = pending_recursion;
8130
8131   if (!pendrecp || !pending_recursion)
8132     var->var_part[0].cur_loc = result;
8133
8134   return result;
8135 }
8136
8137 /* Callback for cselib_expand_value, that looks for expressions
8138    holding the value in the var-tracking hash tables.  Return X for
8139    standard processing, anything else is to be used as-is.  */
8140
8141 static rtx
8142 vt_expand_loc_callback (rtx x, bitmap regs,
8143                         int max_depth ATTRIBUTE_UNUSED,
8144                         void *data)
8145 {
8146   struct expand_loc_callback_data *elcd
8147     = (struct expand_loc_callback_data *) data;
8148   decl_or_value dv;
8149   variable var;
8150   rtx result, subreg;
8151   bool pending_recursion = false;
8152   bool from_empty = false;
8153
8154   switch (GET_CODE (x))
8155     {
8156     case SUBREG:
8157       subreg = cselib_expand_value_rtx_cb (SUBREG_REG (x), regs,
8158                                            EXPR_DEPTH,
8159                                            vt_expand_loc_callback, data);
8160
8161       if (!subreg)
8162         return NULL;
8163
8164       result = simplify_gen_subreg (GET_MODE (x), subreg,
8165                                     GET_MODE (SUBREG_REG (x)),
8166                                     SUBREG_BYTE (x));
8167
8168       /* Invalid SUBREGs are ok in debug info.  ??? We could try
8169          alternate expansions for the VALUE as well.  */
8170       if (!result)
8171         result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));
8172
8173       return result;
8174
8175     case DEBUG_EXPR:
8176     case VALUE:
8177       dv = dv_from_rtx (x);
8178       break;
8179
8180     default:
8181       return x;
8182     }
8183
8184   VEC_safe_push (rtx, stack, elcd->expanding, x);
8185
8186   /* Check that VALUE_RECURSED_INTO implies NO_LOC_P.  */
8187   gcc_checking_assert (!VALUE_RECURSED_INTO (x) || NO_LOC_P (x));
8188
8189   if (NO_LOC_P (x))
8190     {
8191       gcc_checking_assert (VALUE_RECURSED_INTO (x) || !dv_changed_p (dv));
8192       return NULL;
8193     }
8194
8195   var = (variable) htab_find_with_hash (elcd->vars, dv, dv_htab_hash (dv));
8196
8197   if (!var)
8198     {
8199       from_empty = true;
8200       var = variable_from_dropped (dv, INSERT);
8201     }
8202
8203   gcc_checking_assert (var);
8204
8205   if (!dv_changed_p (dv))
8206     {
8207       gcc_checking_assert (!NO_LOC_P (x));
8208       gcc_checking_assert (var->var_part[0].cur_loc);
8209       gcc_checking_assert (VAR_LOC_1PAUX (var));
8210       gcc_checking_assert (VAR_LOC_1PAUX (var)->depth.complexity);
8211
8212       elcd->depth = update_depth (elcd->depth, VAR_LOC_1PAUX (var)->depth);
8213
8214       return var->var_part[0].cur_loc;
8215     }
8216
8217   VALUE_RECURSED_INTO (x) = true;
8218   /* This is tentative, but it makes some tests simpler.  */
8219   NO_LOC_P (x) = true;
8220
8221   gcc_checking_assert (var->n_var_parts == 1 || from_empty);
8222
8223   result = vt_expand_var_loc_chain (var, regs, data, &pending_recursion);
8224
8225   if (pending_recursion)
8226     {
8227       gcc_checking_assert (!result);
8228       VEC_safe_push (rtx, stack, elcd->pending, x);
8229     }
8230   else
8231     {
8232       NO_LOC_P (x) = !result;
8233       VALUE_RECURSED_INTO (x) = false;
8234       set_dv_changed (dv, false);
8235
8236       if (result)
8237         notify_dependents_of_resolved_value (var, elcd->vars);
8238     }
8239
8240   return result;
8241 }
8242
8243 /* While expanding variables, we may encounter recursion cycles
8244    because of mutual (possibly indirect) dependencies between two
8245    particular variables (or values), say A and B.  If we're trying to
8246    expand A when we get to B, which in turn attempts to expand A, if
8247    we can't find any other expansion for B, we'll add B to this
8248    pending-recursion stack, and tentatively return NULL for its
8249    location.  This tentative value will be used for any other
8250    occurrences of B, unless A gets some other location, in which case
8251    it will notify B that it is worth another try at computing a
8252    location for it, and it will use the location computed for A then.
8253    At the end of the expansion, the tentative NULL locations become
8254    final for all members of PENDING that didn't get a notification.
8255    This function performs this finalization of NULL locations.  */
8256
8257 static void
8258 resolve_expansions_pending_recursion (VEC (rtx, stack) *pending)
8259 {
8260   while (!VEC_empty (rtx, pending))
8261     {
8262       rtx x = VEC_pop (rtx, pending);
8263       decl_or_value dv;
8264
8265       if (!VALUE_RECURSED_INTO (x))
8266         continue;
8267
8268       gcc_checking_assert (NO_LOC_P (x));
8269       VALUE_RECURSED_INTO (x) = false;
8270       dv = dv_from_rtx (x);
8271       gcc_checking_assert (dv_changed_p (dv));
8272       set_dv_changed (dv, false);
8273     }
8274 }
8275
8276 /* Initialize expand_loc_callback_data D with variable hash table V.
8277    It must be a macro because of alloca (VEC stack).  */
8278 #define INIT_ELCD(d, v)                                         \
8279   do                                                            \
8280     {                                                           \
8281       (d).vars = (v);                                           \
8282       (d).expanding = VEC_alloc (rtx, stack, 4);                \
8283       (d).pending = VEC_alloc (rtx, stack, 4);                  \
8284       (d).depth.complexity = (d).depth.entryvals = 0;           \
8285     }                                                           \
8286   while (0)
8287 /* Finalize expand_loc_callback_data D, resolved to location L.  */
8288 #define FINI_ELCD(d, l)                                         \
8289   do                                                            \
8290     {                                                           \
8291       resolve_expansions_pending_recursion ((d).pending);       \
8292       VEC_free (rtx, stack, (d).pending);                       \
8293       VEC_free (rtx, stack, (d).expanding);                     \
8294                                                                 \
8295       if ((l) && MEM_P (l))                                     \
8296         (l) = targetm.delegitimize_address (l);                 \
8297     }                                                           \
8298   while (0)
8299
8300 /* Expand VALUEs and DEBUG_EXPRs in LOC to a location, using the
8301    equivalences in VARS, updating their CUR_LOCs in the process.  */
8302
8303 static rtx
8304 vt_expand_loc (rtx loc, htab_t vars)
8305 {
8306   struct expand_loc_callback_data data;
8307   rtx result;
8308
8309   if (!MAY_HAVE_DEBUG_INSNS)
8310     return loc;
8311
8312   INIT_ELCD (data, vars);
8313
8314   result = cselib_expand_value_rtx_cb (loc, scratch_regs, EXPR_DEPTH,
8315                                        vt_expand_loc_callback, &data);
8316
8317   FINI_ELCD (data, result);
8318
8319   return result;
8320 }
8321
8322 /* Expand the one-part VARiable to a location, using the equivalences
8323    in VARS, updating their CUR_LOCs in the process.  */
8324
8325 static rtx
8326 vt_expand_1pvar (variable var, htab_t vars)
8327 {
8328   struct expand_loc_callback_data data;
8329   rtx loc;
8330
8331   gcc_checking_assert (var->onepart && var->n_var_parts == 1);
8332
8333   if (!dv_changed_p (var->dv))
8334     return var->var_part[0].cur_loc;
8335
8336   INIT_ELCD (data, vars);
8337
8338   loc = vt_expand_var_loc_chain (var, scratch_regs, &data, NULL);
8339
8340   gcc_checking_assert (VEC_empty (rtx, data.expanding));
8341
8342   FINI_ELCD (data, loc);
8343
8344   return loc;
8345 }
8346
8347 /* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP.  DATA contains
8348    additional parameters: WHERE specifies whether the note shall be emitted
8349    before or after instruction INSN.  */
8350
8351 static int
8352 emit_note_insn_var_location (void **varp, void *data)
8353 {
8354   variable var = (variable) *varp;
8355   rtx insn = ((emit_note_data *)data)->insn;
8356   enum emit_note_where where = ((emit_note_data *)data)->where;
8357   htab_t vars = ((emit_note_data *)data)->vars;
8358   rtx note, note_vl;
8359   int i, j, n_var_parts;
8360   bool complete;
8361   enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED;
8362   HOST_WIDE_INT last_limit;
8363   tree type_size_unit;
8364   HOST_WIDE_INT offsets[MAX_VAR_PARTS];
8365   rtx loc[MAX_VAR_PARTS];
8366   tree decl;
8367   location_chain lc;
8368
8369   gcc_checking_assert (var->onepart == NOT_ONEPART
8370                        || var->onepart == ONEPART_VDECL);
8371
8372   decl = dv_as_decl (var->dv);
8373
8374   complete = true;
8375   last_limit = 0;
8376   n_var_parts = 0;
8377   if (!var->onepart)
8378     for (i = 0; i < var->n_var_parts; i++)
8379       if (var->var_part[i].cur_loc == NULL && var->var_part[i].loc_chain)
8380         var->var_part[i].cur_loc = var->var_part[i].loc_chain->loc;
8381   for (i = 0; i < var->n_var_parts; i++)
8382     {
8383       enum machine_mode mode, wider_mode;
8384       rtx loc2;
8385       HOST_WIDE_INT offset;
8386
8387       if (i == 0 && var->onepart)
8388         {
8389           gcc_checking_assert (var->n_var_parts == 1);
8390           offset = 0;
8391           initialized = VAR_INIT_STATUS_INITIALIZED;
8392           loc2 = vt_expand_1pvar (var, vars);
8393         }
8394       else
8395         {
8396           if (last_limit < VAR_PART_OFFSET (var, i))
8397             {
8398               complete = false;
8399               break;
8400             }
8401           else if (last_limit > VAR_PART_OFFSET (var, i))
8402             continue;
8403           offset = VAR_PART_OFFSET (var, i);
8404           loc2 = var->var_part[i].cur_loc;
8405           if (loc2 && GET_CODE (loc2) == MEM
8406               && GET_CODE (XEXP (loc2, 0)) == VALUE)
8407             {
8408               rtx depval = XEXP (loc2, 0);
8409
8410               loc2 = vt_expand_loc (loc2, vars);
8411
8412               if (loc2)
8413                 loc_exp_insert_dep (var, depval, vars);
8414             }
8415           if (!loc2)
8416             {
8417               complete = false;
8418               continue;
8419             }
8420           gcc_checking_assert (GET_CODE (loc2) != VALUE);
8421           for (lc = var->var_part[i].loc_chain; lc; lc = lc->next)
8422             if (var->var_part[i].cur_loc == lc->loc)
8423               {
8424                 initialized = lc->init;
8425                 break;
8426               }
8427           gcc_assert (lc);
8428         }
8429
8430       offsets[n_var_parts] = offset;
8431       if (!loc2)
8432         {
8433           complete = false;
8434           continue;
8435         }
8436       loc[n_var_parts] = loc2;
8437       mode = GET_MODE (var->var_part[i].cur_loc);
8438       if (mode == VOIDmode && var->onepart)
8439         mode = DECL_MODE (decl);
8440       last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
8441
8442       /* Attempt to merge adjacent registers or memory.  */
8443       wider_mode = GET_MODE_WIDER_MODE (mode);
8444       for (j = i + 1; j < var->n_var_parts; j++)
8445         if (last_limit <= VAR_PART_OFFSET (var, j))
8446           break;
8447       if (j < var->n_var_parts
8448           && wider_mode != VOIDmode
8449           && var->var_part[j].cur_loc
8450           && mode == GET_MODE (var->var_part[j].cur_loc)
8451           && (REG_P (loc[n_var_parts]) || MEM_P (loc[n_var_parts]))
8452           && last_limit == (var->onepart ? 0 : VAR_PART_OFFSET (var, j))
8453           && (loc2 = vt_expand_loc (var->var_part[j].cur_loc, vars))
8454           && GET_CODE (loc[n_var_parts]) == GET_CODE (loc2))
8455         {
8456           rtx new_loc = NULL;
8457
8458           if (REG_P (loc[n_var_parts])
8459               && hard_regno_nregs[REGNO (loc[n_var_parts])][mode] * 2
8460                  == hard_regno_nregs[REGNO (loc[n_var_parts])][wider_mode]
8461               && end_hard_regno (mode, REGNO (loc[n_var_parts]))
8462                  == REGNO (loc2))
8463             {
8464               if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
8465                 new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
8466                                            mode, 0);
8467               else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
8468                 new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
8469               if (new_loc)
8470                 {
8471                   if (!REG_P (new_loc)
8472                       || REGNO (new_loc) != REGNO (loc[n_var_parts]))
8473                     new_loc = NULL;
8474                   else
8475                     REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
8476                 }
8477             }
8478           else if (MEM_P (loc[n_var_parts])
8479                    && GET_CODE (XEXP (loc2, 0)) == PLUS
8480                    && REG_P (XEXP (XEXP (loc2, 0), 0))
8481                    && CONST_INT_P (XEXP (XEXP (loc2, 0), 1)))
8482             {
8483               if ((REG_P (XEXP (loc[n_var_parts], 0))
8484                    && rtx_equal_p (XEXP (loc[n_var_parts], 0),
8485                                    XEXP (XEXP (loc2, 0), 0))
8486                    && INTVAL (XEXP (XEXP (loc2, 0), 1))
8487                       == GET_MODE_SIZE (mode))
8488                   || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
8489                       && CONST_INT_P (XEXP (XEXP (loc[n_var_parts], 0), 1))
8490                       && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
8491                                       XEXP (XEXP (loc2, 0), 0))
8492                       && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
8493                          + GET_MODE_SIZE (mode)
8494                          == INTVAL (XEXP (XEXP (loc2, 0), 1))))
8495                 new_loc = adjust_address_nv (loc[n_var_parts],
8496                                              wider_mode, 0);
8497             }
8498
8499           if (new_loc)
8500             {
8501               loc[n_var_parts] = new_loc;
8502               mode = wider_mode;
8503               last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
8504               i = j;
8505             }
8506         }
8507       ++n_var_parts;
8508     }
8509   type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8510   if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
8511     complete = false;
8512
8513   if (! flag_var_tracking_uninit)
8514     initialized = VAR_INIT_STATUS_INITIALIZED;
8515
8516   note_vl = NULL_RTX;
8517   if (!complete)
8518     note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, NULL_RTX,
8519                                     (int) initialized);
8520   else if (n_var_parts == 1)
8521     {
8522       rtx expr_list;
8523
8524       if (offsets[0] || GET_CODE (loc[0]) == PARALLEL)
8525         expr_list = gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
8526       else
8527         expr_list = loc[0];
8528
8529       note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, expr_list,
8530                                       (int) initialized);
8531     }
8532   else if (n_var_parts)
8533     {
8534       rtx parallel;
8535
8536       for (i = 0; i < n_var_parts; i++)
8537         loc[i]
8538           = gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));
8539
8540       parallel = gen_rtx_PARALLEL (VOIDmode,
8541                                    gen_rtvec_v (n_var_parts, loc));
8542       note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl,
8543                                       parallel, (int) initialized);
8544     }
8545
8546   if (where != EMIT_NOTE_BEFORE_INSN)
8547     {
8548       note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
8549       if (where == EMIT_NOTE_AFTER_CALL_INSN)
8550         NOTE_DURING_CALL_P (note) = true;
8551     }
8552   else
8553     {
8554       /* Make sure that the call related notes come first.  */
8555       while (NEXT_INSN (insn)
8556              && NOTE_P (insn)
8557              && ((NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
8558                   && NOTE_DURING_CALL_P (insn))
8559                  || NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
8560         insn = NEXT_INSN (insn);
8561       if (NOTE_P (insn)
8562           && ((NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
8563                && NOTE_DURING_CALL_P (insn))
8564               || NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
8565         note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
8566       else
8567         note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
8568     }
8569   NOTE_VAR_LOCATION (note) = note_vl;
8570
8571   set_dv_changed (var->dv, false);
8572   gcc_assert (var->in_changed_variables);
8573   var->in_changed_variables = false;
8574   htab_clear_slot (changed_variables, varp);
8575
8576   /* Continue traversing the hash table.  */
8577   return 1;
8578 }
8579
8580 /* While traversing changed_variables, push onto DATA (a stack of RTX
8581    values) entries that aren't user variables.  */
8582
8583 static int
8584 values_to_stack (void **slot, void *data)
8585 {
8586   VEC (rtx, stack) **changed_values_stack = (VEC (rtx, stack) **)data;
8587   variable var = (variable) *slot;
8588
8589   if (var->onepart == ONEPART_VALUE)
8590     VEC_safe_push (rtx, stack, *changed_values_stack, dv_as_value (var->dv));
8591   else if (var->onepart == ONEPART_DEXPR)
8592     VEC_safe_push (rtx, stack, *changed_values_stack,
8593                    DECL_RTL_KNOWN_SET (dv_as_decl (var->dv)));
8594
8595   return 1;
8596 }
8597
8598 /* Remove from changed_variables the entry whose DV corresponds to
8599    value or debug_expr VAL.  */
8600 static void
8601 remove_value_from_changed_variables (rtx val)
8602 {
8603   decl_or_value dv = dv_from_rtx (val);
8604   void **slot;
8605   variable var;
8606
8607   slot = htab_find_slot_with_hash (changed_variables,
8608                                    dv, dv_htab_hash (dv), NO_INSERT);
8609   var = (variable) *slot;
8610   var->in_changed_variables = false;
8611   htab_clear_slot (changed_variables, slot);
8612 }
8613
8614 /* If VAL (a value or debug_expr) has backlinks to variables actively
8615    dependent on it in HTAB or in CHANGED_VARIABLES, mark them as
8616    changed, adding to CHANGED_VALUES_STACK any dependencies that may
8617    have dependencies of their own to notify.  */
8618
8619 static void
8620 notify_dependents_of_changed_value (rtx val, htab_t htab,
8621                                     VEC (rtx, stack) **changed_values_stack)
8622 {
8623   void **slot;
8624   variable var;
8625   loc_exp_dep *led;
8626   decl_or_value dv = dv_from_rtx (val);
8627
8628   slot = htab_find_slot_with_hash (changed_variables,
8629                                    dv, dv_htab_hash (dv), NO_INSERT);
8630   if (!slot)
8631     slot = htab_find_slot_with_hash (htab,
8632                                      dv, dv_htab_hash (dv), NO_INSERT);
8633   if (!slot)
8634     slot = htab_find_slot_with_hash (dropped_values,
8635                                      dv, dv_htab_hash (dv), NO_INSERT);
8636   var = (variable) *slot;
8637
8638   while ((led = VAR_LOC_DEP_LST (var)))
8639     {
8640       decl_or_value ldv = led->dv;
8641       variable ivar;
8642
8643       /* Deactivate and remove the backlink, as it was “used up”.  It
8644          makes no sense to attempt to notify the same entity again:
8645          either it will be recomputed and re-register an active
8646          dependency, or it will still have the changed mark.  */
8647       if (led->next)
8648         led->next->pprev = led->pprev;
8649       if (led->pprev)
8650         *led->pprev = led->next;
8651       led->next = NULL;
8652       led->pprev = NULL;
8653
8654       if (dv_changed_p (ldv))
8655         continue;
8656
8657       switch (dv_onepart_p (ldv))
8658         {
8659         case ONEPART_VALUE:
8660         case ONEPART_DEXPR:
8661           set_dv_changed (ldv, true);
8662           VEC_safe_push (rtx, stack, *changed_values_stack, dv_as_rtx (ldv));
8663           break;
8664
8665         case ONEPART_VDECL:
8666           ivar = (variable) htab_find_with_hash (htab, ldv, dv_htab_hash (ldv));
8667           gcc_checking_assert (!VAR_LOC_DEP_LST (ivar));
8668           variable_was_changed (ivar, NULL);
8669           break;
8670
8671         case NOT_ONEPART:
8672           pool_free (loc_exp_dep_pool, led);
8673           ivar = (variable) htab_find_with_hash (htab, ldv, dv_htab_hash (ldv));
8674           if (ivar)
8675             {
8676               int i = ivar->n_var_parts;
8677               while (i--)
8678                 {
8679                   rtx loc = ivar->var_part[i].cur_loc;
8680
8681                   if (loc && GET_CODE (loc) == MEM
8682                       && XEXP (loc, 0) == val)
8683                     {
8684                       variable_was_changed (ivar, NULL);
8685                       break;
8686                     }
8687                 }
8688             }
8689           break;
8690
8691         default:
8692           gcc_unreachable ();
8693         }
8694     }
8695 }
8696
8697 /* Take out of changed_variables any entries that don't refer to use
8698    variables.  Back-propagate change notifications from values and
8699    debug_exprs to their active dependencies in HTAB or in
8700    CHANGED_VARIABLES.  */
8701
8702 static void
8703 process_changed_values (htab_t htab)
8704 {
8705   int i, n;
8706   rtx val;
8707   VEC (rtx, stack) *changed_values_stack = VEC_alloc (rtx, stack, 20);
8708
8709   /* Move values from changed_variables to changed_values_stack.  */
8710   htab_traverse (changed_variables, values_to_stack, &changed_values_stack);
8711
8712   /* Back-propagate change notifications in values while popping
8713      them from the stack.  */
8714   for (n = i = VEC_length (rtx, changed_values_stack);
8715        i > 0; i = VEC_length (rtx, changed_values_stack))
8716     {
8717       val = VEC_pop (rtx, changed_values_stack);
8718       notify_dependents_of_changed_value (val, htab, &changed_values_stack);
8719
8720       /* This condition will hold when visiting each of the entries
8721          originally in changed_variables.  We can't remove them
8722          earlier because this could drop the backlinks before we got a
8723          chance to use them.  */
8724       if (i == n)
8725         {
8726           remove_value_from_changed_variables (val);
8727           n--;
8728         }
8729     }
8730
8731   VEC_free (rtx, stack, changed_values_stack);
8732 }
8733
8734 /* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
8735    CHANGED_VARIABLES and delete this chain.  WHERE specifies whether
8736    the notes shall be emitted before of after instruction INSN.  */
8737
8738 static void
8739 emit_notes_for_changes (rtx insn, enum emit_note_where where,
8740                         shared_hash vars)
8741 {
8742   emit_note_data data;
8743   htab_t htab = shared_hash_htab (vars);
8744
8745   if (!htab_elements (changed_variables))
8746     return;
8747
8748   if (MAY_HAVE_DEBUG_INSNS)
8749     process_changed_values (htab);
8750
8751   data.insn = insn;
8752   data.where = where;
8753   data.vars = htab;
8754
8755   htab_traverse (changed_variables, emit_note_insn_var_location, &data);
8756 }
8757
8758 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
8759    same variable in hash table DATA or is not there at all.  */
8760
8761 static int
8762 emit_notes_for_differences_1 (void **slot, void *data)
8763 {
8764   htab_t new_vars = (htab_t) data;
8765   variable old_var, new_var;
8766
8767   old_var = (variable) *slot;
8768   new_var = (variable) htab_find_with_hash (new_vars, old_var->dv,
8769                                             dv_htab_hash (old_var->dv));
8770
8771   if (!new_var)
8772     {
8773       /* Variable has disappeared.  */
8774       variable empty_var = NULL;
8775
8776       if (old_var->onepart == ONEPART_VALUE
8777           || old_var->onepart == ONEPART_DEXPR)
8778         {
8779           empty_var = variable_from_dropped (old_var->dv, NO_INSERT);
8780           if (empty_var)
8781             {
8782               gcc_checking_assert (!empty_var->in_changed_variables);
8783               if (!VAR_LOC_1PAUX (old_var))
8784                 {
8785                   VAR_LOC_1PAUX (old_var) = VAR_LOC_1PAUX (empty_var);
8786                   VAR_LOC_1PAUX (empty_var) = NULL;
8787                 }
8788               else
8789                 gcc_checking_assert (!VAR_LOC_1PAUX (empty_var));
8790             }
8791         }
8792
8793       if (!empty_var)
8794         {
8795           empty_var = (variable) pool_alloc (onepart_pool (old_var->onepart));
8796           empty_var->dv = old_var->dv;
8797           empty_var->refcount = 0;
8798           empty_var->n_var_parts = 0;
8799           empty_var->onepart = old_var->onepart;
8800           empty_var->in_changed_variables = false;
8801         }
8802
8803       if (empty_var->onepart)
8804         {
8805           /* Propagate the auxiliary data to (ultimately)
8806              changed_variables.  */
8807           empty_var->var_part[0].loc_chain = NULL;
8808           empty_var->var_part[0].cur_loc = NULL;
8809           VAR_LOC_1PAUX (empty_var) = VAR_LOC_1PAUX (old_var);
8810           VAR_LOC_1PAUX (old_var) = NULL;
8811         }
8812       variable_was_changed (empty_var, NULL);
8813       /* Continue traversing the hash table.  */
8814       return 1;
8815     }
8816   /* Update cur_loc and one-part auxiliary data, before new_var goes
8817      through variable_was_changed.  */
8818   if (old_var != new_var && new_var->onepart)
8819     {
8820       gcc_checking_assert (VAR_LOC_1PAUX (new_var) == NULL);
8821       VAR_LOC_1PAUX (new_var) = VAR_LOC_1PAUX (old_var);
8822       VAR_LOC_1PAUX (old_var) = NULL;
8823       new_var->var_part[0].cur_loc = old_var->var_part[0].cur_loc;
8824     }
8825   if (variable_different_p (old_var, new_var))
8826     variable_was_changed (new_var, NULL);
8827
8828   /* Continue traversing the hash table.  */
8829   return 1;
8830 }
8831
8832 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
8833    table DATA.  */
8834
8835 static int
8836 emit_notes_for_differences_2 (void **slot, void *data)
8837 {
8838   htab_t old_vars = (htab_t) data;
8839   variable old_var, new_var;
8840
8841   new_var = (variable) *slot;
8842   old_var = (variable) htab_find_with_hash (old_vars, new_var->dv,
8843                                             dv_htab_hash (new_var->dv));
8844   if (!old_var)
8845     {
8846       int i;
8847       for (i = 0; i < new_var->n_var_parts; i++)
8848         new_var->var_part[i].cur_loc = NULL;
8849       variable_was_changed (new_var, NULL);
8850     }
8851
8852   /* Continue traversing the hash table.  */
8853   return 1;
8854 }
8855
8856 /* Emit notes before INSN for differences between dataflow sets OLD_SET and
8857    NEW_SET.  */
8858
8859 static void
8860 emit_notes_for_differences (rtx insn, dataflow_set *old_set,
8861                             dataflow_set *new_set)
8862 {
8863   htab_traverse (shared_hash_htab (old_set->vars),
8864                  emit_notes_for_differences_1,
8865                  shared_hash_htab (new_set->vars));
8866   htab_traverse (shared_hash_htab (new_set->vars),
8867                  emit_notes_for_differences_2,
8868                  shared_hash_htab (old_set->vars));
8869   emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, new_set->vars);
8870 }
8871
8872 /* Return the next insn after INSN that is not a NOTE_INSN_VAR_LOCATION.  */
8873
8874 static rtx
8875 next_non_note_insn_var_location (rtx insn)
8876 {
8877   while (insn)
8878     {
8879       insn = NEXT_INSN (insn);
8880       if (insn == 0
8881           || !NOTE_P (insn)
8882           || NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION)
8883         break;
8884     }
8885
8886   return insn;
8887 }
8888
8889 /* Emit the notes for changes of location parts in the basic block BB.  */
8890
8891 static void
8892 emit_notes_in_bb (basic_block bb, dataflow_set *set)
8893 {
8894   unsigned int i;
8895   micro_operation *mo;
8896
8897   dataflow_set_clear (set);
8898   dataflow_set_copy (set, &VTI (bb)->in);
8899
8900   FOR_EACH_VEC_ELT (micro_operation, VTI (bb)->mos, i, mo)
8901     {
8902       rtx insn = mo->insn;
8903       rtx next_insn = next_non_note_insn_var_location (insn);
8904
8905       switch (mo->type)
8906         {
8907           case MO_CALL:
8908             dataflow_set_clear_at_call (set);
8909             emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars);
8910             {
8911               rtx arguments = mo->u.loc, *p = &arguments, note;
8912               while (*p)
8913                 {
8914                   XEXP (XEXP (*p, 0), 1)
8915                     = vt_expand_loc (XEXP (XEXP (*p, 0), 1),
8916                                      shared_hash_htab (set->vars));
8917                   /* If expansion is successful, keep it in the list.  */
8918                   if (XEXP (XEXP (*p, 0), 1))
8919                     p = &XEXP (*p, 1);
8920                   /* Otherwise, if the following item is data_value for it,
8921                      drop it too too.  */
8922                   else if (XEXP (*p, 1)
8923                            && REG_P (XEXP (XEXP (*p, 0), 0))
8924                            && MEM_P (XEXP (XEXP (XEXP (*p, 1), 0), 0))
8925                            && REG_P (XEXP (XEXP (XEXP (XEXP (*p, 1), 0), 0),
8926                                            0))
8927                            && REGNO (XEXP (XEXP (*p, 0), 0))
8928                               == REGNO (XEXP (XEXP (XEXP (XEXP (*p, 1), 0),
8929                                                     0), 0)))
8930                     *p = XEXP (XEXP (*p, 1), 1);
8931                   /* Just drop this item.  */
8932                   else
8933                     *p = XEXP (*p, 1);
8934                 }
8935               note = emit_note_after (NOTE_INSN_CALL_ARG_LOCATION, insn);
8936               NOTE_VAR_LOCATION (note) = arguments;
8937             }
8938             break;
8939
8940           case MO_USE:
8941             {
8942               rtx loc = mo->u.loc;
8943
8944               if (REG_P (loc))
8945                 var_reg_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
8946               else
8947                 var_mem_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
8948
8949               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
8950             }
8951             break;
8952
8953           case MO_VAL_LOC:
8954             {
8955               rtx loc = mo->u.loc;
8956               rtx val, vloc;
8957               tree var;
8958
8959               if (GET_CODE (loc) == CONCAT)
8960                 {
8961                   val = XEXP (loc, 0);
8962                   vloc = XEXP (loc, 1);
8963                 }
8964               else
8965                 {
8966                   val = NULL_RTX;
8967                   vloc = loc;
8968                 }
8969
8970               var = PAT_VAR_LOCATION_DECL (vloc);
8971
8972               clobber_variable_part (set, NULL_RTX,
8973                                      dv_from_decl (var), 0, NULL_RTX);
8974               if (val)
8975                 {
8976                   if (VAL_NEEDS_RESOLUTION (loc))
8977                     val_resolve (set, val, PAT_VAR_LOCATION_LOC (vloc), insn);
8978                   set_variable_part (set, val, dv_from_decl (var), 0,
8979                                      VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
8980                                      INSERT);
8981                 }
8982               else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
8983                 set_variable_part (set, PAT_VAR_LOCATION_LOC (vloc),
8984                                    dv_from_decl (var), 0,
8985                                    VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
8986                                    INSERT);
8987
8988               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
8989             }
8990             break;
8991
8992           case MO_VAL_USE:
8993             {
8994               rtx loc = mo->u.loc;
8995               rtx val, vloc, uloc;
8996
8997               vloc = uloc = XEXP (loc, 1);
8998               val = XEXP (loc, 0);
8999
9000               if (GET_CODE (val) == CONCAT)
9001                 {
9002                   uloc = XEXP (val, 1);
9003                   val = XEXP (val, 0);
9004                 }
9005
9006               if (VAL_NEEDS_RESOLUTION (loc))
9007                 val_resolve (set, val, vloc, insn);
9008               else
9009                 val_store (set, val, uloc, insn, false);
9010
9011               if (VAL_HOLDS_TRACK_EXPR (loc))
9012                 {
9013                   if (GET_CODE (uloc) == REG)
9014                     var_reg_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
9015                                  NULL);
9016                   else if (GET_CODE (uloc) == MEM)
9017                     var_mem_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
9018                                  NULL);
9019                 }
9020
9021               emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
9022             }
9023             break;
9024
9025           case MO_VAL_SET:
9026             {
9027               rtx loc = mo->u.loc;
9028               rtx val, vloc, uloc;
9029               rtx dstv, srcv;
9030
9031               vloc = loc;
9032               uloc = XEXP (vloc, 1);
9033               val = XEXP (vloc, 0);
9034               vloc = uloc;
9035
9036               if (GET_CODE (uloc) == SET)
9037                 {
9038                   dstv = SET_DEST (uloc);
9039                   srcv = SET_SRC (uloc);
9040                 }
9041               else
9042                 {
9043                   dstv = uloc;
9044                   srcv = NULL;
9045                 }
9046
9047               if (GET_CODE (val) == CONCAT)
9048                 {
9049                   dstv = vloc = XEXP (val, 1);
9050                   val = XEXP (val, 0);
9051                 }
9052
9053               if (GET_CODE (vloc) == SET)
9054                 {
9055                   srcv = SET_SRC (vloc);
9056
9057                   gcc_assert (val != srcv);
9058                   gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
9059
9060                   dstv = vloc = SET_DEST (vloc);
9061
9062                   if (VAL_NEEDS_RESOLUTION (loc))
9063                     val_resolve (set, val, srcv, insn);
9064                 }
9065               else if (VAL_NEEDS_RESOLUTION (loc))
9066                 {
9067                   gcc_assert (GET_CODE (uloc) == SET
9068                               && GET_CODE (SET_SRC (uloc)) == REG);
9069                   val_resolve (set, val, SET_SRC (uloc), insn);
9070                 }
9071
9072               if (VAL_HOLDS_TRACK_EXPR (loc))
9073                 {
9074                   if (VAL_EXPR_IS_CLOBBERED (loc))
9075                     {
9076                       if (REG_P (uloc))
9077                         var_reg_delete (set, uloc, true);
9078                       else if (MEM_P (uloc))
9079                         {
9080                           gcc_assert (MEM_P (dstv));
9081                           gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (uloc));
9082                           var_mem_delete (set, dstv, true);
9083                         }
9084                     }
9085                   else
9086                     {
9087                       bool copied_p = VAL_EXPR_IS_COPIED (loc);
9088                       rtx src = NULL, dst = uloc;
9089                       enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
9090
9091                       if (GET_CODE (uloc) == SET)
9092                         {
9093                           src = SET_SRC (uloc);
9094                           dst = SET_DEST (uloc);
9095                         }
9096
9097                       if (copied_p)
9098                         {
9099                           status = find_src_status (set, src);
9100
9101                           src = find_src_set_src (set, src);
9102                         }
9103
9104                       if (REG_P (dst))
9105                         var_reg_delete_and_set (set, dst, !copied_p,
9106                                                 status, srcv);
9107                       else if (MEM_P (dst))
9108                         {
9109                           gcc_assert (MEM_P (dstv));
9110                           gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (dst));
9111                           var_mem_delete_and_set (set, dstv, !copied_p,
9112                                                   status, srcv);
9113                         }
9114                     }
9115                 }
9116               else if (REG_P (uloc))
9117                 var_regno_delete (set, REGNO (uloc));
9118               else if (MEM_P (uloc))
9119                 clobber_overlapping_mems (set, uloc);
9120
9121               val_store (set, val, dstv, insn, true);
9122
9123               emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
9124                                       set->vars);
9125             }
9126             break;
9127
9128           case MO_SET:
9129             {
9130               rtx loc = mo->u.loc;
9131               rtx set_src = NULL;
9132
9133               if (GET_CODE (loc) == SET)
9134                 {
9135                   set_src = SET_SRC (loc);
9136                   loc = SET_DEST (loc);
9137                 }
9138
9139               if (REG_P (loc))
9140                 var_reg_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
9141                                         set_src);
9142               else
9143                 var_mem_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
9144                                         set_src);
9145
9146               emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
9147                                       set->vars);
9148             }
9149             break;
9150
9151           case MO_COPY:
9152             {
9153               rtx loc = mo->u.loc;
9154               enum var_init_status src_status;
9155               rtx set_src = NULL;
9156
9157               if (GET_CODE (loc) == SET)
9158                 {
9159                   set_src = SET_SRC (loc);
9160                   loc = SET_DEST (loc);
9161                 }
9162
9163               src_status = find_src_status (set, set_src);
9164               set_src = find_src_set_src (set, set_src);
9165
9166               if (REG_P (loc))
9167                 var_reg_delete_and_set (set, loc, false, src_status, set_src);
9168               else
9169                 var_mem_delete_and_set (set, loc, false, src_status, set_src);
9170
9171               emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
9172                                       set->vars);
9173             }
9174             break;
9175
9176           case MO_USE_NO_VAR:
9177             {
9178               rtx loc = mo->u.loc;
9179
9180               if (REG_P (loc))
9181                 var_reg_delete (set, loc, false);
9182               else
9183                 var_mem_delete (set, loc, false);
9184
9185               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
9186             }
9187             break;
9188
9189           case MO_CLOBBER:
9190             {
9191               rtx loc = mo->u.loc;
9192
9193               if (REG_P (loc))
9194                 var_reg_delete (set, loc, true);
9195               else
9196                 var_mem_delete (set, loc, true);
9197
9198               emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
9199                                       set->vars);
9200             }
9201             break;
9202
9203           case MO_ADJUST:
9204             set->stack_adjust += mo->u.adjust;
9205             break;
9206         }
9207     }
9208 }
9209
9210 /* Emit notes for the whole function.  */
9211
9212 static void
9213 vt_emit_notes (void)
9214 {
9215   basic_block bb;
9216   dataflow_set cur;
9217
9218   gcc_assert (!htab_elements (changed_variables));
9219
9220   /* Free memory occupied by the out hash tables, as they aren't used
9221      anymore.  */
9222   FOR_EACH_BB (bb)
9223     dataflow_set_clear (&VTI (bb)->out);
9224
9225   /* Enable emitting notes by functions (mainly by set_variable_part and
9226      delete_variable_part).  */
9227   emit_notes = true;
9228
9229   if (MAY_HAVE_DEBUG_INSNS)
9230     {
9231       dropped_values = htab_create (cselib_get_next_uid () * 2,
9232                                     variable_htab_hash, variable_htab_eq,
9233                                     variable_htab_free);
9234       loc_exp_dep_pool = create_alloc_pool ("loc_exp_dep pool",
9235                                             sizeof (loc_exp_dep), 64);
9236     }
9237
9238   dataflow_set_init (&cur);
9239
9240   FOR_EACH_BB (bb)
9241     {
9242       /* Emit the notes for changes of variable locations between two
9243          subsequent basic blocks.  */
9244       emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
9245
9246       /* Emit the notes for the changes in the basic block itself.  */
9247       emit_notes_in_bb (bb, &cur);
9248
9249       /* Free memory occupied by the in hash table, we won't need it
9250          again.  */
9251       dataflow_set_clear (&VTI (bb)->in);
9252     }
9253 #ifdef ENABLE_CHECKING
9254   htab_traverse (shared_hash_htab (cur.vars),
9255                  emit_notes_for_differences_1,
9256                  shared_hash_htab (empty_shared_hash));
9257 #endif
9258   dataflow_set_destroy (&cur);
9259
9260   if (MAY_HAVE_DEBUG_INSNS)
9261     htab_delete (dropped_values);
9262
9263   emit_notes = false;
9264 }
9265
9266 /* If there is a declaration and offset associated with register/memory RTL
9267    assign declaration to *DECLP and offset to *OFFSETP, and return true.  */
9268
9269 static bool
9270 vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
9271 {
9272   if (REG_P (rtl))
9273     {
9274       if (REG_ATTRS (rtl))
9275         {
9276           *declp = REG_EXPR (rtl);
9277           *offsetp = REG_OFFSET (rtl);
9278           return true;
9279         }
9280     }
9281   else if (MEM_P (rtl))
9282     {
9283       if (MEM_ATTRS (rtl))
9284         {
9285           *declp = MEM_EXPR (rtl);
9286           *offsetp = INT_MEM_OFFSET (rtl);
9287           return true;
9288         }
9289     }
9290   return false;
9291 }
9292
9293 /* Record the value for the ENTRY_VALUE of RTL as a global equivalence
9294    of VAL.  */
9295
9296 static void
9297 record_entry_value (cselib_val *val, rtx rtl)
9298 {
9299   rtx ev = gen_rtx_ENTRY_VALUE (GET_MODE (rtl));
9300
9301   ENTRY_VALUE_EXP (ev) = rtl;
9302
9303   cselib_add_permanent_equiv (val, ev, get_insns ());
9304 }
9305
9306 /* Insert function parameter PARM in IN and OUT sets of ENTRY_BLOCK.  */
9307
9308 static void
9309 vt_add_function_parameter (tree parm)
9310 {
9311   rtx decl_rtl = DECL_RTL_IF_SET (parm);
9312   rtx incoming = DECL_INCOMING_RTL (parm);
9313   tree decl;
9314   enum machine_mode mode;
9315   HOST_WIDE_INT offset;
9316   dataflow_set *out;
9317   decl_or_value dv;
9318
9319   if (TREE_CODE (parm) != PARM_DECL)
9320     return;
9321
9322   if (!decl_rtl || !incoming)
9323     return;
9324
9325   if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
9326     return;
9327
9328   /* If there is a DRAP register or a pseudo in internal_arg_pointer,
9329      rewrite the incoming location of parameters passed on the stack
9330      into MEMs based on the argument pointer, so that incoming doesn't
9331      depend on a pseudo.  */
9332   if (MEM_P (incoming)
9333       && (XEXP (incoming, 0) == crtl->args.internal_arg_pointer
9334           || (GET_CODE (XEXP (incoming, 0)) == PLUS
9335               && XEXP (XEXP (incoming, 0), 0)
9336                  == crtl->args.internal_arg_pointer
9337               && CONST_INT_P (XEXP (XEXP (incoming, 0), 1)))))
9338     {
9339       HOST_WIDE_INT off = -FIRST_PARM_OFFSET (current_function_decl);
9340       if (GET_CODE (XEXP (incoming, 0)) == PLUS)
9341         off += INTVAL (XEXP (XEXP (incoming, 0), 1));
9342       incoming
9343         = replace_equiv_address_nv (incoming,
9344                                     plus_constant (Pmode,
9345                                                    arg_pointer_rtx, off));
9346     }
9347
9348 #ifdef HAVE_window_save
9349   /* DECL_INCOMING_RTL uses the INCOMING_REGNO of parameter registers.
9350      If the target machine has an explicit window save instruction, the
9351      actual entry value is the corresponding OUTGOING_REGNO instead.  */
9352   if (REG_P (incoming)
9353       && HARD_REGISTER_P (incoming)
9354       && OUTGOING_REGNO (REGNO (incoming)) != REGNO (incoming))
9355     {
9356       parm_reg_t p;
9357       p.incoming = incoming;
9358       incoming
9359         = gen_rtx_REG_offset (incoming, GET_MODE (incoming),
9360                               OUTGOING_REGNO (REGNO (incoming)), 0);
9361       p.outgoing = incoming;
9362       VEC_safe_push (parm_reg_t, gc, windowed_parm_regs, p);
9363     }
9364   else if (MEM_P (incoming)
9365            && REG_P (XEXP (incoming, 0))
9366            && HARD_REGISTER_P (XEXP (incoming, 0)))
9367     {
9368       rtx reg = XEXP (incoming, 0);
9369       if (OUTGOING_REGNO (REGNO (reg)) != REGNO (reg))
9370         {
9371           parm_reg_t p;
9372           p.incoming = reg;
9373           reg = gen_raw_REG (GET_MODE (reg), OUTGOING_REGNO (REGNO (reg)));
9374           p.outgoing = reg;
9375           VEC_safe_push (parm_reg_t, gc, windowed_parm_regs, p);
9376           incoming = replace_equiv_address_nv (incoming, reg);
9377         }
9378     }
9379 #endif
9380
9381   if (!vt_get_decl_and_offset (incoming, &decl, &offset))
9382     {
9383       if (REG_P (incoming) || MEM_P (incoming))
9384         {
9385           /* This means argument is passed by invisible reference.  */
9386           offset = 0;
9387           decl = parm;
9388           incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
9389         }
9390       else
9391         {
9392           if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
9393             return;
9394           offset += byte_lowpart_offset (GET_MODE (incoming),
9395                                          GET_MODE (decl_rtl));
9396         }
9397     }
9398
9399   if (!decl)
9400     return;
9401
9402   if (parm != decl)
9403     {
9404       /* If that DECL_RTL wasn't a pseudo that got spilled to
9405          memory, bail out.  Otherwise, the spill slot sharing code
9406          will force the memory to reference spill_slot_decl (%sfp),
9407          so we don't match above.  That's ok, the pseudo must have
9408          referenced the entire parameter, so just reset OFFSET.  */
9409       if (decl != get_spill_slot_decl (false))
9410         return;
9411       offset = 0;
9412     }
9413
9414   if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
9415     return;
9416
9417   out = &VTI (ENTRY_BLOCK_PTR)->out;
9418
9419   dv = dv_from_decl (parm);
9420
9421   if (target_for_debug_bind (parm)
9422       /* We can't deal with these right now, because this kind of
9423          variable is single-part.  ??? We could handle parallels
9424          that describe multiple locations for the same single
9425          value, but ATM we don't.  */
9426       && GET_CODE (incoming) != PARALLEL)
9427     {
9428       cselib_val *val;
9429       rtx lowpart;
9430
9431       /* ??? We shouldn't ever hit this, but it may happen because
9432          arguments passed by invisible reference aren't dealt with
9433          above: incoming-rtl will have Pmode rather than the
9434          expected mode for the type.  */
9435       if (offset)
9436         return;
9437
9438       lowpart = var_lowpart (mode, incoming);
9439       if (!lowpart)
9440         return;
9441
9442       val = cselib_lookup_from_insn (lowpart, mode, true,
9443                                      VOIDmode, get_insns ());
9444
9445       /* ??? Float-typed values in memory are not handled by
9446          cselib.  */
9447       if (val)
9448         {
9449           preserve_value (val);
9450           set_variable_part (out, val->val_rtx, dv, offset,
9451                              VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9452           dv = dv_from_value (val->val_rtx);
9453         }
9454
9455       if (MEM_P (incoming))
9456         {
9457           val = cselib_lookup_from_insn (XEXP (incoming, 0), mode, true,
9458                                          VOIDmode, get_insns ());
9459           if (val)
9460             {
9461               preserve_value (val);
9462               incoming = replace_equiv_address_nv (incoming, val->val_rtx);
9463             }
9464         }
9465     }
9466
9467   if (REG_P (incoming))
9468     {
9469       incoming = var_lowpart (mode, incoming);
9470       gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
9471       attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
9472                          incoming);
9473       set_variable_part (out, incoming, dv, offset,
9474                          VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9475       if (dv_is_value_p (dv))
9476         {
9477           record_entry_value (CSELIB_VAL_PTR (dv_as_value (dv)), incoming);
9478           if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE
9479               && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (parm))))
9480             {
9481               enum machine_mode indmode
9482                 = TYPE_MODE (TREE_TYPE (TREE_TYPE (parm)));
9483               rtx mem = gen_rtx_MEM (indmode, incoming);
9484               cselib_val *val = cselib_lookup_from_insn (mem, indmode, true,
9485                                                          VOIDmode,
9486                                                          get_insns ());
9487               if (val)
9488                 {
9489                   preserve_value (val);
9490                   record_entry_value (val, mem);
9491                   set_variable_part (out, mem, dv_from_value (val->val_rtx), 0,
9492                                      VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9493                 }
9494             }
9495         }
9496     }
9497   else if (MEM_P (incoming))
9498     {
9499       incoming = var_lowpart (mode, incoming);
9500       set_variable_part (out, incoming, dv, offset,
9501                          VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9502     }
9503 }
9504
9505 /* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */
9506
9507 static void
9508 vt_add_function_parameters (void)
9509 {
9510   tree parm;
9511
9512   for (parm = DECL_ARGUMENTS (current_function_decl);
9513        parm; parm = DECL_CHAIN (parm))
9514     vt_add_function_parameter (parm);
9515
9516   if (DECL_HAS_VALUE_EXPR_P (DECL_RESULT (current_function_decl)))
9517     {
9518       tree vexpr = DECL_VALUE_EXPR (DECL_RESULT (current_function_decl));
9519
9520       if (TREE_CODE (vexpr) == INDIRECT_REF)
9521         vexpr = TREE_OPERAND (vexpr, 0);
9522
9523       if (TREE_CODE (vexpr) == PARM_DECL
9524           && DECL_ARTIFICIAL (vexpr)
9525           && !DECL_IGNORED_P (vexpr)
9526           && DECL_NAMELESS (vexpr))
9527         vt_add_function_parameter (vexpr);
9528     }
9529 }
9530
9531 /* Return true if INSN in the prologue initializes hard_frame_pointer_rtx.  */
9532
9533 static bool
9534 fp_setter (rtx insn)
9535 {
9536   rtx pat = PATTERN (insn);
9537   if (RTX_FRAME_RELATED_P (insn))
9538     {
9539       rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
9540       if (expr)
9541         pat = XEXP (expr, 0);
9542     }
9543   if (GET_CODE (pat) == SET)
9544     return SET_DEST (pat) == hard_frame_pointer_rtx;
9545   else if (GET_CODE (pat) == PARALLEL)
9546     {
9547       int i;
9548       for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
9549         if (GET_CODE (XVECEXP (pat, 0, i)) == SET
9550             && SET_DEST (XVECEXP (pat, 0, i)) == hard_frame_pointer_rtx)
9551           return true;
9552     }
9553   return false;
9554 }
9555
9556 /* Initialize cfa_base_rtx, create a preserved VALUE for it and
9557    ensure it isn't flushed during cselib_reset_table.
9558    Can be called only if frame_pointer_rtx resp. arg_pointer_rtx
9559    has been eliminated.  */
9560
9561 static void
9562 vt_init_cfa_base (void)
9563 {
9564   cselib_val *val;
9565
9566 #ifdef FRAME_POINTER_CFA_OFFSET
9567   cfa_base_rtx = frame_pointer_rtx;
9568   cfa_base_offset = -FRAME_POINTER_CFA_OFFSET (current_function_decl);
9569 #else
9570   cfa_base_rtx = arg_pointer_rtx;
9571   cfa_base_offset = -ARG_POINTER_CFA_OFFSET (current_function_decl);
9572 #endif
9573   if (cfa_base_rtx == hard_frame_pointer_rtx
9574       || !fixed_regs[REGNO (cfa_base_rtx)])
9575     {
9576       cfa_base_rtx = NULL_RTX;
9577       return;
9578     }
9579   if (!MAY_HAVE_DEBUG_INSNS)
9580     return;
9581
9582   /* Tell alias analysis that cfa_base_rtx should share
9583      find_base_term value with stack pointer or hard frame pointer.  */
9584   if (!frame_pointer_needed)
9585     vt_equate_reg_base_value (cfa_base_rtx, stack_pointer_rtx);
9586   else if (!crtl->stack_realign_tried)
9587     vt_equate_reg_base_value (cfa_base_rtx, hard_frame_pointer_rtx);
9588
9589   val = cselib_lookup_from_insn (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1,
9590                                  VOIDmode, get_insns ());
9591   preserve_value (val);
9592   cselib_preserve_cfa_base_value (val, REGNO (cfa_base_rtx));
9593 }
9594
9595 /* Allocate and initialize the data structures for variable tracking
9596    and parse the RTL to get the micro operations.  */
9597
9598 static bool
9599 vt_initialize (void)
9600 {
9601   basic_block bb, prologue_bb = single_succ (ENTRY_BLOCK_PTR);
9602   HOST_WIDE_INT fp_cfa_offset = -1;
9603
9604   alloc_aux_for_blocks (sizeof (struct variable_tracking_info_def));
9605
9606   attrs_pool = create_alloc_pool ("attrs_def pool",
9607                                   sizeof (struct attrs_def), 1024);
9608   var_pool = create_alloc_pool ("variable_def pool",
9609                                 sizeof (struct variable_def)
9610                                 + (MAX_VAR_PARTS - 1)
9611                                 * sizeof (((variable)NULL)->var_part[0]), 64);
9612   loc_chain_pool = create_alloc_pool ("location_chain_def pool",
9613                                       sizeof (struct location_chain_def),
9614                                       1024);
9615   shared_hash_pool = create_alloc_pool ("shared_hash_def pool",
9616                                         sizeof (struct shared_hash_def), 256);
9617   empty_shared_hash = (shared_hash) pool_alloc (shared_hash_pool);
9618   empty_shared_hash->refcount = 1;
9619   empty_shared_hash->htab
9620     = htab_create (1, variable_htab_hash, variable_htab_eq,
9621                    variable_htab_free);
9622   changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
9623                                    variable_htab_free);
9624
9625   /* Init the IN and OUT sets.  */
9626   FOR_ALL_BB (bb)
9627     {
9628       VTI (bb)->visited = false;
9629       VTI (bb)->flooded = false;
9630       dataflow_set_init (&VTI (bb)->in);
9631       dataflow_set_init (&VTI (bb)->out);
9632       VTI (bb)->permp = NULL;
9633     }
9634
9635   if (MAY_HAVE_DEBUG_INSNS)
9636     {
9637       cselib_init (CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS);
9638       scratch_regs = BITMAP_ALLOC (NULL);
9639       valvar_pool = create_alloc_pool ("small variable_def pool",
9640                                        sizeof (struct variable_def), 256);
9641       preserved_values = VEC_alloc (rtx, heap, 256);
9642     }
9643   else
9644     {
9645       scratch_regs = NULL;
9646       valvar_pool = NULL;
9647     }
9648
9649   if (MAY_HAVE_DEBUG_INSNS)
9650     {
9651       rtx reg, expr;
9652       int ofst;
9653       cselib_val *val;
9654
9655 #ifdef FRAME_POINTER_CFA_OFFSET
9656       reg = frame_pointer_rtx;
9657       ofst = FRAME_POINTER_CFA_OFFSET (current_function_decl);
9658 #else
9659       reg = arg_pointer_rtx;
9660       ofst = ARG_POINTER_CFA_OFFSET (current_function_decl);
9661 #endif
9662
9663       ofst -= INCOMING_FRAME_SP_OFFSET;
9664
9665       val = cselib_lookup_from_insn (reg, GET_MODE (reg), 1,
9666                                      VOIDmode, get_insns ());
9667       preserve_value (val);
9668       cselib_preserve_cfa_base_value (val, REGNO (reg));
9669       expr = plus_constant (GET_MODE (stack_pointer_rtx),
9670                             stack_pointer_rtx, -ofst);
9671       cselib_add_permanent_equiv (val, expr, get_insns ());
9672
9673       if (ofst)
9674         {
9675           val = cselib_lookup_from_insn (stack_pointer_rtx,
9676                                          GET_MODE (stack_pointer_rtx), 1,
9677                                          VOIDmode, get_insns ());
9678           preserve_value (val);
9679           expr = plus_constant (GET_MODE (reg), reg, ofst);
9680           cselib_add_permanent_equiv (val, expr, get_insns ());
9681         }
9682     }
9683
9684   /* In order to factor out the adjustments made to the stack pointer or to
9685      the hard frame pointer and thus be able to use DW_OP_fbreg operations
9686      instead of individual location lists, we're going to rewrite MEMs based
9687      on them into MEMs based on the CFA by de-eliminating stack_pointer_rtx
9688      or hard_frame_pointer_rtx to the virtual CFA pointer frame_pointer_rtx
9689      resp. arg_pointer_rtx.  We can do this either when there is no frame
9690      pointer in the function and stack adjustments are consistent for all
9691      basic blocks or when there is a frame pointer and no stack realignment.
9692      But we first have to check that frame_pointer_rtx resp. arg_pointer_rtx
9693      has been eliminated.  */
9694   if (!frame_pointer_needed)
9695     {
9696       rtx reg, elim;
9697
9698       if (!vt_stack_adjustments ())
9699         return false;
9700
9701 #ifdef FRAME_POINTER_CFA_OFFSET
9702       reg = frame_pointer_rtx;
9703 #else
9704       reg = arg_pointer_rtx;
9705 #endif
9706       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
9707       if (elim != reg)
9708         {
9709           if (GET_CODE (elim) == PLUS)
9710             elim = XEXP (elim, 0);
9711           if (elim == stack_pointer_rtx)
9712             vt_init_cfa_base ();
9713         }
9714     }
9715   else if (!crtl->stack_realign_tried)
9716     {
9717       rtx reg, elim;
9718
9719 #ifdef FRAME_POINTER_CFA_OFFSET
9720       reg = frame_pointer_rtx;
9721       fp_cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
9722 #else
9723       reg = arg_pointer_rtx;
9724       fp_cfa_offset = ARG_POINTER_CFA_OFFSET (current_function_decl);
9725 #endif
9726       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
9727       if (elim != reg)
9728         {
9729           if (GET_CODE (elim) == PLUS)
9730             {
9731               fp_cfa_offset -= INTVAL (XEXP (elim, 1));
9732               elim = XEXP (elim, 0);
9733             }
9734           if (elim != hard_frame_pointer_rtx)
9735             fp_cfa_offset = -1;
9736         }
9737       else
9738         fp_cfa_offset = -1;
9739     }
9740
9741   /* If the stack is realigned and a DRAP register is used, we're going to
9742      rewrite MEMs based on it representing incoming locations of parameters
9743      passed on the stack into MEMs based on the argument pointer.  Although
9744      we aren't going to rewrite other MEMs, we still need to initialize the
9745      virtual CFA pointer in order to ensure that the argument pointer will
9746      be seen as a constant throughout the function.
9747
9748      ??? This doesn't work if FRAME_POINTER_CFA_OFFSET is defined.  */
9749   else if (stack_realign_drap)
9750     {
9751       rtx reg, elim;
9752
9753 #ifdef FRAME_POINTER_CFA_OFFSET
9754       reg = frame_pointer_rtx;
9755 #else
9756       reg = arg_pointer_rtx;
9757 #endif
9758       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
9759       if (elim != reg)
9760         {
9761           if (GET_CODE (elim) == PLUS)
9762             elim = XEXP (elim, 0);
9763           if (elim == hard_frame_pointer_rtx)
9764             vt_init_cfa_base ();
9765         }
9766     }
9767
9768   hard_frame_pointer_adjustment = -1;
9769
9770   vt_add_function_parameters ();
9771
9772   FOR_EACH_BB (bb)
9773     {
9774       rtx insn;
9775       HOST_WIDE_INT pre, post = 0;
9776       basic_block first_bb, last_bb;
9777
9778       if (MAY_HAVE_DEBUG_INSNS)
9779         {
9780           cselib_record_sets_hook = add_with_sets;
9781           if (dump_file && (dump_flags & TDF_DETAILS))
9782             fprintf (dump_file, "first value: %i\n",
9783                      cselib_get_next_uid ());
9784         }
9785
9786       first_bb = bb;
9787       for (;;)
9788         {
9789           edge e;
9790           if (bb->next_bb == EXIT_BLOCK_PTR
9791               || ! single_pred_p (bb->next_bb))
9792             break;
9793           e = find_edge (bb, bb->next_bb);
9794           if (! e || (e->flags & EDGE_FALLTHRU) == 0)
9795             break;
9796           bb = bb->next_bb;
9797         }
9798       last_bb = bb;
9799
9800       /* Add the micro-operations to the vector.  */
9801       FOR_BB_BETWEEN (bb, first_bb, last_bb->next_bb, next_bb)
9802         {
9803           HOST_WIDE_INT offset = VTI (bb)->out.stack_adjust;
9804           VTI (bb)->out.stack_adjust = VTI (bb)->in.stack_adjust;
9805           for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
9806                insn = NEXT_INSN (insn))
9807             {
9808               if (INSN_P (insn))
9809                 {
9810                   if (!frame_pointer_needed)
9811                     {
9812                       insn_stack_adjust_offset_pre_post (insn, &pre, &post);
9813                       if (pre)
9814                         {
9815                           micro_operation mo;
9816                           mo.type = MO_ADJUST;
9817                           mo.u.adjust = pre;
9818                           mo.insn = insn;
9819                           if (dump_file && (dump_flags & TDF_DETAILS))
9820                             log_op_type (PATTERN (insn), bb, insn,
9821                                          MO_ADJUST, dump_file);
9822                           VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
9823                                          mo);
9824                           VTI (bb)->out.stack_adjust += pre;
9825                         }
9826                     }
9827
9828                   cselib_hook_called = false;
9829                   adjust_insn (bb, insn);
9830                   if (MAY_HAVE_DEBUG_INSNS)
9831                     {
9832                       if (CALL_P (insn))
9833                         prepare_call_arguments (bb, insn);
9834                       cselib_process_insn (insn);
9835                       if (dump_file && (dump_flags & TDF_DETAILS))
9836                         {
9837                           print_rtl_single (dump_file, insn);
9838                           dump_cselib_table (dump_file);
9839                         }
9840                     }
9841                   if (!cselib_hook_called)
9842                     add_with_sets (insn, 0, 0);
9843                   cancel_changes (0);
9844
9845                   if (!frame_pointer_needed && post)
9846                     {
9847                       micro_operation mo;
9848                       mo.type = MO_ADJUST;
9849                       mo.u.adjust = post;
9850                       mo.insn = insn;
9851                       if (dump_file && (dump_flags & TDF_DETAILS))
9852                         log_op_type (PATTERN (insn), bb, insn,
9853                                      MO_ADJUST, dump_file);
9854                       VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
9855                                      mo);
9856                       VTI (bb)->out.stack_adjust += post;
9857                     }
9858
9859                   if (bb == prologue_bb
9860                       && fp_cfa_offset != -1
9861                       && hard_frame_pointer_adjustment == -1
9862                       && RTX_FRAME_RELATED_P (insn)
9863                       && fp_setter (insn))
9864                     {
9865                       vt_init_cfa_base ();
9866                       hard_frame_pointer_adjustment = fp_cfa_offset;
9867                       /* Disassociate sp from fp now.  */
9868                       if (MAY_HAVE_DEBUG_INSNS)
9869                         {
9870                           cselib_val *v;
9871                           cselib_invalidate_rtx (stack_pointer_rtx);
9872                           v = cselib_lookup (stack_pointer_rtx, Pmode, 1,
9873                                              VOIDmode);
9874                           if (v && !cselib_preserved_value_p (v))
9875                             {
9876                               cselib_set_value_sp_based (v);
9877                               preserve_value (v);
9878                             }
9879                         }
9880                     }
9881                 }
9882             }
9883           gcc_assert (offset == VTI (bb)->out.stack_adjust);
9884         }
9885
9886       bb = last_bb;
9887
9888       if (MAY_HAVE_DEBUG_INSNS)
9889         {
9890           cselib_preserve_only_values ();
9891           cselib_reset_table (cselib_get_next_uid ());
9892           cselib_record_sets_hook = NULL;
9893         }
9894     }
9895
9896   hard_frame_pointer_adjustment = -1;
9897   VTI (ENTRY_BLOCK_PTR)->flooded = true;
9898   cfa_base_rtx = NULL_RTX;
9899   return true;
9900 }
9901
9902 /* This is *not* reset after each function.  It gives each
9903    NOTE_INSN_DELETED_DEBUG_LABEL in the entire compilation
9904    a unique label number.  */
9905
9906 static int debug_label_num = 1;
9907
9908 /* Get rid of all debug insns from the insn stream.  */
9909
9910 static void
9911 delete_debug_insns (void)
9912 {
9913   basic_block bb;
9914   rtx insn, next;
9915
9916   if (!MAY_HAVE_DEBUG_INSNS)
9917     return;
9918
9919   FOR_EACH_BB (bb)
9920     {
9921       FOR_BB_INSNS_SAFE (bb, insn, next)
9922         if (DEBUG_INSN_P (insn))
9923           {
9924             tree decl = INSN_VAR_LOCATION_DECL (insn);
9925             if (TREE_CODE (decl) == LABEL_DECL
9926                 && DECL_NAME (decl)
9927                 && !DECL_RTL_SET_P (decl))
9928               {
9929                 PUT_CODE (insn, NOTE);
9930                 NOTE_KIND (insn) = NOTE_INSN_DELETED_DEBUG_LABEL;
9931                 NOTE_DELETED_LABEL_NAME (insn)
9932                   = IDENTIFIER_POINTER (DECL_NAME (decl));
9933                 SET_DECL_RTL (decl, insn);
9934                 CODE_LABEL_NUMBER (insn) = debug_label_num++;
9935               }
9936             else
9937               delete_insn (insn);
9938           }
9939     }
9940 }
9941
9942 /* Run a fast, BB-local only version of var tracking, to take care of
9943    information that we don't do global analysis on, such that not all
9944    information is lost.  If SKIPPED holds, we're skipping the global
9945    pass entirely, so we should try to use information it would have
9946    handled as well..  */
9947
9948 static void
9949 vt_debug_insns_local (bool skipped ATTRIBUTE_UNUSED)
9950 {
9951   /* ??? Just skip it all for now.  */
9952   delete_debug_insns ();
9953 }
9954
9955 /* Free the data structures needed for variable tracking.  */
9956
9957 static void
9958 vt_finalize (void)
9959 {
9960   basic_block bb;
9961
9962   FOR_EACH_BB (bb)
9963     {
9964       VEC_free (micro_operation, heap, VTI (bb)->mos);
9965     }
9966
9967   FOR_ALL_BB (bb)
9968     {
9969       dataflow_set_destroy (&VTI (bb)->in);
9970       dataflow_set_destroy (&VTI (bb)->out);
9971       if (VTI (bb)->permp)
9972         {
9973           dataflow_set_destroy (VTI (bb)->permp);
9974           XDELETE (VTI (bb)->permp);
9975         }
9976     }
9977   free_aux_for_blocks ();
9978   htab_delete (empty_shared_hash->htab);
9979   htab_delete (changed_variables);
9980   free_alloc_pool (attrs_pool);
9981   free_alloc_pool (var_pool);
9982   free_alloc_pool (loc_chain_pool);
9983   free_alloc_pool (shared_hash_pool);
9984
9985   if (MAY_HAVE_DEBUG_INSNS)
9986     {
9987       if (loc_exp_dep_pool)
9988         free_alloc_pool (loc_exp_dep_pool);
9989       loc_exp_dep_pool = NULL;
9990       free_alloc_pool (valvar_pool);
9991       VEC_free (rtx, heap, preserved_values);
9992       cselib_finish ();
9993       BITMAP_FREE (scratch_regs);
9994       scratch_regs = NULL;
9995     }
9996
9997 #ifdef HAVE_window_save
9998   VEC_free (parm_reg_t, gc, windowed_parm_regs);
9999 #endif
10000
10001   if (vui_vec)
10002     XDELETEVEC (vui_vec);
10003   vui_vec = NULL;
10004   vui_allocated = 0;
10005 }
10006
10007 /* The entry point to variable tracking pass.  */
10008
10009 static inline unsigned int
10010 variable_tracking_main_1 (void)
10011 {
10012   bool success;
10013
10014   if (flag_var_tracking_assignments < 0)
10015     {
10016       delete_debug_insns ();
10017       return 0;
10018     }
10019
10020   if (n_basic_blocks > 500 && n_edges / n_basic_blocks >= 20)
10021     {
10022       vt_debug_insns_local (true);
10023       return 0;
10024     }
10025
10026   mark_dfs_back_edges ();
10027   if (!vt_initialize ())
10028     {
10029       vt_finalize ();
10030       vt_debug_insns_local (true);
10031       return 0;
10032     }
10033
10034   success = vt_find_locations ();
10035
10036   if (!success && flag_var_tracking_assignments > 0)
10037     {
10038       vt_finalize ();
10039
10040       delete_debug_insns ();
10041
10042       /* This is later restored by our caller.  */
10043       flag_var_tracking_assignments = 0;
10044
10045       success = vt_initialize ();
10046       gcc_assert (success);
10047
10048       success = vt_find_locations ();
10049     }
10050
10051   if (!success)
10052     {
10053       vt_finalize ();
10054       vt_debug_insns_local (false);
10055       return 0;
10056     }
10057
10058   if (dump_file && (dump_flags & TDF_DETAILS))
10059     {
10060       dump_dataflow_sets ();
10061       dump_reg_info (dump_file);
10062       dump_flow_info (dump_file, dump_flags);
10063     }
10064
10065   timevar_push (TV_VAR_TRACKING_EMIT);
10066   vt_emit_notes ();
10067   timevar_pop (TV_VAR_TRACKING_EMIT);
10068
10069   vt_finalize ();
10070   vt_debug_insns_local (false);
10071   return 0;
10072 }
10073
10074 unsigned int
10075 variable_tracking_main (void)
10076 {
10077   unsigned int ret;
10078   int save = flag_var_tracking_assignments;
10079
10080   ret = variable_tracking_main_1 ();
10081
10082   flag_var_tracking_assignments = save;
10083
10084   return ret;
10085 }
10086 \f
10087 static bool
10088 gate_handle_var_tracking (void)
10089 {
10090   return (flag_var_tracking && !targetm.delay_vartrack);
10091 }
10092
10093
10094
10095 struct rtl_opt_pass pass_variable_tracking =
10096 {
10097  {
10098   RTL_PASS,
10099   "vartrack",                           /* name */
10100   gate_handle_var_tracking,             /* gate */
10101   variable_tracking_main,               /* execute */
10102   NULL,                                 /* sub */
10103   NULL,                                 /* next */
10104   0,                                    /* static_pass_number */
10105   TV_VAR_TRACKING,                      /* tv_id */
10106   0,                                    /* properties_required */
10107   0,                                    /* properties_provided */
10108   0,                                    /* properties_destroyed */
10109   0,                                    /* todo_flags_start */
10110   TODO_verify_rtl_sharing               /* todo_flags_finish */
10111  }
10112 };