OSDN Git Service

* common.opt (debug_struct_ordinary, debug_struct_generic): New
[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 "toplev.h"
114 #include "params.h"
115 #include "diagnostic.h"
116 #include "tree-pretty-print.h"
117 #include "pointer-set.h"
118 #include "recog.h"
119
120 /* var-tracking.c assumes that tree code with the same value as VALUE rtx code
121    has no chance to appear in REG_EXPR/MEM_EXPRs and isn't a decl.
122    Currently the value is the same as IDENTIFIER_NODE, which has such
123    a property.  If this compile time assertion ever fails, make sure that
124    the new tree code that equals (int) VALUE has the same property.  */
125 extern char check_value_val[(int) VALUE == (int) IDENTIFIER_NODE ? 1 : -1];
126
127 /* Type of micro operation.  */
128 enum micro_operation_type
129 {
130   MO_USE,       /* Use location (REG or MEM).  */
131   MO_USE_NO_VAR,/* Use location which is not associated with a variable
132                    or the variable is not trackable.  */
133   MO_VAL_USE,   /* Use location which is associated with a value.  */
134   MO_VAL_LOC,   /* Use location which appears in a debug insn.  */
135   MO_VAL_SET,   /* Set location associated with a value.  */
136   MO_SET,       /* Set location.  */
137   MO_COPY,      /* Copy the same portion of a variable from one
138                    location to another.  */
139   MO_CLOBBER,   /* Clobber location.  */
140   MO_CALL,      /* Call insn.  */
141   MO_ADJUST     /* Adjust stack pointer.  */
142
143 };
144
145 static const char * const ATTRIBUTE_UNUSED
146 micro_operation_type_name[] = {
147   "MO_USE",
148   "MO_USE_NO_VAR",
149   "MO_VAL_USE",
150   "MO_VAL_LOC",
151   "MO_VAL_SET",
152   "MO_SET",
153   "MO_COPY",
154   "MO_CLOBBER",
155   "MO_CALL",
156   "MO_ADJUST"
157 };
158
159 /* Where shall the note be emitted?  BEFORE or AFTER the instruction.
160    Notes emitted as AFTER_CALL are to take effect during the call,
161    rather than after the call.  */
162 enum emit_note_where
163 {
164   EMIT_NOTE_BEFORE_INSN,
165   EMIT_NOTE_AFTER_INSN,
166   EMIT_NOTE_AFTER_CALL_INSN
167 };
168
169 /* Structure holding information about micro operation.  */
170 typedef struct micro_operation_def
171 {
172   /* Type of micro operation.  */
173   enum micro_operation_type type;
174
175   /* The instruction which the micro operation is in, for MO_USE,
176      MO_USE_NO_VAR, MO_CALL and MO_ADJUST, or the subsequent
177      instruction or note in the original flow (before any var-tracking
178      notes are inserted, to simplify emission of notes), for MO_SET
179      and MO_CLOBBER.  */
180   rtx insn;
181
182   union {
183     /* Location.  For MO_SET and MO_COPY, this is the SET that
184        performs the assignment, if known, otherwise it is the target
185        of the assignment.  For MO_VAL_USE and MO_VAL_SET, it is a
186        CONCAT of the VALUE and the LOC associated with it.  For
187        MO_VAL_LOC, it is a CONCAT of the VALUE and the VAR_LOCATION
188        associated with it.  */
189     rtx loc;
190
191     /* Stack adjustment.  */
192     HOST_WIDE_INT adjust;
193   } u;
194 } micro_operation;
195
196 DEF_VEC_O(micro_operation);
197 DEF_VEC_ALLOC_O(micro_operation,heap);
198
199 /* A declaration of a variable, or an RTL value being handled like a
200    declaration.  */
201 typedef void *decl_or_value;
202
203 /* Structure for passing some other parameters to function
204    emit_note_insn_var_location.  */
205 typedef struct emit_note_data_def
206 {
207   /* The instruction which the note will be emitted before/after.  */
208   rtx insn;
209
210   /* Where the note will be emitted (before/after insn)?  */
211   enum emit_note_where where;
212
213   /* The variables and values active at this point.  */
214   htab_t vars;
215 } emit_note_data;
216
217 /* Description of location of a part of a variable.  The content of a physical
218    register is described by a chain of these structures.
219    The chains are pretty short (usually 1 or 2 elements) and thus
220    chain is the best data structure.  */
221 typedef struct attrs_def
222 {
223   /* Pointer to next member of the list.  */
224   struct attrs_def *next;
225
226   /* The rtx of register.  */
227   rtx loc;
228
229   /* The declaration corresponding to LOC.  */
230   decl_or_value dv;
231
232   /* Offset from start of DECL.  */
233   HOST_WIDE_INT offset;
234 } *attrs;
235
236 /* Structure holding a refcounted hash table.  If refcount > 1,
237    it must be first unshared before modified.  */
238 typedef struct shared_hash_def
239 {
240   /* Reference count.  */
241   int refcount;
242
243   /* Actual hash table.  */
244   htab_t htab;
245 } *shared_hash;
246
247 /* Structure holding the IN or OUT set for a basic block.  */
248 typedef struct dataflow_set_def
249 {
250   /* Adjustment of stack offset.  */
251   HOST_WIDE_INT stack_adjust;
252
253   /* Attributes for registers (lists of attrs).  */
254   attrs regs[FIRST_PSEUDO_REGISTER];
255
256   /* Variable locations.  */
257   shared_hash vars;
258
259   /* Vars that is being traversed.  */
260   shared_hash traversed_vars;
261 } dataflow_set;
262
263 /* The structure (one for each basic block) containing the information
264    needed for variable tracking.  */
265 typedef struct variable_tracking_info_def
266 {
267   /* The vector of micro operations.  */
268   VEC(micro_operation, heap) *mos;
269
270   /* The IN and OUT set for dataflow analysis.  */
271   dataflow_set in;
272   dataflow_set out;
273
274   /* The permanent-in dataflow set for this block.  This is used to
275      hold values for which we had to compute entry values.  ??? This
276      should probably be dynamically allocated, to avoid using more
277      memory in non-debug builds.  */
278   dataflow_set *permp;
279
280   /* Has the block been visited in DFS?  */
281   bool visited;
282
283   /* Has the block been flooded in VTA?  */
284   bool flooded;
285
286 } *variable_tracking_info;
287
288 /* Structure for chaining the locations.  */
289 typedef struct location_chain_def
290 {
291   /* Next element in the chain.  */
292   struct location_chain_def *next;
293
294   /* The location (REG, MEM or VALUE).  */
295   rtx loc;
296
297   /* The "value" stored in this location.  */
298   rtx set_src;
299
300   /* Initialized? */
301   enum var_init_status init;
302 } *location_chain;
303
304 /* Structure describing one part of variable.  */
305 typedef struct variable_part_def
306 {
307   /* Chain of locations of the part.  */
308   location_chain loc_chain;
309
310   /* Location which was last emitted to location list.  */
311   rtx cur_loc;
312
313   /* The offset in the variable.  */
314   HOST_WIDE_INT offset;
315 } variable_part;
316
317 /* Maximum number of location parts.  */
318 #define MAX_VAR_PARTS 16
319
320 /* Structure describing where the variable is located.  */
321 typedef struct variable_def
322 {
323   /* The declaration of the variable, or an RTL value being handled
324      like a declaration.  */
325   decl_or_value dv;
326
327   /* Reference count.  */
328   int refcount;
329
330   /* Number of variable parts.  */
331   char n_var_parts;
332
333   /* True if this variable changed (any of its) cur_loc fields
334      during the current emit_notes_for_changes resp.
335      emit_notes_for_differences call.  */
336   bool cur_loc_changed;
337
338   /* True if this variable_def struct is currently in the
339      changed_variables hash table.  */
340   bool in_changed_variables;
341
342   /* The variable parts.  */
343   variable_part var_part[1];
344 } *variable;
345 typedef const struct variable_def *const_variable;
346
347 /* Structure for chaining backlinks from referenced VALUEs to
348    DVs that are referencing them.  */
349 typedef struct value_chain_def
350 {
351   /* Next value_chain entry.  */
352   struct value_chain_def *next;
353
354   /* The declaration of the variable, or an RTL value
355      being handled like a declaration, whose var_parts[0].loc_chain
356      references the VALUE owning this value_chain.  */
357   decl_or_value dv;
358
359   /* Reference count.  */
360   int refcount;
361 } *value_chain;
362 typedef const struct value_chain_def *const_value_chain;
363
364 /* Pointer to the BB's information specific to variable tracking pass.  */
365 #define VTI(BB) ((variable_tracking_info) (BB)->aux)
366
367 /* Macro to access MEM_OFFSET as an HOST_WIDE_INT.  Evaluates MEM twice.  */
368 #define INT_MEM_OFFSET(mem) (MEM_OFFSET (mem) ? INTVAL (MEM_OFFSET (mem)) : 0)
369
370 /* Alloc pool for struct attrs_def.  */
371 static alloc_pool attrs_pool;
372
373 /* Alloc pool for struct variable_def with MAX_VAR_PARTS entries.  */
374 static alloc_pool var_pool;
375
376 /* Alloc pool for struct variable_def with a single var_part entry.  */
377 static alloc_pool valvar_pool;
378
379 /* Alloc pool for struct location_chain_def.  */
380 static alloc_pool loc_chain_pool;
381
382 /* Alloc pool for struct shared_hash_def.  */
383 static alloc_pool shared_hash_pool;
384
385 /* Alloc pool for struct value_chain_def.  */
386 static alloc_pool value_chain_pool;
387
388 /* Changed variables, notes will be emitted for them.  */
389 static htab_t changed_variables;
390
391 /* Links from VALUEs to DVs referencing them in their current loc_chains.  */
392 static htab_t value_chains;
393
394 /* Shall notes be emitted?  */
395 static bool emit_notes;
396
397 /* Empty shared hashtable.  */
398 static shared_hash empty_shared_hash;
399
400 /* Scratch register bitmap used by cselib_expand_value_rtx.  */
401 static bitmap scratch_regs = NULL;
402
403 /* Variable used to tell whether cselib_process_insn called our hook.  */
404 static bool cselib_hook_called;
405
406 /* Local function prototypes.  */
407 static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
408                                           HOST_WIDE_INT *);
409 static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
410                                                HOST_WIDE_INT *);
411 static bool vt_stack_adjustments (void);
412 static hashval_t variable_htab_hash (const void *);
413 static int variable_htab_eq (const void *, const void *);
414 static void variable_htab_free (void *);
415
416 static void init_attrs_list_set (attrs *);
417 static void attrs_list_clear (attrs *);
418 static attrs attrs_list_member (attrs, decl_or_value, HOST_WIDE_INT);
419 static void attrs_list_insert (attrs *, decl_or_value, HOST_WIDE_INT, rtx);
420 static void attrs_list_copy (attrs *, attrs);
421 static void attrs_list_union (attrs *, attrs);
422
423 static void **unshare_variable (dataflow_set *set, void **slot, variable var,
424                                 enum var_init_status);
425 static void vars_copy (htab_t, htab_t);
426 static tree var_debug_decl (tree);
427 static void var_reg_set (dataflow_set *, rtx, enum var_init_status, rtx);
428 static void var_reg_delete_and_set (dataflow_set *, rtx, bool,
429                                     enum var_init_status, rtx);
430 static void var_reg_delete (dataflow_set *, rtx, bool);
431 static void var_regno_delete (dataflow_set *, int);
432 static void var_mem_set (dataflow_set *, rtx, enum var_init_status, rtx);
433 static void var_mem_delete_and_set (dataflow_set *, rtx, bool,
434                                     enum var_init_status, rtx);
435 static void var_mem_delete (dataflow_set *, rtx, bool);
436
437 static void dataflow_set_init (dataflow_set *);
438 static void dataflow_set_clear (dataflow_set *);
439 static void dataflow_set_copy (dataflow_set *, dataflow_set *);
440 static int variable_union_info_cmp_pos (const void *, const void *);
441 static void dataflow_set_union (dataflow_set *, dataflow_set *);
442 static location_chain find_loc_in_1pdv (rtx, variable, htab_t);
443 static bool canon_value_cmp (rtx, rtx);
444 static int loc_cmp (rtx, rtx);
445 static bool variable_part_different_p (variable_part *, variable_part *);
446 static bool onepart_variable_different_p (variable, variable);
447 static bool variable_different_p (variable, variable);
448 static bool dataflow_set_different (dataflow_set *, dataflow_set *);
449 static void dataflow_set_destroy (dataflow_set *);
450
451 static bool contains_symbol_ref (rtx);
452 static bool track_expr_p (tree, bool);
453 static bool same_variable_part_p (rtx, tree, HOST_WIDE_INT);
454 static int add_uses (rtx *, void *);
455 static void add_uses_1 (rtx *, void *);
456 static void add_stores (rtx, const_rtx, void *);
457 static bool compute_bb_dataflow (basic_block);
458 static bool vt_find_locations (void);
459
460 static void dump_attrs_list (attrs);
461 static int dump_var_slot (void **, void *);
462 static void dump_var (variable);
463 static void dump_vars (htab_t);
464 static void dump_dataflow_set (dataflow_set *);
465 static void dump_dataflow_sets (void);
466
467 static void variable_was_changed (variable, dataflow_set *);
468 static void **set_slot_part (dataflow_set *, rtx, void **,
469                              decl_or_value, HOST_WIDE_INT,
470                              enum var_init_status, rtx);
471 static void set_variable_part (dataflow_set *, rtx,
472                                decl_or_value, HOST_WIDE_INT,
473                                enum var_init_status, rtx, enum insert_option);
474 static void **clobber_slot_part (dataflow_set *, rtx,
475                                  void **, HOST_WIDE_INT, rtx);
476 static void clobber_variable_part (dataflow_set *, rtx,
477                                    decl_or_value, HOST_WIDE_INT, rtx);
478 static void **delete_slot_part (dataflow_set *, rtx, void **, HOST_WIDE_INT);
479 static void delete_variable_part (dataflow_set *, rtx,
480                                   decl_or_value, HOST_WIDE_INT);
481 static int emit_note_insn_var_location (void **, void *);
482 static void emit_notes_for_changes (rtx, enum emit_note_where, shared_hash);
483 static int emit_notes_for_differences_1 (void **, void *);
484 static int emit_notes_for_differences_2 (void **, void *);
485 static void emit_notes_for_differences (rtx, dataflow_set *, dataflow_set *);
486 static void emit_notes_in_bb (basic_block, dataflow_set *);
487 static void vt_emit_notes (void);
488
489 static bool vt_get_decl_and_offset (rtx, tree *, HOST_WIDE_INT *);
490 static void vt_add_function_parameters (void);
491 static bool vt_initialize (void);
492 static void vt_finalize (void);
493
494 /* Given a SET, calculate the amount of stack adjustment it contains
495    PRE- and POST-modifying stack pointer.
496    This function is similar to stack_adjust_offset.  */
497
498 static void
499 stack_adjust_offset_pre_post (rtx pattern, HOST_WIDE_INT *pre,
500                               HOST_WIDE_INT *post)
501 {
502   rtx src = SET_SRC (pattern);
503   rtx dest = SET_DEST (pattern);
504   enum rtx_code code;
505
506   if (dest == stack_pointer_rtx)
507     {
508       /* (set (reg sp) (plus (reg sp) (const_int))) */
509       code = GET_CODE (src);
510       if (! (code == PLUS || code == MINUS)
511           || XEXP (src, 0) != stack_pointer_rtx
512           || !CONST_INT_P (XEXP (src, 1)))
513         return;
514
515       if (code == MINUS)
516         *post += INTVAL (XEXP (src, 1));
517       else
518         *post -= INTVAL (XEXP (src, 1));
519     }
520   else if (MEM_P (dest))
521     {
522       /* (set (mem (pre_dec (reg sp))) (foo)) */
523       src = XEXP (dest, 0);
524       code = GET_CODE (src);
525
526       switch (code)
527         {
528         case PRE_MODIFY:
529         case POST_MODIFY:
530           if (XEXP (src, 0) == stack_pointer_rtx)
531             {
532               rtx val = XEXP (XEXP (src, 1), 1);
533               /* We handle only adjustments by constant amount.  */
534               gcc_assert (GET_CODE (XEXP (src, 1)) == PLUS &&
535                           CONST_INT_P (val));
536
537               if (code == PRE_MODIFY)
538                 *pre -= INTVAL (val);
539               else
540                 *post -= INTVAL (val);
541               break;
542             }
543           return;
544
545         case PRE_DEC:
546           if (XEXP (src, 0) == stack_pointer_rtx)
547             {
548               *pre += GET_MODE_SIZE (GET_MODE (dest));
549               break;
550             }
551           return;
552
553         case POST_DEC:
554           if (XEXP (src, 0) == stack_pointer_rtx)
555             {
556               *post += GET_MODE_SIZE (GET_MODE (dest));
557               break;
558             }
559           return;
560
561         case PRE_INC:
562           if (XEXP (src, 0) == stack_pointer_rtx)
563             {
564               *pre -= GET_MODE_SIZE (GET_MODE (dest));
565               break;
566             }
567           return;
568
569         case POST_INC:
570           if (XEXP (src, 0) == stack_pointer_rtx)
571             {
572               *post -= GET_MODE_SIZE (GET_MODE (dest));
573               break;
574             }
575           return;
576
577         default:
578           return;
579         }
580     }
581 }
582
583 /* Given an INSN, calculate the amount of stack adjustment it contains
584    PRE- and POST-modifying stack pointer.  */
585
586 static void
587 insn_stack_adjust_offset_pre_post (rtx insn, HOST_WIDE_INT *pre,
588                                    HOST_WIDE_INT *post)
589 {
590   rtx pattern;
591
592   *pre = 0;
593   *post = 0;
594
595   pattern = PATTERN (insn);
596   if (RTX_FRAME_RELATED_P (insn))
597     {
598       rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
599       if (expr)
600         pattern = XEXP (expr, 0);
601     }
602
603   if (GET_CODE (pattern) == SET)
604     stack_adjust_offset_pre_post (pattern, pre, post);
605   else if (GET_CODE (pattern) == PARALLEL
606            || GET_CODE (pattern) == SEQUENCE)
607     {
608       int i;
609
610       /* There may be stack adjustments inside compound insns.  Search
611          for them.  */
612       for ( i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
613         if (GET_CODE (XVECEXP (pattern, 0, i)) == SET)
614           stack_adjust_offset_pre_post (XVECEXP (pattern, 0, i), pre, post);
615     }
616 }
617
618 /* Compute stack adjustments for all blocks by traversing DFS tree.
619    Return true when the adjustments on all incoming edges are consistent.
620    Heavily borrowed from pre_and_rev_post_order_compute.  */
621
622 static bool
623 vt_stack_adjustments (void)
624 {
625   edge_iterator *stack;
626   int sp;
627
628   /* Initialize entry block.  */
629   VTI (ENTRY_BLOCK_PTR)->visited = true;
630   VTI (ENTRY_BLOCK_PTR)->in.stack_adjust = INCOMING_FRAME_SP_OFFSET;
631   VTI (ENTRY_BLOCK_PTR)->out.stack_adjust = INCOMING_FRAME_SP_OFFSET;
632
633   /* Allocate stack for back-tracking up CFG.  */
634   stack = XNEWVEC (edge_iterator, n_basic_blocks + 1);
635   sp = 0;
636
637   /* Push the first edge on to the stack.  */
638   stack[sp++] = ei_start (ENTRY_BLOCK_PTR->succs);
639
640   while (sp)
641     {
642       edge_iterator ei;
643       basic_block src;
644       basic_block dest;
645
646       /* Look at the edge on the top of the stack.  */
647       ei = stack[sp - 1];
648       src = ei_edge (ei)->src;
649       dest = ei_edge (ei)->dest;
650
651       /* Check if the edge destination has been visited yet.  */
652       if (!VTI (dest)->visited)
653         {
654           rtx insn;
655           HOST_WIDE_INT pre, post, offset;
656           VTI (dest)->visited = true;
657           VTI (dest)->in.stack_adjust = offset = VTI (src)->out.stack_adjust;
658
659           if (dest != EXIT_BLOCK_PTR)
660             for (insn = BB_HEAD (dest);
661                  insn != NEXT_INSN (BB_END (dest));
662                  insn = NEXT_INSN (insn))
663               if (INSN_P (insn))
664                 {
665                   insn_stack_adjust_offset_pre_post (insn, &pre, &post);
666                   offset += pre + post;
667                 }
668
669           VTI (dest)->out.stack_adjust = offset;
670
671           if (EDGE_COUNT (dest->succs) > 0)
672             /* Since the DEST node has been visited for the first
673                time, check its successors.  */
674             stack[sp++] = ei_start (dest->succs);
675         }
676       else
677         {
678           /* Check whether the adjustments on the edges are the same.  */
679           if (VTI (dest)->in.stack_adjust != VTI (src)->out.stack_adjust)
680             {
681               free (stack);
682               return false;
683             }
684
685           if (! ei_one_before_end_p (ei))
686             /* Go to the next edge.  */
687             ei_next (&stack[sp - 1]);
688           else
689             /* Return to previous level if there are no more edges.  */
690             sp--;
691         }
692     }
693
694   free (stack);
695   return true;
696 }
697
698 /* arg_pointer_rtx resp. frame_pointer_rtx if stack_pointer_rtx or
699    hard_frame_pointer_rtx is being mapped to it and offset for it.  */
700 static rtx cfa_base_rtx;
701 static HOST_WIDE_INT cfa_base_offset;
702
703 /* Compute a CFA-based value for the stack pointer.  */
704
705 static inline rtx
706 compute_cfa_pointer (HOST_WIDE_INT adjustment)
707 {
708   return plus_constant (cfa_base_rtx, adjustment + cfa_base_offset);
709 }
710
711 /* Adjustment for hard_frame_pointer_rtx to cfa base reg,
712    or -1 if the replacement shouldn't be done.  */
713 static HOST_WIDE_INT hard_frame_pointer_adjustment = -1;
714
715 /* Data for adjust_mems callback.  */
716
717 struct adjust_mem_data
718 {
719   bool store;
720   enum machine_mode mem_mode;
721   HOST_WIDE_INT stack_adjust;
722   rtx side_effects;
723 };
724
725 /* Helper for adjust_mems.  Return 1 if *loc is unsuitable for
726    transformation of wider mode arithmetics to narrower mode,
727    -1 if it is suitable and subexpressions shouldn't be
728    traversed and 0 if it is suitable and subexpressions should
729    be traversed.  Called through for_each_rtx.  */
730
731 static int
732 use_narrower_mode_test (rtx *loc, void *data)
733 {
734   rtx subreg = (rtx) data;
735
736   if (CONSTANT_P (*loc))
737     return -1;
738   switch (GET_CODE (*loc))
739     {
740     case REG:
741       if (cselib_lookup (*loc, GET_MODE (SUBREG_REG (subreg)), 0))
742         return 1;
743       return -1;
744     case PLUS:
745     case MINUS:
746     case MULT:
747       return 0;
748     case ASHIFT:
749       if (for_each_rtx (&XEXP (*loc, 0), use_narrower_mode_test, data))
750         return 1;
751       else
752         return -1;
753     default:
754       return 1;
755     }
756 }
757
758 /* Transform X into narrower mode MODE from wider mode WMODE.  */
759
760 static rtx
761 use_narrower_mode (rtx x, enum machine_mode mode, enum machine_mode wmode)
762 {
763   rtx op0, op1;
764   if (CONSTANT_P (x))
765     return lowpart_subreg (mode, x, wmode);
766   switch (GET_CODE (x))
767     {
768     case REG:
769       return lowpart_subreg (mode, x, wmode);
770     case PLUS:
771     case MINUS:
772     case MULT:
773       op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
774       op1 = use_narrower_mode (XEXP (x, 1), mode, wmode);
775       return simplify_gen_binary (GET_CODE (x), mode, op0, op1);
776     case ASHIFT:
777       op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
778       return simplify_gen_binary (ASHIFT, mode, op0, XEXP (x, 1));
779     default:
780       gcc_unreachable ();
781     }
782 }
783
784 /* Helper function for adjusting used MEMs.  */
785
786 static rtx
787 adjust_mems (rtx loc, const_rtx old_rtx, void *data)
788 {
789   struct adjust_mem_data *amd = (struct adjust_mem_data *) data;
790   rtx mem, addr = loc, tem;
791   enum machine_mode mem_mode_save;
792   bool store_save;
793   switch (GET_CODE (loc))
794     {
795     case REG:
796       /* Don't do any sp or fp replacements outside of MEM addresses
797          on the LHS.  */
798       if (amd->mem_mode == VOIDmode && amd->store)
799         return loc;
800       if (loc == stack_pointer_rtx
801           && !frame_pointer_needed
802           && cfa_base_rtx)
803         return compute_cfa_pointer (amd->stack_adjust);
804       else if (loc == hard_frame_pointer_rtx
805                && frame_pointer_needed
806                && hard_frame_pointer_adjustment != -1
807                && cfa_base_rtx)
808         return compute_cfa_pointer (hard_frame_pointer_adjustment);
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 #ifdef ENABLE_RTL_CHECKING
7100 /* Used to verify that cur_loc_changed updating is safe.  */
7101 static struct pointer_map_t *emitted_notes;
7102
7103 /* Strip REG_POINTER from REGs and MEM_POINTER from MEMs in order to
7104    avoid differences in commutative operand simplification.  */
7105 static rtx
7106 strip_pointer_flags (rtx x, const_rtx old_rtx ATTRIBUTE_UNUSED,
7107                      void *data ATTRIBUTE_UNUSED)
7108 {
7109   if (REG_P (x) && REG_POINTER (x))
7110     return gen_rtx_REG (GET_MODE (x), REGNO (x));
7111   if (MEM_P (x) && MEM_POINTER (x))
7112     return gen_rtx_MEM (GET_MODE (x), XEXP (x, 0));
7113   return NULL_RTX;
7114 }
7115 #endif
7116
7117 /* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP.  DATA contains
7118    additional parameters: WHERE specifies whether the note shall be emitted
7119    before or after instruction INSN.  */
7120
7121 static int
7122 emit_note_insn_var_location (void **varp, void *data)
7123 {
7124   variable var = (variable) *varp;
7125   rtx insn = ((emit_note_data *)data)->insn;
7126   enum emit_note_where where = ((emit_note_data *)data)->where;
7127   htab_t vars = ((emit_note_data *)data)->vars;
7128   rtx note, note_vl;
7129   int i, j, n_var_parts;
7130   bool complete;
7131   enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED;
7132   HOST_WIDE_INT last_limit;
7133   tree type_size_unit;
7134   HOST_WIDE_INT offsets[MAX_VAR_PARTS];
7135   rtx loc[MAX_VAR_PARTS];
7136   tree decl;
7137   location_chain lc;
7138
7139   if (dv_is_value_p (var->dv))
7140     goto value_or_debug_decl;
7141
7142   decl = dv_as_decl (var->dv);
7143
7144   if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
7145     goto value_or_debug_decl;
7146
7147   complete = true;
7148   last_limit = 0;
7149   n_var_parts = 0;
7150   if (!MAY_HAVE_DEBUG_INSNS)
7151     {
7152       for (i = 0; i < var->n_var_parts; i++)
7153         if (var->var_part[i].cur_loc == NULL && var->var_part[i].loc_chain)
7154           {
7155             var->var_part[i].cur_loc = var->var_part[i].loc_chain->loc;
7156             var->cur_loc_changed = true;
7157           }
7158       if (var->n_var_parts == 0)
7159         var->cur_loc_changed = true;
7160     }
7161 #ifndef ENABLE_RTL_CHECKING
7162   if (!var->cur_loc_changed)
7163     goto clear;
7164 #endif
7165   for (i = 0; i < var->n_var_parts; i++)
7166     {
7167       enum machine_mode mode, wider_mode;
7168       rtx loc2;
7169
7170       if (last_limit < var->var_part[i].offset)
7171         {
7172           complete = false;
7173           break;
7174         }
7175       else if (last_limit > var->var_part[i].offset)
7176         continue;
7177       offsets[n_var_parts] = var->var_part[i].offset;
7178       if (!var->var_part[i].cur_loc)
7179         {
7180           complete = false;
7181           continue;
7182         }
7183       loc2 = vt_expand_loc (var->var_part[i].cur_loc, vars);
7184       if (!loc2)
7185         {
7186           complete = false;
7187           continue;
7188         }
7189       loc[n_var_parts] = loc2;
7190       mode = GET_MODE (var->var_part[i].cur_loc);
7191       if (mode == VOIDmode && dv_onepart_p (var->dv))
7192         mode = DECL_MODE (decl);
7193       for (lc = var->var_part[i].loc_chain; lc; lc = lc->next)
7194         if (var->var_part[i].cur_loc == lc->loc)
7195           {
7196             initialized = lc->init;
7197             break;
7198           }
7199       gcc_assert (lc);
7200       last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
7201
7202       /* Attempt to merge adjacent registers or memory.  */
7203       wider_mode = GET_MODE_WIDER_MODE (mode);
7204       for (j = i + 1; j < var->n_var_parts; j++)
7205         if (last_limit <= var->var_part[j].offset)
7206           break;
7207       if (j < var->n_var_parts
7208           && wider_mode != VOIDmode
7209           && var->var_part[j].cur_loc
7210           && mode == GET_MODE (var->var_part[j].cur_loc)
7211           && (REG_P (loc[n_var_parts]) || MEM_P (loc[n_var_parts]))
7212           && last_limit == var->var_part[j].offset
7213           && (loc2 = vt_expand_loc (var->var_part[j].cur_loc, vars))
7214           && GET_CODE (loc[n_var_parts]) == GET_CODE (loc2))
7215         {
7216           rtx new_loc = NULL;
7217
7218           if (REG_P (loc[n_var_parts])
7219               && hard_regno_nregs[REGNO (loc[n_var_parts])][mode] * 2
7220                  == hard_regno_nregs[REGNO (loc[n_var_parts])][wider_mode]
7221               && end_hard_regno (mode, REGNO (loc[n_var_parts]))
7222                  == REGNO (loc2))
7223             {
7224               if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
7225                 new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
7226                                            mode, 0);
7227               else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
7228                 new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
7229               if (new_loc)
7230                 {
7231                   if (!REG_P (new_loc)
7232                       || REGNO (new_loc) != REGNO (loc[n_var_parts]))
7233                     new_loc = NULL;
7234                   else
7235                     REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
7236                 }
7237             }
7238           else if (MEM_P (loc[n_var_parts])
7239                    && GET_CODE (XEXP (loc2, 0)) == PLUS
7240                    && REG_P (XEXP (XEXP (loc2, 0), 0))
7241                    && CONST_INT_P (XEXP (XEXP (loc2, 0), 1)))
7242             {
7243               if ((REG_P (XEXP (loc[n_var_parts], 0))
7244                    && rtx_equal_p (XEXP (loc[n_var_parts], 0),
7245                                    XEXP (XEXP (loc2, 0), 0))
7246                    && INTVAL (XEXP (XEXP (loc2, 0), 1))
7247                       == GET_MODE_SIZE (mode))
7248                   || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
7249                       && CONST_INT_P (XEXP (XEXP (loc[n_var_parts], 0), 1))
7250                       && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
7251                                       XEXP (XEXP (loc2, 0), 0))
7252                       && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
7253                          + GET_MODE_SIZE (mode)
7254                          == INTVAL (XEXP (XEXP (loc2, 0), 1))))
7255                 new_loc = adjust_address_nv (loc[n_var_parts],
7256                                              wider_mode, 0);
7257             }
7258
7259           if (new_loc)
7260             {
7261               loc[n_var_parts] = new_loc;
7262               mode = wider_mode;
7263               last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
7264               i = j;
7265             }
7266         }
7267       ++n_var_parts;
7268     }
7269   type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl));
7270   if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
7271     complete = false;
7272
7273   if (! flag_var_tracking_uninit)
7274     initialized = VAR_INIT_STATUS_INITIALIZED;
7275
7276   note_vl = NULL_RTX;
7277   if (!complete)
7278     note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, NULL_RTX,
7279                                     (int) initialized);
7280   else if (n_var_parts == 1)
7281     {
7282       rtx expr_list;
7283
7284       if (offsets[0] || GET_CODE (loc[0]) == PARALLEL)
7285         expr_list = gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
7286       else
7287         expr_list = loc[0];
7288
7289       note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, expr_list,
7290                                       (int) initialized);
7291     }
7292   else if (n_var_parts)
7293     {
7294       rtx parallel;
7295
7296       for (i = 0; i < n_var_parts; i++)
7297         loc[i]
7298           = gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));
7299
7300       parallel = gen_rtx_PARALLEL (VOIDmode,
7301                                    gen_rtvec_v (n_var_parts, loc));
7302       note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl,
7303                                       parallel, (int) initialized);
7304     }
7305
7306 #ifdef ENABLE_RTL_CHECKING
7307   if (note_vl)
7308     {
7309       void **note_slot = pointer_map_insert (emitted_notes, decl);
7310       rtx pnote = (rtx) *note_slot;
7311       if (!var->cur_loc_changed && (pnote || PAT_VAR_LOCATION_LOC (note_vl)))
7312         {
7313           rtx old_vl, new_vl;
7314           gcc_assert (pnote);
7315           old_vl = PAT_VAR_LOCATION_LOC (pnote);
7316           new_vl = PAT_VAR_LOCATION_LOC (note_vl);
7317           if (!rtx_equal_p (old_vl, new_vl))
7318             {
7319               /* There might be differences caused by REG_POINTER
7320                  differences.  REG_POINTER affects
7321                  swap_commutative_operands_p.  */
7322               old_vl = simplify_replace_fn_rtx (old_vl, NULL_RTX,
7323                                                 strip_pointer_flags, NULL);
7324               new_vl = simplify_replace_fn_rtx (new_vl, NULL_RTX,
7325                                                 strip_pointer_flags, NULL);
7326               gcc_assert (rtx_equal_p (old_vl, new_vl));
7327               PAT_VAR_LOCATION_LOC (note_vl) = new_vl;
7328             }
7329         }
7330       *note_slot = (void *) note_vl;
7331     }
7332   if (!var->cur_loc_changed)
7333     goto clear;
7334 #endif
7335
7336   if (where != EMIT_NOTE_BEFORE_INSN)
7337     {
7338       note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
7339       if (where == EMIT_NOTE_AFTER_CALL_INSN)
7340         NOTE_DURING_CALL_P (note) = true;
7341     }
7342   else
7343     {
7344       /* Make sure that the call related notes come first.  */
7345       while (NEXT_INSN (insn)
7346              && NOTE_P (insn)
7347              && NOTE_DURING_CALL_P (insn))
7348         insn = NEXT_INSN (insn);
7349       if (NOTE_P (insn) && NOTE_DURING_CALL_P (insn))
7350         note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
7351       else
7352         note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
7353     }
7354   NOTE_VAR_LOCATION (note) = note_vl;
7355
7356  clear:
7357   set_dv_changed (var->dv, false);
7358   var->cur_loc_changed = false;
7359   gcc_assert (var->in_changed_variables);
7360   var->in_changed_variables = false;
7361   htab_clear_slot (changed_variables, varp);
7362
7363   /* Continue traversing the hash table.  */
7364   return 1;
7365
7366  value_or_debug_decl:
7367   if (dv_changed_p (var->dv) && var->n_var_parts)
7368     {
7369       location_chain lc;
7370       bool cur_loc_changed;
7371
7372       if (var->var_part[0].cur_loc
7373           && vt_expand_loc_dummy (var->var_part[0].cur_loc, vars,
7374                                   &cur_loc_changed))
7375         goto clear;
7376       for (lc = var->var_part[0].loc_chain; lc; lc = lc->next)
7377         if (lc->loc != var->var_part[0].cur_loc
7378             && vt_expand_loc_dummy (lc->loc, vars, &cur_loc_changed))
7379           break;
7380       var->var_part[0].cur_loc = lc ? lc->loc : NULL_RTX;
7381     }
7382   goto clear;
7383 }
7384
7385 DEF_VEC_P (variable);
7386 DEF_VEC_ALLOC_P (variable, heap);
7387
7388 /* Stack of variable_def pointers that need processing with
7389    check_changed_vars_2.  */
7390
7391 static VEC (variable, heap) *changed_variables_stack;
7392
7393 /* VALUEs with no variables that need set_dv_changed (val, false)
7394    called before check_changed_vars_3.  */
7395
7396 static VEC (rtx, heap) *changed_values_stack;
7397
7398 /* Helper function for check_changed_vars_1 and check_changed_vars_2.  */
7399
7400 static void
7401 check_changed_vars_0 (decl_or_value dv, htab_t htab)
7402 {
7403   value_chain vc
7404     = (value_chain) htab_find_with_hash (value_chains, dv, dv_htab_hash (dv));
7405
7406   if (vc == NULL)
7407     return;
7408   for (vc = vc->next; vc; vc = vc->next)
7409     if (!dv_changed_p (vc->dv))
7410       {
7411         variable vcvar
7412           = (variable) htab_find_with_hash (htab, vc->dv,
7413                                             dv_htab_hash (vc->dv));
7414         if (vcvar)
7415           {
7416             set_dv_changed (vc->dv, true);
7417             VEC_safe_push (variable, heap, changed_variables_stack, vcvar);
7418           }
7419         else if (dv_is_value_p (vc->dv))
7420           {
7421             set_dv_changed (vc->dv, true);
7422             VEC_safe_push (rtx, heap, changed_values_stack,
7423                            dv_as_value (vc->dv));
7424             check_changed_vars_0 (vc->dv, htab);
7425           }
7426       }
7427 }
7428
7429 /* Populate changed_variables_stack with variable_def pointers
7430    that need variable_was_changed called on them.  */
7431
7432 static int
7433 check_changed_vars_1 (void **slot, void *data)
7434 {
7435   variable var = (variable) *slot;
7436   htab_t htab = (htab_t) data;
7437
7438   if (dv_is_value_p (var->dv)
7439       || TREE_CODE (dv_as_decl (var->dv)) == DEBUG_EXPR_DECL)
7440     check_changed_vars_0 (var->dv, htab);
7441   return 1;
7442 }
7443
7444 /* Add VAR to changed_variables and also for VALUEs add recursively
7445    all DVs that aren't in changed_variables yet but reference the
7446    VALUE from its loc_chain.  */
7447
7448 static void
7449 check_changed_vars_2 (variable var, htab_t htab)
7450 {
7451   variable_was_changed (var, NULL);
7452   if (dv_is_value_p (var->dv)
7453       || TREE_CODE (dv_as_decl (var->dv)) == DEBUG_EXPR_DECL)
7454     check_changed_vars_0 (var->dv, htab);
7455 }
7456
7457 /* For each changed decl (except DEBUG_EXPR_DECLs) recompute
7458    cur_loc if needed (and cur_loc of all VALUEs and DEBUG_EXPR_DECLs
7459    it needs and are also in changed variables) and track whether
7460    cur_loc (or anything it uses to compute location) had to change
7461    during the current emit_notes_for_changes call.  */
7462
7463 static int
7464 check_changed_vars_3 (void **slot, void *data)
7465 {
7466   variable var = (variable) *slot;
7467   htab_t vars = (htab_t) data;
7468   int i;
7469   location_chain lc;
7470   bool cur_loc_changed;
7471
7472   if (dv_is_value_p (var->dv)
7473       || TREE_CODE (dv_as_decl (var->dv)) == DEBUG_EXPR_DECL)
7474     return 1;
7475
7476   for (i = 0; i < var->n_var_parts; i++)
7477     {
7478       if (var->var_part[i].cur_loc
7479           && vt_expand_loc_dummy (var->var_part[i].cur_loc, vars,
7480                                   &cur_loc_changed))
7481         {
7482           if (cur_loc_changed)
7483             var->cur_loc_changed = true;
7484           continue;
7485         }
7486       for (lc = var->var_part[i].loc_chain; lc; lc = lc->next)
7487         if (lc->loc != var->var_part[i].cur_loc
7488             && vt_expand_loc_dummy (lc->loc, vars, &cur_loc_changed))
7489           break;
7490       if (lc || var->var_part[i].cur_loc)
7491         var->cur_loc_changed = true;
7492       var->var_part[i].cur_loc = lc ? lc->loc : NULL_RTX;
7493     }
7494   if (var->n_var_parts == 0)
7495     var->cur_loc_changed = true;
7496   return 1;
7497 }
7498
7499 /* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
7500    CHANGED_VARIABLES and delete this chain.  WHERE specifies whether the notes
7501    shall be emitted before of after instruction INSN.  */
7502
7503 static void
7504 emit_notes_for_changes (rtx insn, enum emit_note_where where,
7505                         shared_hash vars)
7506 {
7507   emit_note_data data;
7508   htab_t htab = shared_hash_htab (vars);
7509
7510   if (!htab_elements (changed_variables))
7511     return;
7512
7513   if (MAY_HAVE_DEBUG_INSNS)
7514     {
7515       /* Unfortunately this has to be done in two steps, because
7516          we can't traverse a hashtab into which we are inserting
7517          through variable_was_changed.  */
7518       htab_traverse (changed_variables, check_changed_vars_1, htab);
7519       while (VEC_length (variable, changed_variables_stack) > 0)
7520         check_changed_vars_2 (VEC_pop (variable, changed_variables_stack),
7521                               htab);
7522       while (VEC_length (rtx, changed_values_stack) > 0)
7523         set_dv_changed (dv_from_value (VEC_pop (rtx, changed_values_stack)),
7524                         false);
7525       htab_traverse (changed_variables, check_changed_vars_3, htab);
7526     }
7527
7528   data.insn = insn;
7529   data.where = where;
7530   data.vars = htab;
7531
7532   htab_traverse (changed_variables, emit_note_insn_var_location, &data);
7533 }
7534
7535 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
7536    same variable in hash table DATA or is not there at all.  */
7537
7538 static int
7539 emit_notes_for_differences_1 (void **slot, void *data)
7540 {
7541   htab_t new_vars = (htab_t) data;
7542   variable old_var, new_var;
7543
7544   old_var = (variable) *slot;
7545   new_var = (variable) htab_find_with_hash (new_vars, old_var->dv,
7546                                             dv_htab_hash (old_var->dv));
7547
7548   if (!new_var)
7549     {
7550       /* Variable has disappeared.  */
7551       variable empty_var;
7552
7553       empty_var = (variable) pool_alloc (dv_pool (old_var->dv));
7554       empty_var->dv = old_var->dv;
7555       empty_var->refcount = 0;
7556       empty_var->n_var_parts = 0;
7557       empty_var->cur_loc_changed = false;
7558       empty_var->in_changed_variables = false;
7559       if (dv_onepart_p (old_var->dv))
7560         {
7561           location_chain lc;
7562
7563           gcc_assert (old_var->n_var_parts == 1);
7564           for (lc = old_var->var_part[0].loc_chain; lc; lc = lc->next)
7565             remove_value_chains (old_var->dv, lc->loc);
7566         }
7567       variable_was_changed (empty_var, NULL);
7568       /* Continue traversing the hash table.  */
7569       return 1;
7570     }
7571   if (variable_different_p (old_var, new_var))
7572     {
7573       if (dv_onepart_p (old_var->dv))
7574         {
7575           location_chain lc1, lc2;
7576
7577           gcc_assert (old_var->n_var_parts == 1
7578                       && new_var->n_var_parts == 1);
7579           lc1 = old_var->var_part[0].loc_chain;
7580           lc2 = new_var->var_part[0].loc_chain;
7581           while (lc1
7582                  && lc2
7583                  && ((REG_P (lc1->loc) && REG_P (lc2->loc))
7584                      || rtx_equal_p (lc1->loc, lc2->loc)))
7585             {
7586               lc1 = lc1->next;
7587               lc2 = lc2->next;
7588             }
7589           for (; lc2; lc2 = lc2->next)
7590             add_value_chains (old_var->dv, lc2->loc);
7591           for (; lc1; lc1 = lc1->next)
7592             remove_value_chains (old_var->dv, lc1->loc);
7593         }
7594       variable_was_changed (new_var, NULL);
7595     }
7596   /* Update cur_loc.  */
7597   if (old_var != new_var)
7598     {
7599       int i;
7600       for (i = 0; i < new_var->n_var_parts; i++)
7601         {
7602           new_var->var_part[i].cur_loc = NULL;
7603           if (old_var->n_var_parts != new_var->n_var_parts
7604               || old_var->var_part[i].offset != new_var->var_part[i].offset)
7605             new_var->cur_loc_changed = true;
7606           else if (old_var->var_part[i].cur_loc != NULL)
7607             {
7608               location_chain lc;
7609               rtx cur_loc = old_var->var_part[i].cur_loc;
7610
7611               for (lc = new_var->var_part[i].loc_chain; lc; lc = lc->next)
7612                 if (lc->loc == cur_loc
7613                     || rtx_equal_p (cur_loc, lc->loc))
7614                   {
7615                     new_var->var_part[i].cur_loc = lc->loc;
7616                     break;
7617                   }
7618               if (lc == NULL)
7619                 new_var->cur_loc_changed = true;
7620             }
7621         }
7622     }
7623
7624   /* Continue traversing the hash table.  */
7625   return 1;
7626 }
7627
7628 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
7629    table DATA.  */
7630
7631 static int
7632 emit_notes_for_differences_2 (void **slot, void *data)
7633 {
7634   htab_t old_vars = (htab_t) data;
7635   variable old_var, new_var;
7636
7637   new_var = (variable) *slot;
7638   old_var = (variable) htab_find_with_hash (old_vars, new_var->dv,
7639                                             dv_htab_hash (new_var->dv));
7640   if (!old_var)
7641     {
7642       int i;
7643       /* Variable has appeared.  */
7644       if (dv_onepart_p (new_var->dv))
7645         {
7646           location_chain lc;
7647
7648           gcc_assert (new_var->n_var_parts == 1);
7649           for (lc = new_var->var_part[0].loc_chain; lc; lc = lc->next)
7650             add_value_chains (new_var->dv, lc->loc);
7651         }
7652       for (i = 0; i < new_var->n_var_parts; i++)
7653         new_var->var_part[i].cur_loc = NULL;
7654       variable_was_changed (new_var, NULL);
7655     }
7656
7657   /* Continue traversing the hash table.  */
7658   return 1;
7659 }
7660
7661 /* Emit notes before INSN for differences between dataflow sets OLD_SET and
7662    NEW_SET.  */
7663
7664 static void
7665 emit_notes_for_differences (rtx insn, dataflow_set *old_set,
7666                             dataflow_set *new_set)
7667 {
7668   htab_traverse (shared_hash_htab (old_set->vars),
7669                  emit_notes_for_differences_1,
7670                  shared_hash_htab (new_set->vars));
7671   htab_traverse (shared_hash_htab (new_set->vars),
7672                  emit_notes_for_differences_2,
7673                  shared_hash_htab (old_set->vars));
7674   emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, new_set->vars);
7675 }
7676
7677 /* Emit the notes for changes of location parts in the basic block BB.  */
7678
7679 static void
7680 emit_notes_in_bb (basic_block bb, dataflow_set *set)
7681 {
7682   unsigned int i;
7683   micro_operation *mo;
7684
7685   dataflow_set_clear (set);
7686   dataflow_set_copy (set, &VTI (bb)->in);
7687
7688   FOR_EACH_VEC_ELT (micro_operation, VTI (bb)->mos, i, mo)
7689     {
7690       rtx insn = mo->insn;
7691
7692       switch (mo->type)
7693         {
7694           case MO_CALL:
7695             dataflow_set_clear_at_call (set);
7696             emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars);
7697             break;
7698
7699           case MO_USE:
7700             {
7701               rtx loc = mo->u.loc;
7702
7703               if (REG_P (loc))
7704                 var_reg_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
7705               else
7706                 var_mem_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
7707
7708               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
7709             }
7710             break;
7711
7712           case MO_VAL_LOC:
7713             {
7714               rtx loc = mo->u.loc;
7715               rtx val, vloc;
7716               tree var;
7717
7718               if (GET_CODE (loc) == CONCAT)
7719                 {
7720                   val = XEXP (loc, 0);
7721                   vloc = XEXP (loc, 1);
7722                 }
7723               else
7724                 {
7725                   val = NULL_RTX;
7726                   vloc = loc;
7727                 }
7728
7729               var = PAT_VAR_LOCATION_DECL (vloc);
7730
7731               clobber_variable_part (set, NULL_RTX,
7732                                      dv_from_decl (var), 0, NULL_RTX);
7733               if (val)
7734                 {
7735                   if (VAL_NEEDS_RESOLUTION (loc))
7736                     val_resolve (set, val, PAT_VAR_LOCATION_LOC (vloc), insn);
7737                   set_variable_part (set, val, dv_from_decl (var), 0,
7738                                      VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
7739                                      INSERT);
7740                 }
7741               else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
7742                 set_variable_part (set, PAT_VAR_LOCATION_LOC (vloc),
7743                                    dv_from_decl (var), 0,
7744                                    VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
7745                                    INSERT);
7746
7747               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
7748             }
7749             break;
7750
7751           case MO_VAL_USE:
7752             {
7753               rtx loc = mo->u.loc;
7754               rtx val, vloc, uloc;
7755
7756               vloc = uloc = XEXP (loc, 1);
7757               val = XEXP (loc, 0);
7758
7759               if (GET_CODE (val) == CONCAT)
7760                 {
7761                   uloc = XEXP (val, 1);
7762                   val = XEXP (val, 0);
7763                 }
7764
7765               if (VAL_NEEDS_RESOLUTION (loc))
7766                 val_resolve (set, val, vloc, insn);
7767               else
7768                 val_store (set, val, uloc, insn, false);
7769
7770               if (VAL_HOLDS_TRACK_EXPR (loc))
7771                 {
7772                   if (GET_CODE (uloc) == REG)
7773                     var_reg_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
7774                                  NULL);
7775                   else if (GET_CODE (uloc) == MEM)
7776                     var_mem_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
7777                                  NULL);
7778                 }
7779
7780               emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
7781             }
7782             break;
7783
7784           case MO_VAL_SET:
7785             {
7786               rtx loc = mo->u.loc;
7787               rtx val, vloc, uloc, reverse = NULL_RTX;
7788
7789               vloc = loc;
7790               if (VAL_EXPR_HAS_REVERSE (loc))
7791                 {
7792                   reverse = XEXP (loc, 1);
7793                   vloc = XEXP (loc, 0);
7794                 }
7795               uloc = XEXP (vloc, 1);
7796               val = XEXP (vloc, 0);
7797               vloc = uloc;
7798
7799               if (GET_CODE (val) == CONCAT)
7800                 {
7801                   vloc = XEXP (val, 1);
7802                   val = XEXP (val, 0);
7803                 }
7804
7805               if (GET_CODE (vloc) == SET)
7806                 {
7807                   rtx vsrc = SET_SRC (vloc);
7808
7809                   gcc_assert (val != vsrc);
7810                   gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
7811
7812                   vloc = SET_DEST (vloc);
7813
7814                   if (VAL_NEEDS_RESOLUTION (loc))
7815                     val_resolve (set, val, vsrc, insn);
7816                 }
7817               else if (VAL_NEEDS_RESOLUTION (loc))
7818                 {
7819                   gcc_assert (GET_CODE (uloc) == SET
7820                               && GET_CODE (SET_SRC (uloc)) == REG);
7821                   val_resolve (set, val, SET_SRC (uloc), insn);
7822                 }
7823
7824               if (VAL_HOLDS_TRACK_EXPR (loc))
7825                 {
7826                   if (VAL_EXPR_IS_CLOBBERED (loc))
7827                     {
7828                       if (REG_P (uloc))
7829                         var_reg_delete (set, uloc, true);
7830                       else if (MEM_P (uloc))
7831                         var_mem_delete (set, uloc, true);
7832                     }
7833                   else
7834                     {
7835                       bool copied_p = VAL_EXPR_IS_COPIED (loc);
7836                       rtx set_src = NULL;
7837                       enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
7838
7839                       if (GET_CODE (uloc) == SET)
7840                         {
7841                           set_src = SET_SRC (uloc);
7842                           uloc = SET_DEST (uloc);
7843                         }
7844
7845                       if (copied_p)
7846                         {
7847                           status = find_src_status (set, set_src);
7848
7849                           set_src = find_src_set_src (set, set_src);
7850                         }
7851
7852                       if (REG_P (uloc))
7853                         var_reg_delete_and_set (set, uloc, !copied_p,
7854                                                 status, set_src);
7855                       else if (MEM_P (uloc))
7856                         var_mem_delete_and_set (set, uloc, !copied_p,
7857                                                 status, set_src);
7858                     }
7859                 }
7860               else if (REG_P (uloc))
7861                 var_regno_delete (set, REGNO (uloc));
7862
7863               val_store (set, val, vloc, insn, true);
7864
7865               if (reverse)
7866                 val_store (set, XEXP (reverse, 0), XEXP (reverse, 1),
7867                            insn, false);
7868
7869               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
7870                                       set->vars);
7871             }
7872             break;
7873
7874           case MO_SET:
7875             {
7876               rtx loc = mo->u.loc;
7877               rtx set_src = NULL;
7878
7879               if (GET_CODE (loc) == SET)
7880                 {
7881                   set_src = SET_SRC (loc);
7882                   loc = SET_DEST (loc);
7883                 }
7884
7885               if (REG_P (loc))
7886                 var_reg_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
7887                                         set_src);
7888               else
7889                 var_mem_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
7890                                         set_src);
7891
7892               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
7893                                       set->vars);
7894             }
7895             break;
7896
7897           case MO_COPY:
7898             {
7899               rtx loc = mo->u.loc;
7900               enum var_init_status src_status;
7901               rtx set_src = NULL;
7902
7903               if (GET_CODE (loc) == SET)
7904                 {
7905                   set_src = SET_SRC (loc);
7906                   loc = SET_DEST (loc);
7907                 }
7908
7909               src_status = find_src_status (set, set_src);
7910               set_src = find_src_set_src (set, set_src);
7911
7912               if (REG_P (loc))
7913                 var_reg_delete_and_set (set, loc, false, src_status, set_src);
7914               else
7915                 var_mem_delete_and_set (set, loc, false, src_status, set_src);
7916
7917               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
7918                                       set->vars);
7919             }
7920             break;
7921
7922           case MO_USE_NO_VAR:
7923             {
7924               rtx loc = mo->u.loc;
7925
7926               if (REG_P (loc))
7927                 var_reg_delete (set, loc, false);
7928               else
7929                 var_mem_delete (set, loc, false);
7930
7931               emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
7932             }
7933             break;
7934
7935           case MO_CLOBBER:
7936             {
7937               rtx loc = mo->u.loc;
7938
7939               if (REG_P (loc))
7940                 var_reg_delete (set, loc, true);
7941               else
7942                 var_mem_delete (set, loc, true);
7943
7944               emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
7945                                       set->vars);
7946             }
7947             break;
7948
7949           case MO_ADJUST:
7950             set->stack_adjust += mo->u.adjust;
7951             break;
7952         }
7953     }
7954 }
7955
7956 /* Emit notes for the whole function.  */
7957
7958 static void
7959 vt_emit_notes (void)
7960 {
7961   basic_block bb;
7962   dataflow_set cur;
7963
7964 #ifdef ENABLE_RTL_CHECKING
7965   emitted_notes = pointer_map_create ();
7966 #endif
7967   gcc_assert (!htab_elements (changed_variables));
7968
7969   /* Free memory occupied by the out hash tables, as they aren't used
7970      anymore.  */
7971   FOR_EACH_BB (bb)
7972     dataflow_set_clear (&VTI (bb)->out);
7973
7974   /* Enable emitting notes by functions (mainly by set_variable_part and
7975      delete_variable_part).  */
7976   emit_notes = true;
7977
7978   if (MAY_HAVE_DEBUG_INSNS)
7979     {
7980       unsigned int i;
7981       rtx val;
7982
7983       FOR_EACH_VEC_ELT (rtx, preserved_values, i, val)
7984         add_cselib_value_chains (dv_from_value (val));
7985       changed_variables_stack = VEC_alloc (variable, heap, 40);
7986       changed_values_stack = VEC_alloc (rtx, heap, 40);
7987     }
7988
7989   dataflow_set_init (&cur);
7990
7991   FOR_EACH_BB (bb)
7992     {
7993       /* Emit the notes for changes of variable locations between two
7994          subsequent basic blocks.  */
7995       emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
7996
7997       /* Emit the notes for the changes in the basic block itself.  */
7998       emit_notes_in_bb (bb, &cur);
7999
8000       /* Free memory occupied by the in hash table, we won't need it
8001          again.  */
8002       dataflow_set_clear (&VTI (bb)->in);
8003     }
8004 #ifdef ENABLE_CHECKING
8005   htab_traverse (shared_hash_htab (cur.vars),
8006                  emit_notes_for_differences_1,
8007                  shared_hash_htab (empty_shared_hash));
8008   if (MAY_HAVE_DEBUG_INSNS)
8009     {
8010       unsigned int i;
8011       rtx val;
8012
8013       FOR_EACH_VEC_ELT (rtx, preserved_values, i, val)
8014         remove_cselib_value_chains (dv_from_value (val));
8015       gcc_assert (htab_elements (value_chains) == 0);
8016     }
8017 #endif
8018   dataflow_set_destroy (&cur);
8019
8020   if (MAY_HAVE_DEBUG_INSNS)
8021     {
8022       VEC_free (variable, heap, changed_variables_stack);
8023       VEC_free (rtx, heap, changed_values_stack);
8024     }
8025
8026 #ifdef ENABLE_RTL_CHECKING
8027   pointer_map_destroy (emitted_notes);
8028 #endif
8029   emit_notes = false;
8030 }
8031
8032 /* If there is a declaration and offset associated with register/memory RTL
8033    assign declaration to *DECLP and offset to *OFFSETP, and return true.  */
8034
8035 static bool
8036 vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
8037 {
8038   if (REG_P (rtl))
8039     {
8040       if (REG_ATTRS (rtl))
8041         {
8042           *declp = REG_EXPR (rtl);
8043           *offsetp = REG_OFFSET (rtl);
8044           return true;
8045         }
8046     }
8047   else if (MEM_P (rtl))
8048     {
8049       if (MEM_ATTRS (rtl))
8050         {
8051           *declp = MEM_EXPR (rtl);
8052           *offsetp = INT_MEM_OFFSET (rtl);
8053           return true;
8054         }
8055     }
8056   return false;
8057 }
8058
8059 /* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */
8060
8061 static void
8062 vt_add_function_parameters (void)
8063 {
8064   tree parm;
8065
8066   for (parm = DECL_ARGUMENTS (current_function_decl);
8067        parm; parm = DECL_CHAIN (parm))
8068     {
8069       rtx decl_rtl = DECL_RTL_IF_SET (parm);
8070       rtx incoming = DECL_INCOMING_RTL (parm);
8071       tree decl;
8072       enum machine_mode mode;
8073       HOST_WIDE_INT offset;
8074       dataflow_set *out;
8075       decl_or_value dv;
8076
8077       if (TREE_CODE (parm) != PARM_DECL)
8078         continue;
8079
8080       if (!DECL_NAME (parm))
8081         continue;
8082
8083       if (!decl_rtl || !incoming)
8084         continue;
8085
8086       if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
8087         continue;
8088
8089       if (!vt_get_decl_and_offset (incoming, &decl, &offset))
8090         {
8091           if (REG_P (incoming) || MEM_P (incoming))
8092             {
8093               /* This means argument is passed by invisible reference.  */
8094               offset = 0;
8095               decl = parm;
8096               incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
8097             }
8098           else
8099             {
8100               if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
8101                 continue;
8102               offset += byte_lowpart_offset (GET_MODE (incoming),
8103                                              GET_MODE (decl_rtl));
8104             }
8105         }
8106
8107       if (!decl)
8108         continue;
8109
8110       if (parm != decl)
8111         {
8112           /* Assume that DECL_RTL was a pseudo that got spilled to
8113              memory.  The spill slot sharing code will force the
8114              memory to reference spill_slot_decl (%sfp), so we don't
8115              match above.  That's ok, the pseudo must have referenced
8116              the entire parameter, so just reset OFFSET.  */
8117           gcc_assert (decl == get_spill_slot_decl (false));
8118           offset = 0;
8119         }
8120
8121       if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
8122         continue;
8123
8124       out = &VTI (ENTRY_BLOCK_PTR)->out;
8125
8126       dv = dv_from_decl (parm);
8127
8128       if (target_for_debug_bind (parm)
8129           /* We can't deal with these right now, because this kind of
8130              variable is single-part.  ??? We could handle parallels
8131              that describe multiple locations for the same single
8132              value, but ATM we don't.  */
8133           && GET_CODE (incoming) != PARALLEL)
8134         {
8135           cselib_val *val;
8136
8137           /* ??? We shouldn't ever hit this, but it may happen because
8138              arguments passed by invisible reference aren't dealt with
8139              above: incoming-rtl will have Pmode rather than the
8140              expected mode for the type.  */
8141           if (offset)
8142             continue;
8143
8144           val = cselib_lookup (var_lowpart (mode, incoming), mode, true);
8145
8146           /* ??? Float-typed values in memory are not handled by
8147              cselib.  */
8148           if (val)
8149             {
8150               preserve_value (val);
8151               set_variable_part (out, val->val_rtx, dv, offset,
8152                                  VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
8153               dv = dv_from_value (val->val_rtx);
8154             }
8155         }
8156
8157       if (REG_P (incoming))
8158         {
8159           incoming = var_lowpart (mode, incoming);
8160           gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
8161           attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
8162                              incoming);
8163           set_variable_part (out, incoming, dv, offset,
8164                              VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
8165         }
8166       else if (MEM_P (incoming))
8167         {
8168           incoming = var_lowpart (mode, incoming);
8169           set_variable_part (out, incoming, dv, offset,
8170                              VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
8171         }
8172     }
8173
8174   if (MAY_HAVE_DEBUG_INSNS)
8175     {
8176       cselib_preserve_only_values ();
8177       cselib_reset_table (cselib_get_next_uid ());
8178     }
8179
8180 }
8181
8182 /* Return true if INSN in the prologue initializes hard_frame_pointer_rtx.  */
8183
8184 static bool
8185 fp_setter (rtx insn)
8186 {
8187   rtx pat = PATTERN (insn);
8188   if (RTX_FRAME_RELATED_P (insn))
8189     {
8190       rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
8191       if (expr)
8192         pat = XEXP (expr, 0);
8193     }
8194   if (GET_CODE (pat) == SET)
8195     return SET_DEST (pat) == hard_frame_pointer_rtx;
8196   else if (GET_CODE (pat) == PARALLEL)
8197     {
8198       int i;
8199       for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
8200         if (GET_CODE (XVECEXP (pat, 0, i)) == SET
8201             && SET_DEST (XVECEXP (pat, 0, i)) == hard_frame_pointer_rtx)
8202           return true;
8203     }
8204   return false;
8205 }
8206
8207 /* Initialize cfa_base_rtx, create a preserved VALUE for it and
8208    ensure it isn't flushed during cselib_reset_table.
8209    Can be called only if frame_pointer_rtx resp. arg_pointer_rtx
8210    has been eliminated.  */
8211
8212 static void
8213 vt_init_cfa_base (void)
8214 {
8215   cselib_val *val;
8216
8217 #ifdef FRAME_POINTER_CFA_OFFSET
8218   cfa_base_rtx = frame_pointer_rtx;
8219   cfa_base_offset = -FRAME_POINTER_CFA_OFFSET (current_function_decl);
8220 #else
8221   cfa_base_rtx = arg_pointer_rtx;
8222   cfa_base_offset = -ARG_POINTER_CFA_OFFSET (current_function_decl);
8223 #endif
8224   if (cfa_base_rtx == hard_frame_pointer_rtx
8225       || !fixed_regs[REGNO (cfa_base_rtx)])
8226     {
8227       cfa_base_rtx = NULL_RTX;
8228       return;
8229     }
8230   if (!MAY_HAVE_DEBUG_INSNS)
8231     return;
8232
8233   /* Tell alias analysis that cfa_base_rtx should share
8234      find_base_term value with stack pointer or hard frame pointer.  */
8235   vt_equate_reg_base_value (cfa_base_rtx,
8236                             frame_pointer_needed
8237                             ? hard_frame_pointer_rtx : stack_pointer_rtx);
8238   val = cselib_lookup_from_insn (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1,
8239                                  get_insns ());
8240   preserve_value (val);
8241   cselib_preserve_cfa_base_value (val, REGNO (cfa_base_rtx));
8242   var_reg_decl_set (&VTI (ENTRY_BLOCK_PTR)->out, cfa_base_rtx,
8243                     VAR_INIT_STATUS_INITIALIZED, dv_from_value (val->val_rtx),
8244                     0, NULL_RTX, INSERT);
8245 }
8246
8247 /* Allocate and initialize the data structures for variable tracking
8248    and parse the RTL to get the micro operations.  */
8249
8250 static bool
8251 vt_initialize (void)
8252 {
8253   basic_block bb, prologue_bb = NULL;
8254   HOST_WIDE_INT fp_cfa_offset = -1;
8255
8256   alloc_aux_for_blocks (sizeof (struct variable_tracking_info_def));
8257
8258   attrs_pool = create_alloc_pool ("attrs_def pool",
8259                                   sizeof (struct attrs_def), 1024);
8260   var_pool = create_alloc_pool ("variable_def pool",
8261                                 sizeof (struct variable_def)
8262                                 + (MAX_VAR_PARTS - 1)
8263                                 * sizeof (((variable)NULL)->var_part[0]), 64);
8264   loc_chain_pool = create_alloc_pool ("location_chain_def pool",
8265                                       sizeof (struct location_chain_def),
8266                                       1024);
8267   shared_hash_pool = create_alloc_pool ("shared_hash_def pool",
8268                                         sizeof (struct shared_hash_def), 256);
8269   empty_shared_hash = (shared_hash) pool_alloc (shared_hash_pool);
8270   empty_shared_hash->refcount = 1;
8271   empty_shared_hash->htab
8272     = htab_create (1, variable_htab_hash, variable_htab_eq,
8273                    variable_htab_free);
8274   changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
8275                                    variable_htab_free);
8276   if (MAY_HAVE_DEBUG_INSNS)
8277     {
8278       value_chain_pool = create_alloc_pool ("value_chain_def pool",
8279                                             sizeof (struct value_chain_def),
8280                                             1024);
8281       value_chains = htab_create (32, value_chain_htab_hash,
8282                                   value_chain_htab_eq, NULL);
8283     }
8284
8285   /* Init the IN and OUT sets.  */
8286   FOR_ALL_BB (bb)
8287     {
8288       VTI (bb)->visited = false;
8289       VTI (bb)->flooded = false;
8290       dataflow_set_init (&VTI (bb)->in);
8291       dataflow_set_init (&VTI (bb)->out);
8292       VTI (bb)->permp = NULL;
8293     }
8294
8295   if (MAY_HAVE_DEBUG_INSNS)
8296     {
8297       cselib_init (CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS);
8298       scratch_regs = BITMAP_ALLOC (NULL);
8299       valvar_pool = create_alloc_pool ("small variable_def pool",
8300                                        sizeof (struct variable_def), 256);
8301       preserved_values = VEC_alloc (rtx, heap, 256);
8302     }
8303   else
8304     {
8305       scratch_regs = NULL;
8306       valvar_pool = NULL;
8307     }
8308
8309   if (!frame_pointer_needed)
8310     {
8311       rtx reg, elim;
8312
8313       if (!vt_stack_adjustments ())
8314         return false;
8315
8316 #ifdef FRAME_POINTER_CFA_OFFSET
8317       reg = frame_pointer_rtx;
8318 #else
8319       reg = arg_pointer_rtx;
8320 #endif
8321       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
8322       if (elim != reg)
8323         {
8324           if (GET_CODE (elim) == PLUS)
8325             elim = XEXP (elim, 0);
8326           if (elim == stack_pointer_rtx)
8327             vt_init_cfa_base ();
8328         }
8329     }
8330   else if (!crtl->stack_realign_tried)
8331     {
8332       rtx reg, elim;
8333
8334 #ifdef FRAME_POINTER_CFA_OFFSET
8335       reg = frame_pointer_rtx;
8336       fp_cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
8337 #else
8338       reg = arg_pointer_rtx;
8339       fp_cfa_offset = ARG_POINTER_CFA_OFFSET (current_function_decl);
8340 #endif
8341       elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
8342       if (elim != reg)
8343         {
8344           if (GET_CODE (elim) == PLUS)
8345             {
8346               fp_cfa_offset -= INTVAL (XEXP (elim, 1));
8347               elim = XEXP (elim, 0);
8348             }
8349           if (elim != hard_frame_pointer_rtx)
8350             fp_cfa_offset = -1;
8351           else
8352             prologue_bb = single_succ (ENTRY_BLOCK_PTR);
8353         }
8354     }
8355
8356   hard_frame_pointer_adjustment = -1;
8357
8358   FOR_EACH_BB (bb)
8359     {
8360       rtx insn;
8361       HOST_WIDE_INT pre, post = 0;
8362       basic_block first_bb, last_bb;
8363
8364       if (MAY_HAVE_DEBUG_INSNS)
8365         {
8366           cselib_record_sets_hook = add_with_sets;
8367           if (dump_file && (dump_flags & TDF_DETAILS))
8368             fprintf (dump_file, "first value: %i\n",
8369                      cselib_get_next_uid ());
8370         }
8371
8372       first_bb = bb;
8373       for (;;)
8374         {
8375           edge e;
8376           if (bb->next_bb == EXIT_BLOCK_PTR
8377               || ! single_pred_p (bb->next_bb))
8378             break;
8379           e = find_edge (bb, bb->next_bb);
8380           if (! e || (e->flags & EDGE_FALLTHRU) == 0)
8381             break;
8382           bb = bb->next_bb;
8383         }
8384       last_bb = bb;
8385
8386       /* Add the micro-operations to the vector.  */
8387       FOR_BB_BETWEEN (bb, first_bb, last_bb->next_bb, next_bb)
8388         {
8389           HOST_WIDE_INT offset = VTI (bb)->out.stack_adjust;
8390           VTI (bb)->out.stack_adjust = VTI (bb)->in.stack_adjust;
8391           for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
8392                insn = NEXT_INSN (insn))
8393             {
8394               if (INSN_P (insn))
8395                 {
8396                   if (!frame_pointer_needed)
8397                     {
8398                       insn_stack_adjust_offset_pre_post (insn, &pre, &post);
8399                       if (pre)
8400                         {
8401                           micro_operation mo;
8402                           mo.type = MO_ADJUST;
8403                           mo.u.adjust = pre;
8404                           mo.insn = insn;
8405                           if (dump_file && (dump_flags & TDF_DETAILS))
8406                             log_op_type (PATTERN (insn), bb, insn,
8407                                          MO_ADJUST, dump_file);
8408                           VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
8409                                          &mo);
8410                           VTI (bb)->out.stack_adjust += pre;
8411                         }
8412                     }
8413
8414                   cselib_hook_called = false;
8415                   adjust_insn (bb, insn);
8416                   if (MAY_HAVE_DEBUG_INSNS)
8417                     {
8418                       cselib_process_insn (insn);
8419                       if (dump_file && (dump_flags & TDF_DETAILS))
8420                         {
8421                           print_rtl_single (dump_file, insn);
8422                           dump_cselib_table (dump_file);
8423                         }
8424                     }
8425                   if (!cselib_hook_called)
8426                     add_with_sets (insn, 0, 0);
8427                   cancel_changes (0);
8428
8429                   if (!frame_pointer_needed && post)
8430                     {
8431                       micro_operation mo;
8432                       mo.type = MO_ADJUST;
8433                       mo.u.adjust = post;
8434                       mo.insn = insn;
8435                       if (dump_file && (dump_flags & TDF_DETAILS))
8436                         log_op_type (PATTERN (insn), bb, insn,
8437                                      MO_ADJUST, dump_file);
8438                       VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
8439                                      &mo);
8440                       VTI (bb)->out.stack_adjust += post;
8441                     }
8442
8443                   if (bb == prologue_bb
8444                       && hard_frame_pointer_adjustment == -1
8445                       && RTX_FRAME_RELATED_P (insn)
8446                       && fp_setter (insn))
8447                     {
8448                       vt_init_cfa_base ();
8449                       hard_frame_pointer_adjustment = fp_cfa_offset;
8450                     }
8451                 }
8452             }
8453           gcc_assert (offset == VTI (bb)->out.stack_adjust);
8454         }
8455
8456       bb = last_bb;
8457
8458       if (MAY_HAVE_DEBUG_INSNS)
8459         {
8460           cselib_preserve_only_values ();
8461           cselib_reset_table (cselib_get_next_uid ());
8462           cselib_record_sets_hook = NULL;
8463         }
8464     }
8465
8466   hard_frame_pointer_adjustment = -1;
8467   VTI (ENTRY_BLOCK_PTR)->flooded = true;
8468   vt_add_function_parameters ();
8469   cfa_base_rtx = NULL_RTX;
8470   return true;
8471 }
8472
8473 /* Get rid of all debug insns from the insn stream.  */
8474
8475 static void
8476 delete_debug_insns (void)
8477 {
8478   basic_block bb;
8479   rtx insn, next;
8480
8481   if (!MAY_HAVE_DEBUG_INSNS)
8482     return;
8483
8484   FOR_EACH_BB (bb)
8485     {
8486       FOR_BB_INSNS_SAFE (bb, insn, next)
8487         if (DEBUG_INSN_P (insn))
8488           delete_insn (insn);
8489     }
8490 }
8491
8492 /* Run a fast, BB-local only version of var tracking, to take care of
8493    information that we don't do global analysis on, such that not all
8494    information is lost.  If SKIPPED holds, we're skipping the global
8495    pass entirely, so we should try to use information it would have
8496    handled as well..  */
8497
8498 static void
8499 vt_debug_insns_local (bool skipped ATTRIBUTE_UNUSED)
8500 {
8501   /* ??? Just skip it all for now.  */
8502   delete_debug_insns ();
8503 }
8504
8505 /* Free the data structures needed for variable tracking.  */
8506
8507 static void
8508 vt_finalize (void)
8509 {
8510   basic_block bb;
8511
8512   FOR_EACH_BB (bb)
8513     {
8514       VEC_free (micro_operation, heap, VTI (bb)->mos);
8515     }
8516
8517   FOR_ALL_BB (bb)
8518     {
8519       dataflow_set_destroy (&VTI (bb)->in);
8520       dataflow_set_destroy (&VTI (bb)->out);
8521       if (VTI (bb)->permp)
8522         {
8523           dataflow_set_destroy (VTI (bb)->permp);
8524           XDELETE (VTI (bb)->permp);
8525         }
8526     }
8527   free_aux_for_blocks ();
8528   htab_delete (empty_shared_hash->htab);
8529   htab_delete (changed_variables);
8530   free_alloc_pool (attrs_pool);
8531   free_alloc_pool (var_pool);
8532   free_alloc_pool (loc_chain_pool);
8533   free_alloc_pool (shared_hash_pool);
8534
8535   if (MAY_HAVE_DEBUG_INSNS)
8536     {
8537       htab_delete (value_chains);
8538       free_alloc_pool (value_chain_pool);
8539       free_alloc_pool (valvar_pool);
8540       VEC_free (rtx, heap, preserved_values);
8541       cselib_finish ();
8542       BITMAP_FREE (scratch_regs);
8543       scratch_regs = NULL;
8544     }
8545
8546   if (vui_vec)
8547     XDELETEVEC (vui_vec);
8548   vui_vec = NULL;
8549   vui_allocated = 0;
8550 }
8551
8552 /* The entry point to variable tracking pass.  */
8553
8554 static inline unsigned int
8555 variable_tracking_main_1 (void)
8556 {
8557   bool success;
8558
8559   if (flag_var_tracking_assignments < 0)
8560     {
8561       delete_debug_insns ();
8562       return 0;
8563     }
8564
8565   if (n_basic_blocks > 500 && n_edges / n_basic_blocks >= 20)
8566     {
8567       vt_debug_insns_local (true);
8568       return 0;
8569     }
8570
8571   mark_dfs_back_edges ();
8572   if (!vt_initialize ())
8573     {
8574       vt_finalize ();
8575       vt_debug_insns_local (true);
8576       return 0;
8577     }
8578
8579   success = vt_find_locations ();
8580
8581   if (!success && flag_var_tracking_assignments > 0)
8582     {
8583       vt_finalize ();
8584
8585       delete_debug_insns ();
8586
8587       /* This is later restored by our caller.  */
8588       flag_var_tracking_assignments = 0;
8589
8590       success = vt_initialize ();
8591       gcc_assert (success);
8592
8593       success = vt_find_locations ();
8594     }
8595
8596   if (!success)
8597     {
8598       vt_finalize ();
8599       vt_debug_insns_local (false);
8600       return 0;
8601     }
8602
8603   if (dump_file && (dump_flags & TDF_DETAILS))
8604     {
8605       dump_dataflow_sets ();
8606       dump_flow_info (dump_file, dump_flags);
8607     }
8608
8609   timevar_push (TV_VAR_TRACKING_EMIT);
8610   vt_emit_notes ();
8611   timevar_pop (TV_VAR_TRACKING_EMIT);
8612
8613   vt_finalize ();
8614   vt_debug_insns_local (false);
8615   return 0;
8616 }
8617
8618 unsigned int
8619 variable_tracking_main (void)
8620 {
8621   unsigned int ret;
8622   int save = flag_var_tracking_assignments;
8623
8624   ret = variable_tracking_main_1 ();
8625
8626   flag_var_tracking_assignments = save;
8627
8628   return ret;
8629 }
8630 \f
8631 static bool
8632 gate_handle_var_tracking (void)
8633 {
8634   return (flag_var_tracking);
8635 }
8636
8637
8638
8639 struct rtl_opt_pass pass_variable_tracking =
8640 {
8641  {
8642   RTL_PASS,
8643   "vartrack",                           /* name */
8644   gate_handle_var_tracking,             /* gate */
8645   variable_tracking_main,               /* execute */
8646   NULL,                                 /* sub */
8647   NULL,                                 /* next */
8648   0,                                    /* static_pass_number */
8649   TV_VAR_TRACKING,                      /* tv_id */
8650   0,                                    /* properties_required */
8651   0,                                    /* properties_provided */
8652   0,                                    /* properties_destroyed */
8653   0,                                    /* todo_flags_start */
8654   TODO_dump_func | TODO_verify_rtl_sharing/* todo_flags_finish */
8655  }
8656 };