OSDN Git Service

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