OSDN Git Service

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