OSDN Git Service

c11d11953f464f7763c1ee9a135ef097b2f2b95e
[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);
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 /* Bind one-part variables to the canonical value in an equivalence
3172    set.  Not doing this causes dataflow convergence failure in rare
3173    circumstances, see PR42873.  Unfortunately we can't do this
3174    efficiently as part of canonicalize_values_star, since we may not
3175    have determined or even seen the canonical value of a set when we
3176    get to a variable that references another member of the set.  */
3177
3178 static int
3179 canonicalize_vars_star (void **slot, void *data)
3180 {
3181   dataflow_set *set = (dataflow_set *)data;
3182   variable var = (variable) *slot;
3183   decl_or_value dv = var->dv;
3184   location_chain node;
3185   rtx cval;
3186   decl_or_value cdv;
3187   void **cslot;
3188   variable cvar;
3189   location_chain cnode;
3190
3191   if (!dv_onepart_p (dv) || dv_is_value_p (dv))
3192     return 1;
3193
3194   gcc_assert (var->n_var_parts == 1);
3195
3196   node = var->var_part[0].loc_chain;
3197
3198   if (GET_CODE (node->loc) != VALUE)
3199     return 1;
3200
3201   gcc_assert (!node->next);
3202   cval = node->loc;
3203
3204   /* Push values to the canonical one.  */
3205   cdv = dv_from_value (cval);
3206   cslot = shared_hash_find_slot_noinsert (set->vars, cdv);
3207   if (!cslot)
3208     return 1;
3209   cvar = (variable)*cslot;
3210   gcc_assert (cvar->n_var_parts == 1);
3211
3212   cnode = cvar->var_part[0].loc_chain;
3213
3214   /* CVAL is canonical if its value list contains non-VALUEs or VALUEs
3215      that are not “more canonical” than it.  */
3216   if (GET_CODE (cnode->loc) != VALUE
3217       || !canon_value_cmp (cnode->loc, cval))
3218     return 1;
3219
3220   /* CVAL was found to be non-canonical.  Change the variable to point
3221      to the canonical VALUE.  */
3222   gcc_assert (!cnode->next);
3223   cval = cnode->loc;
3224
3225   slot = set_slot_part (set, cval, slot, dv, 0,
3226                         node->init, node->set_src);
3227   slot = clobber_slot_part (set, cval, slot, 0, node->set_src);
3228
3229   return 1;
3230 }
3231
3232 /* Combine variable or value in *S1SLOT (in DSM->cur) with the
3233    corresponding entry in DSM->src.  Multi-part variables are combined
3234    with variable_union, whereas onepart dvs are combined with
3235    intersection.  */
3236
3237 static int
3238 variable_merge_over_cur (void **s1slot, void *data)
3239 {
3240   struct dfset_merge *dsm = (struct dfset_merge *)data;
3241   dataflow_set *dst = dsm->dst;
3242   void **dstslot;
3243   variable s1var = (variable) *s1slot;
3244   variable s2var, dvar = NULL;
3245   decl_or_value dv = s1var->dv;
3246   bool onepart = dv_onepart_p (dv);
3247   rtx val;
3248   hashval_t dvhash;
3249   location_chain node, *nodep;
3250
3251   /* If the incoming onepart variable has an empty location list, then
3252      the intersection will be just as empty.  For other variables,
3253      it's always union.  */
3254   gcc_assert (s1var->n_var_parts);
3255   gcc_assert (s1var->var_part[0].loc_chain);
3256
3257   if (!onepart)
3258     return variable_union (s1slot, dst);
3259
3260   gcc_assert (s1var->n_var_parts == 1);
3261   gcc_assert (s1var->var_part[0].offset == 0);
3262
3263   dvhash = dv_htab_hash (dv);
3264   if (dv_is_value_p (dv))
3265     val = dv_as_value (dv);
3266   else
3267     val = NULL;
3268
3269   s2var = shared_hash_find_1 (dsm->src->vars, dv, dvhash);
3270   if (!s2var)
3271     {
3272       dst_can_be_shared = false;
3273       return 1;
3274     }
3275
3276   dsm->src_onepart_cnt--;
3277   gcc_assert (s2var->var_part[0].loc_chain);
3278   gcc_assert (s2var->n_var_parts == 1);
3279   gcc_assert (s2var->var_part[0].offset == 0);
3280
3281   dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3282   if (dstslot)
3283     {
3284       dvar = (variable)*dstslot;
3285       gcc_assert (dvar->refcount == 1);
3286       gcc_assert (dvar->n_var_parts == 1);
3287       gcc_assert (dvar->var_part[0].offset == 0);
3288       nodep = &dvar->var_part[0].loc_chain;
3289     }
3290   else
3291     {
3292       nodep = &node;
3293       node = NULL;
3294     }
3295
3296   if (!dstslot && !onepart_variable_different_p (s1var, s2var))
3297     {
3298       dstslot = shared_hash_find_slot_unshare_1 (&dst->vars, dv,
3299                                                  dvhash, INSERT);
3300       *dstslot = dvar = s2var;
3301       dvar->refcount++;
3302     }
3303   else
3304     {
3305       dst_can_be_shared = false;
3306
3307       intersect_loc_chains (val, nodep, dsm,
3308                             s1var->var_part[0].loc_chain, s2var);
3309
3310       if (!dstslot)
3311         {
3312           if (node)
3313             {
3314               dvar = (variable) pool_alloc (dv_pool (dv));
3315               dvar->dv = dv;
3316               dvar->refcount = 1;
3317               dvar->n_var_parts = 1;
3318               dvar->cur_loc_changed = false;
3319               dvar->in_changed_variables = false;
3320               dvar->var_part[0].offset = 0;
3321               dvar->var_part[0].loc_chain = node;
3322               dvar->var_part[0].cur_loc = NULL;
3323
3324               dstslot
3325                 = shared_hash_find_slot_unshare_1 (&dst->vars, dv, dvhash,
3326                                                    INSERT);
3327               gcc_assert (!*dstslot);
3328               *dstslot = dvar;
3329             }
3330           else
3331             return 1;
3332         }
3333     }
3334
3335   nodep = &dvar->var_part[0].loc_chain;
3336   while ((node = *nodep))
3337     {
3338       location_chain *nextp = &node->next;
3339
3340       if (GET_CODE (node->loc) == REG)
3341         {
3342           attrs list;
3343
3344           for (list = dst->regs[REGNO (node->loc)]; list; list = list->next)
3345             if (GET_MODE (node->loc) == GET_MODE (list->loc)
3346                 && dv_is_value_p (list->dv))
3347               break;
3348
3349           if (!list)
3350             attrs_list_insert (&dst->regs[REGNO (node->loc)],
3351                                dv, 0, node->loc);
3352           /* If this value became canonical for another value that had
3353              this register, we want to leave it alone.  */
3354           else if (dv_as_value (list->dv) != val)
3355             {
3356               dstslot = set_slot_part (dst, dv_as_value (list->dv),
3357                                        dstslot, dv, 0,
3358                                        node->init, NULL_RTX);
3359               dstslot = delete_slot_part (dst, node->loc, dstslot, 0);
3360
3361               /* Since nextp points into the removed node, we can't
3362                  use it.  The pointer to the next node moved to nodep.
3363                  However, if the variable we're walking is unshared
3364                  during our walk, we'll keep walking the location list
3365                  of the previously-shared variable, in which case the
3366                  node won't have been removed, and we'll want to skip
3367                  it.  That's why we test *nodep here.  */
3368               if (*nodep != node)
3369                 nextp = nodep;
3370             }
3371         }
3372       else
3373         /* Canonicalization puts registers first, so we don't have to
3374            walk it all.  */
3375         break;
3376       nodep = nextp;
3377     }
3378
3379   if (dvar != (variable)*dstslot)
3380     dvar = (variable)*dstslot;
3381   nodep = &dvar->var_part[0].loc_chain;
3382
3383   if (val)
3384     {
3385       /* Mark all referenced nodes for canonicalization, and make sure
3386          we have mutual equivalence links.  */
3387       VALUE_RECURSED_INTO (val) = true;
3388       for (node = *nodep; node; node = node->next)
3389         if (GET_CODE (node->loc) == VALUE)
3390           {
3391             VALUE_RECURSED_INTO (node->loc) = true;
3392             set_variable_part (dst, val, dv_from_value (node->loc), 0,
3393                                node->init, NULL, INSERT);
3394           }
3395
3396       dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3397       gcc_assert (*dstslot == dvar);
3398       canonicalize_values_star (dstslot, dst);
3399 #ifdef ENABLE_CHECKING
3400       gcc_assert (dstslot
3401                   == shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash));
3402 #endif
3403       dvar = (variable)*dstslot;
3404     }
3405   else
3406     {
3407       bool has_value = false, has_other = false;
3408
3409       /* If we have one value and anything else, we're going to
3410          canonicalize this, so make sure all values have an entry in
3411          the table and are marked for canonicalization.  */
3412       for (node = *nodep; node; node = node->next)
3413         {
3414           if (GET_CODE (node->loc) == VALUE)
3415             {
3416               /* If this was marked during register canonicalization,
3417                  we know we have to canonicalize values.  */
3418               if (has_value)
3419                 has_other = true;
3420               has_value = true;
3421               if (has_other)
3422                 break;
3423             }
3424           else
3425             {
3426               has_other = true;
3427               if (has_value)
3428                 break;
3429             }
3430         }
3431
3432       if (has_value && has_other)
3433         {
3434           for (node = *nodep; node; node = node->next)
3435             {
3436               if (GET_CODE (node->loc) == VALUE)
3437                 {
3438                   decl_or_value dv = dv_from_value (node->loc);
3439                   void **slot = NULL;
3440
3441                   if (shared_hash_shared (dst->vars))
3442                     slot = shared_hash_find_slot_noinsert (dst->vars, dv);
3443                   if (!slot)
3444                     slot = shared_hash_find_slot_unshare (&dst->vars, dv,
3445                                                           INSERT);
3446                   if (!*slot)
3447                     {
3448                       variable var = (variable) pool_alloc (dv_pool (dv));
3449                       var->dv = dv;
3450                       var->refcount = 1;
3451                       var->n_var_parts = 1;
3452                       var->cur_loc_changed = false;
3453                       var->in_changed_variables = false;
3454                       var->var_part[0].offset = 0;
3455                       var->var_part[0].loc_chain = NULL;
3456                       var->var_part[0].cur_loc = NULL;
3457                       *slot = var;
3458                     }
3459
3460                   VALUE_RECURSED_INTO (node->loc) = true;
3461                 }
3462             }
3463
3464           dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3465           gcc_assert (*dstslot == dvar);
3466           canonicalize_values_star (dstslot, dst);
3467 #ifdef ENABLE_CHECKING
3468           gcc_assert (dstslot
3469                       == shared_hash_find_slot_noinsert_1 (dst->vars,
3470                                                            dv, dvhash));
3471 #endif
3472           dvar = (variable)*dstslot;
3473         }
3474     }
3475
3476   if (!onepart_variable_different_p (dvar, s2var))
3477     {
3478       variable_htab_free (dvar);
3479       *dstslot = dvar = s2var;
3480       dvar->refcount++;
3481     }
3482   else if (s2var != s1var && !onepart_variable_different_p (dvar, s1var))
3483     {
3484       variable_htab_free (dvar);
3485       *dstslot = dvar = s1var;
3486       dvar->refcount++;
3487       dst_can_be_shared = false;
3488     }
3489   else
3490     dst_can_be_shared = false;
3491
3492   return 1;
3493 }
3494
3495 /* Copy s2slot (in DSM->src) to DSM->dst if the variable is a
3496    multi-part variable.  Unions of multi-part variables and
3497    intersections of one-part ones will be handled in
3498    variable_merge_over_cur().  */
3499
3500 static int
3501 variable_merge_over_src (void **s2slot, void *data)
3502 {
3503   struct dfset_merge *dsm = (struct dfset_merge *)data;
3504   dataflow_set *dst = dsm->dst;
3505   variable s2var = (variable) *s2slot;
3506   decl_or_value dv = s2var->dv;
3507   bool onepart = dv_onepart_p (dv);
3508
3509   if (!onepart)
3510     {
3511       void **dstp = shared_hash_find_slot (dst->vars, dv);
3512       *dstp = s2var;
3513       s2var->refcount++;
3514       return 1;
3515     }
3516
3517   dsm->src_onepart_cnt++;
3518   return 1;
3519 }
3520
3521 /* Combine dataflow set information from SRC2 into DST, using PDST
3522    to carry over information across passes.  */
3523
3524 static void
3525 dataflow_set_merge (dataflow_set *dst, dataflow_set *src2)
3526 {
3527   dataflow_set cur = *dst;
3528   dataflow_set *src1 = &cur;
3529   struct dfset_merge dsm;
3530   int i;
3531   size_t src1_elems, src2_elems;
3532
3533   src1_elems = htab_elements (shared_hash_htab (src1->vars));
3534   src2_elems = htab_elements (shared_hash_htab (src2->vars));
3535   dataflow_set_init (dst);
3536   dst->stack_adjust = cur.stack_adjust;
3537   shared_hash_destroy (dst->vars);
3538   dst->vars = (shared_hash) pool_alloc (shared_hash_pool);
3539   dst->vars->refcount = 1;
3540   dst->vars->htab
3541     = htab_create (MAX (src1_elems, src2_elems), variable_htab_hash,
3542                    variable_htab_eq, variable_htab_free);
3543
3544   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3545     attrs_list_mpdv_union (&dst->regs[i], src1->regs[i], src2->regs[i]);
3546
3547   dsm.dst = dst;
3548   dsm.src = src2;
3549   dsm.cur = src1;
3550   dsm.src_onepart_cnt = 0;
3551
3552   htab_traverse (shared_hash_htab (dsm.src->vars), variable_merge_over_src,
3553                  &dsm);
3554   htab_traverse (shared_hash_htab (dsm.cur->vars), variable_merge_over_cur,
3555                  &dsm);
3556
3557   if (dsm.src_onepart_cnt)
3558     dst_can_be_shared = false;
3559
3560   dataflow_set_destroy (src1);
3561 }
3562
3563 /* Mark register equivalences.  */
3564
3565 static void
3566 dataflow_set_equiv_regs (dataflow_set *set)
3567 {
3568   int i;
3569   attrs list, *listp;
3570
3571   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3572     {
3573       rtx canon[NUM_MACHINE_MODES];
3574
3575       memset (canon, 0, sizeof (canon));
3576
3577       for (list = set->regs[i]; list; list = list->next)
3578         if (list->offset == 0 && dv_is_value_p (list->dv))
3579           {
3580             rtx val = dv_as_value (list->dv);
3581             rtx *cvalp = &canon[(int)GET_MODE (val)];
3582             rtx cval = *cvalp;
3583
3584             if (canon_value_cmp (val, cval))
3585               *cvalp = val;
3586           }
3587
3588       for (list = set->regs[i]; list; list = list->next)
3589         if (list->offset == 0 && dv_onepart_p (list->dv))
3590           {
3591             rtx cval = canon[(int)GET_MODE (list->loc)];
3592
3593             if (!cval)
3594               continue;
3595
3596             if (dv_is_value_p (list->dv))
3597               {
3598                 rtx val = dv_as_value (list->dv);
3599
3600                 if (val == cval)
3601                   continue;
3602
3603                 VALUE_RECURSED_INTO (val) = true;
3604                 set_variable_part (set, val, dv_from_value (cval), 0,
3605                                    VAR_INIT_STATUS_INITIALIZED,
3606                                    NULL, NO_INSERT);
3607               }
3608
3609             VALUE_RECURSED_INTO (cval) = true;
3610             set_variable_part (set, cval, list->dv, 0,
3611                                VAR_INIT_STATUS_INITIALIZED, NULL, NO_INSERT);
3612           }
3613
3614       for (listp = &set->regs[i]; (list = *listp);
3615            listp = list ? &list->next : listp)
3616         if (list->offset == 0 && dv_onepart_p (list->dv))
3617           {
3618             rtx cval = canon[(int)GET_MODE (list->loc)];
3619             void **slot;
3620
3621             if (!cval)
3622               continue;
3623
3624             if (dv_is_value_p (list->dv))
3625               {
3626                 rtx val = dv_as_value (list->dv);
3627                 if (!VALUE_RECURSED_INTO (val))
3628                   continue;
3629               }
3630
3631             slot = shared_hash_find_slot_noinsert (set->vars, list->dv);
3632             canonicalize_values_star (slot, set);
3633             if (*listp != list)
3634               list = NULL;
3635           }
3636     }
3637 }
3638
3639 /* Remove any redundant values in the location list of VAR, which must
3640    be unshared and 1-part.  */
3641
3642 static void
3643 remove_duplicate_values (variable var)
3644 {
3645   location_chain node, *nodep;
3646
3647   gcc_assert (dv_onepart_p (var->dv));
3648   gcc_assert (var->n_var_parts == 1);
3649   gcc_assert (var->refcount == 1);
3650
3651   for (nodep = &var->var_part[0].loc_chain; (node = *nodep); )
3652     {
3653       if (GET_CODE (node->loc) == VALUE)
3654         {
3655           if (VALUE_RECURSED_INTO (node->loc))
3656             {
3657               /* Remove duplicate value node.  */
3658               *nodep = node->next;
3659               pool_free (loc_chain_pool, node);
3660               continue;
3661             }
3662           else
3663             VALUE_RECURSED_INTO (node->loc) = true;
3664         }
3665       nodep = &node->next;
3666     }
3667
3668   for (node = var->var_part[0].loc_chain; node; node = node->next)
3669     if (GET_CODE (node->loc) == VALUE)
3670       {
3671         gcc_assert (VALUE_RECURSED_INTO (node->loc));
3672         VALUE_RECURSED_INTO (node->loc) = false;
3673       }
3674 }
3675
3676
3677 /* Hash table iteration argument passed to variable_post_merge.  */
3678 struct dfset_post_merge
3679 {
3680   /* The new input set for the current block.  */
3681   dataflow_set *set;
3682   /* Pointer to the permanent input set for the current block, or
3683      NULL.  */
3684   dataflow_set **permp;
3685 };
3686
3687 /* Create values for incoming expressions associated with one-part
3688    variables that don't have value numbers for them.  */
3689
3690 static int
3691 variable_post_merge_new_vals (void **slot, void *info)
3692 {
3693   struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info;
3694   dataflow_set *set = dfpm->set;
3695   variable var = (variable)*slot;
3696   location_chain node;
3697
3698   if (!dv_onepart_p (var->dv) || !var->n_var_parts)
3699     return 1;
3700
3701   gcc_assert (var->n_var_parts == 1);
3702
3703   if (dv_is_decl_p (var->dv))
3704     {
3705       bool check_dupes = false;
3706
3707     restart:
3708       for (node = var->var_part[0].loc_chain; node; node = node->next)
3709         {
3710           if (GET_CODE (node->loc) == VALUE)
3711             gcc_assert (!VALUE_RECURSED_INTO (node->loc));
3712           else if (GET_CODE (node->loc) == REG)
3713             {
3714               attrs att, *attp, *curp = NULL;
3715
3716               if (var->refcount != 1)
3717                 {
3718                   slot = unshare_variable (set, slot, var,
3719                                            VAR_INIT_STATUS_INITIALIZED);
3720                   var = (variable)*slot;
3721                   goto restart;
3722                 }
3723
3724               for (attp = &set->regs[REGNO (node->loc)]; (att = *attp);
3725                    attp = &att->next)
3726                 if (att->offset == 0
3727                     && GET_MODE (att->loc) == GET_MODE (node->loc))
3728                   {
3729                     if (dv_is_value_p (att->dv))
3730                       {
3731                         rtx cval = dv_as_value (att->dv);
3732                         node->loc = cval;
3733                         check_dupes = true;
3734                         break;
3735                       }
3736                     else if (dv_as_opaque (att->dv) == dv_as_opaque (var->dv))
3737                       curp = attp;
3738                   }
3739
3740               if (!curp)
3741                 {
3742                   curp = attp;
3743                   while (*curp)
3744                     if ((*curp)->offset == 0
3745                         && GET_MODE ((*curp)->loc) == GET_MODE (node->loc)
3746                         && dv_as_opaque ((*curp)->dv) == dv_as_opaque (var->dv))
3747                       break;
3748                     else
3749                       curp = &(*curp)->next;
3750                   gcc_assert (*curp);
3751                 }
3752
3753               if (!att)
3754                 {
3755                   decl_or_value cdv;
3756                   rtx cval;
3757
3758                   if (!*dfpm->permp)
3759                     {
3760                       *dfpm->permp = XNEW (dataflow_set);
3761                       dataflow_set_init (*dfpm->permp);
3762                     }
3763
3764                   for (att = (*dfpm->permp)->regs[REGNO (node->loc)];
3765                        att; att = att->next)
3766                     if (GET_MODE (att->loc) == GET_MODE (node->loc))
3767                       {
3768                         gcc_assert (att->offset == 0);
3769                         gcc_assert (dv_is_value_p (att->dv));
3770                         val_reset (set, att->dv);
3771                         break;
3772                       }
3773
3774                   if (att)
3775                     {
3776                       cdv = att->dv;
3777                       cval = dv_as_value (cdv);
3778                     }
3779                   else
3780                     {
3781                       /* Create a unique value to hold this register,
3782                          that ought to be found and reused in
3783                          subsequent rounds.  */
3784                       cselib_val *v;
3785                       gcc_assert (!cselib_lookup (node->loc,
3786                                                   GET_MODE (node->loc), 0));
3787                       v = cselib_lookup (node->loc, GET_MODE (node->loc), 1);
3788                       cselib_preserve_value (v);
3789                       cselib_invalidate_rtx (node->loc);
3790                       cval = v->val_rtx;
3791                       cdv = dv_from_value (cval);
3792                       if (dump_file)
3793                         fprintf (dump_file,
3794                                  "Created new value %u:%u for reg %i\n",
3795                                  v->uid, v->hash, REGNO (node->loc));
3796                     }
3797
3798                   var_reg_decl_set (*dfpm->permp, node->loc,
3799                                     VAR_INIT_STATUS_INITIALIZED,
3800                                     cdv, 0, NULL, INSERT);
3801
3802                   node->loc = cval;
3803                   check_dupes = true;
3804                 }
3805
3806               /* Remove attribute referring to the decl, which now
3807                  uses the value for the register, already existing or
3808                  to be added when we bring perm in.  */
3809               att = *curp;
3810               *curp = att->next;
3811               pool_free (attrs_pool, att);
3812             }
3813         }
3814
3815       if (check_dupes)
3816         remove_duplicate_values (var);
3817     }
3818
3819   return 1;
3820 }
3821
3822 /* Reset values in the permanent set that are not associated with the
3823    chosen expression.  */
3824
3825 static int
3826 variable_post_merge_perm_vals (void **pslot, void *info)
3827 {
3828   struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info;
3829   dataflow_set *set = dfpm->set;
3830   variable pvar = (variable)*pslot, var;
3831   location_chain pnode;
3832   decl_or_value dv;
3833   attrs att;
3834
3835   gcc_assert (dv_is_value_p (pvar->dv));
3836   gcc_assert (pvar->n_var_parts == 1);
3837   pnode = pvar->var_part[0].loc_chain;
3838   gcc_assert (pnode);
3839   gcc_assert (!pnode->next);
3840   gcc_assert (REG_P (pnode->loc));
3841
3842   dv = pvar->dv;
3843
3844   var = shared_hash_find (set->vars, dv);
3845   if (var)
3846     {
3847       if (find_loc_in_1pdv (pnode->loc, var, shared_hash_htab (set->vars)))
3848         return 1;
3849       val_reset (set, dv);
3850     }
3851
3852   for (att = set->regs[REGNO (pnode->loc)]; att; att = att->next)
3853     if (att->offset == 0
3854         && GET_MODE (att->loc) == GET_MODE (pnode->loc)
3855         && dv_is_value_p (att->dv))
3856       break;
3857
3858   /* If there is a value associated with this register already, create
3859      an equivalence.  */
3860   if (att && dv_as_value (att->dv) != dv_as_value (dv))
3861     {
3862       rtx cval = dv_as_value (att->dv);
3863       set_variable_part (set, cval, dv, 0, pnode->init, NULL, INSERT);
3864       set_variable_part (set, dv_as_value (dv), att->dv, 0, pnode->init,
3865                          NULL, INSERT);
3866     }
3867   else if (!att)
3868     {
3869       attrs_list_insert (&set->regs[REGNO (pnode->loc)],
3870                          dv, 0, pnode->loc);
3871       variable_union (pslot, set);
3872     }
3873
3874   return 1;
3875 }
3876
3877 /* Just checking stuff and registering register attributes for
3878    now.  */
3879
3880 static void
3881 dataflow_post_merge_adjust (dataflow_set *set, dataflow_set **permp)
3882 {
3883   struct dfset_post_merge dfpm;
3884
3885   dfpm.set = set;
3886   dfpm.permp = permp;
3887
3888   htab_traverse (shared_hash_htab (set->vars), variable_post_merge_new_vals,
3889                  &dfpm);
3890   if (*permp)
3891     htab_traverse (shared_hash_htab ((*permp)->vars),
3892                    variable_post_merge_perm_vals, &dfpm);
3893   htab_traverse (shared_hash_htab (set->vars), canonicalize_values_star, set);
3894   htab_traverse (shared_hash_htab (set->vars), canonicalize_vars_star, set);
3895 }
3896
3897 /* Return a node whose loc is a MEM that refers to EXPR in the
3898    location list of a one-part variable or value VAR, or in that of
3899    any values recursively mentioned in the location lists.  */
3900
3901 static location_chain
3902 find_mem_expr_in_1pdv (tree expr, rtx val, htab_t vars)
3903 {
3904   location_chain node;
3905   decl_or_value dv;
3906   variable var;
3907   location_chain where = NULL;
3908
3909   if (!val)
3910     return NULL;
3911
3912   gcc_assert (GET_CODE (val) == VALUE);
3913
3914   gcc_assert (!VALUE_RECURSED_INTO (val));
3915
3916   dv = dv_from_value (val);
3917   var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
3918
3919   if (!var)
3920     return NULL;
3921
3922   gcc_assert (dv_onepart_p (var->dv));
3923
3924   if (!var->n_var_parts)
3925     return NULL;
3926
3927   gcc_assert (var->var_part[0].offset == 0);
3928
3929   VALUE_RECURSED_INTO (val) = true;
3930
3931   for (node = var->var_part[0].loc_chain; node; node = node->next)
3932     if (MEM_P (node->loc) && MEM_EXPR (node->loc) == expr
3933         && MEM_OFFSET (node->loc) == 0)
3934       {
3935         where = node;
3936         break;
3937       }
3938     else if (GET_CODE (node->loc) == VALUE
3939              && !VALUE_RECURSED_INTO (node->loc)
3940              && (where = find_mem_expr_in_1pdv (expr, node->loc, vars)))
3941       break;
3942
3943   VALUE_RECURSED_INTO (val) = false;
3944
3945   return where;
3946 }
3947
3948 /* Return TRUE if the value of MEM may vary across a call.  */
3949
3950 static bool
3951 mem_dies_at_call (rtx mem)
3952 {
3953   tree expr = MEM_EXPR (mem);
3954   tree decl;
3955
3956   if (!expr)
3957     return true;
3958
3959   decl = get_base_address (expr);
3960
3961   if (!decl)
3962     return true;
3963
3964   if (!DECL_P (decl))
3965     return true;
3966
3967   return (may_be_aliased (decl)
3968           || (!TREE_READONLY (decl) && is_global_var (decl)));
3969 }
3970
3971 /* Remove all MEMs from the location list of a hash table entry for a
3972    one-part variable, except those whose MEM attributes map back to
3973    the variable itself, directly or within a VALUE.  */
3974
3975 static int
3976 dataflow_set_preserve_mem_locs (void **slot, void *data)
3977 {
3978   dataflow_set *set = (dataflow_set *) data;
3979   variable var = (variable) *slot;
3980
3981   if (dv_is_decl_p (var->dv) && dv_onepart_p (var->dv))
3982     {
3983       tree decl = dv_as_decl (var->dv);
3984       location_chain loc, *locp;
3985       bool changed = false;
3986
3987       if (!var->n_var_parts)
3988         return 1;
3989
3990       gcc_assert (var->n_var_parts == 1);
3991
3992       if (shared_var_p (var, set->vars))
3993         {
3994           for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
3995             {
3996               /* We want to remove dying MEMs that doesn't refer to
3997                  DECL.  */
3998               if (GET_CODE (loc->loc) == MEM
3999                   && (MEM_EXPR (loc->loc) != decl
4000                       || MEM_OFFSET (loc->loc))
4001                   && !mem_dies_at_call (loc->loc))
4002                 break;
4003               /* We want to move here MEMs that do refer to DECL.  */
4004               else if (GET_CODE (loc->loc) == VALUE
4005                        && find_mem_expr_in_1pdv (decl, loc->loc,
4006                                                  shared_hash_htab (set->vars)))
4007                 break;
4008             }
4009
4010           if (!loc)
4011             return 1;
4012
4013           slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
4014           var = (variable)*slot;
4015           gcc_assert (var->n_var_parts == 1);
4016         }
4017
4018       for (locp = &var->var_part[0].loc_chain, loc = *locp;
4019            loc; loc = *locp)
4020         {
4021           rtx old_loc = loc->loc;
4022           if (GET_CODE (old_loc) == VALUE)
4023             {
4024               location_chain mem_node
4025                 = find_mem_expr_in_1pdv (decl, loc->loc,
4026                                          shared_hash_htab (set->vars));
4027
4028               /* ??? This picks up only one out of multiple MEMs that
4029                  refer to the same variable.  Do we ever need to be
4030                  concerned about dealing with more than one, or, given
4031                  that they should all map to the same variable
4032                  location, their addresses will have been merged and
4033                  they will be regarded as equivalent?  */
4034               if (mem_node)
4035                 {
4036                   loc->loc = mem_node->loc;
4037                   loc->set_src = mem_node->set_src;
4038                   loc->init = MIN (loc->init, mem_node->init);
4039                 }
4040             }
4041
4042           if (GET_CODE (loc->loc) != MEM
4043               || (MEM_EXPR (loc->loc) == decl
4044                   && MEM_OFFSET (loc->loc) == 0)
4045               || !mem_dies_at_call (loc->loc))
4046             {
4047               if (old_loc != loc->loc && emit_notes)
4048                 {
4049                   if (old_loc == var->var_part[0].cur_loc)
4050                     {
4051                       changed = true;
4052                       var->var_part[0].cur_loc = NULL;
4053                       var->cur_loc_changed = true;
4054                     }
4055                   add_value_chains (var->dv, loc->loc);
4056                   remove_value_chains (var->dv, old_loc);
4057                 }
4058               locp = &loc->next;
4059               continue;
4060             }
4061
4062           if (emit_notes)
4063             {
4064               remove_value_chains (var->dv, old_loc);
4065               if (old_loc == var->var_part[0].cur_loc)
4066                 {
4067                   changed = true;
4068                   var->var_part[0].cur_loc = NULL;
4069                   var->cur_loc_changed = true;
4070                 }
4071             }
4072           *locp = loc->next;
4073           pool_free (loc_chain_pool, loc);
4074         }
4075
4076       if (!var->var_part[0].loc_chain)
4077         {
4078           var->n_var_parts--;
4079           changed = true;
4080         }
4081       if (changed)
4082         variable_was_changed (var, set);
4083     }
4084
4085   return 1;
4086 }
4087
4088 /* Remove all MEMs from the location list of a hash table entry for a
4089    value.  */
4090
4091 static int
4092 dataflow_set_remove_mem_locs (void **slot, void *data)
4093 {
4094   dataflow_set *set = (dataflow_set *) data;
4095   variable var = (variable) *slot;
4096
4097   if (dv_is_value_p (var->dv))
4098     {
4099       location_chain loc, *locp;
4100       bool changed = false;
4101
4102       gcc_assert (var->n_var_parts == 1);
4103
4104       if (shared_var_p (var, set->vars))
4105         {
4106           for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
4107             if (GET_CODE (loc->loc) == MEM
4108                 && mem_dies_at_call (loc->loc))
4109               break;
4110
4111           if (!loc)
4112             return 1;
4113
4114           slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
4115           var = (variable)*slot;
4116           gcc_assert (var->n_var_parts == 1);
4117         }
4118
4119       for (locp = &var->var_part[0].loc_chain, loc = *locp;
4120            loc; loc = *locp)
4121         {
4122           if (GET_CODE (loc->loc) != MEM
4123               || !mem_dies_at_call (loc->loc))
4124             {
4125               locp = &loc->next;
4126               continue;
4127             }
4128
4129           if (emit_notes)
4130             remove_value_chains (var->dv, loc->loc);
4131           *locp = loc->next;
4132           /* If we have deleted the location which was last emitted
4133              we have to emit new location so add the variable to set
4134              of changed variables.  */
4135           if (var->var_part[0].cur_loc == loc->loc)
4136             {
4137               changed = true;
4138               var->var_part[0].cur_loc = NULL;
4139               var->cur_loc_changed = true;
4140             }
4141           pool_free (loc_chain_pool, loc);
4142         }
4143
4144       if (!var->var_part[0].loc_chain)
4145         {
4146           var->n_var_parts--;
4147           changed = true;
4148         }
4149       if (changed)
4150         variable_was_changed (var, set);
4151     }
4152
4153   return 1;
4154 }
4155
4156 /* Remove all variable-location information about call-clobbered
4157    registers, as well as associations between MEMs and VALUEs.  */
4158
4159 static void
4160 dataflow_set_clear_at_call (dataflow_set *set)
4161 {
4162   int r;
4163
4164   for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
4165     if (TEST_HARD_REG_BIT (call_used_reg_set, r))
4166       var_regno_delete (set, r);
4167
4168   if (MAY_HAVE_DEBUG_INSNS)
4169     {
4170       set->traversed_vars = set->vars;
4171       htab_traverse (shared_hash_htab (set->vars),
4172                      dataflow_set_preserve_mem_locs, set);
4173       set->traversed_vars = set->vars;
4174       htab_traverse (shared_hash_htab (set->vars), dataflow_set_remove_mem_locs,
4175                      set);
4176       set->traversed_vars = NULL;
4177     }
4178 }
4179
4180 /* Flag whether two dataflow sets being compared contain different data.  */
4181 static bool
4182 dataflow_set_different_value;
4183
4184 static bool
4185 variable_part_different_p (variable_part *vp1, variable_part *vp2)
4186 {
4187   location_chain lc1, lc2;
4188
4189   for (lc1 = vp1->loc_chain; lc1; lc1 = lc1->next)
4190     {
4191       for (lc2 = vp2->loc_chain; lc2; lc2 = lc2->next)
4192         {
4193           if (REG_P (lc1->loc) && REG_P (lc2->loc))
4194             {
4195               if (REGNO (lc1->loc) == REGNO (lc2->loc))
4196                 break;
4197             }
4198           if (rtx_equal_p (lc1->loc, lc2->loc))
4199             break;
4200         }
4201       if (!lc2)
4202         return true;
4203     }
4204   return false;
4205 }
4206
4207 /* Return true if one-part variables VAR1 and VAR2 are different.
4208    They must be in canonical order.  */
4209
4210 static bool
4211 onepart_variable_different_p (variable var1, variable var2)
4212 {
4213   location_chain lc1, lc2;
4214
4215   if (var1 == var2)
4216     return false;
4217
4218   gcc_assert (var1->n_var_parts == 1);
4219   gcc_assert (var2->n_var_parts == 1);
4220
4221   lc1 = var1->var_part[0].loc_chain;
4222   lc2 = var2->var_part[0].loc_chain;
4223
4224   gcc_assert (lc1);
4225   gcc_assert (lc2);
4226
4227   while (lc1 && lc2)
4228     {
4229       if (loc_cmp (lc1->loc, lc2->loc))
4230         return true;
4231       lc1 = lc1->next;
4232       lc2 = lc2->next;
4233     }
4234
4235   return lc1 != lc2;
4236 }
4237
4238 /* Return true if variables VAR1 and VAR2 are different.  */
4239
4240 static bool
4241 variable_different_p (variable var1, variable var2)
4242 {
4243   int i;
4244
4245   if (var1 == var2)
4246     return false;
4247
4248   if (var1->n_var_parts != var2->n_var_parts)
4249     return true;
4250
4251   for (i = 0; i < var1->n_var_parts; i++)
4252     {
4253       if (var1->var_part[i].offset != var2->var_part[i].offset)
4254         return true;
4255       /* One-part values have locations in a canonical order.  */
4256       if (i == 0 && var1->var_part[i].offset == 0 && dv_onepart_p (var1->dv))
4257         {
4258           gcc_assert (var1->n_var_parts == 1);
4259           gcc_assert (dv_as_opaque (var1->dv) == dv_as_opaque (var2->dv));
4260           return onepart_variable_different_p (var1, var2);
4261         }
4262       if (variable_part_different_p (&var1->var_part[i], &var2->var_part[i]))
4263         return true;
4264       if (variable_part_different_p (&var2->var_part[i], &var1->var_part[i]))
4265         return true;
4266     }
4267   return false;
4268 }
4269
4270 /* Compare variable *SLOT with the same variable in hash table DATA
4271    and set DATAFLOW_SET_DIFFERENT_VALUE if they are different.  */
4272
4273 static int
4274 dataflow_set_different_1 (void **slot, void *data)
4275 {
4276   htab_t htab = (htab_t) data;
4277   variable var1, var2;
4278
4279   var1 = (variable) *slot;
4280   var2 = (variable) htab_find_with_hash (htab, var1->dv,
4281                                          dv_htab_hash (var1->dv));
4282   if (!var2)
4283     {
4284       dataflow_set_different_value = true;
4285
4286       if (dump_file && (dump_flags & TDF_DETAILS))
4287         {
4288           fprintf (dump_file, "dataflow difference found: removal of:\n");
4289           dump_var (var1);
4290         }
4291
4292       /* Stop traversing the hash table.  */
4293       return 0;
4294     }
4295
4296   if (variable_different_p (var1, var2))
4297     {
4298       dataflow_set_different_value = true;
4299
4300       if (dump_file && (dump_flags & TDF_DETAILS))
4301         {
4302           fprintf (dump_file, "dataflow difference found: old and new follow:\n");
4303           dump_var (var1);
4304           dump_var (var2);
4305         }
4306
4307       /* Stop traversing the hash table.  */
4308       return 0;
4309     }
4310
4311   /* Continue traversing the hash table.  */
4312   return 1;
4313 }
4314
4315 /* Return true if dataflow sets OLD_SET and NEW_SET differ.  */
4316
4317 static bool
4318 dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
4319 {
4320   if (old_set->vars == new_set->vars)
4321     return false;
4322
4323   if (htab_elements (shared_hash_htab (old_set->vars))
4324       != htab_elements (shared_hash_htab (new_set->vars)))
4325     return true;
4326
4327   dataflow_set_different_value = false;
4328
4329   htab_traverse (shared_hash_htab (old_set->vars), dataflow_set_different_1,
4330                  shared_hash_htab (new_set->vars));
4331   /* No need to traverse the second hashtab, if both have the same number
4332      of elements and the second one had all entries found in the first one,
4333      then it can't have any extra entries.  */
4334   return dataflow_set_different_value;
4335 }
4336
4337 /* Free the contents of dataflow set SET.  */
4338
4339 static void
4340 dataflow_set_destroy (dataflow_set *set)
4341 {
4342   int i;
4343
4344   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4345     attrs_list_clear (&set->regs[i]);
4346
4347   shared_hash_destroy (set->vars);
4348   set->vars = NULL;
4349 }
4350
4351 /* Return true if RTL X contains a SYMBOL_REF.  */
4352
4353 static bool
4354 contains_symbol_ref (rtx x)
4355 {
4356   const char *fmt;
4357   RTX_CODE code;
4358   int i;
4359
4360   if (!x)
4361     return false;
4362
4363   code = GET_CODE (x);
4364   if (code == SYMBOL_REF)
4365     return true;
4366
4367   fmt = GET_RTX_FORMAT (code);
4368   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4369     {
4370       if (fmt[i] == 'e')
4371         {
4372           if (contains_symbol_ref (XEXP (x, i)))
4373             return true;
4374         }
4375       else if (fmt[i] == 'E')
4376         {
4377           int j;
4378           for (j = 0; j < XVECLEN (x, i); j++)
4379             if (contains_symbol_ref (XVECEXP (x, i, j)))
4380               return true;
4381         }
4382     }
4383
4384   return false;
4385 }
4386
4387 /* Shall EXPR be tracked?  */
4388
4389 static bool
4390 track_expr_p (tree expr, bool need_rtl)
4391 {
4392   rtx decl_rtl;
4393   tree realdecl;
4394
4395   if (TREE_CODE (expr) == DEBUG_EXPR_DECL)
4396     return DECL_RTL_SET_P (expr);
4397
4398   /* If EXPR is not a parameter or a variable do not track it.  */
4399   if (TREE_CODE (expr) != VAR_DECL && TREE_CODE (expr) != PARM_DECL)
4400     return 0;
4401
4402   /* It also must have a name...  */
4403   if (!DECL_NAME (expr) && need_rtl)
4404     return 0;
4405
4406   /* ... and a RTL assigned to it.  */
4407   decl_rtl = DECL_RTL_IF_SET (expr);
4408   if (!decl_rtl && need_rtl)
4409     return 0;
4410
4411   /* If this expression is really a debug alias of some other declaration, we
4412      don't need to track this expression if the ultimate declaration is
4413      ignored.  */
4414   realdecl = expr;
4415   if (DECL_DEBUG_EXPR_IS_FROM (realdecl) && DECL_DEBUG_EXPR (realdecl))
4416     {
4417       realdecl = DECL_DEBUG_EXPR (realdecl);
4418       /* ??? We don't yet know how to emit DW_OP_piece for variable
4419          that has been SRA'ed.  */
4420       if (!DECL_P (realdecl))
4421         return 0;
4422     }
4423
4424   /* Do not track EXPR if REALDECL it should be ignored for debugging
4425      purposes.  */
4426   if (DECL_IGNORED_P (realdecl))
4427     return 0;
4428
4429   /* Do not track global variables until we are able to emit correct location
4430      list for them.  */
4431   if (TREE_STATIC (realdecl))
4432     return 0;
4433
4434   /* When the EXPR is a DECL for alias of some variable (see example)
4435      the TREE_STATIC flag is not used.  Disable tracking all DECLs whose
4436      DECL_RTL contains SYMBOL_REF.
4437
4438      Example:
4439      extern char **_dl_argv_internal __attribute__ ((alias ("_dl_argv")));
4440      char **_dl_argv;
4441   */
4442   if (decl_rtl && MEM_P (decl_rtl)
4443       && contains_symbol_ref (XEXP (decl_rtl, 0)))
4444     return 0;
4445
4446   /* If RTX is a memory it should not be very large (because it would be
4447      an array or struct).  */
4448   if (decl_rtl && MEM_P (decl_rtl))
4449     {
4450       /* Do not track structures and arrays.  */
4451       if (GET_MODE (decl_rtl) == BLKmode
4452           || AGGREGATE_TYPE_P (TREE_TYPE (realdecl)))
4453         return 0;
4454       if (MEM_SIZE (decl_rtl)
4455           && INTVAL (MEM_SIZE (decl_rtl)) > MAX_VAR_PARTS)
4456         return 0;
4457     }
4458
4459   DECL_CHANGED (expr) = 0;
4460   DECL_CHANGED (realdecl) = 0;
4461   return 1;
4462 }
4463
4464 /* Determine whether a given LOC refers to the same variable part as
4465    EXPR+OFFSET.  */
4466
4467 static bool
4468 same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset)
4469 {
4470   tree expr2;
4471   HOST_WIDE_INT offset2;
4472
4473   if (! DECL_P (expr))
4474     return false;
4475
4476   if (REG_P (loc))
4477     {
4478       expr2 = REG_EXPR (loc);
4479       offset2 = REG_OFFSET (loc);
4480     }
4481   else if (MEM_P (loc))
4482     {
4483       expr2 = MEM_EXPR (loc);
4484       offset2 = INT_MEM_OFFSET (loc);
4485     }
4486   else
4487     return false;
4488
4489   if (! expr2 || ! DECL_P (expr2))
4490     return false;
4491
4492   expr = var_debug_decl (expr);
4493   expr2 = var_debug_decl (expr2);
4494
4495   return (expr == expr2 && offset == offset2);
4496 }
4497
4498 /* LOC is a REG or MEM that we would like to track if possible.
4499    If EXPR is null, we don't know what expression LOC refers to,
4500    otherwise it refers to EXPR + OFFSET.  STORE_REG_P is true if
4501    LOC is an lvalue register.
4502
4503    Return true if EXPR is nonnull and if LOC, or some lowpart of it,
4504    is something we can track.  When returning true, store the mode of
4505    the lowpart we can track in *MODE_OUT (if nonnull) and its offset
4506    from EXPR in *OFFSET_OUT (if nonnull).  */
4507
4508 static bool
4509 track_loc_p (rtx loc, tree expr, HOST_WIDE_INT offset, bool store_reg_p,
4510              enum machine_mode *mode_out, HOST_WIDE_INT *offset_out)
4511 {
4512   enum machine_mode mode;
4513
4514   if (expr == NULL || !track_expr_p (expr, true))
4515     return false;
4516
4517   /* If REG was a paradoxical subreg, its REG_ATTRS will describe the
4518      whole subreg, but only the old inner part is really relevant.  */
4519   mode = GET_MODE (loc);
4520   if (REG_P (loc) && !HARD_REGISTER_NUM_P (ORIGINAL_REGNO (loc)))
4521     {
4522       enum machine_mode pseudo_mode;
4523
4524       pseudo_mode = PSEUDO_REGNO_MODE (ORIGINAL_REGNO (loc));
4525       if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (pseudo_mode))
4526         {
4527           offset += byte_lowpart_offset (pseudo_mode, mode);
4528           mode = pseudo_mode;
4529         }
4530     }
4531
4532   /* If LOC is a paradoxical lowpart of EXPR, refer to EXPR itself.
4533      Do the same if we are storing to a register and EXPR occupies
4534      the whole of register LOC; in that case, the whole of EXPR is
4535      being changed.  We exclude complex modes from the second case
4536      because the real and imaginary parts are represented as separate
4537      pseudo registers, even if the whole complex value fits into one
4538      hard register.  */
4539   if ((GET_MODE_SIZE (mode) > GET_MODE_SIZE (DECL_MODE (expr))
4540        || (store_reg_p
4541            && !COMPLEX_MODE_P (DECL_MODE (expr))
4542            && hard_regno_nregs[REGNO (loc)][DECL_MODE (expr)] == 1))
4543       && offset + byte_lowpart_offset (DECL_MODE (expr), mode) == 0)
4544     {
4545       mode = DECL_MODE (expr);
4546       offset = 0;
4547     }
4548
4549   if (offset < 0 || offset >= MAX_VAR_PARTS)
4550     return false;
4551
4552   if (mode_out)
4553     *mode_out = mode;
4554   if (offset_out)
4555     *offset_out = offset;
4556   return true;
4557 }
4558
4559 /* Return the MODE lowpart of LOC, or null if LOC is not something we
4560    want to track.  When returning nonnull, make sure that the attributes
4561    on the returned value are updated.  */
4562
4563 static rtx
4564 var_lowpart (enum machine_mode mode, rtx loc)
4565 {
4566   unsigned int offset, reg_offset, regno;
4567
4568   if (!REG_P (loc) && !MEM_P (loc))
4569     return NULL;
4570
4571   if (GET_MODE (loc) == mode)
4572     return loc;
4573
4574   offset = byte_lowpart_offset (mode, GET_MODE (loc));
4575
4576   if (MEM_P (loc))
4577     return adjust_address_nv (loc, mode, offset);
4578
4579   reg_offset = subreg_lowpart_offset (mode, GET_MODE (loc));
4580   regno = REGNO (loc) + subreg_regno_offset (REGNO (loc), GET_MODE (loc),
4581                                              reg_offset, mode);
4582   return gen_rtx_REG_offset (loc, mode, regno, offset);
4583 }
4584
4585 /* arg_pointer_rtx resp. frame_pointer_rtx if stack_pointer_rtx or
4586    hard_frame_pointer_rtx is being mapped to it.  */
4587 static rtx cfa_base_rtx;
4588
4589 /* Carry information about uses and stores while walking rtx.  */
4590
4591 struct count_use_info
4592 {
4593   /* The insn where the RTX is.  */
4594   rtx insn;
4595
4596   /* The basic block where insn is.  */
4597   basic_block bb;
4598
4599   /* The array of n_sets sets in the insn, as determined by cselib.  */
4600   struct cselib_set *sets;
4601   int n_sets;
4602
4603   /* True if we're counting stores, false otherwise.  */
4604   bool store_p;
4605 };
4606
4607 /* Find a VALUE corresponding to X.   */
4608
4609 static inline cselib_val *
4610 find_use_val (rtx x, enum machine_mode mode, struct count_use_info *cui)
4611 {
4612   int i;
4613
4614   if (cui->sets)
4615     {
4616       /* This is called after uses are set up and before stores are
4617          processed bycselib, so it's safe to look up srcs, but not
4618          dsts.  So we look up expressions that appear in srcs or in
4619          dest expressions, but we search the sets array for dests of
4620          stores.  */
4621       if (cui->store_p)
4622         {
4623           for (i = 0; i < cui->n_sets; i++)
4624             if (cui->sets[i].dest == x)
4625               return cui->sets[i].src_elt;
4626         }
4627       else
4628         return cselib_lookup (x, mode, 0);
4629     }
4630
4631   return NULL;
4632 }
4633
4634 /* Helper function to get mode of MEM's address.  */
4635
4636 static inline enum machine_mode
4637 get_address_mode (rtx mem)
4638 {
4639   enum machine_mode mode = GET_MODE (XEXP (mem, 0));
4640   if (mode != VOIDmode)
4641     return mode;
4642   return targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
4643 }
4644
4645 /* Replace all registers and addresses in an expression with VALUE
4646    expressions that map back to them, unless the expression is a
4647    register.  If no mapping is or can be performed, returns NULL.  */
4648
4649 static rtx
4650 replace_expr_with_values (rtx loc)
4651 {
4652   if (REG_P (loc))
4653     return NULL;
4654   else if (MEM_P (loc))
4655     {
4656       cselib_val *addr = cselib_lookup (XEXP (loc, 0),
4657                                         get_address_mode (loc), 0);
4658       if (addr)
4659         return replace_equiv_address_nv (loc, addr->val_rtx);
4660       else
4661         return NULL;
4662     }
4663   else
4664     return cselib_subst_to_values (loc);
4665 }
4666
4667 /* Determine what kind of micro operation to choose for a USE.  Return
4668    MO_CLOBBER if no micro operation is to be generated.  */
4669
4670 static enum micro_operation_type
4671 use_type (rtx loc, struct count_use_info *cui, enum machine_mode *modep)
4672 {
4673   tree expr;
4674
4675   if (cui && cui->sets)
4676     {
4677       if (GET_CODE (loc) == VAR_LOCATION)
4678         {
4679           if (track_expr_p (PAT_VAR_LOCATION_DECL (loc), false))
4680             {
4681               rtx ploc = PAT_VAR_LOCATION_LOC (loc);
4682               if (! VAR_LOC_UNKNOWN_P (ploc))
4683                 {
4684                   cselib_val *val = cselib_lookup (ploc, GET_MODE (loc), 1);
4685
4686                   /* ??? flag_float_store and volatile mems are never
4687                      given values, but we could in theory use them for
4688                      locations.  */
4689                   gcc_assert (val || 1);
4690                 }
4691               return MO_VAL_LOC;
4692             }
4693           else
4694             return MO_CLOBBER;
4695         }
4696
4697       if (REG_P (loc) || MEM_P (loc))
4698         {
4699           if (modep)
4700             *modep = GET_MODE (loc);
4701           if (cui->store_p)
4702             {
4703               if (REG_P (loc)
4704                   || (find_use_val (loc, GET_MODE (loc), cui)
4705                       && cselib_lookup (XEXP (loc, 0),
4706                                         get_address_mode (loc), 0)))
4707                 return MO_VAL_SET;
4708             }
4709           else
4710             {
4711               cselib_val *val = find_use_val (loc, GET_MODE (loc), cui);
4712
4713               if (val && !cselib_preserved_value_p (val))
4714                 return MO_VAL_USE;
4715             }
4716         }
4717     }
4718
4719   if (REG_P (loc))
4720     {
4721       gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
4722
4723       if (loc == cfa_base_rtx)
4724         return MO_CLOBBER;
4725       expr = REG_EXPR (loc);
4726
4727       if (!expr)
4728         return MO_USE_NO_VAR;
4729       else if (target_for_debug_bind (var_debug_decl (expr)))
4730         return MO_CLOBBER;
4731       else if (track_loc_p (loc, expr, REG_OFFSET (loc),
4732                             false, modep, NULL))
4733         return MO_USE;
4734       else
4735         return MO_USE_NO_VAR;
4736     }
4737   else if (MEM_P (loc))
4738     {
4739       expr = MEM_EXPR (loc);
4740
4741       if (!expr)
4742         return MO_CLOBBER;
4743       else if (target_for_debug_bind (var_debug_decl (expr)))
4744         return MO_CLOBBER;
4745       else if (track_loc_p (loc, expr, INT_MEM_OFFSET (loc),
4746                             false, modep, NULL))
4747         return MO_USE;
4748       else
4749         return MO_CLOBBER;
4750     }
4751
4752   return MO_CLOBBER;
4753 }
4754
4755 /* Log to OUT information about micro-operation MOPT involving X in
4756    INSN of BB.  */
4757
4758 static inline void
4759 log_op_type (rtx x, basic_block bb, rtx insn,
4760              enum micro_operation_type mopt, FILE *out)
4761 {
4762   fprintf (out, "bb %i op %i insn %i %s ",
4763            bb->index, VEC_length (micro_operation, VTI (bb)->mos),
4764            INSN_UID (insn), micro_operation_type_name[mopt]);
4765   print_inline_rtx (out, x, 2);
4766   fputc ('\n', out);
4767 }
4768
4769 /* Tell whether the CONCAT used to holds a VALUE and its location
4770    needs value resolution, i.e., an attempt of mapping the location
4771    back to other incoming values.  */
4772 #define VAL_NEEDS_RESOLUTION(x) \
4773   (RTL_FLAG_CHECK1 ("VAL_NEEDS_RESOLUTION", (x), CONCAT)->volatil)
4774 /* Whether the location in the CONCAT is a tracked expression, that
4775    should also be handled like a MO_USE.  */
4776 #define VAL_HOLDS_TRACK_EXPR(x) \
4777   (RTL_FLAG_CHECK1 ("VAL_HOLDS_TRACK_EXPR", (x), CONCAT)->used)
4778 /* Whether the location in the CONCAT should be handled like a MO_COPY
4779    as well.  */
4780 #define VAL_EXPR_IS_COPIED(x) \
4781   (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_COPIED", (x), CONCAT)->jump)
4782 /* Whether the location in the CONCAT should be handled like a
4783    MO_CLOBBER as well.  */
4784 #define VAL_EXPR_IS_CLOBBERED(x) \
4785   (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_CLOBBERED", (x), CONCAT)->unchanging)
4786 /* Whether the location is a CONCAT of the MO_VAL_SET expression and
4787    a reverse operation that should be handled afterwards.  */
4788 #define VAL_EXPR_HAS_REVERSE(x) \
4789   (RTL_FLAG_CHECK1 ("VAL_EXPR_HAS_REVERSE", (x), CONCAT)->return_val)
4790
4791 /* All preserved VALUEs.  */
4792 static VEC (rtx, heap) *preserved_values;
4793
4794 /* Ensure VAL is preserved and remember it in a vector for vt_emit_notes.  */
4795
4796 static void
4797 preserve_value (cselib_val *val)
4798 {
4799   cselib_preserve_value (val);
4800   VEC_safe_push (rtx, heap, preserved_values, val->val_rtx);
4801 }
4802
4803 /* Helper function for MO_VAL_LOC handling.  Return non-zero if
4804    any rtxes not suitable for CONST use not replaced by VALUEs
4805    are discovered.  */
4806
4807 static int
4808 non_suitable_const (rtx *x, void *data ATTRIBUTE_UNUSED)
4809 {
4810   if (*x == NULL_RTX)
4811     return 0;
4812
4813   switch (GET_CODE (*x))
4814     {
4815     case REG:
4816     case DEBUG_EXPR:
4817     case PC:
4818     case SCRATCH:
4819     case CC0:
4820     case ASM_INPUT:
4821     case ASM_OPERANDS:
4822       return 1;
4823     case MEM:
4824       return !MEM_READONLY_P (*x);
4825     default:
4826       return 0;
4827     }
4828 }
4829
4830 /* Add uses (register and memory references) LOC which will be tracked
4831    to VTI (bb)->mos.  INSN is instruction which the LOC is part of.  */
4832
4833 static int
4834 add_uses (rtx *ploc, void *data)
4835 {
4836   rtx loc = *ploc;
4837   enum machine_mode mode = VOIDmode;
4838   struct count_use_info *cui = (struct count_use_info *)data;
4839   enum micro_operation_type type = use_type (loc, cui, &mode);
4840
4841   if (type != MO_CLOBBER)
4842     {
4843       basic_block bb = cui->bb;
4844       micro_operation mo;
4845
4846       mo.type = type;
4847       mo.u.loc = type == MO_USE ? var_lowpart (mode, loc) : loc;
4848       mo.insn = cui->insn;
4849
4850       if (type == MO_VAL_LOC)
4851         {
4852           rtx oloc = loc;
4853           rtx vloc = PAT_VAR_LOCATION_LOC (oloc);
4854           cselib_val *val;
4855
4856           gcc_assert (cui->sets);
4857
4858           if (MEM_P (vloc)
4859               && !REG_P (XEXP (vloc, 0))
4860               && !MEM_P (XEXP (vloc, 0))
4861               && (GET_CODE (XEXP (vloc, 0)) != PLUS
4862                   || XEXP (XEXP (vloc, 0), 0) != cfa_base_rtx
4863                   || !CONST_INT_P (XEXP (XEXP (vloc, 0), 1))))
4864             {
4865               rtx mloc = vloc;
4866               enum machine_mode address_mode = get_address_mode (mloc);
4867               cselib_val *val
4868                 = cselib_lookup (XEXP (mloc, 0), address_mode, 0);
4869
4870               if (val && !cselib_preserved_value_p (val))
4871                 {
4872                   micro_operation moa;
4873                   preserve_value (val);
4874                   mloc = cselib_subst_to_values (XEXP (mloc, 0));
4875                   moa.type = MO_VAL_USE;
4876                   moa.insn = cui->insn;
4877                   moa.u.loc = gen_rtx_CONCAT (address_mode,
4878                                               val->val_rtx, mloc);
4879                   if (dump_file && (dump_flags & TDF_DETAILS))
4880                     log_op_type (moa.u.loc, cui->bb, cui->insn,
4881                                  moa.type, dump_file);
4882                   VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &moa);
4883                 }
4884             }
4885
4886           if (CONSTANT_P (vloc)
4887               && (GET_CODE (vloc) != CONST
4888                   || for_each_rtx (&vloc, non_suitable_const, NULL)))
4889             /* For constants don't look up any value.  */;
4890           else if (!VAR_LOC_UNKNOWN_P (vloc)
4891                    && (val = find_use_val (vloc, GET_MODE (oloc), cui)))
4892             {
4893               enum machine_mode mode2;
4894               enum micro_operation_type type2;
4895               rtx nloc = replace_expr_with_values (vloc);
4896
4897               if (nloc)
4898                 {
4899                   oloc = shallow_copy_rtx (oloc);
4900                   PAT_VAR_LOCATION_LOC (oloc) = nloc;
4901                 }
4902
4903               oloc = gen_rtx_CONCAT (mode, val->val_rtx, oloc);
4904
4905               type2 = use_type (vloc, 0, &mode2);
4906
4907               gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
4908                           || type2 == MO_CLOBBER);
4909
4910               if (type2 == MO_CLOBBER
4911                   && !cselib_preserved_value_p (val))
4912                 {
4913                   VAL_NEEDS_RESOLUTION (oloc) = 1;
4914                   preserve_value (val);
4915                 }
4916             }
4917           else if (!VAR_LOC_UNKNOWN_P (vloc))
4918             {
4919               oloc = shallow_copy_rtx (oloc);
4920               PAT_VAR_LOCATION_LOC (oloc) = gen_rtx_UNKNOWN_VAR_LOC ();
4921             }
4922
4923           mo.u.loc = oloc;
4924         }
4925       else if (type == MO_VAL_USE)
4926         {
4927           enum machine_mode mode2 = VOIDmode;
4928           enum micro_operation_type type2;
4929           cselib_val *val = find_use_val (loc, GET_MODE (loc), cui);
4930           rtx vloc, oloc = loc, nloc;
4931
4932           gcc_assert (cui->sets);
4933
4934           if (MEM_P (oloc)
4935               && !REG_P (XEXP (oloc, 0))
4936               && !MEM_P (XEXP (oloc, 0))
4937               && (GET_CODE (XEXP (oloc, 0)) != PLUS
4938                   || XEXP (XEXP (oloc, 0), 0) != cfa_base_rtx
4939                   || !CONST_INT_P (XEXP (XEXP (oloc, 0), 1))))
4940             {
4941               rtx mloc = oloc;
4942               enum machine_mode address_mode = get_address_mode (mloc);
4943               cselib_val *val
4944                 = cselib_lookup (XEXP (mloc, 0), address_mode, 0);
4945
4946               if (val && !cselib_preserved_value_p (val))
4947                 {
4948                   micro_operation moa;
4949                   preserve_value (val);
4950                   mloc = cselib_subst_to_values (XEXP (mloc, 0));
4951                   moa.type = MO_VAL_USE;
4952                   moa.insn = cui->insn;
4953                   moa.u.loc = gen_rtx_CONCAT (address_mode,
4954                                               val->val_rtx, mloc);
4955                   if (dump_file && (dump_flags & TDF_DETAILS))
4956                     log_op_type (moa.u.loc, cui->bb, cui->insn,
4957                                  moa.type, dump_file);
4958                   VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &moa);
4959                 }
4960             }
4961
4962           type2 = use_type (loc, 0, &mode2);
4963
4964           gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
4965                       || type2 == MO_CLOBBER);
4966
4967           if (type2 == MO_USE)
4968             vloc = var_lowpart (mode2, loc);
4969           else
4970             vloc = oloc;
4971
4972           /* The loc of a MO_VAL_USE may have two forms:
4973
4974              (concat val src): val is at src, a value-based
4975              representation.
4976
4977              (concat (concat val use) src): same as above, with use as
4978              the MO_USE tracked value, if it differs from src.
4979
4980           */
4981
4982           nloc = replace_expr_with_values (loc);
4983           if (!nloc)
4984             nloc = oloc;
4985
4986           if (vloc != nloc)
4987             oloc = gen_rtx_CONCAT (mode2, val->val_rtx, vloc);
4988           else
4989             oloc = val->val_rtx;
4990
4991           mo.u.loc = gen_rtx_CONCAT (mode, oloc, nloc);
4992
4993           if (type2 == MO_USE)
4994             VAL_HOLDS_TRACK_EXPR (mo.u.loc) = 1;
4995           if (!cselib_preserved_value_p (val))
4996             {
4997               VAL_NEEDS_RESOLUTION (mo.u.loc) = 1;
4998               preserve_value (val);
4999             }
5000         }
5001       else
5002         gcc_assert (type == MO_USE || type == MO_USE_NO_VAR);
5003
5004       if (dump_file && (dump_flags & TDF_DETAILS))
5005         log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
5006       VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
5007     }
5008
5009   return 0;
5010 }
5011
5012 /* Helper function for finding all uses of REG/MEM in X in insn INSN.  */
5013
5014 static void
5015 add_uses_1 (rtx *x, void *cui)
5016 {
5017   for_each_rtx (x, add_uses, cui);
5018 }
5019
5020 /* Attempt to reverse the EXPR operation in the debug info.  Say for
5021    reg1 = reg2 + 6 even when reg2 is no longer live we
5022    can express its value as VAL - 6.  */
5023
5024 static rtx
5025 reverse_op (rtx val, const_rtx expr)
5026 {
5027   rtx src, arg, ret;
5028   cselib_val *v;
5029   enum rtx_code code;
5030
5031   if (GET_CODE (expr) != SET)
5032     return NULL_RTX;
5033
5034   if (!REG_P (SET_DEST (expr)) || GET_MODE (val) != GET_MODE (SET_DEST (expr)))
5035     return NULL_RTX;
5036
5037   src = SET_SRC (expr);
5038   switch (GET_CODE (src))
5039     {
5040     case PLUS:
5041     case MINUS:
5042     case XOR:
5043     case NOT:
5044     case NEG:
5045     case SIGN_EXTEND:
5046     case ZERO_EXTEND:
5047       break;
5048     default:
5049       return NULL_RTX;
5050     }
5051
5052   if (!REG_P (XEXP (src, 0)) || !SCALAR_INT_MODE_P (GET_MODE (src)))
5053     return NULL_RTX;
5054
5055   v = cselib_lookup (XEXP (src, 0), GET_MODE (XEXP (src, 0)), 0);
5056   if (!v || !cselib_preserved_value_p (v))
5057     return NULL_RTX;
5058
5059   switch (GET_CODE (src))
5060     {
5061     case NOT:
5062     case NEG:
5063       if (GET_MODE (v->val_rtx) != GET_MODE (val))
5064         return NULL_RTX;
5065       ret = gen_rtx_fmt_e (GET_CODE (src), GET_MODE (val), val);
5066       break;
5067     case SIGN_EXTEND:
5068     case ZERO_EXTEND:
5069       ret = gen_lowpart_SUBREG (GET_MODE (v->val_rtx), val);
5070       break;
5071     case XOR:
5072       code = XOR;
5073       goto binary;
5074     case PLUS:
5075       code = MINUS;
5076       goto binary;
5077     case MINUS:
5078       code = PLUS;
5079       goto binary;
5080     binary:
5081       if (GET_MODE (v->val_rtx) != GET_MODE (val))
5082         return NULL_RTX;
5083       arg = XEXP (src, 1);
5084       if (!CONST_INT_P (arg) && GET_CODE (arg) != SYMBOL_REF)
5085         {
5086           arg = cselib_expand_value_rtx (arg, scratch_regs, 5);
5087           if (arg == NULL_RTX)
5088             return NULL_RTX;
5089           if (!CONST_INT_P (arg) && GET_CODE (arg) != SYMBOL_REF)
5090             return NULL_RTX;
5091         }
5092       ret = simplify_gen_binary (code, GET_MODE (val), val, arg);
5093       if (ret == val)
5094         /* Ensure ret isn't VALUE itself (which can happen e.g. for
5095            (plus (reg1) (reg2)) when reg2 is known to be 0), as that
5096            breaks a lot of routines during var-tracking.  */
5097         ret = gen_rtx_fmt_ee (PLUS, GET_MODE (val), val, const0_rtx);
5098       break;
5099     default:
5100       gcc_unreachable ();
5101     }
5102
5103   return gen_rtx_CONCAT (GET_MODE (v->val_rtx), v->val_rtx, ret);
5104 }
5105
5106 /* Add stores (register and memory references) LOC which will be tracked
5107    to VTI (bb)->mos.  EXPR is the RTL expression containing the store.
5108    CUIP->insn is instruction which the LOC is part of.  */
5109
5110 static void
5111 add_stores (rtx loc, const_rtx expr, void *cuip)
5112 {
5113   enum machine_mode mode = VOIDmode, mode2;
5114   struct count_use_info *cui = (struct count_use_info *)cuip;
5115   basic_block bb = cui->bb;
5116   micro_operation mo;
5117   rtx oloc = loc, nloc, src = NULL;
5118   enum micro_operation_type type = use_type (loc, cui, &mode);
5119   bool track_p = false;
5120   cselib_val *v;
5121   bool resolve, preserve;
5122   rtx reverse;
5123
5124   if (type == MO_CLOBBER)
5125     return;
5126
5127   mode2 = mode;
5128
5129   if (REG_P (loc))
5130     {
5131       gcc_assert (loc != cfa_base_rtx);
5132       if ((GET_CODE (expr) == CLOBBER && type != MO_VAL_SET)
5133           || !(track_p = use_type (loc, NULL, &mode2) == MO_USE)
5134           || GET_CODE (expr) == CLOBBER)
5135         {
5136           mo.type = MO_CLOBBER;
5137           mo.u.loc = loc;
5138         }
5139       else
5140         {
5141           if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
5142             src = var_lowpart (mode2, SET_SRC (expr));
5143           loc = var_lowpart (mode2, loc);
5144
5145           if (src == NULL)
5146             {
5147               mo.type = MO_SET;
5148               mo.u.loc = loc;
5149             }
5150           else
5151             {
5152               rtx xexpr = gen_rtx_SET (VOIDmode, loc, src);
5153               if (same_variable_part_p (src, REG_EXPR (loc), REG_OFFSET (loc)))
5154                 mo.type = MO_COPY;
5155               else
5156                 mo.type = MO_SET;
5157               mo.u.loc = xexpr;
5158             }
5159         }
5160       mo.insn = cui->insn;
5161     }
5162   else if (MEM_P (loc)
5163            && ((track_p = use_type (loc, NULL, &mode2) == MO_USE)
5164                || cui->sets))
5165     {
5166       if (MEM_P (loc) && type == MO_VAL_SET
5167           && !REG_P (XEXP (loc, 0))
5168           && !MEM_P (XEXP (loc, 0))
5169           && (GET_CODE (XEXP (loc, 0)) != PLUS
5170               || XEXP (XEXP (loc, 0), 0) != cfa_base_rtx
5171               || !CONST_INT_P (XEXP (XEXP (loc, 0), 1))))
5172         {
5173           rtx mloc = loc;
5174           enum machine_mode address_mode = get_address_mode (mloc);
5175           cselib_val *val = cselib_lookup (XEXP (mloc, 0),
5176                                            address_mode, 0);
5177
5178           if (val && !cselib_preserved_value_p (val))
5179             {
5180               preserve_value (val);
5181               mo.type = MO_VAL_USE;
5182               mloc = cselib_subst_to_values (XEXP (mloc, 0));
5183               mo.u.loc = gen_rtx_CONCAT (address_mode, val->val_rtx, mloc);
5184               mo.insn = cui->insn;
5185               if (dump_file && (dump_flags & TDF_DETAILS))
5186                 log_op_type (mo.u.loc, cui->bb, cui->insn,
5187                              mo.type, dump_file);
5188               VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
5189             }
5190         }
5191
5192       if (GET_CODE (expr) == CLOBBER || !track_p)
5193         {
5194           mo.type = MO_CLOBBER;
5195           mo.u.loc = track_p ? var_lowpart (mode2, loc) : loc;
5196         }
5197       else
5198         {
5199           if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
5200             src = var_lowpart (mode2, SET_SRC (expr));
5201           loc = var_lowpart (mode2, loc);
5202
5203           if (src == NULL)
5204             {
5205               mo.type = MO_SET;
5206               mo.u.loc = loc;
5207             }
5208           else
5209             {
5210               rtx xexpr = gen_rtx_SET (VOIDmode, loc, src);
5211               if (same_variable_part_p (SET_SRC (xexpr),
5212                                         MEM_EXPR (loc),
5213                                         INT_MEM_OFFSET (loc)))
5214                 mo.type = MO_COPY;
5215               else
5216                 mo.type = MO_SET;
5217               mo.u.loc = xexpr;
5218             }
5219         }
5220       mo.insn = cui->insn;
5221     }
5222   else
5223     return;
5224
5225   if (type != MO_VAL_SET)
5226     goto log_and_return;
5227
5228   v = find_use_val (oloc, mode, cui);
5229
5230   if (!v)
5231     goto log_and_return;
5232
5233   resolve = preserve = !cselib_preserved_value_p (v);
5234
5235   nloc = replace_expr_with_values (oloc);
5236   if (nloc)
5237     oloc = nloc;
5238
5239   if (GET_CODE (PATTERN (cui->insn)) == COND_EXEC)
5240     {
5241       cselib_val *oval = cselib_lookup (oloc, GET_MODE (oloc), 0);
5242
5243       gcc_assert (oval != v);
5244       gcc_assert (REG_P (oloc) || MEM_P (oloc));
5245
5246       if (!cselib_preserved_value_p (oval))
5247         {
5248           micro_operation moa;
5249
5250           preserve_value (oval);
5251
5252           moa.type = MO_VAL_USE;
5253           moa.u.loc = gen_rtx_CONCAT (mode, oval->val_rtx, oloc);
5254           VAL_NEEDS_RESOLUTION (moa.u.loc) = 1;
5255           moa.insn = cui->insn;
5256
5257           if (dump_file && (dump_flags & TDF_DETAILS))
5258             log_op_type (moa.u.loc, cui->bb, cui->insn,
5259                          moa.type, dump_file);
5260           VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &moa);
5261         }
5262
5263       resolve = false;
5264     }
5265   else if (resolve && GET_CODE (mo.u.loc) == SET)
5266     {
5267       nloc = replace_expr_with_values (SET_SRC (expr));
5268
5269       /* Avoid the mode mismatch between oexpr and expr.  */
5270       if (!nloc && mode != mode2)
5271         {
5272           nloc = SET_SRC (expr);
5273           gcc_assert (oloc == SET_DEST (expr));
5274         }
5275
5276       if (nloc)
5277         oloc = gen_rtx_SET (GET_MODE (mo.u.loc), oloc, nloc);
5278       else
5279         {
5280           if (oloc == SET_DEST (mo.u.loc))
5281             /* No point in duplicating.  */
5282             oloc = mo.u.loc;
5283           if (!REG_P (SET_SRC (mo.u.loc)))
5284             resolve = false;
5285         }
5286     }
5287   else if (!resolve)
5288     {
5289       if (GET_CODE (mo.u.loc) == SET
5290           && oloc == SET_DEST (mo.u.loc))
5291         /* No point in duplicating.  */
5292         oloc = mo.u.loc;
5293     }
5294   else
5295     resolve = false;
5296
5297   loc = gen_rtx_CONCAT (mode, v->val_rtx, oloc);
5298
5299   if (mo.u.loc != oloc)
5300     loc = gen_rtx_CONCAT (GET_MODE (mo.u.loc), loc, mo.u.loc);
5301
5302   /* The loc of a MO_VAL_SET may have various forms:
5303
5304      (concat val dst): dst now holds val
5305
5306      (concat val (set dst src)): dst now holds val, copied from src
5307
5308      (concat (concat val dstv) dst): dst now holds val; dstv is dst
5309      after replacing mems and non-top-level regs with values.
5310
5311      (concat (concat val dstv) (set dst src)): dst now holds val,
5312      copied from src.  dstv is a value-based representation of dst, if
5313      it differs from dst.  If resolution is needed, src is a REG, and
5314      its mode is the same as that of val.
5315
5316      (concat (concat val (set dstv srcv)) (set dst src)): src
5317      copied to dst, holding val.  dstv and srcv are value-based
5318      representations of dst and src, respectively.
5319
5320   */
5321
5322   if (GET_CODE (PATTERN (cui->insn)) != COND_EXEC)
5323     {
5324       reverse = reverse_op (v->val_rtx, expr);
5325       if (reverse)
5326         {
5327           loc = gen_rtx_CONCAT (GET_MODE (mo.u.loc), loc, reverse);
5328           VAL_EXPR_HAS_REVERSE (loc) = 1;
5329         }
5330     }
5331
5332   mo.u.loc = loc;
5333
5334   if (track_p)
5335     VAL_HOLDS_TRACK_EXPR (loc) = 1;
5336   if (preserve)
5337     {
5338       VAL_NEEDS_RESOLUTION (loc) = resolve;
5339       preserve_value (v);
5340     }
5341   if (mo.type == MO_CLOBBER)
5342     VAL_EXPR_IS_CLOBBERED (loc) = 1;
5343   if (mo.type == MO_COPY)
5344     VAL_EXPR_IS_COPIED (loc) = 1;
5345
5346   mo.type = MO_VAL_SET;
5347
5348  log_and_return:
5349   if (dump_file && (dump_flags & TDF_DETAILS))
5350     log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
5351   VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
5352 }
5353
5354 /* Callback for cselib_record_sets_hook, that records as micro
5355    operations uses and stores in an insn after cselib_record_sets has
5356    analyzed the sets in an insn, but before it modifies the stored
5357    values in the internal tables, unless cselib_record_sets doesn't
5358    call it directly (perhaps because we're not doing cselib in the
5359    first place, in which case sets and n_sets will be 0).  */
5360
5361 static void
5362 add_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
5363 {
5364   basic_block bb = BLOCK_FOR_INSN (insn);
5365   int n1, n2;
5366   struct count_use_info cui;
5367   micro_operation *mos;
5368
5369   cselib_hook_called = true;
5370
5371   cui.insn = insn;
5372   cui.bb = bb;
5373   cui.sets = sets;
5374   cui.n_sets = n_sets;
5375
5376   n1 = VEC_length (micro_operation, VTI (bb)->mos);
5377   cui.store_p = false;
5378   note_uses (&PATTERN (insn), add_uses_1, &cui);
5379   n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
5380   mos = VEC_address (micro_operation, VTI (bb)->mos);
5381
5382   /* Order the MO_USEs to be before MO_USE_NO_VARs and MO_VAL_USE, and
5383      MO_VAL_LOC last.  */
5384   while (n1 < n2)
5385     {
5386       while (n1 < n2 && mos[n1].type == MO_USE)
5387         n1++;
5388       while (n1 < n2 && mos[n2].type != MO_USE)
5389         n2--;
5390       if (n1 < n2)
5391         {
5392           micro_operation sw;
5393
5394           sw = mos[n1];
5395           mos[n1] = mos[n2];
5396           mos[n2] = sw;
5397         }
5398     }
5399
5400   n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
5401   while (n1 < n2)
5402     {
5403       while (n1 < n2 && mos[n1].type != MO_VAL_LOC)
5404         n1++;
5405       while (n1 < n2 && mos[n2].type == MO_VAL_LOC)
5406         n2--;
5407       if (n1 < n2)
5408         {
5409           micro_operation sw;
5410
5411           sw = mos[n1];
5412           mos[n1] = mos[n2];
5413           mos[n2] = sw;
5414         }
5415     }
5416
5417   if (CALL_P (insn))
5418     {
5419       micro_operation mo;
5420
5421       mo.type = MO_CALL;
5422       mo.insn = insn;
5423       mo.u.loc = NULL_RTX;
5424
5425       if (dump_file && (dump_flags & TDF_DETAILS))
5426         log_op_type (PATTERN (insn), bb, insn, mo.type, dump_file);
5427       VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
5428     }
5429
5430   n1 = VEC_length (micro_operation, VTI (bb)->mos);
5431   /* This will record NEXT_INSN (insn), such that we can
5432      insert notes before it without worrying about any
5433      notes that MO_USEs might emit after the insn.  */
5434   cui.store_p = true;
5435   note_stores (PATTERN (insn), add_stores, &cui);
5436   n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
5437   mos = VEC_address (micro_operation, VTI (bb)->mos);
5438
5439   /* Order the MO_VAL_USEs first (note_stores does nothing
5440      on DEBUG_INSNs, so there are no MO_VAL_LOCs from this
5441      insn), then MO_CLOBBERs, then MO_SET/MO_COPY/MO_VAL_SET.  */
5442   while (n1 < n2)
5443     {
5444       while (n1 < n2 && mos[n1].type == MO_VAL_USE)
5445         n1++;
5446       while (n1 < n2 && mos[n2].type != MO_VAL_USE)
5447         n2--;
5448       if (n1 < n2)
5449         {
5450           micro_operation sw;
5451
5452           sw = mos[n1];
5453           mos[n1] = mos[n2];
5454           mos[n2] = sw;
5455         }
5456     }
5457
5458   n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
5459   while (n1 < n2)
5460     {
5461       while (n1 < n2 && mos[n1].type == MO_CLOBBER)
5462         n1++;
5463       while (n1 < n2 && mos[n2].type != MO_CLOBBER)
5464         n2--;
5465       if (n1 < n2)
5466         {
5467           micro_operation sw;
5468
5469           sw = mos[n1];
5470           mos[n1] = mos[n2];
5471           mos[n2] = sw;
5472         }
5473     }
5474 }
5475
5476 static enum var_init_status
5477 find_src_status (dataflow_set *in, rtx src)
5478 {
5479   tree decl = NULL_TREE;
5480   enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
5481
5482   if (! flag_var_tracking_uninit)
5483     status = VAR_INIT_STATUS_INITIALIZED;
5484
5485   if (src && REG_P (src))
5486     decl = var_debug_decl (REG_EXPR (src));
5487   else if (src && MEM_P (src))
5488     decl = var_debug_decl (MEM_EXPR (src));
5489
5490   if (src && decl)
5491     status = get_init_value (in, src, dv_from_decl (decl));
5492
5493   return status;
5494 }
5495
5496 /* SRC is the source of an assignment.  Use SET to try to find what
5497    was ultimately assigned to SRC.  Return that value if known,
5498    otherwise return SRC itself.  */
5499
5500 static rtx
5501 find_src_set_src (dataflow_set *set, rtx src)
5502 {
5503   tree decl = NULL_TREE;   /* The variable being copied around.          */
5504   rtx set_src = NULL_RTX;  /* The value for "decl" stored in "src".      */
5505   variable var;
5506   location_chain nextp;
5507   int i;
5508   bool found;
5509
5510   if (src && REG_P (src))
5511     decl = var_debug_decl (REG_EXPR (src));
5512   else if (src && MEM_P (src))
5513     decl = var_debug_decl (MEM_EXPR (src));
5514
5515   if (src && decl)
5516     {
5517       decl_or_value dv = dv_from_decl (decl);
5518
5519       var = shared_hash_find (set->vars, dv);
5520       if (var)
5521         {
5522           found = false;
5523           for (i = 0; i < var->n_var_parts && !found; i++)
5524             for (nextp = var->var_part[i].loc_chain; nextp && !found;
5525                  nextp = nextp->next)
5526               if (rtx_equal_p (nextp->loc, src))
5527                 {
5528                   set_src = nextp->set_src;
5529                   found = true;
5530                 }
5531
5532         }
5533     }
5534
5535   return set_src;
5536 }
5537
5538 /* Compute the changes of variable locations in the basic block BB.  */
5539
5540 static bool
5541 compute_bb_dataflow (basic_block bb)
5542 {
5543   unsigned int i;
5544   micro_operation *mo;
5545   bool changed;
5546   dataflow_set old_out;
5547   dataflow_set *in = &VTI (bb)->in;
5548   dataflow_set *out = &VTI (bb)->out;
5549
5550   dataflow_set_init (&old_out);
5551   dataflow_set_copy (&old_out, out);
5552   dataflow_set_copy (out, in);
5553
5554   for (i = 0; VEC_iterate (micro_operation, VTI (bb)->mos, i, mo); i++)
5555     {
5556       rtx insn = mo->insn;
5557
5558       switch (mo->type)
5559         {
5560           case MO_CALL:
5561             dataflow_set_clear_at_call (out);
5562             break;
5563
5564           case MO_USE:
5565             {
5566               rtx loc = mo->u.loc;
5567
5568               if (REG_P (loc))
5569                 var_reg_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
5570               else if (MEM_P (loc))
5571                 var_mem_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
5572             }
5573             break;
5574
5575           case MO_VAL_LOC:
5576             {
5577               rtx loc = mo->u.loc;
5578               rtx val, vloc;
5579               tree var;
5580
5581               if (GET_CODE (loc) == CONCAT)
5582                 {
5583                   val = XEXP (loc, 0);
5584                   vloc = XEXP (loc, 1);
5585                 }
5586               else
5587                 {
5588                   val = NULL_RTX;
5589                   vloc = loc;
5590                 }
5591
5592               var = PAT_VAR_LOCATION_DECL (vloc);
5593
5594               clobber_variable_part (out, NULL_RTX,
5595                                      dv_from_decl (var), 0, NULL_RTX);
5596               if (val)
5597                 {
5598                   if (VAL_NEEDS_RESOLUTION (loc))
5599                     val_resolve (out, val, PAT_VAR_LOCATION_LOC (vloc), insn);
5600                   set_variable_part (out, val, dv_from_decl (var), 0,
5601                                      VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
5602                                      INSERT);
5603                 }
5604               else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
5605                 set_variable_part (out, PAT_VAR_LOCATION_LOC (vloc),
5606                                    dv_from_decl (var), 0,
5607                                    VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
5608                                    INSERT);
5609             }
5610             break;
5611
5612           case MO_VAL_USE:
5613             {
5614               rtx loc = mo->u.loc;
5615               rtx val, vloc, uloc;
5616
5617               vloc = uloc = XEXP (loc, 1);
5618               val = XEXP (loc, 0);
5619
5620               if (GET_CODE (val) == CONCAT)
5621                 {
5622                   uloc = XEXP (val, 1);
5623                   val = XEXP (val, 0);
5624                 }
5625
5626               if (VAL_NEEDS_RESOLUTION (loc))
5627                 val_resolve (out, val, vloc, insn);
5628               else
5629                 val_store (out, val, uloc, insn, false);
5630
5631               if (VAL_HOLDS_TRACK_EXPR (loc))
5632                 {
5633                   if (GET_CODE (uloc) == REG)
5634                     var_reg_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
5635                                  NULL);
5636                   else if (GET_CODE (uloc) == MEM)
5637                     var_mem_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
5638                                  NULL);
5639                 }
5640             }
5641             break;
5642
5643           case MO_VAL_SET:
5644             {
5645               rtx loc = mo->u.loc;
5646               rtx val, vloc, uloc, reverse = NULL_RTX;
5647
5648               vloc = loc;
5649               if (VAL_EXPR_HAS_REVERSE (loc))
5650                 {
5651                   reverse = XEXP (loc, 1);
5652                   vloc = XEXP (loc, 0);
5653                 }
5654               uloc = XEXP (vloc, 1);
5655               val = XEXP (vloc, 0);
5656               vloc = uloc;
5657
5658               if (GET_CODE (val) == CONCAT)
5659                 {
5660                   vloc = XEXP (val, 1);
5661                   val = XEXP (val, 0);
5662                 }
5663
5664               if (GET_CODE (vloc) == SET)
5665                 {
5666                   rtx vsrc = SET_SRC (vloc);
5667
5668                   gcc_assert (val != vsrc);
5669                   gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
5670
5671                   vloc = SET_DEST (vloc);
5672
5673                   if (VAL_NEEDS_RESOLUTION (loc))
5674                     val_resolve (out, val, vsrc, insn);
5675                 }
5676               else if (VAL_NEEDS_RESOLUTION (loc))
5677                 {
5678                   gcc_assert (GET_CODE (uloc) == SET
5679                               && GET_CODE (SET_SRC (uloc)) == REG);
5680                   val_resolve (out, val, SET_SRC (uloc), insn);
5681                 }
5682
5683               if (VAL_HOLDS_TRACK_EXPR (loc))
5684                 {
5685                   if (VAL_EXPR_IS_CLOBBERED (loc))
5686                     {
5687                       if (REG_P (uloc))
5688                         var_reg_delete (out, uloc, true);
5689                       else if (MEM_P (uloc))
5690                         var_mem_delete (out, uloc, true);
5691                     }
5692                   else
5693                     {
5694                       bool copied_p = VAL_EXPR_IS_COPIED (loc);
5695                       rtx set_src = NULL;
5696                       enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
5697
5698                       if (GET_CODE (uloc) == SET)
5699                         {
5700                           set_src = SET_SRC (uloc);
5701                           uloc = SET_DEST (uloc);
5702                         }
5703
5704                       if (copied_p)
5705                         {
5706                           if (flag_var_tracking_uninit)
5707                             {
5708                               status = find_src_status (in, set_src);
5709
5710                               if (status == VAR_INIT_STATUS_UNKNOWN)
5711                                 status = find_src_status (out, set_src);
5712                             }
5713
5714                           set_src = find_src_set_src (in, set_src);
5715                         }
5716
5717                       if (REG_P (uloc))
5718                         var_reg_delete_and_set (out, uloc, !copied_p,
5719                                                 status, set_src);
5720                       else if (MEM_P (uloc))
5721                         var_mem_delete_and_set (out, uloc, !copied_p,
5722                                                 status, set_src);
5723                     }
5724                 }
5725               else if (REG_P (uloc))
5726                 var_regno_delete (out, REGNO (uloc));
5727
5728               val_store (out, val, vloc, insn, true);
5729
5730               if (reverse)
5731                 val_store (out, XEXP (reverse, 0), XEXP (reverse, 1),
5732                            insn, false);
5733             }
5734             break;
5735
5736           case MO_SET:
5737             {
5738               rtx loc = mo->u.loc;
5739               rtx set_src = NULL;
5740
5741               if (GET_CODE (loc) == SET)
5742                 {
5743                   set_src = SET_SRC (loc);
5744                   loc = SET_DEST (loc);
5745                 }
5746
5747               if (REG_P (loc))
5748                 var_reg_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
5749                                         set_src);
5750               else if (MEM_P (loc))
5751                 var_mem_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
5752                                         set_src);
5753             }
5754             break;
5755
5756           case MO_COPY:
5757             {
5758               rtx loc = mo->u.loc;
5759               enum var_init_status src_status;
5760               rtx set_src = NULL;
5761
5762               if (GET_CODE (loc) == SET)
5763                 {
5764                   set_src = SET_SRC (loc);
5765                   loc = SET_DEST (loc);
5766                 }
5767
5768               if (! flag_var_tracking_uninit)
5769                 src_status = VAR_INIT_STATUS_INITIALIZED;
5770               else
5771                 {
5772                   src_status = find_src_status (in, set_src);
5773
5774                   if (src_status == VAR_INIT_STATUS_UNKNOWN)
5775                     src_status = find_src_status (out, set_src);
5776                 }
5777
5778               set_src = find_src_set_src (in, set_src);
5779
5780               if (REG_P (loc))
5781                 var_reg_delete_and_set (out, loc, false, src_status, set_src);
5782               else if (MEM_P (loc))
5783                 var_mem_delete_and_set (out, loc, false, src_status, set_src);
5784             }
5785             break;
5786
5787           case MO_USE_NO_VAR:
5788             {
5789               rtx loc = mo->u.loc;
5790
5791               if (REG_P (loc))
5792                 var_reg_delete (out, loc, false);
5793               else if (MEM_P (loc))
5794                 var_mem_delete (out, loc, false);
5795             }
5796             break;
5797
5798           case MO_CLOBBER:
5799             {
5800               rtx loc = mo->u.loc;
5801
5802               if (REG_P (loc))
5803                 var_reg_delete (out, loc, true);
5804               else if (MEM_P (loc))
5805                 var_mem_delete (out, loc, true);
5806             }
5807             break;
5808
5809           case MO_ADJUST:
5810             out->stack_adjust += mo->u.adjust;
5811             break;
5812         }
5813     }
5814
5815   if (MAY_HAVE_DEBUG_INSNS)
5816     {
5817       dataflow_set_equiv_regs (out);
5818       htab_traverse (shared_hash_htab (out->vars), canonicalize_values_mark,
5819                      out);
5820       htab_traverse (shared_hash_htab (out->vars), canonicalize_values_star,
5821                      out);
5822 #if ENABLE_CHECKING
5823       htab_traverse (shared_hash_htab (out->vars),
5824                      canonicalize_loc_order_check, out);
5825 #endif
5826     }
5827   changed = dataflow_set_different (&old_out, out);
5828   dataflow_set_destroy (&old_out);
5829   return changed;
5830 }
5831
5832 /* Find the locations of variables in the whole function.  */
5833
5834 static bool
5835 vt_find_locations (void)
5836 {
5837   fibheap_t worklist, pending, fibheap_swap;
5838   sbitmap visited, in_worklist, in_pending, sbitmap_swap;
5839   basic_block bb;
5840   edge e;
5841   int *bb_order;
5842   int *rc_order;
5843   int i;
5844   int htabsz = 0;
5845   int htabmax = PARAM_VALUE (PARAM_MAX_VARTRACK_SIZE);
5846   bool success = true;
5847
5848   /* Compute reverse completion order of depth first search of the CFG
5849      so that the data-flow runs faster.  */
5850   rc_order = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
5851   bb_order = XNEWVEC (int, last_basic_block);
5852   pre_and_rev_post_order_compute (NULL, rc_order, false);
5853   for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
5854     bb_order[rc_order[i]] = i;
5855   free (rc_order);
5856
5857   worklist = fibheap_new ();
5858   pending = fibheap_new ();
5859   visited = sbitmap_alloc (last_basic_block);
5860   in_worklist = sbitmap_alloc (last_basic_block);
5861   in_pending = sbitmap_alloc (last_basic_block);
5862   sbitmap_zero (in_worklist);
5863
5864   FOR_EACH_BB (bb)
5865     fibheap_insert (pending, bb_order[bb->index], bb);
5866   sbitmap_ones (in_pending);
5867
5868   while (success && !fibheap_empty (pending))
5869     {
5870       fibheap_swap = pending;
5871       pending = worklist;
5872       worklist = fibheap_swap;
5873       sbitmap_swap = in_pending;
5874       in_pending = in_worklist;
5875       in_worklist = sbitmap_swap;
5876
5877       sbitmap_zero (visited);
5878
5879       while (!fibheap_empty (worklist))
5880         {
5881           bb = (basic_block) fibheap_extract_min (worklist);
5882           RESET_BIT (in_worklist, bb->index);
5883           if (!TEST_BIT (visited, bb->index))
5884             {
5885               bool changed;
5886               edge_iterator ei;
5887               int oldinsz, oldoutsz;
5888
5889               SET_BIT (visited, bb->index);
5890
5891               if (VTI (bb)->in.vars)
5892                 {
5893                   htabsz
5894                     -= (htab_size (shared_hash_htab (VTI (bb)->in.vars))
5895                         + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
5896                   oldinsz
5897                     = htab_elements (shared_hash_htab (VTI (bb)->in.vars));
5898                   oldoutsz
5899                     = htab_elements (shared_hash_htab (VTI (bb)->out.vars));
5900                 }
5901               else
5902                 oldinsz = oldoutsz = 0;
5903
5904               if (MAY_HAVE_DEBUG_INSNS)
5905                 {
5906                   dataflow_set *in = &VTI (bb)->in, *first_out = NULL;
5907                   bool first = true, adjust = false;
5908
5909                   /* Calculate the IN set as the intersection of
5910                      predecessor OUT sets.  */
5911
5912                   dataflow_set_clear (in);
5913                   dst_can_be_shared = true;
5914
5915                   FOR_EACH_EDGE (e, ei, bb->preds)
5916                     if (!VTI (e->src)->flooded)
5917                       gcc_assert (bb_order[bb->index]
5918                                   <= bb_order[e->src->index]);
5919                     else if (first)
5920                       {
5921                         dataflow_set_copy (in, &VTI (e->src)->out);
5922                         first_out = &VTI (e->src)->out;
5923                         first = false;
5924                       }
5925                     else
5926                       {
5927                         dataflow_set_merge (in, &VTI (e->src)->out);
5928                         adjust = true;
5929                       }
5930
5931                   if (adjust)
5932                     {
5933                       dataflow_post_merge_adjust (in, &VTI (bb)->permp);
5934 #if ENABLE_CHECKING
5935                       /* Merge and merge_adjust should keep entries in
5936                          canonical order.  */
5937                       htab_traverse (shared_hash_htab (in->vars),
5938                                      canonicalize_loc_order_check,
5939                                      in);
5940 #endif
5941                       if (dst_can_be_shared)
5942                         {
5943                           shared_hash_destroy (in->vars);
5944                           in->vars = shared_hash_copy (first_out->vars);
5945                         }
5946                     }
5947
5948                   VTI (bb)->flooded = true;
5949                 }
5950               else
5951                 {
5952                   /* Calculate the IN set as union of predecessor OUT sets.  */
5953                   dataflow_set_clear (&VTI (bb)->in);
5954                   FOR_EACH_EDGE (e, ei, bb->preds)
5955                     dataflow_set_union (&VTI (bb)->in, &VTI (e->src)->out);
5956                 }
5957
5958               changed = compute_bb_dataflow (bb);
5959               htabsz += (htab_size (shared_hash_htab (VTI (bb)->in.vars))
5960                          + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
5961
5962               if (htabmax && htabsz > htabmax)
5963                 {
5964                   if (MAY_HAVE_DEBUG_INSNS)
5965                     inform (DECL_SOURCE_LOCATION (cfun->decl),
5966                             "variable tracking size limit exceeded with "
5967                             "-fvar-tracking-assignments, retrying without");
5968                   else
5969                     inform (DECL_SOURCE_LOCATION (cfun->decl),
5970                             "variable tracking size limit exceeded");
5971                   success = false;
5972                   break;
5973                 }
5974
5975               if (changed)
5976                 {
5977                   FOR_EACH_EDGE (e, ei, bb->succs)
5978                     {
5979                       if (e->dest == EXIT_BLOCK_PTR)
5980                         continue;
5981
5982                       if (TEST_BIT (visited, e->dest->index))
5983                         {
5984                           if (!TEST_BIT (in_pending, e->dest->index))
5985                             {
5986                               /* Send E->DEST to next round.  */
5987                               SET_BIT (in_pending, e->dest->index);
5988                               fibheap_insert (pending,
5989                                               bb_order[e->dest->index],
5990                                               e->dest);
5991                             }
5992                         }
5993                       else if (!TEST_BIT (in_worklist, e->dest->index))
5994                         {
5995                           /* Add E->DEST to current round.  */
5996                           SET_BIT (in_worklist, e->dest->index);
5997                           fibheap_insert (worklist, bb_order[e->dest->index],
5998                                           e->dest);
5999                         }
6000                     }
6001                 }
6002
6003               if (dump_file)
6004                 fprintf (dump_file,
6005                          "BB %i: in %i (was %i), out %i (was %i), rem %i + %i, tsz %i\n",
6006                          bb->index,
6007                          (int)htab_elements (shared_hash_htab (VTI (bb)->in.vars)),
6008                          oldinsz,
6009                          (int)htab_elements (shared_hash_htab (VTI (bb)->out.vars)),
6010                          oldoutsz,
6011                          (int)worklist->nodes, (int)pending->nodes, htabsz);
6012
6013               if (dump_file && (dump_flags & TDF_DETAILS))
6014                 {
6015                   fprintf (dump_file, "BB %i IN:\n", bb->index);
6016                   dump_dataflow_set (&VTI (bb)->in);
6017                   fprintf (dump_file, "BB %i OUT:\n", bb->index);
6018                   dump_dataflow_set (&VTI (bb)->out);
6019                 }
6020             }
6021         }
6022     }
6023
6024   if (success && MAY_HAVE_DEBUG_INSNS)
6025     FOR_EACH_BB (bb)
6026       gcc_assert (VTI (bb)->flooded);
6027
6028   free (bb_order);
6029   fibheap_delete (worklist);
6030   fibheap_delete (pending);
6031   sbitmap_free (visited);
6032   sbitmap_free (in_worklist);
6033   sbitmap_free (in_pending);
6034
6035   return success;
6036 }
6037
6038 /* Print the content of the LIST to dump file.  */
6039
6040 static void
6041 dump_attrs_list (attrs list)
6042 {
6043   for (; list; list = list->next)
6044     {
6045       if (dv_is_decl_p (list->dv))
6046         print_mem_expr (dump_file, dv_as_decl (list->dv));
6047       else
6048         print_rtl_single (dump_file, dv_as_value (list->dv));
6049       fprintf (dump_file, "+" HOST_WIDE_INT_PRINT_DEC, list->offset);
6050     }
6051   fprintf (dump_file, "\n");
6052 }
6053
6054 /* Print the information about variable *SLOT to dump file.  */
6055
6056 static int
6057 dump_var_slot (void **slot, void *data ATTRIBUTE_UNUSED)
6058 {
6059   variable var = (variable) *slot;
6060
6061   dump_var (var);
6062
6063   /* Continue traversing the hash table.  */
6064   return 1;
6065 }
6066
6067 /* Print the information about variable VAR to dump file.  */
6068
6069 static void
6070 dump_var (variable var)
6071 {
6072   int i;
6073   location_chain node;
6074
6075   if (dv_is_decl_p (var->dv))
6076     {
6077       const_tree decl = dv_as_decl (var->dv);
6078
6079       if (DECL_NAME (decl))
6080         {
6081           fprintf (dump_file, "  name: %s",
6082                    IDENTIFIER_POINTER (DECL_NAME (decl)));
6083           if (dump_flags & TDF_UID)
6084             fprintf (dump_file, "D.%u", DECL_UID (decl));
6085         }
6086       else if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
6087         fprintf (dump_file, "  name: D#%u", DEBUG_TEMP_UID (decl));
6088       else
6089         fprintf (dump_file, "  name: D.%u", DECL_UID (decl));
6090       fprintf (dump_file, "\n");
6091     }
6092   else
6093     {
6094       fputc (' ', dump_file);
6095       print_rtl_single (dump_file, dv_as_value (var->dv));
6096     }
6097
6098   for (i = 0; i < var->n_var_parts; i++)
6099     {
6100       fprintf (dump_file, "    offset %ld\n",
6101                (long) var->var_part[i].offset);
6102       for (node = var->var_part[i].loc_chain; node; node = node->next)
6103         {
6104           fprintf (dump_file, "      ");
6105           if (node->init == VAR_INIT_STATUS_UNINITIALIZED)
6106             fprintf (dump_file, "[uninit]");
6107           print_rtl_single (dump_file, node->loc);
6108         }
6109     }
6110 }
6111
6112 /* Print the information about variables from hash table VARS to dump file.  */
6113
6114 static void
6115 dump_vars (htab_t vars)
6116 {
6117   if (htab_elements (vars) > 0)
6118     {
6119       fprintf (dump_file, "Variables:\n");
6120       htab_traverse (vars, dump_var_slot, NULL);
6121     }
6122 }
6123
6124 /* Print the dataflow set SET to dump file.  */
6125
6126 static void
6127 dump_dataflow_set (dataflow_set *set)
6128 {
6129   int i;
6130
6131   fprintf (dump_file, "Stack adjustment: " HOST_WIDE_INT_PRINT_DEC "\n",
6132            set->stack_adjust);
6133   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
6134     {
6135       if (set->regs[i])
6136         {
6137           fprintf (dump_file, "Reg %d:", i);
6138           dump_attrs_list (set->regs[i]);
6139         }
6140     }
6141   dump_vars (shared_hash_htab (set->vars));
6142   fprintf (dump_file, "\n");
6143 }
6144
6145 /* Print the IN and OUT sets for each basic block to dump file.  */
6146
6147 static void
6148 dump_dataflow_sets (void)
6149 {
6150   basic_block bb;
6151
6152   FOR_EACH_BB (bb)
6153     {
6154       fprintf (dump_file, "\nBasic block %d:\n", bb->index);
6155       fprintf (dump_file, "IN:\n");
6156       dump_dataflow_set (&VTI (bb)->in);
6157       fprintf (dump_file, "OUT:\n");
6158       dump_dataflow_set (&VTI (bb)->out);
6159     }
6160 }
6161
6162 /* Add variable VAR to the hash table of changed variables and
6163    if it has no locations delete it from SET's hash table.  */
6164
6165 static void
6166 variable_was_changed (variable var, dataflow_set *set)
6167 {
6168   hashval_t hash = dv_htab_hash (var->dv);
6169
6170   if (emit_notes)
6171     {
6172       void **slot;
6173       bool old_cur_loc_changed = false;
6174
6175       /* Remember this decl or VALUE has been added to changed_variables.  */
6176       set_dv_changed (var->dv, true);
6177
6178       slot = htab_find_slot_with_hash (changed_variables,
6179                                        var->dv,
6180                                        hash, INSERT);
6181
6182       if (*slot)
6183         {
6184           variable old_var = (variable) *slot;
6185           gcc_assert (old_var->in_changed_variables);
6186           old_var->in_changed_variables = false;
6187           old_cur_loc_changed = old_var->cur_loc_changed;
6188           variable_htab_free (*slot);
6189         }
6190       if (set && var->n_var_parts == 0)
6191         {
6192           variable empty_var;
6193
6194           empty_var = (variable) pool_alloc (dv_pool (var->dv));
6195           empty_var->dv = var->dv;
6196           empty_var->refcount = 1;
6197           empty_var->n_var_parts = 0;
6198           empty_var->cur_loc_changed = true;
6199           empty_var->in_changed_variables = true;
6200           *slot = empty_var;
6201           goto drop_var;
6202         }
6203       else
6204         {
6205           var->refcount++;
6206           var->in_changed_variables = true;
6207           /* If within processing one uop a variable is deleted
6208              and then readded, we need to assume it has changed.  */
6209           if (old_cur_loc_changed)
6210             var->cur_loc_changed = true;
6211           *slot = var;
6212         }
6213     }
6214   else
6215     {
6216       gcc_assert (set);
6217       if (var->n_var_parts == 0)
6218         {
6219           void **slot;
6220
6221         drop_var:
6222           slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
6223           if (slot)
6224             {
6225               if (shared_hash_shared (set->vars))
6226                 slot = shared_hash_find_slot_unshare (&set->vars, var->dv,
6227                                                       NO_INSERT);
6228               htab_clear_slot (shared_hash_htab (set->vars), slot);
6229             }
6230         }
6231     }
6232 }
6233
6234 /* Look for the index in VAR->var_part corresponding to OFFSET.
6235    Return -1 if not found.  If INSERTION_POINT is non-NULL, the
6236    referenced int will be set to the index that the part has or should
6237    have, if it should be inserted.  */
6238
6239 static inline int
6240 find_variable_location_part (variable var, HOST_WIDE_INT offset,
6241                              int *insertion_point)
6242 {
6243   int pos, low, high;
6244
6245   /* Find the location part.  */
6246   low = 0;
6247   high = var->n_var_parts;
6248   while (low != high)
6249     {
6250       pos = (low + high) / 2;
6251       if (var->var_part[pos].offset < offset)
6252         low = pos + 1;
6253       else
6254         high = pos;
6255     }
6256   pos = low;
6257
6258   if (insertion_point)
6259     *insertion_point = pos;
6260
6261   if (pos < var->n_var_parts && var->var_part[pos].offset == offset)
6262     return pos;
6263
6264   return -1;
6265 }
6266
6267 static void **
6268 set_slot_part (dataflow_set *set, rtx loc, void **slot,
6269                decl_or_value dv, HOST_WIDE_INT offset,
6270                enum var_init_status initialized, rtx set_src)
6271 {
6272   int pos;
6273   location_chain node, next;
6274   location_chain *nextp;
6275   variable var;
6276   bool onepart = dv_onepart_p (dv);
6277
6278   gcc_assert (offset == 0 || !onepart);
6279   gcc_assert (loc != dv_as_opaque (dv));
6280
6281   var = (variable) *slot;
6282
6283   if (! flag_var_tracking_uninit)
6284     initialized = VAR_INIT_STATUS_INITIALIZED;
6285
6286   if (!var)
6287     {
6288       /* Create new variable information.  */
6289       var = (variable) pool_alloc (dv_pool (dv));
6290       var->dv = dv;
6291       var->refcount = 1;
6292       var->n_var_parts = 1;
6293       var->cur_loc_changed = false;
6294       var->in_changed_variables = false;
6295       var->var_part[0].offset = offset;
6296       var->var_part[0].loc_chain = NULL;
6297       var->var_part[0].cur_loc = NULL;
6298       *slot = var;
6299       pos = 0;
6300       nextp = &var->var_part[0].loc_chain;
6301     }
6302   else if (onepart)
6303     {
6304       int r = -1, c = 0;
6305
6306       gcc_assert (dv_as_opaque (var->dv) == dv_as_opaque (dv));
6307
6308       pos = 0;
6309
6310       if (GET_CODE (loc) == VALUE)
6311         {
6312           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
6313                nextp = &node->next)
6314             if (GET_CODE (node->loc) == VALUE)
6315               {
6316                 if (node->loc == loc)
6317                   {
6318                     r = 0;
6319                     break;
6320                   }
6321                 if (canon_value_cmp (node->loc, loc))
6322                   c++;
6323                 else
6324                   {
6325                     r = 1;
6326                     break;
6327                   }
6328               }
6329             else if (REG_P (node->loc) || MEM_P (node->loc))
6330               c++;
6331             else
6332               {
6333                 r = 1;
6334                 break;
6335               }
6336         }
6337       else if (REG_P (loc))
6338         {
6339           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
6340                nextp = &node->next)
6341             if (REG_P (node->loc))
6342               {
6343                 if (REGNO (node->loc) < REGNO (loc))
6344                   c++;
6345                 else
6346                   {
6347                     if (REGNO (node->loc) == REGNO (loc))
6348                       r = 0;
6349                     else
6350                       r = 1;
6351                     break;
6352                   }
6353               }
6354             else
6355               {
6356                 r = 1;
6357                 break;
6358               }
6359         }
6360       else if (MEM_P (loc))
6361         {
6362           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
6363                nextp = &node->next)
6364             if (REG_P (node->loc))
6365               c++;
6366             else if (MEM_P (node->loc))
6367               {
6368                 if ((r = loc_cmp (XEXP (node->loc, 0), XEXP (loc, 0))) >= 0)
6369                   break;
6370                 else
6371                   c++;
6372               }
6373             else
6374               {
6375                 r = 1;
6376                 break;
6377               }
6378         }
6379       else
6380         for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
6381              nextp = &node->next)
6382           if ((r = loc_cmp (node->loc, loc)) >= 0)
6383             break;
6384           else
6385             c++;
6386
6387       if (r == 0)
6388         return slot;
6389
6390       if (shared_var_p (var, set->vars))
6391         {
6392           slot = unshare_variable (set, slot, var, initialized);
6393           var = (variable)*slot;
6394           for (nextp = &var->var_part[0].loc_chain; c;
6395                nextp = &(*nextp)->next)
6396             c--;
6397           gcc_assert ((!node && !*nextp) || node->loc == (*nextp)->loc);
6398         }
6399     }
6400   else
6401     {
6402       int inspos = 0;
6403
6404       gcc_assert (dv_as_decl (var->dv) == dv_as_decl (dv));
6405
6406       pos = find_variable_location_part (var, offset, &inspos);
6407
6408       if (pos >= 0)
6409         {
6410           node = var->var_part[pos].loc_chain;
6411
6412           if (node
6413               && ((REG_P (node->loc) && REG_P (loc)
6414                    && REGNO (node->loc) == REGNO (loc))
6415                   || rtx_equal_p (node->loc, loc)))
6416             {
6417               /* LOC is in the beginning of the chain so we have nothing
6418                  to do.  */
6419               if (node->init < initialized)
6420                 node->init = initialized;
6421               if (set_src != NULL)
6422                 node->set_src = set_src;
6423
6424               return slot;
6425             }
6426           else
6427             {
6428               /* We have to make a copy of a shared variable.  */
6429               if (shared_var_p (var, set->vars))
6430                 {
6431                   slot = unshare_variable (set, slot, var, initialized);
6432                   var = (variable)*slot;
6433                 }
6434             }
6435         }
6436       else
6437         {
6438           /* We have not found the location part, new one will be created.  */
6439
6440           /* We have to make a copy of the shared variable.  */
6441           if (shared_var_p (var, set->vars))
6442             {
6443               slot = unshare_variable (set, slot, var, initialized);
6444               var = (variable)*slot;
6445             }
6446
6447           /* We track only variables whose size is <= MAX_VAR_PARTS bytes
6448              thus there are at most MAX_VAR_PARTS different offsets.  */
6449           gcc_assert (var->n_var_parts < MAX_VAR_PARTS
6450                       && (!var->n_var_parts || !dv_onepart_p (var->dv)));
6451
6452           /* We have to move the elements of array starting at index
6453              inspos to the next position.  */
6454           for (pos = var->n_var_parts; pos > inspos; pos--)
6455             var->var_part[pos] = var->var_part[pos - 1];
6456
6457           var->n_var_parts++;
6458           var->var_part[pos].offset = offset;
6459           var->var_part[pos].loc_chain = NULL;
6460           var->var_part[pos].cur_loc = NULL;
6461         }
6462
6463       /* Delete the location from the list.  */
6464       nextp = &var->var_part[pos].loc_chain;
6465       for (node = var->var_part[pos].loc_chain; node; node = next)
6466         {
6467           next = node->next;
6468           if ((REG_P (node->loc) && REG_P (loc)
6469                && REGNO (node->loc) == REGNO (loc))
6470               || rtx_equal_p (node->loc, loc))
6471             {
6472               /* Save these values, to assign to the new node, before
6473                  deleting this one.  */
6474               if (node->init > initialized)
6475                 initialized = node->init;
6476               if (node->set_src != NULL && set_src == NULL)
6477                 set_src = node->set_src;
6478               if (var->var_part[pos].cur_loc == node->loc)
6479                 {
6480                   var->var_part[pos].cur_loc = NULL;
6481                   var->cur_loc_changed = true;
6482                 }
6483               pool_free (loc_chain_pool, node);
6484               *nextp = next;
6485               break;
6486             }
6487           else
6488             nextp = &node->next;
6489         }
6490
6491       nextp = &var->var_part[pos].loc_chain;
6492     }
6493
6494   /* Add the location to the beginning.  */
6495   node = (location_chain) pool_alloc (loc_chain_pool);
6496   node->loc = loc;
6497   node->init = initialized;
6498   node->set_src = set_src;
6499   node->next = *nextp;
6500   *nextp = node;
6501
6502   if (onepart && emit_notes)
6503     add_value_chains (var->dv, loc);
6504
6505   /* If no location was emitted do so.  */
6506   if (var->var_part[pos].cur_loc == NULL)
6507     variable_was_changed (var, set);
6508
6509   return slot;
6510 }
6511
6512 /* Set the part of variable's location in the dataflow set SET.  The
6513    variable part is specified by variable's declaration in DV and
6514    offset OFFSET and the part's location by LOC.  IOPT should be
6515    NO_INSERT if the variable is known to be in SET already and the
6516    variable hash table must not be resized, and INSERT otherwise.  */
6517
6518 static void
6519 set_variable_part (dataflow_set *set, rtx loc,
6520                    decl_or_value dv, HOST_WIDE_INT offset,
6521                    enum var_init_status initialized, rtx set_src,
6522                    enum insert_option iopt)
6523 {
6524   void **slot;
6525
6526   if (iopt == NO_INSERT)
6527     slot = shared_hash_find_slot_noinsert (set->vars, dv);
6528   else
6529     {
6530       slot = shared_hash_find_slot (set->vars, dv);
6531       if (!slot)
6532         slot = shared_hash_find_slot_unshare (&set->vars, dv, iopt);
6533     }
6534   slot = set_slot_part (set, loc, slot, dv, offset, initialized, set_src);
6535 }
6536
6537 /* Remove all recorded register locations for the given variable part
6538    from dataflow set SET, except for those that are identical to loc.
6539    The variable part is specified by variable's declaration or value
6540    DV and offset OFFSET.  */
6541
6542 static void **
6543 clobber_slot_part (dataflow_set *set, rtx loc, void **slot,
6544                    HOST_WIDE_INT offset, rtx set_src)
6545 {
6546   variable var = (variable) *slot;
6547   int pos = find_variable_location_part (var, offset, NULL);
6548
6549   if (pos >= 0)
6550     {
6551       location_chain node, next;
6552
6553       /* Remove the register locations from the dataflow set.  */
6554       next = var->var_part[pos].loc_chain;
6555       for (node = next; node; node = next)
6556         {
6557           next = node->next;
6558           if (node->loc != loc
6559               && (!flag_var_tracking_uninit
6560                   || !set_src
6561                   || MEM_P (set_src)
6562                   || !rtx_equal_p (set_src, node->set_src)))
6563             {
6564               if (REG_P (node->loc))
6565                 {
6566                   attrs anode, anext;
6567                   attrs *anextp;
6568
6569                   /* Remove the variable part from the register's
6570                      list, but preserve any other variable parts
6571                      that might be regarded as live in that same
6572                      register.  */
6573                   anextp = &set->regs[REGNO (node->loc)];
6574                   for (anode = *anextp; anode; anode = anext)
6575                     {
6576                       anext = anode->next;
6577                       if (dv_as_opaque (anode->dv) == dv_as_opaque (var->dv)
6578                           && anode->offset == offset)
6579                         {
6580                           pool_free (attrs_pool, anode);
6581                           *anextp = anext;
6582                         }
6583                       else
6584                         anextp = &anode->next;
6585                     }
6586                 }
6587
6588               slot = delete_slot_part (set, node->loc, slot, offset);
6589             }
6590         }
6591     }
6592
6593   return slot;
6594 }
6595
6596 /* Remove all recorded register locations for the given variable part
6597    from dataflow set SET, except for those that are identical to loc.
6598    The variable part is specified by variable's declaration or value
6599    DV and offset OFFSET.  */
6600
6601 static void
6602 clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
6603                        HOST_WIDE_INT offset, rtx set_src)
6604 {
6605   void **slot;
6606
6607   if (!dv_as_opaque (dv)
6608       || (!dv_is_value_p (dv) && ! DECL_P (dv_as_decl (dv))))
6609     return;
6610
6611   slot = shared_hash_find_slot_noinsert (set->vars, dv);
6612   if (!slot)
6613     return;
6614
6615   slot = clobber_slot_part (set, loc, slot, offset, set_src);
6616 }
6617
6618 /* Delete the part of variable's location from dataflow set SET.  The
6619    variable part is specified by its SET->vars slot SLOT and offset
6620    OFFSET and the part's location by LOC.  */
6621
6622 static void **
6623 delete_slot_part (dataflow_set *set, rtx loc, void **slot,
6624                   HOST_WIDE_INT offset)
6625 {
6626   variable var = (variable) *slot;
6627   int pos = find_variable_location_part (var, offset, NULL);
6628
6629   if (pos >= 0)
6630     {
6631       location_chain node, next;
6632       location_chain *nextp;
6633       bool changed;
6634
6635       if (shared_var_p (var, set->vars))
6636         {
6637           /* If the variable contains the location part we have to
6638              make a copy of the variable.  */
6639           for (node = var->var_part[pos].loc_chain; node;
6640                node = node->next)
6641             {
6642               if ((REG_P (node->loc) && REG_P (loc)
6643                    && REGNO (node->loc) == REGNO (loc))
6644                   || rtx_equal_p (node->loc, loc))
6645                 {
6646                   slot = unshare_variable (set, slot, var,
6647                                            VAR_INIT_STATUS_UNKNOWN);
6648                   var = (variable)*slot;
6649                   break;
6650                 }
6651             }
6652         }
6653
6654       /* Delete the location part.  */
6655       changed = false;
6656       nextp = &var->var_part[pos].loc_chain;
6657       for (node = *nextp; node; node = next)
6658         {
6659           next = node->next;
6660           if ((REG_P (node->loc) && REG_P (loc)
6661                && REGNO (node->loc) == REGNO (loc))
6662               || rtx_equal_p (node->loc, loc))
6663             {
6664               if (emit_notes && pos == 0 && dv_onepart_p (var->dv))
6665                 remove_value_chains (var->dv, node->loc);
6666               /* If we have deleted the location which was last emitted
6667                  we have to emit new location so add the variable to set
6668                  of changed variables.  */
6669               if (var->var_part[pos].cur_loc == node->loc)
6670                 {
6671                   changed = true;
6672                   var->var_part[pos].cur_loc = NULL;
6673                   var->cur_loc_changed = true;
6674                 }
6675               pool_free (loc_chain_pool, node);
6676               *nextp = next;
6677               break;
6678             }
6679           else
6680             nextp = &node->next;
6681         }
6682
6683       if (var->var_part[pos].loc_chain == NULL)
6684         {
6685           changed = true;
6686           var->n_var_parts--;
6687           if (emit_notes)
6688             var->cur_loc_changed = true;
6689           while (pos < var->n_var_parts)
6690             {
6691               var->var_part[pos] = var->var_part[pos + 1];
6692               pos++;
6693             }
6694         }
6695       if (changed)
6696         variable_was_changed (var, set);
6697     }
6698
6699   return slot;
6700 }
6701
6702 /* Delete the part of variable's location from dataflow set SET.  The
6703    variable part is specified by variable's declaration or value DV
6704    and offset OFFSET and the part's location by LOC.  */
6705
6706 static void
6707 delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
6708                       HOST_WIDE_INT offset)
6709 {
6710   void **slot = shared_hash_find_slot_noinsert (set->vars, dv);
6711   if (!slot)
6712     return;
6713
6714   slot = delete_slot_part (set, loc, slot, offset);
6715 }
6716
6717 /* Structure for passing some other parameters to function
6718    vt_expand_loc_callback.  */
6719 struct expand_loc_callback_data
6720 {
6721   /* The variables and values active at this point.  */
6722   htab_t vars;
6723
6724   /* True in vt_expand_loc_dummy calls, no rtl should be allocated.
6725      Non-NULL should be returned if vt_expand_loc would return
6726      non-NULL in that case, NULL otherwise.  cur_loc_changed should be
6727      computed and cur_loc recomputed when possible (but just once
6728      per emit_notes_for_changes call).  */
6729   bool dummy;
6730
6731   /* True if expansion of subexpressions had to recompute some
6732      VALUE/DEBUG_EXPR_DECL's cur_loc or used a VALUE/DEBUG_EXPR_DECL
6733      whose cur_loc has been already recomputed during current
6734      emit_notes_for_changes call.  */
6735   bool cur_loc_changed;
6736 };
6737
6738 /* Callback for cselib_expand_value, that looks for expressions
6739    holding the value in the var-tracking hash tables.  Return X for
6740    standard processing, anything else is to be used as-is.  */
6741
6742 static rtx
6743 vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data)
6744 {
6745   struct expand_loc_callback_data *elcd
6746     = (struct expand_loc_callback_data *) data;
6747   bool dummy = elcd->dummy;
6748   bool cur_loc_changed = elcd->cur_loc_changed;
6749   decl_or_value dv;
6750   variable var;
6751   location_chain loc;
6752   rtx result, subreg, xret;
6753
6754   switch (GET_CODE (x))
6755     {
6756     case SUBREG:
6757       if (dummy)
6758         {
6759           if (cselib_dummy_expand_value_rtx_cb (SUBREG_REG (x), regs,
6760                                                 max_depth - 1,
6761                                                 vt_expand_loc_callback, data))
6762             return pc_rtx;
6763           else
6764             return NULL;
6765         }
6766
6767       subreg = cselib_expand_value_rtx_cb (SUBREG_REG (x), regs,
6768                                            max_depth - 1,
6769                                            vt_expand_loc_callback, data);
6770
6771       if (!subreg)
6772         return NULL;
6773
6774       result = simplify_gen_subreg (GET_MODE (x), subreg,
6775                                     GET_MODE (SUBREG_REG (x)),
6776                                     SUBREG_BYTE (x));
6777
6778       /* Invalid SUBREGs are ok in debug info.  ??? We could try
6779          alternate expansions for the VALUE as well.  */
6780       if (!result)
6781         result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));
6782
6783       return result;
6784
6785     case DEBUG_EXPR:
6786       dv = dv_from_decl (DEBUG_EXPR_TREE_DECL (x));
6787       xret = NULL;
6788       break;
6789
6790     case VALUE:
6791       dv = dv_from_value (x);
6792       xret = x;
6793       break;
6794
6795     default:
6796       return x;
6797     }
6798
6799   if (VALUE_RECURSED_INTO (x))
6800     return NULL;
6801
6802   var = (variable) htab_find_with_hash (elcd->vars, dv, dv_htab_hash (dv));
6803
6804   if (!var)
6805     {
6806       if (dummy && dv_changed_p (dv))
6807         elcd->cur_loc_changed = true;
6808       return xret;
6809     }
6810
6811   if (var->n_var_parts == 0)
6812     {
6813       if (dummy)
6814         elcd->cur_loc_changed = true;
6815       return xret;
6816     }
6817
6818   gcc_assert (var->n_var_parts == 1);
6819
6820   VALUE_RECURSED_INTO (x) = true;
6821   result = NULL;
6822
6823   if (var->var_part[0].cur_loc)
6824     {
6825       if (dummy)
6826         {
6827           if (cselib_dummy_expand_value_rtx_cb (var->var_part[0].cur_loc, regs,
6828                                                 max_depth,
6829                                                 vt_expand_loc_callback, data))
6830             result = pc_rtx;
6831         }
6832       else
6833         result = cselib_expand_value_rtx_cb (var->var_part[0].cur_loc, regs,
6834                                              max_depth,
6835                                              vt_expand_loc_callback, data);
6836       if (result)
6837         set_dv_changed (dv, false);
6838     }
6839   if (!result && dv_changed_p (dv))
6840     {
6841       set_dv_changed (dv, false);
6842       for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
6843         if (loc->loc == var->var_part[0].cur_loc)
6844           continue;
6845         else if (dummy)
6846           {
6847             elcd->cur_loc_changed = cur_loc_changed;
6848             if (cselib_dummy_expand_value_rtx_cb (loc->loc, regs, max_depth,
6849                                                   vt_expand_loc_callback,
6850                                                   data))
6851               {
6852                 result = pc_rtx;
6853                 break;
6854               }
6855             else
6856               {
6857                 result = cselib_expand_value_rtx_cb (loc->loc, regs, max_depth,
6858                                                      vt_expand_loc_callback,
6859                                                      data);
6860                 if (result)
6861                   break;
6862               }
6863           }
6864       if (dummy && (result || var->var_part[0].cur_loc))
6865         var->cur_loc_changed = true;
6866       var->var_part[0].cur_loc = loc ? loc->loc : NULL_RTX;
6867     }
6868   if (dummy)
6869     {
6870       if (var->cur_loc_changed)
6871         elcd->cur_loc_changed = true;
6872       else if (!result && var->var_part[0].cur_loc == NULL_RTX)
6873         elcd->cur_loc_changed = cur_loc_changed;
6874     }
6875
6876   VALUE_RECURSED_INTO (x) = false;
6877   if (result)
6878     return result;
6879   else
6880     return xret;
6881 }
6882
6883 /* Expand VALUEs in LOC, using VARS as well as cselib's equivalence
6884    tables.  */
6885
6886 static rtx
6887 vt_expand_loc (rtx loc, htab_t vars)
6888 {
6889   struct expand_loc_callback_data data;
6890
6891   if (!MAY_HAVE_DEBUG_INSNS)
6892     return loc;
6893
6894   data.vars = vars;
6895   data.dummy = false;
6896   data.cur_loc_changed = false;
6897   loc = cselib_expand_value_rtx_cb (loc, scratch_regs, 5,
6898                                     vt_expand_loc_callback, &data);
6899
6900   if (loc && MEM_P (loc))
6901     loc = targetm.delegitimize_address (loc);
6902   return loc;
6903 }
6904
6905 /* Like vt_expand_loc, but only return true/false (whether vt_expand_loc
6906    would succeed or not, without actually allocating new rtxes.  */
6907
6908 static bool
6909 vt_expand_loc_dummy (rtx loc, htab_t vars, bool *pcur_loc_changed)
6910 {
6911   struct expand_loc_callback_data data;
6912   bool ret;
6913
6914   gcc_assert (MAY_HAVE_DEBUG_INSNS);
6915   data.vars = vars;
6916   data.dummy = true;
6917   data.cur_loc_changed = false;
6918   ret = cselib_dummy_expand_value_rtx_cb (loc, scratch_regs, 5,
6919                                           vt_expand_loc_callback, &data);
6920   *pcur_loc_changed = data.cur_loc_changed;
6921   return ret;
6922 }
6923
6924 #ifdef ENABLE_RTL_CHECKING
6925 /* Used to verify that cur_loc_changed updating is safe.  */
6926 static struct pointer_map_t *emitted_notes;
6927 #endif
6928
6929 /* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP.  DATA contains
6930    additional parameters: WHERE specifies whether the note shall be emitted
6931    before or after instruction INSN.  */
6932
6933 static int
6934 emit_note_insn_var_location (void **varp, void *data)
6935 {
6936   variable var = (variable) *varp;
6937   rtx insn = ((emit_note_data *)data)->insn;
6938   enum emit_note_where where = ((emit_note_data *)data)->where;
6939   htab_t vars = ((emit_note_data *)data)->vars;
6940   rtx note, note_vl;
6941   int i, j, n_var_parts;
6942   bool complete;
6943   enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED;
6944   HOST_WIDE_INT last_limit;
6945   tree type_size_unit;
6946   HOST_WIDE_INT offsets[MAX_VAR_PARTS];
6947   rtx loc[MAX_VAR_PARTS];
6948   tree decl;
6949   location_chain lc;
6950
6951   if (dv_is_value_p (var->dv))
6952     goto value_or_debug_decl;
6953
6954   decl = dv_as_decl (var->dv);
6955
6956   if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
6957     goto value_or_debug_decl;
6958
6959   complete = true;
6960   last_limit = 0;
6961   n_var_parts = 0;
6962   if (!MAY_HAVE_DEBUG_INSNS)
6963     {
6964       for (i = 0; i < var->n_var_parts; i++)
6965         if (var->var_part[i].cur_loc == NULL && var->var_part[i].loc_chain)
6966           {
6967             var->var_part[i].cur_loc = var->var_part[i].loc_chain->loc;
6968             var->cur_loc_changed = true;
6969           }
6970       if (var->n_var_parts == 0)
6971         var->cur_loc_changed = true;
6972     }
6973 #ifndef ENABLE_RTL_CHECKING
6974   if (!var->cur_loc_changed)
6975     goto clear;
6976 #endif
6977   for (i = 0; i < var->n_var_parts; i++)
6978     {
6979       enum machine_mode mode, wider_mode;
6980       rtx loc2;
6981
6982       if (last_limit < var->var_part[i].offset)
6983         {
6984           complete = false;
6985           break;
6986         }
6987       else if (last_limit > var->var_part[i].offset)
6988         continue;
6989       offsets[n_var_parts] = var->var_part[i].offset;
6990       if (!var->var_part[i].cur_loc)
6991         {
6992           complete = false;
6993           continue;
6994         }
6995       loc2 = vt_expand_loc (var->var_part[i].cur_loc, vars);
6996       if (!loc2)
6997         {
6998           complete = false;
6999           continue;
7000         }
7001       loc[n_var_parts] = loc2;
7002       mode = GET_MODE (var->var_part[i].cur_loc);
7003       if (mode == VOIDmode && dv_onepart_p (var->dv))
7004         mode = DECL_MODE (decl);
7005       for (lc = var->var_part[i].loc_chain; lc; lc = lc->next)
7006         if (var->var_part[i].cur_loc == lc->loc)
7007           {
7008             initialized = lc->init;
7009             break;
7010           }
7011       gcc_assert (lc);
7012       last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
7013
7014       /* Attempt to merge adjacent registers or memory.  */
7015       wider_mode = GET_MODE_WIDER_MODE (mode);
7016       for (j = i + 1; j < var->n_var_parts; j++)
7017         if (last_limit <= var->var_part[j].offset)
7018           break;
7019       if (j < var->n_var_parts
7020           && wider_mode != VOIDmode
7021           && var->var_part[j].cur_loc
7022           && mode == GET_MODE (var->var_part[j].cur_loc)
7023           && (REG_P (loc[n_var_parts]) || MEM_P (loc[n_var_parts]))
7024           && last_limit == var->var_part[j].offset
7025           && (loc2 = vt_expand_loc (var->var_part[j].cur_loc, vars))
7026           && GET_CODE (loc[n_var_parts]) == GET_CODE (loc2))
7027         {
7028           rtx new_loc = NULL;
7029
7030           if (REG_P (loc[n_var_parts])
7031               && hard_regno_nregs[REGNO (loc[n_var_parts])][mode] * 2
7032                  == hard_regno_nregs[REGNO (loc[n_var_parts])][wider_mode]
7033               && end_hard_regno (mode, REGNO (loc[n_var_parts]))
7034                  == REGNO (loc2))
7035             {
7036               if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
7037                 new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
7038                                            mode, 0);
7039               else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
7040                 new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
7041               if (new_loc)
7042                 {
7043                   if (!REG_P (new_loc)
7044                       || REGNO (new_loc) != REGNO (loc[n_var_parts]))
7045                     new_loc = NULL;
7046                   else
7047                     REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
7048                 }
7049             }
7050           else if (MEM_P (loc[n_var_parts])
7051                    && GET_CODE (XEXP (loc2, 0)) == PLUS
7052                    && REG_P (XEXP (XEXP (loc2, 0), 0))
7053                    && CONST_INT_P (XEXP (XEXP (loc2, 0), 1)))
7054             {
7055               if ((REG_P (XEXP (loc[n_var_parts], 0))
7056                    && rtx_equal_p (XEXP (loc[n_var_parts], 0),
7057                                    XEXP (XEXP (loc2, 0), 0))
7058                    && INTVAL (XEXP (XEXP (loc2, 0), 1))
7059                       == GET_MODE_SIZE (mode))
7060                   || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
7061                       && CONST_INT_P (XEXP (XEXP (loc[n_var_parts], 0), 1))
7062                       && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
7063                                       XEXP (XEXP (loc2, 0), 0))
7064                       && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
7065                          + GET_MODE_SIZE (mode)
7066                          == INTVAL (XEXP (XEXP (loc2, 0), 1))))
7067                 new_loc = adjust_address_nv (loc[n_var_parts],
7068                                              wider_mode, 0);
7069             }
7070
7071           if (new_loc)
7072             {
7073               loc[n_var_parts] = new_loc;
7074               mode = wider_mode;
7075               last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
7076               i = j;
7077             }
7078         }
7079       ++n_var_parts;
7080     }
7081   type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl));
7082   if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
7083     complete = false;
7084
7085   if (! flag_var_tracking_uninit)
7086     initialized = VAR_INIT_STATUS_INITIALIZED;
7087
7088   note_vl = NULL_RTX;
7089   if (!complete)
7090     note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, NULL_RTX,
7091                                     (int) initialized);
7092   else if (n_var_parts == 1)
7093     {
7094       rtx expr_list
7095         = gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
7096
7097       note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, expr_list,
7098                                       (int) initialized);
7099     }
7100   else if (n_var_parts)
7101     {
7102       rtx parallel;
7103
7104       for (i = 0; i < n_var_parts; i++)
7105         loc[i]
7106           = gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));
7107
7108       parallel = gen_rtx_PARALLEL (VOIDmode,
7109                                    gen_rtvec_v (n_var_parts, loc));
7110       note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl,
7111                                       parallel, (int) initialized);
7112     }
7113
7114 #ifdef ENABLE_RTL_CHECKING
7115   if (note_vl)
7116     {
7117       void **note_slot = pointer_map_insert (emitted_notes, decl);
7118       rtx pnote = (rtx) *note_slot;
7119       if (!var->cur_loc_changed && (pnote || PAT_VAR_LOCATION_LOC (note_vl)))
7120         {
7121           gcc_assert (pnote);
7122           gcc_assert (rtx_equal_p (PAT_VAR_LOCATION_LOC (pnote),
7123                                    PAT_VAR_LOCATION_LOC (note_vl)));
7124         }
7125       *note_slot = (void *) note_vl;
7126     }
7127   if (!var->cur_loc_changed)
7128     goto clear;
7129 #endif
7130
7131   if (where != EMIT_NOTE_BEFORE_INSN)
7132     {
7133       note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
7134       if (where == EMIT_NOTE_AFTER_CALL_INSN)
7135         NOTE_DURING_CALL_P (note) = true;
7136     }
7137   else
7138     note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
7139   NOTE_VAR_LOCATION (note) = note_vl;
7140
7141  clear:
7142   set_dv_changed (var->dv, false);
7143   var->cur_loc_changed = false;
7144   gcc_assert (var->in_changed_variables);
7145   var->in_changed_variables = false;
7146   htab_clear_slot (changed_variables, varp);
7147
7148   /* Continue traversing the hash table.  */
7149   return 1;
7150
7151  value_or_debug_decl:
7152   if (dv_changed_p (var->dv) && var->n_var_parts)
7153     {
7154       location_chain lc;
7155       bool cur_loc_changed;
7156
7157       if (var->var_part[0].cur_loc
7158           && vt_expand_loc_dummy (var->var_part[0].cur_loc, vars,
7159                                   &cur_loc_changed))
7160         goto clear;
7161       for (lc = var->var_part[0].loc_chain; lc; lc = lc->next)
7162         if (lc->loc != var->var_part[0].cur_loc
7163             && vt_expand_loc_dummy (lc->loc, vars, &cur_loc_changed))
7164           break;
7165       var->var_part[0].cur_loc = lc ? lc->loc : NULL_RTX;
7166     }
7167   goto clear;
7168 }
7169
7170 DEF_VEC_P (variable);
7171 DEF_VEC_ALLOC_P (variable, heap);
7172
7173 /* Stack of variable_def pointers that need processing with
7174    check_changed_vars_2.  */
7175
7176 static VEC (variable, heap) *changed_variables_stack;
7177
7178 /* VALUEs with no variables that need set_dv_changed (val, false)
7179    called before check_changed_vars_3.  */
7180
7181 static VEC (rtx, heap) *changed_values_stack;
7182
7183 /* Helper function for check_changed_vars_1 and check_changed_vars_2.  */
7184
7185 static void
7186 check_changed_vars_0 (decl_or_value dv, htab_t htab)
7187 {
7188   value_chain vc
7189     = (value_chain) htab_find_with_hash (value_chains, dv, dv_htab_hash (dv));
7190
7191   if (vc == NULL)
7192     return;
7193   for (vc = vc->next; vc; vc = vc->next)
7194     if (!dv_changed_p (vc->dv))
7195       {
7196         variable vcvar
7197           = (variable) htab_find_with_hash (htab, vc->dv,
7198                                             dv_htab_hash (vc->dv));
7199         if (vcvar)
7200           {
7201             set_dv_changed (vc->dv, true);
7202             VEC_safe_push (variable, heap, changed_variables_stack, vcvar);
7203           }
7204         else if (dv_is_value_p (vc->dv))
7205           {
7206             set_dv_changed (vc->dv, true);
7207             VEC_safe_push (rtx, heap, changed_values_stack,
7208                            dv_as_value (vc->dv));
7209             check_changed_vars_0 (vc->dv, htab);
7210           }
7211       }
7212 }
7213
7214 /* Populate changed_variables_stack with variable_def pointers
7215    that need variable_was_changed called on them.  */
7216
7217 static int
7218 check_changed_vars_1 (void **slot, void *data)
7219 {
7220   variable var = (variable) *slot;
7221   htab_t htab = (htab_t) data;
7222
7223   if (dv_is_value_p (var->dv)
7224       || TREE_CODE (dv_as_decl (var->dv)) == DEBUG_EXPR_DECL)
7225     check_changed_vars_0 (var->dv, htab);
7226   return 1;
7227 }
7228
7229 /* Add VAR to changed_variables and also for VALUEs add recursively
7230    all DVs that aren't in changed_variables yet but reference the
7231    VALUE from its loc_chain.  */
7232
7233 static void
7234 check_changed_vars_2 (variable var, htab_t htab)
7235 {
7236   variable_was_changed (var, NULL);
7237   if (dv_is_value_p (var->dv)
7238       || TREE_CODE (dv_as_decl (var->dv)) == DEBUG_EXPR_DECL)
7239     check_changed_vars_0 (var->dv, htab);
7240 }
7241
7242 /* For each changed decl (except DEBUG_EXPR_DECLs) recompute
7243    cur_loc if needed (and cur_loc of all VALUEs and DEBUG_EXPR_DECLs
7244    it needs and are also in changed variables) and track whether
7245    cur_loc (or anything it uses to compute location) had to change
7246    during the current emit_notes_for_changes call.  */
7247
7248 static int
7249 check_changed_vars_3 (void **slot, void *data)
7250 {
7251   variable var = (variable) *slot;
7252   htab_t vars = (htab_t) data;
7253   int i;
7254   location_chain lc;
7255   bool cur_loc_changed;
7256
7257   if (dv_is_value_p (var->dv)
7258       || TREE_CODE (dv_as_decl (var->dv)) == DEBUG_EXPR_DECL)
7259     return 1;
7260
7261   for (i = 0; i < var->n_var_parts; i++)
7262     {
7263       if (var->var_part[i].cur_loc
7264           && vt_expand_loc_dummy (var->var_part[i].cur_loc, vars,
7265                                   &cur_loc_changed))
7266         {
7267           if (cur_loc_changed)
7268             var->cur_loc_changed = true;
7269           continue;
7270         }
7271       for (lc = var->var_part[i].loc_chain; lc; lc = lc->next)
7272         if (lc->loc != var->var_part[i].cur_loc
7273             && vt_expand_loc_dummy (lc->loc, vars, &cur_loc_changed))
7274           break;
7275       if (lc || var->var_part[i].cur_loc)
7276         var->cur_loc_changed = true;
7277       var->var_part[i].cur_loc = lc ? lc->loc : NULL_RTX;
7278     }
7279   if (var->n_var_parts == 0)
7280     var->cur_loc_changed = true;
7281   return 1;
7282 }
7283
7284 /* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
7285    CHANGED_VARIABLES and delete this chain.  WHERE specifies whether the notes
7286    shall be emitted before of after instruction INSN.  */
7287
7288 static void
7289 emit_notes_for_changes (rtx insn, enum emit_note_where where,
7290                         shared_hash vars)
7291 {
7292   emit_note_data data;
7293   htab_t htab = shared_hash_htab (vars);
7294
7295   if (!htab_elements (changed_variables))
7296     return;
7297
7298   if (MAY_HAVE_DEBUG_INSNS)
7299     {
7300       /* Unfortunately this has to be done in two steps, because
7301          we can't traverse a hashtab into which we are inserting
7302          through variable_was_changed.  */
7303       htab_traverse (changed_variables, check_changed_vars_1, htab);
7304       while (VEC_length (variable, changed_variables_stack) > 0)
7305         check_changed_vars_2 (VEC_pop (variable, changed_variables_stack),
7306                               htab);
7307       while (VEC_length (rtx, changed_values_stack) > 0)
7308         set_dv_changed (dv_from_value (VEC_pop (rtx, changed_values_stack)),
7309                         false);
7310       htab_traverse (changed_variables, check_changed_vars_3, htab);
7311     }
7312
7313   data.insn = insn;
7314   data.where = where;
7315   data.vars = htab;
7316
7317   htab_traverse (changed_variables, emit_note_insn_var_location, &data);
7318 }
7319
7320 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
7321    same variable in hash table DATA or is not there at all.  */
7322
7323 static int
7324 emit_notes_for_differences_1 (void **slot, void *data)
7325 {
7326   htab_t new_vars = (htab_t) data;
7327   variable old_var, new_var;
7328
7329   old_var = (variable) *slot;
7330   new_var = (variable) htab_find_with_hash (new_vars, old_var->dv,
7331                                             dv_htab_hash (old_var->dv));
7332
7333   if (!new_var)
7334     {
7335       /* Variable has disappeared.  */
7336       variable empty_var;
7337
7338       empty_var = (variable) pool_alloc (dv_pool (old_var->dv));
7339       empty_var->dv = old_var->dv;
7340       empty_var->refcount = 0;
7341       empty_var->n_var_parts = 0;
7342       empty_var->cur_loc_changed = false;
7343       empty_var->in_changed_variables = false;
7344       if (dv_onepart_p (old_var->dv))
7345         {
7346           location_chain lc;
7347
7348           gcc_assert (old_var->n_var_parts == 1);
7349           for (lc = old_var->var_part[0].loc_chain; lc; lc = lc->next)
7350             remove_value_chains (old_var->dv, lc->loc);
7351         }
7352       variable_was_changed (empty_var, NULL);
7353       /* Continue traversing the hash table.  */
7354       return 1;
7355     }
7356   if (variable_different_p (old_var, new_var))
7357     {
7358       if (dv_onepart_p (old_var->dv))
7359         {
7360           location_chain lc1, lc2;
7361
7362           gcc_assert (old_var->n_var_parts == 1);
7363           gcc_assert (new_var->n_var_parts == 1);
7364           lc1 = old_var->var_part[0].loc_chain;
7365           lc2 = new_var->var_part[0].loc_chain;
7366           while (lc1
7367                  && lc2
7368                  && ((REG_P (lc1->loc) && REG_P (lc2->loc))
7369                      || rtx_equal_p (lc1->loc, lc2->loc)))
7370             {
7371               lc1 = lc1->next;
7372               lc2 = lc2->next;
7373             }
7374           for (; lc2; lc2 = lc2->next)
7375             add_value_chains (old_var->dv, lc2->loc);
7376           for (; lc1; lc1 = lc1->next)
7377             remove_value_chains (old_var->dv, lc1->loc);
7378         }
7379       variable_was_changed (new_var, NULL);
7380     }
7381   /* Update cur_loc.  */
7382   if (old_var != new_var)
7383     {
7384       int i;
7385       for (i = 0; i < new_var->n_var_parts; i++)
7386         {
7387           new_var->var_part[i].cur_loc = NULL;
7388           if (old_var->n_var_parts != new_var->n_var_parts
7389               || old_var->var_part[i].offset != new_var->var_part[i].offset)
7390             new_var->cur_loc_changed = true;
7391           else if (old_var->var_part[i].cur_loc != NULL)
7392             {
7393               location_chain lc;
7394               rtx cur_loc = old_var->var_part[i].cur_loc;
7395
7396               for (lc = new_var->var_part[i].loc_chain; lc; lc = lc->next)
7397                 if (lc->loc == cur_loc
7398                     || rtx_equal_p (cur_loc, lc->loc))
7399                   {
7400                     new_var->var_part[i].cur_loc = lc->loc;
7401                     break;
7402                   }
7403               if (lc == NULL)
7404                 new_var->cur_loc_changed = true;
7405             }
7406         }
7407     }
7408
7409   /* Continue traversing the hash table.  */
7410   return 1;
7411 }
7412
7413 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
7414    table DATA.  */
7415
7416 static int
7417 emit_notes_for_differences_2 (void **slot, void *data)
7418 {
7419   htab_t old_vars = (htab_t) data;
7420   variable old_var, new_var;
7421
7422   new_var = (variable) *slot;
7423   old_var = (variable) htab_find_with_hash (old_vars, new_var->dv,
7424                                             dv_htab_hash (new_var->dv));
7425   if (!old_var)
7426     {
7427       int i;
7428       /* Variable has appeared.  */
7429       if (dv_onepart_p (new_var->dv))
7430         {
7431           location_chain lc;
7432
7433           gcc_assert (new_var->n_var_parts == 1);
7434           for (lc = new_var->var_part[0].loc_chain; lc; lc = lc->next)
7435             add_value_chains (new_var->dv, lc->loc);
7436         }
7437       for (i = 0; i < new_var->n_var_parts; i++)
7438         new_var->var_part[i].cur_loc = NULL;
7439       variable_was_changed (new_var, NULL);
7440     }
7441
7442   /* Continue traversing the hash table.  */
7443   return 1;
7444 }
7445
7446 /* Emit notes before INSN for differences between dataflow sets OLD_SET and
7447    NEW_SET.  */
7448
7449 static void
7450 emit_notes_for_differences (rtx insn, dataflow_set *old_set,
7451                             dataflow_set *new_set)
7452 {
7453   htab_traverse (shared_hash_htab (old_set->vars),
7454                  emit_notes_for_differences_1,
7455                  shared_hash_htab (new_set->vars));
7456   htab_traverse (shared_hash_htab (new_set->vars),
7457                  emit_notes_for_differences_2,
7458                  shared_hash_htab (old_set->vars));
7459   emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, new_set->vars);
7460 }
7461
7462 /* Emit the notes for changes of location parts in the basic block BB.  */
7463
7464 static void
7465 emit_notes_in_bb (basic_block bb, dataflow_set *set)
7466 {
7467   unsigned int i;
7468   micro_operation *mo;
7469
7470   dataflow_set_clear (set);
7471   dataflow_set_copy (set, &VTI (bb)->in);
7472
7473   for (i = 0; VEC_iterate (micro_operation, VTI (bb)->mos, i, mo); i++)
7474     {
7475       rtx insn = mo->insn;
7476
7477       switch (mo->type)
7478         {
7479           case MO_CALL:
7480             dataflow_set_clear_at_call (set);
7481             emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars);
7482             break;
7483
7484           case MO_USE:
7485             {
7486               rtx loc = mo->u.loc;
7487
7488               if (REG_P (loc))
7489                 var_reg_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
7490               else
7491                 var_mem_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
7492
7493               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
7494             }
7495             break;
7496
7497           case MO_VAL_LOC:
7498             {
7499               rtx loc = mo->u.loc;
7500               rtx val, vloc;
7501               tree var;
7502
7503               if (GET_CODE (loc) == CONCAT)
7504                 {
7505                   val = XEXP (loc, 0);
7506                   vloc = XEXP (loc, 1);
7507                 }
7508               else
7509                 {
7510                   val = NULL_RTX;
7511                   vloc = loc;
7512                 }
7513
7514               var = PAT_VAR_LOCATION_DECL (vloc);
7515
7516               clobber_variable_part (set, NULL_RTX,
7517                                      dv_from_decl (var), 0, NULL_RTX);
7518               if (val)
7519                 {
7520                   if (VAL_NEEDS_RESOLUTION (loc))
7521                     val_resolve (set, val, PAT_VAR_LOCATION_LOC (vloc), insn);
7522                   set_variable_part (set, val, dv_from_decl (var), 0,
7523                                      VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
7524                                      INSERT);
7525                 }
7526               else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
7527                 set_variable_part (set, PAT_VAR_LOCATION_LOC (vloc),
7528                                    dv_from_decl (var), 0,
7529                                    VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
7530                                    INSERT);
7531
7532               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
7533             }
7534             break;
7535
7536           case MO_VAL_USE:
7537             {
7538               rtx loc = mo->u.loc;
7539               rtx val, vloc, uloc;
7540
7541               vloc = uloc = XEXP (loc, 1);
7542               val = XEXP (loc, 0);
7543
7544               if (GET_CODE (val) == CONCAT)
7545                 {
7546                   uloc = XEXP (val, 1);
7547                   val = XEXP (val, 0);
7548                 }
7549
7550               if (VAL_NEEDS_RESOLUTION (loc))
7551                 val_resolve (set, val, vloc, insn);
7552               else
7553                 val_store (set, val, uloc, insn, false);
7554
7555               if (VAL_HOLDS_TRACK_EXPR (loc))
7556                 {
7557                   if (GET_CODE (uloc) == REG)
7558                     var_reg_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
7559                                  NULL);
7560                   else if (GET_CODE (uloc) == MEM)
7561                     var_mem_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
7562                                  NULL);
7563                 }
7564
7565               emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
7566             }
7567             break;
7568
7569           case MO_VAL_SET:
7570             {
7571               rtx loc = mo->u.loc;
7572               rtx val, vloc, uloc, reverse = NULL_RTX;
7573
7574               vloc = loc;
7575               if (VAL_EXPR_HAS_REVERSE (loc))
7576                 {
7577                   reverse = XEXP (loc, 1);
7578                   vloc = XEXP (loc, 0);
7579                 }
7580               uloc = XEXP (vloc, 1);
7581               val = XEXP (vloc, 0);
7582               vloc = uloc;
7583
7584               if (GET_CODE (val) == CONCAT)
7585                 {
7586                   vloc = XEXP (val, 1);
7587                   val = XEXP (val, 0);
7588                 }
7589
7590               if (GET_CODE (vloc) == SET)
7591                 {
7592                   rtx vsrc = SET_SRC (vloc);
7593
7594                   gcc_assert (val != vsrc);
7595                   gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
7596
7597                   vloc = SET_DEST (vloc);
7598
7599                   if (VAL_NEEDS_RESOLUTION (loc))
7600                     val_resolve (set, val, vsrc, insn);
7601                 }
7602               else if (VAL_NEEDS_RESOLUTION (loc))
7603                 {
7604                   gcc_assert (GET_CODE (uloc) == SET
7605                               && GET_CODE (SET_SRC (uloc)) == REG);
7606                   val_resolve (set, val, SET_SRC (uloc), insn);
7607                 }
7608
7609               if (VAL_HOLDS_TRACK_EXPR (loc))
7610                 {
7611                   if (VAL_EXPR_IS_CLOBBERED (loc))
7612                     {
7613                       if (REG_P (uloc))
7614                         var_reg_delete (set, uloc, true);
7615                       else if (MEM_P (uloc))
7616                         var_mem_delete (set, uloc, true);
7617                     }
7618                   else
7619                     {
7620                       bool copied_p = VAL_EXPR_IS_COPIED (loc);
7621                       rtx set_src = NULL;
7622                       enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
7623
7624                       if (GET_CODE (uloc) == SET)
7625                         {
7626                           set_src = SET_SRC (uloc);
7627                           uloc = SET_DEST (uloc);
7628                         }
7629
7630                       if (copied_p)
7631                         {
7632                           status = find_src_status (set, set_src);
7633
7634                           set_src = find_src_set_src (set, set_src);
7635                         }
7636
7637                       if (REG_P (uloc))
7638                         var_reg_delete_and_set (set, uloc, !copied_p,
7639                                                 status, set_src);
7640                       else if (MEM_P (uloc))
7641                         var_mem_delete_and_set (set, uloc, !copied_p,
7642                                                 status, set_src);
7643                     }
7644                 }
7645               else if (REG_P (uloc))
7646                 var_regno_delete (set, REGNO (uloc));
7647
7648               val_store (set, val, vloc, insn, true);
7649
7650               if (reverse)
7651                 val_store (set, XEXP (reverse, 0), XEXP (reverse, 1),
7652                            insn, false);
7653
7654               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
7655                                       set->vars);
7656             }
7657             break;
7658
7659           case MO_SET:
7660             {
7661               rtx loc = mo->u.loc;
7662               rtx set_src = NULL;
7663
7664               if (GET_CODE (loc) == SET)
7665                 {
7666                   set_src = SET_SRC (loc);
7667                   loc = SET_DEST (loc);
7668                 }
7669
7670               if (REG_P (loc))
7671                 var_reg_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
7672                                         set_src);
7673               else
7674                 var_mem_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
7675                                         set_src);
7676
7677               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
7678                                       set->vars);
7679             }
7680             break;
7681
7682           case MO_COPY:
7683             {
7684               rtx loc = mo->u.loc;
7685               enum var_init_status src_status;
7686               rtx set_src = NULL;
7687
7688               if (GET_CODE (loc) == SET)
7689                 {
7690                   set_src = SET_SRC (loc);
7691                   loc = SET_DEST (loc);
7692                 }
7693
7694               src_status = find_src_status (set, set_src);
7695               set_src = find_src_set_src (set, set_src);
7696
7697               if (REG_P (loc))
7698                 var_reg_delete_and_set (set, loc, false, src_status, set_src);
7699               else
7700                 var_mem_delete_and_set (set, loc, false, src_status, set_src);
7701
7702               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
7703                                       set->vars);
7704             }
7705             break;
7706
7707           case MO_USE_NO_VAR:
7708             {
7709               rtx loc = mo->u.loc;
7710
7711               if (REG_P (loc))
7712                 var_reg_delete (set, loc, false);
7713               else
7714                 var_mem_delete (set, loc, false);
7715
7716               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
7717             }
7718             break;
7719
7720           case MO_CLOBBER:
7721             {
7722               rtx loc = mo->u.loc;
7723
7724               if (REG_P (loc))
7725                 var_reg_delete (set, loc, true);
7726               else
7727                 var_mem_delete (set, loc, true);
7728
7729               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
7730                                       set->vars);
7731             }
7732             break;
7733
7734           case MO_ADJUST:
7735             set->stack_adjust += mo->u.adjust;
7736             break;
7737         }
7738     }
7739 }
7740
7741 /* Emit notes for the whole function.  */
7742
7743 static void
7744 vt_emit_notes (void)
7745 {
7746   basic_block bb;
7747   dataflow_set cur;
7748
7749 #ifdef ENABLE_RTL_CHECKING
7750   emitted_notes = pointer_map_create ();
7751 #endif
7752   gcc_assert (!htab_elements (changed_variables));
7753
7754   /* Free memory occupied by the out hash tables, as they aren't used
7755      anymore.  */
7756   FOR_EACH_BB (bb)
7757     dataflow_set_clear (&VTI (bb)->out);
7758
7759   /* Enable emitting notes by functions (mainly by set_variable_part and
7760      delete_variable_part).  */
7761   emit_notes = true;
7762
7763   if (MAY_HAVE_DEBUG_INSNS)
7764     {
7765       unsigned int i;
7766       rtx val;
7767
7768       for (i = 0; VEC_iterate (rtx, preserved_values, i, val); i++)
7769         add_cselib_value_chains (dv_from_value (val));
7770       changed_variables_stack = VEC_alloc (variable, heap, 40);
7771       changed_values_stack = VEC_alloc (rtx, heap, 40);
7772     }
7773
7774   dataflow_set_init (&cur);
7775
7776   FOR_EACH_BB (bb)
7777     {
7778       /* Emit the notes for changes of variable locations between two
7779          subsequent basic blocks.  */
7780       emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
7781
7782       /* Emit the notes for the changes in the basic block itself.  */
7783       emit_notes_in_bb (bb, &cur);
7784
7785       /* Free memory occupied by the in hash table, we won't need it
7786          again.  */
7787       dataflow_set_clear (&VTI (bb)->in);
7788     }
7789 #ifdef ENABLE_CHECKING
7790   htab_traverse (shared_hash_htab (cur.vars),
7791                  emit_notes_for_differences_1,
7792                  shared_hash_htab (empty_shared_hash));
7793   if (MAY_HAVE_DEBUG_INSNS)
7794     {
7795       unsigned int i;
7796       rtx val;
7797
7798       for (i = 0; VEC_iterate (rtx, preserved_values, i, val); i++)
7799         remove_cselib_value_chains (dv_from_value (val));
7800       gcc_assert (htab_elements (value_chains) == 0);
7801     }
7802 #endif
7803   dataflow_set_destroy (&cur);
7804
7805   if (MAY_HAVE_DEBUG_INSNS)
7806     {
7807       VEC_free (variable, heap, changed_variables_stack);
7808       VEC_free (rtx, heap, changed_values_stack);
7809     }
7810
7811 #ifdef ENABLE_RTL_CHECKING
7812   pointer_map_destroy (emitted_notes);
7813 #endif
7814   emit_notes = false;
7815 }
7816
7817 /* If there is a declaration and offset associated with register/memory RTL
7818    assign declaration to *DECLP and offset to *OFFSETP, and return true.  */
7819
7820 static bool
7821 vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
7822 {
7823   if (REG_P (rtl))
7824     {
7825       if (REG_ATTRS (rtl))
7826         {
7827           *declp = REG_EXPR (rtl);
7828           *offsetp = REG_OFFSET (rtl);
7829           return true;
7830         }
7831     }
7832   else if (MEM_P (rtl))
7833     {
7834       if (MEM_ATTRS (rtl))
7835         {
7836           *declp = MEM_EXPR (rtl);
7837           *offsetp = INT_MEM_OFFSET (rtl);
7838           return true;
7839         }
7840     }
7841   return false;
7842 }
7843
7844 /* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */
7845
7846 static void
7847 vt_add_function_parameters (void)
7848 {
7849   tree parm;
7850
7851   for (parm = DECL_ARGUMENTS (current_function_decl);
7852        parm; parm = TREE_CHAIN (parm))
7853     {
7854       rtx decl_rtl = DECL_RTL_IF_SET (parm);
7855       rtx incoming = DECL_INCOMING_RTL (parm);
7856       tree decl;
7857       enum machine_mode mode;
7858       HOST_WIDE_INT offset;
7859       dataflow_set *out;
7860       decl_or_value dv;
7861
7862       if (TREE_CODE (parm) != PARM_DECL)
7863         continue;
7864
7865       if (!DECL_NAME (parm))
7866         continue;
7867
7868       if (!decl_rtl || !incoming)
7869         continue;
7870
7871       if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
7872         continue;
7873
7874       if (!vt_get_decl_and_offset (incoming, &decl, &offset))
7875         {
7876           if (REG_P (incoming) || MEM_P (incoming))
7877             {
7878               /* This means argument is passed by invisible reference.  */
7879               offset = 0;
7880               decl = parm;
7881               incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
7882             }
7883           else
7884             {
7885               if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
7886                 continue;
7887               offset += byte_lowpart_offset (GET_MODE (incoming),
7888                                              GET_MODE (decl_rtl));
7889             }
7890         }
7891
7892       if (!decl)
7893         continue;
7894
7895       if (parm != decl)
7896         {
7897           /* Assume that DECL_RTL was a pseudo that got spilled to
7898              memory.  The spill slot sharing code will force the
7899              memory to reference spill_slot_decl (%sfp), so we don't
7900              match above.  That's ok, the pseudo must have referenced
7901              the entire parameter, so just reset OFFSET.  */
7902           gcc_assert (decl == get_spill_slot_decl (false));
7903           offset = 0;
7904         }
7905
7906       if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
7907         continue;
7908
7909       out = &VTI (ENTRY_BLOCK_PTR)->out;
7910
7911       dv = dv_from_decl (parm);
7912
7913       if (target_for_debug_bind (parm)
7914           /* We can't deal with these right now, because this kind of
7915              variable is single-part.  ??? We could handle parallels
7916              that describe multiple locations for the same single
7917              value, but ATM we don't.  */
7918           && GET_CODE (incoming) != PARALLEL)
7919         {
7920           cselib_val *val;
7921
7922           /* ??? We shouldn't ever hit this, but it may happen because
7923              arguments passed by invisible reference aren't dealt with
7924              above: incoming-rtl will have Pmode rather than the
7925              expected mode for the type.  */
7926           if (offset)
7927             continue;
7928
7929           val = cselib_lookup (var_lowpart (mode, incoming), mode, true);
7930
7931           /* ??? Float-typed values in memory are not handled by
7932              cselib.  */
7933           if (val)
7934             {
7935               preserve_value (val);
7936               set_variable_part (out, val->val_rtx, dv, offset,
7937                                  VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
7938               dv = dv_from_value (val->val_rtx);
7939             }
7940         }
7941
7942       if (REG_P (incoming))
7943         {
7944           incoming = var_lowpart (mode, incoming);
7945           gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
7946           attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
7947                              incoming);
7948           set_variable_part (out, incoming, dv, offset,
7949                              VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
7950         }
7951       else if (MEM_P (incoming))
7952         {
7953           incoming = var_lowpart (mode, incoming);
7954           set_variable_part (out, incoming, dv, offset,
7955                              VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
7956         }
7957     }
7958
7959   if (MAY_HAVE_DEBUG_INSNS)
7960     {
7961       cselib_preserve_only_values ();
7962       cselib_reset_table (cselib_get_next_uid ());
7963     }
7964
7965 }
7966
7967 /* Return true if INSN in the prologue initializes hard_frame_pointer_rtx.  */
7968
7969 static bool
7970 fp_setter (rtx insn)
7971 {
7972   rtx pat = PATTERN (insn);
7973   if (RTX_FRAME_RELATED_P (insn))
7974     {
7975       rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
7976       if (expr)
7977         pat = XEXP (expr, 0);
7978     }
7979   if (GET_CODE (pat) == SET)
7980     return SET_DEST (pat) == hard_frame_pointer_rtx;
7981   else if (GET_CODE (pat) == PARALLEL)
7982     {
7983       int i;
7984       for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
7985         if (GET_CODE (XVECEXP (pat, 0, i)) == SET
7986             && SET_DEST (XVECEXP (pat, 0, i)) == hard_frame_pointer_rtx)
7987           return true;
7988     }
7989   return false;
7990 }
7991
7992 /* Initialize cfa_base_rtx, create a preserved VALUE for it and
7993    ensure it isn't flushed during cselib_reset_table.
7994    Can be called only if frame_pointer_rtx resp. arg_pointer_rtx
7995    has been eliminated.  */
7996
7997 static void
7998 vt_init_cfa_base (void)
7999 {
8000   cselib_val *val;
8001
8002 #ifdef FRAME_POINTER_CFA_OFFSET
8003   cfa_base_rtx = frame_pointer_rtx;
8004 #else
8005   cfa_base_rtx = arg_pointer_rtx;
8006 #endif
8007   if (cfa_base_rtx == hard_frame_pointer_rtx
8008       || !fixed_regs[REGNO (cfa_base_rtx)])
8009     {
8010       cfa_base_rtx = NULL_RTX;
8011       return;
8012     }
8013   if (!MAY_HAVE_DEBUG_INSNS)
8014     return;
8015
8016   val = cselib_lookup (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1);
8017   preserve_value (val);
8018   cselib_preserve_cfa_base_value (val);
8019   val->locs->setting_insn = get_insns ();
8020   var_reg_decl_set (&VTI (ENTRY_BLOCK_PTR)->out, cfa_base_rtx,
8021                     VAR_INIT_STATUS_INITIALIZED, dv_from_value (val->val_rtx),
8022                     0, NULL_RTX, INSERT);
8023 }
8024
8025 /* Allocate and initialize the data structures for variable tracking
8026    and parse the RTL to get the micro operations.  */
8027
8028 static bool
8029 vt_initialize (void)
8030 {
8031   basic_block bb, prologue_bb = NULL;
8032   HOST_WIDE_INT fp_cfa_offset = -1;
8033
8034   alloc_aux_for_blocks (sizeof (struct variable_tracking_info_def));
8035
8036   attrs_pool = create_alloc_pool ("attrs_def pool",
8037                                   sizeof (struct attrs_def), 1024);
8038   var_pool = create_alloc_pool ("variable_def pool",
8039                                 sizeof (struct variable_def)
8040                                 + (MAX_VAR_PARTS - 1)
8041                                 * sizeof (((variable)NULL)->var_part[0]), 64);
8042   loc_chain_pool = create_alloc_pool ("location_chain_def pool",
8043                                       sizeof (struct location_chain_def),
8044                                       1024);
8045   shared_hash_pool = create_alloc_pool ("shared_hash_def pool",
8046                                         sizeof (struct shared_hash_def), 256);
8047   empty_shared_hash = (shared_hash) pool_alloc (shared_hash_pool);
8048   empty_shared_hash->refcount = 1;
8049   empty_shared_hash->htab
8050     = htab_create (1, variable_htab_hash, variable_htab_eq,
8051                    variable_htab_free);
8052   changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
8053                                    variable_htab_free);
8054   if (MAY_HAVE_DEBUG_INSNS)
8055     {
8056       value_chain_pool = create_alloc_pool ("value_chain_def pool",
8057                                             sizeof (struct value_chain_def),
8058                                             1024);
8059       value_chains = htab_create (32, value_chain_htab_hash,
8060                                   value_chain_htab_eq, NULL);
8061     }
8062
8063   /* Init the IN and OUT sets.  */
8064   FOR_ALL_BB (bb)
8065     {
8066       VTI (bb)->visited = false;
8067       VTI (bb)->flooded = false;
8068       dataflow_set_init (&VTI (bb)->in);
8069       dataflow_set_init (&VTI (bb)->out);
8070       VTI (bb)->permp = NULL;
8071     }
8072
8073   if (MAY_HAVE_DEBUG_INSNS)
8074     {
8075       cselib_init (CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS);
8076       scratch_regs = BITMAP_ALLOC (NULL);
8077       valvar_pool = create_alloc_pool ("small variable_def pool",
8078                                        sizeof (struct variable_def), 256);
8079       preserved_values = VEC_alloc (rtx, heap, 256);
8080     }
8081   else
8082     {
8083       scratch_regs = NULL;
8084       valvar_pool = NULL;
8085     }
8086
8087   if (!frame_pointer_needed)
8088     {
8089       rtx reg, elim;
8090
8091       if (!vt_stack_adjustments ())
8092         return false;
8093
8094 #ifdef FRAME_POINTER_CFA_OFFSET
8095       reg = frame_pointer_rtx;
8096 #else
8097       reg = arg_pointer_rtx;
8098 #endif
8099       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
8100       if (elim != reg)
8101         {
8102           if (GET_CODE (elim) == PLUS)
8103             elim = XEXP (elim, 0);
8104           if (elim == stack_pointer_rtx)
8105             vt_init_cfa_base ();
8106         }
8107     }
8108   else if (!crtl->stack_realign_tried)
8109     {
8110       rtx reg, elim;
8111
8112 #ifdef FRAME_POINTER_CFA_OFFSET
8113       reg = frame_pointer_rtx;
8114       fp_cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
8115 #else
8116       reg = arg_pointer_rtx;
8117       fp_cfa_offset = ARG_POINTER_CFA_OFFSET (current_function_decl);
8118 #endif
8119       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
8120       if (elim != reg)
8121         {
8122           if (GET_CODE (elim) == PLUS)
8123             {
8124               fp_cfa_offset -= INTVAL (XEXP (elim, 1));
8125               elim = XEXP (elim, 0);
8126             }
8127           if (elim != hard_frame_pointer_rtx)
8128             fp_cfa_offset = -1;
8129           else
8130             prologue_bb = single_succ (ENTRY_BLOCK_PTR);
8131         }
8132     }
8133
8134   hard_frame_pointer_adjustment = -1;
8135
8136   FOR_EACH_BB (bb)
8137     {
8138       rtx insn;
8139       HOST_WIDE_INT pre, post = 0;
8140       basic_block first_bb, last_bb;
8141
8142       if (MAY_HAVE_DEBUG_INSNS)
8143         {
8144           cselib_record_sets_hook = add_with_sets;
8145           if (dump_file && (dump_flags & TDF_DETAILS))
8146             fprintf (dump_file, "first value: %i\n",
8147                      cselib_get_next_uid ());
8148         }
8149
8150       first_bb = bb;
8151       for (;;)
8152         {
8153           edge e;
8154           if (bb->next_bb == EXIT_BLOCK_PTR
8155               || ! single_pred_p (bb->next_bb))
8156             break;
8157           e = find_edge (bb, bb->next_bb);
8158           if (! e || (e->flags & EDGE_FALLTHRU) == 0)
8159             break;
8160           bb = bb->next_bb;
8161         }
8162       last_bb = bb;
8163
8164       /* Add the micro-operations to the vector.  */
8165       FOR_BB_BETWEEN (bb, first_bb, last_bb->next_bb, next_bb)
8166         {
8167           HOST_WIDE_INT offset = VTI (bb)->out.stack_adjust;
8168           VTI (bb)->out.stack_adjust = VTI (bb)->in.stack_adjust;
8169           for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
8170                insn = NEXT_INSN (insn))
8171             {
8172               if (INSN_P (insn))
8173                 {
8174                   if (!frame_pointer_needed)
8175                     {
8176                       insn_stack_adjust_offset_pre_post (insn, &pre, &post);
8177                       if (pre)
8178                         {
8179                           micro_operation mo;
8180                           mo.type = MO_ADJUST;
8181                           mo.u.adjust = pre;
8182                           mo.insn = insn;
8183                           if (dump_file && (dump_flags & TDF_DETAILS))
8184                             log_op_type (PATTERN (insn), bb, insn,
8185                                          MO_ADJUST, dump_file);
8186                           VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
8187                                          &mo);
8188                           VTI (bb)->out.stack_adjust += pre;
8189                         }
8190                     }
8191
8192                   cselib_hook_called = false;
8193                   adjust_insn (bb, insn);
8194                   if (MAY_HAVE_DEBUG_INSNS)
8195                     {
8196                       cselib_process_insn (insn);
8197                       if (dump_file && (dump_flags & TDF_DETAILS))
8198                         {
8199                           print_rtl_single (dump_file, insn);
8200                           dump_cselib_table (dump_file);
8201                         }
8202                     }
8203                   if (!cselib_hook_called)
8204                     add_with_sets (insn, 0, 0);
8205                   cancel_changes (0);
8206
8207                   if (!frame_pointer_needed && post)
8208                     {
8209                       micro_operation mo;
8210                       mo.type = MO_ADJUST;
8211                       mo.u.adjust = post;
8212                       mo.insn = insn;
8213                       if (dump_file && (dump_flags & TDF_DETAILS))
8214                         log_op_type (PATTERN (insn), bb, insn,
8215                                      MO_ADJUST, dump_file);
8216                       VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
8217                                      &mo);
8218                       VTI (bb)->out.stack_adjust += post;
8219                     }
8220
8221                   if (bb == prologue_bb
8222                       && hard_frame_pointer_adjustment == -1
8223                       && RTX_FRAME_RELATED_P (insn)
8224                       && fp_setter (insn))
8225                     {
8226                       vt_init_cfa_base ();
8227                       hard_frame_pointer_adjustment = fp_cfa_offset;
8228                     }
8229                 }
8230             }
8231           gcc_assert (offset == VTI (bb)->out.stack_adjust);
8232         }
8233
8234       bb = last_bb;
8235
8236       if (MAY_HAVE_DEBUG_INSNS)
8237         {
8238           cselib_preserve_only_values ();
8239           cselib_reset_table (cselib_get_next_uid ());
8240           cselib_record_sets_hook = NULL;
8241         }
8242     }
8243
8244   hard_frame_pointer_adjustment = -1;
8245   VTI (ENTRY_BLOCK_PTR)->flooded = true;
8246   vt_add_function_parameters ();
8247   cfa_base_rtx = NULL_RTX;
8248   return true;
8249 }
8250
8251 /* Get rid of all debug insns from the insn stream.  */
8252
8253 static void
8254 delete_debug_insns (void)
8255 {
8256   basic_block bb;
8257   rtx insn, next;
8258
8259   if (!MAY_HAVE_DEBUG_INSNS)
8260     return;
8261
8262   FOR_EACH_BB (bb)
8263     {
8264       FOR_BB_INSNS_SAFE (bb, insn, next)
8265         if (DEBUG_INSN_P (insn))
8266           delete_insn (insn);
8267     }
8268 }
8269
8270 /* Run a fast, BB-local only version of var tracking, to take care of
8271    information that we don't do global analysis on, such that not all
8272    information is lost.  If SKIPPED holds, we're skipping the global
8273    pass entirely, so we should try to use information it would have
8274    handled as well..  */
8275
8276 static void
8277 vt_debug_insns_local (bool skipped ATTRIBUTE_UNUSED)
8278 {
8279   /* ??? Just skip it all for now.  */
8280   delete_debug_insns ();
8281 }
8282
8283 /* Free the data structures needed for variable tracking.  */
8284
8285 static void
8286 vt_finalize (void)
8287 {
8288   basic_block bb;
8289
8290   FOR_EACH_BB (bb)
8291     {
8292       VEC_free (micro_operation, heap, VTI (bb)->mos);
8293     }
8294
8295   FOR_ALL_BB (bb)
8296     {
8297       dataflow_set_destroy (&VTI (bb)->in);
8298       dataflow_set_destroy (&VTI (bb)->out);
8299       if (VTI (bb)->permp)
8300         {
8301           dataflow_set_destroy (VTI (bb)->permp);
8302           XDELETE (VTI (bb)->permp);
8303         }
8304     }
8305   free_aux_for_blocks ();
8306   htab_delete (empty_shared_hash->htab);
8307   htab_delete (changed_variables);
8308   free_alloc_pool (attrs_pool);
8309   free_alloc_pool (var_pool);
8310   free_alloc_pool (loc_chain_pool);
8311   free_alloc_pool (shared_hash_pool);
8312
8313   if (MAY_HAVE_DEBUG_INSNS)
8314     {
8315       htab_delete (value_chains);
8316       free_alloc_pool (value_chain_pool);
8317       free_alloc_pool (valvar_pool);
8318       VEC_free (rtx, heap, preserved_values);
8319       cselib_finish ();
8320       BITMAP_FREE (scratch_regs);
8321       scratch_regs = NULL;
8322     }
8323
8324   if (vui_vec)
8325     XDELETEVEC (vui_vec);
8326   vui_vec = NULL;
8327   vui_allocated = 0;
8328 }
8329
8330 /* The entry point to variable tracking pass.  */
8331
8332 static inline unsigned int
8333 variable_tracking_main_1 (void)
8334 {
8335   bool success;
8336
8337   if (flag_var_tracking_assignments < 0)
8338     {
8339       delete_debug_insns ();
8340       return 0;
8341     }
8342
8343   if (n_basic_blocks > 500 && n_edges / n_basic_blocks >= 20)
8344     {
8345       vt_debug_insns_local (true);
8346       return 0;
8347     }
8348
8349   mark_dfs_back_edges ();
8350   if (!vt_initialize ())
8351     {
8352       vt_finalize ();
8353       vt_debug_insns_local (true);
8354       return 0;
8355     }
8356
8357   success = vt_find_locations ();
8358
8359   if (!success && flag_var_tracking_assignments > 0)
8360     {
8361       vt_finalize ();
8362
8363       delete_debug_insns ();
8364
8365       /* This is later restored by our caller.  */
8366       flag_var_tracking_assignments = 0;
8367
8368       success = vt_initialize ();
8369       gcc_assert (success);
8370
8371       success = vt_find_locations ();
8372     }
8373
8374   if (!success)
8375     {
8376       vt_finalize ();
8377       vt_debug_insns_local (false);
8378       return 0;
8379     }
8380
8381   if (dump_file && (dump_flags & TDF_DETAILS))
8382     {
8383       dump_dataflow_sets ();
8384       dump_flow_info (dump_file, dump_flags);
8385     }
8386
8387   vt_emit_notes ();
8388
8389   vt_finalize ();
8390   vt_debug_insns_local (false);
8391   return 0;
8392 }
8393
8394 unsigned int
8395 variable_tracking_main (void)
8396 {
8397   unsigned int ret;
8398   int save = flag_var_tracking_assignments;
8399
8400   ret = variable_tracking_main_1 ();
8401
8402   flag_var_tracking_assignments = save;
8403
8404   return ret;
8405 }
8406 \f
8407 static bool
8408 gate_handle_var_tracking (void)
8409 {
8410   return (flag_var_tracking);
8411 }
8412
8413
8414
8415 struct rtl_opt_pass pass_variable_tracking =
8416 {
8417  {
8418   RTL_PASS,
8419   "vartrack",                           /* name */
8420   gate_handle_var_tracking,             /* gate */
8421   variable_tracking_main,               /* execute */
8422   NULL,                                 /* sub */
8423   NULL,                                 /* next */
8424   0,                                    /* static_pass_number */
8425   TV_VAR_TRACKING,                      /* tv_id */
8426   0,                                    /* properties_required */
8427   0,                                    /* properties_provided */
8428   0,                                    /* properties_destroyed */
8429   0,                                    /* todo_flags_start */
8430   TODO_dump_func | TODO_verify_rtl_sharing/* todo_flags_finish */
8431  }
8432 };