OSDN Git Service

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