OSDN Git Service

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