OSDN Git Service

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