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