OSDN Git Service

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