OSDN Git Service

gcc/fortran/
[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       enum machine_mode address_mode
4363         = targetm.addr_space.address_mode (MEM_ADDR_SPACE (loc));
4364       cselib_val *addr = cselib_lookup (XEXP (loc, 0), address_mode, 0);
4365       if (addr)
4366         return replace_equiv_address_nv (loc, addr->val_rtx);
4367       else
4368         return NULL;
4369     }
4370   else
4371     return cselib_subst_to_values (loc);
4372 }
4373
4374 /* Determine what kind of micro operation to choose for a USE.  Return
4375    MO_CLOBBER if no micro operation is to be generated.  */
4376
4377 static enum micro_operation_type
4378 use_type (rtx *loc, struct count_use_info *cui, enum machine_mode *modep)
4379 {
4380   tree expr;
4381   cselib_val *val;
4382
4383   if (cui && cui->sets)
4384     {
4385       if (GET_CODE (*loc) == VAR_LOCATION)
4386         {
4387           if (track_expr_p (PAT_VAR_LOCATION_DECL (*loc), false))
4388             {
4389               rtx ploc = PAT_VAR_LOCATION_LOC (*loc);
4390               cselib_val *val = cselib_lookup (ploc, GET_MODE (*loc), 1);
4391
4392               /* ??? flag_float_store and volatile mems are never
4393                  given values, but we could in theory use them for
4394                  locations.  */
4395               gcc_assert (val || 1);
4396               return MO_VAL_LOC;
4397             }
4398           else
4399             return MO_CLOBBER;
4400         }
4401
4402       if ((REG_P (*loc) || MEM_P (*loc))
4403           && (val = find_use_val (*loc, GET_MODE (*loc), cui)))
4404         {
4405           if (modep)
4406             *modep = GET_MODE (*loc);
4407           if (cui->store_p)
4408             {
4409               if (REG_P (*loc)
4410                   || cselib_lookup (XEXP (*loc, 0), GET_MODE (*loc), 0))
4411                 return MO_VAL_SET;
4412             }
4413           else if (!cselib_preserved_value_p (val))
4414             return MO_VAL_USE;
4415         }
4416     }
4417
4418   if (REG_P (*loc))
4419     {
4420       gcc_assert (REGNO (*loc) < FIRST_PSEUDO_REGISTER);
4421
4422       expr = REG_EXPR (*loc);
4423
4424       if (!expr)
4425         return MO_USE_NO_VAR;
4426       else if (target_for_debug_bind (var_debug_decl (expr)))
4427         return MO_CLOBBER;
4428       else if (track_loc_p (*loc, expr, REG_OFFSET (*loc),
4429                             false, modep, NULL))
4430         return MO_USE;
4431       else
4432         return MO_USE_NO_VAR;
4433     }
4434   else if (MEM_P (*loc))
4435     {
4436       expr = MEM_EXPR (*loc);
4437
4438       if (!expr)
4439         return MO_CLOBBER;
4440       else if (target_for_debug_bind (var_debug_decl (expr)))
4441         return MO_CLOBBER;
4442       else if (track_loc_p (*loc, expr, INT_MEM_OFFSET (*loc),
4443                             false, modep, NULL))
4444         return MO_USE;
4445       else
4446         return MO_CLOBBER;
4447     }
4448
4449   return MO_CLOBBER;
4450 }
4451
4452 /* Log to OUT information about micro-operation MOPT involving X in
4453    INSN of BB.  */
4454
4455 static inline void
4456 log_op_type (rtx x, basic_block bb, rtx insn,
4457              enum micro_operation_type mopt, FILE *out)
4458 {
4459   fprintf (out, "bb %i op %i insn %i %s ",
4460            bb->index, VTI (bb)->n_mos - 1,
4461            INSN_UID (insn), micro_operation_type_name[mopt]);
4462   print_inline_rtx (out, x, 2);
4463   fputc ('\n', out);
4464 }
4465
4466 /* Count uses (register and memory references) LOC which will be tracked.
4467    INSN is instruction which the LOC is part of.  */
4468
4469 static int
4470 count_uses (rtx *loc, void *cuip)
4471 {
4472   struct count_use_info *cui = (struct count_use_info *) cuip;
4473   enum micro_operation_type mopt = use_type (loc, cui, NULL);
4474
4475   if (mopt != MO_CLOBBER)
4476     {
4477       cselib_val *val;
4478       enum machine_mode mode = GET_MODE (*loc);
4479
4480       VTI (cui->bb)->n_mos++;
4481
4482       if (dump_file && (dump_flags & TDF_DETAILS))
4483         log_op_type (*loc, cui->bb, cui->insn, mopt, dump_file);
4484
4485       switch (mopt)
4486         {
4487         case MO_VAL_LOC:
4488           loc = &PAT_VAR_LOCATION_LOC (*loc);
4489           if (VAR_LOC_UNKNOWN_P (*loc))
4490             break;
4491           /* Fall through.  */
4492
4493         case MO_VAL_USE:
4494         case MO_VAL_SET:
4495           if (MEM_P (*loc)
4496               && !REG_P (XEXP (*loc, 0)) && !MEM_P (XEXP (*loc, 0)))
4497             {
4498               enum machine_mode address_mode
4499                 = targetm.addr_space.address_mode (MEM_ADDR_SPACE (*loc));
4500               val = cselib_lookup (XEXP (*loc, 0), address_mode, false);
4501
4502               if (val && !cselib_preserved_value_p (val))
4503                 {
4504                   VTI (cui->bb)->n_mos++;
4505                   cselib_preserve_value (val);
4506                 }
4507             }
4508
4509           val = find_use_val (*loc, mode, cui);
4510           if (val)
4511             cselib_preserve_value (val);
4512           else
4513             gcc_assert (mopt == MO_VAL_LOC);
4514
4515           break;
4516
4517         default:
4518           break;
4519         }
4520     }
4521
4522   return 0;
4523 }
4524
4525 /* Helper function for finding all uses of REG/MEM in X in CUI's
4526    insn.  */
4527
4528 static void
4529 count_uses_1 (rtx *x, void *cui)
4530 {
4531   for_each_rtx (x, count_uses, cui);
4532 }
4533
4534 /* Count stores (register and memory references) LOC which will be
4535    tracked.  CUI is a count_use_info object containing the instruction
4536    which the LOC is part of.  */
4537
4538 static void
4539 count_stores (rtx loc, const_rtx expr ATTRIBUTE_UNUSED, void *cui)
4540 {
4541   count_uses (&loc, cui);
4542 }
4543
4544 /* Callback for cselib_record_sets_hook, that counts how many micro
4545    operations it takes for uses and stores in an insn after
4546    cselib_record_sets has analyzed the sets in an insn, but before it
4547    modifies the stored values in the internal tables, unless
4548    cselib_record_sets doesn't call it directly (perhaps because we're
4549    not doing cselib in the first place, in which case sets and n_sets
4550    will be 0).  */
4551
4552 static void
4553 count_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
4554 {
4555   basic_block bb = BLOCK_FOR_INSN (insn);
4556   struct count_use_info cui;
4557
4558   cselib_hook_called = true;
4559
4560   cui.insn = insn;
4561   cui.bb = bb;
4562   cui.sets = sets;
4563   cui.n_sets = n_sets;
4564
4565   cui.store_p = false;
4566   note_uses (&PATTERN (insn), count_uses_1, &cui);
4567   cui.store_p = true;
4568   note_stores (PATTERN (insn), count_stores, &cui);
4569 }
4570
4571 /* Tell whether the CONCAT used to holds a VALUE and its location
4572    needs value resolution, i.e., an attempt of mapping the location
4573    back to other incoming values.  */
4574 #define VAL_NEEDS_RESOLUTION(x) \
4575   (RTL_FLAG_CHECK1 ("VAL_NEEDS_RESOLUTION", (x), CONCAT)->volatil)
4576 /* Whether the location in the CONCAT is a tracked expression, that
4577    should also be handled like a MO_USE.  */
4578 #define VAL_HOLDS_TRACK_EXPR(x) \
4579   (RTL_FLAG_CHECK1 ("VAL_HOLDS_TRACK_EXPR", (x), CONCAT)->used)
4580 /* Whether the location in the CONCAT should be handled like a MO_COPY
4581    as well.  */
4582 #define VAL_EXPR_IS_COPIED(x) \
4583   (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_COPIED", (x), CONCAT)->jump)
4584 /* Whether the location in the CONCAT should be handled like a
4585    MO_CLOBBER as well.  */
4586 #define VAL_EXPR_IS_CLOBBERED(x) \
4587   (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_CLOBBERED", (x), CONCAT)->unchanging)
4588
4589 /* Add uses (register and memory references) LOC which will be tracked
4590    to VTI (bb)->mos.  INSN is instruction which the LOC is part of.  */
4591
4592 static int
4593 add_uses (rtx *loc, void *data)
4594 {
4595   enum machine_mode mode = VOIDmode;
4596   struct count_use_info *cui = (struct count_use_info *)data;
4597   enum micro_operation_type type = use_type (loc, cui, &mode);
4598
4599   if (type != MO_CLOBBER)
4600     {
4601       basic_block bb = cui->bb;
4602       micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
4603
4604       mo->type = type;
4605       mo->u.loc = type == MO_USE ? var_lowpart (mode, *loc) : *loc;
4606       mo->insn = cui->insn;
4607
4608       if (type == MO_VAL_LOC)
4609         {
4610           rtx oloc = *loc;
4611           rtx vloc = PAT_VAR_LOCATION_LOC (oloc);
4612           cselib_val *val;
4613
4614           gcc_assert (cui->sets);
4615
4616           if (MEM_P (vloc)
4617               && !REG_P (XEXP (vloc, 0)) && !MEM_P (XEXP (vloc, 0)))
4618             {
4619               rtx mloc = vloc;
4620               enum machine_mode address_mode
4621                 = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mloc));
4622               cselib_val *val
4623                 = cselib_lookup (XEXP (mloc, 0), address_mode, 0);
4624
4625               if (val && !cselib_preserved_value_p (val))
4626                 {
4627                   micro_operation *mon = VTI (bb)->mos + VTI (bb)->n_mos++;
4628                   mon->type = mo->type;
4629                   mon->u.loc = mo->u.loc;
4630                   mon->insn = mo->insn;
4631                   cselib_preserve_value (val);
4632                   mo->type = MO_VAL_USE;
4633                   mloc = cselib_subst_to_values (XEXP (mloc, 0));
4634                   mo->u.loc = gen_rtx_CONCAT (address_mode,
4635                                               val->val_rtx, mloc);
4636                   if (dump_file && (dump_flags & TDF_DETAILS))
4637                     log_op_type (mo->u.loc, cui->bb, cui->insn,
4638                                  mo->type, dump_file);
4639                   mo = mon;
4640                 }
4641             }
4642
4643           if (!VAR_LOC_UNKNOWN_P (vloc)
4644               && (val = find_use_val (vloc, GET_MODE (oloc), cui)))
4645             {
4646               enum machine_mode mode2;
4647               enum micro_operation_type type2;
4648               rtx nloc = replace_expr_with_values (vloc);
4649
4650               if (nloc)
4651                 {
4652                   oloc = shallow_copy_rtx (oloc);
4653                   PAT_VAR_LOCATION_LOC (oloc) = nloc;
4654                 }
4655
4656               oloc = gen_rtx_CONCAT (mode, val->val_rtx, oloc);
4657
4658               type2 = use_type (&vloc, 0, &mode2);
4659
4660               gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
4661                           || type2 == MO_CLOBBER);
4662
4663               if (type2 == MO_CLOBBER
4664                   && !cselib_preserved_value_p (val))
4665                 {
4666                   VAL_NEEDS_RESOLUTION (oloc) = 1;
4667                   cselib_preserve_value (val);
4668                 }
4669             }
4670           else if (!VAR_LOC_UNKNOWN_P (vloc))
4671             {
4672               oloc = shallow_copy_rtx (oloc);
4673               PAT_VAR_LOCATION_LOC (oloc) = gen_rtx_UNKNOWN_VAR_LOC ();
4674             }
4675
4676           mo->u.loc = oloc;
4677         }
4678       else if (type == MO_VAL_USE)
4679         {
4680           enum machine_mode mode2 = VOIDmode;
4681           enum micro_operation_type type2;
4682           cselib_val *val = find_use_val (*loc, GET_MODE (*loc), cui);
4683           rtx vloc, oloc = *loc, nloc;
4684
4685           gcc_assert (cui->sets);
4686
4687           if (MEM_P (oloc)
4688               && !REG_P (XEXP (oloc, 0)) && !MEM_P (XEXP (oloc, 0)))
4689             {
4690               rtx mloc = oloc;
4691               enum machine_mode address_mode
4692                 = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mloc));
4693               cselib_val *val
4694                 = cselib_lookup (XEXP (mloc, 0), address_mode, 0);
4695
4696               if (val && !cselib_preserved_value_p (val))
4697                 {
4698                   micro_operation *mon = VTI (bb)->mos + VTI (bb)->n_mos++;
4699                   mon->type = mo->type;
4700                   mon->u.loc = mo->u.loc;
4701                   mon->insn = mo->insn;
4702                   cselib_preserve_value (val);
4703                   mo->type = MO_VAL_USE;
4704                   mloc = cselib_subst_to_values (XEXP (mloc, 0));
4705                   mo->u.loc = gen_rtx_CONCAT (address_mode,
4706                                               val->val_rtx, mloc);
4707                   mo->insn = cui->insn;
4708                   if (dump_file && (dump_flags & TDF_DETAILS))
4709                     log_op_type (mo->u.loc, cui->bb, cui->insn,
4710                                  mo->type, dump_file);
4711                   mo = mon;
4712                 }
4713             }
4714
4715           type2 = use_type (loc, 0, &mode2);
4716
4717           gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
4718                       || type2 == MO_CLOBBER);
4719
4720           if (type2 == MO_USE)
4721             vloc = var_lowpart (mode2, *loc);
4722           else
4723             vloc = oloc;
4724
4725           /* The loc of a MO_VAL_USE may have two forms:
4726
4727              (concat val src): val is at src, a value-based
4728              representation.
4729
4730              (concat (concat val use) src): same as above, with use as
4731              the MO_USE tracked value, if it differs from src.
4732
4733           */
4734
4735           nloc = replace_expr_with_values (*loc);
4736           if (!nloc)
4737             nloc = oloc;
4738
4739           if (vloc != nloc)
4740             oloc = gen_rtx_CONCAT (mode2, val->val_rtx, vloc);
4741           else
4742             oloc = val->val_rtx;
4743
4744           mo->u.loc = gen_rtx_CONCAT (mode, oloc, nloc);
4745
4746           if (type2 == MO_USE)
4747             VAL_HOLDS_TRACK_EXPR (mo->u.loc) = 1;
4748           if (!cselib_preserved_value_p (val))
4749             {
4750               VAL_NEEDS_RESOLUTION (mo->u.loc) = 1;
4751               cselib_preserve_value (val);
4752             }
4753         }
4754       else
4755         gcc_assert (type == MO_USE || type == MO_USE_NO_VAR);
4756
4757       if (dump_file && (dump_flags & TDF_DETAILS))
4758         log_op_type (mo->u.loc, cui->bb, cui->insn, mo->type, dump_file);
4759     }
4760
4761   return 0;
4762 }
4763
4764 /* Helper function for finding all uses of REG/MEM in X in insn INSN.  */
4765
4766 static void
4767 add_uses_1 (rtx *x, void *cui)
4768 {
4769   for_each_rtx (x, add_uses, cui);
4770 }
4771
4772 /* Add stores (register and memory references) LOC which will be tracked
4773    to VTI (bb)->mos.  EXPR is the RTL expression containing the store.
4774    CUIP->insn is instruction which the LOC is part of.  */
4775
4776 static void
4777 add_stores (rtx loc, const_rtx expr, void *cuip)
4778 {
4779   enum machine_mode mode = VOIDmode, mode2;
4780   struct count_use_info *cui = (struct count_use_info *)cuip;
4781   basic_block bb = cui->bb;
4782   micro_operation *mo;
4783   rtx oloc = loc, nloc, src = NULL;
4784   enum micro_operation_type type = use_type (&loc, cui, &mode);
4785   bool track_p = false;
4786   cselib_val *v;
4787   bool resolve, preserve;
4788
4789   if (type == MO_CLOBBER)
4790     return;
4791
4792   mode2 = mode;
4793
4794   if (REG_P (loc))
4795     {
4796       mo = VTI (bb)->mos + VTI (bb)->n_mos++;
4797
4798       if ((GET_CODE (expr) == CLOBBER && type != MO_VAL_SET)
4799           || !(track_p = use_type (&loc, NULL, &mode2) == MO_USE)
4800           || GET_CODE (expr) == CLOBBER)
4801         {
4802           mo->type = MO_CLOBBER;
4803           mo->u.loc = loc;
4804         }
4805       else
4806         {
4807           if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
4808             src = var_lowpart (mode2, SET_SRC (expr));
4809           loc = var_lowpart (mode2, loc);
4810
4811           if (src == NULL)
4812             {
4813               mo->type = MO_SET;
4814               mo->u.loc = loc;
4815             }
4816           else
4817             {
4818               if (SET_SRC (expr) != src)
4819                 expr = gen_rtx_SET (VOIDmode, loc, src);
4820               if (same_variable_part_p (src, REG_EXPR (loc), REG_OFFSET (loc)))
4821                 mo->type = MO_COPY;
4822               else
4823                 mo->type = MO_SET;
4824               mo->u.loc = CONST_CAST_RTX (expr);
4825             }
4826         }
4827       mo->insn = cui->insn;
4828     }
4829   else if (MEM_P (loc)
4830            && ((track_p = use_type (&loc, NULL, &mode2) == MO_USE)
4831                || cui->sets))
4832     {
4833       mo = VTI (bb)->mos + VTI (bb)->n_mos++;
4834
4835       if (MEM_P (loc) && type == MO_VAL_SET
4836           && !REG_P (XEXP (loc, 0)) && !MEM_P (XEXP (loc, 0)))
4837         {
4838           rtx mloc = loc;
4839           enum machine_mode address_mode
4840             = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mloc));
4841           cselib_val *val = cselib_lookup (XEXP (mloc, 0), address_mode, 0);
4842
4843           if (val && !cselib_preserved_value_p (val))
4844             {
4845               cselib_preserve_value (val);
4846               mo->type = MO_VAL_USE;
4847               mloc = cselib_subst_to_values (XEXP (mloc, 0));
4848               mo->u.loc = gen_rtx_CONCAT (address_mode, val->val_rtx, mloc);
4849               mo->insn = cui->insn;
4850               if (dump_file && (dump_flags & TDF_DETAILS))
4851                 log_op_type (mo->u.loc, cui->bb, cui->insn,
4852                              mo->type, dump_file);
4853               mo = VTI (bb)->mos + VTI (bb)->n_mos++;
4854             }
4855         }
4856
4857       if (GET_CODE (expr) == CLOBBER || !track_p)
4858         {
4859           mo->type = MO_CLOBBER;
4860           mo->u.loc = track_p ? var_lowpart (mode2, loc) : loc;
4861         }
4862       else
4863         {
4864           if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
4865             src = var_lowpart (mode2, SET_SRC (expr));
4866           loc = var_lowpart (mode2, loc);
4867
4868           if (src == NULL)
4869             {
4870               mo->type = MO_SET;
4871               mo->u.loc = loc;
4872             }
4873           else
4874             {
4875               if (SET_SRC (expr) != src)
4876                 expr = gen_rtx_SET (VOIDmode, loc, src);
4877               if (same_variable_part_p (SET_SRC (expr),
4878                                         MEM_EXPR (loc),
4879                                         INT_MEM_OFFSET (loc)))
4880                 mo->type = MO_COPY;
4881               else
4882                 mo->type = MO_SET;
4883               mo->u.loc = CONST_CAST_RTX (expr);
4884             }
4885         }
4886       mo->insn = cui->insn;
4887     }
4888   else
4889     return;
4890
4891   if (type != MO_VAL_SET)
4892     goto log_and_return;
4893
4894   v = find_use_val (oloc, mode, cui);
4895
4896   resolve = preserve = !cselib_preserved_value_p (v);
4897
4898   nloc = replace_expr_with_values (oloc);
4899   if (nloc)
4900     oloc = nloc;
4901
4902   if (resolve && GET_CODE (mo->u.loc) == SET)
4903     {
4904       nloc = replace_expr_with_values (SET_SRC (mo->u.loc));
4905
4906       if (nloc)
4907         oloc = gen_rtx_SET (GET_MODE (mo->u.loc), oloc, nloc);
4908       else
4909         {
4910           if (oloc == SET_DEST (mo->u.loc))
4911             /* No point in duplicating.  */
4912             oloc = mo->u.loc;
4913           if (!REG_P (SET_SRC (mo->u.loc)))
4914             resolve = false;
4915         }
4916     }
4917   else if (!resolve)
4918     {
4919       if (GET_CODE (mo->u.loc) == SET
4920           && oloc == SET_DEST (mo->u.loc))
4921         /* No point in duplicating.  */
4922         oloc = mo->u.loc;
4923     }
4924   else
4925     resolve = false;
4926
4927   loc = gen_rtx_CONCAT (mode, v->val_rtx, oloc);
4928
4929   if (mo->u.loc != oloc)
4930     loc = gen_rtx_CONCAT (GET_MODE (mo->u.loc), loc, mo->u.loc);
4931
4932   /* The loc of a MO_VAL_SET may have various forms:
4933
4934      (concat val dst): dst now holds val
4935
4936      (concat val (set dst src)): dst now holds val, copied from src
4937
4938      (concat (concat val dstv) dst): dst now holds val; dstv is dst
4939      after replacing mems and non-top-level regs with values.
4940
4941      (concat (concat val dstv) (set dst src)): dst now holds val,
4942      copied from src.  dstv is a value-based representation of dst, if
4943      it differs from dst.  If resolution is needed, src is a REG.
4944
4945      (concat (concat val (set dstv srcv)) (set dst src)): src
4946      copied to dst, holding val.  dstv and srcv are value-based
4947      representations of dst and src, respectively.
4948
4949   */
4950
4951   mo->u.loc = loc;
4952
4953   if (track_p)
4954     VAL_HOLDS_TRACK_EXPR (loc) = 1;
4955   if (preserve)
4956     {
4957       VAL_NEEDS_RESOLUTION (loc) = resolve;
4958       cselib_preserve_value (v);
4959     }
4960   if (mo->type == MO_CLOBBER)
4961     VAL_EXPR_IS_CLOBBERED (loc) = 1;
4962   if (mo->type == MO_COPY)
4963     VAL_EXPR_IS_COPIED (loc) = 1;
4964
4965   mo->type = MO_VAL_SET;
4966
4967  log_and_return:
4968   if (dump_file && (dump_flags & TDF_DETAILS))
4969     log_op_type (mo->u.loc, cui->bb, cui->insn, mo->type, dump_file);
4970 }
4971
4972 /* Callback for cselib_record_sets_hook, that records as micro
4973    operations uses and stores in an insn after cselib_record_sets has
4974    analyzed the sets in an insn, but before it modifies the stored
4975    values in the internal tables, unless cselib_record_sets doesn't
4976    call it directly (perhaps because we're not doing cselib in the
4977    first place, in which case sets and n_sets will be 0).  */
4978
4979 static void
4980 add_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
4981 {
4982   basic_block bb = BLOCK_FOR_INSN (insn);
4983   int n1, n2;
4984   struct count_use_info cui;
4985
4986   cselib_hook_called = true;
4987
4988   cui.insn = insn;
4989   cui.bb = bb;
4990   cui.sets = sets;
4991   cui.n_sets = n_sets;
4992
4993   n1 = VTI (bb)->n_mos;
4994   cui.store_p = false;
4995   note_uses (&PATTERN (insn), add_uses_1, &cui);
4996   n2 = VTI (bb)->n_mos - 1;
4997
4998   /* Order the MO_USEs to be before MO_USE_NO_VARs and MO_VAL_USE, and
4999      MO_VAL_LOC last.  */
5000   while (n1 < n2)
5001     {
5002       while (n1 < n2 && VTI (bb)->mos[n1].type == MO_USE)
5003         n1++;
5004       while (n1 < n2 && VTI (bb)->mos[n2].type != MO_USE)
5005         n2--;
5006       if (n1 < n2)
5007         {
5008           micro_operation sw;
5009
5010           sw = VTI (bb)->mos[n1];
5011           VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
5012           VTI (bb)->mos[n2] = sw;
5013         }
5014     }
5015
5016   n2 = VTI (bb)->n_mos - 1;
5017
5018   while (n1 < n2)
5019     {
5020       while (n1 < n2 && VTI (bb)->mos[n1].type != MO_VAL_LOC)
5021         n1++;
5022       while (n1 < n2 && VTI (bb)->mos[n2].type == MO_VAL_LOC)
5023         n2--;
5024       if (n1 < n2)
5025         {
5026           micro_operation sw;
5027
5028           sw = VTI (bb)->mos[n1];
5029           VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
5030           VTI (bb)->mos[n2] = sw;
5031         }
5032     }
5033
5034   if (CALL_P (insn))
5035     {
5036       micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
5037
5038       mo->type = MO_CALL;
5039       mo->insn = insn;
5040
5041       if (dump_file && (dump_flags & TDF_DETAILS))
5042         log_op_type (PATTERN (insn), bb, insn, mo->type, dump_file);
5043     }
5044
5045   n1 = VTI (bb)->n_mos;
5046   /* This will record NEXT_INSN (insn), such that we can
5047      insert notes before it without worrying about any
5048      notes that MO_USEs might emit after the insn.  */
5049   cui.store_p = true;
5050   note_stores (PATTERN (insn), add_stores, &cui);
5051   n2 = VTI (bb)->n_mos - 1;
5052
5053   /* Order the MO_CLOBBERs to be before MO_SETs.  */
5054   while (n1 < n2)
5055     {
5056       while (n1 < n2 && VTI (bb)->mos[n1].type == MO_CLOBBER)
5057         n1++;
5058       while (n1 < n2 && VTI (bb)->mos[n2].type != MO_CLOBBER)
5059         n2--;
5060       if (n1 < n2)
5061         {
5062           micro_operation sw;
5063
5064           sw = VTI (bb)->mos[n1];
5065           VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
5066           VTI (bb)->mos[n2] = sw;
5067         }
5068     }
5069 }
5070
5071 static enum var_init_status
5072 find_src_status (dataflow_set *in, rtx src)
5073 {
5074   tree decl = NULL_TREE;
5075   enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
5076
5077   if (! flag_var_tracking_uninit)
5078     status = VAR_INIT_STATUS_INITIALIZED;
5079
5080   if (src && REG_P (src))
5081     decl = var_debug_decl (REG_EXPR (src));
5082   else if (src && MEM_P (src))
5083     decl = var_debug_decl (MEM_EXPR (src));
5084
5085   if (src && decl)
5086     status = get_init_value (in, src, dv_from_decl (decl));
5087
5088   return status;
5089 }
5090
5091 /* SRC is the source of an assignment.  Use SET to try to find what
5092    was ultimately assigned to SRC.  Return that value if known,
5093    otherwise return SRC itself.  */
5094
5095 static rtx
5096 find_src_set_src (dataflow_set *set, rtx src)
5097 {
5098   tree decl = NULL_TREE;   /* The variable being copied around.          */
5099   rtx set_src = NULL_RTX;  /* The value for "decl" stored in "src".      */
5100   variable var;
5101   location_chain nextp;
5102   int i;
5103   bool found;
5104
5105   if (src && REG_P (src))
5106     decl = var_debug_decl (REG_EXPR (src));
5107   else if (src && MEM_P (src))
5108     decl = var_debug_decl (MEM_EXPR (src));
5109
5110   if (src && decl)
5111     {
5112       decl_or_value dv = dv_from_decl (decl);
5113
5114       var = shared_hash_find (set->vars, dv);
5115       if (var)
5116         {
5117           found = false;
5118           for (i = 0; i < var->n_var_parts && !found; i++)
5119             for (nextp = var->var_part[i].loc_chain; nextp && !found;
5120                  nextp = nextp->next)
5121               if (rtx_equal_p (nextp->loc, src))
5122                 {
5123                   set_src = nextp->set_src;
5124                   found = true;
5125                 }
5126
5127         }
5128     }
5129
5130   return set_src;
5131 }
5132
5133 /* Compute the changes of variable locations in the basic block BB.  */
5134
5135 static bool
5136 compute_bb_dataflow (basic_block bb)
5137 {
5138   int i, n;
5139   bool changed;
5140   dataflow_set old_out;
5141   dataflow_set *in = &VTI (bb)->in;
5142   dataflow_set *out = &VTI (bb)->out;
5143
5144   dataflow_set_init (&old_out);
5145   dataflow_set_copy (&old_out, out);
5146   dataflow_set_copy (out, in);
5147
5148   n = VTI (bb)->n_mos;
5149   for (i = 0; i < n; i++)
5150     {
5151       rtx insn = VTI (bb)->mos[i].insn;
5152
5153       switch (VTI (bb)->mos[i].type)
5154         {
5155           case MO_CALL:
5156             dataflow_set_clear_at_call (out);
5157             break;
5158
5159           case MO_USE:
5160             {
5161               rtx loc = VTI (bb)->mos[i].u.loc;
5162
5163               if (REG_P (loc))
5164                 var_reg_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
5165               else if (MEM_P (loc))
5166                 var_mem_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
5167             }
5168             break;
5169
5170           case MO_VAL_LOC:
5171             {
5172               rtx loc = VTI (bb)->mos[i].u.loc;
5173               rtx val, vloc;
5174               tree var;
5175
5176               if (GET_CODE (loc) == CONCAT)
5177                 {
5178                   val = XEXP (loc, 0);
5179                   vloc = XEXP (loc, 1);
5180                 }
5181               else
5182                 {
5183                   val = NULL_RTX;
5184                   vloc = loc;
5185                 }
5186
5187               var = PAT_VAR_LOCATION_DECL (vloc);
5188
5189               clobber_variable_part (out, NULL_RTX,
5190                                      dv_from_decl (var), 0, NULL_RTX);
5191               if (val)
5192                 {
5193                   if (VAL_NEEDS_RESOLUTION (loc))
5194                     val_resolve (out, val, PAT_VAR_LOCATION_LOC (vloc), insn);
5195                   set_variable_part (out, val, dv_from_decl (var), 0,
5196                                      VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
5197                                      INSERT);
5198                 }
5199             }
5200             break;
5201
5202           case MO_VAL_USE:
5203             {
5204               rtx loc = VTI (bb)->mos[i].u.loc;
5205               rtx val, vloc, uloc;
5206
5207               vloc = uloc = XEXP (loc, 1);
5208               val = XEXP (loc, 0);
5209
5210               if (GET_CODE (val) == CONCAT)
5211                 {
5212                   uloc = XEXP (val, 1);
5213                   val = XEXP (val, 0);
5214                 }
5215
5216               if (VAL_NEEDS_RESOLUTION (loc))
5217                 val_resolve (out, val, vloc, insn);
5218
5219               if (VAL_HOLDS_TRACK_EXPR (loc))
5220                 {
5221                   if (GET_CODE (uloc) == REG)
5222                     var_reg_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
5223                                  NULL);
5224                   else if (GET_CODE (uloc) == MEM)
5225                     var_mem_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
5226                                  NULL);
5227                 }
5228             }
5229             break;
5230
5231           case MO_VAL_SET:
5232             {
5233               rtx loc = VTI (bb)->mos[i].u.loc;
5234               rtx val, vloc, uloc;
5235
5236               vloc = uloc = XEXP (loc, 1);
5237               val = XEXP (loc, 0);
5238
5239               if (GET_CODE (val) == CONCAT)
5240                 {
5241                   vloc = XEXP (val, 1);
5242                   val = XEXP (val, 0);
5243                 }
5244
5245               if (GET_CODE (vloc) == SET)
5246                 {
5247                   rtx vsrc = SET_SRC (vloc);
5248
5249                   gcc_assert (val != vsrc);
5250                   gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
5251
5252                   vloc = SET_DEST (vloc);
5253
5254                   if (VAL_NEEDS_RESOLUTION (loc))
5255                     val_resolve (out, val, vsrc, insn);
5256                 }
5257               else if (VAL_NEEDS_RESOLUTION (loc))
5258                 {
5259                   gcc_assert (GET_CODE (uloc) == SET
5260                               && GET_CODE (SET_SRC (uloc)) == REG);
5261                   val_resolve (out, val, SET_SRC (uloc), insn);
5262                 }
5263
5264               if (VAL_HOLDS_TRACK_EXPR (loc))
5265                 {
5266                   if (VAL_EXPR_IS_CLOBBERED (loc))
5267                     {
5268                       if (REG_P (uloc))
5269                         var_reg_delete (out, uloc, true);
5270                       else if (MEM_P (uloc))
5271                         var_mem_delete (out, uloc, true);
5272                     }
5273                   else
5274                     {
5275                       bool copied_p = VAL_EXPR_IS_COPIED (loc);
5276                       rtx set_src = NULL;
5277                       enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
5278
5279                       if (GET_CODE (uloc) == SET)
5280                         {
5281                           set_src = SET_SRC (uloc);
5282                           uloc = SET_DEST (uloc);
5283                         }
5284
5285                       if (copied_p)
5286                         {
5287                           if (flag_var_tracking_uninit)
5288                             {
5289                               status = find_src_status (in, set_src);
5290
5291                               if (status == VAR_INIT_STATUS_UNKNOWN)
5292                                 status = find_src_status (out, set_src);
5293                             }
5294
5295                           set_src = find_src_set_src (in, set_src);
5296                         }
5297
5298                       if (REG_P (uloc))
5299                         var_reg_delete_and_set (out, uloc, !copied_p,
5300                                                 status, set_src);
5301                       else if (MEM_P (uloc))
5302                         var_mem_delete_and_set (out, uloc, !copied_p,
5303                                                 status, set_src);
5304                     }
5305                 }
5306               else if (REG_P (uloc))
5307                 var_regno_delete (out, REGNO (uloc));
5308
5309               val_store (out, val, vloc, insn);
5310             }
5311             break;
5312
5313           case MO_SET:
5314             {
5315               rtx loc = VTI (bb)->mos[i].u.loc;
5316               rtx set_src = NULL;
5317
5318               if (GET_CODE (loc) == SET)
5319                 {
5320                   set_src = SET_SRC (loc);
5321                   loc = SET_DEST (loc);
5322                 }
5323
5324               if (REG_P (loc))
5325                 var_reg_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
5326                                         set_src);
5327               else if (MEM_P (loc))
5328                 var_mem_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
5329                                         set_src);
5330             }
5331             break;
5332
5333           case MO_COPY:
5334             {
5335               rtx loc = VTI (bb)->mos[i].u.loc;
5336               enum var_init_status src_status;
5337               rtx set_src = NULL;
5338
5339               if (GET_CODE (loc) == SET)
5340                 {
5341                   set_src = SET_SRC (loc);
5342                   loc = SET_DEST (loc);
5343                 }
5344
5345               if (! flag_var_tracking_uninit)
5346                 src_status = VAR_INIT_STATUS_INITIALIZED;
5347               else
5348                 {
5349                   src_status = find_src_status (in, set_src);
5350
5351                   if (src_status == VAR_INIT_STATUS_UNKNOWN)
5352                     src_status = find_src_status (out, set_src);
5353                 }
5354
5355               set_src = find_src_set_src (in, set_src);
5356
5357               if (REG_P (loc))
5358                 var_reg_delete_and_set (out, loc, false, src_status, set_src);
5359               else if (MEM_P (loc))
5360                 var_mem_delete_and_set (out, loc, false, src_status, set_src);
5361             }
5362             break;
5363
5364           case MO_USE_NO_VAR:
5365             {
5366               rtx loc = VTI (bb)->mos[i].u.loc;
5367
5368               if (REG_P (loc))
5369                 var_reg_delete (out, loc, false);
5370               else if (MEM_P (loc))
5371                 var_mem_delete (out, loc, false);
5372             }
5373             break;
5374
5375           case MO_CLOBBER:
5376             {
5377               rtx loc = VTI (bb)->mos[i].u.loc;
5378
5379               if (REG_P (loc))
5380                 var_reg_delete (out, loc, true);
5381               else if (MEM_P (loc))
5382                 var_mem_delete (out, loc, true);
5383             }
5384             break;
5385
5386           case MO_ADJUST:
5387             out->stack_adjust += VTI (bb)->mos[i].u.adjust;
5388             break;
5389         }
5390     }
5391
5392   if (MAY_HAVE_DEBUG_INSNS)
5393     {
5394       dataflow_set_equiv_regs (out);
5395       htab_traverse (shared_hash_htab (out->vars), canonicalize_values_mark,
5396                      out);
5397       htab_traverse (shared_hash_htab (out->vars), canonicalize_values_star,
5398                      out);
5399 #if ENABLE_CHECKING
5400       htab_traverse (shared_hash_htab (out->vars),
5401                      canonicalize_loc_order_check, out);
5402 #endif
5403     }
5404   changed = dataflow_set_different (&old_out, out);
5405   dataflow_set_destroy (&old_out);
5406   return changed;
5407 }
5408
5409 /* Find the locations of variables in the whole function.  */
5410
5411 static void
5412 vt_find_locations (void)
5413 {
5414   fibheap_t worklist, pending, fibheap_swap;
5415   sbitmap visited, in_worklist, in_pending, sbitmap_swap;
5416   basic_block bb;
5417   edge e;
5418   int *bb_order;
5419   int *rc_order;
5420   int i;
5421   int htabsz = 0;
5422
5423   /* Compute reverse completion order of depth first search of the CFG
5424      so that the data-flow runs faster.  */
5425   rc_order = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
5426   bb_order = XNEWVEC (int, last_basic_block);
5427   pre_and_rev_post_order_compute (NULL, rc_order, false);
5428   for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
5429     bb_order[rc_order[i]] = i;
5430   free (rc_order);
5431
5432   worklist = fibheap_new ();
5433   pending = fibheap_new ();
5434   visited = sbitmap_alloc (last_basic_block);
5435   in_worklist = sbitmap_alloc (last_basic_block);
5436   in_pending = sbitmap_alloc (last_basic_block);
5437   sbitmap_zero (in_worklist);
5438
5439   FOR_EACH_BB (bb)
5440     fibheap_insert (pending, bb_order[bb->index], bb);
5441   sbitmap_ones (in_pending);
5442
5443   while (!fibheap_empty (pending))
5444     {
5445       fibheap_swap = pending;
5446       pending = worklist;
5447       worklist = fibheap_swap;
5448       sbitmap_swap = in_pending;
5449       in_pending = in_worklist;
5450       in_worklist = sbitmap_swap;
5451
5452       sbitmap_zero (visited);
5453
5454       while (!fibheap_empty (worklist))
5455         {
5456           bb = (basic_block) fibheap_extract_min (worklist);
5457           RESET_BIT (in_worklist, bb->index);
5458           if (!TEST_BIT (visited, bb->index))
5459             {
5460               bool changed;
5461               edge_iterator ei;
5462               int oldinsz, oldoutsz;
5463
5464               SET_BIT (visited, bb->index);
5465
5466               if (dump_file && VTI (bb)->in.vars)
5467                 {
5468                   htabsz
5469                     -= htab_size (shared_hash_htab (VTI (bb)->in.vars))
5470                        + htab_size (shared_hash_htab (VTI (bb)->out.vars));
5471                   oldinsz
5472                     = htab_elements (shared_hash_htab (VTI (bb)->in.vars));
5473                   oldoutsz
5474                     = htab_elements (shared_hash_htab (VTI (bb)->out.vars));
5475                 }
5476               else
5477                 oldinsz = oldoutsz = 0;
5478
5479               if (MAY_HAVE_DEBUG_INSNS)
5480                 {
5481                   dataflow_set *in = &VTI (bb)->in, *first_out = NULL;
5482                   bool first = true, adjust = false;
5483
5484                   /* Calculate the IN set as the intersection of
5485                      predecessor OUT sets.  */
5486
5487                   dataflow_set_clear (in);
5488                   dst_can_be_shared = true;
5489
5490                   FOR_EACH_EDGE (e, ei, bb->preds)
5491                     if (!VTI (e->src)->flooded)
5492                       gcc_assert (bb_order[bb->index]
5493                                   <= bb_order[e->src->index]);
5494                     else if (first)
5495                       {
5496                         dataflow_set_copy (in, &VTI (e->src)->out);
5497                         first_out = &VTI (e->src)->out;
5498                         first = false;
5499                       }
5500                     else
5501                       {
5502                         dataflow_set_merge (in, &VTI (e->src)->out);
5503                         adjust = true;
5504                       }
5505
5506                   if (adjust)
5507                     {
5508                       dataflow_post_merge_adjust (in, &VTI (bb)->permp);
5509 #if ENABLE_CHECKING
5510                       /* Merge and merge_adjust should keep entries in
5511                          canonical order.  */
5512                       htab_traverse (shared_hash_htab (in->vars),
5513                                      canonicalize_loc_order_check,
5514                                      in);
5515 #endif
5516                       if (dst_can_be_shared)
5517                         {
5518                           shared_hash_destroy (in->vars);
5519                           in->vars = shared_hash_copy (first_out->vars);
5520                         }
5521                     }
5522
5523                   VTI (bb)->flooded = true;
5524                 }
5525               else
5526                 {
5527                   /* Calculate the IN set as union of predecessor OUT sets.  */
5528                   dataflow_set_clear (&VTI (bb)->in);
5529                   FOR_EACH_EDGE (e, ei, bb->preds)
5530                     dataflow_set_union (&VTI (bb)->in, &VTI (e->src)->out);
5531                 }
5532
5533               changed = compute_bb_dataflow (bb);
5534               if (dump_file)
5535                 htabsz += htab_size (shared_hash_htab (VTI (bb)->in.vars))
5536                           + htab_size (shared_hash_htab (VTI (bb)->out.vars));
5537
5538               if (changed)
5539                 {
5540                   FOR_EACH_EDGE (e, ei, bb->succs)
5541                     {
5542                       if (e->dest == EXIT_BLOCK_PTR)
5543                         continue;
5544
5545                       if (TEST_BIT (visited, e->dest->index))
5546                         {
5547                           if (!TEST_BIT (in_pending, e->dest->index))
5548                             {
5549                               /* Send E->DEST to next round.  */
5550                               SET_BIT (in_pending, e->dest->index);
5551                               fibheap_insert (pending,
5552                                               bb_order[e->dest->index],
5553                                               e->dest);
5554                             }
5555                         }
5556                       else if (!TEST_BIT (in_worklist, e->dest->index))
5557                         {
5558                           /* Add E->DEST to current round.  */
5559                           SET_BIT (in_worklist, e->dest->index);
5560                           fibheap_insert (worklist, bb_order[e->dest->index],
5561                                           e->dest);
5562                         }
5563                     }
5564                 }
5565
5566               if (dump_file)
5567                 fprintf (dump_file,
5568                          "BB %i: in %i (was %i), out %i (was %i), rem %i + %i, tsz %i\n",
5569                          bb->index,
5570                          (int)htab_elements (shared_hash_htab (VTI (bb)->in.vars)),
5571                          oldinsz,
5572                          (int)htab_elements (shared_hash_htab (VTI (bb)->out.vars)),
5573                          oldoutsz,
5574                          (int)worklist->nodes, (int)pending->nodes, htabsz);
5575
5576               if (dump_file && (dump_flags & TDF_DETAILS))
5577                 {
5578                   fprintf (dump_file, "BB %i IN:\n", bb->index);
5579                   dump_dataflow_set (&VTI (bb)->in);
5580                   fprintf (dump_file, "BB %i OUT:\n", bb->index);
5581                   dump_dataflow_set (&VTI (bb)->out);
5582                 }
5583             }
5584         }
5585     }
5586
5587   if (MAY_HAVE_DEBUG_INSNS)
5588     FOR_EACH_BB (bb)
5589       gcc_assert (VTI (bb)->flooded);
5590
5591   free (bb_order);
5592   fibheap_delete (worklist);
5593   fibheap_delete (pending);
5594   sbitmap_free (visited);
5595   sbitmap_free (in_worklist);
5596   sbitmap_free (in_pending);
5597 }
5598
5599 /* Print the content of the LIST to dump file.  */
5600
5601 static void
5602 dump_attrs_list (attrs list)
5603 {
5604   for (; list; list = list->next)
5605     {
5606       if (dv_is_decl_p (list->dv))
5607         print_mem_expr (dump_file, dv_as_decl (list->dv));
5608       else
5609         print_rtl_single (dump_file, dv_as_value (list->dv));
5610       fprintf (dump_file, "+" HOST_WIDE_INT_PRINT_DEC, list->offset);
5611     }
5612   fprintf (dump_file, "\n");
5613 }
5614
5615 /* Print the information about variable *SLOT to dump file.  */
5616
5617 static int
5618 dump_variable_slot (void **slot, void *data ATTRIBUTE_UNUSED)
5619 {
5620   variable var = (variable) *slot;
5621
5622   dump_variable (var);
5623
5624   /* Continue traversing the hash table.  */
5625   return 1;
5626 }
5627
5628 /* Print the information about variable VAR to dump file.  */
5629
5630 static void
5631 dump_variable (variable var)
5632 {
5633   int i;
5634   location_chain node;
5635
5636   if (dv_is_decl_p (var->dv))
5637     {
5638       const_tree decl = dv_as_decl (var->dv);
5639
5640       if (DECL_NAME (decl))
5641         fprintf (dump_file, "  name: %s",
5642                  IDENTIFIER_POINTER (DECL_NAME (decl)));
5643       else
5644         fprintf (dump_file, "  name: D.%u", DECL_UID (decl));
5645       if (dump_flags & TDF_UID)
5646         fprintf (dump_file, " D.%u\n", DECL_UID (decl));
5647       else
5648         fprintf (dump_file, "\n");
5649     }
5650   else
5651     {
5652       fputc (' ', dump_file);
5653       print_rtl_single (dump_file, dv_as_value (var->dv));
5654     }
5655
5656   for (i = 0; i < var->n_var_parts; i++)
5657     {
5658       fprintf (dump_file, "    offset %ld\n",
5659                (long) var->var_part[i].offset);
5660       for (node = var->var_part[i].loc_chain; node; node = node->next)
5661         {
5662           fprintf (dump_file, "      ");
5663           if (node->init == VAR_INIT_STATUS_UNINITIALIZED)
5664             fprintf (dump_file, "[uninit]");
5665           print_rtl_single (dump_file, node->loc);
5666         }
5667     }
5668 }
5669
5670 /* Print the information about variables from hash table VARS to dump file.  */
5671
5672 static void
5673 dump_vars (htab_t vars)
5674 {
5675   if (htab_elements (vars) > 0)
5676     {
5677       fprintf (dump_file, "Variables:\n");
5678       htab_traverse (vars, dump_variable_slot, NULL);
5679     }
5680 }
5681
5682 /* Print the dataflow set SET to dump file.  */
5683
5684 static void
5685 dump_dataflow_set (dataflow_set *set)
5686 {
5687   int i;
5688
5689   fprintf (dump_file, "Stack adjustment: " HOST_WIDE_INT_PRINT_DEC "\n",
5690            set->stack_adjust);
5691   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
5692     {
5693       if (set->regs[i])
5694         {
5695           fprintf (dump_file, "Reg %d:", i);
5696           dump_attrs_list (set->regs[i]);
5697         }
5698     }
5699   dump_vars (shared_hash_htab (set->vars));
5700   fprintf (dump_file, "\n");
5701 }
5702
5703 /* Print the IN and OUT sets for each basic block to dump file.  */
5704
5705 static void
5706 dump_dataflow_sets (void)
5707 {
5708   basic_block bb;
5709
5710   FOR_EACH_BB (bb)
5711     {
5712       fprintf (dump_file, "\nBasic block %d:\n", bb->index);
5713       fprintf (dump_file, "IN:\n");
5714       dump_dataflow_set (&VTI (bb)->in);
5715       fprintf (dump_file, "OUT:\n");
5716       dump_dataflow_set (&VTI (bb)->out);
5717     }
5718 }
5719
5720 /* Add variable VAR to the hash table of changed variables and
5721    if it has no locations delete it from SET's hash table.  */
5722
5723 static void
5724 variable_was_changed (variable var, dataflow_set *set)
5725 {
5726   hashval_t hash = dv_htab_hash (var->dv);
5727
5728   if (emit_notes)
5729     {
5730       void **slot;
5731
5732       /* Remember this decl or VALUE has been added to changed_variables.  */
5733       set_dv_changed (var->dv, true);
5734
5735       slot = htab_find_slot_with_hash (changed_variables,
5736                                        var->dv,
5737                                        hash, INSERT);
5738
5739       if (set && var->n_var_parts == 0)
5740         {
5741           variable empty_var;
5742
5743           empty_var = (variable) pool_alloc (dv_pool (var->dv));
5744           empty_var->dv = var->dv;
5745           empty_var->refcount = 1;
5746           empty_var->n_var_parts = 0;
5747           *slot = empty_var;
5748           goto drop_var;
5749         }
5750       else
5751         {
5752           var->refcount++;
5753           *slot = var;
5754         }
5755     }
5756   else
5757     {
5758       gcc_assert (set);
5759       if (var->n_var_parts == 0)
5760         {
5761           void **slot;
5762
5763         drop_var:
5764           slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
5765           if (slot)
5766             {
5767               if (shared_hash_shared (set->vars))
5768                 slot = shared_hash_find_slot_unshare (&set->vars, var->dv,
5769                                                       NO_INSERT);
5770               htab_clear_slot (shared_hash_htab (set->vars), slot);
5771             }
5772         }
5773     }
5774 }
5775
5776 /* Look for the index in VAR->var_part corresponding to OFFSET.
5777    Return -1 if not found.  If INSERTION_POINT is non-NULL, the
5778    referenced int will be set to the index that the part has or should
5779    have, if it should be inserted.  */
5780
5781 static inline int
5782 find_variable_location_part (variable var, HOST_WIDE_INT offset,
5783                              int *insertion_point)
5784 {
5785   int pos, low, high;
5786
5787   /* Find the location part.  */
5788   low = 0;
5789   high = var->n_var_parts;
5790   while (low != high)
5791     {
5792       pos = (low + high) / 2;
5793       if (var->var_part[pos].offset < offset)
5794         low = pos + 1;
5795       else
5796         high = pos;
5797     }
5798   pos = low;
5799
5800   if (insertion_point)
5801     *insertion_point = pos;
5802
5803   if (pos < var->n_var_parts && var->var_part[pos].offset == offset)
5804     return pos;
5805
5806   return -1;
5807 }
5808
5809 static void **
5810 set_slot_part (dataflow_set *set, rtx loc, void **slot,
5811                decl_or_value dv, HOST_WIDE_INT offset,
5812                enum var_init_status initialized, rtx set_src)
5813 {
5814   int pos;
5815   location_chain node, next;
5816   location_chain *nextp;
5817   variable var;
5818   bool onepart = dv_onepart_p (dv);
5819
5820   gcc_assert (offset == 0 || !onepart);
5821   gcc_assert (loc != dv_as_opaque (dv));
5822
5823   var = (variable) *slot;
5824
5825   if (! flag_var_tracking_uninit)
5826     initialized = VAR_INIT_STATUS_INITIALIZED;
5827
5828   if (!var)
5829     {
5830       /* Create new variable information.  */
5831       var = (variable) pool_alloc (dv_pool (dv));
5832       var->dv = dv;
5833       var->refcount = 1;
5834       var->n_var_parts = 1;
5835       var->var_part[0].offset = offset;
5836       var->var_part[0].loc_chain = NULL;
5837       var->var_part[0].cur_loc = NULL;
5838       *slot = var;
5839       pos = 0;
5840       nextp = &var->var_part[0].loc_chain;
5841       if (emit_notes && dv_is_value_p (dv))
5842         add_cselib_value_chains (dv);
5843     }
5844   else if (onepart)
5845     {
5846       int r = -1, c = 0;
5847
5848       gcc_assert (dv_as_opaque (var->dv) == dv_as_opaque (dv));
5849
5850       pos = 0;
5851
5852       if (GET_CODE (loc) == VALUE)
5853         {
5854           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
5855                nextp = &node->next)
5856             if (GET_CODE (node->loc) == VALUE)
5857               {
5858                 if (node->loc == loc)
5859                   {
5860                     r = 0;
5861                     break;
5862                   }
5863                 if (canon_value_cmp (node->loc, loc))
5864                   c++;
5865                 else
5866                   {
5867                     r = 1;
5868                     break;
5869                   }
5870               }
5871             else if (REG_P (node->loc) || MEM_P (node->loc))
5872               c++;
5873             else
5874               {
5875                 r = 1;
5876                 break;
5877               }
5878         }
5879       else if (REG_P (loc))
5880         {
5881           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
5882                nextp = &node->next)
5883             if (REG_P (node->loc))
5884               {
5885                 if (REGNO (node->loc) < REGNO (loc))
5886                   c++;
5887                 else
5888                   {
5889                     if (REGNO (node->loc) == REGNO (loc))
5890                       r = 0;
5891                     else
5892                       r = 1;
5893                     break;
5894                   }
5895               }
5896             else
5897               {
5898                 r = 1;
5899                 break;
5900               }
5901         }
5902       else if (MEM_P (loc))
5903         {
5904           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
5905                nextp = &node->next)
5906             if (REG_P (node->loc))
5907               c++;
5908             else if (MEM_P (node->loc))
5909               {
5910                 if ((r = loc_cmp (XEXP (node->loc, 0), XEXP (loc, 0))) >= 0)
5911                   break;
5912                 else
5913                   c++;
5914               }
5915             else
5916               {
5917                 r = 1;
5918                 break;
5919               }
5920         }
5921       else
5922         for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
5923              nextp = &node->next)
5924           if ((r = loc_cmp (node->loc, loc)) >= 0)
5925             break;
5926           else
5927             c++;
5928
5929       if (r == 0)
5930         return slot;
5931
5932       if (var->refcount > 1 || shared_hash_shared (set->vars))
5933         {
5934           slot = unshare_variable (set, slot, var, initialized);
5935           var = (variable)*slot;
5936           for (nextp = &var->var_part[0].loc_chain; c;
5937                nextp = &(*nextp)->next)
5938             c--;
5939           gcc_assert ((!node && !*nextp) || node->loc == (*nextp)->loc);
5940         }
5941     }
5942   else
5943     {
5944       int inspos = 0;
5945
5946       gcc_assert (dv_as_decl (var->dv) == dv_as_decl (dv));
5947
5948       pos = find_variable_location_part (var, offset, &inspos);
5949
5950       if (pos >= 0)
5951         {
5952           node = var->var_part[pos].loc_chain;
5953
5954           if (node
5955               && ((REG_P (node->loc) && REG_P (loc)
5956                    && REGNO (node->loc) == REGNO (loc))
5957                   || rtx_equal_p (node->loc, loc)))
5958             {
5959               /* LOC is in the beginning of the chain so we have nothing
5960                  to do.  */
5961               if (node->init < initialized)
5962                 node->init = initialized;
5963               if (set_src != NULL)
5964                 node->set_src = set_src;
5965
5966               return slot;
5967             }
5968           else
5969             {
5970               /* We have to make a copy of a shared variable.  */
5971               if (var->refcount > 1 || shared_hash_shared (set->vars))
5972                 {
5973                   slot = unshare_variable (set, slot, var, initialized);
5974                   var = (variable)*slot;
5975                 }
5976             }
5977         }
5978       else
5979         {
5980           /* We have not found the location part, new one will be created.  */
5981
5982           /* We have to make a copy of the shared variable.  */
5983           if (var->refcount > 1 || shared_hash_shared (set->vars))
5984             {
5985               slot = unshare_variable (set, slot, var, initialized);
5986               var = (variable)*slot;
5987             }
5988
5989           /* We track only variables whose size is <= MAX_VAR_PARTS bytes
5990              thus there are at most MAX_VAR_PARTS different offsets.  */
5991           gcc_assert (var->n_var_parts < MAX_VAR_PARTS
5992                       && (!var->n_var_parts || !dv_onepart_p (var->dv)));
5993
5994           /* We have to move the elements of array starting at index
5995              inspos to the next position.  */
5996           for (pos = var->n_var_parts; pos > inspos; pos--)
5997             var->var_part[pos] = var->var_part[pos - 1];
5998
5999           var->n_var_parts++;
6000           var->var_part[pos].offset = offset;
6001           var->var_part[pos].loc_chain = NULL;
6002           var->var_part[pos].cur_loc = NULL;
6003         }
6004
6005       /* Delete the location from the list.  */
6006       nextp = &var->var_part[pos].loc_chain;
6007       for (node = var->var_part[pos].loc_chain; node; node = next)
6008         {
6009           next = node->next;
6010           if ((REG_P (node->loc) && REG_P (loc)
6011                && REGNO (node->loc) == REGNO (loc))
6012               || rtx_equal_p (node->loc, loc))
6013             {
6014               /* Save these values, to assign to the new node, before
6015                  deleting this one.  */
6016               if (node->init > initialized)
6017                 initialized = node->init;
6018               if (node->set_src != NULL && set_src == NULL)
6019                 set_src = node->set_src;
6020               pool_free (loc_chain_pool, node);
6021               *nextp = next;
6022               break;
6023             }
6024           else
6025             nextp = &node->next;
6026         }
6027
6028       nextp = &var->var_part[pos].loc_chain;
6029     }
6030
6031   /* Add the location to the beginning.  */
6032   node = (location_chain) pool_alloc (loc_chain_pool);
6033   node->loc = loc;
6034   node->init = initialized;
6035   node->set_src = set_src;
6036   node->next = *nextp;
6037   *nextp = node;
6038
6039   if (onepart && emit_notes)
6040     add_value_chains (var->dv, loc);
6041
6042   /* If no location was emitted do so.  */
6043   if (var->var_part[pos].cur_loc == NULL)
6044     {
6045       var->var_part[pos].cur_loc = loc;
6046       variable_was_changed (var, set);
6047     }
6048
6049   return slot;
6050 }
6051
6052 /* Set the part of variable's location in the dataflow set SET.  The
6053    variable part is specified by variable's declaration in DV and
6054    offset OFFSET and the part's location by LOC.  IOPT should be
6055    NO_INSERT if the variable is known to be in SET already and the
6056    variable hash table must not be resized, and INSERT otherwise.  */
6057
6058 static void
6059 set_variable_part (dataflow_set *set, rtx loc,
6060                    decl_or_value dv, HOST_WIDE_INT offset,
6061                    enum var_init_status initialized, rtx set_src,
6062                    enum insert_option iopt)
6063 {
6064   void **slot;
6065
6066   if (iopt == NO_INSERT)
6067     slot = shared_hash_find_slot_noinsert (set->vars, dv);
6068   else
6069     {
6070       slot = shared_hash_find_slot (set->vars, dv);
6071       if (!slot)
6072         slot = shared_hash_find_slot_unshare (&set->vars, dv, iopt);
6073     }
6074   slot = set_slot_part (set, loc, slot, dv, offset, initialized, set_src);
6075 }
6076
6077 /* Remove all recorded register locations for the given variable part
6078    from dataflow set SET, except for those that are identical to loc.
6079    The variable part is specified by variable's declaration or value
6080    DV and offset OFFSET.  */
6081
6082 static void **
6083 clobber_slot_part (dataflow_set *set, rtx loc, void **slot,
6084                    HOST_WIDE_INT offset, rtx set_src)
6085 {
6086   variable var = (variable) *slot;
6087   int pos = find_variable_location_part (var, offset, NULL);
6088
6089   if (pos >= 0)
6090     {
6091       location_chain node, next;
6092
6093       /* Remove the register locations from the dataflow set.  */
6094       next = var->var_part[pos].loc_chain;
6095       for (node = next; node; node = next)
6096         {
6097           next = node->next;
6098           if (node->loc != loc
6099               && (!flag_var_tracking_uninit
6100                   || !set_src
6101                   || MEM_P (set_src)
6102                   || !rtx_equal_p (set_src, node->set_src)))
6103             {
6104               if (REG_P (node->loc))
6105                 {
6106                   attrs anode, anext;
6107                   attrs *anextp;
6108
6109                   /* Remove the variable part from the register's
6110                      list, but preserve any other variable parts
6111                      that might be regarded as live in that same
6112                      register.  */
6113                   anextp = &set->regs[REGNO (node->loc)];
6114                   for (anode = *anextp; anode; anode = anext)
6115                     {
6116                       anext = anode->next;
6117                       if (dv_as_opaque (anode->dv) == dv_as_opaque (var->dv)
6118                           && anode->offset == offset)
6119                         {
6120                           pool_free (attrs_pool, anode);
6121                           *anextp = anext;
6122                         }
6123                       else
6124                         anextp = &anode->next;
6125                     }
6126                 }
6127
6128               slot = delete_slot_part (set, node->loc, slot, offset);
6129             }
6130         }
6131     }
6132
6133   return slot;
6134 }
6135
6136 /* Remove all recorded register locations for the given variable part
6137    from dataflow set SET, except for those that are identical to loc.
6138    The variable part is specified by variable's declaration or value
6139    DV and offset OFFSET.  */
6140
6141 static void
6142 clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
6143                        HOST_WIDE_INT offset, rtx set_src)
6144 {
6145   void **slot;
6146
6147   if (!dv_as_opaque (dv)
6148       || (!dv_is_value_p (dv) && ! DECL_P (dv_as_decl (dv))))
6149     return;
6150
6151   slot = shared_hash_find_slot_noinsert (set->vars, dv);
6152   if (!slot)
6153     return;
6154
6155   slot = clobber_slot_part (set, loc, slot, offset, set_src);
6156 }
6157
6158 /* Delete the part of variable's location from dataflow set SET.  The
6159    variable part is specified by its SET->vars slot SLOT and offset
6160    OFFSET and the part's location by LOC.  */
6161
6162 static void **
6163 delete_slot_part (dataflow_set *set, rtx loc, void **slot,
6164                   HOST_WIDE_INT offset)
6165 {
6166   variable var = (variable) *slot;
6167   int pos = find_variable_location_part (var, offset, NULL);
6168
6169   if (pos >= 0)
6170     {
6171       location_chain node, next;
6172       location_chain *nextp;
6173       bool changed;
6174
6175       if (var->refcount > 1 || shared_hash_shared (set->vars))
6176         {
6177           /* If the variable contains the location part we have to
6178              make a copy of the variable.  */
6179           for (node = var->var_part[pos].loc_chain; node;
6180                node = node->next)
6181             {
6182               if ((REG_P (node->loc) && REG_P (loc)
6183                    && REGNO (node->loc) == REGNO (loc))
6184                   || rtx_equal_p (node->loc, loc))
6185                 {
6186                   slot = unshare_variable (set, slot, var,
6187                                            VAR_INIT_STATUS_UNKNOWN);
6188                   var = (variable)*slot;
6189                   break;
6190                 }
6191             }
6192         }
6193
6194       /* Delete the location part.  */
6195       nextp = &var->var_part[pos].loc_chain;
6196       for (node = *nextp; node; node = next)
6197         {
6198           next = node->next;
6199           if ((REG_P (node->loc) && REG_P (loc)
6200                && REGNO (node->loc) == REGNO (loc))
6201               || rtx_equal_p (node->loc, loc))
6202             {
6203               if (emit_notes && pos == 0 && dv_onepart_p (var->dv))
6204                 remove_value_chains (var->dv, node->loc);
6205               pool_free (loc_chain_pool, node);
6206               *nextp = next;
6207               break;
6208             }
6209           else
6210             nextp = &node->next;
6211         }
6212
6213       /* If we have deleted the location which was last emitted
6214          we have to emit new location so add the variable to set
6215          of changed variables.  */
6216       if (var->var_part[pos].cur_loc
6217           && ((REG_P (loc)
6218                && REG_P (var->var_part[pos].cur_loc)
6219                && REGNO (loc) == REGNO (var->var_part[pos].cur_loc))
6220               || rtx_equal_p (loc, var->var_part[pos].cur_loc)))
6221         {
6222           changed = true;
6223           if (var->var_part[pos].loc_chain)
6224             var->var_part[pos].cur_loc = var->var_part[pos].loc_chain->loc;
6225         }
6226       else
6227         changed = false;
6228
6229       if (var->var_part[pos].loc_chain == NULL)
6230         {
6231           gcc_assert (changed);
6232           var->n_var_parts--;
6233           if (emit_notes && var->n_var_parts == 0 && dv_is_value_p (var->dv))
6234             remove_cselib_value_chains (var->dv);
6235           while (pos < var->n_var_parts)
6236             {
6237               var->var_part[pos] = var->var_part[pos + 1];
6238               pos++;
6239             }
6240         }
6241       if (changed)
6242         variable_was_changed (var, set);
6243     }
6244
6245   return slot;
6246 }
6247
6248 /* Delete the part of variable's location from dataflow set SET.  The
6249    variable part is specified by variable's declaration or value DV
6250    and offset OFFSET and the part's location by LOC.  */
6251
6252 static void
6253 delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
6254                       HOST_WIDE_INT offset)
6255 {
6256   void **slot = shared_hash_find_slot_noinsert (set->vars, dv);
6257   if (!slot)
6258     return;
6259
6260   slot = delete_slot_part (set, loc, slot, offset);
6261 }
6262
6263 /* Callback for cselib_expand_value, that looks for expressions
6264    holding the value in the var-tracking hash tables.  Return X for
6265    standard processing, anything else is to be used as-is.  */
6266
6267 static rtx
6268 vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data)
6269 {
6270   htab_t vars = (htab_t)data;
6271   decl_or_value dv;
6272   variable var;
6273   location_chain loc;
6274   rtx result, subreg, xret;
6275
6276   switch (GET_CODE (x))
6277     {
6278     case SUBREG:
6279       subreg = SUBREG_REG (x);
6280
6281       if (GET_CODE (SUBREG_REG (x)) != VALUE)
6282         return x;
6283
6284       subreg = cselib_expand_value_rtx_cb (SUBREG_REG (x), regs,
6285                                            max_depth - 1,
6286                                            vt_expand_loc_callback, data);
6287
6288       if (!subreg)
6289         return NULL;
6290
6291       result = simplify_gen_subreg (GET_MODE (x), subreg,
6292                                     GET_MODE (SUBREG_REG (x)),
6293                                     SUBREG_BYTE (x));
6294
6295       /* Invalid SUBREGs are ok in debug info.  ??? We could try
6296          alternate expansions for the VALUE as well.  */
6297       if (!result && (REG_P (subreg) || MEM_P (subreg)))
6298         result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));
6299
6300       return result;
6301
6302     case DEBUG_EXPR:
6303       dv = dv_from_decl (DEBUG_EXPR_TREE_DECL (x));
6304       xret = NULL;
6305       break;
6306
6307     case VALUE:
6308       dv = dv_from_value (x);
6309       xret = x;
6310       break;
6311
6312     default:
6313       return x;
6314     }
6315
6316   if (VALUE_RECURSED_INTO (x))
6317     return NULL;
6318
6319   var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
6320
6321   if (!var)
6322     return xret;
6323
6324   if (var->n_var_parts == 0)
6325     return xret;
6326
6327   gcc_assert (var->n_var_parts == 1);
6328
6329   VALUE_RECURSED_INTO (x) = true;
6330   result = NULL;
6331
6332   for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
6333     {
6334       result = cselib_expand_value_rtx_cb (loc->loc, regs, max_depth,
6335                                            vt_expand_loc_callback, vars);
6336       if (result)
6337         break;
6338     }
6339
6340   VALUE_RECURSED_INTO (x) = false;
6341   if (result)
6342     return result;
6343   else
6344     return xret;
6345 }
6346
6347 /* Expand VALUEs in LOC, using VARS as well as cselib's equivalence
6348    tables.  */
6349
6350 static rtx
6351 vt_expand_loc (rtx loc, htab_t vars)
6352 {
6353   if (!MAY_HAVE_DEBUG_INSNS)
6354     return loc;
6355
6356   loc = cselib_expand_value_rtx_cb (loc, scratch_regs, 5,
6357                                     vt_expand_loc_callback, vars);
6358
6359   if (loc && MEM_P (loc))
6360     loc = targetm.delegitimize_address (loc);
6361
6362   return loc;
6363 }
6364
6365 /* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP.  DATA contains
6366    additional parameters: WHERE specifies whether the note shall be emitted
6367    before or after instruction INSN.  */
6368
6369 static int
6370 emit_note_insn_var_location (void **varp, void *data)
6371 {
6372   variable var = (variable) *varp;
6373   rtx insn = ((emit_note_data *)data)->insn;
6374   enum emit_note_where where = ((emit_note_data *)data)->where;
6375   htab_t vars = ((emit_note_data *)data)->vars;
6376   rtx note;
6377   int i, j, n_var_parts;
6378   bool complete;
6379   enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED;
6380   HOST_WIDE_INT last_limit;
6381   tree type_size_unit;
6382   HOST_WIDE_INT offsets[MAX_VAR_PARTS];
6383   rtx loc[MAX_VAR_PARTS];
6384   tree decl;
6385
6386   if (dv_is_value_p (var->dv))
6387     goto clear;
6388
6389   decl = dv_as_decl (var->dv);
6390
6391   if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
6392     goto clear;
6393
6394   gcc_assert (decl);
6395
6396   complete = true;
6397   last_limit = 0;
6398   n_var_parts = 0;
6399   for (i = 0; i < var->n_var_parts; i++)
6400     {
6401       enum machine_mode mode, wider_mode;
6402       rtx loc2;
6403
6404       if (last_limit < var->var_part[i].offset)
6405         {
6406           complete = false;
6407           break;
6408         }
6409       else if (last_limit > var->var_part[i].offset)
6410         continue;
6411       offsets[n_var_parts] = var->var_part[i].offset;
6412       loc2 = vt_expand_loc (var->var_part[i].loc_chain->loc, vars);
6413       if (!loc2)
6414         {
6415           complete = false;
6416           continue;
6417         }
6418       loc[n_var_parts] = loc2;
6419       mode = GET_MODE (var->var_part[i].loc_chain->loc);
6420       initialized = var->var_part[i].loc_chain->init;
6421       last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
6422
6423       /* Attempt to merge adjacent registers or memory.  */
6424       wider_mode = GET_MODE_WIDER_MODE (mode);
6425       for (j = i + 1; j < var->n_var_parts; j++)
6426         if (last_limit <= var->var_part[j].offset)
6427           break;
6428       if (j < var->n_var_parts
6429           && wider_mode != VOIDmode
6430           && mode == GET_MODE (var->var_part[j].loc_chain->loc)
6431           && (REG_P (loc[n_var_parts]) || MEM_P (loc[n_var_parts]))
6432           && (loc2 = vt_expand_loc (var->var_part[j].loc_chain->loc, vars))
6433           && GET_CODE (loc[n_var_parts]) == GET_CODE (loc2)
6434           && last_limit == var->var_part[j].offset)
6435         {
6436           rtx new_loc = NULL;
6437
6438           if (REG_P (loc[n_var_parts])
6439               && hard_regno_nregs[REGNO (loc[n_var_parts])][mode] * 2
6440                  == hard_regno_nregs[REGNO (loc[n_var_parts])][wider_mode]
6441               && end_hard_regno (mode, REGNO (loc[n_var_parts]))
6442                  == REGNO (loc2))
6443             {
6444               if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
6445                 new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
6446                                            mode, 0);
6447               else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
6448                 new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
6449               if (new_loc)
6450                 {
6451                   if (!REG_P (new_loc)
6452                       || REGNO (new_loc) != REGNO (loc[n_var_parts]))
6453                     new_loc = NULL;
6454                   else
6455                     REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
6456                 }
6457             }
6458           else if (MEM_P (loc[n_var_parts])
6459                    && GET_CODE (XEXP (loc2, 0)) == PLUS
6460                    && REG_P (XEXP (XEXP (loc2, 0), 0))
6461                    && CONST_INT_P (XEXP (XEXP (loc2, 0), 1)))
6462             {
6463               if ((REG_P (XEXP (loc[n_var_parts], 0))
6464                    && rtx_equal_p (XEXP (loc[n_var_parts], 0),
6465                                    XEXP (XEXP (loc2, 0), 0))
6466                    && INTVAL (XEXP (XEXP (loc2, 0), 1))
6467                       == GET_MODE_SIZE (mode))
6468                   || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
6469                       && CONST_INT_P (XEXP (XEXP (loc[n_var_parts], 0), 1))
6470                       && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
6471                                       XEXP (XEXP (loc2, 0), 0))
6472                       && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
6473                          + GET_MODE_SIZE (mode)
6474                          == INTVAL (XEXP (XEXP (loc2, 0), 1))))
6475                 new_loc = adjust_address_nv (loc[n_var_parts],
6476                                              wider_mode, 0);
6477             }
6478
6479           if (new_loc)
6480             {
6481               loc[n_var_parts] = new_loc;
6482               mode = wider_mode;
6483               last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
6484               i = j;
6485             }
6486         }
6487       ++n_var_parts;
6488     }
6489   type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl));
6490   if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
6491     complete = false;
6492
6493   if (where != EMIT_NOTE_BEFORE_INSN)
6494     {
6495       note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
6496       if (where == EMIT_NOTE_AFTER_CALL_INSN)
6497         NOTE_DURING_CALL_P (note) = true;
6498     }
6499   else
6500     note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
6501
6502   if (! flag_var_tracking_uninit)
6503     initialized = VAR_INIT_STATUS_INITIALIZED;
6504
6505   if (!complete)
6506     {
6507       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, decl,
6508                                                        NULL_RTX, (int) initialized);
6509     }
6510   else if (n_var_parts == 1)
6511     {
6512       rtx expr_list
6513         = gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
6514
6515       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, decl,
6516                                                        expr_list,
6517                                                        (int) initialized);
6518     }
6519   else if (n_var_parts)
6520     {
6521       rtx parallel;
6522
6523       for (i = 0; i < n_var_parts; i++)
6524         loc[i]
6525           = gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));
6526
6527       parallel = gen_rtx_PARALLEL (VOIDmode,
6528                                    gen_rtvec_v (n_var_parts, loc));
6529       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, decl,
6530                                                        parallel,
6531                                                        (int) initialized);
6532     }
6533
6534  clear:
6535   set_dv_changed (var->dv, false);
6536   htab_clear_slot (changed_variables, varp);
6537
6538   /* Continue traversing the hash table.  */
6539   return 1;
6540 }
6541
6542 DEF_VEC_P (variable);
6543 DEF_VEC_ALLOC_P (variable, heap);
6544
6545 /* Stack of variable_def pointers that need processing with
6546    check_changed_vars_2.  */
6547
6548 static VEC (variable, heap) *changed_variables_stack;
6549
6550 /* Populate changed_variables_stack with variable_def pointers
6551    that need variable_was_changed called on them.  */
6552
6553 static int
6554 check_changed_vars_1 (void **slot, void *data)
6555 {
6556   variable var = (variable) *slot;
6557   htab_t htab = (htab_t) data;
6558
6559   if (dv_is_value_p (var->dv))
6560     {
6561       value_chain vc
6562         = (value_chain) htab_find_with_hash (value_chains, var->dv,
6563                                              dv_htab_hash (var->dv));
6564
6565       if (vc == NULL)
6566         return 1;
6567       for (vc = vc->next; vc; vc = vc->next)
6568         if (!dv_changed_p (vc->dv))
6569           {
6570             variable vcvar
6571               = (variable) htab_find_with_hash (htab, vc->dv,
6572                                                 dv_htab_hash (vc->dv));
6573             if (vcvar)
6574               VEC_safe_push (variable, heap, changed_variables_stack,
6575                              vcvar);
6576           }
6577     }
6578   return 1;
6579 }
6580
6581 /* Add VAR to changed_variables and also for VALUEs add recursively
6582    all DVs that aren't in changed_variables yet but reference the
6583    VALUE from its loc_chain.  */
6584
6585 static void
6586 check_changed_vars_2 (variable var, htab_t htab)
6587 {
6588   variable_was_changed (var, NULL);
6589   if (dv_is_value_p (var->dv))
6590     {
6591       value_chain vc
6592         = (value_chain) htab_find_with_hash (value_chains, var->dv,
6593                                              dv_htab_hash (var->dv));
6594
6595       if (vc == NULL)
6596         return;
6597       for (vc = vc->next; vc; vc = vc->next)
6598         if (!dv_changed_p (vc->dv))
6599           {
6600             variable vcvar
6601               = (variable) htab_find_with_hash (htab, vc->dv,
6602                                                 dv_htab_hash (vc->dv));
6603             if (vcvar)
6604               check_changed_vars_2 (vcvar, htab);
6605           }
6606     }
6607 }
6608
6609 /* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
6610    CHANGED_VARIABLES and delete this chain.  WHERE specifies whether the notes
6611    shall be emitted before of after instruction INSN.  */
6612
6613 static void
6614 emit_notes_for_changes (rtx insn, enum emit_note_where where,
6615                         shared_hash vars)
6616 {
6617   emit_note_data data;
6618   htab_t htab = shared_hash_htab (vars);
6619
6620   if (!htab_elements (changed_variables))
6621     return;
6622
6623   if (MAY_HAVE_DEBUG_INSNS)
6624     {
6625       /* Unfortunately this has to be done in two steps, because
6626          we can't traverse a hashtab into which we are inserting
6627          through variable_was_changed.  */
6628       htab_traverse (changed_variables, check_changed_vars_1, htab);
6629       while (VEC_length (variable, changed_variables_stack) > 0)
6630         check_changed_vars_2 (VEC_pop (variable, changed_variables_stack),
6631                               htab);
6632     }
6633
6634   data.insn = insn;
6635   data.where = where;
6636   data.vars = htab;
6637
6638   htab_traverse (changed_variables, emit_note_insn_var_location, &data);
6639 }
6640
6641 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
6642    same variable in hash table DATA or is not there at all.  */
6643
6644 static int
6645 emit_notes_for_differences_1 (void **slot, void *data)
6646 {
6647   htab_t new_vars = (htab_t) data;
6648   variable old_var, new_var;
6649
6650   old_var = (variable) *slot;
6651   new_var = (variable) htab_find_with_hash (new_vars, old_var->dv,
6652                                             dv_htab_hash (old_var->dv));
6653
6654   if (!new_var)
6655     {
6656       /* Variable has disappeared.  */
6657       variable empty_var;
6658
6659       empty_var = (variable) pool_alloc (dv_pool (old_var->dv));
6660       empty_var->dv = old_var->dv;
6661       empty_var->refcount = 0;
6662       empty_var->n_var_parts = 0;
6663       if (dv_onepart_p (old_var->dv))
6664         {
6665           location_chain lc;
6666
6667           gcc_assert (old_var->n_var_parts == 1);
6668           for (lc = old_var->var_part[0].loc_chain; lc; lc = lc->next)
6669             remove_value_chains (old_var->dv, lc->loc);
6670           if (dv_is_value_p (old_var->dv))
6671             remove_cselib_value_chains (old_var->dv);
6672         }
6673       variable_was_changed (empty_var, NULL);
6674     }
6675   else if (variable_different_p (old_var, new_var, true))
6676     {
6677       if (dv_onepart_p (old_var->dv))
6678         {
6679           location_chain lc1, lc2;
6680
6681           gcc_assert (old_var->n_var_parts == 1);
6682           gcc_assert (new_var->n_var_parts == 1);
6683           lc1 = old_var->var_part[0].loc_chain;
6684           lc2 = new_var->var_part[0].loc_chain;
6685           while (lc1
6686                  && lc2
6687                  && ((REG_P (lc1->loc) && REG_P (lc2->loc))
6688                      || rtx_equal_p (lc1->loc, lc2->loc)))
6689             {
6690               lc1 = lc1->next;
6691               lc2 = lc2->next;
6692             }
6693           for (; lc2; lc2 = lc2->next)
6694             add_value_chains (old_var->dv, lc2->loc);
6695           for (; lc1; lc1 = lc1->next)
6696             remove_value_chains (old_var->dv, lc1->loc);
6697         }
6698       variable_was_changed (new_var, NULL);
6699     }
6700
6701   /* Continue traversing the hash table.  */
6702   return 1;
6703 }
6704
6705 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
6706    table DATA.  */
6707
6708 static int
6709 emit_notes_for_differences_2 (void **slot, void *data)
6710 {
6711   htab_t old_vars = (htab_t) data;
6712   variable old_var, new_var;
6713
6714   new_var = (variable) *slot;
6715   old_var = (variable) htab_find_with_hash (old_vars, new_var->dv,
6716                                             dv_htab_hash (new_var->dv));
6717   if (!old_var)
6718     {
6719       /* Variable has appeared.  */
6720       if (dv_onepart_p (new_var->dv))
6721         {
6722           location_chain lc;
6723
6724           gcc_assert (new_var->n_var_parts == 1);
6725           for (lc = new_var->var_part[0].loc_chain; lc; lc = lc->next)
6726             add_value_chains (new_var->dv, lc->loc);
6727           if (dv_is_value_p (new_var->dv))
6728             add_cselib_value_chains (new_var->dv);
6729         }
6730       variable_was_changed (new_var, NULL);
6731     }
6732
6733   /* Continue traversing the hash table.  */
6734   return 1;
6735 }
6736
6737 /* Emit notes before INSN for differences between dataflow sets OLD_SET and
6738    NEW_SET.  */
6739
6740 static void
6741 emit_notes_for_differences (rtx insn, dataflow_set *old_set,
6742                             dataflow_set *new_set)
6743 {
6744   htab_traverse (shared_hash_htab (old_set->vars),
6745                  emit_notes_for_differences_1,
6746                  shared_hash_htab (new_set->vars));
6747   htab_traverse (shared_hash_htab (new_set->vars),
6748                  emit_notes_for_differences_2,
6749                  shared_hash_htab (old_set->vars));
6750   emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, new_set->vars);
6751 }
6752
6753 /* Emit the notes for changes of location parts in the basic block BB.  */
6754
6755 static void
6756 emit_notes_in_bb (basic_block bb, dataflow_set *set)
6757 {
6758   int i;
6759
6760   dataflow_set_clear (set);
6761   dataflow_set_copy (set, &VTI (bb)->in);
6762
6763   for (i = 0; i < VTI (bb)->n_mos; i++)
6764     {
6765       rtx insn = VTI (bb)->mos[i].insn;
6766
6767       switch (VTI (bb)->mos[i].type)
6768         {
6769           case MO_CALL:
6770             dataflow_set_clear_at_call (set);
6771             emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars);
6772             break;
6773
6774           case MO_USE:
6775             {
6776               rtx loc = VTI (bb)->mos[i].u.loc;
6777
6778               if (REG_P (loc))
6779                 var_reg_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6780               else
6781                 var_mem_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6782
6783               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
6784             }
6785             break;
6786
6787           case MO_VAL_LOC:
6788             {
6789               rtx loc = VTI (bb)->mos[i].u.loc;
6790               rtx val, vloc;
6791               tree var;
6792
6793               if (GET_CODE (loc) == CONCAT)
6794                 {
6795                   val = XEXP (loc, 0);
6796                   vloc = XEXP (loc, 1);
6797                 }
6798               else
6799                 {
6800                   val = NULL_RTX;
6801                   vloc = loc;
6802                 }
6803
6804               var = PAT_VAR_LOCATION_DECL (vloc);
6805
6806               clobber_variable_part (set, NULL_RTX,
6807                                      dv_from_decl (var), 0, NULL_RTX);
6808               if (val)
6809                 {
6810                   if (VAL_NEEDS_RESOLUTION (loc))
6811                     val_resolve (set, val, PAT_VAR_LOCATION_LOC (vloc), insn);
6812                   set_variable_part (set, val, dv_from_decl (var), 0,
6813                                      VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
6814                                      INSERT);
6815                 }
6816
6817               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
6818             }
6819             break;
6820
6821           case MO_VAL_USE:
6822             {
6823               rtx loc = VTI (bb)->mos[i].u.loc;
6824               rtx val, vloc, uloc;
6825
6826               vloc = uloc = XEXP (loc, 1);
6827               val = XEXP (loc, 0);
6828
6829               if (GET_CODE (val) == CONCAT)
6830                 {
6831                   uloc = XEXP (val, 1);
6832                   val = XEXP (val, 0);
6833                 }
6834
6835               if (VAL_NEEDS_RESOLUTION (loc))
6836                 val_resolve (set, val, vloc, insn);
6837
6838               if (VAL_HOLDS_TRACK_EXPR (loc))
6839                 {
6840                   if (GET_CODE (uloc) == REG)
6841                     var_reg_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6842                                  NULL);
6843                   else if (GET_CODE (uloc) == MEM)
6844                     var_mem_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6845                                  NULL);
6846                 }
6847
6848               emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
6849             }
6850             break;
6851
6852           case MO_VAL_SET:
6853             {
6854               rtx loc = VTI (bb)->mos[i].u.loc;
6855               rtx val, vloc, uloc;
6856
6857               vloc = uloc = XEXP (loc, 1);
6858               val = XEXP (loc, 0);
6859
6860               if (GET_CODE (val) == CONCAT)
6861                 {
6862                   vloc = XEXP (val, 1);
6863                   val = XEXP (val, 0);
6864                 }
6865
6866               if (GET_CODE (vloc) == SET)
6867                 {
6868                   rtx vsrc = SET_SRC (vloc);
6869
6870                   gcc_assert (val != vsrc);
6871                   gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
6872
6873                   vloc = SET_DEST (vloc);
6874
6875                   if (VAL_NEEDS_RESOLUTION (loc))
6876                     val_resolve (set, val, vsrc, insn);
6877                 }
6878               else if (VAL_NEEDS_RESOLUTION (loc))
6879                 {
6880                   gcc_assert (GET_CODE (uloc) == SET
6881                               && GET_CODE (SET_SRC (uloc)) == REG);
6882                   val_resolve (set, val, SET_SRC (uloc), insn);
6883                 }
6884
6885               if (VAL_HOLDS_TRACK_EXPR (loc))
6886                 {
6887                   if (VAL_EXPR_IS_CLOBBERED (loc))
6888                     {
6889                       if (REG_P (uloc))
6890                         var_reg_delete (set, uloc, true);
6891                       else if (MEM_P (uloc))
6892                         var_mem_delete (set, uloc, true);
6893                     }
6894                   else
6895                     {
6896                       bool copied_p = VAL_EXPR_IS_COPIED (loc);
6897                       rtx set_src = NULL;
6898                       enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
6899
6900                       if (GET_CODE (uloc) == SET)
6901                         {
6902                           set_src = SET_SRC (uloc);
6903                           uloc = SET_DEST (uloc);
6904                         }
6905
6906                       if (copied_p)
6907                         {
6908                           status = find_src_status (set, set_src);
6909
6910                           set_src = find_src_set_src (set, set_src);
6911                         }
6912
6913                       if (REG_P (uloc))
6914                         var_reg_delete_and_set (set, uloc, !copied_p,
6915                                                 status, set_src);
6916                       else if (MEM_P (uloc))
6917                         var_mem_delete_and_set (set, uloc, !copied_p,
6918                                                 status, set_src);
6919                     }
6920                 }
6921               else if (REG_P (uloc))
6922                 var_regno_delete (set, REGNO (uloc));
6923
6924               val_store (set, val, vloc, insn);
6925
6926               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
6927                                       set->vars);
6928             }
6929             break;
6930
6931           case MO_SET:
6932             {
6933               rtx loc = VTI (bb)->mos[i].u.loc;
6934               rtx set_src = NULL;
6935
6936               if (GET_CODE (loc) == SET)
6937                 {
6938                   set_src = SET_SRC (loc);
6939                   loc = SET_DEST (loc);
6940                 }
6941
6942               if (REG_P (loc))
6943                 var_reg_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
6944                                         set_src);
6945               else
6946                 var_mem_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
6947                                         set_src);
6948
6949               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
6950                                       set->vars);
6951             }
6952             break;
6953
6954           case MO_COPY:
6955             {
6956               rtx loc = VTI (bb)->mos[i].u.loc;
6957               enum var_init_status src_status;
6958               rtx set_src = NULL;
6959
6960               if (GET_CODE (loc) == SET)
6961                 {
6962                   set_src = SET_SRC (loc);
6963                   loc = SET_DEST (loc);
6964                 }
6965
6966               src_status = find_src_status (set, set_src);
6967               set_src = find_src_set_src (set, set_src);
6968
6969               if (REG_P (loc))
6970                 var_reg_delete_and_set (set, loc, false, src_status, set_src);
6971               else
6972                 var_mem_delete_and_set (set, loc, false, src_status, set_src);
6973
6974               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
6975                                       set->vars);
6976             }
6977             break;
6978
6979           case MO_USE_NO_VAR:
6980             {
6981               rtx loc = VTI (bb)->mos[i].u.loc;
6982
6983               if (REG_P (loc))
6984                 var_reg_delete (set, loc, false);
6985               else
6986                 var_mem_delete (set, loc, false);
6987
6988               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
6989             }
6990             break;
6991
6992           case MO_CLOBBER:
6993             {
6994               rtx loc = VTI (bb)->mos[i].u.loc;
6995
6996               if (REG_P (loc))
6997                 var_reg_delete (set, loc, true);
6998               else
6999                 var_mem_delete (set, loc, true);
7000
7001               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
7002                                       set->vars);
7003             }
7004             break;
7005
7006           case MO_ADJUST:
7007             set->stack_adjust += VTI (bb)->mos[i].u.adjust;
7008             break;
7009         }
7010     }
7011 }
7012
7013 /* Emit notes for the whole function.  */
7014
7015 static void
7016 vt_emit_notes (void)
7017 {
7018   basic_block bb;
7019   dataflow_set cur;
7020
7021   gcc_assert (!htab_elements (changed_variables));
7022
7023   /* Free memory occupied by the out hash tables, as they aren't used
7024      anymore.  */
7025   FOR_EACH_BB (bb)
7026     dataflow_set_clear (&VTI (bb)->out);
7027
7028   /* Enable emitting notes by functions (mainly by set_variable_part and
7029      delete_variable_part).  */
7030   emit_notes = true;
7031
7032   if (MAY_HAVE_DEBUG_INSNS)
7033     changed_variables_stack = VEC_alloc (variable, heap, 40);
7034
7035   dataflow_set_init (&cur);
7036
7037   FOR_EACH_BB (bb)
7038     {
7039       /* Emit the notes for changes of variable locations between two
7040          subsequent basic blocks.  */
7041       emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
7042
7043       /* Emit the notes for the changes in the basic block itself.  */
7044       emit_notes_in_bb (bb, &cur);
7045
7046       /* Free memory occupied by the in hash table, we won't need it
7047          again.  */
7048       dataflow_set_clear (&VTI (bb)->in);
7049     }
7050 #ifdef ENABLE_CHECKING
7051   htab_traverse (shared_hash_htab (cur.vars),
7052                  emit_notes_for_differences_1,
7053                  shared_hash_htab (empty_shared_hash));
7054   if (MAY_HAVE_DEBUG_INSNS)
7055     gcc_assert (htab_elements (value_chains) == 0);
7056 #endif
7057   dataflow_set_destroy (&cur);
7058
7059   if (MAY_HAVE_DEBUG_INSNS)
7060     VEC_free (variable, heap, changed_variables_stack);
7061
7062   emit_notes = false;
7063 }
7064
7065 /* If there is a declaration and offset associated with register/memory RTL
7066    assign declaration to *DECLP and offset to *OFFSETP, and return true.  */
7067
7068 static bool
7069 vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
7070 {
7071   if (REG_P (rtl))
7072     {
7073       if (REG_ATTRS (rtl))
7074         {
7075           *declp = REG_EXPR (rtl);
7076           *offsetp = REG_OFFSET (rtl);
7077           return true;
7078         }
7079     }
7080   else if (MEM_P (rtl))
7081     {
7082       if (MEM_ATTRS (rtl))
7083         {
7084           *declp = MEM_EXPR (rtl);
7085           *offsetp = INT_MEM_OFFSET (rtl);
7086           return true;
7087         }
7088     }
7089   return false;
7090 }
7091
7092 /* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */
7093
7094 static void
7095 vt_add_function_parameters (void)
7096 {
7097   tree parm;
7098
7099   for (parm = DECL_ARGUMENTS (current_function_decl);
7100        parm; parm = TREE_CHAIN (parm))
7101     {
7102       rtx decl_rtl = DECL_RTL_IF_SET (parm);
7103       rtx incoming = DECL_INCOMING_RTL (parm);
7104       tree decl;
7105       enum machine_mode mode;
7106       HOST_WIDE_INT offset;
7107       dataflow_set *out;
7108       decl_or_value dv;
7109
7110       if (TREE_CODE (parm) != PARM_DECL)
7111         continue;
7112
7113       if (!DECL_NAME (parm))
7114         continue;
7115
7116       if (!decl_rtl || !incoming)
7117         continue;
7118
7119       if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
7120         continue;
7121
7122       if (!vt_get_decl_and_offset (incoming, &decl, &offset))
7123         {
7124           if (REG_P (incoming) || MEM_P (incoming))
7125             {
7126               /* This means argument is passed by invisible reference.  */
7127               offset = 0;
7128               decl = parm;
7129               incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
7130             }
7131           else
7132             {
7133               if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
7134                 continue;
7135               offset += byte_lowpart_offset (GET_MODE (incoming),
7136                                              GET_MODE (decl_rtl));
7137             }
7138         }
7139
7140       if (!decl)
7141         continue;
7142
7143       if (parm != decl)
7144         {
7145           /* Assume that DECL_RTL was a pseudo that got spilled to
7146              memory.  The spill slot sharing code will force the
7147              memory to reference spill_slot_decl (%sfp), so we don't
7148              match above.  That's ok, the pseudo must have referenced
7149              the entire parameter, so just reset OFFSET.  */
7150           gcc_assert (decl == get_spill_slot_decl (false));
7151           offset = 0;
7152         }
7153
7154       if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
7155         continue;
7156
7157       out = &VTI (ENTRY_BLOCK_PTR)->out;
7158
7159       dv = dv_from_decl (parm);
7160
7161       if (target_for_debug_bind (parm)
7162           /* We can't deal with these right now, because this kind of
7163              variable is single-part.  ??? We could handle parallels
7164              that describe multiple locations for the same single
7165              value, but ATM we don't.  */
7166           && GET_CODE (incoming) != PARALLEL)
7167         {
7168           cselib_val *val;
7169
7170           /* ??? We shouldn't ever hit this, but it may happen because
7171              arguments passed by invisible reference aren't dealt with
7172              above: incoming-rtl will have Pmode rather than the
7173              expected mode for the type.  */
7174           if (offset)
7175             continue;
7176
7177           val = cselib_lookup (var_lowpart (mode, incoming), mode, true);
7178
7179           /* ??? Float-typed values in memory are not handled by
7180              cselib.  */
7181           if (val)
7182             {
7183               cselib_preserve_value (val);
7184               set_variable_part (out, val->val_rtx, dv, offset,
7185                                  VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
7186               dv = dv_from_value (val->val_rtx);
7187             }
7188         }
7189
7190       if (REG_P (incoming))
7191         {
7192           incoming = var_lowpart (mode, incoming);
7193           gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
7194           attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
7195                              incoming);
7196           set_variable_part (out, incoming, dv, offset,
7197                              VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
7198         }
7199       else if (MEM_P (incoming))
7200         {
7201           incoming = var_lowpart (mode, incoming);
7202           set_variable_part (out, incoming, dv, offset,
7203                              VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
7204         }
7205     }
7206
7207   if (MAY_HAVE_DEBUG_INSNS)
7208     {
7209       cselib_preserve_only_values (true);
7210       cselib_reset_table_with_next_value (cselib_get_next_unknown_value ());
7211     }
7212
7213 }
7214
7215 /* Allocate and initialize the data structures for variable tracking
7216    and parse the RTL to get the micro operations.  */
7217
7218 static void
7219 vt_initialize (void)
7220 {
7221   basic_block bb;
7222
7223   alloc_aux_for_blocks (sizeof (struct variable_tracking_info_def));
7224
7225   if (MAY_HAVE_DEBUG_INSNS)
7226     {
7227       cselib_init (true);
7228       scratch_regs = BITMAP_ALLOC (NULL);
7229       valvar_pool = create_alloc_pool ("small variable_def pool",
7230                                        sizeof (struct variable_def), 256);
7231     }
7232   else
7233     {
7234       scratch_regs = NULL;
7235       valvar_pool = NULL;
7236     }
7237
7238   FOR_EACH_BB (bb)
7239     {
7240       rtx insn;
7241       HOST_WIDE_INT pre, post = 0;
7242       int count;
7243       unsigned int next_value_before = cselib_get_next_unknown_value ();
7244       unsigned int next_value_after = next_value_before;
7245
7246       if (MAY_HAVE_DEBUG_INSNS)
7247         {
7248           cselib_record_sets_hook = count_with_sets;
7249           if (dump_file && (dump_flags & TDF_DETAILS))
7250             fprintf (dump_file, "first value: %i\n",
7251                      cselib_get_next_unknown_value ());
7252         }
7253
7254       /* Count the number of micro operations.  */
7255       VTI (bb)->n_mos = 0;
7256       for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
7257            insn = NEXT_INSN (insn))
7258         {
7259           if (INSN_P (insn))
7260             {
7261               if (!frame_pointer_needed)
7262                 {
7263                   insn_stack_adjust_offset_pre_post (insn, &pre, &post);
7264                   if (pre)
7265                     {
7266                       VTI (bb)->n_mos++;
7267                       if (dump_file && (dump_flags & TDF_DETAILS))
7268                         log_op_type (GEN_INT (pre), bb, insn,
7269                                      MO_ADJUST, dump_file);
7270                     }
7271                   if (post)
7272                     {
7273                       VTI (bb)->n_mos++;
7274                       if (dump_file && (dump_flags & TDF_DETAILS))
7275                         log_op_type (GEN_INT (post), bb, insn,
7276                                      MO_ADJUST, dump_file);
7277                     }
7278                 }
7279               cselib_hook_called = false;
7280               if (MAY_HAVE_DEBUG_INSNS)
7281                 {
7282                   cselib_process_insn (insn);
7283                   if (dump_file && (dump_flags & TDF_DETAILS))
7284                     {
7285                       print_rtl_single (dump_file, insn);
7286                       dump_cselib_table (dump_file);
7287                     }
7288                 }
7289               if (!cselib_hook_called)
7290                 count_with_sets (insn, 0, 0);
7291               if (CALL_P (insn))
7292                 {
7293                   VTI (bb)->n_mos++;
7294                   if (dump_file && (dump_flags & TDF_DETAILS))
7295                     log_op_type (PATTERN (insn), bb, insn,
7296                                  MO_CALL, dump_file);
7297                 }
7298             }
7299         }
7300
7301       count = VTI (bb)->n_mos;
7302
7303       if (MAY_HAVE_DEBUG_INSNS)
7304         {
7305           cselib_preserve_only_values (false);
7306           next_value_after = cselib_get_next_unknown_value ();
7307           cselib_reset_table_with_next_value (next_value_before);
7308           cselib_record_sets_hook = add_with_sets;
7309           if (dump_file && (dump_flags & TDF_DETAILS))
7310             fprintf (dump_file, "first value: %i\n",
7311                      cselib_get_next_unknown_value ());
7312         }
7313
7314       /* Add the micro-operations to the array.  */
7315       VTI (bb)->mos = XNEWVEC (micro_operation, VTI (bb)->n_mos);
7316       VTI (bb)->n_mos = 0;
7317       for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
7318            insn = NEXT_INSN (insn))
7319         {
7320           if (INSN_P (insn))
7321             {
7322               if (!frame_pointer_needed)
7323                 {
7324                   insn_stack_adjust_offset_pre_post (insn, &pre, &post);
7325                   if (pre)
7326                     {
7327                       micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
7328
7329                       mo->type = MO_ADJUST;
7330                       mo->u.adjust = pre;
7331                       mo->insn = insn;
7332
7333                       if (dump_file && (dump_flags & TDF_DETAILS))
7334                         log_op_type (PATTERN (insn), bb, insn,
7335                                      MO_ADJUST, dump_file);
7336                     }
7337                 }
7338
7339               cselib_hook_called = false;
7340               if (MAY_HAVE_DEBUG_INSNS)
7341                 {
7342                   cselib_process_insn (insn);
7343                   if (dump_file && (dump_flags & TDF_DETAILS))
7344                     {
7345                       print_rtl_single (dump_file, insn);
7346                       dump_cselib_table (dump_file);
7347                     }
7348                 }
7349               if (!cselib_hook_called)
7350                 add_with_sets (insn, 0, 0);
7351
7352               if (!frame_pointer_needed && post)
7353                 {
7354                   micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
7355
7356                   mo->type = MO_ADJUST;
7357                   mo->u.adjust = post;
7358                   mo->insn = insn;
7359
7360                   if (dump_file && (dump_flags & TDF_DETAILS))
7361                     log_op_type (PATTERN (insn), bb, insn,
7362                                  MO_ADJUST, dump_file);
7363                 }
7364             }
7365         }
7366       gcc_assert (count == VTI (bb)->n_mos);
7367       if (MAY_HAVE_DEBUG_INSNS)
7368         {
7369           cselib_preserve_only_values (true);
7370           gcc_assert (next_value_after == cselib_get_next_unknown_value ());
7371           cselib_reset_table_with_next_value (next_value_after);
7372           cselib_record_sets_hook = NULL;
7373         }
7374     }
7375
7376   attrs_pool = create_alloc_pool ("attrs_def pool",
7377                                   sizeof (struct attrs_def), 1024);
7378   var_pool = create_alloc_pool ("variable_def pool",
7379                                 sizeof (struct variable_def)
7380                                 + (MAX_VAR_PARTS - 1)
7381                                 * sizeof (((variable)NULL)->var_part[0]), 64);
7382   loc_chain_pool = create_alloc_pool ("location_chain_def pool",
7383                                       sizeof (struct location_chain_def),
7384                                       1024);
7385   shared_hash_pool = create_alloc_pool ("shared_hash_def pool",
7386                                         sizeof (struct shared_hash_def), 256);
7387   empty_shared_hash = (shared_hash) pool_alloc (shared_hash_pool);
7388   empty_shared_hash->refcount = 1;
7389   empty_shared_hash->htab
7390     = htab_create (1, variable_htab_hash, variable_htab_eq,
7391                    variable_htab_free);
7392   changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
7393                                    variable_htab_free);
7394   if (MAY_HAVE_DEBUG_INSNS)
7395     {
7396       value_chain_pool = create_alloc_pool ("value_chain_def pool",
7397                                             sizeof (struct value_chain_def),
7398                                             1024);
7399       value_chains = htab_create (32, value_chain_htab_hash,
7400                                   value_chain_htab_eq, NULL);
7401     }
7402
7403   /* Init the IN and OUT sets.  */
7404   FOR_ALL_BB (bb)
7405     {
7406       VTI (bb)->visited = false;
7407       VTI (bb)->flooded = false;
7408       dataflow_set_init (&VTI (bb)->in);
7409       dataflow_set_init (&VTI (bb)->out);
7410       VTI (bb)->permp = NULL;
7411     }
7412
7413   VTI (ENTRY_BLOCK_PTR)->flooded = true;
7414   vt_add_function_parameters ();
7415 }
7416
7417 /* Get rid of all debug insns from the insn stream.  */
7418
7419 static void
7420 delete_debug_insns (void)
7421 {
7422   basic_block bb;
7423   rtx insn, next;
7424
7425   if (!MAY_HAVE_DEBUG_INSNS)
7426     return;
7427
7428   FOR_EACH_BB (bb)
7429     {
7430       FOR_BB_INSNS_SAFE (bb, insn, next)
7431         if (DEBUG_INSN_P (insn))
7432           delete_insn (insn);
7433     }
7434 }
7435
7436 /* Run a fast, BB-local only version of var tracking, to take care of
7437    information that we don't do global analysis on, such that not all
7438    information is lost.  If SKIPPED holds, we're skipping the global
7439    pass entirely, so we should try to use information it would have
7440    handled as well..  */
7441
7442 static void
7443 vt_debug_insns_local (bool skipped ATTRIBUTE_UNUSED)
7444 {
7445   /* ??? Just skip it all for now.  */
7446   delete_debug_insns ();
7447 }
7448
7449 /* Free the data structures needed for variable tracking.  */
7450
7451 static void
7452 vt_finalize (void)
7453 {
7454   basic_block bb;
7455
7456   FOR_EACH_BB (bb)
7457     {
7458       free (VTI (bb)->mos);
7459     }
7460
7461   FOR_ALL_BB (bb)
7462     {
7463       dataflow_set_destroy (&VTI (bb)->in);
7464       dataflow_set_destroy (&VTI (bb)->out);
7465       if (VTI (bb)->permp)
7466         {
7467           dataflow_set_destroy (VTI (bb)->permp);
7468           XDELETE (VTI (bb)->permp);
7469         }
7470     }
7471   free_aux_for_blocks ();
7472   htab_delete (empty_shared_hash->htab);
7473   htab_delete (changed_variables);
7474   free_alloc_pool (attrs_pool);
7475   free_alloc_pool (var_pool);
7476   free_alloc_pool (loc_chain_pool);
7477   free_alloc_pool (shared_hash_pool);
7478
7479   if (MAY_HAVE_DEBUG_INSNS)
7480     {
7481       htab_delete (value_chains);
7482       free_alloc_pool (value_chain_pool);
7483       free_alloc_pool (valvar_pool);
7484       cselib_finish ();
7485       BITMAP_FREE (scratch_regs);
7486       scratch_regs = NULL;
7487     }
7488
7489   if (vui_vec)
7490     XDELETEVEC (vui_vec);
7491   vui_vec = NULL;
7492   vui_allocated = 0;
7493 }
7494
7495 /* The entry point to variable tracking pass.  */
7496
7497 unsigned int
7498 variable_tracking_main (void)
7499 {
7500   if (flag_var_tracking_assignments < 0)
7501     {
7502       delete_debug_insns ();
7503       return 0;
7504     }
7505
7506   if (n_basic_blocks > 500 && n_edges / n_basic_blocks >= 20)
7507     {
7508       vt_debug_insns_local (true);
7509       return 0;
7510     }
7511
7512   mark_dfs_back_edges ();
7513   vt_initialize ();
7514   if (!frame_pointer_needed)
7515     {
7516       if (!vt_stack_adjustments ())
7517         {
7518           vt_finalize ();
7519           vt_debug_insns_local (true);
7520           return 0;
7521         }
7522     }
7523
7524   vt_find_locations ();
7525
7526   if (dump_file && (dump_flags & TDF_DETAILS))
7527     {
7528       dump_dataflow_sets ();
7529       dump_flow_info (dump_file, dump_flags);
7530     }
7531
7532   vt_emit_notes ();
7533
7534   vt_finalize ();
7535   vt_debug_insns_local (false);
7536   return 0;
7537 }
7538 \f
7539 static bool
7540 gate_handle_var_tracking (void)
7541 {
7542   return (flag_var_tracking);
7543 }
7544
7545
7546
7547 struct rtl_opt_pass pass_variable_tracking =
7548 {
7549  {
7550   RTL_PASS,
7551   "vartrack",                           /* name */
7552   gate_handle_var_tracking,             /* gate */
7553   variable_tracking_main,               /* execute */
7554   NULL,                                 /* sub */
7555   NULL,                                 /* next */
7556   0,                                    /* static_pass_number */
7557   TV_VAR_TRACKING,                      /* tv_id */
7558   0,                                    /* properties_required */
7559   0,                                    /* properties_provided */
7560   0,                                    /* properties_destroyed */
7561   0,                                    /* todo_flags_start */
7562   TODO_dump_func | TODO_verify_rtl_sharing/* todo_flags_finish */
7563  }
7564 };