OSDN Git Service

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