OSDN Git Service

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