OSDN Git Service

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