1 /* Variable tracking routines for the GNU compiler.
2 Copyright (C) 2002-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
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)
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.
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/>. */
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
25 With this debug information, it is possible to show variables
26 even when debugging optimized code.
28 How does the variable tracking pass work?
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
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
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.
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
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
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).
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).
90 #include "coretypes.h"
97 #include "stor-layout.h"
99 #include "hard-reg-set.h"
100 #include "function.h"
101 #include "dominance.h"
105 #include "basic-block.h"
108 #include "insn-config.h"
111 #include "alloc-pool.h"
117 #include "emit-rtl.h"
120 #include "tree-pass.h"
122 #include "tree-dfa.h"
123 #include "tree-ssa.h"
127 #include "diagnostic.h"
128 #include "tree-pretty-print.h"
130 #include "rtl-iter.h"
131 #include "fibonacci_heap.h"
133 typedef fibonacci_heap
<long, basic_block_def
> bb_heap_t
;
134 typedef fibonacci_node
<long, basic_block_def
> bb_heap_node_t
;
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];
143 /* Type of micro operation. */
144 enum micro_operation_type
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. */
161 static const char * const ATTRIBUTE_UNUSED
162 micro_operation_type_name
[] = {
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. */
180 EMIT_NOTE_BEFORE_INSN
,
181 EMIT_NOTE_AFTER_INSN
,
182 EMIT_NOTE_AFTER_CALL_INSN
185 /* Structure holding information about micro operation. */
186 typedef struct micro_operation_def
188 /* Type of micro operation. */
189 enum micro_operation_type type
;
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
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. */
207 /* Stack adjustment. */
208 HOST_WIDE_INT adjust
;
213 /* A declaration of a variable, or an RTL value being handled like a
215 typedef void *decl_or_value
;
217 /* Return true if a decl_or_value DV is a DECL or NULL. */
219 dv_is_decl_p (decl_or_value dv
)
221 return !dv
|| (int) TREE_CODE ((tree
) dv
) != (int) VALUE
;
224 /* Return true if a decl_or_value is a VALUE rtl. */
226 dv_is_value_p (decl_or_value dv
)
228 return dv
&& !dv_is_decl_p (dv
);
231 /* Return the decl in the decl_or_value. */
233 dv_as_decl (decl_or_value dv
)
235 gcc_checking_assert (dv_is_decl_p (dv
));
239 /* Return the value in the decl_or_value. */
241 dv_as_value (decl_or_value dv
)
243 gcc_checking_assert (dv_is_value_p (dv
));
247 /* Return the opaque pointer in the decl_or_value. */
249 dv_as_opaque (decl_or_value dv
)
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
261 /* Pointer to next member of the list. */
262 struct attrs_def
*next
;
264 /* The rtx of register. */
267 /* The declaration corresponding to LOC. */
270 /* Offset from start of DECL. */
271 HOST_WIDE_INT offset
;
273 /* Pool allocation new operator. */
274 inline void *operator new (size_t)
276 return pool
.allocate ();
279 /* Delete operator utilizing pool allocation. */
280 inline void operator delete (void *ptr
)
282 pool
.remove ((attrs_def
*) ptr
);
285 /* Memory allocation pool. */
286 static pool_allocator
<attrs_def
> pool
;
289 /* Structure for chaining the locations. */
290 typedef struct location_chain_def
292 /* Next element in the chain. */
293 struct location_chain_def
*next
;
295 /* The location (REG, MEM or VALUE). */
298 /* The "value" stored in this location. */
302 enum var_init_status init
;
304 /* Pool allocation new operator. */
305 inline void *operator new (size_t)
307 return pool
.allocate ();
310 /* Delete operator utilizing pool allocation. */
311 inline void operator delete (void *ptr
)
313 pool
.remove ((location_chain_def
*) ptr
);
316 /* Memory allocation pool. */
317 static pool_allocator
<location_chain_def
> pool
;
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
326 /* The dependent DV. */
328 /* The dependency VALUE or DECL_DEBUG. */
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
;
336 /* Pool allocation new operator. */
337 inline void *operator new (size_t)
339 return pool
.allocate ();
342 /* Delete operator utilizing pool allocation. */
343 inline void operator delete (void *ptr
)
345 pool
.remove ((loc_exp_dep_s
*) ptr
);
348 /* Memory allocation pool. */
349 static pool_allocator
<loc_exp_dep_s
> pool
;
353 /* This data structure holds information about the depth of a variable
355 typedef struct expand_depth_struct
357 /* This measures the complexity of the expanded expression. It
358 grows by one for each level of expansion that adds more than one
361 /* This counts the number of ENTRY_VALUE expressions in an
362 expansion. We want to minimize their use. */
366 /* This data structure is allocated for one-part variables at the time
367 of emitting notes. */
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. */
383 /* The depth of the cur_loc expression. */
385 /* Dependencies actively used when expand FROM into cur_loc. */
386 vec
<loc_exp_dep
, va_heap
, vl_embed
> deps
;
389 /* Structure describing one part of variable. */
390 typedef struct variable_part_def
392 /* Chain of locations of the part. */
393 location_chain loc_chain
;
395 /* Location which was last emitted to location list. */
400 /* The offset in the variable, if !var->onepart. */
401 HOST_WIDE_INT offset
;
403 /* Pointer to auxiliary data, if var->onepart and emit_notes. */
404 struct onepart_aux
*onepaux
;
408 /* Maximum number of location parts. */
409 #define MAX_VAR_PARTS 16
411 /* Enumeration type used to discriminate various types of one-part
413 typedef enum onepart_enum
415 /* Not a one-part variable. */
417 /* A one-part DECL that is not a DEBUG_EXPR_DECL. */
419 /* A DEBUG_EXPR_DECL. */
425 /* Structure describing where the variable is located. */
426 typedef struct variable_def
428 /* The declaration of the variable, or an RTL value being handled
429 like a declaration. */
432 /* Reference count. */
435 /* Number of variable parts. */
438 /* What type of DV this is, according to enum onepart_enum. */
439 ENUM_BITFIELD (onepart_enum
) onepart
: CHAR_BIT
;
441 /* True if this variable_def struct is currently in the
442 changed_variables hash table. */
443 bool in_changed_variables
;
445 /* The variable parts. */
446 variable_part var_part
[1];
448 typedef const struct variable_def
*const_variable
;
450 /* Pointer to the BB's information specific to variable tracking pass. */
451 #define VTI(BB) ((variable_tracking_info) (BB)->aux)
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)
456 #if ENABLE_CHECKING && (GCC_VERSION >= 2007)
458 /* Access VAR's Ith part's offset, checking that it's not a one-part
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; }))
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; }))
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)
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
480 #define VAR_LOC_DEP_LST(var) (VAR_LOC_1PAUX (var) \
481 ? VAR_LOC_1PAUX (var)->backlinks \
483 #define VAR_LOC_DEP_LSTP(var) (VAR_LOC_1PAUX (var) \
484 ? &VAR_LOC_1PAUX (var)->backlinks \
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 \
494 typedef unsigned int dvuid
;
496 /* Return the uid of DV. */
499 dv_uid (decl_or_value dv
)
501 if (dv_is_value_p (dv
))
502 return CSELIB_VAL_PTR (dv_as_value (dv
))->uid
;
504 return DECL_UID (dv_as_decl (dv
));
507 /* Compute the hash from the uid. */
509 static inline hashval_t
510 dv_uid2hash (dvuid uid
)
515 /* The hash function for a mask table in a shared_htab chain. */
517 static inline hashval_t
518 dv_htab_hash (decl_or_value dv
)
520 return dv_uid2hash (dv_uid (dv
));
523 static void variable_htab_free (void *);
525 /* Variable hashtable helpers. */
527 struct variable_hasher
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
*);
536 /* The hash function for variable_htab, computes the hash value
537 from the declaration of variable X. */
540 variable_hasher::hash (const variable_def
*v
)
542 return dv_htab_hash (v
->dv
);
545 /* Compare the declaration of variable X with declaration Y. */
548 variable_hasher::equal (const variable_def
*v
, const void *y
)
550 decl_or_value dv
= CONST_CAST2 (decl_or_value
, const void *, y
);
552 return (dv_as_opaque (v
->dv
) == dv_as_opaque (dv
));
555 /* Free the element of VARIABLE_HTAB (its type is struct variable_def). */
558 variable_hasher::remove (variable_def
*var
)
560 variable_htab_free (var
);
563 typedef hash_table
<variable_hasher
> variable_table_type
;
564 typedef variable_table_type::iterator variable_iterator_type
;
566 /* Structure for passing some other parameters to function
567 emit_note_insn_var_location. */
568 typedef struct emit_note_data_def
570 /* The instruction which the note will be emitted before/after. */
573 /* Where the note will be emitted (before/after insn)? */
574 enum emit_note_where where
;
576 /* The variables and values active at this point. */
577 variable_table_type
*vars
;
580 /* Structure holding a refcounted hash table. If refcount > 1,
581 it must be first unshared before modified. */
582 typedef struct shared_hash_def
584 /* Reference count. */
587 /* Actual hash table. */
588 variable_table_type
*htab
;
590 /* Pool allocation new operator. */
591 inline void *operator new (size_t)
593 return pool
.allocate ();
596 /* Delete operator utilizing pool allocation. */
597 inline void operator delete (void *ptr
)
599 pool
.remove ((shared_hash_def
*) ptr
);
602 /* Memory allocation pool. */
603 static pool_allocator
<shared_hash_def
> pool
;
606 /* Structure holding the IN or OUT set for a basic block. */
607 typedef struct dataflow_set_def
609 /* Adjustment of stack offset. */
610 HOST_WIDE_INT stack_adjust
;
612 /* Attributes for registers (lists of attrs). */
613 attrs regs
[FIRST_PSEUDO_REGISTER
];
615 /* Variable locations. */
618 /* Vars that is being traversed. */
619 shared_hash traversed_vars
;
622 /* The structure (one for each basic block) containing the information
623 needed for variable tracking. */
624 typedef struct variable_tracking_info_def
626 /* The vector of micro operations. */
627 vec
<micro_operation
> mos
;
629 /* The IN and OUT set for dataflow analysis. */
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. */
639 /* Has the block been visited in DFS? */
642 /* Has the block been flooded in VTA? */
645 } *variable_tracking_info
;
647 /* Alloc pool for struct attrs_def. */
648 pool_allocator
<attrs_def
> attrs_def::pool ("attrs_def pool", 1024);
650 /* Alloc pool for struct variable_def with MAX_VAR_PARTS entries. */
652 static pool_allocator
<variable_def
> var_pool
653 ("variable_def pool", 64,
654 (MAX_VAR_PARTS
- 1) * sizeof (((variable
)NULL
)->var_part
[0]));
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);
660 /* Alloc pool for struct location_chain_def. */
661 pool_allocator
<location_chain_def
> location_chain_def::pool
662 ("location_chain_def pool", 1024);
664 /* Alloc pool for struct shared_hash_def. */
665 pool_allocator
<shared_hash_def
> shared_hash_def::pool
666 ("shared_hash_def pool", 256);
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);
671 /* Changed variables, notes will be emitted for them. */
672 static variable_table_type
*changed_variables
;
674 /* Shall notes be emitted? */
675 static bool emit_notes
;
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
;
682 /* Empty shared hashtable. */
683 static shared_hash empty_shared_hash
;
685 /* Scratch register bitmap used by cselib_expand_value_rtx. */
686 static bitmap scratch_regs
= NULL
;
688 #ifdef HAVE_window_save
689 typedef struct GTY(()) parm_reg
{
695 /* Vector of windowed parameter registers, if any. */
696 static vec
<parm_reg_t
, va_gc
> *windowed_parm_regs
= NULL
;
699 /* Variable used to tell whether cselib_process_insn called our hook. */
700 static bool cselib_hook_called
;
702 /* Local function prototypes. */
703 static void stack_adjust_offset_pre_post (rtx
, HOST_WIDE_INT
*,
705 static void insn_stack_adjust_offset_pre_post (rtx_insn
*, HOST_WIDE_INT
*,
707 static bool vt_stack_adjustments (void);
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
);
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);
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
*);
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);
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);
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
**,
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);
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);
782 /* Callback for stack_adjust_offset_pre_post, called via for_each_inc_dec. */
785 stack_adjust_offset_pre_post_cb (rtx
, rtx op
, rtx dest
, rtx src
, rtx srcoff
,
788 if (dest
!= stack_pointer_rtx
)
791 switch (GET_CODE (op
))
795 ((HOST_WIDE_INT
*)arg
)[0] -= INTVAL (srcoff
);
799 ((HOST_WIDE_INT
*)arg
)[1] -= INTVAL (srcoff
);
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));
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. */
820 stack_adjust_offset_pre_post (rtx pattern
, HOST_WIDE_INT
*pre
,
823 rtx src
= SET_SRC (pattern
);
824 rtx dest
= SET_DEST (pattern
);
827 if (dest
== stack_pointer_rtx
)
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)))
837 *post
+= INTVAL (XEXP (src
, 1));
839 *post
-= INTVAL (XEXP (src
, 1));
842 HOST_WIDE_INT res
[2] = { 0, 0 };
843 for_each_inc_dec (pattern
, stack_adjust_offset_pre_post_cb
, res
);
848 /* Given an INSN, calculate the amount of stack adjustment it contains
849 PRE- and POST-modifying stack pointer. */
852 insn_stack_adjust_offset_pre_post (rtx_insn
*insn
, HOST_WIDE_INT
*pre
,
860 pattern
= PATTERN (insn
);
861 if (RTX_FRAME_RELATED_P (insn
))
863 rtx expr
= find_reg_note (insn
, REG_FRAME_RELATED_EXPR
, NULL_RTX
);
865 pattern
= XEXP (expr
, 0);
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
)
875 /* There may be stack adjustments inside compound insns. Search
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
);
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. */
888 vt_stack_adjustments (void)
890 edge_iterator
*stack
;
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
;
900 /* Allocate stack for back-tracking up CFG. */
901 stack
= XNEWVEC (edge_iterator
, n_basic_blocks_for_fn (cfun
) + 1);
904 /* Push the first edge on to the stack. */
905 stack
[sp
++] = ei_start (ENTRY_BLOCK_PTR_FOR_FN (cfun
)->succs
);
913 /* Look at the edge on the top of the stack. */
915 src
= ei_edge (ei
)->src
;
916 dest
= ei_edge (ei
)->dest
;
918 /* Check if the edge destination has been visited yet. */
919 if (!VTI (dest
)->visited
)
922 HOST_WIDE_INT pre
, post
, offset
;
923 VTI (dest
)->visited
= true;
924 VTI (dest
)->in
.stack_adjust
= offset
= VTI (src
)->out
.stack_adjust
;
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
))
932 insn_stack_adjust_offset_pre_post (insn
, &pre
, &post
);
933 offset
+= pre
+ post
;
936 VTI (dest
)->out
.stack_adjust
= offset
;
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
);
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.
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.
960 We must check whether the adjustments on other edges are
962 if (dest
!= EXIT_BLOCK_PTR_FOR_FN (cfun
)
963 && VTI (dest
)->in
.stack_adjust
!= VTI (src
)->out
.stack_adjust
)
969 if (! ei_one_before_end_p (ei
))
970 /* Go to the next edge. */
971 ei_next (&stack
[sp
- 1]);
973 /* Return to previous level if there are no more edges. */
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
;
987 /* Compute a CFA-based value for an ADJUSTMENT made to stack_pointer_rtx
988 or hard_frame_pointer_rtx. */
991 compute_cfa_pointer (HOST_WIDE_INT adjustment
)
993 return plus_constant (Pmode
, cfa_base_rtx
, adjustment
+ cfa_base_offset
);
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;
1000 /* Data for adjust_mems callback. */
1002 struct adjust_mem_data
1005 machine_mode mem_mode
;
1006 HOST_WIDE_INT stack_adjust
;
1007 rtx_expr_list
*side_effects
;
1010 /* Helper for adjust_mems. Return true if X is suitable for
1011 transformation of wider mode arithmetics to narrower mode. */
1014 use_narrower_mode_test (rtx x
, const_rtx subreg
)
1016 subrtx_var_iterator::array_type array
;
1017 FOR_EACH_SUBRTX_VAR (iter
, array
, x
, NONCONST
)
1021 iter
.skip_subrtxes ();
1023 switch (GET_CODE (x
))
1026 if (cselib_lookup (x
, GET_MODE (SUBREG_REG (subreg
)), 0, VOIDmode
))
1028 if (!validate_subreg (GET_MODE (subreg
), GET_MODE (x
), x
,
1029 subreg_lowpart_offset (GET_MODE (subreg
),
1038 iter
.substitute (XEXP (x
, 0));
1047 /* Transform X into narrower mode MODE from wider mode WMODE. */
1050 use_narrower_mode (rtx x
, machine_mode mode
, machine_mode wmode
)
1054 return lowpart_subreg (mode
, x
, wmode
);
1055 switch (GET_CODE (x
))
1058 return lowpart_subreg (mode
, x
, wmode
);
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
);
1066 op0
= use_narrower_mode (XEXP (x
, 0), mode
, wmode
);
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
);
1079 /* Helper function for adjusting used MEMs. */
1082 adjust_mems (rtx loc
, const_rtx old_rtx
, void *data
)
1084 struct adjust_mem_data
*amd
= (struct adjust_mem_data
*) data
;
1085 rtx mem
, addr
= loc
, tem
;
1086 machine_mode mem_mode_save
;
1088 switch (GET_CODE (loc
))
1091 /* Don't do any sp or fp replacements outside of MEM addresses
1093 if (amd
->mem_mode
== VOIDmode
&& amd
->store
)
1095 if (loc
== stack_pointer_rtx
1096 && !frame_pointer_needed
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
1103 return compute_cfa_pointer (hard_frame_pointer_adjustment
);
1104 gcc_checking_assert (loc
!= virtual_incoming_args_rtx
);
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
);
1115 addr
= XEXP (mem
, 0);
1116 mem_mode_save
= amd
->mem_mode
;
1117 amd
->mem_mode
= GET_MODE (mem
);
1118 store_save
= amd
->store
;
1120 addr
= simplify_replace_fn_rtx (addr
, old_rtx
, adjust_mems
, data
);
1121 amd
->store
= store_save
;
1122 amd
->mem_mode
= mem_mode_save
;
1124 addr
= targetm
.delegitimize_address (addr
);
1125 if (addr
!= XEXP (mem
, 0))
1126 mem
= replace_equiv_address_nv (mem
, addr
);
1128 mem
= avoid_constant_pool_reference (mem
);
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
),
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
),
1149 store_save
= amd
->store
;
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
),
1158 addr
= XEXP (loc
, 1);
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
;
1166 tem
= simplify_replace_fn_rtx (XEXP (loc
, 1), old_rtx
,
1168 amd
->store
= store_save
;
1169 amd
->side_effects
= alloc_EXPR_LIST (0,
1170 gen_rtx_SET (XEXP (loc
, 0), tem
),
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
;
1178 addr
= simplify_replace_fn_rtx (SUBREG_REG (loc
), old_rtx
, adjust_mems
,
1180 amd
->store
= store_save
;
1181 mem
= simplify_replace_fn_rtx (addr
, old_rtx
, adjust_mems
, data
);
1182 if (mem
== SUBREG_REG (loc
))
1187 tem
= simplify_gen_subreg (GET_MODE (loc
), mem
,
1188 GET_MODE (SUBREG_REG (loc
)),
1192 tem
= simplify_gen_subreg (GET_MODE (loc
), addr
,
1193 GET_MODE (SUBREG_REG (loc
)),
1195 if (tem
== NULL_RTX
)
1196 tem
= gen_rtx_raw_SUBREG (GET_MODE (loc
), addr
, SUBREG_BYTE (loc
));
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
)));
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
1222 if (ASM_OPERANDS_OUTPUT_IDX (loc
) != 0)
1231 /* Helper function for replacement of uses. */
1234 adjust_mem_uses (rtx
*x
, void *data
)
1236 rtx new_x
= simplify_replace_fn_rtx (*x
, NULL_RTX
, adjust_mems
, data
);
1238 validate_change (NULL_RTX
, x
, new_x
, true);
1241 /* Helper function for replacement of stores. */
1244 adjust_mem_stores (rtx loc
, const_rtx expr
, void *data
)
1248 rtx new_dest
= simplify_replace_fn_rtx (SET_DEST (expr
), NULL_RTX
,
1250 if (new_dest
!= SET_DEST (expr
))
1252 rtx xexpr
= CONST_CAST_RTX (expr
);
1253 validate_change (NULL_RTX
, &SET_DEST (xexpr
), new_dest
, true);
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. */
1263 adjust_insn (basic_block bb
, rtx_insn
*insn
)
1265 struct adjust_mem_data amd
;
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
))
1274 unsigned int i
, nregs
= vec_safe_length (windowed_parm_regs
);
1275 rtx rtl
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nregs
* 2));
1278 FOR_EACH_VEC_SAFE_ELT (windowed_parm_regs
, i
, p
)
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
)));
1289 validate_change (NULL_RTX
, &PATTERN (insn
), rtl
, true);
1294 amd
.mem_mode
= VOIDmode
;
1295 amd
.stack_adjust
= -VTI (bb
)->out
.stack_adjust
;
1296 amd
.side_effects
= NULL
;
1299 note_stores (PATTERN (insn
), adjust_mem_stores
, &amd
);
1302 if (GET_CODE (PATTERN (insn
)) == PARALLEL
1303 && asm_noperands (PATTERN (insn
)) > 0
1304 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 0)) == SET
)
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
)
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
))
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
)))
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);
1349 note_uses (&PATTERN (insn
), adjust_mem_uses
, &amd
);
1351 /* For read-only MEMs containing some constant, prefer those
1353 set
= single_set (insn
);
1354 if (set
&& MEM_P (SET_SRC (set
)) && MEM_READONLY_P (SET_SRC (set
)))
1356 rtx note
= find_reg_equal_equiv_note (insn
);
1358 if (note
&& CONSTANT_P (XEXP (note
, 0)))
1359 validate_change (NULL_RTX
, &SET_SRC (set
), XEXP (note
, 0), true);
1362 if (amd
.side_effects
)
1364 rtx
*pat
, new_pat
, s
;
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);
1374 for (s
= amd
.side_effects
, newn
= 0; s
; newn
++)
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
);
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);
1389 /* Return the DEBUG_EXPR of a DEBUG_EXPR_DECL or the VALUE in DV. */
1391 dv_as_rtx (decl_or_value dv
)
1395 if (dv_is_value_p (dv
))
1396 return dv_as_value (dv
);
1398 decl
= dv_as_decl (dv
);
1400 gcc_checking_assert (TREE_CODE (decl
) == DEBUG_EXPR_DECL
);
1401 return DECL_RTL_KNOWN_SET (decl
);
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
)
1412 if (!MAY_HAVE_DEBUG_INSNS
)
1415 if (dv_is_value_p (dv
))
1416 return ONEPART_VALUE
;
1418 decl
= dv_as_decl (dv
);
1420 if (TREE_CODE (decl
) == DEBUG_EXPR_DECL
)
1421 return ONEPART_DEXPR
;
1423 if (target_for_debug_bind (decl
) != NULL_TREE
)
1424 return ONEPART_VDECL
;
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
)
1433 return onepart
? valvar_pool
: var_pool
;
1436 /* Build a decl_or_value out of a decl. */
1437 static inline decl_or_value
1438 dv_from_decl (tree decl
)
1442 gcc_checking_assert (dv_is_decl_p (dv
));
1446 /* Build a decl_or_value out of a value. */
1447 static inline decl_or_value
1448 dv_from_value (rtx value
)
1452 gcc_checking_assert (dv_is_value_p (dv
));
1456 /* Return a value or the decl of a debug_expr as a decl_or_value. */
1457 static inline decl_or_value
1462 switch (GET_CODE (x
))
1465 dv
= dv_from_decl (DEBUG_EXPR_TREE_DECL (x
));
1466 gcc_checking_assert (DECL_RTL_KNOWN_SET (DEBUG_EXPR_TREE_DECL (x
)) == x
);
1470 dv
= dv_from_value (x
);
1480 extern void debug_dv (decl_or_value dv
);
1483 debug_dv (decl_or_value dv
)
1485 if (dv_is_value_p (dv
))
1486 debug_rtx (dv_as_value (dv
));
1488 debug_generic_stmt (dv_as_decl (dv
));
1491 static void loc_exp_dep_clear (variable var
);
1493 /* Free the element of VARIABLE_HTAB (its type is struct variable_def). */
1496 variable_htab_free (void *elem
)
1499 variable var
= (variable
) elem
;
1500 location_chain node
, next
;
1502 gcc_checking_assert (var
->refcount
> 0);
1505 if (var
->refcount
> 0)
1508 for (i
= 0; i
< var
->n_var_parts
; i
++)
1510 for (node
= var
->var_part
[i
].loc_chain
; node
; node
= next
)
1515 var
->var_part
[i
].loc_chain
= NULL
;
1517 if (var
->onepart
&& VAR_LOC_1PAUX (var
))
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
1525 if (var
->onepart
== ONEPART_DEXPR
)
1526 set_dv_changed (var
->dv
, true);
1528 onepart_pool (var
->onepart
).remove (var
);
1531 /* Initialize the set (array) SET of attrs to empty lists. */
1534 init_attrs_list_set (attrs
*set
)
1538 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1542 /* Make the list *LISTP empty. */
1545 attrs_list_clear (attrs
*listp
)
1549 for (list
= *listp
; list
; list
= next
)
1557 /* Return true if the pair of DECL and OFFSET is the member of the LIST. */
1560 attrs_list_member (attrs list
, decl_or_value dv
, HOST_WIDE_INT offset
)
1562 for (; list
; list
= list
->next
)
1563 if (dv_as_opaque (list
->dv
) == dv_as_opaque (dv
) && list
->offset
== offset
)
1568 /* Insert the triplet DECL, OFFSET, LOC to the list *LISTP. */
1571 attrs_list_insert (attrs
*listp
, decl_or_value dv
,
1572 HOST_WIDE_INT offset
, rtx loc
)
1574 attrs list
= new attrs_def
;
1577 list
->offset
= offset
;
1578 list
->next
= *listp
;
1582 /* Copy all nodes from SRC and create a list *DSTP of the copies. */
1585 attrs_list_copy (attrs
*dstp
, attrs src
)
1587 attrs_list_clear (dstp
);
1588 for (; src
; src
= src
->next
)
1590 attrs n
= new attrs_def
;
1593 n
->offset
= src
->offset
;
1599 /* Add all nodes from SRC which are not in *DSTP to *DSTP. */
1602 attrs_list_union (attrs
*dstp
, attrs src
)
1604 for (; src
; src
= src
->next
)
1606 if (!attrs_list_member (*dstp
, src
->dv
, src
->offset
))
1607 attrs_list_insert (dstp
, src
->dv
, src
->offset
, src
->loc
);
1611 /* Combine nodes that are not onepart nodes from SRC and SRC2 into
1615 attrs_list_mpdv_union (attrs
*dstp
, attrs src
, attrs src2
)
1617 gcc_assert (!*dstp
);
1618 for (; src
; src
= src
->next
)
1620 if (!dv_onepart_p (src
->dv
))
1621 attrs_list_insert (dstp
, src
->dv
, src
->offset
, src
->loc
);
1623 for (src
= src2
; src
; src
= src
->next
)
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
);
1631 /* Shared hashtable support. */
1633 /* Return true if VARS is shared. */
1636 shared_hash_shared (shared_hash vars
)
1638 return vars
->refcount
> 1;
1641 /* Return the hash table for VARS. */
1643 static inline variable_table_type
*
1644 shared_hash_htab (shared_hash vars
)
1649 /* Return true if VAR is shared, or maybe because VARS is shared. */
1652 shared_var_p (variable var
, shared_hash vars
)
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
));
1659 /* Copy variables into a new hash table. */
1662 shared_hash_unshare (shared_hash vars
)
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
);
1673 /* Increment reference counter on VARS and return it. */
1675 static inline shared_hash
1676 shared_hash_copy (shared_hash vars
)
1682 /* Decrement reference counter and destroy hash table if not shared
1686 shared_hash_destroy (shared_hash vars
)
1688 gcc_checking_assert (vars
->refcount
> 0);
1689 if (--vars
->refcount
== 0)
1696 /* Unshare *PVARS if shared and return slot for DV. If INS is
1697 INSERT, insert it if not already present. */
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
)
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
);
1708 static inline variable_def
**
1709 shared_hash_find_slot_unshare (shared_hash
*pvars
, decl_or_value dv
,
1710 enum insert_option ins
)
1712 return shared_hash_find_slot_unshare_1 (pvars
, dv
, dv_htab_hash (dv
), ins
);
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
1719 static inline variable_def
**
1720 shared_hash_find_slot_1 (shared_hash vars
, decl_or_value dv
, hashval_t dvhash
)
1722 return shared_hash_htab (vars
)->find_slot_with_hash (dv
, dvhash
,
1723 shared_hash_shared (vars
)
1724 ? NO_INSERT
: INSERT
);
1727 static inline variable_def
**
1728 shared_hash_find_slot (shared_hash vars
, decl_or_value dv
)
1730 return shared_hash_find_slot_1 (vars
, dv
, dv_htab_hash (dv
));
1733 /* Return slot for DV only if it is already present in the hash table. */
1735 static inline variable_def
**
1736 shared_hash_find_slot_noinsert_1 (shared_hash vars
, decl_or_value dv
,
1739 return shared_hash_htab (vars
)->find_slot_with_hash (dv
, dvhash
, NO_INSERT
);
1742 static inline variable_def
**
1743 shared_hash_find_slot_noinsert (shared_hash vars
, decl_or_value dv
)
1745 return shared_hash_find_slot_noinsert_1 (vars
, dv
, dv_htab_hash (dv
));
1748 /* Return variable for DV or NULL if not already present in the hash
1751 static inline variable
1752 shared_hash_find_1 (shared_hash vars
, decl_or_value dv
, hashval_t dvhash
)
1754 return shared_hash_htab (vars
)->find_with_hash (dv
, dvhash
);
1757 static inline variable
1758 shared_hash_find (shared_hash vars
, decl_or_value dv
)
1760 return shared_hash_find_1 (vars
, dv
, dv_htab_hash (dv
));
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.
1773 canon_value_cmp (rtx tval
, rtx cval
)
1776 || CSELIB_VAL_PTR (tval
)->uid
< CSELIB_VAL_PTR (cval
)->uid
;
1779 static bool dst_can_be_shared
;
1781 /* Return a copy of a variable VAR and insert it to dataflow set SET. */
1783 static variable_def
**
1784 unshare_variable (dataflow_set
*set
, variable_def
**slot
, variable var
,
1785 enum var_init_status initialized
)
1790 new_var
= onepart_pool (var
->onepart
).allocate ();
1791 new_var
->dv
= var
->dv
;
1792 new_var
->refcount
= 1;
1794 new_var
->n_var_parts
= var
->n_var_parts
;
1795 new_var
->onepart
= var
->onepart
;
1796 new_var
->in_changed_variables
= false;
1798 if (! flag_var_tracking_uninit
)
1799 initialized
= VAR_INIT_STATUS_INITIALIZED
;
1801 for (i
= 0; i
< var
->n_var_parts
; i
++)
1803 location_chain node
;
1804 location_chain
*nextp
;
1806 if (i
== 0 && var
->onepart
)
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
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
;
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
)
1821 location_chain new_lc
;
1823 new_lc
= new location_chain_def
;
1824 new_lc
->next
= NULL
;
1825 if (node
->init
> initialized
)
1826 new_lc
->init
= node
->init
;
1828 new_lc
->init
= initialized
;
1829 if (node
->set_src
&& !(MEM_P (node
->set_src
)))
1830 new_lc
->set_src
= node
->set_src
;
1832 new_lc
->set_src
= NULL
;
1833 new_lc
->loc
= node
->loc
;
1836 nextp
= &new_lc
->next
;
1839 new_var
->var_part
[i
].cur_loc
= var
->var_part
[i
].cur_loc
;
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
);
1848 if (var
->in_changed_variables
)
1850 variable_def
**cslot
1851 = changed_variables
->find_slot_with_hash (var
->dv
,
1852 dv_htab_hash (var
->dv
),
1854 gcc_assert (*cslot
== (void *) var
);
1855 var
->in_changed_variables
= false;
1856 variable_htab_free (var
);
1858 new_var
->in_changed_variables
= true;
1863 /* Copy all variables from hash table SRC to hash table DST. */
1866 vars_copy (variable_table_type
*dst
, variable_table_type
*src
)
1868 variable_iterator_type hi
;
1871 FOR_EACH_HASH_TABLE_ELEMENT (*src
, var
, variable
, hi
)
1873 variable_def
**dstp
;
1875 dstp
= dst
->find_slot_with_hash (var
->dv
, dv_htab_hash (var
->dv
),
1881 /* Map a decl to its main debug decl. */
1884 var_debug_decl (tree decl
)
1886 if (decl
&& TREE_CODE (decl
) == VAR_DECL
1887 && DECL_HAS_DEBUG_EXPR_P (decl
))
1889 tree debugdecl
= DECL_DEBUG_EXPR (decl
);
1890 if (DECL_P (debugdecl
))
1897 /* Set the register LOC to contain DV, OFFSET. */
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
)
1905 bool decl_p
= dv_is_decl_p (dv
);
1908 dv
= dv_from_decl (var_debug_decl (dv_as_decl (dv
)));
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
)
1915 attrs_list_insert (&set
->regs
[REGNO (loc
)], dv
, offset
, loc
);
1916 set_variable_part (set
, loc
, dv
, offset
, initialized
, set_src
, iopt
);
1919 /* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). */
1922 var_reg_set (dataflow_set
*set
, rtx loc
, enum var_init_status initialized
,
1925 tree decl
= REG_EXPR (loc
);
1926 HOST_WIDE_INT offset
= REG_OFFSET (loc
);
1928 var_reg_decl_set (set
, loc
, initialized
,
1929 dv_from_decl (decl
), offset
, set_src
, INSERT
);
1932 static enum var_init_status
1933 get_init_value (dataflow_set
*set
, rtx loc
, decl_or_value dv
)
1937 enum var_init_status ret_val
= VAR_INIT_STATUS_UNKNOWN
;
1939 if (! flag_var_tracking_uninit
)
1940 return VAR_INIT_STATUS_INITIALIZED
;
1942 var
= shared_hash_find (set
->vars
, dv
);
1945 for (i
= 0; i
< var
->n_var_parts
&& ret_val
== VAR_INIT_STATUS_UNKNOWN
; i
++)
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
))
1951 ret_val
= nextp
->init
;
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
1968 var_reg_delete_and_set (dataflow_set
*set
, rtx loc
, bool modify
,
1969 enum var_init_status initialized
, rtx set_src
)
1971 tree decl
= REG_EXPR (loc
);
1972 HOST_WIDE_INT offset
= REG_OFFSET (loc
);
1976 decl
= var_debug_decl (decl
);
1978 if (initialized
== VAR_INIT_STATUS_UNKNOWN
)
1979 initialized
= get_init_value (set
, loc
, dv_from_decl (decl
));
1981 nextp
= &set
->regs
[REGNO (loc
)];
1982 for (node
= *nextp
; node
; node
= next
)
1985 if (dv_as_opaque (node
->dv
) != decl
|| node
->offset
!= offset
)
1987 delete_variable_part (set
, node
->loc
, node
->dv
, node
->offset
);
1994 nextp
= &node
->next
;
1998 clobber_variable_part (set
, loc
, dv_from_decl (decl
), offset
, set_src
);
1999 var_reg_set (set
, loc
, initialized
, set_src
);
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. */
2008 var_reg_delete (dataflow_set
*set
, rtx loc
, bool clobber
)
2010 attrs
*nextp
= &set
->regs
[REGNO (loc
)];
2015 tree decl
= REG_EXPR (loc
);
2016 HOST_WIDE_INT offset
= REG_OFFSET (loc
);
2018 decl
= var_debug_decl (decl
);
2020 clobber_variable_part (set
, NULL
, dv_from_decl (decl
), offset
, NULL
);
2023 for (node
= *nextp
; node
; node
= next
)
2026 if (clobber
|| !dv_onepart_p (node
->dv
))
2028 delete_variable_part (set
, node
->loc
, node
->dv
, node
->offset
);
2033 nextp
= &node
->next
;
2037 /* Delete content of register with number REGNO in dataflow set SET. */
2040 var_regno_delete (dataflow_set
*set
, int regno
)
2042 attrs
*reg
= &set
->regs
[regno
];
2045 for (node
= *reg
; node
; node
= next
)
2048 delete_variable_part (set
, node
->loc
, node
->dv
, node
->offset
);
2054 /* Return true if I is the negated value of a power of two. */
2056 negative_power_of_two_p (HOST_WIDE_INT i
)
2058 unsigned HOST_WIDE_INT x
= -(unsigned HOST_WIDE_INT
)i
;
2059 return x
== (x
& -x
);
2062 /* Strip constant offsets and alignments off of LOC. Return the base
2066 vt_get_canonicalize_base (rtx loc
)
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);
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
;
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
;
2087 static rtx
vt_canonicalize_addr (dataflow_set
*, rtx
);
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
2094 get_addr_from_global_cache (rtx
const loc
)
2098 gcc_checking_assert (GET_CODE (loc
) == VALUE
);
2101 rtx
*slot
= &global_get_addr_cache
->get_or_insert (loc
, &existed
);
2105 x
= canon_rtx (get_addr (loc
));
2107 /* Tentative, avoiding infinite recursion. */
2112 rtx nx
= vt_canonicalize_addr (NULL
, x
);
2115 /* The table may have moved during recursion, recompute
2117 *global_get_addr_cache
->get (loc
) = x
= nx
;
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
2129 get_addr_from_local_cache (dataflow_set
*set
, rtx
const loc
)
2136 gcc_checking_assert (GET_CODE (loc
) == VALUE
);
2139 rtx
*slot
= &local_get_addr_cache
->get_or_insert (loc
, &existed
);
2143 x
= get_addr_from_global_cache (loc
);
2145 /* Tentative, avoiding infinite recursion. */
2148 /* Recurse to cache local expansion of X, or if we need to search
2149 for a VALUE in the expansion. */
2152 rtx nx
= vt_canonicalize_addr (set
, x
);
2155 slot
= local_get_addr_cache
->get (loc
);
2161 dv
= dv_from_rtx (x
);
2162 var
= shared_hash_find (set
->vars
, dv
);
2166 /* Look for an improved equivalent expression. */
2167 for (l
= var
->var_part
[0].loc_chain
; l
; l
= l
->next
)
2169 rtx base
= vt_get_canonicalize_base (l
->loc
);
2170 if (GET_CODE (base
) == VALUE
2171 && canon_value_cmp (base
, loc
))
2173 rtx nx
= vt_canonicalize_addr (set
, l
->loc
);
2176 slot
= local_get_addr_cache
->get (loc
);
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.
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
2201 vt_canonicalize_addr (dataflow_set
*set
, rtx oloc
)
2203 HOST_WIDE_INT ofst
= 0;
2204 machine_mode mode
= GET_MODE (oloc
);
2211 while (GET_CODE (loc
) == PLUS
2212 && GET_CODE (XEXP (loc
, 1)) == CONST_INT
)
2214 ofst
+= INTVAL (XEXP (loc
, 1));
2215 loc
= XEXP (loc
, 0);
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))))
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));
2231 if (GET_CODE (loc
) == VALUE
)
2234 loc
= get_addr_from_local_cache (set
, loc
);
2236 loc
= get_addr_from_global_cache (loc
);
2238 /* Consolidate plus_constants. */
2239 while (ofst
&& GET_CODE (loc
) == PLUS
2240 && GET_CODE (XEXP (loc
, 1)) == CONST_INT
)
2242 ofst
+= INTVAL (XEXP (loc
, 1));
2243 loc
= XEXP (loc
, 0);
2250 x
= canon_rtx (loc
);
2257 /* Add OFST back in. */
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
)
2266 loc
= plus_constant (mode
, loc
, ofst
);
2272 /* Return true iff there's a true dependence between MLOC and LOC.
2273 MADDR must be a canonicalized version of MLOC's address. */
2276 vt_canon_true_dep (dataflow_set
*set
, rtx mloc
, rtx maddr
, rtx loc
)
2278 if (GET_CODE (loc
) != MEM
)
2281 rtx addr
= vt_canonicalize_addr (set
, XEXP (loc
, 0));
2282 if (!canon_true_dependence (mloc
, GET_MODE (mloc
), maddr
, loc
, addr
))
2288 /* Hold parameters for the hashtab traversal function
2289 drop_overlapping_mem_locs, see below. */
2291 struct overlapping_mems
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. */
2303 drop_overlapping_mem_locs (variable_def
**slot
, overlapping_mems
*coms
)
2305 dataflow_set
*set
= coms
->set
;
2306 rtx mloc
= coms
->loc
, addr
= coms
->addr
;
2307 variable var
= *slot
;
2309 if (var
->onepart
== ONEPART_VALUE
)
2311 location_chain loc
, *locp
;
2312 bool changed
= false;
2315 gcc_assert (var
->n_var_parts
== 1);
2317 if (shared_var_p (var
, set
->vars
))
2319 for (loc
= var
->var_part
[0].loc_chain
; loc
; loc
= loc
->next
)
2320 if (vt_canon_true_dep (set
, mloc
, addr
, loc
->loc
))
2326 slot
= unshare_variable (set
, slot
, var
, VAR_INIT_STATUS_UNKNOWN
);
2328 gcc_assert (var
->n_var_parts
== 1);
2331 if (VAR_LOC_1PAUX (var
))
2332 cur_loc
= VAR_LOC_FROM (var
);
2334 cur_loc
= var
->var_part
[0].cur_loc
;
2336 for (locp
= &var
->var_part
[0].loc_chain
, loc
= *locp
;
2339 if (!vt_canon_true_dep (set
, mloc
, addr
, loc
->loc
))
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
)
2352 var
->var_part
[0].cur_loc
= NULL
;
2353 if (VAR_LOC_1PAUX (var
))
2354 VAR_LOC_FROM (var
) = NULL
;
2359 if (!var
->var_part
[0].loc_chain
)
2365 variable_was_changed (var
, set
);
2371 /* Remove from SET all VALUE bindings to MEMs that overlap with LOC. */
2374 clobber_overlapping_mems (dataflow_set
*set
, rtx loc
)
2376 struct overlapping_mems coms
;
2378 gcc_checking_assert (GET_CODE (loc
) == MEM
);
2381 coms
.loc
= canon_rtx (loc
);
2382 coms
.addr
= vt_canonicalize_addr (set
, XEXP (loc
, 0));
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
;
2390 /* Set the location of DV, OFFSET as the MEM LOC. */
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
)
2397 if (dv_is_decl_p (dv
))
2398 dv
= dv_from_decl (var_debug_decl (dv_as_decl (dv
)));
2400 set_variable_part (set
, loc
, dv
, offset
, initialized
, set_src
, iopt
);
2403 /* Set the location part of variable MEM_EXPR (LOC) in dataflow set
2405 Adjust the address first if it is stack pointer based. */
2408 var_mem_set (dataflow_set
*set
, rtx loc
, enum var_init_status initialized
,
2411 tree decl
= MEM_EXPR (loc
);
2412 HOST_WIDE_INT offset
= INT_MEM_OFFSET (loc
);
2414 var_mem_decl_set (set
, loc
, initialized
,
2415 dv_from_decl (decl
), offset
, set_src
, INSERT
);
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. */
2426 var_mem_delete_and_set (dataflow_set
*set
, rtx loc
, bool modify
,
2427 enum var_init_status initialized
, rtx set_src
)
2429 tree decl
= MEM_EXPR (loc
);
2430 HOST_WIDE_INT offset
= INT_MEM_OFFSET (loc
);
2432 clobber_overlapping_mems (set
, loc
);
2433 decl
= var_debug_decl (decl
);
2435 if (initialized
== VAR_INIT_STATUS_UNKNOWN
)
2436 initialized
= get_init_value (set
, loc
, dv_from_decl (decl
));
2439 clobber_variable_part (set
, NULL
, dv_from_decl (decl
), offset
, set_src
);
2440 var_mem_set (set
, loc
, initialized
, set_src
);
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. */
2448 var_mem_delete (dataflow_set
*set
, rtx loc
, bool clobber
)
2450 tree decl
= MEM_EXPR (loc
);
2451 HOST_WIDE_INT offset
= INT_MEM_OFFSET (loc
);
2453 clobber_overlapping_mems (set
, loc
);
2454 decl
= var_debug_decl (decl
);
2456 clobber_variable_part (set
, NULL
, dv_from_decl (decl
), offset
, NULL
);
2457 delete_variable_part (set
, loc
, dv_from_decl (decl
), offset
);
2460 /* Return true if LOC should not be expanded for location expressions,
2464 unsuitable_loc (rtx loc
)
2466 switch (GET_CODE (loc
))
2480 /* Bind VAL to LOC in SET. If MODIFIED, detach LOC from any values
2484 val_bind (dataflow_set
*set
, rtx val
, rtx loc
, bool 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
);
2493 else if (MEM_P (loc
))
2495 struct elt_loc_list
*l
= CSELIB_VAL_PTR (val
)->locs
;
2498 clobber_overlapping_mems (set
, loc
);
2500 if (l
&& GET_CODE (l
->loc
) == VALUE
)
2501 l
= canonical_cselib_val (CSELIB_VAL_PTR (l
->loc
))->locs
;
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. */
2507 if (GET_CODE (l
->loc
) == MEM
&& XEXP (l
->loc
, 0) == XEXP (loc
, 0))
2513 var_mem_decl_set (set
, loc
, VAR_INIT_STATUS_INITIALIZED
,
2514 dv_from_value (val
), 0, NULL_RTX
, INSERT
);
2518 /* Other kinds of equivalences are necessarily static, at least
2519 so long as we do not perform substitutions while merging
2522 set_variable_part (set
, loc
, dv_from_value (val
), 0,
2523 VAR_INIT_STATUS_INITIALIZED
, NULL_RTX
, INSERT
);
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. */
2532 val_store (dataflow_set
*set
, rtx val
, rtx loc
, rtx_insn
*insn
,
2535 cselib_val
*v
= CSELIB_VAL_PTR (val
);
2537 gcc_assert (cselib_preserved_value_p (v
));
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);
2547 struct elt_loc_list
*l
;
2548 for (l
= v
->locs
; l
; l
= l
->next
)
2550 fprintf (dump_file
, "\n%i: ", INSN_UID (l
->setting_insn
));
2551 print_inline_rtx (dump_file
, l
->loc
, 0);
2554 fprintf (dump_file
, "\n");
2557 gcc_checking_assert (!unsuitable_loc (loc
));
2559 val_bind (set
, val
, loc
, modified
);
2562 /* Clear (canonical address) slots that reference X. */
2565 local_get_addr_clear_given_value (rtx
const &, rtx
*slot
, rtx x
)
2567 if (vt_get_canonicalize_base (*slot
) == x
)
2572 /* Reset this node, detaching all its equivalences. Return the slot
2573 in the variable hash table that holds dv, if there is one. */
2576 val_reset (dataflow_set
*set
, decl_or_value dv
)
2578 variable var
= shared_hash_find (set
->vars
, dv
) ;
2579 location_chain node
;
2582 if (!var
|| !var
->n_var_parts
)
2585 gcc_assert (var
->n_var_parts
== 1);
2587 if (var
->onepart
== ONEPART_VALUE
)
2589 rtx x
= dv_as_value (dv
);
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
);
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. */
2602 local_get_addr_cache
2603 ->traverse
<rtx
, local_get_addr_clear_given_value
> (x
);
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
))
2614 for (node
= var
->var_part
[0].loc_chain
; node
; node
= node
->next
)
2615 if (GET_CODE (node
->loc
) == VALUE
&& cval
!= node
->loc
)
2617 /* Redirect the equivalence link to the new canonical
2618 value, or simply remove it if it would point at
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);
2629 decl_or_value cdv
= dv_from_value (cval
);
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
)
2635 if (node
->loc
== cval
)
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
);
2644 set_variable_part (set
, node
->loc
, cdv
, 0,
2645 node
->init
, node
->set_src
, NO_INSERT
);
2649 /* We remove this last, to make sure that the canonical value is not
2650 removed to the point of requiring reinsertion. */
2652 delete_variable_part (set
, dv_as_value (dv
), dv_from_value (cval
), 0);
2654 clobber_variable_part (set
, NULL
, dv
, 0, NULL
);
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
2662 val_resolve (dataflow_set
*set
, rtx val
, rtx loc
, rtx_insn
*insn
)
2664 decl_or_value dv
= dv_from_value (val
);
2666 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2669 fprintf (dump_file
, "%i: ", INSN_UID (insn
));
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
);
2678 val_reset (set
, dv
);
2680 gcc_checking_assert (!unsuitable_loc (loc
));
2684 attrs node
, found
= NULL
;
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
))
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
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
);
2703 /* If we didn't find any equivalence, we need to remember that
2704 this value is held in the named register. */
2708 /* ??? Attempt to find and merge equivalent MEMs or other
2711 val_bind (set
, val
, loc
, false);
2714 /* Initialize dataflow set SET to be empty.
2715 VARS_SIZE is the initial size of hash table VARS. */
2718 dataflow_set_init (dataflow_set
*set
)
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
;
2726 /* Delete the contents of dataflow set SET. */
2729 dataflow_set_clear (dataflow_set
*set
)
2733 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
2734 attrs_list_clear (&set
->regs
[i
]);
2736 shared_hash_destroy (set
->vars
);
2737 set
->vars
= shared_hash_copy (empty_shared_hash
);
2740 /* Copy the contents of dataflow set SRC to DST. */
2743 dataflow_set_copy (dataflow_set
*dst
, dataflow_set
*src
)
2747 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
2748 attrs_list_copy (&dst
->regs
[i
], src
->regs
[i
]);
2750 shared_hash_destroy (dst
->vars
);
2751 dst
->vars
= shared_hash_copy (src
->vars
);
2752 dst
->stack_adjust
= src
->stack_adjust
;
2755 /* Information for merging lists of locations for a given offset of variable.
2757 struct variable_union_info
2759 /* Node of the location chain. */
2762 /* The sum of positions in the input chains. */
2765 /* The position in the chain of DST dataflow set. */
2769 /* Buffer for location list sorting and its allocated size. */
2770 static struct variable_union_info
*vui_vec
;
2771 static int vui_allocated
;
2773 /* Compare function for qsort, order the structures by POS element. */
2776 variable_union_info_cmp_pos (const void *n1
, const void *n2
)
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
;
2783 if (i1
->pos
!= i2
->pos
)
2784 return i1
->pos
- i2
->pos
;
2786 return (i1
->pos_dst
- i2
->pos_dst
);
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. */
2800 variable_union (variable src
, dataflow_set
*set
)
2803 variable_def
**dstp
;
2806 dstp
= shared_hash_find_slot (set
->vars
, src
->dv
);
2807 if (!dstp
|| !*dstp
)
2811 dst_can_be_shared
= false;
2813 dstp
= shared_hash_find_slot_unshare (&set
->vars
, src
->dv
, INSERT
);
2817 /* Continue traversing the hash table. */
2823 gcc_assert (src
->n_var_parts
);
2824 gcc_checking_assert (src
->onepart
== dst
->onepart
);
2826 /* We can combine one-part variables very efficiently, because their
2827 entries are in canonical order. */
2830 location_chain
*nodep
, dnode
, snode
;
2832 gcc_assert (src
->n_var_parts
== 1
2833 && dst
->n_var_parts
== 1);
2835 snode
= src
->var_part
[0].loc_chain
;
2838 restart_onepart_unshared
:
2839 nodep
= &dst
->var_part
[0].loc_chain
;
2845 int r
= dnode
? loc_cmp (dnode
->loc
, snode
->loc
) : 1;
2849 location_chain nnode
;
2851 if (shared_var_p (dst
, set
->vars
))
2853 dstp
= unshare_variable (set
, dstp
, dst
,
2854 VAR_INIT_STATUS_INITIALIZED
);
2856 goto restart_onepart_unshared
;
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
;
2865 nnode
->set_src
= snode
->set_src
;
2866 nnode
->next
= dnode
;
2870 gcc_checking_assert (rtx_equal_p (dnode
->loc
, snode
->loc
));
2873 snode
= snode
->next
;
2875 nodep
= &dnode
->next
;
2882 gcc_checking_assert (!src
->onepart
);
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
++)
2888 if (VAR_PART_OFFSET (src
, i
) == VAR_PART_OFFSET (dst
, j
))
2893 else if (VAR_PART_OFFSET (src
, i
) < VAR_PART_OFFSET (dst
, j
))
2898 k
+= src
->n_var_parts
- i
;
2899 k
+= dst
->n_var_parts
- j
;
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
);
2905 if (dst
->n_var_parts
!= k
&& shared_var_p (dst
, set
->vars
))
2907 dstp
= unshare_variable (set
, dstp
, dst
, VAR_INIT_STATUS_UNKNOWN
);
2911 i
= src
->n_var_parts
- 1;
2912 j
= dst
->n_var_parts
- 1;
2913 dst
->n_var_parts
= k
;
2915 for (k
--; k
>= 0; k
--)
2917 location_chain node
, node2
;
2919 if (i
>= 0 && j
>= 0
2920 && VAR_PART_OFFSET (src
, i
) == VAR_PART_OFFSET (dst
, j
))
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. */
2927 struct variable_union_info
*vui
;
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
))
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
)
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
)))
2943 if (node2
->init
< node
->init
)
2944 node2
->init
= node
->init
;
2950 dstp
= unshare_variable (set
, dstp
, dst
,
2951 VAR_INIT_STATUS_UNKNOWN
);
2952 dst
= (variable
)*dstp
;
2957 for (node
= src
->var_part
[i
].loc_chain
; node
; node
= node
->next
)
2960 for (node
= dst
->var_part
[j
].loc_chain
; node
; node
= node
->next
)
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
);
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
)))
2976 location_chain new_node
;
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
;
2985 new_node
->set_src
= node
->set_src
;
2986 node2
->next
= new_node
;
2993 if (src_l
+ dst_l
> vui_allocated
)
2995 vui_allocated
= MAX (vui_allocated
* 2, src_l
+ dst_l
);
2996 vui_vec
= XRESIZEVEC (struct variable_union_info
, vui_vec
,
3001 /* Fill in the locations from DST. */
3002 for (node
= dst
->var_part
[j
].loc_chain
, jj
= 0; node
;
3003 node
= node
->next
, jj
++)
3006 vui
[jj
].pos_dst
= jj
;
3008 /* Pos plus value larger than a sum of 2 valid positions. */
3009 vui
[jj
].pos
= jj
+ src_l
+ dst_l
;
3012 /* Fill in the locations from SRC. */
3014 for (node
= src
->var_part
[i
].loc_chain
, ii
= 0; node
;
3015 node
= node
->next
, ii
++)
3017 /* Find location from NODE. */
3018 for (jj
= 0; jj
< dst_l
; jj
++)
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
))
3025 vui
[jj
].pos
= jj
+ ii
;
3029 if (jj
>= dst_l
) /* The location has not been found. */
3031 location_chain new_node
;
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
;
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
;
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
)
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
;
3060 vui
[0].lc
->next
= vui
[2].lc
;
3061 vui
[n
- 1].lc
->next
= NULL
;
3064 vui
[0].lc
->next
= NULL
;
3069 dst
->var_part
[k
].loc_chain
= vui
[0].lc
;
3070 if (n
>= 3 && vui
[2].pos
< vui
[1].pos
)
3072 /* Order should be 0, 2, 1, 3... */
3073 vui
[0].lc
->next
= vui
[2].lc
;
3074 vui
[2].lc
->next
= vui
[1].lc
;
3077 vui
[1].lc
->next
= vui
[3].lc
;
3078 vui
[n
- 1].lc
->next
= NULL
;
3081 vui
[1].lc
->next
= NULL
;
3086 /* Order should be 0, 1, 2... */
3088 vui
[n
- 1].lc
->next
= NULL
;
3091 for (; ii
< n
; ii
++)
3092 vui
[ii
- 1].lc
->next
= vui
[ii
].lc
;
3096 qsort (vui
, n
, sizeof (struct variable_union_info
),
3097 variable_union_info_cmp_pos
);
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
;
3106 VAR_PART_OFFSET (dst
, k
) = VAR_PART_OFFSET (dst
, j
);
3111 else if ((i
>= 0 && j
>= 0
3112 && VAR_PART_OFFSET (src
, i
) < VAR_PART_OFFSET (dst
, j
))
3115 dst
->var_part
[k
] = dst
->var_part
[j
];
3118 else if ((i
>= 0 && j
>= 0
3119 && VAR_PART_OFFSET (src
, i
) > VAR_PART_OFFSET (dst
, j
))
3122 location_chain
*nextp
;
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
)
3128 location_chain new_lc
;
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
;
3136 new_lc
->set_src
= node
->set_src
;
3137 new_lc
->loc
= node
->loc
;
3140 nextp
= &new_lc
->next
;
3143 VAR_PART_OFFSET (dst
, k
) = VAR_PART_OFFSET (src
, i
);
3146 dst
->var_part
[k
].cur_loc
= NULL
;
3149 if (flag_var_tracking_uninit
)
3150 for (i
= 0; i
< src
->n_var_parts
&& i
< dst
->n_var_parts
; i
++)
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
))
3157 if (node
->init
> node2
->init
)
3158 node2
->init
= node
->init
;
3162 /* Continue traversing the hash table. */
3166 /* Compute union of dataflow sets SRC and DST and store it to DST. */
3169 dataflow_set_union (dataflow_set
*dst
, dataflow_set
*src
)
3173 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3174 attrs_list_union (&dst
->regs
[i
], src
->regs
[i
]);
3176 if (dst
->vars
== empty_shared_hash
)
3178 shared_hash_destroy (dst
->vars
);
3179 dst
->vars
= shared_hash_copy (src
->vars
);
3183 variable_iterator_type hi
;
3186 FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (src
->vars
),
3188 variable_union (var
, dst
);
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)
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)
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)
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. */
3213 set_dv_changed (decl_or_value dv
, bool newv
)
3215 switch (dv_onepart_p (dv
))
3219 NO_LOC_P (dv_as_value (dv
)) = false;
3220 VALUE_CHANGED (dv_as_value (dv
)) = newv
;
3225 NO_LOC_P (DECL_RTL_KNOWN_SET (dv_as_decl (dv
))) = false;
3226 /* Fall through... */
3229 DECL_CHANGED (dv_as_decl (dv
)) = newv
;
3234 /* Return true if DV needs to have its cur_loc recomputed. */
3237 dv_changed_p (decl_or_value dv
)
3239 return (dv_is_value_p (dv
)
3240 ? VALUE_CHANGED (dv_as_value (dv
))
3241 : DECL_CHANGED (dv_as_decl (dv
)));
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. */
3249 static location_chain
3250 find_loc_in_1pdv (rtx loc
, variable var
, variable_table_type
*vars
)
3252 location_chain node
;
3253 enum rtx_code loc_code
;
3258 gcc_checking_assert (var
->onepart
);
3260 if (!var
->n_var_parts
)
3263 gcc_checking_assert (loc
!= dv_as_opaque (var
->dv
));
3265 loc_code
= GET_CODE (loc
);
3266 for (node
= var
->var_part
[0].loc_chain
; node
; node
= node
->next
)
3271 if (GET_CODE (node
->loc
) != loc_code
)
3273 if (GET_CODE (node
->loc
) != VALUE
)
3276 else if (loc
== node
->loc
)
3278 else if (loc_code
!= VALUE
)
3280 if (rtx_equal_p (loc
, node
->loc
))
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
)))
3291 /* Skip all subsequent VALUEs. */
3292 while (node
->next
&& GET_CODE (node
->next
->loc
) == VALUE
)
3295 gcc_checking_assert (!canon_value_cmp (node
->loc
,
3296 dv_as_value (var
->dv
)));
3297 if (loc
== node
->loc
)
3303 gcc_checking_assert (node
== var
->var_part
[0].loc_chain
);
3304 gcc_checking_assert (!node
->next
);
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
);
3311 /* ??? Gotta look in cselib_val locations too. */
3316 /* Hash table iteration argument passed to variable_merge. */
3319 /* The set in which the merge is to be inserted. */
3321 /* The set that we're iterating in. */
3323 /* The set that may contain the other dv we are to merge with. */
3325 /* Number of onepart dvs in src. */
3326 int src_onepart_cnt
;
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. */
3333 insert_into_intersection (location_chain
*nodep
, rtx loc
,
3334 enum var_init_status status
)
3336 location_chain node
;
3339 for (node
= *nodep
; node
; nodep
= &node
->next
, node
= *nodep
)
3340 if ((r
= loc_cmp (node
->loc
, loc
)) == 0)
3342 node
->init
= MIN (node
->init
, status
);
3348 node
= new location_chain_def
;
3351 node
->set_src
= NULL
;
3352 node
->init
= status
;
3353 node
->next
= *nodep
;
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
3363 intersect_loc_chains (rtx val
, location_chain
*dest
, struct dfset_merge
*dsm
,
3364 location_chain s1node
, variable s2var
)
3366 dataflow_set
*s1set
= dsm
->cur
;
3367 dataflow_set
*s2set
= dsm
->src
;
3368 location_chain found
;
3372 location_chain s2node
;
3374 gcc_checking_assert (s2var
->onepart
);
3376 if (s2var
->n_var_parts
)
3378 s2node
= s2var
->var_part
[0].loc_chain
;
3380 for (; s1node
&& s2node
;
3381 s1node
= s1node
->next
, s2node
= s2node
->next
)
3382 if (s1node
->loc
!= s2node
->loc
)
3384 else if (s1node
->loc
== val
)
3387 insert_into_intersection (dest
, s1node
->loc
,
3388 MIN (s1node
->init
, s2node
->init
));
3392 for (; s1node
; s1node
= s1node
->next
)
3394 if (s1node
->loc
== val
)
3397 if ((found
= find_loc_in_1pdv (s1node
->loc
, s2var
,
3398 shared_hash_htab (s2set
->vars
))))
3400 insert_into_intersection (dest
, s1node
->loc
,
3401 MIN (s1node
->init
, found
->init
));
3405 if (GET_CODE (s1node
->loc
) == VALUE
3406 && !VALUE_RECURSED_INTO (s1node
->loc
))
3408 decl_or_value dv
= dv_from_value (s1node
->loc
);
3409 variable svar
= shared_hash_find (s1set
->vars
, dv
);
3412 if (svar
->n_var_parts
== 1)
3414 VALUE_RECURSED_INTO (s1node
->loc
) = true;
3415 intersect_loc_chains (val
, dest
, dsm
,
3416 svar
->var_part
[0].loc_chain
,
3418 VALUE_RECURSED_INTO (s1node
->loc
) = false;
3423 /* ??? gotta look in cselib_val locations too. */
3425 /* ??? if the location is equivalent to any location in src,
3426 searched recursively
3428 add to dst the values needed to represent the equivalence
3430 telling whether locations S is equivalent to another dv's
3433 for each location D in the list
3435 if S and D satisfy rtx_equal_p, then it is present
3437 else if D is a value, recurse without cycles
3439 else if S and D have the same CODE and MODE
3441 for each operand oS and the corresponding oD
3443 if oS and oD are not equivalent, then S an D are not equivalent
3445 else if they are RTX vectors
3447 if any vector oS element is not equivalent to its respective oD,
3448 then S and D are not equivalent
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. */
3461 loc_cmp (rtx x
, rtx y
)
3464 RTX_CODE code
= GET_CODE (x
);
3474 gcc_assert (GET_MODE (x
) == GET_MODE (y
));
3475 if (REGNO (x
) == REGNO (y
))
3477 else if (REGNO (x
) < REGNO (y
))
3490 gcc_assert (GET_MODE (x
) == GET_MODE (y
));
3491 return loc_cmp (XEXP (x
, 0), XEXP (y
, 0));
3497 if (GET_CODE (x
) == VALUE
)
3499 if (GET_CODE (y
) != VALUE
)
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
))
3511 if (GET_CODE (y
) == VALUE
)
3514 /* Entry value is the least preferable kind of expression. */
3515 if (GET_CODE (x
) == ENTRY_VALUE
)
3517 if (GET_CODE (y
) != ENTRY_VALUE
)
3519 gcc_assert (GET_MODE (x
) == GET_MODE (y
));
3520 return loc_cmp (ENTRY_VALUE_EXP (x
), ENTRY_VALUE_EXP (y
));
3523 if (GET_CODE (y
) == ENTRY_VALUE
)
3526 if (GET_CODE (x
) == GET_CODE (y
))
3527 /* Compare operands below. */;
3528 else if (GET_CODE (x
) < GET_CODE (y
))
3533 gcc_assert (GET_MODE (x
) == GET_MODE (y
));
3535 if (GET_CODE (x
) == DEBUG_EXPR
)
3537 if (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
))
3538 < DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y
)))
3540 gcc_checking_assert (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
))
3541 > DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y
)));
3545 fmt
= GET_RTX_FORMAT (code
);
3546 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
3550 if (XWINT (x
, i
) == XWINT (y
, i
))
3552 else if (XWINT (x
, i
) < XWINT (y
, i
))
3559 if (XINT (x
, i
) == XINT (y
, i
))
3561 else if (XINT (x
, i
) < XINT (y
, i
))
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
))
3576 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3577 if ((r
= loc_cmp (XVECEXP (x
, i
, j
),
3578 XVECEXP (y
, i
, j
))))
3583 if ((r
= loc_cmp (XEXP (x
, i
), XEXP (y
, i
))))
3589 if (XSTR (x
, i
) == XSTR (y
, i
))
3595 if ((r
= strcmp (XSTR (x
, i
), XSTR (y
, i
))) == 0)
3603 /* These are just backpointers, so they don't matter. */
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. */
3616 if (CONST_WIDE_INT_P (x
))
3618 /* Compare the vector length first. */
3619 if (CONST_WIDE_INT_NUNITS (x
) >= CONST_WIDE_INT_NUNITS (y
))
3621 else if (CONST_WIDE_INT_NUNITS (x
) < CONST_WIDE_INT_NUNITS (y
))
3624 /* Compare the vectors elements. */;
3625 for (j
= CONST_WIDE_INT_NUNITS (x
) - 1; j
>= 0 ; j
--)
3627 if (CONST_WIDE_INT_ELT (x
, j
) < CONST_WIDE_INT_ELT (y
, j
))
3629 if (CONST_WIDE_INT_ELT (x
, j
) > CONST_WIDE_INT_ELT (y
, j
))
3638 /* Check the order of entries in one-part variables. */
3641 canonicalize_loc_order_check (variable_def
**slot
,
3642 dataflow_set
*data ATTRIBUTE_UNUSED
)
3644 variable var
= *slot
;
3645 location_chain node
, next
;
3647 #ifdef ENABLE_RTL_CHECKING
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
);
3657 gcc_assert (var
->n_var_parts
== 1);
3658 node
= var
->var_part
[0].loc_chain
;
3661 while ((next
= node
->next
))
3663 gcc_assert (loc_cmp (node
->loc
, next
->loc
) < 0);
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. */
3677 canonicalize_values_mark (variable_def
**slot
, dataflow_set
*set
)
3679 variable var
= *slot
;
3680 decl_or_value dv
= var
->dv
;
3682 location_chain node
;
3684 if (!dv_is_value_p (dv
))
3687 gcc_checking_assert (var
->n_var_parts
== 1);
3689 val
= dv_as_value (dv
);
3691 for (node
= var
->var_part
[0].loc_chain
; node
; node
= node
->next
)
3692 if (GET_CODE (node
->loc
) == VALUE
)
3694 if (canon_value_cmp (node
->loc
, val
))
3695 VALUE_RECURSED_INTO (val
) = true;
3698 decl_or_value odv
= dv_from_value (node
->loc
);
3699 variable_def
**oslot
;
3700 oslot
= shared_hash_find_slot_noinsert (set
->vars
, odv
);
3702 set_slot_part (set
, val
, oslot
, odv
, 0,
3703 node
->init
, NULL_RTX
);
3705 VALUE_RECURSED_INTO (node
->loc
) = true;
3712 /* Remove redundant entries from equivalence lists in onepart
3713 variables, canonicalizing equivalence sets into star shapes. */
3716 canonicalize_values_star (variable_def
**slot
, dataflow_set
*set
)
3718 variable var
= *slot
;
3719 decl_or_value dv
= var
->dv
;
3720 location_chain node
;
3723 variable_def
**cslot
;
3730 gcc_checking_assert (var
->n_var_parts
== 1);
3732 if (dv_is_value_p (dv
))
3734 cval
= dv_as_value (dv
);
3735 if (!VALUE_RECURSED_INTO (cval
))
3737 VALUE_RECURSED_INTO (cval
) = false;
3747 gcc_assert (var
->n_var_parts
== 1);
3749 for (node
= var
->var_part
[0].loc_chain
; node
; node
= node
->next
)
3750 if (GET_CODE (node
->loc
) == VALUE
)
3753 if (VALUE_RECURSED_INTO (node
->loc
))
3755 if (canon_value_cmp (node
->loc
, cval
))
3764 if (!has_marks
|| dv_is_decl_p (dv
))
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
3770 VALUE_RECURSED_INTO (val
) = true;
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
))
3778 VALUE_RECURSED_INTO (cval
) = false;
3779 dv
= dv_from_value (cval
);
3780 slot
= shared_hash_find_slot_noinsert (set
->vars
, dv
);
3783 gcc_assert (dv_is_decl_p (var
->dv
));
3784 /* The canonical value was reset and dropped.
3786 clobber_variable_part (set
, NULL
, var
->dv
, 0, NULL
);
3790 gcc_assert (dv_is_value_p (var
->dv
));
3791 if (var
->n_var_parts
== 0)
3793 gcc_assert (var
->n_var_parts
== 1);
3797 VALUE_RECURSED_INTO (val
) = false;
3802 /* Push values to the canonical one. */
3803 cdv
= dv_from_value (cval
);
3804 cslot
= shared_hash_find_slot_noinsert (set
->vars
, cdv
);
3806 for (node
= var
->var_part
[0].loc_chain
; node
; node
= node
->next
)
3807 if (node
->loc
!= cval
)
3809 cslot
= set_slot_part (set
, node
->loc
, cslot
, cdv
, 0,
3810 node
->init
, NULL_RTX
);
3811 if (GET_CODE (node
->loc
) == VALUE
)
3813 decl_or_value ndv
= dv_from_value (node
->loc
);
3815 set_variable_part (set
, cval
, ndv
, 0, node
->init
, NULL_RTX
,
3818 if (canon_value_cmp (node
->loc
, val
))
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
3827 VALUE_RECURSED_INTO (node
->loc
) = true;
3828 /* Make sure we visit node->loc by ensuring we cval is
3830 VALUE_RECURSED_INTO (cval
) = true;
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
3836 clobber_variable_part (set
, cval
, ndv
, 0, NULL
);
3838 else if (GET_CODE (node
->loc
) == REG
)
3840 attrs list
= set
->regs
[REGNO (node
->loc
)], *listp
;
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. */
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
)))
3858 if (dv_as_opaque (list
->dv
) == dv_as_opaque (dv
))
3861 for (listp
= &list
->next
; (list
= *listp
); listp
= &list
->next
)
3866 if (dv_as_opaque (list
->dv
) == dv_as_opaque (cdv
))
3868 *listp
= list
->next
;
3874 gcc_assert (dv_as_opaque (list
->dv
) != dv_as_opaque (dv
));
3877 else if (dv_as_opaque (list
->dv
) == dv_as_opaque (cdv
))
3879 for (listp
= &list
->next
; (list
= *listp
); listp
= &list
->next
)
3884 if (dv_as_opaque (list
->dv
) == dv_as_opaque (dv
))
3886 *listp
= list
->next
;
3892 gcc_assert (dv_as_opaque (list
->dv
) != dv_as_opaque (cdv
));
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
)))
3913 set_slot_part (set
, val
, cslot
, cdv
, 0,
3914 VAR_INIT_STATUS_INITIALIZED
, NULL_RTX
);
3916 slot
= clobber_slot_part (set
, cval
, slot
, 0, NULL
);
3918 /* Variable may have been unshared. */
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
);
3923 if (VALUE_RECURSED_INTO (cval
))
3924 goto restart_with_cval
;
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. */
3937 canonicalize_vars_star (variable_def
**slot
, dataflow_set
*set
)
3939 variable var
= *slot
;
3940 decl_or_value dv
= var
->dv
;
3941 location_chain node
;
3944 variable_def
**cslot
;
3946 location_chain cnode
;
3948 if (!var
->onepart
|| var
->onepart
== ONEPART_VALUE
)
3951 gcc_assert (var
->n_var_parts
== 1);
3953 node
= var
->var_part
[0].loc_chain
;
3955 if (GET_CODE (node
->loc
) != VALUE
)
3958 gcc_assert (!node
->next
);
3961 /* Push values to the canonical one. */
3962 cdv
= dv_from_value (cval
);
3963 cslot
= shared_hash_find_slot_noinsert (set
->vars
, cdv
);
3967 gcc_assert (cvar
->n_var_parts
== 1);
3969 cnode
= cvar
->var_part
[0].loc_chain
;
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
))
3977 /* CVAL was found to be non-canonical. Change the variable to point
3978 to the canonical VALUE. */
3979 gcc_assert (!cnode
->next
);
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
);
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
3995 variable_merge_over_cur (variable s1var
, struct dfset_merge
*dsm
)
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
;
4004 location_chain node
, *nodep
;
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
);
4013 return variable_union (s1var
, dst
);
4015 gcc_checking_assert (s1var
->n_var_parts
== 1);
4017 dvhash
= dv_htab_hash (dv
);
4018 if (dv_is_value_p (dv
))
4019 val
= dv_as_value (dv
);
4023 s2var
= shared_hash_find_1 (dsm
->src
->vars
, dv
, dvhash
);
4026 dst_can_be_shared
= false;
4030 dsm
->src_onepart_cnt
--;
4031 gcc_assert (s2var
->var_part
[0].loc_chain
4032 && s2var
->onepart
== onepart
4033 && s2var
->n_var_parts
== 1);
4035 dstslot
= shared_hash_find_slot_noinsert_1 (dst
->vars
, dv
, dvhash
);
4039 gcc_assert (dvar
->refcount
== 1
4040 && dvar
->onepart
== onepart
4041 && dvar
->n_var_parts
== 1);
4042 nodep
= &dvar
->var_part
[0].loc_chain
;
4050 if (!dstslot
&& !onepart_variable_different_p (s1var
, s2var
))
4052 dstslot
= shared_hash_find_slot_unshare_1 (&dst
->vars
, dv
,
4054 *dstslot
= dvar
= s2var
;
4059 dst_can_be_shared
= false;
4061 intersect_loc_chains (val
, nodep
, dsm
,
4062 s1var
->var_part
[0].loc_chain
, s2var
);
4068 dvar
= onepart_pool (onepart
).allocate ();
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
;
4077 VAR_LOC_1PAUX (dvar
) = NULL
;
4079 VAR_PART_OFFSET (dvar
, 0) = 0;
4082 = shared_hash_find_slot_unshare_1 (&dst
->vars
, dv
, dvhash
,
4084 gcc_assert (!*dstslot
);
4092 nodep
= &dvar
->var_part
[0].loc_chain
;
4093 while ((node
= *nodep
))
4095 location_chain
*nextp
= &node
->next
;
4097 if (GET_CODE (node
->loc
) == REG
)
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
))
4107 attrs_list_insert (&dst
->regs
[REGNO (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
)
4113 dstslot
= set_slot_part (dst
, dv_as_value (list
->dv
),
4115 node
->init
, NULL_RTX
);
4116 dstslot
= delete_slot_part (dst
, node
->loc
, dstslot
, 0);
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. */
4130 /* Canonicalization puts registers first, so we don't have to
4136 if (dvar
!= *dstslot
)
4138 nodep
= &dvar
->var_part
[0].loc_chain
;
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
)
4148 VALUE_RECURSED_INTO (node
->loc
) = true;
4149 set_variable_part (dst
, val
, dv_from_value (node
->loc
), 0,
4150 node
->init
, NULL
, INSERT
);
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
,
4163 bool has_value
= false, has_other
= false;
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
)
4170 if (GET_CODE (node
->loc
) == VALUE
)
4172 /* If this was marked during register canonicalization,
4173 we know we have to canonicalize values. */
4188 if (has_value
&& has_other
)
4190 for (node
= *nodep
; node
; node
= node
->next
)
4192 if (GET_CODE (node
->loc
) == VALUE
)
4194 decl_or_value dv
= dv_from_value (node
->loc
);
4195 variable_def
**slot
= NULL
;
4197 if (shared_hash_shared (dst
->vars
))
4198 slot
= shared_hash_find_slot_noinsert (dst
->vars
, dv
);
4200 slot
= shared_hash_find_slot_unshare (&dst
->vars
, dv
,
4204 variable var
= onepart_pool (ONEPART_VALUE
).allocate ();
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
;
4216 VALUE_RECURSED_INTO (node
->loc
) = true;
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
,
4230 if (!onepart_variable_different_p (dvar
, s2var
))
4232 variable_htab_free (dvar
);
4233 *dstslot
= dvar
= s2var
;
4236 else if (s2var
!= s1var
&& !onepart_variable_different_p (dvar
, s1var
))
4238 variable_htab_free (dvar
);
4239 *dstslot
= dvar
= s1var
;
4241 dst_can_be_shared
= false;
4244 dst_can_be_shared
= false;
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(). */
4255 variable_merge_over_src (variable s2var
, struct dfset_merge
*dsm
)
4257 dataflow_set
*dst
= dsm
->dst
;
4258 decl_or_value dv
= s2var
->dv
;
4260 if (!s2var
->onepart
)
4262 variable_def
**dstp
= shared_hash_find_slot (dst
->vars
, dv
);
4268 dsm
->src_onepart_cnt
++;
4272 /* Combine dataflow set information from SRC2 into DST, using PDST
4273 to carry over information across passes. */
4276 dataflow_set_merge (dataflow_set
*dst
, dataflow_set
*src2
)
4278 dataflow_set cur
= *dst
;
4279 dataflow_set
*src1
= &cur
;
4280 struct dfset_merge dsm
;
4282 size_t src1_elems
, src2_elems
;
4283 variable_iterator_type hi
;
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
));
4295 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
4296 attrs_list_mpdv_union (&dst
->regs
[i
], src1
->regs
[i
], src2
->regs
[i
]);
4301 dsm
.src_onepart_cnt
= 0;
4303 FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (dsm
.src
->vars
),
4305 variable_merge_over_src (var
, &dsm
);
4306 FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (dsm
.cur
->vars
),
4308 variable_merge_over_cur (var
, &dsm
);
4310 if (dsm
.src_onepart_cnt
)
4311 dst_can_be_shared
= false;
4313 dataflow_set_destroy (src1
);
4316 /* Mark register equivalences. */
4319 dataflow_set_equiv_regs (dataflow_set
*set
)
4324 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
4326 rtx canon
[NUM_MACHINE_MODES
];
4328 /* If the list is empty or one entry, no need to canonicalize
4330 if (set
->regs
[i
] == NULL
|| set
->regs
[i
]->next
== NULL
)
4333 memset (canon
, 0, sizeof (canon
));
4335 for (list
= set
->regs
[i
]; list
; list
= list
->next
)
4336 if (list
->offset
== 0 && dv_is_value_p (list
->dv
))
4338 rtx val
= dv_as_value (list
->dv
);
4339 rtx
*cvalp
= &canon
[(int)GET_MODE (val
)];
4342 if (canon_value_cmp (val
, cval
))
4346 for (list
= set
->regs
[i
]; list
; list
= list
->next
)
4347 if (list
->offset
== 0 && dv_onepart_p (list
->dv
))
4349 rtx cval
= canon
[(int)GET_MODE (list
->loc
)];
4354 if (dv_is_value_p (list
->dv
))
4356 rtx val
= dv_as_value (list
->dv
);
4361 VALUE_RECURSED_INTO (val
) = true;
4362 set_variable_part (set
, val
, dv_from_value (cval
), 0,
4363 VAR_INIT_STATUS_INITIALIZED
,
4367 VALUE_RECURSED_INTO (cval
) = true;
4368 set_variable_part (set
, cval
, list
->dv
, 0,
4369 VAR_INIT_STATUS_INITIALIZED
, NULL
, NO_INSERT
);
4372 for (listp
= &set
->regs
[i
]; (list
= *listp
);
4373 listp
= list
? &list
->next
: listp
)
4374 if (list
->offset
== 0 && dv_onepart_p (list
->dv
))
4376 rtx cval
= canon
[(int)GET_MODE (list
->loc
)];
4377 variable_def
**slot
;
4382 if (dv_is_value_p (list
->dv
))
4384 rtx val
= dv_as_value (list
->dv
);
4385 if (!VALUE_RECURSED_INTO (val
))
4389 slot
= shared_hash_find_slot_noinsert (set
->vars
, list
->dv
);
4390 canonicalize_values_star (slot
, set
);
4397 /* Remove any redundant values in the location list of VAR, which must
4398 be unshared and 1-part. */
4401 remove_duplicate_values (variable var
)
4403 location_chain node
, *nodep
;
4405 gcc_assert (var
->onepart
);
4406 gcc_assert (var
->n_var_parts
== 1);
4407 gcc_assert (var
->refcount
== 1);
4409 for (nodep
= &var
->var_part
[0].loc_chain
; (node
= *nodep
); )
4411 if (GET_CODE (node
->loc
) == VALUE
)
4413 if (VALUE_RECURSED_INTO (node
->loc
))
4415 /* Remove duplicate value node. */
4416 *nodep
= node
->next
;
4421 VALUE_RECURSED_INTO (node
->loc
) = true;
4423 nodep
= &node
->next
;
4426 for (node
= var
->var_part
[0].loc_chain
; node
; node
= node
->next
)
4427 if (GET_CODE (node
->loc
) == VALUE
)
4429 gcc_assert (VALUE_RECURSED_INTO (node
->loc
));
4430 VALUE_RECURSED_INTO (node
->loc
) = false;
4435 /* Hash table iteration argument passed to variable_post_merge. */
4436 struct dfset_post_merge
4438 /* The new input set for the current block. */
4440 /* Pointer to the permanent input set for the current block, or
4442 dataflow_set
**permp
;
4445 /* Create values for incoming expressions associated with one-part
4446 variables that don't have value numbers for them. */
4449 variable_post_merge_new_vals (variable_def
**slot
, dfset_post_merge
*dfpm
)
4451 dataflow_set
*set
= dfpm
->set
;
4452 variable var
= *slot
;
4453 location_chain node
;
4455 if (!var
->onepart
|| !var
->n_var_parts
)
4458 gcc_assert (var
->n_var_parts
== 1);
4460 if (dv_is_decl_p (var
->dv
))
4462 bool check_dupes
= false;
4465 for (node
= var
->var_part
[0].loc_chain
; node
; node
= node
->next
)
4467 if (GET_CODE (node
->loc
) == VALUE
)
4468 gcc_assert (!VALUE_RECURSED_INTO (node
->loc
));
4469 else if (GET_CODE (node
->loc
) == REG
)
4471 attrs att
, *attp
, *curp
= NULL
;
4473 if (var
->refcount
!= 1)
4475 slot
= unshare_variable (set
, slot
, var
,
4476 VAR_INIT_STATUS_INITIALIZED
);
4481 for (attp
= &set
->regs
[REGNO (node
->loc
)]; (att
= *attp
);
4483 if (att
->offset
== 0
4484 && GET_MODE (att
->loc
) == GET_MODE (node
->loc
))
4486 if (dv_is_value_p (att
->dv
))
4488 rtx cval
= dv_as_value (att
->dv
);
4493 else if (dv_as_opaque (att
->dv
) == dv_as_opaque (var
->dv
))
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
))
4506 curp
= &(*curp
)->next
;
4517 *dfpm
->permp
= XNEW (dataflow_set
);
4518 dataflow_set_init (*dfpm
->permp
);
4521 for (att
= (*dfpm
->permp
)->regs
[REGNO (node
->loc
)];
4522 att
; att
= att
->next
)
4523 if (GET_MODE (att
->loc
) == GET_MODE (node
->loc
))
4525 gcc_assert (att
->offset
== 0
4526 && dv_is_value_p (att
->dv
));
4527 val_reset (set
, att
->dv
);
4534 cval
= dv_as_value (cdv
);
4538 /* Create a unique value to hold this register,
4539 that ought to be found and reused in
4540 subsequent rounds. */
4542 gcc_assert (!cselib_lookup (node
->loc
,
4543 GET_MODE (node
->loc
), 0,
4545 v
= cselib_lookup (node
->loc
, GET_MODE (node
->loc
), 1,
4547 cselib_preserve_value (v
);
4548 cselib_invalidate_rtx (node
->loc
);
4550 cdv
= dv_from_value (cval
);
4553 "Created new value %u:%u for reg %i\n",
4554 v
->uid
, v
->hash
, REGNO (node
->loc
));
4557 var_reg_decl_set (*dfpm
->permp
, node
->loc
,
4558 VAR_INIT_STATUS_INITIALIZED
,
4559 cdv
, 0, NULL
, INSERT
);
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. */
4575 remove_duplicate_values (var
);
4581 /* Reset values in the permanent set that are not associated with the
4582 chosen expression. */
4585 variable_post_merge_perm_vals (variable_def
**pslot
, dfset_post_merge
*dfpm
)
4587 dataflow_set
*set
= dfpm
->set
;
4588 variable pvar
= *pslot
, var
;
4589 location_chain pnode
;
4593 gcc_assert (dv_is_value_p (pvar
->dv
)
4594 && pvar
->n_var_parts
== 1);
4595 pnode
= pvar
->var_part
[0].loc_chain
;
4598 && REG_P (pnode
->loc
));
4602 var
= shared_hash_find (set
->vars
, dv
);
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
)))
4613 val_reset (set
, dv
);
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
))
4622 /* If there is a value associated with this register already, create
4624 if (att
&& dv_as_value (att
->dv
) != dv_as_value (dv
))
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
,
4633 attrs_list_insert (&set
->regs
[REGNO (pnode
->loc
)],
4635 variable_union (pvar
, set
);
4641 /* Just checking stuff and registering register attributes for
4645 dataflow_post_merge_adjust (dataflow_set
*set
, dataflow_set
**permp
)
4647 struct dfset_post_merge dfpm
;
4652 shared_hash_htab (set
->vars
)
4653 ->traverse
<dfset_post_merge
*, variable_post_merge_new_vals
> (&dfpm
);
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
);
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. */
4667 static location_chain
4668 find_mem_expr_in_1pdv (tree expr
, rtx val
, variable_table_type
*vars
)
4670 location_chain node
;
4673 location_chain where
= NULL
;
4678 gcc_assert (GET_CODE (val
) == VALUE
4679 && !VALUE_RECURSED_INTO (val
));
4681 dv
= dv_from_value (val
);
4682 var
= vars
->find_with_hash (dv
, dv_htab_hash (dv
));
4687 gcc_assert (var
->onepart
);
4689 if (!var
->n_var_parts
)
4692 VALUE_RECURSED_INTO (val
) = true;
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)
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
)))
4707 VALUE_RECURSED_INTO (val
) = false;
4712 /* Return TRUE if the value of MEM may vary across a call. */
4715 mem_dies_at_call (rtx mem
)
4717 tree expr
= MEM_EXPR (mem
);
4723 decl
= get_base_address (expr
);
4731 return (may_be_aliased (decl
)
4732 || (!TREE_READONLY (decl
) && is_global_var (decl
)));
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. */
4740 dataflow_set_preserve_mem_locs (variable_def
**slot
, dataflow_set
*set
)
4742 variable var
= *slot
;
4744 if (var
->onepart
== ONEPART_VDECL
|| var
->onepart
== ONEPART_DEXPR
)
4746 tree decl
= dv_as_decl (var
->dv
);
4747 location_chain loc
, *locp
;
4748 bool changed
= false;
4750 if (!var
->n_var_parts
)
4753 gcc_assert (var
->n_var_parts
== 1);
4755 if (shared_var_p (var
, set
->vars
))
4757 for (loc
= var
->var_part
[0].loc_chain
; loc
; loc
= loc
->next
)
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
))
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
)))
4775 slot
= unshare_variable (set
, slot
, var
, VAR_INIT_STATUS_UNKNOWN
);
4777 gcc_assert (var
->n_var_parts
== 1);
4780 for (locp
= &var
->var_part
[0].loc_chain
, loc
= *locp
;
4783 rtx old_loc
= loc
->loc
;
4784 if (GET_CODE (old_loc
) == VALUE
)
4786 location_chain mem_node
4787 = find_mem_expr_in_1pdv (decl
, loc
->loc
,
4788 shared_hash_htab (set
->vars
));
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? */
4798 loc
->loc
= mem_node
->loc
;
4799 loc
->set_src
= mem_node
->set_src
;
4800 loc
->init
= MIN (loc
->init
, mem_node
->init
);
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
))
4809 if (old_loc
!= loc
->loc
&& emit_notes
)
4811 if (old_loc
== var
->var_part
[0].cur_loc
)
4814 var
->var_part
[0].cur_loc
= NULL
;
4823 if (old_loc
== var
->var_part
[0].cur_loc
)
4826 var
->var_part
[0].cur_loc
= NULL
;
4833 if (!var
->var_part
[0].loc_chain
)
4839 variable_was_changed (var
, set
);
4845 /* Remove all MEMs from the location list of a hash table entry for a
4849 dataflow_set_remove_mem_locs (variable_def
**slot
, dataflow_set
*set
)
4851 variable var
= *slot
;
4853 if (var
->onepart
== ONEPART_VALUE
)
4855 location_chain loc
, *locp
;
4856 bool changed
= false;
4859 gcc_assert (var
->n_var_parts
== 1);
4861 if (shared_var_p (var
, set
->vars
))
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
))
4871 slot
= unshare_variable (set
, slot
, var
, VAR_INIT_STATUS_UNKNOWN
);
4873 gcc_assert (var
->n_var_parts
== 1);
4876 if (VAR_LOC_1PAUX (var
))
4877 cur_loc
= VAR_LOC_FROM (var
);
4879 cur_loc
= var
->var_part
[0].cur_loc
;
4881 for (locp
= &var
->var_part
[0].loc_chain
, loc
= *locp
;
4884 if (GET_CODE (loc
->loc
) != MEM
4885 || !mem_dies_at_call (loc
->loc
))
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
)
4898 var
->var_part
[0].cur_loc
= NULL
;
4899 if (VAR_LOC_1PAUX (var
))
4900 VAR_LOC_FROM (var
) = NULL
;
4905 if (!var
->var_part
[0].loc_chain
)
4911 variable_was_changed (var
, set
);
4917 /* Remove all variable-location information about call-clobbered
4918 registers, as well as associations between MEMs and VALUEs. */
4921 dataflow_set_clear_at_call (dataflow_set
*set
)
4924 hard_reg_set_iterator hrsi
;
4926 EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call
, 0, r
, hrsi
)
4927 var_regno_delete (set
, r
);
4929 if (MAY_HAVE_DEBUG_INSNS
)
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
;
4942 variable_part_different_p (variable_part
*vp1
, variable_part
*vp2
)
4944 location_chain lc1
, lc2
;
4946 for (lc1
= vp1
->loc_chain
; lc1
; lc1
= lc1
->next
)
4948 for (lc2
= vp2
->loc_chain
; lc2
; lc2
= lc2
->next
)
4950 if (REG_P (lc1
->loc
) && REG_P (lc2
->loc
))
4952 if (REGNO (lc1
->loc
) == REGNO (lc2
->loc
))
4955 if (rtx_equal_p (lc1
->loc
, lc2
->loc
))
4964 /* Return true if one-part variables VAR1 and VAR2 are different.
4965 They must be in canonical order. */
4968 onepart_variable_different_p (variable var1
, variable var2
)
4970 location_chain lc1
, lc2
;
4975 gcc_assert (var1
->n_var_parts
== 1
4976 && var2
->n_var_parts
== 1);
4978 lc1
= var1
->var_part
[0].loc_chain
;
4979 lc2
= var2
->var_part
[0].loc_chain
;
4981 gcc_assert (lc1
&& lc2
);
4985 if (loc_cmp (lc1
->loc
, lc2
->loc
))
4994 /* Return true if variables VAR1 and VAR2 are different. */
4997 variable_different_p (variable var1
, variable var2
)
5004 if (var1
->onepart
!= var2
->onepart
)
5007 if (var1
->n_var_parts
!= var2
->n_var_parts
)
5010 if (var1
->onepart
&& var1
->n_var_parts
)
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
);
5018 for (i
= 0; i
< var1
->n_var_parts
; i
++)
5020 if (VAR_PART_OFFSET (var1
, i
) != VAR_PART_OFFSET (var2
, i
))
5022 if (variable_part_different_p (&var1
->var_part
[i
], &var2
->var_part
[i
]))
5024 if (variable_part_different_p (&var2
->var_part
[i
], &var1
->var_part
[i
]))
5030 /* Return true if dataflow sets OLD_SET and NEW_SET differ. */
5033 dataflow_set_different (dataflow_set
*old_set
, dataflow_set
*new_set
)
5035 variable_iterator_type hi
;
5038 if (old_set
->vars
== new_set
->vars
)
5041 if (shared_hash_htab (old_set
->vars
)->elements ()
5042 != shared_hash_htab (new_set
->vars
)->elements ())
5045 FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (old_set
->vars
),
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
));
5052 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5054 fprintf (dump_file
, "dataflow difference found: removal of:\n");
5060 if (variable_different_p (var1
, var2
))
5062 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5064 fprintf (dump_file
, "dataflow difference found: "
5065 "old and new follow:\n");
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. */
5079 /* Free the contents of dataflow set SET. */
5082 dataflow_set_destroy (dataflow_set
*set
)
5086 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
5087 attrs_list_clear (&set
->regs
[i
]);
5089 shared_hash_destroy (set
->vars
);
5093 /* Return true if RTL X contains a SYMBOL_REF. */
5096 contains_symbol_ref (rtx x
)
5105 code
= GET_CODE (x
);
5106 if (code
== SYMBOL_REF
)
5109 fmt
= GET_RTX_FORMAT (code
);
5110 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
5114 if (contains_symbol_ref (XEXP (x
, i
)))
5117 else if (fmt
[i
] == 'E')
5120 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
5121 if (contains_symbol_ref (XVECEXP (x
, i
, j
)))
5129 /* Shall EXPR be tracked? */
5132 track_expr_p (tree expr
, bool need_rtl
)
5137 if (TREE_CODE (expr
) == DEBUG_EXPR_DECL
)
5138 return DECL_RTL_SET_P (expr
);
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
)
5144 /* It also must have a name... */
5145 if (!DECL_NAME (expr
) && need_rtl
)
5148 /* ... and a RTL assigned to it. */
5149 decl_rtl
= DECL_RTL_IF_SET (expr
);
5150 if (!decl_rtl
&& need_rtl
)
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
5157 if (TREE_CODE (realdecl
) == VAR_DECL
&& DECL_HAS_DEBUG_EXPR_P (realdecl
))
5159 realdecl
= DECL_DEBUG_EXPR (realdecl
);
5160 if (!DECL_P (realdecl
))
5162 if (handled_component_p (realdecl
)
5163 || (TREE_CODE (realdecl
) == MEM_REF
5164 && TREE_CODE (TREE_OPERAND (realdecl
, 0)) == ADDR_EXPR
))
5166 HOST_WIDE_INT bitsize
, bitpos
, maxsize
;
5168 = get_ref_base_and_extent (realdecl
, &bitpos
, &bitsize
,
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
)
5179 || bitpos
+ bitsize
> 256
5180 || bitsize
!= maxsize
)
5190 /* Do not track EXPR if REALDECL it should be ignored for debugging
5192 if (DECL_IGNORED_P (realdecl
))
5195 /* Do not track global variables until we are able to emit correct location
5197 if (TREE_STATIC (realdecl
))
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.
5205 extern char **_dl_argv_internal __attribute__ ((alias ("_dl_argv")));
5208 if (decl_rtl
&& MEM_P (decl_rtl
)
5209 && contains_symbol_ref (XEXP (decl_rtl
, 0)))
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
))
5216 /* Do not track structures and arrays. */
5217 if (GET_MODE (decl_rtl
) == BLKmode
5218 || AGGREGATE_TYPE_P (TREE_TYPE (realdecl
)))
5220 if (MEM_SIZE_KNOWN_P (decl_rtl
)
5221 && MEM_SIZE (decl_rtl
) > MAX_VAR_PARTS
)
5225 DECL_CHANGED (expr
) = 0;
5226 DECL_CHANGED (realdecl
) = 0;
5230 /* Determine whether a given LOC refers to the same variable part as
5234 same_variable_part_p (rtx loc
, tree expr
, HOST_WIDE_INT offset
)
5237 HOST_WIDE_INT offset2
;
5239 if (! DECL_P (expr
))
5244 expr2
= REG_EXPR (loc
);
5245 offset2
= REG_OFFSET (loc
);
5247 else if (MEM_P (loc
))
5249 expr2
= MEM_EXPR (loc
);
5250 offset2
= INT_MEM_OFFSET (loc
);
5255 if (! expr2
|| ! DECL_P (expr2
))
5258 expr
= var_debug_decl (expr
);
5259 expr2
= var_debug_decl (expr2
);
5261 return (expr
== expr2
&& offset
== offset2
);
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.
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). */
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
)
5280 if (expr
== NULL
|| !track_expr_p (expr
, true))
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
)))
5288 machine_mode pseudo_mode
;
5290 pseudo_mode
= PSEUDO_REGNO_MODE (ORIGINAL_REGNO (loc
));
5291 if (GET_MODE_SIZE (mode
) > GET_MODE_SIZE (pseudo_mode
))
5293 offset
+= byte_lowpart_offset (pseudo_mode
, mode
);
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
5305 if ((GET_MODE_SIZE (mode
) > GET_MODE_SIZE (DECL_MODE (expr
))
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)
5311 mode
= DECL_MODE (expr
);
5315 if (offset
< 0 || offset
>= MAX_VAR_PARTS
)
5321 *offset_out
= offset
;
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. */
5330 var_lowpart (machine_mode mode
, rtx loc
)
5332 unsigned int offset
, reg_offset
, regno
;
5334 if (GET_MODE (loc
) == mode
)
5337 if (!REG_P (loc
) && !MEM_P (loc
))
5340 offset
= byte_lowpart_offset (mode
, GET_MODE (loc
));
5343 return adjust_address_nv (loc
, mode
, offset
);
5345 reg_offset
= subreg_lowpart_offset (mode
, GET_MODE (loc
));
5346 regno
= REGNO (loc
) + subreg_regno_offset (REGNO (loc
), GET_MODE (loc
),
5348 return gen_rtx_REG_offset (loc
, mode
, regno
, offset
);
5351 /* Carry information about uses and stores while walking rtx. */
5353 struct count_use_info
5355 /* The insn where the RTX is. */
5358 /* The basic block where insn is. */
5361 /* The array of n_sets sets in the insn, as determined by cselib. */
5362 struct cselib_set
*sets
;
5365 /* True if we're counting stores, false otherwise. */
5369 /* Find a VALUE corresponding to X. */
5371 static inline cselib_val
*
5372 find_use_val (rtx x
, machine_mode mode
, struct count_use_info
*cui
)
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
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
))
5392 for (i
= 0; i
< cui
->n_sets
; i
++)
5393 if (cui
->sets
[i
].dest
== x
)
5394 return cui
->sets
[i
].src_elt
;
5397 return cselib_lookup (x
, mode
, 0, VOIDmode
);
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. */
5408 replace_expr_with_values (rtx loc
)
5410 if (REG_P (loc
) || GET_CODE (loc
) == ENTRY_VALUE
)
5412 else if (MEM_P (loc
))
5414 cselib_val
*addr
= cselib_lookup (XEXP (loc
, 0),
5415 get_address_mode (loc
), 0,
5418 return replace_equiv_address_nv (loc
, addr
->val_rtx
);
5423 return cselib_subst_to_values (loc
, VOIDmode
);
5426 /* Return true if X contains a DEBUG_EXPR. */
5429 rtx_debug_expr_p (const_rtx x
)
5431 subrtx_iterator::array_type array
;
5432 FOR_EACH_SUBRTX (iter
, array
, x
, ALL
)
5433 if (GET_CODE (*iter
) == DEBUG_EXPR
)
5438 /* Determine what kind of micro operation to choose for a USE. Return
5439 MO_CLOBBER if no micro operation is to be generated. */
5441 static enum micro_operation_type
5442 use_type (rtx loc
, struct count_use_info
*cui
, machine_mode
*modep
)
5446 if (cui
&& cui
->sets
)
5448 if (GET_CODE (loc
) == VAR_LOCATION
)
5450 if (track_expr_p (PAT_VAR_LOCATION_DECL (loc
), false))
5452 rtx ploc
= PAT_VAR_LOCATION_LOC (loc
);
5453 if (! VAR_LOC_UNKNOWN_P (ploc
))
5455 cselib_val
*val
= cselib_lookup (ploc
, GET_MODE (loc
), 1,
5458 /* ??? flag_float_store and volatile mems are never
5459 given values, but we could in theory use them for
5461 gcc_assert (val
|| 1);
5469 if (REG_P (loc
) || MEM_P (loc
))
5472 *modep
= GET_MODE (loc
);
5476 || (find_use_val (loc
, GET_MODE (loc
), cui
)
5477 && cselib_lookup (XEXP (loc
, 0),
5478 get_address_mode (loc
), 0,
5484 cselib_val
*val
= find_use_val (loc
, GET_MODE (loc
), cui
);
5486 if (val
&& !cselib_preserved_value_p (val
))
5494 gcc_assert (REGNO (loc
) < FIRST_PSEUDO_REGISTER
);
5496 if (loc
== cfa_base_rtx
)
5498 expr
= REG_EXPR (loc
);
5501 return MO_USE_NO_VAR
;
5502 else if (target_for_debug_bind (var_debug_decl (expr
)))
5504 else if (track_loc_p (loc
, expr
, REG_OFFSET (loc
),
5505 false, modep
, NULL
))
5508 return MO_USE_NO_VAR
;
5510 else if (MEM_P (loc
))
5512 expr
= MEM_EXPR (loc
);
5516 else if (target_for_debug_bind (var_debug_decl (expr
)))
5518 else if (track_loc_p (loc
, expr
, INT_MEM_OFFSET (loc
),
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
5524 && (!MAY_HAVE_DEBUG_INSNS
5525 || !rtx_debug_expr_p (XEXP (loc
, 0))))
5534 /* Log to OUT information about micro-operation MOPT involving X in
5538 log_op_type (rtx x
, basic_block bb
, rtx_insn
*insn
,
5539 enum micro_operation_type mopt
, FILE *out
)
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);
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
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)
5566 /* All preserved VALUEs. */
5567 static vec
<rtx
> preserved_values
;
5569 /* Ensure VAL is preserved and remember it in a vector for vt_emit_notes. */
5572 preserve_value (cselib_val
*val
)
5574 cselib_preserve_value (val
);
5575 preserved_values
.safe_push (val
->val_rtx
);
5578 /* Helper function for MO_VAL_LOC handling. Return non-zero if
5579 any rtxes not suitable for CONST use not replaced by VALUEs
5583 non_suitable_const (const_rtx x
)
5585 subrtx_iterator::array_type array
;
5586 FOR_EACH_SUBRTX (iter
, array
, x
, ALL
)
5588 const_rtx x
= *iter
;
5589 switch (GET_CODE (x
))
5600 if (!MEM_READONLY_P (x
))
5610 /* Add uses (register and memory references) LOC which will be tracked
5611 to VTI (bb)->mos. */
5614 add_uses (rtx loc
, struct count_use_info
*cui
)
5616 machine_mode mode
= VOIDmode
;
5617 enum micro_operation_type type
= use_type (loc
, cui
, &mode
);
5619 if (type
!= MO_CLOBBER
)
5621 basic_block bb
= cui
->bb
;
5625 mo
.u
.loc
= type
== MO_USE
? var_lowpart (mode
, loc
) : loc
;
5626 mo
.insn
= cui
->insn
;
5628 if (type
== MO_VAL_LOC
)
5631 rtx vloc
= PAT_VAR_LOCATION_LOC (oloc
);
5634 gcc_assert (cui
->sets
);
5637 && !REG_P (XEXP (vloc
, 0))
5638 && !MEM_P (XEXP (vloc
, 0)))
5641 machine_mode address_mode
= get_address_mode (mloc
);
5643 = cselib_lookup (XEXP (mloc
, 0), address_mode
, 0,
5646 if (val
&& !cselib_preserved_value_p (val
))
5647 preserve_value (val
);
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
)))
5657 enum micro_operation_type type2
;
5659 bool resolvable
= REG_P (vloc
) || MEM_P (vloc
);
5662 nloc
= replace_expr_with_values (vloc
);
5666 oloc
= shallow_copy_rtx (oloc
);
5667 PAT_VAR_LOCATION_LOC (oloc
) = nloc
;
5670 oloc
= gen_rtx_CONCAT (mode
, val
->val_rtx
, oloc
);
5672 type2
= use_type (vloc
, 0, &mode2
);
5674 gcc_assert (type2
== MO_USE
|| type2
== MO_USE_NO_VAR
5675 || type2
== MO_CLOBBER
);
5677 if (type2
== MO_CLOBBER
5678 && !cselib_preserved_value_p (val
))
5680 VAL_NEEDS_RESOLUTION (oloc
) = resolvable
;
5681 preserve_value (val
);
5684 else if (!VAR_LOC_UNKNOWN_P (vloc
))
5686 oloc
= shallow_copy_rtx (oloc
);
5687 PAT_VAR_LOCATION_LOC (oloc
) = gen_rtx_UNKNOWN_VAR_LOC ();
5692 else if (type
== MO_VAL_USE
)
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
;
5699 gcc_assert (cui
->sets
);
5702 && !REG_P (XEXP (oloc
, 0))
5703 && !MEM_P (XEXP (oloc
, 0)))
5706 machine_mode address_mode
= get_address_mode (mloc
);
5708 = cselib_lookup (XEXP (mloc
, 0), address_mode
, 0,
5711 if (val
&& !cselib_preserved_value_p (val
))
5712 preserve_value (val
);
5715 type2
= use_type (loc
, 0, &mode2
);
5717 gcc_assert (type2
== MO_USE
|| type2
== MO_USE_NO_VAR
5718 || type2
== MO_CLOBBER
);
5720 if (type2
== MO_USE
)
5721 vloc
= var_lowpart (mode2
, loc
);
5725 /* The loc of a MO_VAL_USE may have two forms:
5727 (concat val src): val is at src, a value-based
5730 (concat (concat val use) src): same as above, with use as
5731 the MO_USE tracked value, if it differs from src.
5735 gcc_checking_assert (REG_P (loc
) || MEM_P (loc
));
5736 nloc
= replace_expr_with_values (loc
);
5741 oloc
= gen_rtx_CONCAT (mode2
, val
->val_rtx
, vloc
);
5743 oloc
= val
->val_rtx
;
5745 mo
.u
.loc
= gen_rtx_CONCAT (mode
, oloc
, nloc
);
5747 if (type2
== MO_USE
)
5748 VAL_HOLDS_TRACK_EXPR (mo
.u
.loc
) = 1;
5749 if (!cselib_preserved_value_p (val
))
5751 VAL_NEEDS_RESOLUTION (mo
.u
.loc
) = 1;
5752 preserve_value (val
);
5756 gcc_assert (type
== MO_USE
|| type
== MO_USE_NO_VAR
);
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
);
5764 /* Helper function for finding all uses of REG/MEM in X in insn INSN. */
5767 add_uses_1 (rtx
*x
, void *cui
)
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
);
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))
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. */
5792 reverse_op (rtx val
, const_rtx expr
, rtx_insn
*insn
)
5796 struct elt_loc_list
*l
;
5800 if (GET_CODE (expr
) != SET
)
5803 if (!REG_P (SET_DEST (expr
)) || GET_MODE (val
) != GET_MODE (SET_DEST (expr
)))
5806 src
= SET_SRC (expr
);
5807 switch (GET_CODE (src
))
5814 if (!REG_P (XEXP (src
, 0)))
5819 if (!REG_P (XEXP (src
, 0)) && !MEM_P (XEXP (src
, 0)))
5826 if (!SCALAR_INT_MODE_P (GET_MODE (src
)) || XEXP (src
, 0) == cfa_base_rtx
)
5829 v
= cselib_lookup (XEXP (src
, 0), GET_MODE (XEXP (src
, 0)), 0, VOIDmode
);
5830 if (!v
|| !cselib_preserved_value_p (v
))
5833 /* Use canonical V to avoid creating multiple redundant expressions
5834 for different VALUES equivalent to V. */
5835 v
= canonical_cselib_val (v
);
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)))
5844 /* Avoid creating too large locs lists. */
5845 else if (count
== PARAM_VALUE (PARAM_MAX_VARTRACK_REVERSE_OP_SIZE
))
5848 switch (GET_CODE (src
))
5852 if (GET_MODE (v
->val_rtx
) != GET_MODE (val
))
5854 ret
= gen_rtx_fmt_e (GET_CODE (src
), GET_MODE (val
), val
);
5858 ret
= gen_lowpart_SUBREG (GET_MODE (v
->val_rtx
), val
);
5870 if (GET_MODE (v
->val_rtx
) != GET_MODE (val
))
5872 arg
= XEXP (src
, 1);
5873 if (!CONST_INT_P (arg
) && GET_CODE (arg
) != SYMBOL_REF
)
5875 arg
= cselib_expand_value_rtx (arg
, scratch_regs
, 5);
5876 if (arg
== NULL_RTX
)
5878 if (!CONST_INT_P (arg
) && GET_CODE (arg
) != SYMBOL_REF
)
5881 ret
= simplify_gen_binary (code
, GET_MODE (val
), val
, arg
);
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
);
5892 cselib_add_permanent_equiv (v
, ret
, insn
);
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. */
5900 add_stores (rtx loc
, const_rtx expr
, void *cuip
)
5902 machine_mode mode
= VOIDmode
, mode2
;
5903 struct count_use_info
*cui
= (struct count_use_info
*)cuip
;
5904 basic_block bb
= cui
->bb
;
5906 rtx oloc
= loc
, nloc
, src
= NULL
;
5907 enum micro_operation_type type
= use_type (loc
, cui
, &mode
);
5908 bool track_p
= false;
5910 bool resolve
, preserve
;
5912 if (type
== MO_CLOBBER
)
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
)
5924 mo
.type
= MO_CLOBBER
;
5926 if (GET_CODE (expr
) == SET
5927 && SET_DEST (expr
) == loc
5928 && !unsuitable_loc (SET_SRC (expr
))
5929 && find_use_val (loc
, mode
, cui
))
5931 gcc_checking_assert (type
== MO_VAL_SET
);
5932 mo
.u
.loc
= gen_rtx_SET (loc
, SET_SRC (expr
));
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
);
5950 rtx xexpr
= gen_rtx_SET (loc
, src
);
5951 if (same_variable_part_p (src
, REG_EXPR (loc
), REG_OFFSET (loc
)))
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. */
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)
5975 mo
.insn
= cui
->insn
;
5977 else if (MEM_P (loc
)
5978 && ((track_p
= use_type (loc
, NULL
, &mode2
) == MO_USE
)
5981 if (MEM_P (loc
) && type
== MO_VAL_SET
5982 && !REG_P (XEXP (loc
, 0))
5983 && !MEM_P (XEXP (loc
, 0)))
5986 machine_mode address_mode
= get_address_mode (mloc
);
5987 cselib_val
*val
= cselib_lookup (XEXP (mloc
, 0),
5991 if (val
&& !cselib_preserved_value_p (val
))
5992 preserve_value (val
);
5995 if (GET_CODE (expr
) == CLOBBER
|| !track_p
)
5997 mo
.type
= MO_CLOBBER
;
5998 mo
.u
.loc
= track_p
? var_lowpart (mode2
, loc
) : loc
;
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
);
6015 rtx xexpr
= gen_rtx_SET (loc
, src
);
6016 if (same_variable_part_p (SET_SRC (xexpr
),
6018 INT_MEM_OFFSET (loc
)))
6025 mo
.insn
= cui
->insn
;
6030 if (type
!= MO_VAL_SET
)
6031 goto log_and_return
;
6033 v
= find_use_val (oloc
, mode
, cui
);
6036 goto log_and_return
;
6038 resolve
= preserve
= !cselib_preserved_value_p (v
);
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. */
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)))
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. */
6060 goto log_and_return
;
6063 if (loc
== stack_pointer_rtx
6064 && hard_frame_pointer_adjustment
!= -1
6066 cselib_set_value_sp_based (v
);
6068 nloc
= replace_expr_with_values (oloc
);
6072 if (GET_CODE (PATTERN (cui
->insn
)) == COND_EXEC
)
6074 cselib_val
*oval
= cselib_lookup (oloc
, GET_MODE (oloc
), 0, VOIDmode
);
6078 gcc_assert (REG_P (oloc
) || MEM_P (oloc
));
6080 if (oval
&& !cselib_preserved_value_p (oval
))
6082 micro_operation moa
;
6084 preserve_value (oval
);
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
;
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
);
6099 else if (resolve
&& GET_CODE (mo
.u
.loc
) == SET
)
6101 if (REG_P (SET_SRC (expr
)) || MEM_P (SET_SRC (expr
)))
6102 nloc
= replace_expr_with_values (SET_SRC (expr
));
6106 /* Avoid the mode mismatch between oexpr and expr. */
6107 if (!nloc
&& mode
!= mode2
)
6109 nloc
= SET_SRC (expr
);
6110 gcc_assert (oloc
== SET_DEST (expr
));
6113 if (nloc
&& nloc
!= SET_SRC (mo
.u
.loc
))
6114 oloc
= gen_rtx_SET (oloc
, nloc
);
6117 if (oloc
== SET_DEST (mo
.u
.loc
))
6118 /* No point in duplicating. */
6120 if (!REG_P (SET_SRC (mo
.u
.loc
)))
6126 if (GET_CODE (mo
.u
.loc
) == SET
6127 && oloc
== SET_DEST (mo
.u
.loc
))
6128 /* No point in duplicating. */
6134 loc
= gen_rtx_CONCAT (mode
, v
->val_rtx
, oloc
);
6136 if (mo
.u
.loc
!= oloc
)
6137 loc
= gen_rtx_CONCAT (GET_MODE (mo
.u
.loc
), loc
, mo
.u
.loc
);
6139 /* The loc of a MO_VAL_SET may have various forms:
6141 (concat val dst): dst now holds val
6143 (concat val (set dst src)): dst now holds val, copied from src
6145 (concat (concat val dstv) dst): dst now holds val; dstv is dst
6146 after replacing mems and non-top-level regs with values.
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.
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.
6159 if (GET_CODE (PATTERN (cui
->insn
)) != COND_EXEC
)
6160 reverse_op (v
->val_rtx
, expr
, cui
->insn
);
6165 VAL_HOLDS_TRACK_EXPR (loc
) = 1;
6168 VAL_NEEDS_RESOLUTION (loc
) = resolve
;
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;
6176 mo
.type
= MO_VAL_SET
;
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
);
6184 /* Arguments to the call. */
6185 static rtx call_arguments
;
6187 /* Compute call_arguments. */
6190 prepare_call_arguments (basic_block bb
, rtx_insn
*insn
)
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
;
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
);
6205 if (GET_CODE (XEXP (XEXP (call
, 0), 0)) == SYMBOL_REF
)
6207 rtx symbol
= XEXP (XEXP (call
, 0), 0);
6208 if (SYMBOL_REF_DECL (symbol
))
6209 fndecl
= SYMBOL_REF_DECL (symbol
);
6211 if (fndecl
== NULL_TREE
)
6212 fndecl
= MEM_EXPR (XEXP (call
, 0));
6214 && TREE_CODE (TREE_TYPE (fndecl
)) != FUNCTION_TYPE
6215 && TREE_CODE (TREE_TYPE (fndecl
)) != METHOD_TYPE
)
6217 if (fndecl
&& TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
6218 type
= TREE_TYPE (fndecl
);
6219 if (fndecl
&& TREE_CODE (fndecl
) != FUNCTION_DECL
)
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);
6228 for (t
= TYPE_ARG_TYPES (type
); t
&& t
!= void_list_node
;
6230 if (TREE_CODE (TREE_VALUE (t
)) == REFERENCE_TYPE
6231 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (t
))))
6233 if ((t
== NULL
|| t
== void_list_node
) && obj_type_ref
== NULL_TREE
)
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)
6243 tree struct_addr
= build_pointer_type (TREE_TYPE (type
));
6244 machine_mode mode
= TYPE_MODE (struct_addr
);
6246 INIT_CUMULATIVE_ARGS (args_so_far_v
, type
, NULL_RTX
, fndecl
,
6248 reg
= targetm
.calls
.function_arg (args_so_far
, mode
,
6250 targetm
.calls
.function_arg_advance (args_so_far
, mode
,
6252 if (reg
== NULL_RTX
)
6254 for (; link
; link
= XEXP (link
, 1))
6255 if (GET_CODE (XEXP (link
, 0)) == USE
6256 && MEM_P (XEXP (XEXP (link
, 0), 0)))
6258 link
= XEXP (link
, 1);
6265 INIT_CUMULATIVE_ARGS (args_so_far_v
, type
, NULL_RTX
, fndecl
,
6267 if (obj_type_ref
&& TYPE_ARG_TYPES (type
) != void_list_node
)
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
)
6278 for (; link
; link
= XEXP (link
, 1))
6279 if (GET_CODE (XEXP (link
, 0)) == USE
6280 && MEM_P (XEXP (XEXP (link
, 0), 0)))
6282 this_arg
= XEXP (XEXP (link
, 0), 0);
6290 t
= type
? TYPE_ARG_TYPES (type
) : NULL_TREE
;
6292 for (link
= CALL_INSN_FUNCTION_USAGE (insn
); link
; link
= XEXP (link
, 1))
6293 if (GET_CODE (XEXP (link
, 0)) == USE
)
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. */;
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
)
6314 machine_mode mode
= GET_MODE (x
);
6316 while ((mode
= GET_MODE_WIDER_MODE (mode
)) != VOIDmode
6317 && GET_MODE_BITSIZE (mode
) <= BITS_PER_WORD
)
6319 rtx reg
= simplify_subreg (mode
, x
, GET_MODE (x
), 0);
6321 if (reg
== NULL_RTX
|| !REG_P (reg
))
6323 val
= cselib_lookup (reg
, mode
, 0, VOIDmode
);
6324 if (val
&& cselib_preserved_value_p (val
))
6326 item
= val
->val_rtx
;
6337 if (!frame_pointer_needed
)
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
;
6344 mem
= simplify_replace_fn_rtx (mem
, NULL_RTX
, adjust_mems
,
6346 gcc_assert (amd
.side_effects
== NULL_RTX
);
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
)
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
)
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
,
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
);
6376 = gen_rtx_EXPR_LIST (VOIDmode
, item
, call_arguments
);
6378 if (t
&& t
!= void_list_node
)
6380 tree argtype
= TREE_VALUE (t
);
6381 machine_mode mode
= TYPE_MODE (argtype
);
6383 if (pass_by_reference (&args_so_far_v
, mode
, argtype
, true))
6385 argtype
= build_pointer_type (argtype
);
6386 mode
= TYPE_MODE (argtype
);
6388 reg
= targetm
.calls
.function_arg (args_so_far
, mode
,
6390 if (TREE_CODE (argtype
) == REFERENCE_TYPE
6391 && INTEGRAL_TYPE_P (TREE_TYPE (argtype
))
6394 && GET_MODE (reg
) == mode
6395 && (GET_MODE_CLASS (mode
) == MODE_INT
6396 || GET_MODE_CLASS (mode
) == MODE_PARTIAL_INT
)
6398 && REGNO (x
) == REGNO (reg
)
6399 && GET_MODE (x
) == mode
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
))
6408 item
= gen_rtx_CONCAT (indmode
, mem
, val
->val_rtx
);
6409 call_arguments
= gen_rtx_EXPR_LIST (VOIDmode
, item
,
6414 struct elt_loc_list
*l
;
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
)))
6430 initial
= DECL_INITIAL (SYMBOL_REF_DECL (l
->loc
));
6431 if (tree_fits_shwi_p (initial
))
6433 item
= GEN_INT (tree_to_shwi (initial
));
6434 item
= gen_rtx_CONCAT (indmode
, mem
, item
);
6436 = gen_rtx_EXPR_LIST (VOIDmode
, item
,
6443 targetm
.calls
.function_arg_advance (args_so_far
, mode
,
6449 /* Add debug arguments. */
6451 && TREE_CODE (fndecl
) == FUNCTION_DECL
6452 && DECL_HAS_DEBUG_ARGS_P (fndecl
))
6454 vec
<tree
, va_gc
> **debug_args
= decl_debug_args_lookup (fndecl
);
6459 for (ix
= 0; vec_safe_iterate (*debug_args
, ix
, ¶m
); ix
+= 2)
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
,
6472 /* Reverse call_arguments chain. */
6474 for (cur
= call_arguments
; cur
; cur
= next
)
6476 next
= XEXP (cur
, 1);
6477 XEXP (cur
, 1) = prev
;
6480 call_arguments
= prev
;
6482 x
= get_call_rtx_from (insn
);
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
))
6490 x
= gen_rtx_CONCAT (GET_MODE (x
) == VOIDmode
? Pmode
: GET_MODE (x
),
6493 = gen_rtx_EXPR_LIST (VOIDmode
, x
, call_arguments
);
6497 cselib_val
*val
= cselib_lookup (x
, GET_MODE (x
), 0, VOIDmode
);
6498 if (val
&& cselib_preserved_value_p (val
))
6500 x
= gen_rtx_CONCAT (GET_MODE (x
), pc_rtx
, val
->val_rtx
);
6502 = gen_rtx_EXPR_LIST (VOIDmode
, x
, call_arguments
);
6509 = TYPE_MODE (TREE_TYPE (OBJ_TYPE_REF_EXPR (obj_type_ref
)));
6510 rtx clobbered
= gen_rtx_MEM (mode
, this_arg
);
6512 = tree_to_shwi (OBJ_TYPE_REF_TOKEN (obj_type_ref
));
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
);
6519 = gen_rtx_EXPR_LIST (VOIDmode
, x
, call_arguments
);
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). */
6531 add_with_sets (rtx_insn
*insn
, struct cselib_set
*sets
, int n_sets
)
6533 basic_block bb
= BLOCK_FOR_INSN (insn
);
6535 struct count_use_info cui
;
6536 micro_operation
*mos
;
6538 cselib_hook_called
= true;
6543 cui
.n_sets
= n_sets
;
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 ();
6551 /* Order the MO_USEs to be before MO_USE_NO_VARs and MO_VAL_USE, and
6555 while (n1
< n2
&& mos
[n1
].type
== MO_USE
)
6557 while (n1
< n2
&& mos
[n2
].type
!= MO_USE
)
6560 std::swap (mos
[n1
], mos
[n2
]);
6563 n2
= VTI (bb
)->mos
.length () - 1;
6566 while (n1
< n2
&& mos
[n1
].type
!= MO_VAL_LOC
)
6568 while (n1
< n2
&& mos
[n2
].type
== MO_VAL_LOC
)
6571 std::swap (mos
[n1
], mos
[n2
]);
6580 mo
.u
.loc
= call_arguments
;
6581 call_arguments
= NULL_RTX
;
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
);
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. */
6593 note_stores (PATTERN (insn
), add_stores
, &cui
);
6594 n2
= VTI (bb
)->mos
.length () - 1;
6595 mos
= VTI (bb
)->mos
.address ();
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. */
6602 while (n1
< n2
&& mos
[n1
].type
== MO_VAL_USE
)
6604 while (n1
< n2
&& mos
[n2
].type
!= MO_VAL_USE
)
6607 std::swap (mos
[n1
], mos
[n2
]);
6610 n2
= VTI (bb
)->mos
.length () - 1;
6613 while (n1
< n2
&& mos
[n1
].type
== MO_CLOBBER
)
6615 while (n1
< n2
&& mos
[n2
].type
!= MO_CLOBBER
)
6618 std::swap (mos
[n1
], mos
[n2
]);
6622 static enum var_init_status
6623 find_src_status (dataflow_set
*in
, rtx src
)
6625 tree decl
= NULL_TREE
;
6626 enum var_init_status status
= VAR_INIT_STATUS_UNINITIALIZED
;
6628 if (! flag_var_tracking_uninit
)
6629 status
= VAR_INIT_STATUS_INITIALIZED
;
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
));
6637 status
= get_init_value (in
, src
, dv_from_decl (decl
));
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. */
6647 find_src_set_src (dataflow_set
*set
, rtx src
)
6649 tree decl
= NULL_TREE
; /* The variable being copied around. */
6650 rtx set_src
= NULL_RTX
; /* The value for "decl" stored in "src". */
6652 location_chain nextp
;
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
));
6663 decl_or_value dv
= dv_from_decl (decl
);
6665 var
= shared_hash_find (set
->vars
, dv
);
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
))
6674 set_src
= nextp
->set_src
;
6684 /* Compute the changes of variable locations in the basic block BB. */
6687 compute_bb_dataflow (basic_block bb
)
6690 micro_operation
*mo
;
6692 dataflow_set old_out
;
6693 dataflow_set
*in
= &VTI (bb
)->in
;
6694 dataflow_set
*out
= &VTI (bb
)->out
;
6696 dataflow_set_init (&old_out
);
6697 dataflow_set_copy (&old_out
, out
);
6698 dataflow_set_copy (out
, in
);
6700 if (MAY_HAVE_DEBUG_INSNS
)
6701 local_get_addr_cache
= new hash_map
<rtx
, rtx
>;
6703 FOR_EACH_VEC_ELT (VTI (bb
)->mos
, i
, mo
)
6705 rtx_insn
*insn
= mo
->insn
;
6710 dataflow_set_clear_at_call (out
);
6715 rtx loc
= mo
->u
.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
);
6726 rtx loc
= mo
->u
.loc
;
6730 if (GET_CODE (loc
) == CONCAT
)
6732 val
= XEXP (loc
, 0);
6733 vloc
= XEXP (loc
, 1);
6741 var
= PAT_VAR_LOCATION_DECL (vloc
);
6743 clobber_variable_part (out
, NULL_RTX
,
6744 dv_from_decl (var
), 0, NULL_RTX
);
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
,
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
,
6763 rtx loc
= mo
->u
.loc
;
6764 rtx val
, vloc
, uloc
;
6766 vloc
= uloc
= XEXP (loc
, 1);
6767 val
= XEXP (loc
, 0);
6769 if (GET_CODE (val
) == CONCAT
)
6771 uloc
= XEXP (val
, 1);
6772 val
= XEXP (val
, 0);
6775 if (VAL_NEEDS_RESOLUTION (loc
))
6776 val_resolve (out
, val
, vloc
, insn
);
6778 val_store (out
, val
, uloc
, insn
, false);
6780 if (VAL_HOLDS_TRACK_EXPR (loc
))
6782 if (GET_CODE (uloc
) == REG
)
6783 var_reg_set (out
, uloc
, VAR_INIT_STATUS_UNINITIALIZED
,
6785 else if (GET_CODE (uloc
) == MEM
)
6786 var_mem_set (out
, uloc
, VAR_INIT_STATUS_UNINITIALIZED
,
6794 rtx loc
= mo
->u
.loc
;
6795 rtx val
, vloc
, uloc
;
6799 uloc
= XEXP (vloc
, 1);
6800 val
= XEXP (vloc
, 0);
6803 if (GET_CODE (uloc
) == SET
)
6805 dstv
= SET_DEST (uloc
);
6806 srcv
= SET_SRC (uloc
);
6814 if (GET_CODE (val
) == CONCAT
)
6816 dstv
= vloc
= XEXP (val
, 1);
6817 val
= XEXP (val
, 0);
6820 if (GET_CODE (vloc
) == SET
)
6822 srcv
= SET_SRC (vloc
);
6824 gcc_assert (val
!= srcv
);
6825 gcc_assert (vloc
== uloc
|| VAL_NEEDS_RESOLUTION (loc
));
6827 dstv
= vloc
= SET_DEST (vloc
);
6829 if (VAL_NEEDS_RESOLUTION (loc
))
6830 val_resolve (out
, val
, srcv
, insn
);
6832 else if (VAL_NEEDS_RESOLUTION (loc
))
6834 gcc_assert (GET_CODE (uloc
) == SET
6835 && GET_CODE (SET_SRC (uloc
)) == REG
);
6836 val_resolve (out
, val
, SET_SRC (uloc
), insn
);
6839 if (VAL_HOLDS_TRACK_EXPR (loc
))
6841 if (VAL_EXPR_IS_CLOBBERED (loc
))
6844 var_reg_delete (out
, uloc
, true);
6845 else if (MEM_P (uloc
))
6847 gcc_assert (MEM_P (dstv
));
6848 gcc_assert (MEM_ATTRS (dstv
) == MEM_ATTRS (uloc
));
6849 var_mem_delete (out
, dstv
, true);
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
;
6858 if (GET_CODE (uloc
) == SET
)
6860 src
= SET_SRC (uloc
);
6861 dst
= SET_DEST (uloc
);
6866 if (flag_var_tracking_uninit
)
6868 status
= find_src_status (in
, src
);
6870 if (status
== VAR_INIT_STATUS_UNKNOWN
)
6871 status
= find_src_status (out
, src
);
6874 src
= find_src_set_src (in
, src
);
6878 var_reg_delete_and_set (out
, dst
, !copied_p
,
6880 else if (MEM_P (dst
))
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
,
6889 else if (REG_P (uloc
))
6890 var_regno_delete (out
, REGNO (uloc
));
6891 else if (MEM_P (uloc
))
6893 gcc_checking_assert (GET_CODE (vloc
) == MEM
);
6894 gcc_checking_assert (dstv
== vloc
);
6896 clobber_overlapping_mems (out
, vloc
);
6899 val_store (out
, val
, dstv
, insn
, true);
6905 rtx loc
= mo
->u
.loc
;
6908 if (GET_CODE (loc
) == SET
)
6910 set_src
= SET_SRC (loc
);
6911 loc
= SET_DEST (loc
);
6915 var_reg_delete_and_set (out
, loc
, true, VAR_INIT_STATUS_INITIALIZED
,
6917 else if (MEM_P (loc
))
6918 var_mem_delete_and_set (out
, loc
, true, VAR_INIT_STATUS_INITIALIZED
,
6925 rtx loc
= mo
->u
.loc
;
6926 enum var_init_status src_status
;
6929 if (GET_CODE (loc
) == SET
)
6931 set_src
= SET_SRC (loc
);
6932 loc
= SET_DEST (loc
);
6935 if (! flag_var_tracking_uninit
)
6936 src_status
= VAR_INIT_STATUS_INITIALIZED
;
6939 src_status
= find_src_status (in
, set_src
);
6941 if (src_status
== VAR_INIT_STATUS_UNKNOWN
)
6942 src_status
= find_src_status (out
, set_src
);
6945 set_src
= find_src_set_src (in
, set_src
);
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
);
6956 rtx loc
= mo
->u
.loc
;
6959 var_reg_delete (out
, loc
, false);
6960 else if (MEM_P (loc
))
6961 var_mem_delete (out
, loc
, false);
6967 rtx loc
= mo
->u
.loc
;
6970 var_reg_delete (out
, loc
, true);
6971 else if (MEM_P (loc
))
6972 var_mem_delete (out
, loc
, true);
6977 out
->stack_adjust
+= mo
->u
.adjust
;
6982 if (MAY_HAVE_DEBUG_INSNS
)
6984 delete local_get_addr_cache
;
6985 local_get_addr_cache
= NULL
;
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
);
6993 shared_hash_htab (out
->vars
)
6994 ->traverse
<dataflow_set
*, canonicalize_loc_order_check
> (out
);
6997 changed
= dataflow_set_different (&old_out
, out
);
6998 dataflow_set_destroy (&old_out
);
7002 /* Find the locations of variables in the whole function. */
7005 vt_find_locations (void)
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
;
7016 int htabmax
= PARAM_VALUE (PARAM_MAX_VARTRACK_SIZE
);
7017 bool success
= true;
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
;
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
);
7034 FOR_EACH_BB_FN (bb
, cfun
)
7035 pending
->insert (bb_order
[bb
->index
], bb
);
7036 bitmap_ones (in_pending
);
7038 while (success
&& !pending
->empty ())
7040 std::swap (worklist
, pending
);
7041 std::swap (in_worklist
, in_pending
);
7043 bitmap_clear (visited
);
7045 while (!worklist
->empty ())
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
))
7054 int oldinsz
, oldoutsz
;
7056 bitmap_set_bit (visited
, bb
->index
);
7058 if (VTI (bb
)->in
.vars
)
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 ();
7065 = shared_hash_htab (VTI (bb
)->out
.vars
)->elements ();
7068 oldinsz
= oldoutsz
= 0;
7070 if (MAY_HAVE_DEBUG_INSNS
)
7072 dataflow_set
*in
= &VTI (bb
)->in
, *first_out
= NULL
;
7073 bool first
= true, adjust
= false;
7075 /* Calculate the IN set as the intersection of
7076 predecessor OUT sets. */
7078 dataflow_set_clear (in
);
7079 dst_can_be_shared
= true;
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
]);
7087 dataflow_set_copy (in
, &VTI (e
->src
)->out
);
7088 first_out
= &VTI (e
->src
)->out
;
7093 dataflow_set_merge (in
, &VTI (e
->src
)->out
);
7099 dataflow_post_merge_adjust (in
, &VTI (bb
)->permp
);
7101 /* Merge and merge_adjust should keep entries in
7103 shared_hash_htab (in
->vars
)
7104 ->traverse
<dataflow_set
*,
7105 canonicalize_loc_order_check
> (in
);
7107 if (dst_can_be_shared
)
7109 shared_hash_destroy (in
->vars
);
7110 in
->vars
= shared_hash_copy (first_out
->vars
);
7114 VTI (bb
)->flooded
= true;
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
);
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 ();
7128 if (htabmax
&& htabsz
> htabmax
)
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");
7135 inform (DECL_SOURCE_LOCATION (cfun
->decl
),
7136 "variable tracking size limit exceeded");
7143 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
7145 if (e
->dest
== EXIT_BLOCK_PTR_FOR_FN (cfun
))
7148 if (bitmap_bit_p (visited
, e
->dest
->index
))
7150 if (!bitmap_bit_p (in_pending
, e
->dest
->index
))
7152 /* Send E->DEST to next round. */
7153 bitmap_set_bit (in_pending
, e
->dest
->index
);
7154 pending
->insert (bb_order
[e
->dest
->index
],
7158 else if (!bitmap_bit_p (in_worklist
, e
->dest
->index
))
7160 /* Add E->DEST to current round. */
7161 bitmap_set_bit (in_worklist
, e
->dest
->index
);
7162 worklist
->insert (bb_order
[e
->dest
->index
],
7170 "BB %i: in %i (was %i), out %i (was %i), rem %i + %i, tsz %i\n",
7172 (int)shared_hash_htab (VTI (bb
)->in
.vars
)->size (),
7174 (int)shared_hash_htab (VTI (bb
)->out
.vars
)->size (),
7176 (int)worklist
->nodes (), (int)pending
->nodes (),
7179 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
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
);
7190 if (success
&& MAY_HAVE_DEBUG_INSNS
)
7191 FOR_EACH_BB_FN (bb
, cfun
)
7192 gcc_assert (VTI (bb
)->flooded
);
7197 sbitmap_free (visited
);
7198 sbitmap_free (in_worklist
);
7199 sbitmap_free (in_pending
);
7201 timevar_pop (TV_VAR_TRACKING_DATAFLOW
);
7205 /* Print the content of the LIST to dump file. */
7208 dump_attrs_list (attrs list
)
7210 for (; list
; list
= list
->next
)
7212 if (dv_is_decl_p (list
->dv
))
7213 print_mem_expr (dump_file
, dv_as_decl (list
->dv
));
7215 print_rtl_single (dump_file
, dv_as_value (list
->dv
));
7216 fprintf (dump_file
, "+" HOST_WIDE_INT_PRINT_DEC
, list
->offset
);
7218 fprintf (dump_file
, "\n");
7221 /* Print the information about variable *SLOT to dump file. */
7224 dump_var_tracking_slot (variable_def
**slot
, void *data ATTRIBUTE_UNUSED
)
7226 variable var
= *slot
;
7230 /* Continue traversing the hash table. */
7234 /* Print the information about variable VAR to dump file. */
7237 dump_var (variable var
)
7240 location_chain node
;
7242 if (dv_is_decl_p (var
->dv
))
7244 const_tree decl
= dv_as_decl (var
->dv
);
7246 if (DECL_NAME (decl
))
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
));
7253 else if (TREE_CODE (decl
) == DEBUG_EXPR_DECL
)
7254 fprintf (dump_file
, " name: D#%u", DEBUG_TEMP_UID (decl
));
7256 fprintf (dump_file
, " name: D.%u", DECL_UID (decl
));
7257 fprintf (dump_file
, "\n");
7261 fputc (' ', dump_file
);
7262 print_rtl_single (dump_file
, dv_as_value (var
->dv
));
7265 for (i
= 0; i
< var
->n_var_parts
; i
++)
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
)
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
);
7279 /* Print the information about variables from hash table VARS to dump file. */
7282 dump_vars (variable_table_type
*vars
)
7284 if (vars
->elements () > 0)
7286 fprintf (dump_file
, "Variables:\n");
7287 vars
->traverse
<void *, dump_var_tracking_slot
> (NULL
);
7291 /* Print the dataflow set SET to dump file. */
7294 dump_dataflow_set (dataflow_set
*set
)
7298 fprintf (dump_file
, "Stack adjustment: " HOST_WIDE_INT_PRINT_DEC
"\n",
7300 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
7304 fprintf (dump_file
, "Reg %d:", i
);
7305 dump_attrs_list (set
->regs
[i
]);
7308 dump_vars (shared_hash_htab (set
->vars
));
7309 fprintf (dump_file
, "\n");
7312 /* Print the IN and OUT sets for each basic block to dump file. */
7315 dump_dataflow_sets (void)
7319 FOR_EACH_BB_FN (bb
, cfun
)
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
);
7329 /* Return the variable for DV in dropped_values, inserting one if
7330 requested with INSERT. */
7332 static inline variable
7333 variable_from_dropped (decl_or_value dv
, enum insert_option insert
)
7335 variable_def
**slot
;
7337 onepart_enum_t onepart
;
7339 slot
= dropped_values
->find_slot_with_hash (dv
, dv_htab_hash (dv
), insert
);
7347 gcc_checking_assert (insert
== INSERT
);
7349 onepart
= dv_onepart_p (dv
);
7351 gcc_checking_assert (onepart
== ONEPART_VALUE
|| onepart
== ONEPART_DEXPR
);
7353 empty_var
= onepart_pool (onepart
).allocate ();
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);
7369 /* Recover the one-part aux from dropped_values. */
7371 static struct onepart_aux
*
7372 recover_dropped_1paux (variable var
)
7376 gcc_checking_assert (var
->onepart
);
7378 if (VAR_LOC_1PAUX (var
))
7379 return VAR_LOC_1PAUX (var
);
7381 if (var
->onepart
== ONEPART_VDECL
)
7384 dvar
= variable_from_dropped (var
->dv
, NO_INSERT
);
7389 VAR_LOC_1PAUX (var
) = VAR_LOC_1PAUX (dvar
);
7390 VAR_LOC_1PAUX (dvar
) = NULL
;
7392 return VAR_LOC_1PAUX (var
);
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. */
7399 variable_was_changed (variable var
, dataflow_set
*set
)
7401 hashval_t hash
= dv_htab_hash (var
->dv
);
7405 variable_def
**slot
;
7407 /* Remember this decl or VALUE has been added to changed_variables. */
7408 set_dv_changed (var
->dv
, true);
7410 slot
= changed_variables
->find_slot_with_hash (var
->dv
, hash
, INSERT
);
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
)
7419 /* Restore the auxiliary info from an empty variable
7420 previously created for changed_variables, so it is
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
;
7426 variable_htab_free (*slot
);
7429 if (set
&& var
->n_var_parts
== 0)
7431 onepart_enum_t onepart
= var
->onepart
;
7432 variable empty_var
= NULL
;
7433 variable_def
**dslot
= NULL
;
7435 if (onepart
== ONEPART_VALUE
|| onepart
== ONEPART_DEXPR
)
7437 dslot
= dropped_values
->find_slot_with_hash (var
->dv
,
7438 dv_htab_hash (var
->dv
),
7444 gcc_checking_assert (!empty_var
->in_changed_variables
);
7445 if (!VAR_LOC_1PAUX (var
))
7447 VAR_LOC_1PAUX (var
) = VAR_LOC_1PAUX (empty_var
);
7448 VAR_LOC_1PAUX (empty_var
) = NULL
;
7451 gcc_checking_assert (!VAR_LOC_1PAUX (empty_var
));
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
;
7464 empty_var
->refcount
++;
7469 empty_var
->refcount
++;
7470 empty_var
->in_changed_variables
= true;
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
;
7483 if (var
->onepart
&& !VAR_LOC_1PAUX (var
))
7484 recover_dropped_1paux (var
);
7486 var
->in_changed_variables
= true;
7493 if (var
->n_var_parts
== 0)
7495 variable_def
**slot
;
7498 slot
= shared_hash_find_slot_noinsert (set
->vars
, var
->dv
);
7501 if (shared_hash_shared (set
->vars
))
7502 slot
= shared_hash_find_slot_unshare (&set
->vars
, var
->dv
,
7504 shared_hash_htab (set
->vars
)->clear_slot (slot
);
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. */
7516 find_variable_location_part (variable var
, HOST_WIDE_INT offset
,
7517 int *insertion_point
)
7526 if (insertion_point
)
7527 *insertion_point
= 0;
7529 return var
->n_var_parts
- 1;
7532 /* Find the location part. */
7534 high
= var
->n_var_parts
;
7537 pos
= (low
+ high
) / 2;
7538 if (VAR_PART_OFFSET (var
, pos
) < offset
)
7545 if (insertion_point
)
7546 *insertion_point
= pos
;
7548 if (pos
< var
->n_var_parts
&& VAR_PART_OFFSET (var
, pos
) == offset
)
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
)
7560 location_chain node
, next
;
7561 location_chain
*nextp
;
7563 onepart_enum_t onepart
;
7568 onepart
= var
->onepart
;
7570 onepart
= dv_onepart_p (dv
);
7572 gcc_checking_assert (offset
== 0 || !onepart
);
7573 gcc_checking_assert (loc
!= dv_as_opaque (dv
));
7575 if (! flag_var_tracking_uninit
)
7576 initialized
= VAR_INIT_STATUS_INITIALIZED
;
7580 /* Create new variable information. */
7581 var
= onepart_pool (onepart
).allocate ();
7584 var
->n_var_parts
= 1;
7585 var
->onepart
= onepart
;
7586 var
->in_changed_variables
= false;
7588 VAR_LOC_1PAUX (var
) = NULL
;
7590 VAR_PART_OFFSET (var
, 0) = offset
;
7591 var
->var_part
[0].loc_chain
= NULL
;
7592 var
->var_part
[0].cur_loc
= NULL
;
7595 nextp
= &var
->var_part
[0].loc_chain
;
7601 gcc_assert (dv_as_opaque (var
->dv
) == dv_as_opaque (dv
));
7605 if (GET_CODE (loc
) == VALUE
)
7607 for (nextp
= &var
->var_part
[0].loc_chain
; (node
= *nextp
);
7608 nextp
= &node
->next
)
7609 if (GET_CODE (node
->loc
) == VALUE
)
7611 if (node
->loc
== loc
)
7616 if (canon_value_cmp (node
->loc
, loc
))
7624 else if (REG_P (node
->loc
) || MEM_P (node
->loc
))
7632 else if (REG_P (loc
))
7634 for (nextp
= &var
->var_part
[0].loc_chain
; (node
= *nextp
);
7635 nextp
= &node
->next
)
7636 if (REG_P (node
->loc
))
7638 if (REGNO (node
->loc
) < REGNO (loc
))
7642 if (REGNO (node
->loc
) == REGNO (loc
))
7655 else if (MEM_P (loc
))
7657 for (nextp
= &var
->var_part
[0].loc_chain
; (node
= *nextp
);
7658 nextp
= &node
->next
)
7659 if (REG_P (node
->loc
))
7661 else if (MEM_P (node
->loc
))
7663 if ((r
= loc_cmp (XEXP (node
->loc
, 0), XEXP (loc
, 0))) >= 0)
7675 for (nextp
= &var
->var_part
[0].loc_chain
; (node
= *nextp
);
7676 nextp
= &node
->next
)
7677 if ((r
= loc_cmp (node
->loc
, loc
)) >= 0)
7685 if (shared_var_p (var
, set
->vars
))
7687 slot
= unshare_variable (set
, slot
, var
, initialized
);
7689 for (nextp
= &var
->var_part
[0].loc_chain
; c
;
7690 nextp
= &(*nextp
)->next
)
7692 gcc_assert ((!node
&& !*nextp
) || node
->loc
== (*nextp
)->loc
);
7699 gcc_assert (dv_as_decl (var
->dv
) == dv_as_decl (dv
));
7701 pos
= find_variable_location_part (var
, offset
, &inspos
);
7705 node
= var
->var_part
[pos
].loc_chain
;
7708 && ((REG_P (node
->loc
) && REG_P (loc
)
7709 && REGNO (node
->loc
) == REGNO (loc
))
7710 || rtx_equal_p (node
->loc
, loc
)))
7712 /* LOC is in the beginning of the chain so we have nothing
7714 if (node
->init
< initialized
)
7715 node
->init
= initialized
;
7716 if (set_src
!= NULL
)
7717 node
->set_src
= set_src
;
7723 /* We have to make a copy of a shared variable. */
7724 if (shared_var_p (var
, set
->vars
))
7726 slot
= unshare_variable (set
, slot
, var
, initialized
);
7733 /* We have not found the location part, new one will be created. */
7735 /* We have to make a copy of the shared variable. */
7736 if (shared_var_p (var
, set
->vars
))
7738 slot
= unshare_variable (set
, slot
, var
, initialized
);
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
));
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];
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
;
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
)
7764 if ((REG_P (node
->loc
) && REG_P (loc
)
7765 && REGNO (node
->loc
) == REGNO (loc
))
7766 || rtx_equal_p (node
->loc
, loc
))
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
;
7781 nextp
= &node
->next
;
7784 nextp
= &var
->var_part
[pos
].loc_chain
;
7787 /* Add the location to the beginning. */
7788 node
= new location_chain_def
;
7790 node
->init
= initialized
;
7791 node
->set_src
= set_src
;
7792 node
->next
= *nextp
;
7795 /* If no location was emitted do so. */
7796 if (var
->var_part
[pos
].cur_loc
== NULL
)
7797 variable_was_changed (var
, set
);
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. */
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
)
7814 variable_def
**slot
;
7816 if (iopt
== NO_INSERT
)
7817 slot
= shared_hash_find_slot_noinsert (set
->vars
, dv
);
7820 slot
= shared_hash_find_slot (set
->vars
, dv
);
7822 slot
= shared_hash_find_slot_unshare (&set
->vars
, dv
, iopt
);
7824 set_slot_part (set
, loc
, slot
, dv
, offset
, initialized
, set_src
);
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. */
7832 static variable_def
**
7833 clobber_slot_part (dataflow_set
*set
, rtx loc
, variable_def
**slot
,
7834 HOST_WIDE_INT offset
, rtx set_src
)
7836 variable var
= *slot
;
7837 int pos
= find_variable_location_part (var
, offset
, NULL
);
7841 location_chain node
, next
;
7843 /* Remove the register locations from the dataflow set. */
7844 next
= var
->var_part
[pos
].loc_chain
;
7845 for (node
= next
; node
; node
= next
)
7848 if (node
->loc
!= loc
7849 && (!flag_var_tracking_uninit
7852 || !rtx_equal_p (set_src
, node
->set_src
)))
7854 if (REG_P (node
->loc
))
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
7863 anextp
= &set
->regs
[REGNO (node
->loc
)];
7864 for (anode
= *anextp
; anode
; anode
= anext
)
7866 anext
= anode
->next
;
7867 if (dv_as_opaque (anode
->dv
) == dv_as_opaque (var
->dv
)
7868 && anode
->offset
== offset
)
7874 anextp
= &anode
->next
;
7878 slot
= delete_slot_part (set
, node
->loc
, slot
, offset
);
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. */
7892 clobber_variable_part (dataflow_set
*set
, rtx loc
, decl_or_value dv
,
7893 HOST_WIDE_INT offset
, rtx set_src
)
7895 variable_def
**slot
;
7897 if (!dv_as_opaque (dv
)
7898 || (!dv_is_value_p (dv
) && ! DECL_P (dv_as_decl (dv
))))
7901 slot
= shared_hash_find_slot_noinsert (set
->vars
, dv
);
7905 clobber_slot_part (set
, loc
, slot
, offset
, set_src
);
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. */
7912 static variable_def
**
7913 delete_slot_part (dataflow_set
*set
, rtx loc
, variable_def
**slot
,
7914 HOST_WIDE_INT offset
)
7916 variable var
= *slot
;
7917 int pos
= find_variable_location_part (var
, offset
, NULL
);
7921 location_chain node
, next
;
7922 location_chain
*nextp
;
7926 if (shared_var_p (var
, set
->vars
))
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
;
7933 if ((REG_P (node
->loc
) && REG_P (loc
)
7934 && REGNO (node
->loc
) == REGNO (loc
))
7935 || rtx_equal_p (node
->loc
, loc
))
7937 slot
= unshare_variable (set
, slot
, var
,
7938 VAR_INIT_STATUS_UNKNOWN
);
7945 if (pos
== 0 && var
->onepart
&& VAR_LOC_1PAUX (var
))
7946 cur_loc
= VAR_LOC_FROM (var
);
7948 cur_loc
= var
->var_part
[pos
].cur_loc
;
7950 /* Delete the location part. */
7952 nextp
= &var
->var_part
[pos
].loc_chain
;
7953 for (node
= *nextp
; node
; node
= next
)
7956 if ((REG_P (node
->loc
) && REG_P (loc
)
7957 && REGNO (node
->loc
) == REGNO (loc
))
7958 || rtx_equal_p (node
->loc
, loc
))
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
)
7966 var
->var_part
[pos
].cur_loc
= NULL
;
7967 if (pos
== 0 && var
->onepart
&& VAR_LOC_1PAUX (var
))
7968 VAR_LOC_FROM (var
) = NULL
;
7975 nextp
= &node
->next
;
7978 if (var
->var_part
[pos
].loc_chain
== NULL
)
7982 while (pos
< var
->n_var_parts
)
7984 var
->var_part
[pos
] = var
->var_part
[pos
+ 1];
7989 variable_was_changed (var
, set
);
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. */
8000 delete_variable_part (dataflow_set
*set
, rtx loc
, decl_or_value dv
,
8001 HOST_WIDE_INT offset
)
8003 variable_def
**slot
= shared_hash_find_slot_noinsert (set
->vars
, dv
);
8007 delete_slot_part (set
, loc
, slot
, offset
);
8011 /* Structure for passing some other parameters to function
8012 vt_expand_loc_callback. */
8013 struct expand_loc_callback_data
8015 /* The variables and values active at this point. */
8016 variable_table_type
*vars
;
8018 /* Stack of values and debug_exprs under expansion, and their
8020 auto_vec
<rtx
, 4> expanding
;
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
8028 auto_vec
<rtx
, 4> pending
;
8030 /* The maximum depth among the sub-expressions under expansion.
8031 Zero indicates no expansion so far. */
8035 /* Allocate the one-part auxiliary data structure for VAR, with enough
8036 room for COUNT dependencies. */
8039 loc_exp_dep_alloc (variable var
, int count
)
8043 gcc_checking_assert (var
->onepart
);
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
8052 gcc_checking_assert (!count
8053 || VAR_LOC_DEP_VEC (var
) == NULL
8054 || VAR_LOC_DEP_VEC (var
)->is_empty ());
8056 if (VAR_LOC_1PAUX (var
) && VAR_LOC_DEP_VEC (var
)->space (count
))
8059 allocsize
= offsetof (struct onepart_aux
, deps
)
8060 + vec
<loc_exp_dep
, va_heap
, vl_embed
>::embedded_size (count
);
8062 if (VAR_LOC_1PAUX (var
))
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
);
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;
8080 VAR_LOC_DEP_VEC (var
)->embedded_init (count
);
8083 /* Remove all entries from the vector of active dependencies of VAR,
8084 removing them from the back-links lists too. */
8087 loc_exp_dep_clear (variable var
)
8089 while (VAR_LOC_DEP_VEC (var
) && !VAR_LOC_DEP_VEC (var
)->is_empty ())
8091 loc_exp_dep
*led
= &VAR_LOC_DEP_VEC (var
)->last ();
8093 led
->next
->pprev
= led
->pprev
;
8095 *led
->pprev
= led
->next
;
8096 VAR_LOC_DEP_VEC (var
)->pop ();
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. */
8105 loc_exp_insert_dep (variable var
, rtx x
, variable_table_type
*vars
)
8111 dv
= dv_from_rtx (x
);
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
));
8119 xvar
= variable_from_dropped (dv
, NO_INSERT
);
8120 gcc_checking_assert (xvar
);
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
8127 if (VAR_LOC_DEP_LST (xvar
) && VAR_LOC_DEP_LST (xvar
)->dv
== var
->dv
)
8130 if (var
->onepart
== NOT_ONEPART
)
8131 led
= new loc_exp_dep
;
8135 memset (&empty
, 0, sizeof (empty
));
8136 VAR_LOC_DEP_VEC (var
)->quick_push (empty
);
8137 led
= &VAR_LOC_DEP_VEC (var
)->last ();
8142 loc_exp_dep_alloc (xvar
, 0);
8143 led
->pprev
= VAR_LOC_DEP_LSTP (xvar
);
8144 led
->next
= *led
->pprev
;
8146 led
->next
->pprev
= &led
->next
;
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. */
8155 loc_exp_dep_set (variable var
, rtx result
, rtx
*value
, int count
,
8156 variable_table_type
*vars
)
8158 bool pending_recursion
= false;
8160 gcc_checking_assert (VAR_LOC_DEP_VEC (var
) == NULL
8161 || VAR_LOC_DEP_VEC (var
)->is_empty ());
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
);
8171 if (!pending_recursion
)
8172 pending_recursion
= !result
&& VALUE_RECURSED_INTO (x
);
8174 loc_exp_insert_dep (var
, x
, vars
);
8177 return pending_recursion
;
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. */
8185 notify_dependents_of_resolved_value (variable ivar
, variable_table_type
*vars
)
8187 loc_exp_dep
*led
, *next
;
8189 for (led
= VAR_LOC_DEP_LST (ivar
); led
; led
= next
)
8191 decl_or_value dv
= led
->dv
;
8196 if (dv_is_value_p (dv
))
8198 rtx value
= dv_as_value (dv
);
8200 /* If we have already resolved it, leave it alone. */
8201 if (!VALUE_RECURSED_INTO (value
))
8204 /* Check that VALUE_RECURSED_INTO, true from the test above,
8205 implies NO_LOC_P. */
8206 gcc_checking_assert (NO_LOC_P (value
));
8208 /* We won't notify variables that are being expanded,
8209 because their dependency list is cleared before
8211 NO_LOC_P (value
) = false;
8212 VALUE_RECURSED_INTO (value
) = false;
8214 gcc_checking_assert (dv_changed_p (dv
));
8218 gcc_checking_assert (dv_onepart_p (dv
) != NOT_ONEPART
);
8219 if (!dv_changed_p (dv
))
8223 var
= vars
->find_with_hash (dv
, dv_htab_hash (dv
));
8226 var
= variable_from_dropped (dv
, NO_INSERT
);
8229 notify_dependents_of_resolved_value (var
, vars
);
8232 next
->pprev
= led
->pprev
;
8240 static rtx
vt_expand_loc_callback (rtx x
, bitmap regs
,
8241 int max_depth
, void *data
);
8243 /* Return the combined depth, when one sub-expression evaluated to
8244 BEST_DEPTH and the previous known depth was SAVED_DEPTH. */
8246 static inline expand_depth
8247 update_depth (expand_depth saved_depth
, expand_depth best_depth
)
8249 /* If we didn't find anything, stick with what we had. */
8250 if (!best_depth
.complexity
)
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,
8257 if (!saved_depth
.complexity
)
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
;
8265 if (saved_depth
.complexity
< best_depth
.complexity
)
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. */
8277 vt_expand_var_loc_chain (variable var
, bitmap regs
, void *data
, bool *pendrecp
)
8279 struct expand_loc_callback_data
*elcd
8280 = (struct expand_loc_callback_data
*) data
;
8281 location_chain loc
, next
;
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;
8290 /* Clear all backlinks pointing at this, so that we're not notified
8291 while we're active. */
8292 loc_exp_dep_clear (var
);
8295 if (var
->onepart
== ONEPART_VALUE
)
8297 cselib_val
*val
= CSELIB_VAL_PTR (dv_as_value (var
->dv
));
8299 gcc_checking_assert (cselib_preserved_value_p (val
));
8304 first_child
= result_first_child
= last_child
8305 = elcd
->expanding
.length ();
8307 wanted_entryvals
= found_entryvals
;
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
)
8313 result_first_child
= last_child
;
8317 loc_from
= cloc
->loc
;
8320 if (unsuitable_loc (loc_from
))
8325 loc_from
= loc
->loc
;
8329 gcc_checking_assert (!unsuitable_loc (loc_from
));
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 ();
8338 depth
= elcd
->depth
;
8340 gcc_checking_assert (depth
.complexity
8341 || result_first_child
== last_child
);
8343 if (last_child
- result_first_child
!= 1)
8345 if (!depth
.complexity
&& GET_CODE (result
) == ENTRY_VALUE
)
8350 if (depth
.complexity
<= EXPR_USE_DEPTH
)
8352 if (depth
.entryvals
<= wanted_entryvals
)
8354 else if (!found_entryvals
|| depth
.entryvals
< found_entryvals
)
8355 found_entryvals
= depth
.entryvals
;
8361 /* Set it up in case we leave the loop. */
8362 depth
.complexity
= depth
.entryvals
= 0;
8364 result_first_child
= first_child
;
8367 if (!loc_from
&& wanted_entryvals
< found_entryvals
)
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
);
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
);
8387 elcd
->expanding
.truncate (first_child
);
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
;
8394 gcc_checking_assert (!depth
.complexity
== !result
);
8396 elcd
->depth
= update_depth (saved_depth
, depth
);
8398 /* Indicate whether any of the dependencies are pending recursion
8401 *pendrecp
= pending_recursion
;
8403 if (!pendrecp
|| !pending_recursion
)
8404 var
->var_part
[0].cur_loc
= result
;
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. */
8414 vt_expand_loc_callback (rtx x
, bitmap regs
,
8415 int max_depth ATTRIBUTE_UNUSED
,
8418 struct expand_loc_callback_data
*elcd
8419 = (struct expand_loc_callback_data
*) data
;
8423 bool pending_recursion
= false;
8424 bool from_empty
= false;
8426 switch (GET_CODE (x
))
8429 subreg
= cselib_expand_value_rtx_cb (SUBREG_REG (x
), regs
,
8431 vt_expand_loc_callback
, data
);
8436 result
= simplify_gen_subreg (GET_MODE (x
), subreg
,
8437 GET_MODE (SUBREG_REG (x
)),
8440 /* Invalid SUBREGs are ok in debug info. ??? We could try
8441 alternate expansions for the VALUE as well. */
8443 result
= gen_rtx_raw_SUBREG (GET_MODE (x
), subreg
, SUBREG_BYTE (x
));
8449 dv
= dv_from_rtx (x
);
8456 elcd
->expanding
.safe_push (x
);
8458 /* Check that VALUE_RECURSED_INTO implies NO_LOC_P. */
8459 gcc_checking_assert (!VALUE_RECURSED_INTO (x
) || NO_LOC_P (x
));
8463 gcc_checking_assert (VALUE_RECURSED_INTO (x
) || !dv_changed_p (dv
));
8467 var
= elcd
->vars
->find_with_hash (dv
, dv_htab_hash (dv
));
8472 var
= variable_from_dropped (dv
, INSERT
);
8475 gcc_checking_assert (var
);
8477 if (!dv_changed_p (dv
))
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
);
8484 elcd
->depth
= update_depth (elcd
->depth
, VAR_LOC_1PAUX (var
)->depth
);
8486 return var
->var_part
[0].cur_loc
;
8489 VALUE_RECURSED_INTO (x
) = true;
8490 /* This is tentative, but it makes some tests simpler. */
8491 NO_LOC_P (x
) = true;
8493 gcc_checking_assert (var
->n_var_parts
== 1 || from_empty
);
8495 result
= vt_expand_var_loc_chain (var
, regs
, data
, &pending_recursion
);
8497 if (pending_recursion
)
8499 gcc_checking_assert (!result
);
8500 elcd
->pending
.safe_push (x
);
8504 NO_LOC_P (x
) = !result
;
8505 VALUE_RECURSED_INTO (x
) = false;
8506 set_dv_changed (dv
, false);
8509 notify_dependents_of_resolved_value (var
, elcd
->vars
);
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. */
8530 resolve_expansions_pending_recursion (vec
<rtx
, va_heap
> *pending
)
8532 while (!pending
->is_empty ())
8534 rtx x
= pending
->pop ();
8537 if (!VALUE_RECURSED_INTO (x
))
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);
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) \
8554 (d).depth.complexity = (d).depth.entryvals = 0; \
8557 /* Finalize expand_loc_callback_data D, resolved to location L. */
8558 #define FINI_ELCD(d, l) \
8561 resolve_expansions_pending_recursion (&(d).pending); \
8562 (d).pending.release (); \
8563 (d).expanding.release (); \
8565 if ((l) && MEM_P (l)) \
8566 (l) = targetm.delegitimize_address (l); \
8570 /* Expand VALUEs and DEBUG_EXPRs in LOC to a location, using the
8571 equivalences in VARS, updating their CUR_LOCs in the process. */
8574 vt_expand_loc (rtx loc
, variable_table_type
*vars
)
8576 struct expand_loc_callback_data data
;
8579 if (!MAY_HAVE_DEBUG_INSNS
)
8582 INIT_ELCD (data
, vars
);
8584 result
= cselib_expand_value_rtx_cb (loc
, scratch_regs
, EXPR_DEPTH
,
8585 vt_expand_loc_callback
, &data
);
8587 FINI_ELCD (data
, result
);
8592 /* Expand the one-part VARiable to a location, using the equivalences
8593 in VARS, updating their CUR_LOCs in the process. */
8596 vt_expand_1pvar (variable var
, variable_table_type
*vars
)
8598 struct expand_loc_callback_data data
;
8601 gcc_checking_assert (var
->onepart
&& var
->n_var_parts
== 1);
8603 if (!dv_changed_p (var
->dv
))
8604 return var
->var_part
[0].cur_loc
;
8606 INIT_ELCD (data
, vars
);
8608 loc
= vt_expand_var_loc_chain (var
, scratch_regs
, &data
, NULL
);
8610 gcc_checking_assert (data
.expanding
.is_empty ());
8612 FINI_ELCD (data
, loc
);
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. */
8622 emit_note_insn_var_location (variable_def
**varp
, emit_note_data
*data
)
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
;
8630 int i
, j
, n_var_parts
;
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
];
8640 gcc_checking_assert (var
->onepart
== NOT_ONEPART
8641 || var
->onepart
== ONEPART_VDECL
);
8643 decl
= dv_as_decl (var
->dv
);
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
++)
8654 machine_mode mode
, wider_mode
;
8656 HOST_WIDE_INT offset
;
8658 if (i
== 0 && var
->onepart
)
8660 gcc_checking_assert (var
->n_var_parts
== 1);
8662 initialized
= VAR_INIT_STATUS_INITIALIZED
;
8663 loc2
= vt_expand_1pvar (var
, vars
);
8667 if (last_limit
< VAR_PART_OFFSET (var
, i
))
8672 else if (last_limit
> VAR_PART_OFFSET (var
, i
))
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
)
8679 rtx depval
= XEXP (loc2
, 0);
8681 loc2
= vt_expand_loc (loc2
, vars
);
8684 loc_exp_insert_dep (var
, depval
, vars
);
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
)
8695 initialized
= lc
->init
;
8701 offsets
[n_var_parts
] = offset
;
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
);
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
))
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
))
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
]))
8735 if (! WORDS_BIG_ENDIAN
&& ! BYTES_BIG_ENDIAN
)
8736 new_loc
= simplify_subreg (wider_mode
, loc
[n_var_parts
],
8738 else if (WORDS_BIG_ENDIAN
&& BYTES_BIG_ENDIAN
)
8739 new_loc
= simplify_subreg (wider_mode
, loc2
, mode
, 0);
8742 if (!REG_P (new_loc
)
8743 || REGNO (new_loc
) != REGNO (loc
[n_var_parts
]))
8746 REG_ATTRS (new_loc
) = REG_ATTRS (loc
[n_var_parts
]);
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)))
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
],
8772 loc
[n_var_parts
] = new_loc
;
8774 last_limit
= offsets
[n_var_parts
] + GET_MODE_SIZE (mode
);
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
))
8784 if (! flag_var_tracking_uninit
)
8785 initialized
= VAR_INIT_STATUS_INITIALIZED
;
8789 note_vl
= gen_rtx_VAR_LOCATION (VOIDmode
, decl
, NULL_RTX
, initialized
);
8790 else if (n_var_parts
== 1)
8794 if (offsets
[0] || GET_CODE (loc
[0]) == PARALLEL
)
8795 expr_list
= gen_rtx_EXPR_LIST (VOIDmode
, loc
[0], GEN_INT (offsets
[0]));
8799 note_vl
= gen_rtx_VAR_LOCATION (VOIDmode
, decl
, expr_list
, initialized
);
8801 else if (n_var_parts
)
8805 for (i
= 0; i
< n_var_parts
; i
++)
8807 = gen_rtx_EXPR_LIST (VOIDmode
, loc
[i
], GEN_INT (offsets
[i
]));
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
);
8815 if (where
!= EMIT_NOTE_BEFORE_INSN
)
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;
8823 /* Make sure that the call related notes come first. */
8824 while (NEXT_INSN (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
);
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
);
8836 note
= emit_note_before (NOTE_INSN_VAR_LOCATION
, insn
);
8838 NOTE_VAR_LOCATION (note
) = note_vl
;
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
);
8845 /* Continue traversing the hash table. */
8849 /* While traversing changed_variables, push onto DATA (a stack of RTX
8850 values) entries that aren't user variables. */
8853 var_track_values_to_stack (variable_def
**slot
,
8854 vec
<rtx
, va_heap
> *changed_values_stack
)
8856 variable var
= *slot
;
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
)));
8866 /* Remove from changed_variables the entry whose DV corresponds to
8867 value or debug_expr VAL. */
8869 remove_value_from_changed_variables (rtx val
)
8871 decl_or_value dv
= dv_from_rtx (val
);
8872 variable_def
**slot
;
8875 slot
= changed_variables
->find_slot_with_hash (dv
, dv_htab_hash (dv
),
8878 var
->in_changed_variables
= false;
8879 changed_variables
->clear_slot (slot
);
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. */
8888 notify_dependents_of_changed_value (rtx val
, variable_table_type
*htab
,
8889 vec
<rtx
, va_heap
> *changed_values_stack
)
8891 variable_def
**slot
;
8894 decl_or_value dv
= dv_from_rtx (val
);
8896 slot
= changed_variables
->find_slot_with_hash (dv
, dv_htab_hash (dv
),
8899 slot
= htab
->find_slot_with_hash (dv
, dv_htab_hash (dv
), NO_INSERT
);
8901 slot
= dropped_values
->find_slot_with_hash (dv
, dv_htab_hash (dv
),
8905 while ((led
= VAR_LOC_DEP_LST (var
)))
8907 decl_or_value ldv
= led
->dv
;
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. */
8915 led
->next
->pprev
= led
->pprev
;
8917 *led
->pprev
= led
->next
;
8921 if (dv_changed_p (ldv
))
8924 switch (dv_onepart_p (ldv
))
8928 set_dv_changed (ldv
, true);
8929 changed_values_stack
->safe_push (dv_as_rtx (ldv
));
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
);
8940 ivar
= htab
->find_with_hash (ldv
, dv_htab_hash (ldv
));
8943 int i
= ivar
->n_var_parts
;
8946 rtx loc
= ivar
->var_part
[i
].cur_loc
;
8948 if (loc
&& GET_CODE (loc
) == MEM
8949 && XEXP (loc
, 0) == val
)
8951 variable_was_changed (ivar
, NULL
);
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. */
8970 process_changed_values (variable_table_type
*htab
)
8974 auto_vec
<rtx
, 20> changed_values_stack
;
8976 /* Move values from changed_variables to changed_values_stack. */
8978 ->traverse
<vec
<rtx
, va_heap
>*, var_track_values_to_stack
>
8979 (&changed_values_stack
);
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 ())
8986 val
= changed_values_stack
.pop ();
8987 notify_dependents_of_changed_value (val
, htab
, &changed_values_stack
);
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. */
8995 remove_value_from_changed_variables (val
);
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. */
9006 emit_notes_for_changes (rtx_insn
*insn
, enum emit_note_where where
,
9009 emit_note_data data
;
9010 variable_table_type
*htab
= shared_hash_htab (vars
);
9012 if (!changed_variables
->elements ())
9015 if (MAY_HAVE_DEBUG_INSNS
)
9016 process_changed_values (htab
);
9023 ->traverse
<emit_note_data
*, emit_note_insn_var_location
> (&data
);
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. */
9030 emit_notes_for_differences_1 (variable_def
**slot
, variable_table_type
*new_vars
)
9032 variable old_var
, new_var
;
9035 new_var
= new_vars
->find_with_hash (old_var
->dv
, dv_htab_hash (old_var
->dv
));
9039 /* Variable has disappeared. */
9040 variable empty_var
= NULL
;
9042 if (old_var
->onepart
== ONEPART_VALUE
9043 || old_var
->onepart
== ONEPART_DEXPR
)
9045 empty_var
= variable_from_dropped (old_var
->dv
, NO_INSERT
);
9048 gcc_checking_assert (!empty_var
->in_changed_variables
);
9049 if (!VAR_LOC_1PAUX (old_var
))
9051 VAR_LOC_1PAUX (old_var
) = VAR_LOC_1PAUX (empty_var
);
9052 VAR_LOC_1PAUX (empty_var
) = NULL
;
9055 gcc_checking_assert (!VAR_LOC_1PAUX (empty_var
));
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;
9069 if (empty_var
->onepart
)
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
;
9078 variable_was_changed (empty_var
, NULL
);
9079 /* Continue traversing the hash table. */
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
)
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
;
9091 if (variable_different_p (old_var
, new_var
))
9092 variable_was_changed (new_var
, NULL
);
9094 /* Continue traversing the hash table. */
9098 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
9102 emit_notes_for_differences_2 (variable_def
**slot
, variable_table_type
*old_vars
)
9104 variable old_var
, new_var
;
9107 old_var
= old_vars
->find_with_hash (new_var
->dv
, dv_htab_hash (new_var
->dv
));
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
);
9116 /* Continue traversing the hash table. */
9120 /* Emit notes before INSN for differences between dataflow sets OLD_SET and
9124 emit_notes_for_differences (rtx_insn
*insn
, dataflow_set
*old_set
,
9125 dataflow_set
*new_set
)
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
);
9136 /* Return the next insn after INSN that is not a NOTE_INSN_VAR_LOCATION. */
9139 next_non_note_insn_var_location (rtx_insn
*insn
)
9143 insn
= NEXT_INSN (insn
);
9146 || NOTE_KIND (insn
) != NOTE_INSN_VAR_LOCATION
)
9153 /* Emit the notes for changes of location parts in the basic block BB. */
9156 emit_notes_in_bb (basic_block bb
, dataflow_set
*set
)
9159 micro_operation
*mo
;
9161 dataflow_set_clear (set
);
9162 dataflow_set_copy (set
, &VTI (bb
)->in
);
9164 FOR_EACH_VEC_ELT (VTI (bb
)->mos
, i
, mo
)
9166 rtx_insn
*insn
= mo
->insn
;
9167 rtx_insn
*next_insn
= next_non_note_insn_var_location (insn
);
9172 dataflow_set_clear_at_call (set
);
9173 emit_notes_for_changes (insn
, EMIT_NOTE_AFTER_CALL_INSN
, set
->vars
);
9175 rtx arguments
= mo
->u
.loc
, *p
= &arguments
;
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))
9185 /* Otherwise, if the following item is data_value for it,
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),
9192 && REGNO (XEXP (XEXP (*p
, 0), 0))
9193 == REGNO (XEXP (XEXP (XEXP (XEXP (*p
, 1), 0),
9195 *p
= XEXP (XEXP (*p
, 1), 1);
9196 /* Just drop this item. */
9200 note
= emit_note_after (NOTE_INSN_CALL_ARG_LOCATION
, insn
);
9201 NOTE_VAR_LOCATION (note
) = arguments
;
9207 rtx loc
= mo
->u
.loc
;
9210 var_reg_set (set
, loc
, VAR_INIT_STATUS_UNINITIALIZED
, NULL
);
9212 var_mem_set (set
, loc
, VAR_INIT_STATUS_UNINITIALIZED
, NULL
);
9214 emit_notes_for_changes (insn
, EMIT_NOTE_BEFORE_INSN
, set
->vars
);
9220 rtx loc
= mo
->u
.loc
;
9224 if (GET_CODE (loc
) == CONCAT
)
9226 val
= XEXP (loc
, 0);
9227 vloc
= XEXP (loc
, 1);
9235 var
= PAT_VAR_LOCATION_DECL (vloc
);
9237 clobber_variable_part (set
, NULL_RTX
,
9238 dv_from_decl (var
), 0, NULL_RTX
);
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
,
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
,
9253 emit_notes_for_changes (insn
, EMIT_NOTE_AFTER_INSN
, set
->vars
);
9259 rtx loc
= mo
->u
.loc
;
9260 rtx val
, vloc
, uloc
;
9262 vloc
= uloc
= XEXP (loc
, 1);
9263 val
= XEXP (loc
, 0);
9265 if (GET_CODE (val
) == CONCAT
)
9267 uloc
= XEXP (val
, 1);
9268 val
= XEXP (val
, 0);
9271 if (VAL_NEEDS_RESOLUTION (loc
))
9272 val_resolve (set
, val
, vloc
, insn
);
9274 val_store (set
, val
, uloc
, insn
, false);
9276 if (VAL_HOLDS_TRACK_EXPR (loc
))
9278 if (GET_CODE (uloc
) == REG
)
9279 var_reg_set (set
, uloc
, VAR_INIT_STATUS_UNINITIALIZED
,
9281 else if (GET_CODE (uloc
) == MEM
)
9282 var_mem_set (set
, uloc
, VAR_INIT_STATUS_UNINITIALIZED
,
9286 emit_notes_for_changes (insn
, EMIT_NOTE_BEFORE_INSN
, set
->vars
);
9292 rtx loc
= mo
->u
.loc
;
9293 rtx val
, vloc
, uloc
;
9297 uloc
= XEXP (vloc
, 1);
9298 val
= XEXP (vloc
, 0);
9301 if (GET_CODE (uloc
) == SET
)
9303 dstv
= SET_DEST (uloc
);
9304 srcv
= SET_SRC (uloc
);
9312 if (GET_CODE (val
) == CONCAT
)
9314 dstv
= vloc
= XEXP (val
, 1);
9315 val
= XEXP (val
, 0);
9318 if (GET_CODE (vloc
) == SET
)
9320 srcv
= SET_SRC (vloc
);
9322 gcc_assert (val
!= srcv
);
9323 gcc_assert (vloc
== uloc
|| VAL_NEEDS_RESOLUTION (loc
));
9325 dstv
= vloc
= SET_DEST (vloc
);
9327 if (VAL_NEEDS_RESOLUTION (loc
))
9328 val_resolve (set
, val
, srcv
, insn
);
9330 else if (VAL_NEEDS_RESOLUTION (loc
))
9332 gcc_assert (GET_CODE (uloc
) == SET
9333 && GET_CODE (SET_SRC (uloc
)) == REG
);
9334 val_resolve (set
, val
, SET_SRC (uloc
), insn
);
9337 if (VAL_HOLDS_TRACK_EXPR (loc
))
9339 if (VAL_EXPR_IS_CLOBBERED (loc
))
9342 var_reg_delete (set
, uloc
, true);
9343 else if (MEM_P (uloc
))
9345 gcc_assert (MEM_P (dstv
));
9346 gcc_assert (MEM_ATTRS (dstv
) == MEM_ATTRS (uloc
));
9347 var_mem_delete (set
, dstv
, true);
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
;
9356 if (GET_CODE (uloc
) == SET
)
9358 src
= SET_SRC (uloc
);
9359 dst
= SET_DEST (uloc
);
9364 status
= find_src_status (set
, src
);
9366 src
= find_src_set_src (set
, src
);
9370 var_reg_delete_and_set (set
, dst
, !copied_p
,
9372 else if (MEM_P (dst
))
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
,
9381 else if (REG_P (uloc
))
9382 var_regno_delete (set
, REGNO (uloc
));
9383 else if (MEM_P (uloc
))
9385 gcc_checking_assert (GET_CODE (vloc
) == MEM
);
9386 gcc_checking_assert (vloc
== dstv
);
9388 clobber_overlapping_mems (set
, vloc
);
9391 val_store (set
, val
, dstv
, insn
, true);
9393 emit_notes_for_changes (next_insn
, EMIT_NOTE_BEFORE_INSN
,
9400 rtx loc
= mo
->u
.loc
;
9403 if (GET_CODE (loc
) == SET
)
9405 set_src
= SET_SRC (loc
);
9406 loc
= SET_DEST (loc
);
9410 var_reg_delete_and_set (set
, loc
, true, VAR_INIT_STATUS_INITIALIZED
,
9413 var_mem_delete_and_set (set
, loc
, true, VAR_INIT_STATUS_INITIALIZED
,
9416 emit_notes_for_changes (next_insn
, EMIT_NOTE_BEFORE_INSN
,
9423 rtx loc
= mo
->u
.loc
;
9424 enum var_init_status src_status
;
9427 if (GET_CODE (loc
) == SET
)
9429 set_src
= SET_SRC (loc
);
9430 loc
= SET_DEST (loc
);
9433 src_status
= find_src_status (set
, set_src
);
9434 set_src
= find_src_set_src (set
, set_src
);
9437 var_reg_delete_and_set (set
, loc
, false, src_status
, set_src
);
9439 var_mem_delete_and_set (set
, loc
, false, src_status
, set_src
);
9441 emit_notes_for_changes (next_insn
, EMIT_NOTE_BEFORE_INSN
,
9448 rtx loc
= mo
->u
.loc
;
9451 var_reg_delete (set
, loc
, false);
9453 var_mem_delete (set
, loc
, false);
9455 emit_notes_for_changes (insn
, EMIT_NOTE_AFTER_INSN
, set
->vars
);
9461 rtx loc
= mo
->u
.loc
;
9464 var_reg_delete (set
, loc
, true);
9466 var_mem_delete (set
, loc
, true);
9468 emit_notes_for_changes (next_insn
, EMIT_NOTE_BEFORE_INSN
,
9474 set
->stack_adjust
+= mo
->u
.adjust
;
9480 /* Emit notes for the whole function. */
9483 vt_emit_notes (void)
9488 gcc_assert (!changed_variables
->elements ());
9490 /* Free memory occupied by the out hash tables, as they aren't used
9492 FOR_EACH_BB_FN (bb
, cfun
)
9493 dataflow_set_clear (&VTI (bb
)->out
);
9495 /* Enable emitting notes by functions (mainly by set_variable_part and
9496 delete_variable_part). */
9499 if (MAY_HAVE_DEBUG_INSNS
)
9501 dropped_values
= new variable_table_type (cselib_get_next_uid () * 2);
9504 dataflow_set_init (&cur
);
9506 FOR_EACH_BB_FN (bb
, cfun
)
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
);
9512 if (MAY_HAVE_DEBUG_INSNS
)
9513 local_get_addr_cache
= new hash_map
<rtx
, rtx
>;
9515 /* Emit the notes for the changes in the basic block itself. */
9516 emit_notes_in_bb (bb
, &cur
);
9518 if (MAY_HAVE_DEBUG_INSNS
)
9519 delete local_get_addr_cache
;
9520 local_get_addr_cache
= NULL
;
9522 /* Free memory occupied by the in hash table, we won't need it
9524 dataflow_set_clear (&VTI (bb
)->in
);
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
));
9531 dataflow_set_destroy (&cur
);
9533 if (MAY_HAVE_DEBUG_INSNS
)
9534 delete dropped_values
;
9535 dropped_values
= NULL
;
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. */
9544 vt_get_decl_and_offset (rtx rtl
, tree
*declp
, HOST_WIDE_INT
*offsetp
)
9548 if (REG_ATTRS (rtl
))
9550 *declp
= REG_EXPR (rtl
);
9551 *offsetp
= REG_OFFSET (rtl
);
9555 else if (GET_CODE (rtl
) == PARALLEL
)
9557 tree decl
= NULL_TREE
;
9558 HOST_WIDE_INT offset
= MAX_VAR_PARTS
;
9559 int len
= XVECLEN (rtl
, 0), i
;
9561 for (i
= 0; i
< len
; i
++)
9563 rtx reg
= XEXP (XVECEXP (rtl
, 0, i
), 0);
9564 if (!REG_P (reg
) || !REG_ATTRS (reg
))
9567 decl
= REG_EXPR (reg
);
9568 if (REG_EXPR (reg
) != decl
)
9570 if (REG_OFFSET (reg
) < offset
)
9571 offset
= REG_OFFSET (reg
);
9581 else if (MEM_P (rtl
))
9583 if (MEM_ATTRS (rtl
))
9585 *declp
= MEM_EXPR (rtl
);
9586 *offsetp
= INT_MEM_OFFSET (rtl
);
9593 /* Record the value for the ENTRY_VALUE of RTL as a global equivalence
9597 record_entry_value (cselib_val
*val
, rtx rtl
)
9599 rtx ev
= gen_rtx_ENTRY_VALUE (GET_MODE (rtl
));
9601 ENTRY_VALUE_EXP (ev
) = rtl
;
9603 cselib_add_permanent_equiv (val
, ev
, get_insns ());
9606 /* Insert function parameter PARM in IN and OUT sets of ENTRY_BLOCK. */
9609 vt_add_function_parameter (tree parm
)
9611 rtx decl_rtl
= DECL_RTL_IF_SET (parm
);
9612 rtx incoming
= DECL_INCOMING_RTL (parm
);
9615 HOST_WIDE_INT offset
;
9619 if (TREE_CODE (parm
) != PARM_DECL
)
9622 if (!decl_rtl
|| !incoming
)
9625 if (GET_MODE (decl_rtl
) == BLKmode
|| GET_MODE (incoming
) == BLKmode
)
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)))))
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));
9643 = replace_equiv_address_nv (incoming
,
9644 plus_constant (Pmode
,
9645 arg_pointer_rtx
, off
));
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
)
9654 if (REG_P (incoming
)
9655 && HARD_REGISTER_P (incoming
)
9656 && OUTGOING_REGNO (REGNO (incoming
)) != REGNO (incoming
))
9659 p
.incoming
= 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
);
9666 else if (GET_CODE (incoming
) == PARALLEL
)
9669 = gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (XVECLEN (incoming
, 0)));
9672 for (i
= 0; i
< XVECLEN (incoming
, 0); i
++)
9674 rtx reg
= XEXP (XVECEXP (incoming
, 0, i
), 0);
9677 reg
= gen_rtx_REG_offset (reg
, GET_MODE (reg
),
9678 OUTGOING_REGNO (REGNO (reg
)), 0);
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
);
9686 incoming
= outgoing
;
9688 else if (MEM_P (incoming
)
9689 && REG_P (XEXP (incoming
, 0))
9690 && HARD_REGISTER_P (XEXP (incoming
, 0)))
9692 rtx reg
= XEXP (incoming
, 0);
9693 if (OUTGOING_REGNO (REGNO (reg
)) != REGNO (reg
))
9697 reg
= gen_raw_REG (GET_MODE (reg
), OUTGOING_REGNO (REGNO (reg
)));
9699 vec_safe_push (windowed_parm_regs
, p
);
9700 incoming
= replace_equiv_address_nv (incoming
, reg
);
9706 if (!vt_get_decl_and_offset (incoming
, &decl
, &offset
))
9708 if (MEM_P (incoming
))
9710 /* This means argument is passed by invisible reference. */
9716 if (!vt_get_decl_and_offset (decl_rtl
, &decl
, &offset
))
9718 offset
+= byte_lowpart_offset (GET_MODE (incoming
),
9719 GET_MODE (decl_rtl
));
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))
9738 if (!track_loc_p (incoming
, parm
, offset
, false, &mode
, &offset
))
9741 out
= &VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun
))->out
;
9743 dv
= dv_from_decl (parm
);
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
)
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. */
9762 lowpart
= var_lowpart (mode
, incoming
);
9766 val
= cselib_lookup_from_insn (lowpart
, mode
, true,
9767 VOIDmode
, get_insns ());
9769 /* ??? Float-typed values in memory are not handled by
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
);
9779 if (MEM_P (incoming
))
9781 val
= cselib_lookup_from_insn (XEXP (incoming
, 0), mode
, true,
9782 VOIDmode
, get_insns ());
9785 preserve_value (val
);
9786 incoming
= replace_equiv_address_nv (incoming
, val
->val_rtx
);
9791 if (REG_P (incoming
))
9793 incoming
= var_lowpart (mode
, incoming
);
9794 gcc_assert (REGNO (incoming
) < FIRST_PSEUDO_REGISTER
);
9795 attrs_list_insert (&out
->regs
[REGNO (incoming
)], dv
, offset
,
9797 set_variable_part (out
, incoming
, dv
, offset
,
9798 VAR_INIT_STATUS_INITIALIZED
, NULL
, INSERT
);
9799 if (dv_is_value_p (dv
))
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
))))
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,
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
);
9821 else if (GET_CODE (incoming
) == PARALLEL
&& !dv_onepart_p (dv
))
9825 for (i
= 0; i
< XVECLEN (incoming
, 0); i
++)
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
);
9835 else if (MEM_P (incoming
))
9837 incoming
= var_lowpart (mode
, incoming
);
9838 set_variable_part (out
, incoming
, dv
, offset
,
9839 VAR_INIT_STATUS_INITIALIZED
, NULL
, INSERT
);
9843 /* Insert function parameters to IN and OUT sets of ENTRY_BLOCK. */
9846 vt_add_function_parameters (void)
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
);
9855 if (DECL_HAS_VALUE_EXPR_P (DECL_RESULT (current_function_decl
)))
9857 tree vexpr
= DECL_VALUE_EXPR (DECL_RESULT (current_function_decl
));
9859 if (TREE_CODE (vexpr
) == INDIRECT_REF
)
9860 vexpr
= TREE_OPERAND (vexpr
, 0);
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
);
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. */
9876 vt_init_cfa_base (void)
9880 #ifdef FRAME_POINTER_CFA_OFFSET
9881 cfa_base_rtx
= frame_pointer_rtx
;
9882 cfa_base_offset
= -FRAME_POINTER_CFA_OFFSET (current_function_decl
);
9884 cfa_base_rtx
= arg_pointer_rtx
;
9885 cfa_base_offset
= -ARG_POINTER_CFA_OFFSET (current_function_decl
);
9887 if (cfa_base_rtx
== hard_frame_pointer_rtx
9888 || !fixed_regs
[REGNO (cfa_base_rtx
)])
9890 cfa_base_rtx
= NULL_RTX
;
9893 if (!MAY_HAVE_DEBUG_INSNS
)
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
);
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
));
9909 /* Allocate and initialize the data structures for variable tracking
9910 and parse the RTL to get the micro operations. */
9913 vt_initialize (void)
9916 HOST_WIDE_INT fp_cfa_offset
= -1;
9918 alloc_aux_for_blocks (sizeof (struct variable_tracking_info_def
));
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);
9925 /* Init the IN and OUT sets. */
9926 FOR_ALL_BB_FN (bb
, cfun
)
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
;
9935 if (MAY_HAVE_DEBUG_INSNS
)
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
>;
9944 scratch_regs
= NULL
;
9945 global_get_addr_cache
= NULL
;
9948 if (MAY_HAVE_DEBUG_INSNS
)
9954 #ifdef FRAME_POINTER_CFA_OFFSET
9955 reg
= frame_pointer_rtx
;
9956 ofst
= FRAME_POINTER_CFA_OFFSET (current_function_decl
);
9958 reg
= arg_pointer_rtx
;
9959 ofst
= ARG_POINTER_CFA_OFFSET (current_function_decl
);
9962 ofst
-= INCOMING_FRAME_SP_OFFSET
;
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 ());
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 ());
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
)
9998 if (!vt_stack_adjustments ())
10001 #ifdef FRAME_POINTER_CFA_OFFSET
10002 reg
= frame_pointer_rtx
;
10004 reg
= arg_pointer_rtx
;
10006 elim
= eliminate_regs (reg
, VOIDmode
, NULL_RTX
);
10009 if (GET_CODE (elim
) == PLUS
)
10010 elim
= XEXP (elim
, 0);
10011 if (elim
== stack_pointer_rtx
)
10012 vt_init_cfa_base ();
10015 else if (!crtl
->stack_realign_tried
)
10019 #ifdef FRAME_POINTER_CFA_OFFSET
10020 reg
= frame_pointer_rtx
;
10021 fp_cfa_offset
= FRAME_POINTER_CFA_OFFSET (current_function_decl
);
10023 reg
= arg_pointer_rtx
;
10024 fp_cfa_offset
= ARG_POINTER_CFA_OFFSET (current_function_decl
);
10026 elim
= eliminate_regs (reg
, VOIDmode
, NULL_RTX
);
10029 if (GET_CODE (elim
) == PLUS
)
10031 fp_cfa_offset
-= INTVAL (XEXP (elim
, 1));
10032 elim
= XEXP (elim
, 0);
10034 if (elim
!= hard_frame_pointer_rtx
)
10035 fp_cfa_offset
= -1;
10038 fp_cfa_offset
= -1;
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.
10048 ??? This doesn't work if FRAME_POINTER_CFA_OFFSET is defined. */
10049 else if (stack_realign_drap
)
10053 #ifdef FRAME_POINTER_CFA_OFFSET
10054 reg
= frame_pointer_rtx
;
10056 reg
= arg_pointer_rtx
;
10058 elim
= eliminate_regs (reg
, VOIDmode
, NULL_RTX
);
10061 if (GET_CODE (elim
) == PLUS
)
10062 elim
= XEXP (elim
, 0);
10063 if (elim
== hard_frame_pointer_rtx
)
10064 vt_init_cfa_base ();
10068 hard_frame_pointer_adjustment
= -1;
10070 vt_add_function_parameters ();
10072 FOR_EACH_BB_FN (bb
, cfun
)
10075 HOST_WIDE_INT pre
, post
= 0;
10076 basic_block first_bb
, last_bb
;
10078 if (MAY_HAVE_DEBUG_INSNS
)
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 ());
10090 if (bb
->next_bb
== EXIT_BLOCK_PTR_FOR_FN (cfun
)
10091 || ! single_pred_p (bb
->next_bb
))
10093 e
= find_edge (bb
, bb
->next_bb
);
10094 if (! e
|| (e
->flags
& EDGE_FALLTHRU
) == 0)
10100 /* Add the micro-operations to the vector. */
10101 FOR_BB_BETWEEN (bb
, first_bb
, last_bb
->next_bb
, next_bb
)
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
))
10110 if (!frame_pointer_needed
)
10112 insn_stack_adjust_offset_pre_post (insn
, &pre
, &post
);
10115 micro_operation mo
;
10116 mo
.type
= MO_ADJUST
;
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
;
10127 cselib_hook_called
= false;
10128 adjust_insn (bb
, insn
);
10129 if (MAY_HAVE_DEBUG_INSNS
)
10132 prepare_call_arguments (bb
, insn
);
10133 cselib_process_insn (insn
);
10134 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
10136 print_rtl_single (dump_file
, insn
);
10137 dump_cselib_table (dump_file
);
10140 if (!cselib_hook_called
)
10141 add_with_sets (insn
, 0, 0);
10142 cancel_changes (0);
10144 if (!frame_pointer_needed
&& post
)
10146 micro_operation mo
;
10147 mo
.type
= MO_ADJUST
;
10148 mo
.u
.adjust
= post
;
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
;
10157 if (fp_cfa_offset
!= -1
10158 && hard_frame_pointer_adjustment
== -1
10159 && fp_setter_insn (insn
))
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
)
10167 cselib_invalidate_rtx (stack_pointer_rtx
);
10168 v
= cselib_lookup (stack_pointer_rtx
, Pmode
, 1,
10170 if (v
&& !cselib_preserved_value_p (v
))
10172 cselib_set_value_sp_based (v
);
10173 preserve_value (v
);
10179 gcc_assert (offset
== VTI (bb
)->out
.stack_adjust
);
10184 if (MAY_HAVE_DEBUG_INSNS
)
10186 cselib_preserve_only_values ();
10187 cselib_reset_table (cselib_get_next_uid ());
10188 cselib_record_sets_hook
= NULL
;
10192 hard_frame_pointer_adjustment
= -1;
10193 VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun
))->flooded
= true;
10194 cfa_base_rtx
= NULL_RTX
;
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. */
10202 static int debug_label_num
= 1;
10204 /* Get rid of all debug insns from the insn stream. */
10207 delete_debug_insns (void)
10210 rtx_insn
*insn
, *next
;
10212 if (!MAY_HAVE_DEBUG_INSNS
)
10215 FOR_EACH_BB_FN (bb
, cfun
)
10217 FOR_BB_INSNS_SAFE (bb
, insn
, next
)
10218 if (DEBUG_INSN_P (insn
))
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
))
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
++;
10233 delete_insn (insn
);
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.. */
10245 vt_debug_insns_local (bool skipped ATTRIBUTE_UNUSED
)
10247 /* ??? Just skip it all for now. */
10248 delete_debug_insns ();
10251 /* Free the data structures needed for variable tracking. */
10258 FOR_EACH_BB_FN (bb
, cfun
)
10260 VTI (bb
)->mos
.release ();
10263 FOR_ALL_BB_FN (bb
, cfun
)
10265 dataflow_set_destroy (&VTI (bb
)->in
);
10266 dataflow_set_destroy (&VTI (bb
)->out
);
10267 if (VTI (bb
)->permp
)
10269 dataflow_set_destroy (VTI (bb
)->permp
);
10270 XDELETE (VTI (bb
)->permp
);
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 ();
10283 if (MAY_HAVE_DEBUG_INSNS
)
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 ();
10292 BITMAP_FREE (scratch_regs
);
10293 scratch_regs
= NULL
;
10296 #ifdef HAVE_window_save
10297 vec_free (windowed_parm_regs
);
10301 XDELETEVEC (vui_vec
);
10306 /* The entry point to variable tracking pass. */
10308 static inline unsigned int
10309 variable_tracking_main_1 (void)
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
)
10318 delete_debug_insns ();
10322 if (n_basic_blocks_for_fn (cfun
) > 500 &&
10323 n_edges_for_fn (cfun
) / n_basic_blocks_for_fn (cfun
) >= 20)
10325 vt_debug_insns_local (true);
10329 mark_dfs_back_edges ();
10330 if (!vt_initialize ())
10333 vt_debug_insns_local (true);
10337 success
= vt_find_locations ();
10339 if (!success
&& flag_var_tracking_assignments
> 0)
10343 delete_debug_insns ();
10345 /* This is later restored by our caller. */
10346 flag_var_tracking_assignments
= 0;
10348 success
= vt_initialize ();
10349 gcc_assert (success
);
10351 success
= vt_find_locations ();
10357 vt_debug_insns_local (false);
10361 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
10363 dump_dataflow_sets ();
10364 dump_reg_info (dump_file
);
10365 dump_flow_info (dump_file
, dump_flags
);
10368 timevar_push (TV_VAR_TRACKING_EMIT
);
10370 timevar_pop (TV_VAR_TRACKING_EMIT
);
10373 vt_debug_insns_local (false);
10378 variable_tracking_main (void)
10381 int save
= flag_var_tracking_assignments
;
10383 ret
= variable_tracking_main_1 ();
10385 flag_var_tracking_assignments
= save
;
10392 const pass_data pass_data_variable_tracking
=
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 */
10405 class pass_variable_tracking
: public rtl_opt_pass
10408 pass_variable_tracking (gcc::context
*ctxt
)
10409 : rtl_opt_pass (pass_data_variable_tracking
, ctxt
)
10412 /* opt_pass methods: */
10413 virtual bool gate (function
*)
10415 return (flag_var_tracking
&& !targetm
.delay_vartrack
);
10418 virtual unsigned int execute (function
*)
10420 return variable_tracking_main ();
10423 }; // class pass_variable_tracking
10425 } // anon namespace
10428 make_pass_variable_tracking (gcc::context
*ctxt
)
10430 return new pass_variable_tracking (ctxt
);