OSDN Git Service

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