OSDN Git Service

2011-07-07 Tobias Burnus <burnus@net-b.de>
[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_v;
5593   cumulative_args_t args_so_far;
5594
5595   memset (&args_so_far_v, 0, sizeof (args_so_far_v));
5596   args_so_far = pack_cumulative_args (&args_so_far_v);
5597   if (GET_CODE (call) == PARALLEL)
5598     call = XVECEXP (call, 0, 0);
5599   if (GET_CODE (call) == SET)
5600     call = SET_SRC (call);
5601   if (GET_CODE (call) == CALL && MEM_P (XEXP (call, 0)))
5602     {
5603       if (GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
5604         {
5605           rtx symbol = XEXP (XEXP (call, 0), 0);
5606           if (SYMBOL_REF_DECL (symbol))
5607             fndecl = SYMBOL_REF_DECL (symbol);
5608         }
5609       if (fndecl == NULL_TREE)
5610         fndecl = MEM_EXPR (XEXP (call, 0));
5611       if (fndecl
5612           && TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE
5613           && TREE_CODE (TREE_TYPE (fndecl)) != METHOD_TYPE)
5614         fndecl = NULL_TREE;
5615       if (fndecl && TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
5616         type = TREE_TYPE (fndecl);
5617       if (fndecl && TREE_CODE (fndecl) != FUNCTION_DECL)
5618         {
5619           if (TREE_CODE (fndecl) == INDIRECT_REF
5620               && TREE_CODE (TREE_OPERAND (fndecl, 0)) == OBJ_TYPE_REF)
5621             obj_type_ref = TREE_OPERAND (fndecl, 0);
5622           fndecl = NULL_TREE;
5623         }
5624       if (type)
5625         {
5626           for (t = TYPE_ARG_TYPES (type); t && t != void_list_node;
5627                t = TREE_CHAIN (t))
5628             if (TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
5629                 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (t))))
5630               break;
5631           if ((t == NULL || t == void_list_node) && obj_type_ref == NULL_TREE)
5632             type = NULL;
5633           else
5634             {
5635               int nargs ATTRIBUTE_UNUSED = list_length (TYPE_ARG_TYPES (type));
5636               link = CALL_INSN_FUNCTION_USAGE (insn);
5637 #ifndef PCC_STATIC_STRUCT_RETURN
5638               if (aggregate_value_p (TREE_TYPE (type), type)
5639                   && targetm.calls.struct_value_rtx (type, 0) == 0)
5640                 {
5641                   tree struct_addr = build_pointer_type (TREE_TYPE (type));
5642                   enum machine_mode mode = TYPE_MODE (struct_addr);
5643                   rtx reg;
5644                   INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
5645                                         nargs + 1);
5646                   reg = targetm.calls.function_arg (args_so_far, mode,
5647                                                     struct_addr, true);
5648                   targetm.calls.function_arg_advance (args_so_far, mode,
5649                                                       struct_addr, true);
5650                   if (reg == NULL_RTX)
5651                     {
5652                       for (; link; link = XEXP (link, 1))
5653                         if (GET_CODE (XEXP (link, 0)) == USE
5654                             && MEM_P (XEXP (XEXP (link, 0), 0)))
5655                           {
5656                             link = XEXP (link, 1);
5657                             break;
5658                           }
5659                     }
5660                 }
5661               else
5662 #endif
5663                 INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
5664                                       nargs);
5665               if (obj_type_ref && TYPE_ARG_TYPES (type) != void_list_node)
5666                 {
5667                   enum machine_mode mode;
5668                   t = TYPE_ARG_TYPES (type);
5669                   mode = TYPE_MODE (TREE_VALUE (t));
5670                   this_arg = targetm.calls.function_arg (args_so_far, mode,
5671                                                          TREE_VALUE (t), true);
5672                   if (this_arg && !REG_P (this_arg))
5673                     this_arg = NULL_RTX;
5674                   else if (this_arg == NULL_RTX)
5675                     {
5676                       for (; link; link = XEXP (link, 1))
5677                         if (GET_CODE (XEXP (link, 0)) == USE
5678                             && MEM_P (XEXP (XEXP (link, 0), 0)))
5679                           {
5680                             this_arg = XEXP (XEXP (link, 0), 0);
5681                             break;
5682                           }
5683                     }
5684                 }
5685             }
5686         }
5687     }
5688   t = type ? TYPE_ARG_TYPES (type) : NULL_TREE;
5689
5690   for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
5691     if (GET_CODE (XEXP (link, 0)) == USE)
5692       {
5693         rtx item = NULL_RTX;
5694         x = XEXP (XEXP (link, 0), 0);
5695         if (REG_P (x))
5696           {
5697             cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
5698             if (val && cselib_preserved_value_p (val))
5699               item = gen_rtx_CONCAT (GET_MODE (x), x, val->val_rtx);
5700             else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
5701               {
5702                 enum machine_mode mode = GET_MODE (x);
5703
5704                 while ((mode = GET_MODE_WIDER_MODE (mode)) != VOIDmode
5705                        && GET_MODE_BITSIZE (mode) <= BITS_PER_WORD)
5706                   {
5707                     rtx reg = simplify_subreg (mode, x, GET_MODE (x), 0);
5708
5709                     if (reg == NULL_RTX || !REG_P (reg))
5710                       continue;
5711                     val = cselib_lookup (reg, mode, 0, VOIDmode);
5712                     if (val && cselib_preserved_value_p (val))
5713                       {
5714                         item = gen_rtx_CONCAT (GET_MODE (x), x,
5715                                                lowpart_subreg (GET_MODE (x),
5716                                                                val->val_rtx,
5717                                                                mode));
5718                         break;
5719                       }
5720                   }
5721               }
5722           }
5723         else if (MEM_P (x))
5724           {
5725             rtx mem = x;
5726             cselib_val *val;
5727
5728             if (!frame_pointer_needed)
5729               {
5730                 struct adjust_mem_data amd;
5731                 amd.mem_mode = VOIDmode;
5732                 amd.stack_adjust = -VTI (bb)->out.stack_adjust;
5733                 amd.side_effects = NULL_RTX;
5734                 amd.store = true;
5735                 mem = simplify_replace_fn_rtx (mem, NULL_RTX, adjust_mems,
5736                                                &amd);
5737                 gcc_assert (amd.side_effects == NULL_RTX);
5738               }
5739             val = cselib_lookup (mem, GET_MODE (mem), 0, VOIDmode);
5740             if (val && cselib_preserved_value_p (val))
5741               item = gen_rtx_CONCAT (GET_MODE (x), copy_rtx (x), val->val_rtx);
5742           }
5743         if (item)
5744           call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item, call_arguments);
5745         if (t && t != void_list_node)
5746           {
5747             tree argtype = TREE_VALUE (t);
5748             enum machine_mode mode = TYPE_MODE (argtype);
5749             rtx reg;
5750             if (pass_by_reference (&args_so_far_v, mode, argtype, true))
5751               {
5752                 argtype = build_pointer_type (argtype);
5753                 mode = TYPE_MODE (argtype);
5754               }
5755             reg = targetm.calls.function_arg (args_so_far, mode,
5756                                               argtype, true);
5757             if (TREE_CODE (argtype) == REFERENCE_TYPE
5758                 && INTEGRAL_TYPE_P (TREE_TYPE (argtype))
5759                 && reg
5760                 && REG_P (reg)
5761                 && GET_MODE (reg) == mode
5762                 && GET_MODE_CLASS (mode) == MODE_INT
5763                 && REG_P (x)
5764                 && REGNO (x) == REGNO (reg)
5765                 && GET_MODE (x) == mode
5766                 && item)
5767               {
5768                 enum machine_mode indmode
5769                   = TYPE_MODE (TREE_TYPE (argtype));
5770                 rtx mem = gen_rtx_MEM (indmode, x);
5771                 cselib_val *val = cselib_lookup (mem, indmode, 0, VOIDmode);
5772                 if (val && cselib_preserved_value_p (val))
5773                   {
5774                     item = gen_rtx_CONCAT (indmode, mem, val->val_rtx);
5775                     call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
5776                                                         call_arguments);
5777                   }
5778                 else
5779                   {
5780                     struct elt_loc_list *l;
5781                     tree initial;
5782
5783                     /* Try harder, when passing address of a constant
5784                        pool integer it can be easily read back.  */
5785                     item = XEXP (item, 1);
5786                     if (GET_CODE (item) == SUBREG)
5787                       item = SUBREG_REG (item);
5788                     gcc_assert (GET_CODE (item) == VALUE);
5789                     val = CSELIB_VAL_PTR (item);
5790                     for (l = val->locs; l; l = l->next)
5791                       if (GET_CODE (l->loc) == SYMBOL_REF
5792                           && TREE_CONSTANT_POOL_ADDRESS_P (l->loc)
5793                           && SYMBOL_REF_DECL (l->loc)
5794                           && DECL_INITIAL (SYMBOL_REF_DECL (l->loc)))
5795                         {
5796                           initial = DECL_INITIAL (SYMBOL_REF_DECL (l->loc));
5797                           if (host_integerp (initial, 0))
5798                             {
5799                               item = GEN_INT (tree_low_cst (initial, 0));
5800                               item = gen_rtx_CONCAT (indmode, mem, item);
5801                               call_arguments
5802                                 = gen_rtx_EXPR_LIST (VOIDmode, item,
5803                                                      call_arguments);
5804                             }
5805                           break;
5806                         }
5807                   }
5808               }
5809             targetm.calls.function_arg_advance (args_so_far, mode,
5810                                                 argtype, true);
5811             t = TREE_CHAIN (t);
5812           }
5813       }
5814
5815   /* Add debug arguments.  */
5816   if (fndecl
5817       && TREE_CODE (fndecl) == FUNCTION_DECL
5818       && DECL_HAS_DEBUG_ARGS_P (fndecl))
5819     {
5820       VEC(tree, gc) **debug_args = decl_debug_args_lookup (fndecl);
5821       if (debug_args)
5822         {
5823           unsigned int ix;
5824           tree param;
5825           for (ix = 0; VEC_iterate (tree, *debug_args, ix, param); ix += 2)
5826             {
5827               rtx item;
5828               tree dtemp = VEC_index (tree, *debug_args, ix + 1);
5829               enum machine_mode mode = DECL_MODE (dtemp);
5830               item = gen_rtx_DEBUG_PARAMETER_REF (mode, param);
5831               item = gen_rtx_CONCAT (mode, item, DECL_RTL (dtemp));
5832               call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
5833                                                   call_arguments);
5834             }
5835         }
5836     }
5837
5838   /* Reverse call_arguments chain.  */
5839   prev = NULL_RTX;
5840   for (cur = call_arguments; cur; cur = next)
5841     {
5842       next = XEXP (cur, 1);
5843       XEXP (cur, 1) = prev;
5844       prev = cur;
5845     }
5846   call_arguments = prev;
5847
5848   x = PATTERN (insn);
5849   if (GET_CODE (x) == PARALLEL)
5850     x = XVECEXP (x, 0, 0);
5851   if (GET_CODE (x) == SET)
5852     x = SET_SRC (x);
5853   if (GET_CODE (x) == CALL && MEM_P (XEXP (x, 0)))
5854     {
5855       x = XEXP (XEXP (x, 0), 0);
5856       if (GET_CODE (x) == SYMBOL_REF)
5857         /* Don't record anything.  */;
5858       else if (CONSTANT_P (x))
5859         {
5860           x = gen_rtx_CONCAT (GET_MODE (x) == VOIDmode ? Pmode : GET_MODE (x),
5861                               pc_rtx, x);
5862           call_arguments
5863             = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
5864         }
5865       else
5866         {
5867           cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
5868           if (val && cselib_preserved_value_p (val))
5869             {
5870               x = gen_rtx_CONCAT (GET_MODE (x), pc_rtx, val->val_rtx);
5871               call_arguments
5872                 = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
5873             }
5874         }
5875     }
5876   if (this_arg)
5877     {
5878       enum machine_mode mode
5879         = TYPE_MODE (TREE_TYPE (OBJ_TYPE_REF_EXPR (obj_type_ref)));
5880       rtx clobbered = gen_rtx_MEM (mode, this_arg);
5881       HOST_WIDE_INT token
5882         = tree_low_cst (OBJ_TYPE_REF_TOKEN (obj_type_ref), 0);
5883       if (token)
5884         clobbered = plus_constant (clobbered, token * GET_MODE_SIZE (mode));
5885       clobbered = gen_rtx_MEM (mode, clobbered);
5886       x = gen_rtx_CONCAT (mode, gen_rtx_CLOBBER (VOIDmode, pc_rtx), clobbered);
5887       call_arguments
5888         = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
5889     }
5890 }
5891
5892 /* Callback for cselib_record_sets_hook, that records as micro
5893    operations uses and stores in an insn after cselib_record_sets has
5894    analyzed the sets in an insn, but before it modifies the stored
5895    values in the internal tables, unless cselib_record_sets doesn't
5896    call it directly (perhaps because we're not doing cselib in the
5897    first place, in which case sets and n_sets will be 0).  */
5898
5899 static void
5900 add_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
5901 {
5902   basic_block bb = BLOCK_FOR_INSN (insn);
5903   int n1, n2;
5904   struct count_use_info cui;
5905   micro_operation *mos;
5906
5907   cselib_hook_called = true;
5908
5909   cui.insn = insn;
5910   cui.bb = bb;
5911   cui.sets = sets;
5912   cui.n_sets = n_sets;
5913
5914   n1 = VEC_length (micro_operation, VTI (bb)->mos);
5915   cui.store_p = false;
5916   note_uses (&PATTERN (insn), add_uses_1, &cui);
5917   n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
5918   mos = VEC_address (micro_operation, VTI (bb)->mos);
5919
5920   /* Order the MO_USEs to be before MO_USE_NO_VARs and MO_VAL_USE, and
5921      MO_VAL_LOC last.  */
5922   while (n1 < n2)
5923     {
5924       while (n1 < n2 && mos[n1].type == MO_USE)
5925         n1++;
5926       while (n1 < n2 && mos[n2].type != MO_USE)
5927         n2--;
5928       if (n1 < n2)
5929         {
5930           micro_operation sw;
5931
5932           sw = mos[n1];
5933           mos[n1] = mos[n2];
5934           mos[n2] = sw;
5935         }
5936     }
5937
5938   n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
5939   while (n1 < n2)
5940     {
5941       while (n1 < n2 && mos[n1].type != MO_VAL_LOC)
5942         n1++;
5943       while (n1 < n2 && mos[n2].type == MO_VAL_LOC)
5944         n2--;
5945       if (n1 < n2)
5946         {
5947           micro_operation sw;
5948
5949           sw = mos[n1];
5950           mos[n1] = mos[n2];
5951           mos[n2] = sw;
5952         }
5953     }
5954
5955   if (CALL_P (insn))
5956     {
5957       micro_operation mo;
5958
5959       mo.type = MO_CALL;
5960       mo.insn = insn;
5961       mo.u.loc = call_arguments;
5962       call_arguments = NULL_RTX;
5963
5964       if (dump_file && (dump_flags & TDF_DETAILS))
5965         log_op_type (PATTERN (insn), bb, insn, mo.type, dump_file);
5966       VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
5967     }
5968
5969   n1 = VEC_length (micro_operation, VTI (bb)->mos);
5970   /* This will record NEXT_INSN (insn), such that we can
5971      insert notes before it without worrying about any
5972      notes that MO_USEs might emit after the insn.  */
5973   cui.store_p = true;
5974   note_stores (PATTERN (insn), add_stores, &cui);
5975   n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
5976   mos = VEC_address (micro_operation, VTI (bb)->mos);
5977
5978   /* Order the MO_VAL_USEs first (note_stores does nothing
5979      on DEBUG_INSNs, so there are no MO_VAL_LOCs from this
5980      insn), then MO_CLOBBERs, then MO_SET/MO_COPY/MO_VAL_SET.  */
5981   while (n1 < n2)
5982     {
5983       while (n1 < n2 && mos[n1].type == MO_VAL_USE)
5984         n1++;
5985       while (n1 < n2 && mos[n2].type != MO_VAL_USE)
5986         n2--;
5987       if (n1 < n2)
5988         {
5989           micro_operation sw;
5990
5991           sw = mos[n1];
5992           mos[n1] = mos[n2];
5993           mos[n2] = sw;
5994         }
5995     }
5996
5997   n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
5998   while (n1 < n2)
5999     {
6000       while (n1 < n2 && mos[n1].type == MO_CLOBBER)
6001         n1++;
6002       while (n1 < n2 && mos[n2].type != MO_CLOBBER)
6003         n2--;
6004       if (n1 < n2)
6005         {
6006           micro_operation sw;
6007
6008           sw = mos[n1];
6009           mos[n1] = mos[n2];
6010           mos[n2] = sw;
6011         }
6012     }
6013 }
6014
6015 static enum var_init_status
6016 find_src_status (dataflow_set *in, rtx src)
6017 {
6018   tree decl = NULL_TREE;
6019   enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
6020
6021   if (! flag_var_tracking_uninit)
6022     status = VAR_INIT_STATUS_INITIALIZED;
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     status = get_init_value (in, src, dv_from_decl (decl));
6031
6032   return status;
6033 }
6034
6035 /* SRC is the source of an assignment.  Use SET to try to find what
6036    was ultimately assigned to SRC.  Return that value if known,
6037    otherwise return SRC itself.  */
6038
6039 static rtx
6040 find_src_set_src (dataflow_set *set, rtx src)
6041 {
6042   tree decl = NULL_TREE;   /* The variable being copied around.          */
6043   rtx set_src = NULL_RTX;  /* The value for "decl" stored in "src".      */
6044   variable var;
6045   location_chain nextp;
6046   int i;
6047   bool found;
6048
6049   if (src && REG_P (src))
6050     decl = var_debug_decl (REG_EXPR (src));
6051   else if (src && MEM_P (src))
6052     decl = var_debug_decl (MEM_EXPR (src));
6053
6054   if (src && decl)
6055     {
6056       decl_or_value dv = dv_from_decl (decl);
6057
6058       var = shared_hash_find (set->vars, dv);
6059       if (var)
6060         {
6061           found = false;
6062           for (i = 0; i < var->n_var_parts && !found; i++)
6063             for (nextp = var->var_part[i].loc_chain; nextp && !found;
6064                  nextp = nextp->next)
6065               if (rtx_equal_p (nextp->loc, src))
6066                 {
6067                   set_src = nextp->set_src;
6068                   found = true;
6069                 }
6070
6071         }
6072     }
6073
6074   return set_src;
6075 }
6076
6077 /* Compute the changes of variable locations in the basic block BB.  */
6078
6079 static bool
6080 compute_bb_dataflow (basic_block bb)
6081 {
6082   unsigned int i;
6083   micro_operation *mo;
6084   bool changed;
6085   dataflow_set old_out;
6086   dataflow_set *in = &VTI (bb)->in;
6087   dataflow_set *out = &VTI (bb)->out;
6088
6089   dataflow_set_init (&old_out);
6090   dataflow_set_copy (&old_out, out);
6091   dataflow_set_copy (out, in);
6092
6093   FOR_EACH_VEC_ELT (micro_operation, VTI (bb)->mos, i, mo)
6094     {
6095       rtx insn = mo->insn;
6096
6097       switch (mo->type)
6098         {
6099           case MO_CALL:
6100             dataflow_set_clear_at_call (out);
6101             break;
6102
6103           case MO_USE:
6104             {
6105               rtx loc = mo->u.loc;
6106
6107               if (REG_P (loc))
6108                 var_reg_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6109               else if (MEM_P (loc))
6110                 var_mem_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6111             }
6112             break;
6113
6114           case MO_VAL_LOC:
6115             {
6116               rtx loc = mo->u.loc;
6117               rtx val, vloc;
6118               tree var;
6119
6120               if (GET_CODE (loc) == CONCAT)
6121                 {
6122                   val = XEXP (loc, 0);
6123                   vloc = XEXP (loc, 1);
6124                 }
6125               else
6126                 {
6127                   val = NULL_RTX;
6128                   vloc = loc;
6129                 }
6130
6131               var = PAT_VAR_LOCATION_DECL (vloc);
6132
6133               clobber_variable_part (out, NULL_RTX,
6134                                      dv_from_decl (var), 0, NULL_RTX);
6135               if (val)
6136                 {
6137                   if (VAL_NEEDS_RESOLUTION (loc))
6138                     val_resolve (out, val, PAT_VAR_LOCATION_LOC (vloc), insn);
6139                   set_variable_part (out, val, dv_from_decl (var), 0,
6140                                      VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
6141                                      INSERT);
6142                 }
6143               else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
6144                 set_variable_part (out, PAT_VAR_LOCATION_LOC (vloc),
6145                                    dv_from_decl (var), 0,
6146                                    VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
6147                                    INSERT);
6148             }
6149             break;
6150
6151           case MO_VAL_USE:
6152             {
6153               rtx loc = mo->u.loc;
6154               rtx val, vloc, uloc;
6155
6156               vloc = uloc = XEXP (loc, 1);
6157               val = XEXP (loc, 0);
6158
6159               if (GET_CODE (val) == CONCAT)
6160                 {
6161                   uloc = XEXP (val, 1);
6162                   val = XEXP (val, 0);
6163                 }
6164
6165               if (VAL_NEEDS_RESOLUTION (loc))
6166                 val_resolve (out, val, vloc, insn);
6167               else
6168                 val_store (out, val, uloc, insn, false);
6169
6170               if (VAL_HOLDS_TRACK_EXPR (loc))
6171                 {
6172                   if (GET_CODE (uloc) == REG)
6173                     var_reg_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6174                                  NULL);
6175                   else if (GET_CODE (uloc) == MEM)
6176                     var_mem_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6177                                  NULL);
6178                 }
6179             }
6180             break;
6181
6182           case MO_VAL_SET:
6183             {
6184               rtx loc = mo->u.loc;
6185               rtx val, vloc, uloc, reverse = NULL_RTX;
6186
6187               vloc = loc;
6188               if (VAL_EXPR_HAS_REVERSE (loc))
6189                 {
6190                   reverse = XEXP (loc, 1);
6191                   vloc = XEXP (loc, 0);
6192                 }
6193               uloc = XEXP (vloc, 1);
6194               val = XEXP (vloc, 0);
6195               vloc = uloc;
6196
6197               if (GET_CODE (val) == CONCAT)
6198                 {
6199                   vloc = XEXP (val, 1);
6200                   val = XEXP (val, 0);
6201                 }
6202
6203               if (GET_CODE (vloc) == SET)
6204                 {
6205                   rtx vsrc = SET_SRC (vloc);
6206
6207                   gcc_assert (val != vsrc);
6208                   gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
6209
6210                   vloc = SET_DEST (vloc);
6211
6212                   if (VAL_NEEDS_RESOLUTION (loc))
6213                     val_resolve (out, val, vsrc, insn);
6214                 }
6215               else if (VAL_NEEDS_RESOLUTION (loc))
6216                 {
6217                   gcc_assert (GET_CODE (uloc) == SET
6218                               && GET_CODE (SET_SRC (uloc)) == REG);
6219                   val_resolve (out, val, SET_SRC (uloc), insn);
6220                 }
6221
6222               if (VAL_HOLDS_TRACK_EXPR (loc))
6223                 {
6224                   if (VAL_EXPR_IS_CLOBBERED (loc))
6225                     {
6226                       if (REG_P (uloc))
6227                         var_reg_delete (out, uloc, true);
6228                       else if (MEM_P (uloc))
6229                         var_mem_delete (out, uloc, true);
6230                     }
6231                   else
6232                     {
6233                       bool copied_p = VAL_EXPR_IS_COPIED (loc);
6234                       rtx set_src = NULL;
6235                       enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
6236
6237                       if (GET_CODE (uloc) == SET)
6238                         {
6239                           set_src = SET_SRC (uloc);
6240                           uloc = SET_DEST (uloc);
6241                         }
6242
6243                       if (copied_p)
6244                         {
6245                           if (flag_var_tracking_uninit)
6246                             {
6247                               status = find_src_status (in, set_src);
6248
6249                               if (status == VAR_INIT_STATUS_UNKNOWN)
6250                                 status = find_src_status (out, set_src);
6251                             }
6252
6253                           set_src = find_src_set_src (in, set_src);
6254                         }
6255
6256                       if (REG_P (uloc))
6257                         var_reg_delete_and_set (out, uloc, !copied_p,
6258                                                 status, set_src);
6259                       else if (MEM_P (uloc))
6260                         var_mem_delete_and_set (out, uloc, !copied_p,
6261                                                 status, set_src);
6262                     }
6263                 }
6264               else if (REG_P (uloc))
6265                 var_regno_delete (out, REGNO (uloc));
6266
6267               val_store (out, val, vloc, insn, true);
6268
6269               if (reverse)
6270                 val_store (out, XEXP (reverse, 0), XEXP (reverse, 1),
6271                            insn, false);
6272             }
6273             break;
6274
6275           case MO_SET:
6276             {
6277               rtx loc = mo->u.loc;
6278               rtx set_src = NULL;
6279
6280               if (GET_CODE (loc) == SET)
6281                 {
6282                   set_src = SET_SRC (loc);
6283                   loc = SET_DEST (loc);
6284                 }
6285
6286               if (REG_P (loc))
6287                 var_reg_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
6288                                         set_src);
6289               else if (MEM_P (loc))
6290                 var_mem_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
6291                                         set_src);
6292             }
6293             break;
6294
6295           case MO_COPY:
6296             {
6297               rtx loc = mo->u.loc;
6298               enum var_init_status src_status;
6299               rtx set_src = NULL;
6300
6301               if (GET_CODE (loc) == SET)
6302                 {
6303                   set_src = SET_SRC (loc);
6304                   loc = SET_DEST (loc);
6305                 }
6306
6307               if (! flag_var_tracking_uninit)
6308                 src_status = VAR_INIT_STATUS_INITIALIZED;
6309               else
6310                 {
6311                   src_status = find_src_status (in, set_src);
6312
6313                   if (src_status == VAR_INIT_STATUS_UNKNOWN)
6314                     src_status = find_src_status (out, set_src);
6315                 }
6316
6317               set_src = find_src_set_src (in, set_src);
6318
6319               if (REG_P (loc))
6320                 var_reg_delete_and_set (out, loc, false, src_status, set_src);
6321               else if (MEM_P (loc))
6322                 var_mem_delete_and_set (out, loc, false, src_status, set_src);
6323             }
6324             break;
6325
6326           case MO_USE_NO_VAR:
6327             {
6328               rtx loc = mo->u.loc;
6329
6330               if (REG_P (loc))
6331                 var_reg_delete (out, loc, false);
6332               else if (MEM_P (loc))
6333                 var_mem_delete (out, loc, false);
6334             }
6335             break;
6336
6337           case MO_CLOBBER:
6338             {
6339               rtx loc = mo->u.loc;
6340
6341               if (REG_P (loc))
6342                 var_reg_delete (out, loc, true);
6343               else if (MEM_P (loc))
6344                 var_mem_delete (out, loc, true);
6345             }
6346             break;
6347
6348           case MO_ADJUST:
6349             out->stack_adjust += mo->u.adjust;
6350             break;
6351         }
6352     }
6353
6354   if (MAY_HAVE_DEBUG_INSNS)
6355     {
6356       dataflow_set_equiv_regs (out);
6357       htab_traverse (shared_hash_htab (out->vars), canonicalize_values_mark,
6358                      out);
6359       htab_traverse (shared_hash_htab (out->vars), canonicalize_values_star,
6360                      out);
6361 #if ENABLE_CHECKING
6362       htab_traverse (shared_hash_htab (out->vars),
6363                      canonicalize_loc_order_check, out);
6364 #endif
6365     }
6366   changed = dataflow_set_different (&old_out, out);
6367   dataflow_set_destroy (&old_out);
6368   return changed;
6369 }
6370
6371 /* Find the locations of variables in the whole function.  */
6372
6373 static bool
6374 vt_find_locations (void)
6375 {
6376   fibheap_t worklist, pending, fibheap_swap;
6377   sbitmap visited, in_worklist, in_pending, sbitmap_swap;
6378   basic_block bb;
6379   edge e;
6380   int *bb_order;
6381   int *rc_order;
6382   int i;
6383   int htabsz = 0;
6384   int htabmax = PARAM_VALUE (PARAM_MAX_VARTRACK_SIZE);
6385   bool success = true;
6386
6387   timevar_push (TV_VAR_TRACKING_DATAFLOW);
6388   /* Compute reverse completion order of depth first search of the CFG
6389      so that the data-flow runs faster.  */
6390   rc_order = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
6391   bb_order = XNEWVEC (int, last_basic_block);
6392   pre_and_rev_post_order_compute (NULL, rc_order, false);
6393   for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
6394     bb_order[rc_order[i]] = i;
6395   free (rc_order);
6396
6397   worklist = fibheap_new ();
6398   pending = fibheap_new ();
6399   visited = sbitmap_alloc (last_basic_block);
6400   in_worklist = sbitmap_alloc (last_basic_block);
6401   in_pending = sbitmap_alloc (last_basic_block);
6402   sbitmap_zero (in_worklist);
6403
6404   FOR_EACH_BB (bb)
6405     fibheap_insert (pending, bb_order[bb->index], bb);
6406   sbitmap_ones (in_pending);
6407
6408   while (success && !fibheap_empty (pending))
6409     {
6410       fibheap_swap = pending;
6411       pending = worklist;
6412       worklist = fibheap_swap;
6413       sbitmap_swap = in_pending;
6414       in_pending = in_worklist;
6415       in_worklist = sbitmap_swap;
6416
6417       sbitmap_zero (visited);
6418
6419       while (!fibheap_empty (worklist))
6420         {
6421           bb = (basic_block) fibheap_extract_min (worklist);
6422           RESET_BIT (in_worklist, bb->index);
6423           gcc_assert (!TEST_BIT (visited, bb->index));
6424           if (!TEST_BIT (visited, bb->index))
6425             {
6426               bool changed;
6427               edge_iterator ei;
6428               int oldinsz, oldoutsz;
6429
6430               SET_BIT (visited, bb->index);
6431
6432               if (VTI (bb)->in.vars)
6433                 {
6434                   htabsz
6435                     -= (htab_size (shared_hash_htab (VTI (bb)->in.vars))
6436                         + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
6437                   oldinsz
6438                     = htab_elements (shared_hash_htab (VTI (bb)->in.vars));
6439                   oldoutsz
6440                     = htab_elements (shared_hash_htab (VTI (bb)->out.vars));
6441                 }
6442               else
6443                 oldinsz = oldoutsz = 0;
6444
6445               if (MAY_HAVE_DEBUG_INSNS)
6446                 {
6447                   dataflow_set *in = &VTI (bb)->in, *first_out = NULL;
6448                   bool first = true, adjust = false;
6449
6450                   /* Calculate the IN set as the intersection of
6451                      predecessor OUT sets.  */
6452
6453                   dataflow_set_clear (in);
6454                   dst_can_be_shared = true;
6455
6456                   FOR_EACH_EDGE (e, ei, bb->preds)
6457                     if (!VTI (e->src)->flooded)
6458                       gcc_assert (bb_order[bb->index]
6459                                   <= bb_order[e->src->index]);
6460                     else if (first)
6461                       {
6462                         dataflow_set_copy (in, &VTI (e->src)->out);
6463                         first_out = &VTI (e->src)->out;
6464                         first = false;
6465                       }
6466                     else
6467                       {
6468                         dataflow_set_merge (in, &VTI (e->src)->out);
6469                         adjust = true;
6470                       }
6471
6472                   if (adjust)
6473                     {
6474                       dataflow_post_merge_adjust (in, &VTI (bb)->permp);
6475 #if ENABLE_CHECKING
6476                       /* Merge and merge_adjust should keep entries in
6477                          canonical order.  */
6478                       htab_traverse (shared_hash_htab (in->vars),
6479                                      canonicalize_loc_order_check,
6480                                      in);
6481 #endif
6482                       if (dst_can_be_shared)
6483                         {
6484                           shared_hash_destroy (in->vars);
6485                           in->vars = shared_hash_copy (first_out->vars);
6486                         }
6487                     }
6488
6489                   VTI (bb)->flooded = true;
6490                 }
6491               else
6492                 {
6493                   /* Calculate the IN set as union of predecessor OUT sets.  */
6494                   dataflow_set_clear (&VTI (bb)->in);
6495                   FOR_EACH_EDGE (e, ei, bb->preds)
6496                     dataflow_set_union (&VTI (bb)->in, &VTI (e->src)->out);
6497                 }
6498
6499               changed = compute_bb_dataflow (bb);
6500               htabsz += (htab_size (shared_hash_htab (VTI (bb)->in.vars))
6501                          + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
6502
6503               if (htabmax && htabsz > htabmax)
6504                 {
6505                   if (MAY_HAVE_DEBUG_INSNS)
6506                     inform (DECL_SOURCE_LOCATION (cfun->decl),
6507                             "variable tracking size limit exceeded with "
6508                             "-fvar-tracking-assignments, retrying without");
6509                   else
6510                     inform (DECL_SOURCE_LOCATION (cfun->decl),
6511                             "variable tracking size limit exceeded");
6512                   success = false;
6513                   break;
6514                 }
6515
6516               if (changed)
6517                 {
6518                   FOR_EACH_EDGE (e, ei, bb->succs)
6519                     {
6520                       if (e->dest == EXIT_BLOCK_PTR)
6521                         continue;
6522
6523                       if (TEST_BIT (visited, e->dest->index))
6524                         {
6525                           if (!TEST_BIT (in_pending, e->dest->index))
6526                             {
6527                               /* Send E->DEST to next round.  */
6528                               SET_BIT (in_pending, e->dest->index);
6529                               fibheap_insert (pending,
6530                                               bb_order[e->dest->index],
6531                                               e->dest);
6532                             }
6533                         }
6534                       else if (!TEST_BIT (in_worklist, e->dest->index))
6535                         {
6536                           /* Add E->DEST to current round.  */
6537                           SET_BIT (in_worklist, e->dest->index);
6538                           fibheap_insert (worklist, bb_order[e->dest->index],
6539                                           e->dest);
6540                         }
6541                     }
6542                 }
6543
6544               if (dump_file)
6545                 fprintf (dump_file,
6546                          "BB %i: in %i (was %i), out %i (was %i), rem %i + %i, tsz %i\n",
6547                          bb->index,
6548                          (int)htab_elements (shared_hash_htab (VTI (bb)->in.vars)),
6549                          oldinsz,
6550                          (int)htab_elements (shared_hash_htab (VTI (bb)->out.vars)),
6551                          oldoutsz,
6552                          (int)worklist->nodes, (int)pending->nodes, htabsz);
6553
6554               if (dump_file && (dump_flags & TDF_DETAILS))
6555                 {
6556                   fprintf (dump_file, "BB %i IN:\n", bb->index);
6557                   dump_dataflow_set (&VTI (bb)->in);
6558                   fprintf (dump_file, "BB %i OUT:\n", bb->index);
6559                   dump_dataflow_set (&VTI (bb)->out);
6560                 }
6561             }
6562         }
6563     }
6564
6565   if (success && MAY_HAVE_DEBUG_INSNS)
6566     FOR_EACH_BB (bb)
6567       gcc_assert (VTI (bb)->flooded);
6568
6569   free (bb_order);
6570   fibheap_delete (worklist);
6571   fibheap_delete (pending);
6572   sbitmap_free (visited);
6573   sbitmap_free (in_worklist);
6574   sbitmap_free (in_pending);
6575
6576   timevar_pop (TV_VAR_TRACKING_DATAFLOW);
6577   return success;
6578 }
6579
6580 /* Print the content of the LIST to dump file.  */
6581
6582 static void
6583 dump_attrs_list (attrs list)
6584 {
6585   for (; list; list = list->next)
6586     {
6587       if (dv_is_decl_p (list->dv))
6588         print_mem_expr (dump_file, dv_as_decl (list->dv));
6589       else
6590         print_rtl_single (dump_file, dv_as_value (list->dv));
6591       fprintf (dump_file, "+" HOST_WIDE_INT_PRINT_DEC, list->offset);
6592     }
6593   fprintf (dump_file, "\n");
6594 }
6595
6596 /* Print the information about variable *SLOT to dump file.  */
6597
6598 static int
6599 dump_var_slot (void **slot, void *data ATTRIBUTE_UNUSED)
6600 {
6601   variable var = (variable) *slot;
6602
6603   dump_var (var);
6604
6605   /* Continue traversing the hash table.  */
6606   return 1;
6607 }
6608
6609 /* Print the information about variable VAR to dump file.  */
6610
6611 static void
6612 dump_var (variable var)
6613 {
6614   int i;
6615   location_chain node;
6616
6617   if (dv_is_decl_p (var->dv))
6618     {
6619       const_tree decl = dv_as_decl (var->dv);
6620
6621       if (DECL_NAME (decl))
6622         {
6623           fprintf (dump_file, "  name: %s",
6624                    IDENTIFIER_POINTER (DECL_NAME (decl)));
6625           if (dump_flags & TDF_UID)
6626             fprintf (dump_file, "D.%u", DECL_UID (decl));
6627         }
6628       else if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
6629         fprintf (dump_file, "  name: D#%u", DEBUG_TEMP_UID (decl));
6630       else
6631         fprintf (dump_file, "  name: D.%u", DECL_UID (decl));
6632       fprintf (dump_file, "\n");
6633     }
6634   else
6635     {
6636       fputc (' ', dump_file);
6637       print_rtl_single (dump_file, dv_as_value (var->dv));
6638     }
6639
6640   for (i = 0; i < var->n_var_parts; i++)
6641     {
6642       fprintf (dump_file, "    offset %ld\n",
6643                (long) var->var_part[i].offset);
6644       for (node = var->var_part[i].loc_chain; node; node = node->next)
6645         {
6646           fprintf (dump_file, "      ");
6647           if (node->init == VAR_INIT_STATUS_UNINITIALIZED)
6648             fprintf (dump_file, "[uninit]");
6649           print_rtl_single (dump_file, node->loc);
6650         }
6651     }
6652 }
6653
6654 /* Print the information about variables from hash table VARS to dump file.  */
6655
6656 static void
6657 dump_vars (htab_t vars)
6658 {
6659   if (htab_elements (vars) > 0)
6660     {
6661       fprintf (dump_file, "Variables:\n");
6662       htab_traverse (vars, dump_var_slot, NULL);
6663     }
6664 }
6665
6666 /* Print the dataflow set SET to dump file.  */
6667
6668 static void
6669 dump_dataflow_set (dataflow_set *set)
6670 {
6671   int i;
6672
6673   fprintf (dump_file, "Stack adjustment: " HOST_WIDE_INT_PRINT_DEC "\n",
6674            set->stack_adjust);
6675   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
6676     {
6677       if (set->regs[i])
6678         {
6679           fprintf (dump_file, "Reg %d:", i);
6680           dump_attrs_list (set->regs[i]);
6681         }
6682     }
6683   dump_vars (shared_hash_htab (set->vars));
6684   fprintf (dump_file, "\n");
6685 }
6686
6687 /* Print the IN and OUT sets for each basic block to dump file.  */
6688
6689 static void
6690 dump_dataflow_sets (void)
6691 {
6692   basic_block bb;
6693
6694   FOR_EACH_BB (bb)
6695     {
6696       fprintf (dump_file, "\nBasic block %d:\n", bb->index);
6697       fprintf (dump_file, "IN:\n");
6698       dump_dataflow_set (&VTI (bb)->in);
6699       fprintf (dump_file, "OUT:\n");
6700       dump_dataflow_set (&VTI (bb)->out);
6701     }
6702 }
6703
6704 /* Add variable VAR to the hash table of changed variables and
6705    if it has no locations delete it from SET's hash table.  */
6706
6707 static void
6708 variable_was_changed (variable var, dataflow_set *set)
6709 {
6710   hashval_t hash = dv_htab_hash (var->dv);
6711
6712   if (emit_notes)
6713     {
6714       void **slot;
6715       bool old_cur_loc_changed = false;
6716
6717       /* Remember this decl or VALUE has been added to changed_variables.  */
6718       set_dv_changed (var->dv, true);
6719
6720       slot = htab_find_slot_with_hash (changed_variables,
6721                                        var->dv,
6722                                        hash, INSERT);
6723
6724       if (*slot)
6725         {
6726           variable old_var = (variable) *slot;
6727           gcc_assert (old_var->in_changed_variables);
6728           old_var->in_changed_variables = false;
6729           old_cur_loc_changed = old_var->cur_loc_changed;
6730           variable_htab_free (*slot);
6731         }
6732       if (set && var->n_var_parts == 0)
6733         {
6734           variable empty_var;
6735
6736           empty_var = (variable) pool_alloc (dv_pool (var->dv));
6737           empty_var->dv = var->dv;
6738           empty_var->refcount = 1;
6739           empty_var->n_var_parts = 0;
6740           empty_var->cur_loc_changed = true;
6741           empty_var->in_changed_variables = true;
6742           *slot = empty_var;
6743           goto drop_var;
6744         }
6745       else
6746         {
6747           var->refcount++;
6748           var->in_changed_variables = true;
6749           /* If within processing one uop a variable is deleted
6750              and then readded, we need to assume it has changed.  */
6751           if (old_cur_loc_changed)
6752             var->cur_loc_changed = true;
6753           *slot = var;
6754         }
6755     }
6756   else
6757     {
6758       gcc_assert (set);
6759       if (var->n_var_parts == 0)
6760         {
6761           void **slot;
6762
6763         drop_var:
6764           slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
6765           if (slot)
6766             {
6767               if (shared_hash_shared (set->vars))
6768                 slot = shared_hash_find_slot_unshare (&set->vars, var->dv,
6769                                                       NO_INSERT);
6770               htab_clear_slot (shared_hash_htab (set->vars), slot);
6771             }
6772         }
6773     }
6774 }
6775
6776 /* Look for the index in VAR->var_part corresponding to OFFSET.
6777    Return -1 if not found.  If INSERTION_POINT is non-NULL, the
6778    referenced int will be set to the index that the part has or should
6779    have, if it should be inserted.  */
6780
6781 static inline int
6782 find_variable_location_part (variable var, HOST_WIDE_INT offset,
6783                              int *insertion_point)
6784 {
6785   int pos, low, high;
6786
6787   /* Find the location part.  */
6788   low = 0;
6789   high = var->n_var_parts;
6790   while (low != high)
6791     {
6792       pos = (low + high) / 2;
6793       if (var->var_part[pos].offset < offset)
6794         low = pos + 1;
6795       else
6796         high = pos;
6797     }
6798   pos = low;
6799
6800   if (insertion_point)
6801     *insertion_point = pos;
6802
6803   if (pos < var->n_var_parts && var->var_part[pos].offset == offset)
6804     return pos;
6805
6806   return -1;
6807 }
6808
6809 static void **
6810 set_slot_part (dataflow_set *set, rtx loc, void **slot,
6811                decl_or_value dv, HOST_WIDE_INT offset,
6812                enum var_init_status initialized, rtx set_src)
6813 {
6814   int pos;
6815   location_chain node, next;
6816   location_chain *nextp;
6817   variable var;
6818   bool onepart = dv_onepart_p (dv);
6819
6820   gcc_assert (offset == 0 || !onepart);
6821   gcc_assert (loc != dv_as_opaque (dv));
6822
6823   var = (variable) *slot;
6824
6825   if (! flag_var_tracking_uninit)
6826     initialized = VAR_INIT_STATUS_INITIALIZED;
6827
6828   if (!var)
6829     {
6830       /* Create new variable information.  */
6831       var = (variable) pool_alloc (dv_pool (dv));
6832       var->dv = dv;
6833       var->refcount = 1;
6834       var->n_var_parts = 1;
6835       var->cur_loc_changed = false;
6836       var->in_changed_variables = false;
6837       var->var_part[0].offset = offset;
6838       var->var_part[0].loc_chain = NULL;
6839       var->var_part[0].cur_loc = NULL;
6840       *slot = var;
6841       pos = 0;
6842       nextp = &var->var_part[0].loc_chain;
6843     }
6844   else if (onepart)
6845     {
6846       int r = -1, c = 0;
6847
6848       gcc_assert (dv_as_opaque (var->dv) == dv_as_opaque (dv));
6849
6850       pos = 0;
6851
6852       if (GET_CODE (loc) == VALUE)
6853         {
6854           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
6855                nextp = &node->next)
6856             if (GET_CODE (node->loc) == VALUE)
6857               {
6858                 if (node->loc == loc)
6859                   {
6860                     r = 0;
6861                     break;
6862                   }
6863                 if (canon_value_cmp (node->loc, loc))
6864                   c++;
6865                 else
6866                   {
6867                     r = 1;
6868                     break;
6869                   }
6870               }
6871             else if (REG_P (node->loc) || MEM_P (node->loc))
6872               c++;
6873             else
6874               {
6875                 r = 1;
6876                 break;
6877               }
6878         }
6879       else if (REG_P (loc))
6880         {
6881           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
6882                nextp = &node->next)
6883             if (REG_P (node->loc))
6884               {
6885                 if (REGNO (node->loc) < REGNO (loc))
6886                   c++;
6887                 else
6888                   {
6889                     if (REGNO (node->loc) == REGNO (loc))
6890                       r = 0;
6891                     else
6892                       r = 1;
6893                     break;
6894                   }
6895               }
6896             else
6897               {
6898                 r = 1;
6899                 break;
6900               }
6901         }
6902       else if (MEM_P (loc))
6903         {
6904           for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
6905                nextp = &node->next)
6906             if (REG_P (node->loc))
6907               c++;
6908             else if (MEM_P (node->loc))
6909               {
6910                 if ((r = loc_cmp (XEXP (node->loc, 0), XEXP (loc, 0))) >= 0)
6911                   break;
6912                 else
6913                   c++;
6914               }
6915             else
6916               {
6917                 r = 1;
6918                 break;
6919               }
6920         }
6921       else
6922         for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
6923              nextp = &node->next)
6924           if ((r = loc_cmp (node->loc, loc)) >= 0)
6925             break;
6926           else
6927             c++;
6928
6929       if (r == 0)
6930         return slot;
6931
6932       if (shared_var_p (var, set->vars))
6933         {
6934           slot = unshare_variable (set, slot, var, initialized);
6935           var = (variable)*slot;
6936           for (nextp = &var->var_part[0].loc_chain; c;
6937                nextp = &(*nextp)->next)
6938             c--;
6939           gcc_assert ((!node && !*nextp) || node->loc == (*nextp)->loc);
6940         }
6941     }
6942   else
6943     {
6944       int inspos = 0;
6945
6946       gcc_assert (dv_as_decl (var->dv) == dv_as_decl (dv));
6947
6948       pos = find_variable_location_part (var, offset, &inspos);
6949
6950       if (pos >= 0)
6951         {
6952           node = var->var_part[pos].loc_chain;
6953
6954           if (node
6955               && ((REG_P (node->loc) && REG_P (loc)
6956                    && REGNO (node->loc) == REGNO (loc))
6957                   || rtx_equal_p (node->loc, loc)))
6958             {
6959               /* LOC is in the beginning of the chain so we have nothing
6960                  to do.  */
6961               if (node->init < initialized)
6962                 node->init = initialized;
6963               if (set_src != NULL)
6964                 node->set_src = set_src;
6965
6966               return slot;
6967             }
6968           else
6969             {
6970               /* We have to make a copy of a shared variable.  */
6971               if (shared_var_p (var, set->vars))
6972                 {
6973                   slot = unshare_variable (set, slot, var, initialized);
6974                   var = (variable)*slot;
6975                 }
6976             }
6977         }
6978       else
6979         {
6980           /* We have not found the location part, new one will be created.  */
6981
6982           /* We have to make a copy of the shared variable.  */
6983           if (shared_var_p (var, set->vars))
6984             {
6985               slot = unshare_variable (set, slot, var, initialized);
6986               var = (variable)*slot;
6987             }
6988
6989           /* We track only variables whose size is <= MAX_VAR_PARTS bytes
6990              thus there are at most MAX_VAR_PARTS different offsets.  */
6991           gcc_assert (var->n_var_parts < MAX_VAR_PARTS
6992                       && (!var->n_var_parts || !dv_onepart_p (var->dv)));
6993
6994           /* We have to move the elements of array starting at index
6995              inspos to the next position.  */
6996           for (pos = var->n_var_parts; pos > inspos; pos--)
6997             var->var_part[pos] = var->var_part[pos - 1];
6998
6999           var->n_var_parts++;
7000           var->var_part[pos].offset = offset;
7001           var->var_part[pos].loc_chain = NULL;
7002           var->var_part[pos].cur_loc = NULL;
7003         }
7004
7005       /* Delete the location from the list.  */
7006       nextp = &var->var_part[pos].loc_chain;
7007       for (node = var->var_part[pos].loc_chain; node; node = next)
7008         {
7009           next = node->next;
7010           if ((REG_P (node->loc) && REG_P (loc)
7011                && REGNO (node->loc) == REGNO (loc))
7012               || rtx_equal_p (node->loc, loc))
7013             {
7014               /* Save these values, to assign to the new node, before
7015                  deleting this one.  */
7016               if (node->init > initialized)
7017                 initialized = node->init;
7018               if (node->set_src != NULL && set_src == NULL)
7019                 set_src = node->set_src;
7020               if (var->var_part[pos].cur_loc == node->loc)
7021                 {
7022                   var->var_part[pos].cur_loc = NULL;
7023                   var->cur_loc_changed = true;
7024                 }
7025               pool_free (loc_chain_pool, node);
7026               *nextp = next;
7027               break;
7028             }
7029           else
7030             nextp = &node->next;
7031         }
7032
7033       nextp = &var->var_part[pos].loc_chain;
7034     }
7035
7036   /* Add the location to the beginning.  */
7037   node = (location_chain) pool_alloc (loc_chain_pool);
7038   node->loc = loc;
7039   node->init = initialized;
7040   node->set_src = set_src;
7041   node->next = *nextp;
7042   *nextp = node;
7043
7044   if (onepart && emit_notes)
7045     add_value_chains (var->dv, loc);
7046
7047   /* If no location was emitted do so.  */
7048   if (var->var_part[pos].cur_loc == NULL)
7049     variable_was_changed (var, set);
7050
7051   return slot;
7052 }
7053
7054 /* Set the part of variable's location in the dataflow set SET.  The
7055    variable part is specified by variable's declaration in DV and
7056    offset OFFSET and the part's location by LOC.  IOPT should be
7057    NO_INSERT if the variable is known to be in SET already and the
7058    variable hash table must not be resized, and INSERT otherwise.  */
7059
7060 static void
7061 set_variable_part (dataflow_set *set, rtx loc,
7062                    decl_or_value dv, HOST_WIDE_INT offset,
7063                    enum var_init_status initialized, rtx set_src,
7064                    enum insert_option iopt)
7065 {
7066   void **slot;
7067
7068   if (iopt == NO_INSERT)
7069     slot = shared_hash_find_slot_noinsert (set->vars, dv);
7070   else
7071     {
7072       slot = shared_hash_find_slot (set->vars, dv);
7073       if (!slot)
7074         slot = shared_hash_find_slot_unshare (&set->vars, dv, iopt);
7075     }
7076   set_slot_part (set, loc, slot, dv, offset, initialized, set_src);
7077 }
7078
7079 /* Remove all recorded register locations for the given variable part
7080    from dataflow set SET, except for those that are identical to loc.
7081    The variable part is specified by variable's declaration or value
7082    DV and offset OFFSET.  */
7083
7084 static void **
7085 clobber_slot_part (dataflow_set *set, rtx loc, void **slot,
7086                    HOST_WIDE_INT offset, rtx set_src)
7087 {
7088   variable var = (variable) *slot;
7089   int pos = find_variable_location_part (var, offset, NULL);
7090
7091   if (pos >= 0)
7092     {
7093       location_chain node, next;
7094
7095       /* Remove the register locations from the dataflow set.  */
7096       next = var->var_part[pos].loc_chain;
7097       for (node = next; node; node = next)
7098         {
7099           next = node->next;
7100           if (node->loc != loc
7101               && (!flag_var_tracking_uninit
7102                   || !set_src
7103                   || MEM_P (set_src)
7104                   || !rtx_equal_p (set_src, node->set_src)))
7105             {
7106               if (REG_P (node->loc))
7107                 {
7108                   attrs anode, anext;
7109                   attrs *anextp;
7110
7111                   /* Remove the variable part from the register's
7112                      list, but preserve any other variable parts
7113                      that might be regarded as live in that same
7114                      register.  */
7115                   anextp = &set->regs[REGNO (node->loc)];
7116                   for (anode = *anextp; anode; anode = anext)
7117                     {
7118                       anext = anode->next;
7119                       if (dv_as_opaque (anode->dv) == dv_as_opaque (var->dv)
7120                           && anode->offset == offset)
7121                         {
7122                           pool_free (attrs_pool, anode);
7123                           *anextp = anext;
7124                         }
7125                       else
7126                         anextp = &anode->next;
7127                     }
7128                 }
7129
7130               slot = delete_slot_part (set, node->loc, slot, offset);
7131             }
7132         }
7133     }
7134
7135   return slot;
7136 }
7137
7138 /* Remove all recorded register locations for the given variable part
7139    from dataflow set SET, except for those that are identical to loc.
7140    The variable part is specified by variable's declaration or value
7141    DV and offset OFFSET.  */
7142
7143 static void
7144 clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
7145                        HOST_WIDE_INT offset, rtx set_src)
7146 {
7147   void **slot;
7148
7149   if (!dv_as_opaque (dv)
7150       || (!dv_is_value_p (dv) && ! DECL_P (dv_as_decl (dv))))
7151     return;
7152
7153   slot = shared_hash_find_slot_noinsert (set->vars, dv);
7154   if (!slot)
7155     return;
7156
7157   clobber_slot_part (set, loc, slot, offset, set_src);
7158 }
7159
7160 /* Delete the part of variable's location from dataflow set SET.  The
7161    variable part is specified by its SET->vars slot SLOT and offset
7162    OFFSET and the part's location by LOC.  */
7163
7164 static void **
7165 delete_slot_part (dataflow_set *set, rtx loc, void **slot,
7166                   HOST_WIDE_INT offset)
7167 {
7168   variable var = (variable) *slot;
7169   int pos = find_variable_location_part (var, offset, NULL);
7170
7171   if (pos >= 0)
7172     {
7173       location_chain node, next;
7174       location_chain *nextp;
7175       bool changed;
7176
7177       if (shared_var_p (var, set->vars))
7178         {
7179           /* If the variable contains the location part we have to
7180              make a copy of the variable.  */
7181           for (node = var->var_part[pos].loc_chain; node;
7182                node = node->next)
7183             {
7184               if ((REG_P (node->loc) && REG_P (loc)
7185                    && REGNO (node->loc) == REGNO (loc))
7186                   || rtx_equal_p (node->loc, loc))
7187                 {
7188                   slot = unshare_variable (set, slot, var,
7189                                            VAR_INIT_STATUS_UNKNOWN);
7190                   var = (variable)*slot;
7191                   break;
7192                 }
7193             }
7194         }
7195
7196       /* Delete the location part.  */
7197       changed = false;
7198       nextp = &var->var_part[pos].loc_chain;
7199       for (node = *nextp; node; node = next)
7200         {
7201           next = node->next;
7202           if ((REG_P (node->loc) && REG_P (loc)
7203                && REGNO (node->loc) == REGNO (loc))
7204               || rtx_equal_p (node->loc, loc))
7205             {
7206               if (emit_notes && pos == 0 && dv_onepart_p (var->dv))
7207                 remove_value_chains (var->dv, node->loc);
7208               /* If we have deleted the location which was last emitted
7209                  we have to emit new location so add the variable to set
7210                  of changed variables.  */
7211               if (var->var_part[pos].cur_loc == node->loc)
7212                 {
7213                   changed = true;
7214                   var->var_part[pos].cur_loc = NULL;
7215                   var->cur_loc_changed = true;
7216                 }
7217               pool_free (loc_chain_pool, node);
7218               *nextp = next;
7219               break;
7220             }
7221           else
7222             nextp = &node->next;
7223         }
7224
7225       if (var->var_part[pos].loc_chain == NULL)
7226         {
7227           changed = true;
7228           var->n_var_parts--;
7229           if (emit_notes)
7230             var->cur_loc_changed = true;
7231           while (pos < var->n_var_parts)
7232             {
7233               var->var_part[pos] = var->var_part[pos + 1];
7234               pos++;
7235             }
7236         }
7237       if (changed)
7238         variable_was_changed (var, set);
7239     }
7240
7241   return slot;
7242 }
7243
7244 /* Delete the part of variable's location from dataflow set SET.  The
7245    variable part is specified by variable's declaration or value DV
7246    and offset OFFSET and the part's location by LOC.  */
7247
7248 static void
7249 delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
7250                       HOST_WIDE_INT offset)
7251 {
7252   void **slot = shared_hash_find_slot_noinsert (set->vars, dv);
7253   if (!slot)
7254     return;
7255
7256   delete_slot_part (set, loc, slot, offset);
7257 }
7258
7259 /* Structure for passing some other parameters to function
7260    vt_expand_loc_callback.  */
7261 struct expand_loc_callback_data
7262 {
7263   /* The variables and values active at this point.  */
7264   htab_t vars;
7265
7266   /* True in vt_expand_loc_dummy calls, no rtl should be allocated.
7267      Non-NULL should be returned if vt_expand_loc would return
7268      non-NULL in that case, NULL otherwise.  cur_loc_changed should be
7269      computed and cur_loc recomputed when possible (but just once
7270      per emit_notes_for_changes call).  */
7271   bool dummy;
7272
7273   /* True if expansion of subexpressions had to recompute some
7274      VALUE/DEBUG_EXPR_DECL's cur_loc or used a VALUE/DEBUG_EXPR_DECL
7275      whose cur_loc has been already recomputed during current
7276      emit_notes_for_changes call.  */
7277   bool cur_loc_changed;
7278
7279   /* True if cur_loc should be ignored and any possible location
7280      returned.  */
7281   bool ignore_cur_loc;
7282 };
7283
7284 /* Callback for cselib_expand_value, that looks for expressions
7285    holding the value in the var-tracking hash tables.  Return X for
7286    standard processing, anything else is to be used as-is.  */
7287
7288 static rtx
7289 vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data)
7290 {
7291   struct expand_loc_callback_data *elcd
7292     = (struct expand_loc_callback_data *) data;
7293   bool dummy = elcd->dummy;
7294   bool cur_loc_changed = elcd->cur_loc_changed;
7295   rtx cur_loc;
7296   decl_or_value dv;
7297   variable var;
7298   location_chain loc;
7299   rtx result, subreg, xret;
7300
7301   switch (GET_CODE (x))
7302     {
7303     case SUBREG:
7304       if (dummy)
7305         {
7306           if (cselib_dummy_expand_value_rtx_cb (SUBREG_REG (x), regs,
7307                                                 max_depth - 1,
7308                                                 vt_expand_loc_callback, data))
7309             return pc_rtx;
7310           else
7311             return NULL;
7312         }
7313
7314       subreg = cselib_expand_value_rtx_cb (SUBREG_REG (x), regs,
7315                                            max_depth - 1,
7316                                            vt_expand_loc_callback, data);
7317
7318       if (!subreg)
7319         return NULL;
7320
7321       result = simplify_gen_subreg (GET_MODE (x), subreg,
7322                                     GET_MODE (SUBREG_REG (x)),
7323                                     SUBREG_BYTE (x));
7324
7325       /* Invalid SUBREGs are ok in debug info.  ??? We could try
7326          alternate expansions for the VALUE as well.  */
7327       if (!result)
7328         result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));
7329
7330       return result;
7331
7332     case DEBUG_EXPR:
7333       dv = dv_from_decl (DEBUG_EXPR_TREE_DECL (x));
7334       xret = NULL;
7335       break;
7336
7337     case VALUE:
7338       dv = dv_from_value (x);
7339       xret = x;
7340       break;
7341
7342     default:
7343       return x;
7344     }
7345
7346   if (VALUE_RECURSED_INTO (x))
7347     return NULL;
7348
7349   var = (variable) htab_find_with_hash (elcd->vars, dv, dv_htab_hash (dv));
7350
7351   if (!var)
7352     {
7353       if (dummy && dv_changed_p (dv))
7354         elcd->cur_loc_changed = true;
7355       return xret;
7356     }
7357
7358   if (var->n_var_parts == 0)
7359     {
7360       if (dummy)
7361         elcd->cur_loc_changed = true;
7362       return xret;
7363     }
7364
7365   gcc_assert (var->n_var_parts == 1);
7366
7367   VALUE_RECURSED_INTO (x) = true;
7368   result = NULL;
7369
7370   if (var->var_part[0].cur_loc && !elcd->ignore_cur_loc)
7371     {
7372       if (dummy)
7373         {
7374           if (cselib_dummy_expand_value_rtx_cb (var->var_part[0].cur_loc, regs,
7375                                                 max_depth,
7376                                                 vt_expand_loc_callback, data))
7377             result = pc_rtx;
7378         }
7379       else
7380         result = cselib_expand_value_rtx_cb (var->var_part[0].cur_loc, regs,
7381                                              max_depth,
7382                                              vt_expand_loc_callback, data);
7383       if (result)
7384         set_dv_changed (dv, false);
7385       cur_loc = var->var_part[0].cur_loc;
7386     }
7387   else
7388     cur_loc = NULL_RTX;
7389   if (!result && (dv_changed_p (dv) || elcd->ignore_cur_loc))
7390     {
7391       if (!elcd->ignore_cur_loc)
7392         set_dv_changed (dv, false);
7393       for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
7394         if (loc->loc == cur_loc)
7395           continue;
7396         else if (dummy)
7397           {
7398             elcd->cur_loc_changed = cur_loc_changed;
7399             if (cselib_dummy_expand_value_rtx_cb (loc->loc, regs, max_depth,
7400                                                   vt_expand_loc_callback,
7401                                                   data))
7402               {
7403                 result = pc_rtx;
7404                 break;
7405               }
7406           }
7407         else
7408           {
7409             result = cselib_expand_value_rtx_cb (loc->loc, regs, max_depth,
7410                                                  vt_expand_loc_callback, data);
7411             if (result)
7412               break;
7413           }
7414       if (dummy && (result || var->var_part[0].cur_loc))
7415         var->cur_loc_changed = true;
7416       if (!elcd->ignore_cur_loc)
7417         var->var_part[0].cur_loc = loc ? loc->loc : NULL_RTX;
7418     }
7419   if (dummy)
7420     {
7421       if (var->cur_loc_changed)
7422         elcd->cur_loc_changed = true;
7423       else if (!result && var->var_part[0].cur_loc == NULL_RTX)
7424         elcd->cur_loc_changed = cur_loc_changed;
7425     }
7426
7427   VALUE_RECURSED_INTO (x) = false;
7428   if (result)
7429     return result;
7430   else
7431     return xret;
7432 }
7433
7434 /* Expand VALUEs in LOC, using VARS as well as cselib's equivalence
7435    tables.  */
7436
7437 static rtx
7438 vt_expand_loc (rtx loc, htab_t vars, bool ignore_cur_loc)
7439 {
7440   struct expand_loc_callback_data data;
7441
7442   if (!MAY_HAVE_DEBUG_INSNS)
7443     return loc;
7444
7445   data.vars = vars;
7446   data.dummy = false;
7447   data.cur_loc_changed = false;
7448   data.ignore_cur_loc = ignore_cur_loc;
7449   loc = cselib_expand_value_rtx_cb (loc, scratch_regs, EXPR_DEPTH,
7450                                     vt_expand_loc_callback, &data);
7451
7452   if (loc && MEM_P (loc))
7453     loc = targetm.delegitimize_address (loc);
7454   return loc;
7455 }
7456
7457 /* Like vt_expand_loc, but only return true/false (whether vt_expand_loc
7458    would succeed or not, without actually allocating new rtxes.  */
7459
7460 static bool
7461 vt_expand_loc_dummy (rtx loc, htab_t vars, bool *pcur_loc_changed)
7462 {
7463   struct expand_loc_callback_data data;
7464   bool ret;
7465
7466   gcc_assert (MAY_HAVE_DEBUG_INSNS);
7467   data.vars = vars;
7468   data.dummy = true;
7469   data.cur_loc_changed = false;
7470   data.ignore_cur_loc = false;
7471   ret = cselib_dummy_expand_value_rtx_cb (loc, scratch_regs, EXPR_DEPTH,
7472                                           vt_expand_loc_callback, &data);
7473   *pcur_loc_changed = data.cur_loc_changed;
7474   return ret;
7475 }
7476
7477 /* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP.  DATA contains
7478    additional parameters: WHERE specifies whether the note shall be emitted
7479    before or after instruction INSN.  */
7480
7481 static int
7482 emit_note_insn_var_location (void **varp, void *data)
7483 {
7484   variable var = (variable) *varp;
7485   rtx insn = ((emit_note_data *)data)->insn;
7486   enum emit_note_where where = ((emit_note_data *)data)->where;
7487   htab_t vars = ((emit_note_data *)data)->vars;
7488   rtx note, note_vl;
7489   int i, j, n_var_parts;
7490   bool complete;
7491   enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED;
7492   HOST_WIDE_INT last_limit;
7493   tree type_size_unit;
7494   HOST_WIDE_INT offsets[MAX_VAR_PARTS];
7495   rtx loc[MAX_VAR_PARTS];
7496   tree decl;
7497   location_chain lc;
7498
7499   if (dv_is_value_p (var->dv))
7500     goto value_or_debug_decl;
7501
7502   decl = dv_as_decl (var->dv);
7503
7504   if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
7505     goto value_or_debug_decl;
7506
7507   complete = true;
7508   last_limit = 0;
7509   n_var_parts = 0;
7510   if (!MAY_HAVE_DEBUG_INSNS)
7511     {
7512       for (i = 0; i < var->n_var_parts; i++)
7513         if (var->var_part[i].cur_loc == NULL && var->var_part[i].loc_chain)
7514           {
7515             var->var_part[i].cur_loc = var->var_part[i].loc_chain->loc;
7516             var->cur_loc_changed = true;
7517           }
7518       if (var->n_var_parts == 0)
7519         var->cur_loc_changed = true;
7520     }
7521   if (!var->cur_loc_changed)
7522     goto clear;
7523   for (i = 0; i < var->n_var_parts; i++)
7524     {
7525       enum machine_mode mode, wider_mode;
7526       rtx loc2;
7527
7528       if (last_limit < var->var_part[i].offset)
7529         {
7530           complete = false;
7531           break;
7532         }
7533       else if (last_limit > var->var_part[i].offset)
7534         continue;
7535       offsets[n_var_parts] = var->var_part[i].offset;
7536       if (!var->var_part[i].cur_loc)
7537         {
7538           complete = false;
7539           continue;
7540         }
7541       loc2 = vt_expand_loc (var->var_part[i].cur_loc, vars, false);
7542       if (!loc2)
7543         {
7544           complete = false;
7545           continue;
7546         }
7547       loc[n_var_parts] = loc2;
7548       mode = GET_MODE (var->var_part[i].cur_loc);
7549       if (mode == VOIDmode && dv_onepart_p (var->dv))
7550         mode = DECL_MODE (decl);
7551       for (lc = var->var_part[i].loc_chain; lc; lc = lc->next)
7552         if (var->var_part[i].cur_loc == lc->loc)
7553           {
7554             initialized = lc->init;
7555             break;
7556           }
7557       gcc_assert (lc);
7558       last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
7559
7560       /* Attempt to merge adjacent registers or memory.  */
7561       wider_mode = GET_MODE_WIDER_MODE (mode);
7562       for (j = i + 1; j < var->n_var_parts; j++)
7563         if (last_limit <= var->var_part[j].offset)
7564           break;
7565       if (j < var->n_var_parts
7566           && wider_mode != VOIDmode
7567           && var->var_part[j].cur_loc
7568           && mode == GET_MODE (var->var_part[j].cur_loc)
7569           && (REG_P (loc[n_var_parts]) || MEM_P (loc[n_var_parts]))
7570           && last_limit == var->var_part[j].offset
7571           && (loc2 = vt_expand_loc (var->var_part[j].cur_loc, vars, false))
7572           && GET_CODE (loc[n_var_parts]) == GET_CODE (loc2))
7573         {
7574           rtx new_loc = NULL;
7575
7576           if (REG_P (loc[n_var_parts])
7577               && hard_regno_nregs[REGNO (loc[n_var_parts])][mode] * 2
7578                  == hard_regno_nregs[REGNO (loc[n_var_parts])][wider_mode]
7579               && end_hard_regno (mode, REGNO (loc[n_var_parts]))
7580                  == REGNO (loc2))
7581             {
7582               if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
7583                 new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
7584                                            mode, 0);
7585               else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
7586                 new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
7587               if (new_loc)
7588                 {
7589                   if (!REG_P (new_loc)
7590                       || REGNO (new_loc) != REGNO (loc[n_var_parts]))
7591                     new_loc = NULL;
7592                   else
7593                     REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
7594                 }
7595             }
7596           else if (MEM_P (loc[n_var_parts])
7597                    && GET_CODE (XEXP (loc2, 0)) == PLUS
7598                    && REG_P (XEXP (XEXP (loc2, 0), 0))
7599                    && CONST_INT_P (XEXP (XEXP (loc2, 0), 1)))
7600             {
7601               if ((REG_P (XEXP (loc[n_var_parts], 0))
7602                    && rtx_equal_p (XEXP (loc[n_var_parts], 0),
7603                                    XEXP (XEXP (loc2, 0), 0))
7604                    && INTVAL (XEXP (XEXP (loc2, 0), 1))
7605                       == GET_MODE_SIZE (mode))
7606                   || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
7607                       && CONST_INT_P (XEXP (XEXP (loc[n_var_parts], 0), 1))
7608                       && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
7609                                       XEXP (XEXP (loc2, 0), 0))
7610                       && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
7611                          + GET_MODE_SIZE (mode)
7612                          == INTVAL (XEXP (XEXP (loc2, 0), 1))))
7613                 new_loc = adjust_address_nv (loc[n_var_parts],
7614                                              wider_mode, 0);
7615             }
7616
7617           if (new_loc)
7618             {
7619               loc[n_var_parts] = new_loc;
7620               mode = wider_mode;
7621               last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
7622               i = j;
7623             }
7624         }
7625       ++n_var_parts;
7626     }
7627   type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl));
7628   if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
7629     complete = false;
7630
7631   if (! flag_var_tracking_uninit)
7632     initialized = VAR_INIT_STATUS_INITIALIZED;
7633
7634   note_vl = NULL_RTX;
7635   if (!complete)
7636     note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, NULL_RTX,
7637                                     (int) initialized);
7638   else if (n_var_parts == 1)
7639     {
7640       rtx expr_list;
7641
7642       if (offsets[0] || GET_CODE (loc[0]) == PARALLEL)
7643         expr_list = gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
7644       else
7645         expr_list = loc[0];
7646
7647       note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, expr_list,
7648                                       (int) initialized);
7649     }
7650   else if (n_var_parts)
7651     {
7652       rtx parallel;
7653
7654       for (i = 0; i < n_var_parts; i++)
7655         loc[i]
7656           = gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));
7657
7658       parallel = gen_rtx_PARALLEL (VOIDmode,
7659                                    gen_rtvec_v (n_var_parts, loc));
7660       note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl,
7661                                       parallel, (int) initialized);
7662     }
7663
7664   if (where != EMIT_NOTE_BEFORE_INSN)
7665     {
7666       note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
7667       if (where == EMIT_NOTE_AFTER_CALL_INSN)
7668         NOTE_DURING_CALL_P (note) = true;
7669     }
7670   else
7671     {
7672       /* Make sure that the call related notes come first.  */
7673       while (NEXT_INSN (insn)
7674              && NOTE_P (insn)
7675              && NOTE_DURING_CALL_P (insn))
7676         insn = NEXT_INSN (insn);
7677       if (NOTE_P (insn) && NOTE_DURING_CALL_P (insn))
7678         note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
7679       else
7680         note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
7681     }
7682   NOTE_VAR_LOCATION (note) = note_vl;
7683
7684  clear:
7685   set_dv_changed (var->dv, false);
7686   var->cur_loc_changed = false;
7687   gcc_assert (var->in_changed_variables);
7688   var->in_changed_variables = false;
7689   htab_clear_slot (changed_variables, varp);
7690
7691   /* Continue traversing the hash table.  */
7692   return 1;
7693
7694  value_or_debug_decl:
7695   if (dv_changed_p (var->dv) && var->n_var_parts)
7696     {
7697       location_chain lc;
7698       bool cur_loc_changed;
7699
7700       if (var->var_part[0].cur_loc
7701           && vt_expand_loc_dummy (var->var_part[0].cur_loc, vars,
7702                                   &cur_loc_changed))
7703         goto clear;
7704       for (lc = var->var_part[0].loc_chain; lc; lc = lc->next)
7705         if (lc->loc != var->var_part[0].cur_loc
7706             && vt_expand_loc_dummy (lc->loc, vars, &cur_loc_changed))
7707           break;
7708       var->var_part[0].cur_loc = lc ? lc->loc : NULL_RTX;
7709     }
7710   goto clear;
7711 }
7712
7713 DEF_VEC_P (variable);
7714 DEF_VEC_ALLOC_P (variable, heap);
7715
7716 /* Stack of variable_def pointers that need processing with
7717    check_changed_vars_2.  */
7718
7719 static VEC (variable, heap) *changed_variables_stack;
7720
7721 /* VALUEs with no variables that need set_dv_changed (val, false)
7722    called before check_changed_vars_3.  */
7723
7724 static VEC (rtx, heap) *changed_values_stack;
7725
7726 /* Helper function for check_changed_vars_1 and check_changed_vars_2.  */
7727
7728 static void
7729 check_changed_vars_0 (decl_or_value dv, htab_t htab)
7730 {
7731   value_chain vc
7732     = (value_chain) htab_find_with_hash (value_chains, dv, dv_htab_hash (dv));
7733
7734   if (vc == NULL)
7735     return;
7736   for (vc = vc->next; vc; vc = vc->next)
7737     if (!dv_changed_p (vc->dv))
7738       {
7739         variable vcvar
7740           = (variable) htab_find_with_hash (htab, vc->dv,
7741                                             dv_htab_hash (vc->dv));
7742         if (vcvar)
7743           {
7744             set_dv_changed (vc->dv, true);
7745             VEC_safe_push (variable, heap, changed_variables_stack, vcvar);
7746           }
7747         else if (dv_is_value_p (vc->dv))
7748           {
7749             set_dv_changed (vc->dv, true);
7750             VEC_safe_push (rtx, heap, changed_values_stack,
7751                            dv_as_value (vc->dv));
7752             check_changed_vars_0 (vc->dv, htab);
7753           }
7754       }
7755 }
7756
7757 /* Populate changed_variables_stack with variable_def pointers
7758    that need variable_was_changed called on them.  */
7759
7760 static int
7761 check_changed_vars_1 (void **slot, void *data)
7762 {
7763   variable var = (variable) *slot;
7764   htab_t htab = (htab_t) data;
7765
7766   if (dv_is_value_p (var->dv)
7767       || TREE_CODE (dv_as_decl (var->dv)) == DEBUG_EXPR_DECL)
7768     check_changed_vars_0 (var->dv, htab);
7769   return 1;
7770 }
7771
7772 /* Add VAR to changed_variables and also for VALUEs add recursively
7773    all DVs that aren't in changed_variables yet but reference the
7774    VALUE from its loc_chain.  */
7775
7776 static void
7777 check_changed_vars_2 (variable var, htab_t htab)
7778 {
7779   variable_was_changed (var, NULL);
7780   if (dv_is_value_p (var->dv)
7781       || TREE_CODE (dv_as_decl (var->dv)) == DEBUG_EXPR_DECL)
7782     check_changed_vars_0 (var->dv, htab);
7783 }
7784
7785 /* For each changed decl (except DEBUG_EXPR_DECLs) recompute
7786    cur_loc if needed (and cur_loc of all VALUEs and DEBUG_EXPR_DECLs
7787    it needs and are also in changed variables) and track whether
7788    cur_loc (or anything it uses to compute location) had to change
7789    during the current emit_notes_for_changes call.  */
7790
7791 static int
7792 check_changed_vars_3 (void **slot, void *data)
7793 {
7794   variable var = (variable) *slot;
7795   htab_t vars = (htab_t) data;
7796   int i;
7797   location_chain lc;
7798   bool cur_loc_changed;
7799
7800   if (dv_is_value_p (var->dv)
7801       || TREE_CODE (dv_as_decl (var->dv)) == DEBUG_EXPR_DECL)
7802     return 1;
7803
7804   for (i = 0; i < var->n_var_parts; i++)
7805     {
7806       if (var->var_part[i].cur_loc
7807           && vt_expand_loc_dummy (var->var_part[i].cur_loc, vars,
7808                                   &cur_loc_changed))
7809         {
7810           if (cur_loc_changed)
7811             var->cur_loc_changed = true;
7812           continue;
7813         }
7814       for (lc = var->var_part[i].loc_chain; lc; lc = lc->next)
7815         if (lc->loc != var->var_part[i].cur_loc
7816             && vt_expand_loc_dummy (lc->loc, vars, &cur_loc_changed))
7817           break;
7818       if (lc || var->var_part[i].cur_loc)
7819         var->cur_loc_changed = true;
7820       var->var_part[i].cur_loc = lc ? lc->loc : NULL_RTX;
7821     }
7822   if (var->n_var_parts == 0)
7823     var->cur_loc_changed = true;
7824   return 1;
7825 }
7826
7827 /* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
7828    CHANGED_VARIABLES and delete this chain.  WHERE specifies whether the notes
7829    shall be emitted before of after instruction INSN.  */
7830
7831 static void
7832 emit_notes_for_changes (rtx insn, enum emit_note_where where,
7833                         shared_hash vars)
7834 {
7835   emit_note_data data;
7836   htab_t htab = shared_hash_htab (vars);
7837
7838   if (!htab_elements (changed_variables))
7839     return;
7840
7841   if (MAY_HAVE_DEBUG_INSNS)
7842     {
7843       /* Unfortunately this has to be done in two steps, because
7844          we can't traverse a hashtab into which we are inserting
7845          through variable_was_changed.  */
7846       htab_traverse (changed_variables, check_changed_vars_1, htab);
7847       while (VEC_length (variable, changed_variables_stack) > 0)
7848         check_changed_vars_2 (VEC_pop (variable, changed_variables_stack),
7849                               htab);
7850       while (VEC_length (rtx, changed_values_stack) > 0)
7851         set_dv_changed (dv_from_value (VEC_pop (rtx, changed_values_stack)),
7852                         false);
7853       htab_traverse (changed_variables, check_changed_vars_3, htab);
7854     }
7855
7856   data.insn = insn;
7857   data.where = where;
7858   data.vars = htab;
7859
7860   htab_traverse (changed_variables, emit_note_insn_var_location, &data);
7861 }
7862
7863 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
7864    same variable in hash table DATA or is not there at all.  */
7865
7866 static int
7867 emit_notes_for_differences_1 (void **slot, void *data)
7868 {
7869   htab_t new_vars = (htab_t) data;
7870   variable old_var, new_var;
7871
7872   old_var = (variable) *slot;
7873   new_var = (variable) htab_find_with_hash (new_vars, old_var->dv,
7874                                             dv_htab_hash (old_var->dv));
7875
7876   if (!new_var)
7877     {
7878       /* Variable has disappeared.  */
7879       variable empty_var;
7880
7881       empty_var = (variable) pool_alloc (dv_pool (old_var->dv));
7882       empty_var->dv = old_var->dv;
7883       empty_var->refcount = 0;
7884       empty_var->n_var_parts = 0;
7885       empty_var->cur_loc_changed = false;
7886       empty_var->in_changed_variables = false;
7887       if (dv_onepart_p (old_var->dv))
7888         {
7889           location_chain lc;
7890
7891           gcc_assert (old_var->n_var_parts == 1);
7892           for (lc = old_var->var_part[0].loc_chain; lc; lc = lc->next)
7893             remove_value_chains (old_var->dv, lc->loc);
7894         }
7895       variable_was_changed (empty_var, NULL);
7896       /* Continue traversing the hash table.  */
7897       return 1;
7898     }
7899   if (variable_different_p (old_var, new_var))
7900     {
7901       if (dv_onepart_p (old_var->dv))
7902         {
7903           location_chain lc1, lc2;
7904
7905           gcc_assert (old_var->n_var_parts == 1
7906                       && new_var->n_var_parts == 1);
7907           lc1 = old_var->var_part[0].loc_chain;
7908           lc2 = new_var->var_part[0].loc_chain;
7909           while (lc1
7910                  && lc2
7911                  && ((REG_P (lc1->loc) && REG_P (lc2->loc))
7912                      || rtx_equal_p (lc1->loc, lc2->loc)))
7913             {
7914               lc1 = lc1->next;
7915               lc2 = lc2->next;
7916             }
7917           for (; lc2; lc2 = lc2->next)
7918             add_value_chains (old_var->dv, lc2->loc);
7919           for (; lc1; lc1 = lc1->next)
7920             remove_value_chains (old_var->dv, lc1->loc);
7921         }
7922       variable_was_changed (new_var, NULL);
7923     }
7924   /* Update cur_loc.  */
7925   if (old_var != new_var)
7926     {
7927       int i;
7928       for (i = 0; i < new_var->n_var_parts; i++)
7929         {
7930           new_var->var_part[i].cur_loc = NULL;
7931           if (old_var->n_var_parts != new_var->n_var_parts
7932               || old_var->var_part[i].offset != new_var->var_part[i].offset)
7933             new_var->cur_loc_changed = true;
7934           else if (old_var->var_part[i].cur_loc != NULL)
7935             {
7936               location_chain lc;
7937               rtx cur_loc = old_var->var_part[i].cur_loc;
7938
7939               for (lc = new_var->var_part[i].loc_chain; lc; lc = lc->next)
7940                 if (lc->loc == cur_loc
7941                     || rtx_equal_p (cur_loc, lc->loc))
7942                   {
7943                     new_var->var_part[i].cur_loc = lc->loc;
7944                     break;
7945                   }
7946               if (lc == NULL)
7947                 new_var->cur_loc_changed = true;
7948             }
7949         }
7950     }
7951
7952   /* Continue traversing the hash table.  */
7953   return 1;
7954 }
7955
7956 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
7957    table DATA.  */
7958
7959 static int
7960 emit_notes_for_differences_2 (void **slot, void *data)
7961 {
7962   htab_t old_vars = (htab_t) data;
7963   variable old_var, new_var;
7964
7965   new_var = (variable) *slot;
7966   old_var = (variable) htab_find_with_hash (old_vars, new_var->dv,
7967                                             dv_htab_hash (new_var->dv));
7968   if (!old_var)
7969     {
7970       int i;
7971       /* Variable has appeared.  */
7972       if (dv_onepart_p (new_var->dv))
7973         {
7974           location_chain lc;
7975
7976           gcc_assert (new_var->n_var_parts == 1);
7977           for (lc = new_var->var_part[0].loc_chain; lc; lc = lc->next)
7978             add_value_chains (new_var->dv, lc->loc);
7979         }
7980       for (i = 0; i < new_var->n_var_parts; i++)
7981         new_var->var_part[i].cur_loc = NULL;
7982       variable_was_changed (new_var, NULL);
7983     }
7984
7985   /* Continue traversing the hash table.  */
7986   return 1;
7987 }
7988
7989 /* Emit notes before INSN for differences between dataflow sets OLD_SET and
7990    NEW_SET.  */
7991
7992 static void
7993 emit_notes_for_differences (rtx insn, dataflow_set *old_set,
7994                             dataflow_set *new_set)
7995 {
7996   htab_traverse (shared_hash_htab (old_set->vars),
7997                  emit_notes_for_differences_1,
7998                  shared_hash_htab (new_set->vars));
7999   htab_traverse (shared_hash_htab (new_set->vars),
8000                  emit_notes_for_differences_2,
8001                  shared_hash_htab (old_set->vars));
8002   emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, new_set->vars);
8003 }
8004
8005 /* Emit the notes for changes of location parts in the basic block BB.  */
8006
8007 static void
8008 emit_notes_in_bb (basic_block bb, dataflow_set *set)
8009 {
8010   unsigned int i;
8011   micro_operation *mo;
8012
8013   dataflow_set_clear (set);
8014   dataflow_set_copy (set, &VTI (bb)->in);
8015
8016   FOR_EACH_VEC_ELT (micro_operation, VTI (bb)->mos, i, mo)
8017     {
8018       rtx insn = mo->insn;
8019
8020       switch (mo->type)
8021         {
8022           case MO_CALL:
8023             dataflow_set_clear_at_call (set);
8024             emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars);
8025             {
8026               rtx arguments = mo->u.loc, *p = &arguments, note;
8027               while (*p)
8028                 {
8029                   XEXP (XEXP (*p, 0), 1)
8030                     = vt_expand_loc (XEXP (XEXP (*p, 0), 1),
8031                                      shared_hash_htab (set->vars), true);
8032                   /* If expansion is successful, keep it in the list.  */
8033                   if (XEXP (XEXP (*p, 0), 1))
8034                     p = &XEXP (*p, 1);
8035                   /* Otherwise, if the following item is data_value for it,
8036                      drop it too too.  */
8037                   else if (XEXP (*p, 1)
8038                            && REG_P (XEXP (XEXP (*p, 0), 0))
8039                            && MEM_P (XEXP (XEXP (XEXP (*p, 1), 0), 0))
8040                            && REG_P (XEXP (XEXP (XEXP (XEXP (*p, 1), 0), 0),
8041                                            0))
8042                            && REGNO (XEXP (XEXP (*p, 0), 0))
8043                               == REGNO (XEXP (XEXP (XEXP (XEXP (*p, 1), 0),
8044                                                     0), 0)))
8045                     *p = XEXP (XEXP (*p, 1), 1);
8046                   /* Just drop this item.  */
8047                   else
8048                     *p = XEXP (*p, 1);
8049                 }
8050               note = emit_note_after (NOTE_INSN_CALL_ARG_LOCATION, insn);
8051               NOTE_VAR_LOCATION (note) = arguments;
8052             }
8053             break;
8054
8055           case MO_USE:
8056             {
8057               rtx loc = mo->u.loc;
8058
8059               if (REG_P (loc))
8060                 var_reg_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
8061               else
8062                 var_mem_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
8063
8064               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
8065             }
8066             break;
8067
8068           case MO_VAL_LOC:
8069             {
8070               rtx loc = mo->u.loc;
8071               rtx val, vloc;
8072               tree var;
8073
8074               if (GET_CODE (loc) == CONCAT)
8075                 {
8076                   val = XEXP (loc, 0);
8077                   vloc = XEXP (loc, 1);
8078                 }
8079               else
8080                 {
8081                   val = NULL_RTX;
8082                   vloc = loc;
8083                 }
8084
8085               var = PAT_VAR_LOCATION_DECL (vloc);
8086
8087               clobber_variable_part (set, NULL_RTX,
8088                                      dv_from_decl (var), 0, NULL_RTX);
8089               if (val)
8090                 {
8091                   if (VAL_NEEDS_RESOLUTION (loc))
8092                     val_resolve (set, val, PAT_VAR_LOCATION_LOC (vloc), insn);
8093                   set_variable_part (set, val, dv_from_decl (var), 0,
8094                                      VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
8095                                      INSERT);
8096                 }
8097               else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
8098                 set_variable_part (set, PAT_VAR_LOCATION_LOC (vloc),
8099                                    dv_from_decl (var), 0,
8100                                    VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
8101                                    INSERT);
8102
8103               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
8104             }
8105             break;
8106
8107           case MO_VAL_USE:
8108             {
8109               rtx loc = mo->u.loc;
8110               rtx val, vloc, uloc;
8111
8112               vloc = uloc = XEXP (loc, 1);
8113               val = XEXP (loc, 0);
8114
8115               if (GET_CODE (val) == CONCAT)
8116                 {
8117                   uloc = XEXP (val, 1);
8118                   val = XEXP (val, 0);
8119                 }
8120
8121               if (VAL_NEEDS_RESOLUTION (loc))
8122                 val_resolve (set, val, vloc, insn);
8123               else
8124                 val_store (set, val, uloc, insn, false);
8125
8126               if (VAL_HOLDS_TRACK_EXPR (loc))
8127                 {
8128                   if (GET_CODE (uloc) == REG)
8129                     var_reg_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
8130                                  NULL);
8131                   else if (GET_CODE (uloc) == MEM)
8132                     var_mem_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
8133                                  NULL);
8134                 }
8135
8136               emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
8137             }
8138             break;
8139
8140           case MO_VAL_SET:
8141             {
8142               rtx loc = mo->u.loc;
8143               rtx val, vloc, uloc, reverse = NULL_RTX;
8144
8145               vloc = loc;
8146               if (VAL_EXPR_HAS_REVERSE (loc))
8147                 {
8148                   reverse = XEXP (loc, 1);
8149                   vloc = XEXP (loc, 0);
8150                 }
8151               uloc = XEXP (vloc, 1);
8152               val = XEXP (vloc, 0);
8153               vloc = uloc;
8154
8155               if (GET_CODE (val) == CONCAT)
8156                 {
8157                   vloc = XEXP (val, 1);
8158                   val = XEXP (val, 0);
8159                 }
8160
8161               if (GET_CODE (vloc) == SET)
8162                 {
8163                   rtx vsrc = SET_SRC (vloc);
8164
8165                   gcc_assert (val != vsrc);
8166                   gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
8167
8168                   vloc = SET_DEST (vloc);
8169
8170                   if (VAL_NEEDS_RESOLUTION (loc))
8171                     val_resolve (set, val, vsrc, insn);
8172                 }
8173               else if (VAL_NEEDS_RESOLUTION (loc))
8174                 {
8175                   gcc_assert (GET_CODE (uloc) == SET
8176                               && GET_CODE (SET_SRC (uloc)) == REG);
8177                   val_resolve (set, val, SET_SRC (uloc), insn);
8178                 }
8179
8180               if (VAL_HOLDS_TRACK_EXPR (loc))
8181                 {
8182                   if (VAL_EXPR_IS_CLOBBERED (loc))
8183                     {
8184                       if (REG_P (uloc))
8185                         var_reg_delete (set, uloc, true);
8186                       else if (MEM_P (uloc))
8187                         var_mem_delete (set, uloc, true);
8188                     }
8189                   else
8190                     {
8191                       bool copied_p = VAL_EXPR_IS_COPIED (loc);
8192                       rtx set_src = NULL;
8193                       enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
8194
8195                       if (GET_CODE (uloc) == SET)
8196                         {
8197                           set_src = SET_SRC (uloc);
8198                           uloc = SET_DEST (uloc);
8199                         }
8200
8201                       if (copied_p)
8202                         {
8203                           status = find_src_status (set, set_src);
8204
8205                           set_src = find_src_set_src (set, set_src);
8206                         }
8207
8208                       if (REG_P (uloc))
8209                         var_reg_delete_and_set (set, uloc, !copied_p,
8210                                                 status, set_src);
8211                       else if (MEM_P (uloc))
8212                         var_mem_delete_and_set (set, uloc, !copied_p,
8213                                                 status, set_src);
8214                     }
8215                 }
8216               else if (REG_P (uloc))
8217                 var_regno_delete (set, REGNO (uloc));
8218
8219               val_store (set, val, vloc, insn, true);
8220
8221               if (reverse)
8222                 val_store (set, XEXP (reverse, 0), XEXP (reverse, 1),
8223                            insn, false);
8224
8225               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
8226                                       set->vars);
8227             }
8228             break;
8229
8230           case MO_SET:
8231             {
8232               rtx loc = mo->u.loc;
8233               rtx set_src = NULL;
8234
8235               if (GET_CODE (loc) == SET)
8236                 {
8237                   set_src = SET_SRC (loc);
8238                   loc = SET_DEST (loc);
8239                 }
8240
8241               if (REG_P (loc))
8242                 var_reg_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
8243                                         set_src);
8244               else
8245                 var_mem_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
8246                                         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_COPY:
8254             {
8255               rtx loc = mo->u.loc;
8256               enum var_init_status src_status;
8257               rtx set_src = NULL;
8258
8259               if (GET_CODE (loc) == SET)
8260                 {
8261                   set_src = SET_SRC (loc);
8262                   loc = SET_DEST (loc);
8263                 }
8264
8265               src_status = find_src_status (set, set_src);
8266               set_src = find_src_set_src (set, set_src);
8267
8268               if (REG_P (loc))
8269                 var_reg_delete_and_set (set, loc, false, src_status, set_src);
8270               else
8271                 var_mem_delete_and_set (set, loc, false, src_status, set_src);
8272
8273               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
8274                                       set->vars);
8275             }
8276             break;
8277
8278           case MO_USE_NO_VAR:
8279             {
8280               rtx loc = mo->u.loc;
8281
8282               if (REG_P (loc))
8283                 var_reg_delete (set, loc, false);
8284               else
8285                 var_mem_delete (set, loc, false);
8286
8287               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
8288             }
8289             break;
8290
8291           case MO_CLOBBER:
8292             {
8293               rtx loc = mo->u.loc;
8294
8295               if (REG_P (loc))
8296                 var_reg_delete (set, loc, true);
8297               else
8298                 var_mem_delete (set, loc, true);
8299
8300               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
8301                                       set->vars);
8302             }
8303             break;
8304
8305           case MO_ADJUST:
8306             set->stack_adjust += mo->u.adjust;
8307             break;
8308         }
8309     }
8310 }
8311
8312 /* Emit notes for the whole function.  */
8313
8314 static void
8315 vt_emit_notes (void)
8316 {
8317   basic_block bb;
8318   dataflow_set cur;
8319
8320   gcc_assert (!htab_elements (changed_variables));
8321
8322   /* Free memory occupied by the out hash tables, as they aren't used
8323      anymore.  */
8324   FOR_EACH_BB (bb)
8325     dataflow_set_clear (&VTI (bb)->out);
8326
8327   /* Enable emitting notes by functions (mainly by set_variable_part and
8328      delete_variable_part).  */
8329   emit_notes = true;
8330
8331   if (MAY_HAVE_DEBUG_INSNS)
8332     {
8333       unsigned int i;
8334       rtx val;
8335
8336       FOR_EACH_VEC_ELT (rtx, preserved_values, i, val)
8337         add_cselib_value_chains (dv_from_value (val));
8338       changed_variables_stack = VEC_alloc (variable, heap, 40);
8339       changed_values_stack = VEC_alloc (rtx, heap, 40);
8340     }
8341
8342   dataflow_set_init (&cur);
8343
8344   FOR_EACH_BB (bb)
8345     {
8346       /* Emit the notes for changes of variable locations between two
8347          subsequent basic blocks.  */
8348       emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
8349
8350       /* Emit the notes for the changes in the basic block itself.  */
8351       emit_notes_in_bb (bb, &cur);
8352
8353       /* Free memory occupied by the in hash table, we won't need it
8354          again.  */
8355       dataflow_set_clear (&VTI (bb)->in);
8356     }
8357 #ifdef ENABLE_CHECKING
8358   htab_traverse (shared_hash_htab (cur.vars),
8359                  emit_notes_for_differences_1,
8360                  shared_hash_htab (empty_shared_hash));
8361   if (MAY_HAVE_DEBUG_INSNS)
8362     {
8363       unsigned int i;
8364       rtx val;
8365
8366       FOR_EACH_VEC_ELT (rtx, preserved_values, i, val)
8367         remove_cselib_value_chains (dv_from_value (val));
8368       gcc_assert (htab_elements (value_chains) == 0);
8369     }
8370 #endif
8371   dataflow_set_destroy (&cur);
8372
8373   if (MAY_HAVE_DEBUG_INSNS)
8374     {
8375       VEC_free (variable, heap, changed_variables_stack);
8376       VEC_free (rtx, heap, changed_values_stack);
8377     }
8378
8379   emit_notes = false;
8380 }
8381
8382 /* If there is a declaration and offset associated with register/memory RTL
8383    assign declaration to *DECLP and offset to *OFFSETP, and return true.  */
8384
8385 static bool
8386 vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
8387 {
8388   if (REG_P (rtl))
8389     {
8390       if (REG_ATTRS (rtl))
8391         {
8392           *declp = REG_EXPR (rtl);
8393           *offsetp = REG_OFFSET (rtl);
8394           return true;
8395         }
8396     }
8397   else if (MEM_P (rtl))
8398     {
8399       if (MEM_ATTRS (rtl))
8400         {
8401           *declp = MEM_EXPR (rtl);
8402           *offsetp = INT_MEM_OFFSET (rtl);
8403           return true;
8404         }
8405     }
8406   return false;
8407 }
8408
8409 /* Helper function for vt_add_function_parameter.  RTL is
8410    the expression and VAL corresponding cselib_val pointer
8411    for which ENTRY_VALUE should be created.  */
8412
8413 static void
8414 create_entry_value (rtx rtl, cselib_val *val)
8415 {
8416   cselib_val *val2;
8417   struct elt_loc_list *el;
8418   el = (struct elt_loc_list *) ggc_alloc_cleared_atomic (sizeof (*el));
8419   el->next = val->locs;
8420   el->loc = gen_rtx_ENTRY_VALUE (GET_MODE (rtl));
8421   ENTRY_VALUE_EXP (el->loc) = rtl;
8422   el->setting_insn = get_insns ();
8423   val->locs = el;
8424   val2 = cselib_lookup_from_insn (el->loc, GET_MODE (rtl), true,
8425                                   VOIDmode, get_insns ());
8426   if (val2
8427       && val2 != val
8428       && val2->locs
8429       && rtx_equal_p (val2->locs->loc, el->loc))
8430     {
8431       struct elt_loc_list *el2;
8432
8433       preserve_value (val2);
8434       el2 = (struct elt_loc_list *) ggc_alloc_cleared_atomic (sizeof (*el2));
8435       el2->next = val2->locs;
8436       el2->loc = val->val_rtx;
8437       el2->setting_insn = get_insns ();
8438       val2->locs = el2;
8439     }
8440 }
8441
8442 /* Insert function parameter PARM in IN and OUT sets of ENTRY_BLOCK.  */
8443
8444 static void
8445 vt_add_function_parameter (tree parm)
8446 {
8447   rtx decl_rtl = DECL_RTL_IF_SET (parm);
8448   rtx incoming = DECL_INCOMING_RTL (parm);
8449   tree decl;
8450   enum machine_mode mode;
8451   HOST_WIDE_INT offset;
8452   dataflow_set *out;
8453   decl_or_value dv;
8454
8455   if (TREE_CODE (parm) != PARM_DECL)
8456     return;
8457
8458   if (!decl_rtl || !incoming)
8459     return;
8460
8461   if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
8462     return;
8463
8464   /* If there is a DRAP register, rewrite the incoming location of parameters
8465      passed on the stack into MEMs based on the argument pointer, as the DRAP
8466      register can be reused for other purposes and we do not track locations
8467      based on generic registers.  But the prerequisite is that this argument
8468      pointer be also the virtual CFA pointer, see vt_initialize.  */
8469   if (MEM_P (incoming)
8470       && stack_realign_drap
8471       && arg_pointer_rtx == cfa_base_rtx
8472       && (XEXP (incoming, 0) == crtl->args.internal_arg_pointer
8473           || (GET_CODE (XEXP (incoming, 0)) == PLUS
8474               && XEXP (XEXP (incoming, 0), 0)
8475                  == crtl->args.internal_arg_pointer
8476               && CONST_INT_P (XEXP (XEXP (incoming, 0), 1)))))
8477     {
8478       HOST_WIDE_INT off = -FIRST_PARM_OFFSET (current_function_decl);
8479       if (GET_CODE (XEXP (incoming, 0)) == PLUS)
8480         off += INTVAL (XEXP (XEXP (incoming, 0), 1));
8481       incoming
8482         = replace_equiv_address_nv (incoming,
8483                                     plus_constant (arg_pointer_rtx, off));
8484     }
8485
8486   if (!vt_get_decl_and_offset (incoming, &decl, &offset))
8487     {
8488       if (REG_P (incoming) || MEM_P (incoming))
8489         {
8490           /* This means argument is passed by invisible reference.  */
8491           offset = 0;
8492           decl = parm;
8493           incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
8494         }
8495       else
8496         {
8497           if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
8498             return;
8499           offset += byte_lowpart_offset (GET_MODE (incoming),
8500                                          GET_MODE (decl_rtl));
8501         }
8502     }
8503
8504   if (!decl)
8505     return;
8506
8507   if (parm != decl)
8508     {
8509       /* Assume that DECL_RTL was a pseudo that got spilled to
8510          memory.  The spill slot sharing code will force the
8511          memory to reference spill_slot_decl (%sfp), so we don't
8512          match above.  That's ok, the pseudo must have referenced
8513          the entire parameter, so just reset OFFSET.  */
8514       gcc_assert (decl == get_spill_slot_decl (false));
8515       offset = 0;
8516     }
8517
8518   if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
8519     return;
8520
8521   out = &VTI (ENTRY_BLOCK_PTR)->out;
8522
8523   dv = dv_from_decl (parm);
8524
8525   if (target_for_debug_bind (parm)
8526       /* We can't deal with these right now, because this kind of
8527          variable is single-part.  ??? We could handle parallels
8528          that describe multiple locations for the same single
8529          value, but ATM we don't.  */
8530       && GET_CODE (incoming) != PARALLEL)
8531     {
8532       cselib_val *val;
8533
8534       /* ??? We shouldn't ever hit this, but it may happen because
8535          arguments passed by invisible reference aren't dealt with
8536          above: incoming-rtl will have Pmode rather than the
8537          expected mode for the type.  */
8538       if (offset)
8539         return;
8540
8541       val = cselib_lookup_from_insn (var_lowpart (mode, incoming), mode, true,
8542                                      VOIDmode, get_insns ());
8543
8544       /* ??? Float-typed values in memory are not handled by
8545          cselib.  */
8546       if (val)
8547         {
8548           preserve_value (val);
8549           set_variable_part (out, val->val_rtx, dv, offset,
8550                              VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
8551           dv = dv_from_value (val->val_rtx);
8552         }
8553     }
8554
8555   if (REG_P (incoming))
8556     {
8557       incoming = var_lowpart (mode, incoming);
8558       gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
8559       attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
8560                          incoming);
8561       set_variable_part (out, incoming, dv, offset,
8562                          VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
8563       if (dv_is_value_p (dv))
8564         {
8565           cselib_val *val = CSELIB_VAL_PTR (dv_as_value (dv));
8566           create_entry_value (incoming, val);
8567           if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE
8568               && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (parm))))
8569             {
8570               enum machine_mode indmode
8571                 = TYPE_MODE (TREE_TYPE (TREE_TYPE (parm)));
8572               rtx mem = gen_rtx_MEM (indmode, incoming);
8573               val = cselib_lookup_from_insn (mem, indmode, true,
8574                                              VOIDmode, get_insns ());
8575               if (val)
8576                 {
8577                   preserve_value (val);
8578                   create_entry_value (mem, val);
8579                 }
8580             }
8581         }
8582     }
8583   else if (MEM_P (incoming))
8584     {
8585       incoming = var_lowpart (mode, incoming);
8586       set_variable_part (out, incoming, dv, offset,
8587                          VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
8588     }
8589 }
8590
8591 /* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */
8592
8593 static void
8594 vt_add_function_parameters (void)
8595 {
8596   tree parm;
8597
8598   for (parm = DECL_ARGUMENTS (current_function_decl);
8599        parm; parm = DECL_CHAIN (parm))
8600     vt_add_function_parameter (parm);
8601
8602   if (DECL_HAS_VALUE_EXPR_P (DECL_RESULT (current_function_decl)))
8603     {
8604       tree vexpr = DECL_VALUE_EXPR (DECL_RESULT (current_function_decl));
8605
8606       if (TREE_CODE (vexpr) == INDIRECT_REF)
8607         vexpr = TREE_OPERAND (vexpr, 0);
8608
8609       if (TREE_CODE (vexpr) == PARM_DECL
8610           && DECL_ARTIFICIAL (vexpr)
8611           && !DECL_IGNORED_P (vexpr)
8612           && DECL_NAMELESS (vexpr))
8613         vt_add_function_parameter (vexpr);
8614     }
8615 }
8616
8617 /* Return true if INSN in the prologue initializes hard_frame_pointer_rtx.  */
8618
8619 static bool
8620 fp_setter (rtx insn)
8621 {
8622   rtx pat = PATTERN (insn);
8623   if (RTX_FRAME_RELATED_P (insn))
8624     {
8625       rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
8626       if (expr)
8627         pat = XEXP (expr, 0);
8628     }
8629   if (GET_CODE (pat) == SET)
8630     return SET_DEST (pat) == hard_frame_pointer_rtx;
8631   else if (GET_CODE (pat) == PARALLEL)
8632     {
8633       int i;
8634       for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
8635         if (GET_CODE (XVECEXP (pat, 0, i)) == SET
8636             && SET_DEST (XVECEXP (pat, 0, i)) == hard_frame_pointer_rtx)
8637           return true;
8638     }
8639   return false;
8640 }
8641
8642 /* Gather all registers used for passing arguments to other functions
8643    called from the current routine.  */
8644
8645 static void
8646 note_register_arguments (rtx insn)
8647 {
8648   rtx link, x;
8649
8650   for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
8651     if (GET_CODE (XEXP (link, 0)) == USE)
8652       {
8653         x = XEXP (XEXP (link, 0), 0);
8654         if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
8655           SET_HARD_REG_BIT (argument_reg_set, REGNO (x));
8656       }
8657 }
8658
8659 /* Initialize cfa_base_rtx, create a preserved VALUE for it and
8660    ensure it isn't flushed during cselib_reset_table.
8661    Can be called only if frame_pointer_rtx resp. arg_pointer_rtx
8662    has been eliminated.  */
8663
8664 static void
8665 vt_init_cfa_base (void)
8666 {
8667   cselib_val *val;
8668
8669 #ifdef FRAME_POINTER_CFA_OFFSET
8670   cfa_base_rtx = frame_pointer_rtx;
8671   cfa_base_offset = -FRAME_POINTER_CFA_OFFSET (current_function_decl);
8672 #else
8673   cfa_base_rtx = arg_pointer_rtx;
8674   cfa_base_offset = -ARG_POINTER_CFA_OFFSET (current_function_decl);
8675 #endif
8676   if (cfa_base_rtx == hard_frame_pointer_rtx
8677       || !fixed_regs[REGNO (cfa_base_rtx)])
8678     {
8679       cfa_base_rtx = NULL_RTX;
8680       return;
8681     }
8682   if (!MAY_HAVE_DEBUG_INSNS)
8683     return;
8684
8685   /* Tell alias analysis that cfa_base_rtx should share
8686      find_base_term value with stack pointer or hard frame pointer.  */
8687   if (!frame_pointer_needed)
8688     vt_equate_reg_base_value (cfa_base_rtx, stack_pointer_rtx);
8689   else if (!crtl->stack_realign_tried)
8690     vt_equate_reg_base_value (cfa_base_rtx, hard_frame_pointer_rtx);
8691
8692   val = cselib_lookup_from_insn (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1,
8693                                  VOIDmode, get_insns ());
8694   preserve_value (val);
8695   cselib_preserve_cfa_base_value (val, REGNO (cfa_base_rtx));
8696   var_reg_decl_set (&VTI (ENTRY_BLOCK_PTR)->out, cfa_base_rtx,
8697                     VAR_INIT_STATUS_INITIALIZED, dv_from_value (val->val_rtx),
8698                     0, NULL_RTX, INSERT);
8699 }
8700
8701 /* Allocate and initialize the data structures for variable tracking
8702    and parse the RTL to get the micro operations.  */
8703
8704 static bool
8705 vt_initialize (void)
8706 {
8707   basic_block bb, prologue_bb = single_succ (ENTRY_BLOCK_PTR);
8708   HOST_WIDE_INT fp_cfa_offset = -1;
8709
8710   alloc_aux_for_blocks (sizeof (struct variable_tracking_info_def));
8711
8712   attrs_pool = create_alloc_pool ("attrs_def pool",
8713                                   sizeof (struct attrs_def), 1024);
8714   var_pool = create_alloc_pool ("variable_def pool",
8715                                 sizeof (struct variable_def)
8716                                 + (MAX_VAR_PARTS - 1)
8717                                 * sizeof (((variable)NULL)->var_part[0]), 64);
8718   loc_chain_pool = create_alloc_pool ("location_chain_def pool",
8719                                       sizeof (struct location_chain_def),
8720                                       1024);
8721   shared_hash_pool = create_alloc_pool ("shared_hash_def pool",
8722                                         sizeof (struct shared_hash_def), 256);
8723   empty_shared_hash = (shared_hash) pool_alloc (shared_hash_pool);
8724   empty_shared_hash->refcount = 1;
8725   empty_shared_hash->htab
8726     = htab_create (1, variable_htab_hash, variable_htab_eq,
8727                    variable_htab_free);
8728   changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
8729                                    variable_htab_free);
8730   if (MAY_HAVE_DEBUG_INSNS)
8731     {
8732       value_chain_pool = create_alloc_pool ("value_chain_def pool",
8733                                             sizeof (struct value_chain_def),
8734                                             1024);
8735       value_chains = htab_create (32, value_chain_htab_hash,
8736                                   value_chain_htab_eq, NULL);
8737     }
8738
8739   /* Init the IN and OUT sets.  */
8740   FOR_ALL_BB (bb)
8741     {
8742       VTI (bb)->visited = false;
8743       VTI (bb)->flooded = false;
8744       dataflow_set_init (&VTI (bb)->in);
8745       dataflow_set_init (&VTI (bb)->out);
8746       VTI (bb)->permp = NULL;
8747     }
8748
8749   if (MAY_HAVE_DEBUG_INSNS)
8750     {
8751       cselib_init (CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS);
8752       scratch_regs = BITMAP_ALLOC (NULL);
8753       valvar_pool = create_alloc_pool ("small variable_def pool",
8754                                        sizeof (struct variable_def), 256);
8755       preserved_values = VEC_alloc (rtx, heap, 256);
8756     }
8757   else
8758     {
8759       scratch_regs = NULL;
8760       valvar_pool = NULL;
8761     }
8762
8763   CLEAR_HARD_REG_SET (argument_reg_set);
8764
8765   /* In order to factor out the adjustments made to the stack pointer or to
8766      the hard frame pointer and thus be able to use DW_OP_fbreg operations
8767      instead of individual location lists, we're going to rewrite MEMs based
8768      on them into MEMs based on the CFA by de-eliminating stack_pointer_rtx
8769      or hard_frame_pointer_rtx to the virtual CFA pointer frame_pointer_rtx
8770      resp. arg_pointer_rtx.  We can do this either when there is no frame
8771      pointer in the function and stack adjustments are consistent for all
8772      basic blocks or when there is a frame pointer and no stack realignment.
8773      But we first have to check that frame_pointer_rtx resp. arg_pointer_rtx
8774      has been eliminated.  */
8775   if (!frame_pointer_needed)
8776     {
8777       rtx reg, elim;
8778
8779       if (!vt_stack_adjustments ())
8780         return false;
8781
8782 #ifdef FRAME_POINTER_CFA_OFFSET
8783       reg = frame_pointer_rtx;
8784 #else
8785       reg = arg_pointer_rtx;
8786 #endif
8787       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
8788       if (elim != reg)
8789         {
8790           if (GET_CODE (elim) == PLUS)
8791             elim = XEXP (elim, 0);
8792           if (elim == stack_pointer_rtx)
8793             vt_init_cfa_base ();
8794         }
8795     }
8796   else if (!crtl->stack_realign_tried)
8797     {
8798       rtx reg, elim;
8799
8800 #ifdef FRAME_POINTER_CFA_OFFSET
8801       reg = frame_pointer_rtx;
8802       fp_cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
8803 #else
8804       reg = arg_pointer_rtx;
8805       fp_cfa_offset = ARG_POINTER_CFA_OFFSET (current_function_decl);
8806 #endif
8807       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
8808       if (elim != reg)
8809         {
8810           if (GET_CODE (elim) == PLUS)
8811             {
8812               fp_cfa_offset -= INTVAL (XEXP (elim, 1));
8813               elim = XEXP (elim, 0);
8814             }
8815           if (elim != hard_frame_pointer_rtx)
8816             fp_cfa_offset = -1;
8817         }
8818       else
8819         fp_cfa_offset = -1;
8820     }
8821
8822   /* If the stack is realigned and a DRAP register is used, we're going to
8823      rewrite MEMs based on it representing incoming locations of parameters
8824      passed on the stack into MEMs based on the argument pointer.  Although
8825      we aren't going to rewrite other MEMs, we still need to initialize the
8826      virtual CFA pointer in order to ensure that the argument pointer will
8827      be seen as a constant throughout the function.
8828
8829      ??? This doesn't work if FRAME_POINTER_CFA_OFFSET is defined.  */
8830   else if (stack_realign_drap)
8831     {
8832       rtx reg, elim;
8833
8834 #ifdef FRAME_POINTER_CFA_OFFSET
8835       reg = frame_pointer_rtx;
8836 #else
8837       reg = arg_pointer_rtx;
8838 #endif
8839       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
8840       if (elim != reg)
8841         {
8842           if (GET_CODE (elim) == PLUS)
8843             elim = XEXP (elim, 0);
8844           if (elim == hard_frame_pointer_rtx)
8845             vt_init_cfa_base ();
8846         }
8847     }
8848
8849   if (frame_pointer_needed)
8850     {
8851       rtx insn;
8852       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8853         if (CALL_P (insn))
8854           note_register_arguments (insn);
8855     }
8856
8857   hard_frame_pointer_adjustment = -1;
8858
8859   vt_add_function_parameters ();
8860
8861   FOR_EACH_BB (bb)
8862     {
8863       rtx insn;
8864       HOST_WIDE_INT pre, post = 0;
8865       basic_block first_bb, last_bb;
8866
8867       if (MAY_HAVE_DEBUG_INSNS)
8868         {
8869           cselib_record_sets_hook = add_with_sets;
8870           if (dump_file && (dump_flags & TDF_DETAILS))
8871             fprintf (dump_file, "first value: %i\n",
8872                      cselib_get_next_uid ());
8873         }
8874
8875       first_bb = bb;
8876       for (;;)
8877         {
8878           edge e;
8879           if (bb->next_bb == EXIT_BLOCK_PTR
8880               || ! single_pred_p (bb->next_bb))
8881             break;
8882           e = find_edge (bb, bb->next_bb);
8883           if (! e || (e->flags & EDGE_FALLTHRU) == 0)
8884             break;
8885           bb = bb->next_bb;
8886         }
8887       last_bb = bb;
8888
8889       /* Add the micro-operations to the vector.  */
8890       FOR_BB_BETWEEN (bb, first_bb, last_bb->next_bb, next_bb)
8891         {
8892           HOST_WIDE_INT offset = VTI (bb)->out.stack_adjust;
8893           VTI (bb)->out.stack_adjust = VTI (bb)->in.stack_adjust;
8894           for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
8895                insn = NEXT_INSN (insn))
8896             {
8897               if (INSN_P (insn))
8898                 {
8899                   if (!frame_pointer_needed)
8900                     {
8901                       insn_stack_adjust_offset_pre_post (insn, &pre, &post);
8902                       if (pre)
8903                         {
8904                           micro_operation mo;
8905                           mo.type = MO_ADJUST;
8906                           mo.u.adjust = pre;
8907                           mo.insn = insn;
8908                           if (dump_file && (dump_flags & TDF_DETAILS))
8909                             log_op_type (PATTERN (insn), bb, insn,
8910                                          MO_ADJUST, dump_file);
8911                           VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
8912                                          &mo);
8913                           VTI (bb)->out.stack_adjust += pre;
8914                         }
8915                     }
8916
8917                   cselib_hook_called = false;
8918                   adjust_insn (bb, insn);
8919                   if (MAY_HAVE_DEBUG_INSNS)
8920                     {
8921                       if (CALL_P (insn))
8922                         prepare_call_arguments (bb, insn);
8923                       cselib_process_insn (insn);
8924                       if (dump_file && (dump_flags & TDF_DETAILS))
8925                         {
8926                           print_rtl_single (dump_file, insn);
8927                           dump_cselib_table (dump_file);
8928                         }
8929                     }
8930                   if (!cselib_hook_called)
8931                     add_with_sets (insn, 0, 0);
8932                   cancel_changes (0);
8933
8934                   if (!frame_pointer_needed && post)
8935                     {
8936                       micro_operation mo;
8937                       mo.type = MO_ADJUST;
8938                       mo.u.adjust = post;
8939                       mo.insn = insn;
8940                       if (dump_file && (dump_flags & TDF_DETAILS))
8941                         log_op_type (PATTERN (insn), bb, insn,
8942                                      MO_ADJUST, dump_file);
8943                       VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
8944                                      &mo);
8945                       VTI (bb)->out.stack_adjust += post;
8946                     }
8947
8948                   if (bb == prologue_bb
8949                       && fp_cfa_offset != -1
8950                       && hard_frame_pointer_adjustment == -1
8951                       && RTX_FRAME_RELATED_P (insn)
8952                       && fp_setter (insn))
8953                     {
8954                       vt_init_cfa_base ();
8955                       hard_frame_pointer_adjustment = fp_cfa_offset;
8956                     }
8957                 }
8958             }
8959           gcc_assert (offset == VTI (bb)->out.stack_adjust);
8960         }
8961
8962       bb = last_bb;
8963
8964       if (MAY_HAVE_DEBUG_INSNS)
8965         {
8966           cselib_preserve_only_values ();
8967           cselib_reset_table (cselib_get_next_uid ());
8968           cselib_record_sets_hook = NULL;
8969         }
8970     }
8971
8972   hard_frame_pointer_adjustment = -1;
8973   VTI (ENTRY_BLOCK_PTR)->flooded = true;
8974   cfa_base_rtx = NULL_RTX;
8975   return true;
8976 }
8977
8978 /* Get rid of all debug insns from the insn stream.  */
8979
8980 static void
8981 delete_debug_insns (void)
8982 {
8983   basic_block bb;
8984   rtx insn, next;
8985
8986   if (!MAY_HAVE_DEBUG_INSNS)
8987     return;
8988
8989   FOR_EACH_BB (bb)
8990     {
8991       FOR_BB_INSNS_SAFE (bb, insn, next)
8992         if (DEBUG_INSN_P (insn))
8993           delete_insn (insn);
8994     }
8995 }
8996
8997 /* Run a fast, BB-local only version of var tracking, to take care of
8998    information that we don't do global analysis on, such that not all
8999    information is lost.  If SKIPPED holds, we're skipping the global
9000    pass entirely, so we should try to use information it would have
9001    handled as well..  */
9002
9003 static void
9004 vt_debug_insns_local (bool skipped ATTRIBUTE_UNUSED)
9005 {
9006   /* ??? Just skip it all for now.  */
9007   delete_debug_insns ();
9008 }
9009
9010 /* Free the data structures needed for variable tracking.  */
9011
9012 static void
9013 vt_finalize (void)
9014 {
9015   basic_block bb;
9016
9017   FOR_EACH_BB (bb)
9018     {
9019       VEC_free (micro_operation, heap, VTI (bb)->mos);
9020     }
9021
9022   FOR_ALL_BB (bb)
9023     {
9024       dataflow_set_destroy (&VTI (bb)->in);
9025       dataflow_set_destroy (&VTI (bb)->out);
9026       if (VTI (bb)->permp)
9027         {
9028           dataflow_set_destroy (VTI (bb)->permp);
9029           XDELETE (VTI (bb)->permp);
9030         }
9031     }
9032   free_aux_for_blocks ();
9033   htab_delete (empty_shared_hash->htab);
9034   htab_delete (changed_variables);
9035   free_alloc_pool (attrs_pool);
9036   free_alloc_pool (var_pool);
9037   free_alloc_pool (loc_chain_pool);
9038   free_alloc_pool (shared_hash_pool);
9039
9040   if (MAY_HAVE_DEBUG_INSNS)
9041     {
9042       htab_delete (value_chains);
9043       free_alloc_pool (value_chain_pool);
9044       free_alloc_pool (valvar_pool);
9045       VEC_free (rtx, heap, preserved_values);
9046       cselib_finish ();
9047       BITMAP_FREE (scratch_regs);
9048       scratch_regs = NULL;
9049     }
9050
9051   if (vui_vec)
9052     XDELETEVEC (vui_vec);
9053   vui_vec = NULL;
9054   vui_allocated = 0;
9055 }
9056
9057 /* The entry point to variable tracking pass.  */
9058
9059 static inline unsigned int
9060 variable_tracking_main_1 (void)
9061 {
9062   bool success;
9063
9064   if (flag_var_tracking_assignments < 0)
9065     {
9066       delete_debug_insns ();
9067       return 0;
9068     }
9069
9070   if (n_basic_blocks > 500 && n_edges / n_basic_blocks >= 20)
9071     {
9072       vt_debug_insns_local (true);
9073       return 0;
9074     }
9075
9076   mark_dfs_back_edges ();
9077   if (!vt_initialize ())
9078     {
9079       vt_finalize ();
9080       vt_debug_insns_local (true);
9081       return 0;
9082     }
9083
9084   success = vt_find_locations ();
9085
9086   if (!success && flag_var_tracking_assignments > 0)
9087     {
9088       vt_finalize ();
9089
9090       delete_debug_insns ();
9091
9092       /* This is later restored by our caller.  */
9093       flag_var_tracking_assignments = 0;
9094
9095       success = vt_initialize ();
9096       gcc_assert (success);
9097
9098       success = vt_find_locations ();
9099     }
9100
9101   if (!success)
9102     {
9103       vt_finalize ();
9104       vt_debug_insns_local (false);
9105       return 0;
9106     }
9107
9108   if (dump_file && (dump_flags & TDF_DETAILS))
9109     {
9110       dump_dataflow_sets ();
9111       dump_flow_info (dump_file, dump_flags);
9112     }
9113
9114   timevar_push (TV_VAR_TRACKING_EMIT);
9115   vt_emit_notes ();
9116   timevar_pop (TV_VAR_TRACKING_EMIT);
9117
9118   vt_finalize ();
9119   vt_debug_insns_local (false);
9120   return 0;
9121 }
9122
9123 unsigned int
9124 variable_tracking_main (void)
9125 {
9126   unsigned int ret;
9127   int save = flag_var_tracking_assignments;
9128
9129   ret = variable_tracking_main_1 ();
9130
9131   flag_var_tracking_assignments = save;
9132
9133   return ret;
9134 }
9135 \f
9136 static bool
9137 gate_handle_var_tracking (void)
9138 {
9139   return (flag_var_tracking && !targetm.delay_vartrack);
9140 }
9141
9142
9143
9144 struct rtl_opt_pass pass_variable_tracking =
9145 {
9146  {
9147   RTL_PASS,
9148   "vartrack",                           /* name */
9149   gate_handle_var_tracking,             /* gate */
9150   variable_tracking_main,               /* execute */
9151   NULL,                                 /* sub */
9152   NULL,                                 /* next */
9153   0,                                    /* static_pass_number */
9154   TV_VAR_TRACKING,                      /* tv_id */
9155   0,                                    /* properties_required */
9156   0,                                    /* properties_provided */
9157   0,                                    /* properties_destroyed */
9158   0,                                    /* todo_flags_start */
9159   TODO_verify_rtl_sharing               /* todo_flags_finish */
9160  }
9161 };