OSDN Git Service

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