OSDN Git Service

Fix for PR debug/43325
[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 int vars_copy_1 (void **, void *);
425 static void vars_copy (htab_t, htab_t);
426 static tree var_debug_decl (tree);
427 static void var_reg_set (dataflow_set *, rtx, enum var_init_status, rtx);
428 static void var_reg_delete_and_set (dataflow_set *, rtx, bool,
429                                     enum var_init_status, rtx);
430 static void var_reg_delete (dataflow_set *, rtx, bool);
431 static void var_regno_delete (dataflow_set *, int);
432 static void var_mem_set (dataflow_set *, rtx, enum var_init_status, rtx);
433 static void var_mem_delete_and_set (dataflow_set *, rtx, bool,
434                                     enum var_init_status, rtx);
435 static void var_mem_delete (dataflow_set *, rtx, bool);
436
437 static void dataflow_set_init (dataflow_set *);
438 static void dataflow_set_clear (dataflow_set *);
439 static void dataflow_set_copy (dataflow_set *, dataflow_set *);
440 static int variable_union_info_cmp_pos (const void *, const void *);
441 static int variable_union (void **, void *);
442 static void dataflow_set_union (dataflow_set *, dataflow_set *);
443 static location_chain find_loc_in_1pdv (rtx, variable, htab_t);
444 static bool canon_value_cmp (rtx, rtx);
445 static int loc_cmp (rtx, rtx);
446 static bool variable_part_different_p (variable_part *, variable_part *);
447 static bool onepart_variable_different_p (variable, variable);
448 static bool variable_different_p (variable, variable);
449 static int dataflow_set_different_1 (void **, void *);
450 static bool dataflow_set_different (dataflow_set *, dataflow_set *);
451 static void dataflow_set_destroy (dataflow_set *);
452
453 static bool contains_symbol_ref (rtx);
454 static bool track_expr_p (tree, bool);
455 static bool same_variable_part_p (rtx, tree, HOST_WIDE_INT);
456 static int add_uses (rtx *, void *);
457 static void add_uses_1 (rtx *, void *);
458 static void add_stores (rtx, const_rtx, void *);
459 static bool compute_bb_dataflow (basic_block);
460 static bool vt_find_locations (void);
461
462 static void dump_attrs_list (attrs);
463 static int dump_var_slot (void **, void *);
464 static void dump_var (variable);
465 static void dump_vars (htab_t);
466 static void dump_dataflow_set (dataflow_set *);
467 static void dump_dataflow_sets (void);
468
469 static void variable_was_changed (variable, dataflow_set *);
470 static void **set_slot_part (dataflow_set *, rtx, void **,
471                              decl_or_value, HOST_WIDE_INT,
472                              enum var_init_status, rtx);
473 static void set_variable_part (dataflow_set *, rtx,
474                                decl_or_value, HOST_WIDE_INT,
475                                enum var_init_status, rtx, enum insert_option);
476 static void **clobber_slot_part (dataflow_set *, rtx,
477                                  void **, HOST_WIDE_INT, rtx);
478 static void clobber_variable_part (dataflow_set *, rtx,
479                                    decl_or_value, HOST_WIDE_INT, rtx);
480 static void **delete_slot_part (dataflow_set *, rtx, void **, HOST_WIDE_INT);
481 static void delete_variable_part (dataflow_set *, rtx,
482                                   decl_or_value, HOST_WIDE_INT);
483 static int emit_note_insn_var_location (void **, void *);
484 static void emit_notes_for_changes (rtx, enum emit_note_where, shared_hash);
485 static int emit_notes_for_differences_1 (void **, void *);
486 static int emit_notes_for_differences_2 (void **, void *);
487 static void emit_notes_for_differences (rtx, dataflow_set *, dataflow_set *);
488 static void emit_notes_in_bb (basic_block, dataflow_set *);
489 static void vt_emit_notes (void);
490
491 static bool vt_get_decl_and_offset (rtx, tree *, HOST_WIDE_INT *);
492 static void vt_add_function_parameters (void);
493 static bool vt_initialize (void);
494 static void vt_finalize (void);
495
496 /* Given a SET, calculate the amount of stack adjustment it contains
497    PRE- and POST-modifying stack pointer.
498    This function is similar to stack_adjust_offset.  */
499
500 static void
501 stack_adjust_offset_pre_post (rtx pattern, HOST_WIDE_INT *pre,
502                               HOST_WIDE_INT *post)
503 {
504   rtx src = SET_SRC (pattern);
505   rtx dest = SET_DEST (pattern);
506   enum rtx_code code;
507
508   if (dest == stack_pointer_rtx)
509     {
510       /* (set (reg sp) (plus (reg sp) (const_int))) */
511       code = GET_CODE (src);
512       if (! (code == PLUS || code == MINUS)
513           || XEXP (src, 0) != stack_pointer_rtx
514           || !CONST_INT_P (XEXP (src, 1)))
515         return;
516
517       if (code == MINUS)
518         *post += INTVAL (XEXP (src, 1));
519       else
520         *post -= INTVAL (XEXP (src, 1));
521     }
522   else if (MEM_P (dest))
523     {
524       /* (set (mem (pre_dec (reg sp))) (foo)) */
525       src = XEXP (dest, 0);
526       code = GET_CODE (src);
527
528       switch (code)
529         {
530         case PRE_MODIFY:
531         case POST_MODIFY:
532           if (XEXP (src, 0) == stack_pointer_rtx)
533             {
534               rtx val = XEXP (XEXP (src, 1), 1);
535               /* We handle only adjustments by constant amount.  */
536               gcc_assert (GET_CODE (XEXP (src, 1)) == PLUS &&
537                           CONST_INT_P (val));
538
539               if (code == PRE_MODIFY)
540                 *pre -= INTVAL (val);
541               else
542                 *post -= INTVAL (val);
543               break;
544             }
545           return;
546
547         case PRE_DEC:
548           if (XEXP (src, 0) == stack_pointer_rtx)
549             {
550               *pre += GET_MODE_SIZE (GET_MODE (dest));
551               break;
552             }
553           return;
554
555         case POST_DEC:
556           if (XEXP (src, 0) == stack_pointer_rtx)
557             {
558               *post += GET_MODE_SIZE (GET_MODE (dest));
559               break;
560             }
561           return;
562
563         case PRE_INC:
564           if (XEXP (src, 0) == stack_pointer_rtx)
565             {
566               *pre -= GET_MODE_SIZE (GET_MODE (dest));
567               break;
568             }
569           return;
570
571         case POST_INC:
572           if (XEXP (src, 0) == stack_pointer_rtx)
573             {
574               *post -= GET_MODE_SIZE (GET_MODE (dest));
575               break;
576             }
577           return;
578
579         default:
580           return;
581         }
582     }
583 }
584
585 /* Given an INSN, calculate the amount of stack adjustment it contains
586    PRE- and POST-modifying stack pointer.  */
587
588 static void
589 insn_stack_adjust_offset_pre_post (rtx insn, HOST_WIDE_INT *pre,
590                                    HOST_WIDE_INT *post)
591 {
592   rtx pattern;
593
594   *pre = 0;
595   *post = 0;
596
597   pattern = PATTERN (insn);
598   if (RTX_FRAME_RELATED_P (insn))
599     {
600       rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
601       if (expr)
602         pattern = XEXP (expr, 0);
603     }
604
605   if (GET_CODE (pattern) == SET)
606     stack_adjust_offset_pre_post (pattern, pre, post);
607   else if (GET_CODE (pattern) == PARALLEL
608            || GET_CODE (pattern) == SEQUENCE)
609     {
610       int i;
611
612       /* There may be stack adjustments inside compound insns.  Search
613          for them.  */
614       for ( i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
615         if (GET_CODE (XVECEXP (pattern, 0, i)) == SET)
616           stack_adjust_offset_pre_post (XVECEXP (pattern, 0, i), pre, post);
617     }
618 }
619
620 /* Compute stack adjustments for all blocks by traversing DFS tree.
621    Return true when the adjustments on all incoming edges are consistent.
622    Heavily borrowed from pre_and_rev_post_order_compute.  */
623
624 static bool
625 vt_stack_adjustments (void)
626 {
627   edge_iterator *stack;
628   int sp;
629
630   /* Initialize entry block.  */
631   VTI (ENTRY_BLOCK_PTR)->visited = true;
632   VTI (ENTRY_BLOCK_PTR)->in.stack_adjust = INCOMING_FRAME_SP_OFFSET;
633   VTI (ENTRY_BLOCK_PTR)->out.stack_adjust = INCOMING_FRAME_SP_OFFSET;
634
635   /* Allocate stack for back-tracking up CFG.  */
636   stack = XNEWVEC (edge_iterator, n_basic_blocks + 1);
637   sp = 0;
638
639   /* Push the first edge on to the stack.  */
640   stack[sp++] = ei_start (ENTRY_BLOCK_PTR->succs);
641
642   while (sp)
643     {
644       edge_iterator ei;
645       basic_block src;
646       basic_block dest;
647
648       /* Look at the edge on the top of the stack.  */
649       ei = stack[sp - 1];
650       src = ei_edge (ei)->src;
651       dest = ei_edge (ei)->dest;
652
653       /* Check if the edge destination has been visited yet.  */
654       if (!VTI (dest)->visited)
655         {
656           rtx insn;
657           HOST_WIDE_INT pre, post, offset;
658           VTI (dest)->visited = true;
659           VTI (dest)->in.stack_adjust = offset = VTI (src)->out.stack_adjust;
660
661           if (dest != EXIT_BLOCK_PTR)
662             for (insn = BB_HEAD (dest);
663                  insn != NEXT_INSN (BB_END (dest));
664                  insn = NEXT_INSN (insn))
665               if (INSN_P (insn))
666                 {
667                   insn_stack_adjust_offset_pre_post (insn, &pre, &post);
668                   offset += pre + post;
669                 }
670
671           VTI (dest)->out.stack_adjust = offset;
672
673           if (EDGE_COUNT (dest->succs) > 0)
674             /* Since the DEST node has been visited for the first
675                time, check its successors.  */
676             stack[sp++] = ei_start (dest->succs);
677         }
678       else
679         {
680           /* Check whether the adjustments on the edges are the same.  */
681           if (VTI (dest)->in.stack_adjust != VTI (src)->out.stack_adjust)
682             {
683               free (stack);
684               return false;
685             }
686
687           if (! ei_one_before_end_p (ei))
688             /* Go to the next edge.  */
689             ei_next (&stack[sp - 1]);
690           else
691             /* Return to previous level if there are no more edges.  */
692             sp--;
693         }
694     }
695
696   free (stack);
697   return true;
698 }
699
700 /* Compute a CFA-based value for the stack pointer.  */
701
702 static rtx
703 compute_cfa_pointer (HOST_WIDE_INT adjustment)
704 {
705   rtx cfa;
706
707 #ifdef FRAME_POINTER_CFA_OFFSET
708   adjustment -= FRAME_POINTER_CFA_OFFSET (current_function_decl);
709   cfa = plus_constant (frame_pointer_rtx, adjustment);
710 #else
711   adjustment -= ARG_POINTER_CFA_OFFSET (current_function_decl);
712   cfa = plus_constant (arg_pointer_rtx, adjustment);
713 #endif
714
715   return cfa;
716 }
717
718 /* Adjustment for hard_frame_pointer_rtx to cfa base reg,
719    or -1 if the replacement shouldn't be done.  */
720 static HOST_WIDE_INT hard_frame_pointer_adjustment = -1;
721
722 /* Data for adjust_mems callback.  */
723
724 struct adjust_mem_data
725 {
726   bool store;
727   enum machine_mode mem_mode;
728   HOST_WIDE_INT stack_adjust;
729   rtx side_effects;
730 };
731
732 /* Helper for adjust_mems.  Return 1 if *loc is unsuitable for
733    transformation of wider mode arithmetics to narrower mode,
734    -1 if it is suitable and subexpressions shouldn't be
735    traversed and 0 if it is suitable and subexpressions should
736    be traversed.  Called through for_each_rtx.  */
737
738 static int
739 use_narrower_mode_test (rtx *loc, void *data)
740 {
741   rtx subreg = (rtx) data;
742
743   if (CONSTANT_P (*loc))
744     return -1;
745   switch (GET_CODE (*loc))
746     {
747     case REG:
748       if (cselib_lookup (*loc, GET_MODE (SUBREG_REG (subreg)), 0))
749         return 1;
750       return -1;
751     case PLUS:
752     case MINUS:
753     case MULT:
754       return 0;
755     case ASHIFT:
756       if (for_each_rtx (&XEXP (*loc, 0), use_narrower_mode_test, data))
757         return 1;
758       else
759         return -1;
760     default:
761       return 1;
762     }
763 }
764
765 /* Transform X into narrower mode MODE from wider mode WMODE.  */
766
767 static rtx
768 use_narrower_mode (rtx x, enum machine_mode mode, enum machine_mode wmode)
769 {
770   rtx op0, op1;
771   if (CONSTANT_P (x))
772     return lowpart_subreg (mode, x, wmode);
773   switch (GET_CODE (x))
774     {
775     case REG:
776       return lowpart_subreg (mode, x, wmode);
777     case PLUS:
778     case MINUS:
779     case MULT:
780       op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
781       op1 = use_narrower_mode (XEXP (x, 1), mode, wmode);
782       return simplify_gen_binary (GET_CODE (x), mode, op0, op1);
783     case ASHIFT:
784       op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
785       return simplify_gen_binary (ASHIFT, mode, op0, XEXP (x, 1));
786     default:
787       gcc_unreachable ();
788     }
789 }
790
791 /* Helper function for adjusting used MEMs.  */
792
793 static rtx
794 adjust_mems (rtx loc, const_rtx old_rtx, void *data)
795 {
796   struct adjust_mem_data *amd = (struct adjust_mem_data *) data;
797   rtx mem, addr = loc, tem;
798   enum machine_mode mem_mode_save;
799   bool store_save;
800   switch (GET_CODE (loc))
801     {
802     case REG:
803       /* Don't do any sp or fp replacements outside of MEM addresses.  */
804       if (amd->mem_mode == VOIDmode)
805         return loc;
806       if (loc == stack_pointer_rtx
807           && !frame_pointer_needed)
808         return compute_cfa_pointer (amd->stack_adjust);
809       else if (loc == hard_frame_pointer_rtx
810                && frame_pointer_needed
811                && hard_frame_pointer_adjustment != -1)
812         return compute_cfa_pointer (hard_frame_pointer_adjustment);
813       return loc;
814     case MEM:
815       mem = loc;
816       if (!amd->store)
817         {
818           mem = targetm.delegitimize_address (mem);
819           if (mem != loc && !MEM_P (mem))
820             return simplify_replace_fn_rtx (mem, old_rtx, adjust_mems, data);
821         }
822
823       addr = XEXP (mem, 0);
824       mem_mode_save = amd->mem_mode;
825       amd->mem_mode = GET_MODE (mem);
826       store_save = amd->store;
827       amd->store = false;
828       addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
829       amd->store = store_save;
830       amd->mem_mode = mem_mode_save;
831       if (mem == loc)
832         addr = targetm.delegitimize_address (addr);
833       if (addr != XEXP (mem, 0))
834         mem = replace_equiv_address_nv (mem, addr);
835       if (!amd->store)
836         mem = avoid_constant_pool_reference (mem);
837       return mem;
838     case PRE_INC:
839     case PRE_DEC:
840       addr = gen_rtx_PLUS (GET_MODE (loc), XEXP (loc, 0),
841                            GEN_INT (GET_CODE (loc) == PRE_INC
842                                     ? GET_MODE_SIZE (amd->mem_mode)
843                                     : -GET_MODE_SIZE (amd->mem_mode)));
844     case POST_INC:
845     case POST_DEC:
846       if (addr == loc)
847         addr = XEXP (loc, 0);
848       gcc_assert (amd->mem_mode != VOIDmode && amd->mem_mode != BLKmode);
849       addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
850       tem = gen_rtx_PLUS (GET_MODE (loc), XEXP (loc, 0),
851                            GEN_INT ((GET_CODE (loc) == PRE_INC
852                                      || GET_CODE (loc) == POST_INC)
853                                     ? GET_MODE_SIZE (amd->mem_mode)
854                                     : -GET_MODE_SIZE (amd->mem_mode)));
855       amd->side_effects = alloc_EXPR_LIST (0,
856                                            gen_rtx_SET (VOIDmode,
857                                                         XEXP (loc, 0),
858                                                         tem),
859                                            amd->side_effects);
860       return addr;
861     case PRE_MODIFY:
862       addr = XEXP (loc, 1);
863     case POST_MODIFY:
864       if (addr == loc)
865         addr = XEXP (loc, 0);
866       gcc_assert (amd->mem_mode != VOIDmode);
867       addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
868       amd->side_effects = alloc_EXPR_LIST (0,
869                                            gen_rtx_SET (VOIDmode,
870                                                         XEXP (loc, 0),
871                                                         XEXP (loc, 1)),
872                                            amd->side_effects);
873       return addr;
874     case SUBREG:
875       /* First try without delegitimization of whole MEMs and
876          avoid_constant_pool_reference, which is more likely to succeed.  */
877       store_save = amd->store;
878       amd->store = true;
879       addr = simplify_replace_fn_rtx (SUBREG_REG (loc), old_rtx, adjust_mems,
880                                       data);
881       amd->store = store_save;
882       mem = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
883       if (mem == SUBREG_REG (loc))
884         {
885           tem = loc;
886           goto finish_subreg;
887         }
888       tem = simplify_gen_subreg (GET_MODE (loc), mem,
889                                  GET_MODE (SUBREG_REG (loc)),
890                                  SUBREG_BYTE (loc));
891       if (tem)
892         goto finish_subreg;
893       tem = simplify_gen_subreg (GET_MODE (loc), addr,
894                                  GET_MODE (SUBREG_REG (loc)),
895                                  SUBREG_BYTE (loc));
896       if (tem == NULL_RTX)
897         tem = gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc));
898     finish_subreg:
899       if (MAY_HAVE_DEBUG_INSNS
900           && GET_CODE (tem) == SUBREG
901           && (GET_CODE (SUBREG_REG (tem)) == PLUS
902               || GET_CODE (SUBREG_REG (tem)) == MINUS
903               || GET_CODE (SUBREG_REG (tem)) == MULT
904               || GET_CODE (SUBREG_REG (tem)) == ASHIFT)
905           && GET_MODE_CLASS (GET_MODE (tem)) == MODE_INT
906           && GET_MODE_CLASS (GET_MODE (SUBREG_REG (tem))) == MODE_INT
907           && GET_MODE_SIZE (GET_MODE (tem))
908              < GET_MODE_SIZE (GET_MODE (SUBREG_REG (tem)))
909           && subreg_lowpart_p (tem)
910           && !for_each_rtx (&SUBREG_REG (tem), use_narrower_mode_test, tem))
911         return use_narrower_mode (SUBREG_REG (tem), GET_MODE (tem),
912                                   GET_MODE (SUBREG_REG (tem)));
913       return tem;
914     default:
915       break;
916     }
917   return NULL_RTX;
918 }
919
920 /* Helper function for replacement of uses.  */
921
922 static void
923 adjust_mem_uses (rtx *x, void *data)
924 {
925   rtx new_x = simplify_replace_fn_rtx (*x, NULL_RTX, adjust_mems, data);
926   if (new_x != *x)
927     validate_change (NULL_RTX, x, new_x, true);
928 }
929
930 /* Helper function for replacement of stores.  */
931
932 static void
933 adjust_mem_stores (rtx loc, const_rtx expr, void *data)
934 {
935   if (MEM_P (loc))
936     {
937       rtx new_dest = simplify_replace_fn_rtx (SET_DEST (expr), NULL_RTX,
938                                               adjust_mems, data);
939       if (new_dest != SET_DEST (expr))
940         {
941           rtx xexpr = CONST_CAST_RTX (expr);
942           validate_change (NULL_RTX, &SET_DEST (xexpr), new_dest, true);
943         }
944     }
945 }
946
947 /* Simplify INSN.  Remove all {PRE,POST}_{INC,DEC,MODIFY} rtxes,
948    replace them with their value in the insn and add the side-effects
949    as other sets to the insn.  */
950
951 static void
952 adjust_insn (basic_block bb, rtx insn)
953 {
954   struct adjust_mem_data amd;
955   rtx set;
956   amd.mem_mode = VOIDmode;
957   amd.stack_adjust = -VTI (bb)->out.stack_adjust;
958   amd.side_effects = NULL_RTX;
959
960   amd.store = true;
961   note_stores (PATTERN (insn), adjust_mem_stores, &amd);
962
963   amd.store = false;
964   note_uses (&PATTERN (insn), adjust_mem_uses, &amd);
965
966   /* For read-only MEMs containing some constant, prefer those
967      constants.  */
968   set = single_set (insn);
969   if (set && MEM_P (SET_SRC (set)) && MEM_READONLY_P (SET_SRC (set)))
970     {
971       rtx note = find_reg_equal_equiv_note (insn);
972
973       if (note && CONSTANT_P (XEXP (note, 0)))
974         validate_change (NULL_RTX, &SET_SRC (set), XEXP (note, 0), true);
975     }
976
977   if (amd.side_effects)
978     {
979       rtx *pat, new_pat, s;
980       int i, oldn, newn;
981
982       pat = &PATTERN (insn);
983       if (GET_CODE (*pat) == COND_EXEC)
984         pat = &COND_EXEC_CODE (*pat);
985       if (GET_CODE (*pat) == PARALLEL)
986         oldn = XVECLEN (*pat, 0);
987       else
988         oldn = 1;
989       for (s = amd.side_effects, newn = 0; s; newn++)
990         s = XEXP (s, 1);
991       new_pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (oldn + newn));
992       if (GET_CODE (*pat) == PARALLEL)
993         for (i = 0; i < oldn; i++)
994           XVECEXP (new_pat, 0, i) = XVECEXP (*pat, 0, i);
995       else
996         XVECEXP (new_pat, 0, 0) = *pat;
997       for (s = amd.side_effects, i = oldn; i < oldn + newn; i++, s = XEXP (s, 1))
998         XVECEXP (new_pat, 0, i) = XEXP (s, 0);
999       free_EXPR_LIST_list (&amd.side_effects);
1000       validate_change (NULL_RTX, pat, new_pat, true);
1001     }
1002 }
1003
1004 /* Return true if a decl_or_value DV is a DECL or NULL.  */
1005 static inline bool
1006 dv_is_decl_p (decl_or_value dv)
1007 {
1008   return !dv || (int) TREE_CODE ((tree) dv) != (int) VALUE;
1009 }
1010
1011 /* Return true if a decl_or_value is a VALUE rtl.  */
1012 static inline bool
1013 dv_is_value_p (decl_or_value dv)
1014 {
1015   return dv && !dv_is_decl_p (dv);
1016 }
1017
1018 /* Return the decl in the decl_or_value.  */
1019 static inline tree
1020 dv_as_decl (decl_or_value dv)
1021 {
1022 #ifdef ENABLE_CHECKING
1023   gcc_assert (dv_is_decl_p (dv));
1024 #endif
1025   return (tree) dv;
1026 }
1027
1028 /* Return the value in the decl_or_value.  */
1029 static inline rtx
1030 dv_as_value (decl_or_value dv)
1031 {
1032 #ifdef ENABLE_CHECKING
1033   gcc_assert (dv_is_value_p (dv));
1034 #endif
1035   return (rtx)dv;
1036 }
1037
1038 /* Return the opaque pointer in the decl_or_value.  */
1039 static inline void *
1040 dv_as_opaque (decl_or_value dv)
1041 {
1042   return dv;
1043 }
1044
1045 /* Return true if a decl_or_value must not have more than one variable
1046    part.  */
1047 static inline bool
1048 dv_onepart_p (decl_or_value dv)
1049 {
1050   tree decl;
1051
1052   if (!MAY_HAVE_DEBUG_INSNS)
1053     return false;
1054
1055   if (dv_is_value_p (dv))
1056     return true;
1057
1058   decl = dv_as_decl (dv);
1059
1060   if (!decl)
1061     return true;
1062
1063   if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
1064     return true;
1065
1066   return (target_for_debug_bind (decl) != NULL_TREE);
1067 }
1068
1069 /* Return the variable pool to be used for dv, depending on whether it
1070    can have multiple parts or not.  */
1071 static inline alloc_pool
1072 dv_pool (decl_or_value dv)
1073 {
1074   return dv_onepart_p (dv) ? valvar_pool : var_pool;
1075 }
1076
1077 /* Build a decl_or_value out of a decl.  */
1078 static inline decl_or_value
1079 dv_from_decl (tree decl)
1080 {
1081   decl_or_value dv;
1082   dv = decl;
1083 #ifdef ENABLE_CHECKING
1084   gcc_assert (dv_is_decl_p (dv));
1085 #endif
1086   return dv;
1087 }
1088
1089 /* Build a decl_or_value out of a value.  */
1090 static inline decl_or_value
1091 dv_from_value (rtx value)
1092 {
1093   decl_or_value dv;
1094   dv = value;
1095 #ifdef ENABLE_CHECKING
1096   gcc_assert (dv_is_value_p (dv));
1097 #endif
1098   return dv;
1099 }
1100
1101 extern void debug_dv (decl_or_value dv);
1102
1103 void
1104 debug_dv (decl_or_value dv)
1105 {
1106   if (dv_is_value_p (dv))
1107     debug_rtx (dv_as_value (dv));
1108   else
1109     debug_generic_stmt (dv_as_decl (dv));
1110 }
1111
1112 typedef unsigned int dvuid;
1113
1114 /* Return the uid of DV.  */
1115
1116 static inline dvuid
1117 dv_uid (decl_or_value dv)
1118 {
1119   if (dv_is_value_p (dv))
1120     return CSELIB_VAL_PTR (dv_as_value (dv))->uid;
1121   else
1122     return DECL_UID (dv_as_decl (dv));
1123 }
1124
1125 /* Compute the hash from the uid.  */
1126
1127 static inline hashval_t
1128 dv_uid2hash (dvuid uid)
1129 {
1130   return uid;
1131 }
1132
1133 /* The hash function for a mask table in a shared_htab chain.  */
1134
1135 static inline hashval_t
1136 dv_htab_hash (decl_or_value dv)
1137 {
1138   return dv_uid2hash (dv_uid (dv));
1139 }
1140
1141 /* The hash function for variable_htab, computes the hash value
1142    from the declaration of variable X.  */
1143
1144 static hashval_t
1145 variable_htab_hash (const void *x)
1146 {
1147   const_variable const v = (const_variable) x;
1148
1149   return dv_htab_hash (v->dv);
1150 }
1151
1152 /* Compare the declaration of variable X with declaration Y.  */
1153
1154 static int
1155 variable_htab_eq (const void *x, const void *y)
1156 {
1157   const_variable const v = (const_variable) x;
1158   decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y);
1159
1160   return (dv_as_opaque (v->dv) == dv_as_opaque (dv));
1161 }
1162
1163 /* Free the element of VARIABLE_HTAB (its type is struct variable_def).  */
1164
1165 static void
1166 variable_htab_free (void *elem)
1167 {
1168   int i;
1169   variable var = (variable) elem;
1170   location_chain node, next;
1171
1172   gcc_assert (var->refcount > 0);
1173
1174   var->refcount--;
1175   if (var->refcount > 0)
1176     return;
1177
1178   for (i = 0; i < var->n_var_parts; i++)
1179     {
1180       for (node = var->var_part[i].loc_chain; node; node = next)
1181         {
1182           next = node->next;
1183           pool_free (loc_chain_pool, node);
1184         }
1185       var->var_part[i].loc_chain = NULL;
1186     }
1187   pool_free (dv_pool (var->dv), var);
1188 }
1189
1190 /* The hash function for value_chains htab, computes the hash value
1191    from the VALUE.  */
1192
1193 static hashval_t
1194 value_chain_htab_hash (const void *x)
1195 {
1196   const_value_chain const v = (const_value_chain) x;
1197
1198   return dv_htab_hash (v->dv);
1199 }
1200
1201 /* Compare the VALUE X with VALUE Y.  */
1202
1203 static int
1204 value_chain_htab_eq (const void *x, const void *y)
1205 {
1206   const_value_chain const v = (const_value_chain) x;
1207   decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y);
1208
1209   return dv_as_opaque (v->dv) == dv_as_opaque (dv);
1210 }
1211
1212 /* Initialize the set (array) SET of attrs to empty lists.  */
1213
1214 static void
1215 init_attrs_list_set (attrs *set)
1216 {
1217   int i;
1218
1219   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1220     set[i] = NULL;
1221 }
1222
1223 /* Make the list *LISTP empty.  */
1224
1225 static void
1226 attrs_list_clear (attrs *listp)
1227 {
1228   attrs list, next;
1229
1230   for (list = *listp; list; list = next)
1231     {
1232       next = list->next;
1233       pool_free (attrs_pool, list);
1234     }
1235   *listp = NULL;
1236 }
1237
1238 /* Return true if the pair of DECL and OFFSET is the member of the LIST.  */
1239
1240 static attrs
1241 attrs_list_member (attrs list, decl_or_value dv, HOST_WIDE_INT offset)
1242 {
1243   for (; list; list = list->next)
1244     if (dv_as_opaque (list->dv) == dv_as_opaque (dv) && list->offset == offset)
1245       return list;
1246   return NULL;
1247 }
1248
1249 /* Insert the triplet DECL, OFFSET, LOC to the list *LISTP.  */
1250
1251 static void
1252 attrs_list_insert (attrs *listp, decl_or_value dv,
1253                    HOST_WIDE_INT offset, rtx loc)
1254 {
1255   attrs list;
1256
1257   list = (attrs) pool_alloc (attrs_pool);
1258   list->loc = loc;
1259   list->dv = dv;
1260   list->offset = offset;
1261   list->next = *listp;
1262   *listp = list;
1263 }
1264
1265 /* Copy all nodes from SRC and create a list *DSTP of the copies.  */
1266
1267 static void
1268 attrs_list_copy (attrs *dstp, attrs src)
1269 {
1270   attrs n;
1271
1272   attrs_list_clear (dstp);
1273   for (; src; src = src->next)
1274     {
1275       n = (attrs) pool_alloc (attrs_pool);
1276       n->loc = src->loc;
1277       n->dv = src->dv;
1278       n->offset = src->offset;
1279       n->next = *dstp;
1280       *dstp = n;
1281     }
1282 }
1283
1284 /* Add all nodes from SRC which are not in *DSTP to *DSTP.  */
1285
1286 static void
1287 attrs_list_union (attrs *dstp, attrs src)
1288 {
1289   for (; src; src = src->next)
1290     {
1291       if (!attrs_list_member (*dstp, src->dv, src->offset))
1292         attrs_list_insert (dstp, src->dv, src->offset, src->loc);
1293     }
1294 }
1295
1296 /* Combine nodes that are not onepart nodes from SRC and SRC2 into
1297    *DSTP.  */
1298
1299 static void
1300 attrs_list_mpdv_union (attrs *dstp, attrs src, attrs src2)
1301 {
1302   gcc_assert (!*dstp);
1303   for (; src; src = src->next)
1304     {
1305       if (!dv_onepart_p (src->dv))
1306         attrs_list_insert (dstp, src->dv, src->offset, src->loc);
1307     }
1308   for (src = src2; src; src = src->next)
1309     {
1310       if (!dv_onepart_p (src->dv)
1311           && !attrs_list_member (*dstp, src->dv, src->offset))
1312         attrs_list_insert (dstp, src->dv, src->offset, src->loc);
1313     }
1314 }
1315
1316 /* Shared hashtable support.  */
1317
1318 /* Return true if VARS is shared.  */
1319
1320 static inline bool
1321 shared_hash_shared (shared_hash vars)
1322 {
1323   return vars->refcount > 1;
1324 }
1325
1326 /* Return the hash table for VARS.  */
1327
1328 static inline htab_t
1329 shared_hash_htab (shared_hash vars)
1330 {
1331   return vars->htab;
1332 }
1333
1334 /* Return true if VAR is shared, or maybe because VARS is shared.  */
1335
1336 static inline bool
1337 shared_var_p (variable var, shared_hash vars)
1338 {
1339   /* Don't count an entry in the changed_variables table as a duplicate.  */
1340   return ((var->refcount > 1 + (int) var->in_changed_variables)
1341           || shared_hash_shared (vars));
1342 }
1343
1344 /* Copy variables into a new hash table.  */
1345
1346 static shared_hash
1347 shared_hash_unshare (shared_hash vars)
1348 {
1349   shared_hash new_vars = (shared_hash) pool_alloc (shared_hash_pool);
1350   gcc_assert (vars->refcount > 1);
1351   new_vars->refcount = 1;
1352   new_vars->htab
1353     = htab_create (htab_elements (vars->htab) + 3, variable_htab_hash,
1354                    variable_htab_eq, variable_htab_free);
1355   vars_copy (new_vars->htab, vars->htab);
1356   vars->refcount--;
1357   return new_vars;
1358 }
1359
1360 /* Increment reference counter on VARS and return it.  */
1361
1362 static inline shared_hash
1363 shared_hash_copy (shared_hash vars)
1364 {
1365   vars->refcount++;
1366   return vars;
1367 }
1368
1369 /* Decrement reference counter and destroy hash table if not shared
1370    anymore.  */
1371
1372 static void
1373 shared_hash_destroy (shared_hash vars)
1374 {
1375   gcc_assert (vars->refcount > 0);
1376   if (--vars->refcount == 0)
1377     {
1378       htab_delete (vars->htab);
1379       pool_free (shared_hash_pool, vars);
1380     }
1381 }
1382
1383 /* Unshare *PVARS if shared and return slot for DV.  If INS is
1384    INSERT, insert it if not already present.  */
1385
1386 static inline void **
1387 shared_hash_find_slot_unshare_1 (shared_hash *pvars, decl_or_value dv,
1388                                  hashval_t dvhash, enum insert_option ins)
1389 {
1390   if (shared_hash_shared (*pvars))
1391     *pvars = shared_hash_unshare (*pvars);
1392   return htab_find_slot_with_hash (shared_hash_htab (*pvars), dv, dvhash, ins);
1393 }
1394
1395 static inline void **
1396 shared_hash_find_slot_unshare (shared_hash *pvars, decl_or_value dv,
1397                                enum insert_option ins)
1398 {
1399   return shared_hash_find_slot_unshare_1 (pvars, dv, dv_htab_hash (dv), ins);
1400 }
1401
1402 /* Return slot for DV, if it is already present in the hash table.
1403    If it is not present, insert it only VARS is not shared, otherwise
1404    return NULL.  */
1405
1406 static inline void **
1407 shared_hash_find_slot_1 (shared_hash vars, decl_or_value dv, hashval_t dvhash)
1408 {
1409   return htab_find_slot_with_hash (shared_hash_htab (vars), dv, dvhash,
1410                                    shared_hash_shared (vars)
1411                                    ? NO_INSERT : INSERT);
1412 }
1413
1414 static inline void **
1415 shared_hash_find_slot (shared_hash vars, decl_or_value dv)
1416 {
1417   return shared_hash_find_slot_1 (vars, dv, dv_htab_hash (dv));
1418 }
1419
1420 /* Return slot for DV only if it is already present in the hash table.  */
1421
1422 static inline void **
1423 shared_hash_find_slot_noinsert_1 (shared_hash vars, decl_or_value dv,
1424                                   hashval_t dvhash)
1425 {
1426   return htab_find_slot_with_hash (shared_hash_htab (vars), dv, dvhash,
1427                                    NO_INSERT);
1428 }
1429
1430 static inline void **
1431 shared_hash_find_slot_noinsert (shared_hash vars, decl_or_value dv)
1432 {
1433   return shared_hash_find_slot_noinsert_1 (vars, dv, dv_htab_hash (dv));
1434 }
1435
1436 /* Return variable for DV or NULL if not already present in the hash
1437    table.  */
1438
1439 static inline variable
1440 shared_hash_find_1 (shared_hash vars, decl_or_value dv, hashval_t dvhash)
1441 {
1442   return (variable) htab_find_with_hash (shared_hash_htab (vars), dv, dvhash);
1443 }
1444
1445 static inline variable
1446 shared_hash_find (shared_hash vars, decl_or_value dv)
1447 {
1448   return shared_hash_find_1 (vars, dv, dv_htab_hash (dv));
1449 }
1450
1451 /* Return true if TVAL is better than CVAL as a canonival value.  We
1452    choose lowest-numbered VALUEs, using the RTX address as a
1453    tie-breaker.  The idea is to arrange them into a star topology,
1454    such that all of them are at most one step away from the canonical
1455    value, and the canonical value has backlinks to all of them, in
1456    addition to all the actual locations.  We don't enforce this
1457    topology throughout the entire dataflow analysis, though.
1458  */
1459
1460 static inline bool
1461 canon_value_cmp (rtx tval, rtx cval)
1462 {
1463   return !cval
1464     || CSELIB_VAL_PTR (tval)->uid < CSELIB_VAL_PTR (cval)->uid;
1465 }
1466
1467 static bool dst_can_be_shared;
1468
1469 /* Return a copy of a variable VAR and insert it to dataflow set SET.  */
1470
1471 static void **
1472 unshare_variable (dataflow_set *set, void **slot, variable var,
1473                   enum var_init_status initialized)
1474 {
1475   variable new_var;
1476   int i;
1477
1478   new_var = (variable) pool_alloc (dv_pool (var->dv));
1479   new_var->dv = var->dv;
1480   new_var->refcount = 1;
1481   var->refcount--;
1482   new_var->n_var_parts = var->n_var_parts;
1483   new_var->cur_loc_changed = var->cur_loc_changed;
1484   var->cur_loc_changed = false;
1485   new_var->in_changed_variables = false;
1486
1487   if (! flag_var_tracking_uninit)
1488     initialized = VAR_INIT_STATUS_INITIALIZED;
1489
1490   for (i = 0; i < var->n_var_parts; i++)
1491     {
1492       location_chain node;
1493       location_chain *nextp;
1494
1495       new_var->var_part[i].offset = var->var_part[i].offset;
1496       nextp = &new_var->var_part[i].loc_chain;
1497       for (node = var->var_part[i].loc_chain; node; node = node->next)
1498         {
1499           location_chain new_lc;
1500
1501           new_lc = (location_chain) pool_alloc (loc_chain_pool);
1502           new_lc->next = NULL;
1503           if (node->init > initialized)
1504             new_lc->init = node->init;
1505           else
1506             new_lc->init = initialized;
1507           if (node->set_src && !(MEM_P (node->set_src)))
1508             new_lc->set_src = node->set_src;
1509           else
1510             new_lc->set_src = NULL;
1511           new_lc->loc = node->loc;
1512
1513           *nextp = new_lc;
1514           nextp = &new_lc->next;
1515         }
1516
1517       new_var->var_part[i].cur_loc = var->var_part[i].cur_loc;
1518     }
1519
1520   dst_can_be_shared = false;
1521   if (shared_hash_shared (set->vars))
1522     slot = shared_hash_find_slot_unshare (&set->vars, var->dv, NO_INSERT);
1523   else if (set->traversed_vars && set->vars != set->traversed_vars)
1524     slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
1525   *slot = new_var;
1526   if (var->in_changed_variables)
1527     {
1528       void **cslot
1529         = htab_find_slot_with_hash (changed_variables, var->dv,
1530                                     dv_htab_hash (var->dv), NO_INSERT);
1531       gcc_assert (*cslot == (void *) var);
1532       var->in_changed_variables = false;
1533       variable_htab_free (var);
1534       *cslot = new_var;
1535       new_var->in_changed_variables = true;
1536     }
1537   return slot;
1538 }
1539
1540 /* Add a variable from *SLOT to hash table DATA and increase its reference
1541    count.  */
1542
1543 static int
1544 vars_copy_1 (void **slot, void *data)
1545 {
1546   htab_t dst = (htab_t) data;
1547   variable src;
1548   void **dstp;
1549
1550   src = (variable) *slot;
1551   src->refcount++;
1552
1553   dstp = htab_find_slot_with_hash (dst, src->dv,
1554                                    dv_htab_hash (src->dv),
1555                                    INSERT);
1556   *dstp = src;
1557
1558   /* Continue traversing the hash table.  */
1559   return 1;
1560 }
1561
1562 /* Copy all variables from hash table SRC to hash table DST.  */
1563
1564 static void
1565 vars_copy (htab_t dst, htab_t src)
1566 {
1567   htab_traverse_noresize (src, vars_copy_1, dst);
1568 }
1569
1570 /* Map a decl to its main debug decl.  */
1571
1572 static inline tree
1573 var_debug_decl (tree decl)
1574 {
1575   if (decl && DECL_P (decl)
1576       && DECL_DEBUG_EXPR_IS_FROM (decl) && DECL_DEBUG_EXPR (decl)
1577       && DECL_P (DECL_DEBUG_EXPR (decl)))
1578     decl = DECL_DEBUG_EXPR (decl);
1579
1580   return decl;
1581 }
1582
1583 /* Set the register LOC to contain DV, OFFSET.  */
1584
1585 static void
1586 var_reg_decl_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1587                   decl_or_value dv, HOST_WIDE_INT offset, rtx set_src,
1588                   enum insert_option iopt)
1589 {
1590   attrs node;
1591   bool decl_p = dv_is_decl_p (dv);
1592
1593   if (decl_p)
1594     dv = dv_from_decl (var_debug_decl (dv_as_decl (dv)));
1595
1596   for (node = set->regs[REGNO (loc)]; node; node = node->next)
1597     if (dv_as_opaque (node->dv) == dv_as_opaque (dv)
1598         && node->offset == offset)
1599       break;
1600   if (!node)
1601     attrs_list_insert (&set->regs[REGNO (loc)], dv, offset, loc);
1602   set_variable_part (set, loc, dv, offset, initialized, set_src, iopt);
1603 }
1604
1605 /* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  */
1606
1607 static void
1608 var_reg_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1609              rtx set_src)
1610 {
1611   tree decl = REG_EXPR (loc);
1612   HOST_WIDE_INT offset = REG_OFFSET (loc);
1613
1614   var_reg_decl_set (set, loc, initialized,
1615                     dv_from_decl (decl), offset, set_src, INSERT);
1616 }
1617
1618 static enum var_init_status
1619 get_init_value (dataflow_set *set, rtx loc, decl_or_value dv)
1620 {
1621   variable var;
1622   int i;
1623   enum var_init_status ret_val = VAR_INIT_STATUS_UNKNOWN;
1624
1625   if (! flag_var_tracking_uninit)
1626     return VAR_INIT_STATUS_INITIALIZED;
1627
1628   var = shared_hash_find (set->vars, dv);
1629   if (var)
1630     {
1631       for (i = 0; i < var->n_var_parts && ret_val == VAR_INIT_STATUS_UNKNOWN; i++)
1632         {
1633           location_chain nextp;
1634           for (nextp = var->var_part[i].loc_chain; nextp; nextp = nextp->next)
1635             if (rtx_equal_p (nextp->loc, loc))
1636               {
1637                 ret_val = nextp->init;
1638                 break;
1639               }
1640         }
1641     }
1642
1643   return ret_val;
1644 }
1645
1646 /* Delete current content of register LOC in dataflow set SET and set
1647    the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  If
1648    MODIFY is true, any other live copies of the same variable part are
1649    also deleted from the dataflow set, otherwise the variable part is
1650    assumed to be copied from another location holding the same
1651    part.  */
1652
1653 static void
1654 var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify,
1655                         enum var_init_status initialized, rtx set_src)
1656 {
1657   tree decl = REG_EXPR (loc);
1658   HOST_WIDE_INT offset = REG_OFFSET (loc);
1659   attrs node, next;
1660   attrs *nextp;
1661
1662   decl = var_debug_decl (decl);
1663
1664   if (initialized == VAR_INIT_STATUS_UNKNOWN)
1665     initialized = get_init_value (set, loc, dv_from_decl (decl));
1666
1667   nextp = &set->regs[REGNO (loc)];
1668   for (node = *nextp; node; node = next)
1669     {
1670       next = node->next;
1671       if (dv_as_opaque (node->dv) != decl || node->offset != offset)
1672         {
1673           delete_variable_part (set, node->loc, node->dv, node->offset);
1674           pool_free (attrs_pool, node);
1675           *nextp = next;
1676         }
1677       else
1678         {
1679           node->loc = loc;
1680           nextp = &node->next;
1681         }
1682     }
1683   if (modify)
1684     clobber_variable_part (set, loc, dv_from_decl (decl), offset, set_src);
1685   var_reg_set (set, loc, initialized, set_src);
1686 }
1687
1688 /* Delete the association of register LOC in dataflow set SET with any
1689    variables that aren't onepart.  If CLOBBER is true, also delete any
1690    other live copies of the same variable part, and delete the
1691    association with onepart dvs too.  */
1692
1693 static void
1694 var_reg_delete (dataflow_set *set, rtx loc, bool clobber)
1695 {
1696   attrs *nextp = &set->regs[REGNO (loc)];
1697   attrs node, next;
1698
1699   if (clobber)
1700     {
1701       tree decl = REG_EXPR (loc);
1702       HOST_WIDE_INT offset = REG_OFFSET (loc);
1703
1704       decl = var_debug_decl (decl);
1705
1706       clobber_variable_part (set, NULL, dv_from_decl (decl), offset, NULL);
1707     }
1708
1709   for (node = *nextp; node; node = next)
1710     {
1711       next = node->next;
1712       if (clobber || !dv_onepart_p (node->dv))
1713         {
1714           delete_variable_part (set, node->loc, node->dv, node->offset);
1715           pool_free (attrs_pool, node);
1716           *nextp = next;
1717         }
1718       else
1719         nextp = &node->next;
1720     }
1721 }
1722
1723 /* Delete content of register with number REGNO in dataflow set SET.  */
1724
1725 static void
1726 var_regno_delete (dataflow_set *set, int regno)
1727 {
1728   attrs *reg = &set->regs[regno];
1729   attrs node, next;
1730
1731   for (node = *reg; node; node = next)
1732     {
1733       next = node->next;
1734       delete_variable_part (set, node->loc, node->dv, node->offset);
1735       pool_free (attrs_pool, node);
1736     }
1737   *reg = NULL;
1738 }
1739
1740 /* Set the location of DV, OFFSET as the MEM LOC.  */
1741
1742 static void
1743 var_mem_decl_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1744                   decl_or_value dv, HOST_WIDE_INT offset, rtx set_src,
1745                   enum insert_option iopt)
1746 {
1747   if (dv_is_decl_p (dv))
1748     dv = dv_from_decl (var_debug_decl (dv_as_decl (dv)));
1749
1750   set_variable_part (set, loc, dv, offset, initialized, set_src, iopt);
1751 }
1752
1753 /* Set the location part of variable MEM_EXPR (LOC) in dataflow set
1754    SET to LOC.
1755    Adjust the address first if it is stack pointer based.  */
1756
1757 static void
1758 var_mem_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1759              rtx set_src)
1760 {
1761   tree decl = MEM_EXPR (loc);
1762   HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
1763
1764   var_mem_decl_set (set, loc, initialized,
1765                     dv_from_decl (decl), offset, set_src, INSERT);
1766 }
1767
1768 /* Delete and set the location part of variable MEM_EXPR (LOC) in
1769    dataflow set SET to LOC.  If MODIFY is true, any other live copies
1770    of the same variable part are also deleted from the dataflow set,
1771    otherwise the variable part is assumed to be copied from another
1772    location holding the same part.
1773    Adjust the address first if it is stack pointer based.  */
1774
1775 static void
1776 var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify,
1777                         enum var_init_status initialized, rtx set_src)
1778 {
1779   tree decl = MEM_EXPR (loc);
1780   HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
1781
1782   decl = var_debug_decl (decl);
1783
1784   if (initialized == VAR_INIT_STATUS_UNKNOWN)
1785     initialized = get_init_value (set, loc, dv_from_decl (decl));
1786
1787   if (modify)
1788     clobber_variable_part (set, NULL, dv_from_decl (decl), offset, set_src);
1789   var_mem_set (set, loc, initialized, set_src);
1790 }
1791
1792 /* Delete the location part LOC from dataflow set SET.  If CLOBBER is
1793    true, also delete any other live copies of the same variable part.
1794    Adjust the address first if it is stack pointer based.  */
1795
1796 static void
1797 var_mem_delete (dataflow_set *set, rtx loc, bool clobber)
1798 {
1799   tree decl = MEM_EXPR (loc);
1800   HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
1801
1802   decl = var_debug_decl (decl);
1803   if (clobber)
1804     clobber_variable_part (set, NULL, dv_from_decl (decl), offset, NULL);
1805   delete_variable_part (set, loc, dv_from_decl (decl), offset);
1806 }
1807
1808 /* Bind a value to a location it was just stored in.  If MODIFIED
1809    holds, assume the location was modified, detaching it from any
1810    values bound to it.  */
1811
1812 static void
1813 val_store (dataflow_set *set, rtx val, rtx loc, rtx insn, bool modified)
1814 {
1815   cselib_val *v = CSELIB_VAL_PTR (val);
1816
1817   gcc_assert (cselib_preserved_value_p (v));
1818
1819   if (dump_file)
1820     {
1821       fprintf (dump_file, "%i: ", INSN_UID (insn));
1822       print_inline_rtx (dump_file, val, 0);
1823       fprintf (dump_file, " stored in ");
1824       print_inline_rtx (dump_file, loc, 0);
1825       if (v->locs)
1826         {
1827           struct elt_loc_list *l;
1828           for (l = v->locs; l; l = l->next)
1829             {
1830               fprintf (dump_file, "\n%i: ", INSN_UID (l->setting_insn));
1831               print_inline_rtx (dump_file, l->loc, 0);
1832             }
1833         }
1834       fprintf (dump_file, "\n");
1835     }
1836
1837   if (REG_P (loc))
1838     {
1839       if (modified)
1840         var_regno_delete (set, REGNO (loc));
1841       var_reg_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
1842                         dv_from_value (val), 0, NULL_RTX, INSERT);
1843     }
1844   else if (MEM_P (loc))
1845     var_mem_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
1846                       dv_from_value (val), 0, NULL_RTX, INSERT);
1847   else
1848     set_variable_part (set, loc, dv_from_value (val), 0,
1849                        VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
1850 }
1851
1852 /* Reset this node, detaching all its equivalences.  Return the slot
1853    in the variable hash table that holds dv, if there is one.  */
1854
1855 static void
1856 val_reset (dataflow_set *set, decl_or_value dv)
1857 {
1858   variable var = shared_hash_find (set->vars, dv) ;
1859   location_chain node;
1860   rtx cval;
1861
1862   if (!var || !var->n_var_parts)
1863     return;
1864
1865   gcc_assert (var->n_var_parts == 1);
1866
1867   cval = NULL;
1868   for (node = var->var_part[0].loc_chain; node; node = node->next)
1869     if (GET_CODE (node->loc) == VALUE
1870         && canon_value_cmp (node->loc, cval))
1871       cval = node->loc;
1872
1873   for (node = var->var_part[0].loc_chain; node; node = node->next)
1874     if (GET_CODE (node->loc) == VALUE && cval != node->loc)
1875       {
1876         /* Redirect the equivalence link to the new canonical
1877            value, or simply remove it if it would point at
1878            itself.  */
1879         if (cval)
1880           set_variable_part (set, cval, dv_from_value (node->loc),
1881                              0, node->init, node->set_src, NO_INSERT);
1882         delete_variable_part (set, dv_as_value (dv),
1883                               dv_from_value (node->loc), 0);
1884       }
1885
1886   if (cval)
1887     {
1888       decl_or_value cdv = dv_from_value (cval);
1889
1890       /* Keep the remaining values connected, accummulating links
1891          in the canonical value.  */
1892       for (node = var->var_part[0].loc_chain; node; node = node->next)
1893         {
1894           if (node->loc == cval)
1895             continue;
1896           else if (GET_CODE (node->loc) == REG)
1897             var_reg_decl_set (set, node->loc, node->init, cdv, 0,
1898                               node->set_src, NO_INSERT);
1899           else if (GET_CODE (node->loc) == MEM)
1900             var_mem_decl_set (set, node->loc, node->init, cdv, 0,
1901                               node->set_src, NO_INSERT);
1902           else
1903             set_variable_part (set, node->loc, cdv, 0,
1904                                node->init, node->set_src, NO_INSERT);
1905         }
1906     }
1907
1908   /* We remove this last, to make sure that the canonical value is not
1909      removed to the point of requiring reinsertion.  */
1910   if (cval)
1911     delete_variable_part (set, dv_as_value (dv), dv_from_value (cval), 0);
1912
1913   clobber_variable_part (set, NULL, dv, 0, NULL);
1914
1915   /* ??? Should we make sure there aren't other available values or
1916      variables whose values involve this one other than by
1917      equivalence?  E.g., at the very least we should reset MEMs, those
1918      shouldn't be too hard to find cselib-looking up the value as an
1919      address, then locating the resulting value in our own hash
1920      table.  */
1921 }
1922
1923 /* Find the values in a given location and map the val to another
1924    value, if it is unique, or add the location as one holding the
1925    value.  */
1926
1927 static void
1928 val_resolve (dataflow_set *set, rtx val, rtx loc, rtx insn)
1929 {
1930   decl_or_value dv = dv_from_value (val);
1931
1932   if (dump_file && (dump_flags & TDF_DETAILS))
1933     {
1934       if (insn)
1935         fprintf (dump_file, "%i: ", INSN_UID (insn));
1936       else
1937         fprintf (dump_file, "head: ");
1938       print_inline_rtx (dump_file, val, 0);
1939       fputs (" is at ", dump_file);
1940       print_inline_rtx (dump_file, loc, 0);
1941       fputc ('\n', dump_file);
1942     }
1943
1944   val_reset (set, dv);
1945
1946   if (REG_P (loc))
1947     {
1948       attrs node, found = NULL;
1949
1950       for (node = set->regs[REGNO (loc)]; node; node = node->next)
1951         if (dv_is_value_p (node->dv)
1952             && GET_MODE (dv_as_value (node->dv)) == GET_MODE (loc))
1953           {
1954             found = node;
1955
1956             /* Map incoming equivalences.  ??? Wouldn't it be nice if
1957              we just started sharing the location lists?  Maybe a
1958              circular list ending at the value itself or some
1959              such.  */
1960             set_variable_part (set, dv_as_value (node->dv),
1961                                dv_from_value (val), node->offset,
1962                                VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
1963             set_variable_part (set, val, node->dv, node->offset,
1964                                VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
1965           }
1966
1967       /* If we didn't find any equivalence, we need to remember that
1968          this value is held in the named register.  */
1969       if (!found)
1970         var_reg_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
1971                           dv_from_value (val), 0, NULL_RTX, INSERT);
1972     }
1973   else if (MEM_P (loc))
1974     /* ??? Merge equivalent MEMs.  */
1975     var_mem_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
1976                       dv_from_value (val), 0, NULL_RTX, INSERT);
1977   else
1978     /* ??? Merge equivalent expressions.  */
1979     set_variable_part (set, loc, dv_from_value (val), 0,
1980                        VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
1981 }
1982
1983 /* Initialize dataflow set SET to be empty.
1984    VARS_SIZE is the initial size of hash table VARS.  */
1985
1986 static void
1987 dataflow_set_init (dataflow_set *set)
1988 {
1989   init_attrs_list_set (set->regs);
1990   set->vars = shared_hash_copy (empty_shared_hash);
1991   set->stack_adjust = 0;
1992   set->traversed_vars = NULL;
1993 }
1994
1995 /* Delete the contents of dataflow set SET.  */
1996
1997 static void
1998 dataflow_set_clear (dataflow_set *set)
1999 {
2000   int i;
2001
2002   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2003     attrs_list_clear (&set->regs[i]);
2004
2005   shared_hash_destroy (set->vars);
2006   set->vars = shared_hash_copy (empty_shared_hash);
2007 }
2008
2009 /* Copy the contents of dataflow set SRC to DST.  */
2010
2011 static void
2012 dataflow_set_copy (dataflow_set *dst, dataflow_set *src)
2013 {
2014   int i;
2015
2016   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2017     attrs_list_copy (&dst->regs[i], src->regs[i]);
2018
2019   shared_hash_destroy (dst->vars);
2020   dst->vars = shared_hash_copy (src->vars);
2021   dst->stack_adjust = src->stack_adjust;
2022 }
2023
2024 /* Information for merging lists of locations for a given offset of variable.
2025  */
2026 struct variable_union_info
2027 {
2028   /* Node of the location chain.  */
2029   location_chain lc;
2030
2031   /* The sum of positions in the input chains.  */
2032   int pos;
2033
2034   /* The position in the chain of DST dataflow set.  */
2035   int pos_dst;
2036 };
2037
2038 /* Buffer for location list sorting and its allocated size.  */
2039 static struct variable_union_info *vui_vec;
2040 static int vui_allocated;
2041
2042 /* Compare function for qsort, order the structures by POS element.  */
2043
2044 static int
2045 variable_union_info_cmp_pos (const void *n1, const void *n2)
2046 {
2047   const struct variable_union_info *const i1 =
2048     (const struct variable_union_info *) n1;
2049   const struct variable_union_info *const i2 =
2050     ( const struct variable_union_info *) n2;
2051
2052   if (i1->pos != i2->pos)
2053     return i1->pos - i2->pos;
2054
2055   return (i1->pos_dst - i2->pos_dst);
2056 }
2057
2058 /* Compute union of location parts of variable *SLOT and the same variable
2059    from hash table DATA.  Compute "sorted" union of the location chains
2060    for common offsets, i.e. the locations of a variable part are sorted by
2061    a priority where the priority is the sum of the positions in the 2 chains
2062    (if a location is only in one list the position in the second list is
2063    defined to be larger than the length of the chains).
2064    When we are updating the location parts the newest location is in the
2065    beginning of the chain, so when we do the described "sorted" union
2066    we keep the newest locations in the beginning.  */
2067
2068 static int
2069 variable_union (void **slot, void *data)
2070 {
2071   variable src, dst;
2072   void **dstp;
2073   dataflow_set *set = (dataflow_set *) data;
2074   int i, j, k;
2075
2076   src = (variable) *slot;
2077   dstp = shared_hash_find_slot (set->vars, src->dv);
2078   if (!dstp || !*dstp)
2079     {
2080       src->refcount++;
2081
2082       dst_can_be_shared = false;
2083       if (!dstp)
2084         dstp = shared_hash_find_slot_unshare (&set->vars, src->dv, INSERT);
2085
2086       *dstp = src;
2087
2088       /* Continue traversing the hash table.  */
2089       return 1;
2090     }
2091   else
2092     dst = (variable) *dstp;
2093
2094   gcc_assert (src->n_var_parts);
2095
2096   /* We can combine one-part variables very efficiently, because their
2097      entries are in canonical order.  */
2098   if (dv_onepart_p (src->dv))
2099     {
2100       location_chain *nodep, dnode, snode;
2101
2102       gcc_assert (src->n_var_parts == 1);
2103       gcc_assert (dst->n_var_parts == 1);
2104
2105       snode = src->var_part[0].loc_chain;
2106       gcc_assert (snode);
2107
2108     restart_onepart_unshared:
2109       nodep = &dst->var_part[0].loc_chain;
2110       dnode = *nodep;
2111       gcc_assert (dnode);
2112
2113       while (snode)
2114         {
2115           int r = dnode ? loc_cmp (dnode->loc, snode->loc) : 1;
2116
2117           if (r > 0)
2118             {
2119               location_chain nnode;
2120
2121               if (shared_var_p (dst, set->vars))
2122                 {
2123                   dstp = unshare_variable (set, dstp, dst,
2124                                            VAR_INIT_STATUS_INITIALIZED);
2125                   dst = (variable)*dstp;
2126                   goto restart_onepart_unshared;
2127                 }
2128
2129               *nodep = nnode = (location_chain) pool_alloc (loc_chain_pool);
2130               nnode->loc = snode->loc;
2131               nnode->init = snode->init;
2132               if (!snode->set_src || MEM_P (snode->set_src))
2133                 nnode->set_src = NULL;
2134               else
2135                 nnode->set_src = snode->set_src;
2136               nnode->next = dnode;
2137               dnode = nnode;
2138             }
2139 #ifdef ENABLE_CHECKING
2140           else if (r == 0)
2141             gcc_assert (rtx_equal_p (dnode->loc, snode->loc));
2142 #endif
2143
2144           if (r >= 0)
2145             snode = snode->next;
2146
2147           nodep = &dnode->next;
2148           dnode = *nodep;
2149         }
2150
2151       return 1;
2152     }
2153
2154   /* Count the number of location parts, result is K.  */
2155   for (i = 0, j = 0, k = 0;
2156        i < src->n_var_parts && j < dst->n_var_parts; k++)
2157     {
2158       if (src->var_part[i].offset == dst->var_part[j].offset)
2159         {
2160           i++;
2161           j++;
2162         }
2163       else if (src->var_part[i].offset < dst->var_part[j].offset)
2164         i++;
2165       else
2166         j++;
2167     }
2168   k += src->n_var_parts - i;
2169   k += dst->n_var_parts - j;
2170
2171   /* We track only variables whose size is <= MAX_VAR_PARTS bytes
2172      thus there are at most MAX_VAR_PARTS different offsets.  */
2173   gcc_assert (dv_onepart_p (dst->dv) ? k == 1 : k <= MAX_VAR_PARTS);
2174
2175   if (dst->n_var_parts != k && shared_var_p (dst, set->vars))
2176     {
2177       dstp = unshare_variable (set, dstp, dst, VAR_INIT_STATUS_UNKNOWN);
2178       dst = (variable)*dstp;
2179     }
2180
2181   i = src->n_var_parts - 1;
2182   j = dst->n_var_parts - 1;
2183   dst->n_var_parts = k;
2184
2185   for (k--; k >= 0; k--)
2186     {
2187       location_chain node, node2;
2188
2189       if (i >= 0 && j >= 0
2190           && src->var_part[i].offset == dst->var_part[j].offset)
2191         {
2192           /* Compute the "sorted" union of the chains, i.e. the locations which
2193              are in both chains go first, they are sorted by the sum of
2194              positions in the chains.  */
2195           int dst_l, src_l;
2196           int ii, jj, n;
2197           struct variable_union_info *vui;
2198
2199           /* If DST is shared compare the location chains.
2200              If they are different we will modify the chain in DST with
2201              high probability so make a copy of DST.  */
2202           if (shared_var_p (dst, set->vars))
2203             {
2204               for (node = src->var_part[i].loc_chain,
2205                    node2 = dst->var_part[j].loc_chain; node && node2;
2206                    node = node->next, node2 = node2->next)
2207                 {
2208                   if (!((REG_P (node2->loc)
2209                          && REG_P (node->loc)
2210                          && REGNO (node2->loc) == REGNO (node->loc))
2211                         || rtx_equal_p (node2->loc, node->loc)))
2212                     {
2213                       if (node2->init < node->init)
2214                         node2->init = node->init;
2215                       break;
2216                     }
2217                 }
2218               if (node || node2)
2219                 {
2220                   dstp = unshare_variable (set, dstp, dst,
2221                                            VAR_INIT_STATUS_UNKNOWN);
2222                   dst = (variable)*dstp;
2223                 }
2224             }
2225
2226           src_l = 0;
2227           for (node = src->var_part[i].loc_chain; node; node = node->next)
2228             src_l++;
2229           dst_l = 0;
2230           for (node = dst->var_part[j].loc_chain; node; node = node->next)
2231             dst_l++;
2232
2233           if (dst_l == 1)
2234             {
2235               /* The most common case, much simpler, no qsort is needed.  */
2236               location_chain dstnode = dst->var_part[j].loc_chain;
2237               dst->var_part[k].loc_chain = dstnode;
2238               dst->var_part[k].offset = dst->var_part[j].offset;
2239               node2 = dstnode;
2240               for (node = src->var_part[i].loc_chain; node; node = node->next)
2241                 if (!((REG_P (dstnode->loc)
2242                        && REG_P (node->loc)
2243                        && REGNO (dstnode->loc) == REGNO (node->loc))
2244                       || rtx_equal_p (dstnode->loc, node->loc)))
2245                   {
2246                     location_chain new_node;
2247
2248                     /* Copy the location from SRC.  */
2249                     new_node = (location_chain) pool_alloc (loc_chain_pool);
2250                     new_node->loc = node->loc;
2251                     new_node->init = node->init;
2252                     if (!node->set_src || MEM_P (node->set_src))
2253                       new_node->set_src = NULL;
2254                     else
2255                       new_node->set_src = node->set_src;
2256                     node2->next = new_node;
2257                     node2 = new_node;
2258                   }
2259               node2->next = NULL;
2260             }
2261           else
2262             {
2263               if (src_l + dst_l > vui_allocated)
2264                 {
2265                   vui_allocated = MAX (vui_allocated * 2, src_l + dst_l);
2266                   vui_vec = XRESIZEVEC (struct variable_union_info, vui_vec,
2267                                         vui_allocated);
2268                 }
2269               vui = vui_vec;
2270
2271               /* Fill in the locations from DST.  */
2272               for (node = dst->var_part[j].loc_chain, jj = 0; node;
2273                    node = node->next, jj++)
2274                 {
2275                   vui[jj].lc = node;
2276                   vui[jj].pos_dst = jj;
2277
2278                   /* Pos plus value larger than a sum of 2 valid positions.  */
2279                   vui[jj].pos = jj + src_l + dst_l;
2280                 }
2281
2282               /* Fill in the locations from SRC.  */
2283               n = dst_l;
2284               for (node = src->var_part[i].loc_chain, ii = 0; node;
2285                    node = node->next, ii++)
2286                 {
2287                   /* Find location from NODE.  */
2288                   for (jj = 0; jj < dst_l; jj++)
2289                     {
2290                       if ((REG_P (vui[jj].lc->loc)
2291                            && REG_P (node->loc)
2292                            && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
2293                           || rtx_equal_p (vui[jj].lc->loc, node->loc))
2294                         {
2295                           vui[jj].pos = jj + ii;
2296                           break;
2297                         }
2298                     }
2299                   if (jj >= dst_l)      /* The location has not been found.  */
2300                     {
2301                       location_chain new_node;
2302
2303                       /* Copy the location from SRC.  */
2304                       new_node = (location_chain) pool_alloc (loc_chain_pool);
2305                       new_node->loc = node->loc;
2306                       new_node->init = node->init;
2307                       if (!node->set_src || MEM_P (node->set_src))
2308                         new_node->set_src = NULL;
2309                       else
2310                         new_node->set_src = node->set_src;
2311                       vui[n].lc = new_node;
2312                       vui[n].pos_dst = src_l + dst_l;
2313                       vui[n].pos = ii + src_l + dst_l;
2314                       n++;
2315                     }
2316                 }
2317
2318               if (dst_l == 2)
2319                 {
2320                   /* Special case still very common case.  For dst_l == 2
2321                      all entries dst_l ... n-1 are sorted, with for i >= dst_l
2322                      vui[i].pos == i + src_l + dst_l.  */
2323                   if (vui[0].pos > vui[1].pos)
2324                     {
2325                       /* Order should be 1, 0, 2... */
2326                       dst->var_part[k].loc_chain = vui[1].lc;
2327                       vui[1].lc->next = vui[0].lc;
2328                       if (n >= 3)
2329                         {
2330                           vui[0].lc->next = vui[2].lc;
2331                           vui[n - 1].lc->next = NULL;
2332                         }
2333                       else
2334                         vui[0].lc->next = NULL;
2335                       ii = 3;
2336                     }
2337                   else
2338                     {
2339                       dst->var_part[k].loc_chain = vui[0].lc;
2340                       if (n >= 3 && vui[2].pos < vui[1].pos)
2341                         {
2342                           /* Order should be 0, 2, 1, 3... */
2343                           vui[0].lc->next = vui[2].lc;
2344                           vui[2].lc->next = vui[1].lc;
2345                           if (n >= 4)
2346                             {
2347                               vui[1].lc->next = vui[3].lc;
2348                               vui[n - 1].lc->next = NULL;
2349                             }
2350                           else
2351                             vui[1].lc->next = NULL;
2352                           ii = 4;
2353                         }
2354                       else
2355                         {
2356                           /* Order should be 0, 1, 2... */
2357                           ii = 1;
2358                           vui[n - 1].lc->next = NULL;
2359                         }
2360                     }
2361                   for (; ii < n; ii++)
2362                     vui[ii - 1].lc->next = vui[ii].lc;
2363                 }
2364               else
2365                 {
2366                   qsort (vui, n, sizeof (struct variable_union_info),
2367                          variable_union_info_cmp_pos);
2368
2369                   /* Reconnect the nodes in sorted order.  */
2370                   for (ii = 1; ii < n; ii++)
2371                     vui[ii - 1].lc->next = vui[ii].lc;
2372                   vui[n - 1].lc->next = NULL;
2373                   dst->var_part[k].loc_chain = vui[0].lc;
2374                 }
2375
2376               dst->var_part[k].offset = dst->var_part[j].offset;
2377             }
2378           i--;
2379           j--;
2380         }
2381       else if ((i >= 0 && j >= 0
2382                 && src->var_part[i].offset < dst->var_part[j].offset)
2383                || i < 0)
2384         {
2385           dst->var_part[k] = dst->var_part[j];
2386           j--;
2387         }
2388       else if ((i >= 0 && j >= 0
2389                 && src->var_part[i].offset > dst->var_part[j].offset)
2390                || j < 0)
2391         {
2392           location_chain *nextp;
2393
2394           /* Copy the chain from SRC.  */
2395           nextp = &dst->var_part[k].loc_chain;
2396           for (node = src->var_part[i].loc_chain; node; node = node->next)
2397             {
2398               location_chain new_lc;
2399
2400               new_lc = (location_chain) pool_alloc (loc_chain_pool);
2401               new_lc->next = NULL;
2402               new_lc->init = node->init;
2403               if (!node->set_src || MEM_P (node->set_src))
2404                 new_lc->set_src = NULL;
2405               else
2406                 new_lc->set_src = node->set_src;
2407               new_lc->loc = node->loc;
2408
2409               *nextp = new_lc;
2410               nextp = &new_lc->next;
2411             }
2412
2413           dst->var_part[k].offset = src->var_part[i].offset;
2414           i--;
2415         }
2416       dst->var_part[k].cur_loc = NULL;
2417     }
2418
2419   if (flag_var_tracking_uninit)
2420     for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
2421       {
2422         location_chain node, node2;
2423         for (node = src->var_part[i].loc_chain; node; node = node->next)
2424           for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
2425             if (rtx_equal_p (node->loc, node2->loc))
2426               {
2427                 if (node->init > node2->init)
2428                   node2->init = node->init;
2429               }
2430       }
2431
2432   /* Continue traversing the hash table.  */
2433   return 1;
2434 }
2435
2436 /* Compute union of dataflow sets SRC and DST and store it to DST.  */
2437
2438 static void
2439 dataflow_set_union (dataflow_set *dst, dataflow_set *src)
2440 {
2441   int i;
2442
2443   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2444     attrs_list_union (&dst->regs[i], src->regs[i]);
2445
2446   if (dst->vars == empty_shared_hash)
2447     {
2448       shared_hash_destroy (dst->vars);
2449       dst->vars = shared_hash_copy (src->vars);
2450     }
2451   else
2452     htab_traverse (shared_hash_htab (src->vars), variable_union, dst);
2453 }
2454
2455 /* Whether the value is currently being expanded.  */
2456 #define VALUE_RECURSED_INTO(x) \
2457   (RTL_FLAG_CHECK2 ("VALUE_RECURSED_INTO", (x), VALUE, DEBUG_EXPR)->used)
2458 /* Whether the value is in changed_variables hash table.  */
2459 #define VALUE_CHANGED(x) \
2460   (RTL_FLAG_CHECK1 ("VALUE_CHANGED", (x), VALUE)->frame_related)
2461 /* Whether the decl is in changed_variables hash table.  */
2462 #define DECL_CHANGED(x) TREE_VISITED (x)
2463
2464 /* Record that DV has been added into resp. removed from changed_variables
2465    hashtable.  */
2466
2467 static inline void
2468 set_dv_changed (decl_or_value dv, bool newv)
2469 {
2470   if (dv_is_value_p (dv))
2471     VALUE_CHANGED (dv_as_value (dv)) = newv;
2472   else
2473     DECL_CHANGED (dv_as_decl (dv)) = newv;
2474 }
2475
2476 /* Return true if DV is present in changed_variables hash table.  */
2477
2478 static inline bool
2479 dv_changed_p (decl_or_value dv)
2480 {
2481   return (dv_is_value_p (dv)
2482           ? VALUE_CHANGED (dv_as_value (dv))
2483           : DECL_CHANGED (dv_as_decl (dv)));
2484 }
2485
2486 /* Return a location list node whose loc is rtx_equal to LOC, in the
2487    location list of a one-part variable or value VAR, or in that of
2488    any values recursively mentioned in the location lists.  */
2489
2490 static location_chain
2491 find_loc_in_1pdv (rtx loc, variable var, htab_t vars)
2492 {
2493   location_chain node;
2494
2495   if (!var)
2496     return NULL;
2497
2498   gcc_assert (dv_onepart_p (var->dv));
2499
2500   if (!var->n_var_parts)
2501     return NULL;
2502
2503   gcc_assert (var->var_part[0].offset == 0);
2504
2505   for (node = var->var_part[0].loc_chain; node; node = node->next)
2506     if (rtx_equal_p (loc, node->loc))
2507       return node;
2508     else if (GET_CODE (node->loc) == VALUE
2509              && !VALUE_RECURSED_INTO (node->loc))
2510       {
2511         decl_or_value dv = dv_from_value (node->loc);
2512         variable var = (variable)
2513                        htab_find_with_hash (vars, dv, dv_htab_hash (dv));
2514
2515         if (var)
2516           {
2517             location_chain where;
2518             VALUE_RECURSED_INTO (node->loc) = true;
2519             if ((where = find_loc_in_1pdv (loc, var, vars)))
2520               {
2521                 VALUE_RECURSED_INTO (node->loc) = false;
2522                 return where;
2523               }
2524             VALUE_RECURSED_INTO (node->loc) = false;
2525           }
2526       }
2527
2528   return NULL;
2529 }
2530
2531 /* Hash table iteration argument passed to variable_merge.  */
2532 struct dfset_merge
2533 {
2534   /* The set in which the merge is to be inserted.  */
2535   dataflow_set *dst;
2536   /* The set that we're iterating in.  */
2537   dataflow_set *cur;
2538   /* The set that may contain the other dv we are to merge with.  */
2539   dataflow_set *src;
2540   /* Number of onepart dvs in src.  */
2541   int src_onepart_cnt;
2542 };
2543
2544 /* Insert LOC in *DNODE, if it's not there yet.  The list must be in
2545    loc_cmp order, and it is maintained as such.  */
2546
2547 static void
2548 insert_into_intersection (location_chain *nodep, rtx loc,
2549                           enum var_init_status status)
2550 {
2551   location_chain node;
2552   int r;
2553
2554   for (node = *nodep; node; nodep = &node->next, node = *nodep)
2555     if ((r = loc_cmp (node->loc, loc)) == 0)
2556       {
2557         node->init = MIN (node->init, status);
2558         return;
2559       }
2560     else if (r > 0)
2561       break;
2562
2563   node = (location_chain) pool_alloc (loc_chain_pool);
2564
2565   node->loc = loc;
2566   node->set_src = NULL;
2567   node->init = status;
2568   node->next = *nodep;
2569   *nodep = node;
2570 }
2571
2572 /* Insert in DEST the intersection the locations present in both
2573    S1NODE and S2VAR, directly or indirectly.  S1NODE is from a
2574    variable in DSM->cur, whereas S2VAR is from DSM->src.  dvar is in
2575    DSM->dst.  */
2576
2577 static void
2578 intersect_loc_chains (rtx val, location_chain *dest, struct dfset_merge *dsm,
2579                       location_chain s1node, variable s2var)
2580 {
2581   dataflow_set *s1set = dsm->cur;
2582   dataflow_set *s2set = dsm->src;
2583   location_chain found;
2584
2585   for (; s1node; s1node = s1node->next)
2586     {
2587       if (s1node->loc == val)
2588         continue;
2589
2590       if ((found = find_loc_in_1pdv (s1node->loc, s2var,
2591                                      shared_hash_htab (s2set->vars))))
2592         {
2593           insert_into_intersection (dest, s1node->loc,
2594                                     MIN (s1node->init, found->init));
2595           continue;
2596         }
2597
2598       if (GET_CODE (s1node->loc) == VALUE
2599           && !VALUE_RECURSED_INTO (s1node->loc))
2600         {
2601           decl_or_value dv = dv_from_value (s1node->loc);
2602           variable svar = shared_hash_find (s1set->vars, dv);
2603           if (svar)
2604             {
2605               if (svar->n_var_parts == 1)
2606                 {
2607                   VALUE_RECURSED_INTO (s1node->loc) = true;
2608                   intersect_loc_chains (val, dest, dsm,
2609                                         svar->var_part[0].loc_chain,
2610                                         s2var);
2611                   VALUE_RECURSED_INTO (s1node->loc) = false;
2612                 }
2613             }
2614         }
2615
2616       /* ??? if the location is equivalent to any location in src,
2617          searched recursively
2618
2619            add to dst the values needed to represent the equivalence
2620
2621      telling whether locations S is equivalent to another dv's
2622      location list:
2623
2624        for each location D in the list
2625
2626          if S and D satisfy rtx_equal_p, then it is present
2627
2628          else if D is a value, recurse without cycles
2629
2630          else if S and D have the same CODE and MODE
2631
2632            for each operand oS and the corresponding oD
2633
2634              if oS and oD are not equivalent, then S an D are not equivalent
2635
2636              else if they are RTX vectors
2637
2638                if any vector oS element is not equivalent to its respective oD,
2639                then S and D are not equivalent
2640
2641    */
2642
2643
2644     }
2645 }
2646
2647 /* Return -1 if X should be before Y in a location list for a 1-part
2648    variable, 1 if Y should be before X, and 0 if they're equivalent
2649    and should not appear in the list.  */
2650
2651 static int
2652 loc_cmp (rtx x, rtx y)
2653 {
2654   int i, j, r;
2655   RTX_CODE code = GET_CODE (x);
2656   const char *fmt;
2657
2658   if (x == y)
2659     return 0;
2660
2661   if (REG_P (x))
2662     {
2663       if (!REG_P (y))
2664         return -1;
2665       gcc_assert (GET_MODE (x) == GET_MODE (y));
2666       if (REGNO (x) == REGNO (y))
2667         return 0;
2668       else if (REGNO (x) < REGNO (y))
2669         return -1;
2670       else
2671         return 1;
2672     }
2673
2674   if (REG_P (y))
2675     return 1;
2676
2677   if (MEM_P (x))
2678     {
2679       if (!MEM_P (y))
2680         return -1;
2681       gcc_assert (GET_MODE (x) == GET_MODE (y));
2682       return loc_cmp (XEXP (x, 0), XEXP (y, 0));
2683     }
2684
2685   if (MEM_P (y))
2686     return 1;
2687
2688   if (GET_CODE (x) == VALUE)
2689     {
2690       if (GET_CODE (y) != VALUE)
2691         return -1;
2692       /* Don't assert the modes are the same, that is true only
2693          when not recursing.  (subreg:QI (value:SI 1:1) 0)
2694          and (subreg:QI (value:DI 2:2) 0) can be compared,
2695          even when the modes are different.  */
2696       if (canon_value_cmp (x, y))
2697         return -1;
2698       else
2699         return 1;
2700     }
2701
2702   if (GET_CODE (y) == VALUE)
2703     return 1;
2704
2705   if (GET_CODE (x) == GET_CODE (y))
2706     /* Compare operands below.  */;
2707   else if (GET_CODE (x) < GET_CODE (y))
2708     return -1;
2709   else
2710     return 1;
2711
2712   gcc_assert (GET_MODE (x) == GET_MODE (y));
2713
2714   if (GET_CODE (x) == DEBUG_EXPR)
2715     {
2716       if (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x))
2717           < DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y)))
2718         return -1;
2719 #ifdef ENABLE_CHECKING
2720       gcc_assert (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x))
2721                   > DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y)));
2722 #endif
2723       return 1;
2724     }
2725
2726   fmt = GET_RTX_FORMAT (code);
2727   for (i = 0; i < GET_RTX_LENGTH (code); i++)
2728     switch (fmt[i])
2729       {
2730       case 'w':
2731         if (XWINT (x, i) == XWINT (y, i))
2732           break;
2733         else if (XWINT (x, i) < XWINT (y, i))
2734           return -1;
2735         else
2736           return 1;
2737
2738       case 'n':
2739       case 'i':
2740         if (XINT (x, i) == XINT (y, i))
2741           break;
2742         else if (XINT (x, i) < XINT (y, i))
2743           return -1;
2744         else
2745           return 1;
2746
2747       case 'V':
2748       case 'E':
2749         /* Compare the vector length first.  */
2750         if (XVECLEN (x, i) == XVECLEN (y, i))
2751           /* Compare the vectors elements.  */;
2752         else if (XVECLEN (x, i) < XVECLEN (y, i))
2753           return -1;
2754         else
2755           return 1;
2756
2757         for (j = 0; j < XVECLEN (x, i); j++)
2758           if ((r = loc_cmp (XVECEXP (x, i, j),
2759                             XVECEXP (y, i, j))))
2760             return r;
2761         break;
2762
2763       case 'e':
2764         if ((r = loc_cmp (XEXP (x, i), XEXP (y, i))))
2765           return r;
2766         break;
2767
2768       case 'S':
2769       case 's':
2770         if (XSTR (x, i) == XSTR (y, i))
2771           break;
2772         if (!XSTR (x, i))
2773           return -1;
2774         if (!XSTR (y, i))
2775           return 1;
2776         if ((r = strcmp (XSTR (x, i), XSTR (y, i))) == 0)
2777           break;
2778         else if (r < 0)
2779           return -1;
2780         else
2781           return 1;
2782
2783       case 'u':
2784         /* These are just backpointers, so they don't matter.  */
2785         break;
2786
2787       case '0':
2788       case 't':
2789         break;
2790
2791         /* It is believed that rtx's at this level will never
2792            contain anything but integers and other rtx's,
2793            except for within LABEL_REFs and SYMBOL_REFs.  */
2794       default:
2795         gcc_unreachable ();
2796       }
2797
2798   return 0;
2799 }
2800
2801 /* If decl or value DVP refers to VALUE from *LOC, add backlinks
2802    from VALUE to DVP.  */
2803
2804 static int
2805 add_value_chain (rtx *loc, void *dvp)
2806 {
2807   decl_or_value dv, ldv;
2808   value_chain vc, nvc;
2809   void **slot;
2810
2811   if (GET_CODE (*loc) == VALUE)
2812     ldv = dv_from_value (*loc);
2813   else if (GET_CODE (*loc) == DEBUG_EXPR)
2814     ldv = dv_from_decl (DEBUG_EXPR_TREE_DECL (*loc));
2815   else
2816     return 0;
2817
2818   if (dv_as_opaque (ldv) == dvp)
2819     return 0;
2820
2821   dv = (decl_or_value) dvp;
2822   slot = htab_find_slot_with_hash (value_chains, ldv, dv_htab_hash (ldv),
2823                                    INSERT);
2824   if (!*slot)
2825     {
2826       vc = (value_chain) pool_alloc (value_chain_pool);
2827       vc->dv = ldv;
2828       vc->next = NULL;
2829       vc->refcount = 0;
2830       *slot = (void *) vc;
2831     }
2832   else
2833     {
2834       for (vc = ((value_chain) *slot)->next; vc; vc = vc->next)
2835         if (dv_as_opaque (vc->dv) == dv_as_opaque (dv))
2836           break;
2837       if (vc)
2838         {
2839           vc->refcount++;
2840           return 0;
2841         }
2842     }
2843   vc = (value_chain) *slot;
2844   nvc = (value_chain) pool_alloc (value_chain_pool);
2845   nvc->dv = dv;
2846   nvc->next = vc->next;
2847   nvc->refcount = 1;
2848   vc->next = nvc;
2849   return 0;
2850 }
2851
2852 /* If decl or value DVP refers to VALUEs from within LOC, add backlinks
2853    from those VALUEs to DVP.  */
2854
2855 static void
2856 add_value_chains (decl_or_value dv, rtx loc)
2857 {
2858   if (GET_CODE (loc) == VALUE || GET_CODE (loc) == DEBUG_EXPR)
2859     {
2860       add_value_chain (&loc, dv_as_opaque (dv));
2861       return;
2862     }
2863   if (REG_P (loc))
2864     return;
2865   if (MEM_P (loc))
2866     loc = XEXP (loc, 0);
2867   for_each_rtx (&loc, add_value_chain, dv_as_opaque (dv));
2868 }
2869
2870 /* If CSELIB_VAL_PTR of value DV refer to VALUEs, add backlinks from those
2871    VALUEs to DV.  Add the same time get rid of ASM_OPERANDS from locs list,
2872    that is something we never can express in .debug_info and can prevent
2873    reverse ops from being used.  */
2874
2875 static void
2876 add_cselib_value_chains (decl_or_value dv)
2877 {
2878   struct elt_loc_list **l;
2879
2880   for (l = &CSELIB_VAL_PTR (dv_as_value (dv))->locs; *l;)
2881     if (GET_CODE ((*l)->loc) == ASM_OPERANDS)
2882       *l = (*l)->next;
2883     else
2884       {
2885         for_each_rtx (&(*l)->loc, add_value_chain, dv_as_opaque (dv));
2886         l = &(*l)->next;
2887       }
2888 }
2889
2890 /* If decl or value DVP refers to VALUE from *LOC, remove backlinks
2891    from VALUE to DVP.  */
2892
2893 static int
2894 remove_value_chain (rtx *loc, void *dvp)
2895 {
2896   decl_or_value dv, ldv;
2897   value_chain vc;
2898   void **slot;
2899
2900   if (GET_CODE (*loc) == VALUE)
2901     ldv = dv_from_value (*loc);
2902   else if (GET_CODE (*loc) == DEBUG_EXPR)
2903     ldv = dv_from_decl (DEBUG_EXPR_TREE_DECL (*loc));
2904   else
2905     return 0;
2906
2907   if (dv_as_opaque (ldv) == dvp)
2908     return 0;
2909
2910   dv = (decl_or_value) dvp;
2911   slot = htab_find_slot_with_hash (value_chains, ldv, dv_htab_hash (ldv),
2912                                    NO_INSERT);
2913   for (vc = (value_chain) *slot; vc->next; vc = vc->next)
2914     if (dv_as_opaque (vc->next->dv) == dv_as_opaque (dv))
2915       {
2916         value_chain dvc = vc->next;
2917         gcc_assert (dvc->refcount > 0);
2918         if (--dvc->refcount == 0)
2919           {
2920             vc->next = dvc->next;
2921             pool_free (value_chain_pool, dvc);
2922             if (vc->next == NULL && vc == (value_chain) *slot)
2923               {
2924                 pool_free (value_chain_pool, vc);
2925                 htab_clear_slot (value_chains, slot);
2926               }
2927           }
2928         return 0;
2929       }
2930   gcc_unreachable ();
2931 }
2932
2933 /* If decl or value DVP refers to VALUEs from within LOC, remove backlinks
2934    from those VALUEs to DVP.  */
2935
2936 static void
2937 remove_value_chains (decl_or_value dv, rtx loc)
2938 {
2939   if (GET_CODE (loc) == VALUE || GET_CODE (loc) == DEBUG_EXPR)
2940     {
2941       remove_value_chain (&loc, dv_as_opaque (dv));
2942       return;
2943     }
2944   if (REG_P (loc))
2945     return;
2946   if (MEM_P (loc))
2947     loc = XEXP (loc, 0);
2948   for_each_rtx (&loc, remove_value_chain, dv_as_opaque (dv));
2949 }
2950
2951 #if ENABLE_CHECKING
2952 /* If CSELIB_VAL_PTR of value DV refer to VALUEs, remove backlinks from those
2953    VALUEs to DV.  */
2954
2955 static void
2956 remove_cselib_value_chains (decl_or_value dv)
2957 {
2958   struct elt_loc_list *l;
2959
2960   for (l = CSELIB_VAL_PTR (dv_as_value (dv))->locs; l; l = l->next)
2961     for_each_rtx (&l->loc, remove_value_chain, dv_as_opaque (dv));
2962 }
2963
2964 /* Check the order of entries in one-part variables.   */
2965
2966 static int
2967 canonicalize_loc_order_check (void **slot, void *data ATTRIBUTE_UNUSED)
2968 {
2969   variable var = (variable) *slot;
2970   decl_or_value dv = var->dv;
2971   location_chain node, next;
2972
2973 #ifdef ENABLE_RTL_CHECKING
2974   int i;
2975   for (i = 0; i < var->n_var_parts; i++)
2976     gcc_assert (var->var_part[0].cur_loc == NULL);
2977   gcc_assert (!var->cur_loc_changed && !var->in_changed_variables);
2978 #endif
2979
2980   if (!dv_onepart_p (dv))
2981     return 1;
2982
2983   gcc_assert (var->n_var_parts == 1);
2984   node = var->var_part[0].loc_chain;
2985   gcc_assert (node);
2986
2987   while ((next = node->next))
2988     {
2989       gcc_assert (loc_cmp (node->loc, next->loc) < 0);
2990       node = next;
2991     }
2992
2993   return 1;
2994 }
2995 #endif
2996
2997 /* Mark with VALUE_RECURSED_INTO values that have neighbors that are
2998    more likely to be chosen as canonical for an equivalence set.
2999    Ensure less likely values can reach more likely neighbors, making
3000    the connections bidirectional.  */
3001
3002 static int
3003 canonicalize_values_mark (void **slot, void *data)
3004 {
3005   dataflow_set *set = (dataflow_set *)data;
3006   variable var = (variable) *slot;
3007   decl_or_value dv = var->dv;
3008   rtx val;
3009   location_chain node;
3010
3011   if (!dv_is_value_p (dv))
3012     return 1;
3013
3014   gcc_assert (var->n_var_parts == 1);
3015
3016   val = dv_as_value (dv);
3017
3018   for (node = var->var_part[0].loc_chain; node; node = node->next)
3019     if (GET_CODE (node->loc) == VALUE)
3020       {
3021         if (canon_value_cmp (node->loc, val))
3022           VALUE_RECURSED_INTO (val) = true;
3023         else
3024           {
3025             decl_or_value odv = dv_from_value (node->loc);
3026             void **oslot = shared_hash_find_slot_noinsert (set->vars, odv);
3027
3028             oslot = set_slot_part (set, val, oslot, odv, 0,
3029                                    node->init, NULL_RTX);
3030
3031             VALUE_RECURSED_INTO (node->loc) = true;
3032           }
3033       }
3034
3035   return 1;
3036 }
3037
3038 /* Remove redundant entries from equivalence lists in onepart
3039    variables, canonicalizing equivalence sets into star shapes.  */
3040
3041 static int
3042 canonicalize_values_star (void **slot, void *data)
3043 {
3044   dataflow_set *set = (dataflow_set *)data;
3045   variable var = (variable) *slot;
3046   decl_or_value dv = var->dv;
3047   location_chain node;
3048   decl_or_value cdv;
3049   rtx val, cval;
3050   void **cslot;
3051   bool has_value;
3052   bool has_marks;
3053
3054   if (!dv_onepart_p (dv))
3055     return 1;
3056
3057   gcc_assert (var->n_var_parts == 1);
3058
3059   if (dv_is_value_p (dv))
3060     {
3061       cval = dv_as_value (dv);
3062       if (!VALUE_RECURSED_INTO (cval))
3063         return 1;
3064       VALUE_RECURSED_INTO (cval) = false;
3065     }
3066   else
3067     cval = NULL_RTX;
3068
3069  restart:
3070   val = cval;
3071   has_value = false;
3072   has_marks = false;
3073
3074   gcc_assert (var->n_var_parts == 1);
3075
3076   for (node = var->var_part[0].loc_chain; node; node = node->next)
3077     if (GET_CODE (node->loc) == VALUE)
3078       {
3079         has_value = true;
3080         if (VALUE_RECURSED_INTO (node->loc))
3081           has_marks = true;
3082         if (canon_value_cmp (node->loc, cval))
3083           cval = node->loc;
3084       }
3085
3086   if (!has_value)
3087     return 1;
3088
3089   if (cval == val)
3090     {
3091       if (!has_marks || dv_is_decl_p (dv))
3092         return 1;
3093
3094       /* Keep it marked so that we revisit it, either after visiting a
3095          child node, or after visiting a new parent that might be
3096          found out.  */
3097       VALUE_RECURSED_INTO (val) = true;
3098
3099       for (node = var->var_part[0].loc_chain; node; node = node->next)
3100         if (GET_CODE (node->loc) == VALUE
3101             && VALUE_RECURSED_INTO (node->loc))
3102           {
3103             cval = node->loc;
3104           restart_with_cval:
3105             VALUE_RECURSED_INTO (cval) = false;
3106             dv = dv_from_value (cval);
3107             slot = shared_hash_find_slot_noinsert (set->vars, dv);
3108             if (!slot)
3109               {
3110                 gcc_assert (dv_is_decl_p (var->dv));
3111                 /* The canonical value was reset and dropped.
3112                    Remove it.  */
3113                 clobber_variable_part (set, NULL, var->dv, 0, NULL);
3114                 return 1;
3115               }
3116             var = (variable)*slot;
3117             gcc_assert (dv_is_value_p (var->dv));
3118             if (var->n_var_parts == 0)
3119               return 1;
3120             gcc_assert (var->n_var_parts == 1);
3121             goto restart;
3122           }
3123
3124       VALUE_RECURSED_INTO (val) = false;
3125
3126       return 1;
3127     }
3128
3129   /* Push values to the canonical one.  */
3130   cdv = dv_from_value (cval);
3131   cslot = shared_hash_find_slot_noinsert (set->vars, cdv);
3132
3133   for (node = var->var_part[0].loc_chain; node; node = node->next)
3134     if (node->loc != cval)
3135       {
3136         cslot = set_slot_part (set, node->loc, cslot, cdv, 0,
3137                                node->init, NULL_RTX);
3138         if (GET_CODE (node->loc) == VALUE)
3139           {
3140             decl_or_value ndv = dv_from_value (node->loc);
3141
3142             set_variable_part (set, cval, ndv, 0, node->init, NULL_RTX,
3143                                NO_INSERT);
3144
3145             if (canon_value_cmp (node->loc, val))
3146               {
3147                 /* If it could have been a local minimum, it's not any more,
3148                    since it's now neighbor to cval, so it may have to push
3149                    to it.  Conversely, if it wouldn't have prevailed over
3150                    val, then whatever mark it has is fine: if it was to
3151                    push, it will now push to a more canonical node, but if
3152                    it wasn't, then it has already pushed any values it might
3153                    have to.  */
3154                 VALUE_RECURSED_INTO (node->loc) = true;
3155                 /* Make sure we visit node->loc by ensuring we cval is
3156                    visited too.  */
3157                 VALUE_RECURSED_INTO (cval) = true;
3158               }
3159             else if (!VALUE_RECURSED_INTO (node->loc))
3160               /* If we have no need to "recurse" into this node, it's
3161                  already "canonicalized", so drop the link to the old
3162                  parent.  */
3163               clobber_variable_part (set, cval, ndv, 0, NULL);
3164           }
3165         else if (GET_CODE (node->loc) == REG)
3166           {
3167             attrs list = set->regs[REGNO (node->loc)], *listp;
3168
3169             /* Change an existing attribute referring to dv so that it
3170                refers to cdv, removing any duplicate this might
3171                introduce, and checking that no previous duplicates
3172                existed, all in a single pass.  */
3173
3174             while (list)
3175               {
3176                 if (list->offset == 0
3177                     && (dv_as_opaque (list->dv) == dv_as_opaque (dv)
3178                         || dv_as_opaque (list->dv) == dv_as_opaque (cdv)))
3179                   break;
3180
3181                 list = list->next;
3182               }
3183
3184             gcc_assert (list);
3185             if (dv_as_opaque (list->dv) == dv_as_opaque (dv))
3186               {
3187                 list->dv = cdv;
3188                 for (listp = &list->next; (list = *listp); listp = &list->next)
3189                   {
3190                     if (list->offset)
3191                       continue;
3192
3193                     if (dv_as_opaque (list->dv) == dv_as_opaque (cdv))
3194                       {
3195                         *listp = list->next;
3196                         pool_free (attrs_pool, list);
3197                         list = *listp;
3198                         break;
3199                       }
3200
3201                     gcc_assert (dv_as_opaque (list->dv) != dv_as_opaque (dv));
3202                   }
3203               }
3204             else if (dv_as_opaque (list->dv) == dv_as_opaque (cdv))
3205               {
3206                 for (listp = &list->next; (list = *listp); listp = &list->next)
3207                   {
3208                     if (list->offset)
3209                       continue;
3210
3211                     if (dv_as_opaque (list->dv) == dv_as_opaque (dv))
3212                       {
3213                         *listp = list->next;
3214                         pool_free (attrs_pool, list);
3215                         list = *listp;
3216                         break;
3217                       }
3218
3219                     gcc_assert (dv_as_opaque (list->dv) != dv_as_opaque (cdv));
3220                   }
3221               }
3222             else
3223               gcc_unreachable ();
3224
3225 #if ENABLE_CHECKING
3226             while (list)
3227               {
3228                 if (list->offset == 0
3229                     && (dv_as_opaque (list->dv) == dv_as_opaque (dv)
3230                         || dv_as_opaque (list->dv) == dv_as_opaque (cdv)))
3231                   gcc_unreachable ();
3232
3233                 list = list->next;
3234               }
3235 #endif
3236           }
3237       }
3238
3239   if (val)
3240     cslot = set_slot_part (set, val, cslot, cdv, 0,
3241                            VAR_INIT_STATUS_INITIALIZED, NULL_RTX);
3242
3243   slot = clobber_slot_part (set, cval, slot, 0, NULL);
3244
3245   /* Variable may have been unshared.  */
3246   var = (variable)*slot;
3247   gcc_assert (var->n_var_parts && var->var_part[0].loc_chain->loc == cval
3248               && var->var_part[0].loc_chain->next == NULL);
3249
3250   if (VALUE_RECURSED_INTO (cval))
3251     goto restart_with_cval;
3252
3253   return 1;
3254 }
3255
3256 /* Bind one-part variables to the canonical value in an equivalence
3257    set.  Not doing this causes dataflow convergence failure in rare
3258    circumstances, see PR42873.  Unfortunately we can't do this
3259    efficiently as part of canonicalize_values_star, since we may not
3260    have determined or even seen the canonical value of a set when we
3261    get to a variable that references another member of the set.  */
3262
3263 static int
3264 canonicalize_vars_star (void **slot, void *data)
3265 {
3266   dataflow_set *set = (dataflow_set *)data;
3267   variable var = (variable) *slot;
3268   decl_or_value dv = var->dv;
3269   location_chain node;
3270   rtx cval;
3271   decl_or_value cdv;
3272   void **cslot;
3273   variable cvar;
3274   location_chain cnode;
3275
3276   if (!dv_onepart_p (dv) || dv_is_value_p (dv))
3277     return 1;
3278
3279   gcc_assert (var->n_var_parts == 1);
3280
3281   node = var->var_part[0].loc_chain;
3282
3283   if (GET_CODE (node->loc) != VALUE)
3284     return 1;
3285
3286   gcc_assert (!node->next);
3287   cval = node->loc;
3288
3289   /* Push values to the canonical one.  */
3290   cdv = dv_from_value (cval);
3291   cslot = shared_hash_find_slot_noinsert (set->vars, cdv);
3292   if (!cslot)
3293     return 1;
3294   cvar = (variable)*cslot;
3295   gcc_assert (cvar->n_var_parts == 1);
3296
3297   cnode = cvar->var_part[0].loc_chain;
3298
3299   /* CVAL is canonical if its value list contains non-VALUEs or VALUEs
3300      that are not “more canonical” than it.  */
3301   if (GET_CODE (cnode->loc) != VALUE
3302       || !canon_value_cmp (cnode->loc, cval))
3303     return 1;
3304
3305   /* CVAL was found to be non-canonical.  Change the variable to point
3306      to the canonical VALUE.  */
3307   gcc_assert (!cnode->next);
3308   cval = cnode->loc;
3309
3310   slot = set_slot_part (set, cval, slot, dv, 0,
3311                         node->init, node->set_src);
3312   slot = clobber_slot_part (set, cval, slot, 0, node->set_src);
3313
3314   return 1;
3315 }
3316
3317 /* Combine variable or value in *S1SLOT (in DSM->cur) with the
3318    corresponding entry in DSM->src.  Multi-part variables are combined
3319    with variable_union, whereas onepart dvs are combined with
3320    intersection.  */
3321
3322 static int
3323 variable_merge_over_cur (void **s1slot, void *data)
3324 {
3325   struct dfset_merge *dsm = (struct dfset_merge *)data;
3326   dataflow_set *dst = dsm->dst;
3327   void **dstslot;
3328   variable s1var = (variable) *s1slot;
3329   variable s2var, dvar = NULL;
3330   decl_or_value dv = s1var->dv;
3331   bool onepart = dv_onepart_p (dv);
3332   rtx val;
3333   hashval_t dvhash;
3334   location_chain node, *nodep;
3335
3336   /* If the incoming onepart variable has an empty location list, then
3337      the intersection will be just as empty.  For other variables,
3338      it's always union.  */
3339   gcc_assert (s1var->n_var_parts);
3340   gcc_assert (s1var->var_part[0].loc_chain);
3341
3342   if (!onepart)
3343     return variable_union (s1slot, dst);
3344
3345   gcc_assert (s1var->n_var_parts == 1);
3346   gcc_assert (s1var->var_part[0].offset == 0);
3347
3348   dvhash = dv_htab_hash (dv);
3349   if (dv_is_value_p (dv))
3350     val = dv_as_value (dv);
3351   else
3352     val = NULL;
3353
3354   s2var = shared_hash_find_1 (dsm->src->vars, dv, dvhash);
3355   if (!s2var)
3356     {
3357       dst_can_be_shared = false;
3358       return 1;
3359     }
3360
3361   dsm->src_onepart_cnt--;
3362   gcc_assert (s2var->var_part[0].loc_chain);
3363   gcc_assert (s2var->n_var_parts == 1);
3364   gcc_assert (s2var->var_part[0].offset == 0);
3365
3366   dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3367   if (dstslot)
3368     {
3369       dvar = (variable)*dstslot;
3370       gcc_assert (dvar->refcount == 1);
3371       gcc_assert (dvar->n_var_parts == 1);
3372       gcc_assert (dvar->var_part[0].offset == 0);
3373       nodep = &dvar->var_part[0].loc_chain;
3374     }
3375   else
3376     {
3377       nodep = &node;
3378       node = NULL;
3379     }
3380
3381   if (!dstslot && !onepart_variable_different_p (s1var, s2var))
3382     {
3383       dstslot = shared_hash_find_slot_unshare_1 (&dst->vars, dv,
3384                                                  dvhash, INSERT);
3385       *dstslot = dvar = s2var;
3386       dvar->refcount++;
3387     }
3388   else
3389     {
3390       dst_can_be_shared = false;
3391
3392       intersect_loc_chains (val, nodep, dsm,
3393                             s1var->var_part[0].loc_chain, s2var);
3394
3395       if (!dstslot)
3396         {
3397           if (node)
3398             {
3399               dvar = (variable) pool_alloc (dv_pool (dv));
3400               dvar->dv = dv;
3401               dvar->refcount = 1;
3402               dvar->n_var_parts = 1;
3403               dvar->cur_loc_changed = false;
3404               dvar->in_changed_variables = false;
3405               dvar->var_part[0].offset = 0;
3406               dvar->var_part[0].loc_chain = node;
3407               dvar->var_part[0].cur_loc = NULL;
3408
3409               dstslot
3410                 = shared_hash_find_slot_unshare_1 (&dst->vars, dv, dvhash,
3411                                                    INSERT);
3412               gcc_assert (!*dstslot);
3413               *dstslot = dvar;
3414             }
3415           else
3416             return 1;
3417         }
3418     }
3419
3420   nodep = &dvar->var_part[0].loc_chain;
3421   while ((node = *nodep))
3422     {
3423       location_chain *nextp = &node->next;
3424
3425       if (GET_CODE (node->loc) == REG)
3426         {
3427           attrs list;
3428
3429           for (list = dst->regs[REGNO (node->loc)]; list; list = list->next)
3430             if (GET_MODE (node->loc) == GET_MODE (list->loc)
3431                 && dv_is_value_p (list->dv))
3432               break;
3433
3434           if (!list)
3435             attrs_list_insert (&dst->regs[REGNO (node->loc)],
3436                                dv, 0, node->loc);
3437           /* If this value became canonical for another value that had
3438              this register, we want to leave it alone.  */
3439           else if (dv_as_value (list->dv) != val)
3440             {
3441               dstslot = set_slot_part (dst, dv_as_value (list->dv),
3442                                        dstslot, dv, 0,
3443                                        node->init, NULL_RTX);
3444               dstslot = delete_slot_part (dst, node->loc, dstslot, 0);
3445
3446               /* Since nextp points into the removed node, we can't
3447                  use it.  The pointer to the next node moved to nodep.
3448                  However, if the variable we're walking is unshared
3449                  during our walk, we'll keep walking the location list
3450                  of the previously-shared variable, in which case the
3451                  node won't have been removed, and we'll want to skip
3452                  it.  That's why we test *nodep here.  */
3453               if (*nodep != node)
3454                 nextp = nodep;
3455             }
3456         }
3457       else
3458         /* Canonicalization puts registers first, so we don't have to
3459            walk it all.  */
3460         break;
3461       nodep = nextp;
3462     }
3463
3464   if (dvar != (variable)*dstslot)
3465     dvar = (variable)*dstslot;
3466   nodep = &dvar->var_part[0].loc_chain;
3467
3468   if (val)
3469     {
3470       /* Mark all referenced nodes for canonicalization, and make sure
3471          we have mutual equivalence links.  */
3472       VALUE_RECURSED_INTO (val) = true;
3473       for (node = *nodep; node; node = node->next)
3474         if (GET_CODE (node->loc) == VALUE)
3475           {
3476             VALUE_RECURSED_INTO (node->loc) = true;
3477             set_variable_part (dst, val, dv_from_value (node->loc), 0,
3478                                node->init, NULL, INSERT);
3479           }
3480
3481       dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3482       gcc_assert (*dstslot == dvar);
3483       canonicalize_values_star (dstslot, dst);
3484 #ifdef ENABLE_CHECKING
3485       gcc_assert (dstslot
3486                   == shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash));
3487 #endif
3488       dvar = (variable)*dstslot;
3489     }
3490   else
3491     {
3492       bool has_value = false, has_other = false;
3493
3494       /* If we have one value and anything else, we're going to
3495          canonicalize this, so make sure all values have an entry in
3496          the table and are marked for canonicalization.  */
3497       for (node = *nodep; node; node = node->next)
3498         {
3499           if (GET_CODE (node->loc) == VALUE)
3500             {
3501               /* If this was marked during register canonicalization,
3502                  we know we have to canonicalize values.  */
3503               if (has_value)
3504                 has_other = true;
3505               has_value = true;
3506               if (has_other)
3507                 break;
3508             }
3509           else
3510             {
3511               has_other = true;
3512               if (has_value)
3513                 break;
3514             }
3515         }
3516
3517       if (has_value && has_other)
3518         {
3519           for (node = *nodep; node; node = node->next)
3520             {
3521               if (GET_CODE (node->loc) == VALUE)
3522                 {
3523                   decl_or_value dv = dv_from_value (node->loc);
3524                   void **slot = NULL;
3525
3526                   if (shared_hash_shared (dst->vars))
3527                     slot = shared_hash_find_slot_noinsert (dst->vars, dv);
3528                   if (!slot)
3529                     slot = shared_hash_find_slot_unshare (&dst->vars, dv,
3530                                                           INSERT);
3531                   if (!*slot)
3532                     {
3533                       variable var = (variable) pool_alloc (dv_pool (dv));
3534                       var->dv = dv;
3535                       var->refcount = 1;
3536                       var->n_var_parts = 1;
3537                       var->cur_loc_changed = false;
3538                       var->in_changed_variables = false;
3539                       var->var_part[0].offset = 0;
3540                       var->var_part[0].loc_chain = NULL;
3541                       var->var_part[0].cur_loc = NULL;
3542                       *slot = var;
3543                     }
3544
3545                   VALUE_RECURSED_INTO (node->loc) = true;
3546                 }
3547             }
3548
3549           dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3550           gcc_assert (*dstslot == dvar);
3551           canonicalize_values_star (dstslot, dst);
3552 #ifdef ENABLE_CHECKING
3553           gcc_assert (dstslot
3554                       == shared_hash_find_slot_noinsert_1 (dst->vars,
3555                                                            dv, dvhash));
3556 #endif
3557           dvar = (variable)*dstslot;
3558         }
3559     }
3560
3561   if (!onepart_variable_different_p (dvar, s2var))
3562     {
3563       variable_htab_free (dvar);
3564       *dstslot = dvar = s2var;
3565       dvar->refcount++;
3566     }
3567   else if (s2var != s1var && !onepart_variable_different_p (dvar, s1var))
3568     {
3569       variable_htab_free (dvar);
3570       *dstslot = dvar = s1var;
3571       dvar->refcount++;
3572       dst_can_be_shared = false;
3573     }
3574   else
3575     dst_can_be_shared = false;
3576
3577   return 1;
3578 }
3579
3580 /* Copy s2slot (in DSM->src) to DSM->dst if the variable is a
3581    multi-part variable.  Unions of multi-part variables and
3582    intersections of one-part ones will be handled in
3583    variable_merge_over_cur().  */
3584
3585 static int
3586 variable_merge_over_src (void **s2slot, void *data)
3587 {
3588   struct dfset_merge *dsm = (struct dfset_merge *)data;
3589   dataflow_set *dst = dsm->dst;
3590   variable s2var = (variable) *s2slot;
3591   decl_or_value dv = s2var->dv;
3592   bool onepart = dv_onepart_p (dv);
3593
3594   if (!onepart)
3595     {
3596       void **dstp = shared_hash_find_slot (dst->vars, dv);
3597       *dstp = s2var;
3598       s2var->refcount++;
3599       return 1;
3600     }
3601
3602   dsm->src_onepart_cnt++;
3603   return 1;
3604 }
3605
3606 /* Combine dataflow set information from SRC2 into DST, using PDST
3607    to carry over information across passes.  */
3608
3609 static void
3610 dataflow_set_merge (dataflow_set *dst, dataflow_set *src2)
3611 {
3612   dataflow_set cur = *dst;
3613   dataflow_set *src1 = &cur;
3614   struct dfset_merge dsm;
3615   int i;
3616   size_t src1_elems, src2_elems;
3617
3618   src1_elems = htab_elements (shared_hash_htab (src1->vars));
3619   src2_elems = htab_elements (shared_hash_htab (src2->vars));
3620   dataflow_set_init (dst);
3621   dst->stack_adjust = cur.stack_adjust;
3622   shared_hash_destroy (dst->vars);
3623   dst->vars = (shared_hash) pool_alloc (shared_hash_pool);
3624   dst->vars->refcount = 1;
3625   dst->vars->htab
3626     = htab_create (MAX (src1_elems, src2_elems), variable_htab_hash,
3627                    variable_htab_eq, variable_htab_free);
3628
3629   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3630     attrs_list_mpdv_union (&dst->regs[i], src1->regs[i], src2->regs[i]);
3631
3632   dsm.dst = dst;
3633   dsm.src = src2;
3634   dsm.cur = src1;
3635   dsm.src_onepart_cnt = 0;
3636
3637   htab_traverse (shared_hash_htab (dsm.src->vars), variable_merge_over_src,
3638                  &dsm);
3639   htab_traverse (shared_hash_htab (dsm.cur->vars), variable_merge_over_cur,
3640                  &dsm);
3641
3642   if (dsm.src_onepart_cnt)
3643     dst_can_be_shared = false;
3644
3645   dataflow_set_destroy (src1);
3646 }
3647
3648 /* Mark register equivalences.  */
3649
3650 static void
3651 dataflow_set_equiv_regs (dataflow_set *set)
3652 {
3653   int i;
3654   attrs list, *listp;
3655
3656   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3657     {
3658       rtx canon[NUM_MACHINE_MODES];
3659
3660       memset (canon, 0, sizeof (canon));
3661
3662       for (list = set->regs[i]; list; list = list->next)
3663         if (list->offset == 0 && dv_is_value_p (list->dv))
3664           {
3665             rtx val = dv_as_value (list->dv);
3666             rtx *cvalp = &canon[(int)GET_MODE (val)];
3667             rtx cval = *cvalp;
3668
3669             if (canon_value_cmp (val, cval))
3670               *cvalp = val;
3671           }
3672
3673       for (list = set->regs[i]; list; list = list->next)
3674         if (list->offset == 0 && dv_onepart_p (list->dv))
3675           {
3676             rtx cval = canon[(int)GET_MODE (list->loc)];
3677
3678             if (!cval)
3679               continue;
3680
3681             if (dv_is_value_p (list->dv))
3682               {
3683                 rtx val = dv_as_value (list->dv);
3684
3685                 if (val == cval)
3686                   continue;
3687
3688                 VALUE_RECURSED_INTO (val) = true;
3689                 set_variable_part (set, val, dv_from_value (cval), 0,
3690                                    VAR_INIT_STATUS_INITIALIZED,
3691                                    NULL, NO_INSERT);
3692               }
3693
3694             VALUE_RECURSED_INTO (cval) = true;
3695             set_variable_part (set, cval, list->dv, 0,
3696                                VAR_INIT_STATUS_INITIALIZED, NULL, NO_INSERT);
3697           }
3698
3699       for (listp = &set->regs[i]; (list = *listp);
3700            listp = list ? &list->next : listp)
3701         if (list->offset == 0 && dv_onepart_p (list->dv))
3702           {
3703             rtx cval = canon[(int)GET_MODE (list->loc)];
3704             void **slot;
3705
3706             if (!cval)
3707               continue;
3708
3709             if (dv_is_value_p (list->dv))
3710               {
3711                 rtx val = dv_as_value (list->dv);
3712                 if (!VALUE_RECURSED_INTO (val))
3713                   continue;
3714               }
3715
3716             slot = shared_hash_find_slot_noinsert (set->vars, list->dv);
3717             canonicalize_values_star (slot, set);
3718             if (*listp != list)
3719               list = NULL;
3720           }
3721     }
3722 }
3723
3724 /* Remove any redundant values in the location list of VAR, which must
3725    be unshared and 1-part.  */
3726
3727 static void
3728 remove_duplicate_values (variable var)
3729 {
3730   location_chain node, *nodep;
3731
3732   gcc_assert (dv_onepart_p (var->dv));
3733   gcc_assert (var->n_var_parts == 1);
3734   gcc_assert (var->refcount == 1);
3735
3736   for (nodep = &var->var_part[0].loc_chain; (node = *nodep); )
3737     {
3738       if (GET_CODE (node->loc) == VALUE)
3739         {
3740           if (VALUE_RECURSED_INTO (node->loc))
3741             {
3742               /* Remove duplicate value node.  */
3743               *nodep = node->next;
3744               pool_free (loc_chain_pool, node);
3745               continue;
3746             }
3747           else
3748             VALUE_RECURSED_INTO (node->loc) = true;
3749         }
3750       nodep = &node->next;
3751     }
3752
3753   for (node = var->var_part[0].loc_chain; node; node = node->next)
3754     if (GET_CODE (node->loc) == VALUE)
3755       {
3756         gcc_assert (VALUE_RECURSED_INTO (node->loc));
3757         VALUE_RECURSED_INTO (node->loc) = false;
3758       }
3759 }
3760
3761
3762 /* Hash table iteration argument passed to variable_post_merge.  */
3763 struct dfset_post_merge
3764 {
3765   /* The new input set for the current block.  */
3766   dataflow_set *set;
3767   /* Pointer to the permanent input set for the current block, or
3768      NULL.  */
3769   dataflow_set **permp;
3770 };
3771
3772 /* Create values for incoming expressions associated with one-part
3773    variables that don't have value numbers for them.  */
3774
3775 static int
3776 variable_post_merge_new_vals (void **slot, void *info)
3777 {
3778   struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info;
3779   dataflow_set *set = dfpm->set;
3780   variable var = (variable)*slot;
3781   location_chain node;
3782
3783   if (!dv_onepart_p (var->dv) || !var->n_var_parts)
3784     return 1;
3785
3786   gcc_assert (var->n_var_parts == 1);
3787
3788   if (dv_is_decl_p (var->dv))
3789     {
3790       bool check_dupes = false;
3791
3792     restart:
3793       for (node = var->var_part[0].loc_chain; node; node = node->next)
3794         {
3795           if (GET_CODE (node->loc) == VALUE)
3796             gcc_assert (!VALUE_RECURSED_INTO (node->loc));
3797           else if (GET_CODE (node->loc) == REG)
3798             {
3799               attrs att, *attp, *curp = NULL;
3800
3801               if (var->refcount != 1)
3802                 {
3803                   slot = unshare_variable (set, slot, var,
3804                                            VAR_INIT_STATUS_INITIALIZED);
3805                   var = (variable)*slot;
3806                   goto restart;
3807                 }
3808
3809               for (attp = &set->regs[REGNO (node->loc)]; (att = *attp);
3810                    attp = &att->next)
3811                 if (att->offset == 0
3812                     && GET_MODE (att->loc) == GET_MODE (node->loc))
3813                   {
3814                     if (dv_is_value_p (att->dv))
3815                       {
3816                         rtx cval = dv_as_value (att->dv);
3817                         node->loc = cval;
3818                         check_dupes = true;
3819                         break;
3820                       }
3821                     else if (dv_as_opaque (att->dv) == dv_as_opaque (var->dv))
3822                       curp = attp;
3823                   }
3824
3825               if (!curp)
3826                 {
3827                   curp = attp;
3828                   while (*curp)
3829                     if ((*curp)->offset == 0
3830                         && GET_MODE ((*curp)->loc) == GET_MODE (node->loc)
3831                         && dv_as_opaque ((*curp)->dv) == dv_as_opaque (var->dv))
3832                       break;
3833                     else
3834                       curp = &(*curp)->next;
3835                   gcc_assert (*curp);
3836                 }
3837
3838               if (!att)
3839                 {
3840                   decl_or_value cdv;
3841                   rtx cval;
3842
3843                   if (!*dfpm->permp)
3844                     {
3845                       *dfpm->permp = XNEW (dataflow_set);
3846                       dataflow_set_init (*dfpm->permp);
3847                     }
3848
3849                   for (att = (*dfpm->permp)->regs[REGNO (node->loc)];
3850                        att; att = att->next)
3851                     if (GET_MODE (att->loc) == GET_MODE (node->loc))
3852                       {
3853                         gcc_assert (att->offset == 0);
3854                         gcc_assert (dv_is_value_p (att->dv));
3855                         val_reset (set, att->dv);
3856                         break;
3857                       }
3858
3859                   if (att)
3860                     {
3861                       cdv = att->dv;
3862                       cval = dv_as_value (cdv);
3863                     }
3864                   else
3865                     {
3866                       /* Create a unique value to hold this register,
3867                          that ought to be found and reused in
3868                          subsequent rounds.  */
3869                       cselib_val *v;
3870                       gcc_assert (!cselib_lookup (node->loc,
3871                                                   GET_MODE (node->loc), 0));
3872                       v = cselib_lookup (node->loc, GET_MODE (node->loc), 1);
3873                       cselib_preserve_value (v);
3874                       cselib_invalidate_rtx (node->loc);
3875                       cval = v->val_rtx;
3876                       cdv = dv_from_value (cval);
3877                       if (dump_file)
3878                         fprintf (dump_file,
3879                                  "Created new value %u:%u for reg %i\n",
3880                                  v->uid, v->hash, REGNO (node->loc));
3881                     }
3882
3883                   var_reg_decl_set (*dfpm->permp, node->loc,
3884                                     VAR_INIT_STATUS_INITIALIZED,
3885                                     cdv, 0, NULL, INSERT);
3886
3887                   node->loc = cval;
3888                   check_dupes = true;
3889                 }
3890
3891               /* Remove attribute referring to the decl, which now
3892                  uses the value for the register, already existing or
3893                  to be added when we bring perm in.  */
3894               att = *curp;
3895               *curp = att->next;
3896               pool_free (attrs_pool, att);
3897             }
3898         }
3899
3900       if (check_dupes)
3901         remove_duplicate_values (var);
3902     }
3903
3904   return 1;
3905 }
3906
3907 /* Reset values in the permanent set that are not associated with the
3908    chosen expression.  */
3909
3910 static int
3911 variable_post_merge_perm_vals (void **pslot, void *info)
3912 {
3913   struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info;
3914   dataflow_set *set = dfpm->set;
3915   variable pvar = (variable)*pslot, var;
3916   location_chain pnode;
3917   decl_or_value dv;
3918   attrs att;
3919
3920   gcc_assert (dv_is_value_p (pvar->dv));
3921   gcc_assert (pvar->n_var_parts == 1);
3922   pnode = pvar->var_part[0].loc_chain;
3923   gcc_assert (pnode);
3924   gcc_assert (!pnode->next);
3925   gcc_assert (REG_P (pnode->loc));
3926
3927   dv = pvar->dv;
3928
3929   var = shared_hash_find (set->vars, dv);
3930   if (var)
3931     {
3932       if (find_loc_in_1pdv (pnode->loc, var, shared_hash_htab (set->vars)))
3933         return 1;
3934       val_reset (set, dv);
3935     }
3936
3937   for (att = set->regs[REGNO (pnode->loc)]; att; att = att->next)
3938     if (att->offset == 0
3939         && GET_MODE (att->loc) == GET_MODE (pnode->loc)
3940         && dv_is_value_p (att->dv))
3941       break;
3942
3943   /* If there is a value associated with this register already, create
3944      an equivalence.  */
3945   if (att && dv_as_value (att->dv) != dv_as_value (dv))
3946     {
3947       rtx cval = dv_as_value (att->dv);
3948       set_variable_part (set, cval, dv, 0, pnode->init, NULL, INSERT);
3949       set_variable_part (set, dv_as_value (dv), att->dv, 0, pnode->init,
3950                          NULL, INSERT);
3951     }
3952   else if (!att)
3953     {
3954       attrs_list_insert (&set->regs[REGNO (pnode->loc)],
3955                          dv, 0, pnode->loc);
3956       variable_union (pslot, set);
3957     }
3958
3959   return 1;
3960 }
3961
3962 /* Just checking stuff and registering register attributes for
3963    now.  */
3964
3965 static void
3966 dataflow_post_merge_adjust (dataflow_set *set, dataflow_set **permp)
3967 {
3968   struct dfset_post_merge dfpm;
3969
3970   dfpm.set = set;
3971   dfpm.permp = permp;
3972
3973   htab_traverse (shared_hash_htab (set->vars), variable_post_merge_new_vals,
3974                  &dfpm);
3975   if (*permp)
3976     htab_traverse (shared_hash_htab ((*permp)->vars),
3977                    variable_post_merge_perm_vals, &dfpm);
3978   htab_traverse (shared_hash_htab (set->vars), canonicalize_values_star, set);
3979   htab_traverse (shared_hash_htab (set->vars), canonicalize_vars_star, set);
3980 }
3981
3982 /* Return a node whose loc is a MEM that refers to EXPR in the
3983    location list of a one-part variable or value VAR, or in that of
3984    any values recursively mentioned in the location lists.  */
3985
3986 static location_chain
3987 find_mem_expr_in_1pdv (tree expr, rtx val, htab_t vars)
3988 {
3989   location_chain node;
3990   decl_or_value dv;
3991   variable var;
3992   location_chain where = NULL;
3993
3994   if (!val)
3995     return NULL;
3996
3997   gcc_assert (GET_CODE (val) == VALUE);
3998
3999   gcc_assert (!VALUE_RECURSED_INTO (val));
4000
4001   dv = dv_from_value (val);
4002   var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
4003
4004   if (!var)
4005     return NULL;
4006
4007   gcc_assert (dv_onepart_p (var->dv));
4008
4009   if (!var->n_var_parts)
4010     return NULL;
4011
4012   gcc_assert (var->var_part[0].offset == 0);
4013
4014   VALUE_RECURSED_INTO (val) = true;
4015
4016   for (node = var->var_part[0].loc_chain; node; node = node->next)
4017     if (MEM_P (node->loc) && MEM_EXPR (node->loc) == expr
4018         && MEM_OFFSET (node->loc) == 0)
4019       {
4020         where = node;
4021         break;
4022       }
4023     else if (GET_CODE (node->loc) == VALUE
4024              && !VALUE_RECURSED_INTO (node->loc)
4025              && (where = find_mem_expr_in_1pdv (expr, node->loc, vars)))
4026       break;
4027
4028   VALUE_RECURSED_INTO (val) = false;
4029
4030   return where;
4031 }
4032
4033 /* Return TRUE if the value of MEM may vary across a call.  */
4034
4035 static bool
4036 mem_dies_at_call (rtx mem)
4037 {
4038   tree expr = MEM_EXPR (mem);
4039   tree decl;
4040
4041   if (!expr)
4042     return true;
4043
4044   decl = get_base_address (expr);
4045
4046   if (!decl)
4047     return true;
4048
4049   if (!DECL_P (decl))
4050     return true;
4051
4052   return (may_be_aliased (decl)
4053           || (!TREE_READONLY (decl) && is_global_var (decl)));
4054 }
4055
4056 /* Remove all MEMs from the location list of a hash table entry for a
4057    one-part variable, except those whose MEM attributes map back to
4058    the variable itself, directly or within a VALUE.  */
4059
4060 static int
4061 dataflow_set_preserve_mem_locs (void **slot, void *data)
4062 {
4063   dataflow_set *set = (dataflow_set *) data;
4064   variable var = (variable) *slot;
4065
4066   if (dv_is_decl_p (var->dv) && dv_onepart_p (var->dv))
4067     {
4068       tree decl = dv_as_decl (var->dv);
4069       location_chain loc, *locp;
4070       bool changed = false;
4071
4072       if (!var->n_var_parts)
4073         return 1;
4074
4075       gcc_assert (var->n_var_parts == 1);
4076
4077       if (shared_var_p (var, set->vars))
4078         {
4079           for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
4080             {
4081               /* We want to remove dying MEMs that doesn't refer to
4082                  DECL.  */
4083               if (GET_CODE (loc->loc) == MEM
4084                   && (MEM_EXPR (loc->loc) != decl
4085                       || MEM_OFFSET (loc->loc))
4086                   && !mem_dies_at_call (loc->loc))
4087                 break;
4088               /* We want to move here MEMs that do refer to DECL.  */
4089               else if (GET_CODE (loc->loc) == VALUE
4090                        && find_mem_expr_in_1pdv (decl, loc->loc,
4091                                                  shared_hash_htab (set->vars)))
4092                 break;
4093             }
4094
4095           if (!loc)
4096             return 1;
4097
4098           slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
4099           var = (variable)*slot;
4100           gcc_assert (var->n_var_parts == 1);
4101         }
4102
4103       for (locp = &var->var_part[0].loc_chain, loc = *locp;
4104            loc; loc = *locp)
4105         {
4106           rtx old_loc = loc->loc;
4107           if (GET_CODE (old_loc) == VALUE)
4108             {
4109               location_chain mem_node
4110                 = find_mem_expr_in_1pdv (decl, loc->loc,
4111                                          shared_hash_htab (set->vars));
4112
4113               /* ??? This picks up only one out of multiple MEMs that
4114                  refer to the same variable.  Do we ever need to be
4115                  concerned about dealing with more than one, or, given
4116                  that they should all map to the same variable
4117                  location, their addresses will have been merged and
4118                  they will be regarded as equivalent?  */
4119               if (mem_node)
4120                 {
4121                   loc->loc = mem_node->loc;
4122                   loc->set_src = mem_node->set_src;
4123                   loc->init = MIN (loc->init, mem_node->init);
4124                 }
4125             }
4126
4127           if (GET_CODE (loc->loc) != MEM
4128               || (MEM_EXPR (loc->loc) == decl
4129                   && MEM_OFFSET (loc->loc) == 0)
4130               || !mem_dies_at_call (loc->loc))
4131             {
4132               if (old_loc != loc->loc && emit_notes)
4133                 {
4134                   if (old_loc == var->var_part[0].cur_loc)
4135                     {
4136                       changed = true;
4137                       var->var_part[0].cur_loc = NULL;
4138                       var->cur_loc_changed = true;
4139                     }
4140                   add_value_chains (var->dv, loc->loc);
4141                   remove_value_chains (var->dv, old_loc);
4142                 }
4143               locp = &loc->next;
4144               continue;
4145             }
4146
4147           if (emit_notes)
4148             {
4149               remove_value_chains (var->dv, old_loc);
4150               if (old_loc == var->var_part[0].cur_loc)
4151                 {
4152                   changed = true;
4153                   var->var_part[0].cur_loc = NULL;
4154                   var->cur_loc_changed = true;
4155                 }
4156             }
4157           *locp = loc->next;
4158           pool_free (loc_chain_pool, loc);
4159         }
4160
4161       if (!var->var_part[0].loc_chain)
4162         {
4163           var->n_var_parts--;
4164           changed = true;
4165         }
4166       if (changed)
4167         variable_was_changed (var, set);
4168     }
4169
4170   return 1;
4171 }
4172
4173 /* Remove all MEMs from the location list of a hash table entry for a
4174    value.  */
4175
4176 static int
4177 dataflow_set_remove_mem_locs (void **slot, void *data)
4178 {
4179   dataflow_set *set = (dataflow_set *) data;
4180   variable var = (variable) *slot;
4181
4182   if (dv_is_value_p (var->dv))
4183     {
4184       location_chain loc, *locp;
4185       bool changed = false;
4186
4187       gcc_assert (var->n_var_parts == 1);
4188
4189       if (shared_var_p (var, set->vars))
4190         {
4191           for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
4192             if (GET_CODE (loc->loc) == MEM
4193                 && mem_dies_at_call (loc->loc))
4194               break;
4195
4196           if (!loc)
4197             return 1;
4198
4199           slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
4200           var = (variable)*slot;
4201           gcc_assert (var->n_var_parts == 1);
4202         }
4203
4204       for (locp = &var->var_part[0].loc_chain, loc = *locp;
4205            loc; loc = *locp)
4206         {
4207           if (GET_CODE (loc->loc) != MEM
4208               || !mem_dies_at_call (loc->loc))
4209             {
4210               locp = &loc->next;
4211               continue;
4212             }
4213
4214           if (emit_notes)
4215             remove_value_chains (var->dv, loc->loc);
4216           *locp = loc->next;
4217           /* If we have deleted the location which was last emitted
4218              we have to emit new location so add the variable to set
4219              of changed variables.  */
4220           if (var->var_part[0].cur_loc == loc->loc)
4221             {
4222               changed = true;
4223               var->var_part[0].cur_loc = NULL;
4224               var->cur_loc_changed = true;
4225             }
4226           pool_free (loc_chain_pool, loc);
4227         }
4228
4229       if (!var->var_part[0].loc_chain)
4230         {
4231           var->n_var_parts--;
4232           changed = true;
4233         }
4234       if (changed)
4235         variable_was_changed (var, set);
4236     }
4237
4238   return 1;
4239 }
4240
4241 /* Remove all variable-location information about call-clobbered
4242    registers, as well as associations between MEMs and VALUEs.  */
4243
4244 static void
4245 dataflow_set_clear_at_call (dataflow_set *set)
4246 {
4247   int r;
4248
4249   for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
4250     if (TEST_HARD_REG_BIT (regs_invalidated_by_call, r))
4251       var_regno_delete (set, r);
4252
4253   if (MAY_HAVE_DEBUG_INSNS)
4254     {
4255       set->traversed_vars = set->vars;
4256       htab_traverse (shared_hash_htab (set->vars),
4257                      dataflow_set_preserve_mem_locs, set);
4258       set->traversed_vars = set->vars;
4259       htab_traverse (shared_hash_htab (set->vars), dataflow_set_remove_mem_locs,
4260                      set);
4261       set->traversed_vars = NULL;
4262     }
4263 }
4264
4265 /* Flag whether two dataflow sets being compared contain different data.  */
4266 static bool
4267 dataflow_set_different_value;
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   gcc_assert (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);
4310   gcc_assert (lc2);
4311
4312   while (lc1 && lc2)
4313     {
4314       if (loc_cmp (lc1->loc, lc2->loc))
4315         return true;
4316       lc1 = lc1->next;
4317       lc2 = lc2->next;
4318     }
4319
4320   return lc1 != lc2;
4321 }
4322
4323 /* Return true if variables VAR1 and VAR2 are different.  */
4324
4325 static bool
4326 variable_different_p (variable var1, variable var2)
4327 {
4328   int i;
4329
4330   if (var1 == var2)
4331     return false;
4332
4333   if (var1->n_var_parts != var2->n_var_parts)
4334     return true;
4335
4336   for (i = 0; i < var1->n_var_parts; i++)
4337     {
4338       if (var1->var_part[i].offset != var2->var_part[i].offset)
4339         return true;
4340       /* One-part values have locations in a canonical order.  */
4341       if (i == 0 && var1->var_part[i].offset == 0 && dv_onepart_p (var1->dv))
4342         {
4343           gcc_assert (var1->n_var_parts == 1);
4344           gcc_assert (dv_as_opaque (var1->dv) == dv_as_opaque (var2->dv));
4345           return onepart_variable_different_p (var1, var2);
4346         }
4347       if (variable_part_different_p (&var1->var_part[i], &var2->var_part[i]))
4348         return true;
4349       if (variable_part_different_p (&var2->var_part[i], &var1->var_part[i]))
4350         return true;
4351     }
4352   return false;
4353 }
4354
4355 /* Compare variable *SLOT with the same variable in hash table DATA
4356    and set DATAFLOW_SET_DIFFERENT_VALUE if they are different.  */
4357
4358 static int
4359 dataflow_set_different_1 (void **slot, void *data)
4360 {
4361   htab_t htab = (htab_t) data;
4362   variable var1, var2;
4363
4364   var1 = (variable) *slot;
4365   var2 = (variable) htab_find_with_hash (htab, var1->dv,
4366                                          dv_htab_hash (var1->dv));
4367   if (!var2)
4368     {
4369       dataflow_set_different_value = true;
4370
4371       if (dump_file && (dump_flags & TDF_DETAILS))
4372         {
4373           fprintf (dump_file, "dataflow difference found: removal of:\n");
4374           dump_var (var1);
4375         }
4376
4377       /* Stop traversing the hash table.  */
4378       return 0;
4379     }
4380
4381   if (variable_different_p (var1, var2))
4382     {
4383       dataflow_set_different_value = true;
4384
4385       if (dump_file && (dump_flags & TDF_DETAILS))
4386         {
4387           fprintf (dump_file, "dataflow difference found: old and new follow:\n");
4388           dump_var (var1);
4389           dump_var (var2);
4390         }
4391
4392       /* Stop traversing the hash table.  */
4393       return 0;
4394     }
4395
4396   /* Continue traversing the hash table.  */
4397   return 1;
4398 }
4399
4400 /* Return true if dataflow sets OLD_SET and NEW_SET differ.  */
4401
4402 static bool
4403 dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
4404 {
4405   if (old_set->vars == new_set->vars)
4406     return false;
4407
4408   if (htab_elements (shared_hash_htab (old_set->vars))
4409       != htab_elements (shared_hash_htab (new_set->vars)))
4410     return true;
4411
4412   dataflow_set_different_value = false;
4413
4414   htab_traverse (shared_hash_htab (old_set->vars), dataflow_set_different_1,
4415                  shared_hash_htab (new_set->vars));
4416   /* No need to traverse the second hashtab, if both have the same number
4417      of elements and the second one had all entries found in the first one,
4418      then it can't have any extra entries.  */
4419   return dataflow_set_different_value;
4420 }
4421
4422 /* Free the contents of dataflow set SET.  */
4423
4424 static void
4425 dataflow_set_destroy (dataflow_set *set)
4426 {
4427   int i;
4428
4429   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4430     attrs_list_clear (&set->regs[i]);
4431
4432   shared_hash_destroy (set->vars);
4433   set->vars = NULL;
4434 }
4435
4436 /* Return true if RTL X contains a SYMBOL_REF.  */
4437
4438 static bool
4439 contains_symbol_ref (rtx x)
4440 {
4441   const char *fmt;
4442   RTX_CODE code;
4443   int i;
4444
4445   if (!x)
4446     return false;
4447
4448   code = GET_CODE (x);
4449   if (code == SYMBOL_REF)
4450     return true;
4451
4452   fmt = GET_RTX_FORMAT (code);
4453   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4454     {
4455       if (fmt[i] == 'e')
4456         {
4457           if (contains_symbol_ref (XEXP (x, i)))
4458             return true;
4459         }
4460       else if (fmt[i] == 'E')
4461         {
4462           int j;
4463           for (j = 0; j < XVECLEN (x, i); j++)
4464             if (contains_symbol_ref (XVECEXP (x, i, j)))
4465               return true;
4466         }
4467     }
4468
4469   return false;
4470 }
4471
4472 /* Shall EXPR be tracked?  */
4473
4474 static bool
4475 track_expr_p (tree expr, bool need_rtl)
4476 {
4477   rtx decl_rtl;
4478   tree realdecl;
4479
4480   if (TREE_CODE (expr) == DEBUG_EXPR_DECL)
4481     return DECL_RTL_SET_P (expr);
4482
4483   /* If EXPR is not a parameter or a variable do not track it.  */
4484   if (TREE_CODE (expr) != VAR_DECL && TREE_CODE (expr) != PARM_DECL)
4485     return 0;
4486
4487   /* It also must have a name...  */
4488   if (!DECL_NAME (expr) && need_rtl)
4489     return 0;
4490
4491   /* ... and a RTL assigned to it.  */
4492   decl_rtl = DECL_RTL_IF_SET (expr);
4493   if (!decl_rtl && need_rtl)
4494     return 0;
4495
4496   /* If this expression is really a debug alias of some other declaration, we
4497      don't need to track this expression if the ultimate declaration is
4498      ignored.  */
4499   realdecl = expr;
4500   if (DECL_DEBUG_EXPR_IS_FROM (realdecl) && DECL_DEBUG_EXPR (realdecl))
4501     {
4502       realdecl = DECL_DEBUG_EXPR (realdecl);
4503       /* ??? We don't yet know how to emit DW_OP_piece for variable
4504          that has been SRA'ed.  */
4505       if (!DECL_P (realdecl))
4506         return 0;
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           gcc_assert (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 };