OSDN Git Service

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