OSDN Git Service

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