OSDN Git Service

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