OSDN Git Service

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