OSDN Git Service

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