OSDN Git Service

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