OSDN Git Service

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