OSDN Git Service

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