OSDN Git Service

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