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