OSDN Git Service

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