1 /* Variable tracking routines for the GNU compiler.
2 Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This file contains the variable tracking pass. It computes where
22 variables are located (which registers or where in memory) at each position
23 in instruction stream and emits notes describing the locations.
24 Debug information (DWARF2 location lists) is finally generated from
26 With this debug information, it is possible to show variables
27 even when debugging optimized code.
29 How does the variable tracking pass work?
31 First, it scans RTL code for uses, stores and clobbers (register/memory
32 references in instructions), for call insns and for stack adjustments
33 separately for each basic block and saves them to an array of micro
35 The micro operations of one instruction are ordered so that
36 pre-modifying stack adjustment < use < use with no var < call insn <
37 < set < clobber < post-modifying stack adjustment
39 Then, a forward dataflow analysis is performed to find out how locations
40 of variables change through code and to propagate the variable locations
41 along control flow graph.
42 The IN set for basic block BB is computed as a union of OUT sets of BB's
43 predecessors, the OUT set for BB is copied from the IN set for BB and
44 is changed according to micro operations in BB.
46 The IN and OUT sets for basic blocks consist of a current stack adjustment
47 (used for adjusting offset of variables addressed using stack pointer),
48 the table of structures describing the locations of parts of a variable
49 and for each physical register a linked list for each physical register.
50 The linked list is a list of variable parts stored in the register,
51 i.e. it is a list of triplets (reg, decl, offset) where decl is
52 REG_EXPR (reg) and offset is REG_OFFSET (reg). The linked list is used for
53 effective deleting appropriate variable parts when we set or clobber the
56 There may be more than one variable part in a register. The linked lists
57 should be pretty short so it is a good data structure here.
58 For example in the following code, register allocator may assign same
59 register to variables A and B, and both of them are stored in the same
72 Finally, the NOTE_INSN_VAR_LOCATION notes describing the variable locations
73 are emitted to appropriate positions in RTL code. Each such a note describes
74 the location of one variable at the point in instruction stream where the
75 note is. There is no need to emit a note for each variable before each
76 instruction, we only emit these notes where the location of variable changes
77 (this means that we also emit notes for changes between the OUT set of the
78 previous block and the IN set of the current block).
80 The notes consist of two parts:
81 1. the declaration (from REG_EXPR or MEM_EXPR)
82 2. the location of a variable - it is either a simple register/memory
83 reference (for simple variables, for example int),
84 or a parallel of register/memory references (for a large variables
85 which consist of several parts, for example long long).
91 #include "coretypes.h"
95 #include "hard-reg-set.h"
96 #include "basic-block.h"
99 #include "insn-config.h"
102 #include "alloc-pool.h"
108 #include "tree-pass.h"
110 /* Type of micro operation. */
111 enum micro_operation_type
113 MO_USE, /* Use location (REG or MEM). */
114 MO_USE_NO_VAR,/* Use location which is not associated with a variable
115 or the variable is not trackable. */
116 MO_SET, /* Set location. */
117 MO_COPY, /* Copy the same portion of a variable from one
118 location to another. */
119 MO_CLOBBER, /* Clobber location. */
120 MO_CALL, /* Call insn. */
121 MO_ADJUST /* Adjust stack pointer. */
124 /* Where shall the note be emitted? BEFORE or AFTER the instruction. */
127 EMIT_NOTE_BEFORE_INSN,
131 /* Structure holding information about micro operation. */
132 typedef struct micro_operation_def
134 /* Type of micro operation. */
135 enum micro_operation_type type;
138 /* Location. For MO_SET and MO_COPY, this is the SET that performs
139 the assignment, if known, otherwise it is the target of the
143 /* Stack adjustment. */
144 HOST_WIDE_INT adjust;
147 /* The instruction which the micro operation is in, for MO_USE,
148 MO_USE_NO_VAR, MO_CALL and MO_ADJUST, or the subsequent
149 instruction or note in the original flow (before any var-tracking
150 notes are inserted, to simplify emission of notes), for MO_SET
155 /* Structure for passing some other parameters to function
156 emit_note_insn_var_location. */
157 typedef struct emit_note_data_def
159 /* The instruction which the note will be emitted before/after. */
162 /* Where the note will be emitted (before/after insn)? */
163 enum emit_note_where where;
166 /* Description of location of a part of a variable. The content of a physical
167 register is described by a chain of these structures.
168 The chains are pretty short (usually 1 or 2 elements) and thus
169 chain is the best data structure. */
170 typedef struct attrs_def
172 /* Pointer to next member of the list. */
173 struct attrs_def *next;
175 /* The rtx of register. */
178 /* The declaration corresponding to LOC. */
181 /* Offset from start of DECL. */
182 HOST_WIDE_INT offset;
185 /* Structure holding a refcounted hash table. If refcount > 1,
186 it must be first unshared before modified. */
187 typedef struct shared_hash_def
189 /* Reference count. */
192 /* Actual hash table. */
196 /* Structure holding the IN or OUT set for a basic block. */
197 typedef struct dataflow_set_def
199 /* Adjustment of stack offset. */
200 HOST_WIDE_INT stack_adjust;
202 /* Attributes for registers (lists of attrs). */
203 attrs regs[FIRST_PSEUDO_REGISTER];
205 /* Variable locations. */
209 /* The structure (one for each basic block) containing the information
210 needed for variable tracking. */
211 typedef struct variable_tracking_info_def
213 /* Number of micro operations stored in the MOS array. */
216 /* The array of micro operations. */
217 micro_operation *mos;
219 /* The IN and OUT set for dataflow analysis. */
223 /* Has the block been visited in DFS? */
225 } *variable_tracking_info;
227 /* Structure for chaining the locations. */
228 typedef struct location_chain_def
230 /* Next element in the chain. */
231 struct location_chain_def *next;
233 /* The location (REG or MEM). */
236 /* The "value" stored in this location. */
240 enum var_init_status init;
243 /* Structure describing one part of variable. */
244 typedef struct variable_part_def
246 /* Chain of locations of the part. */
247 location_chain loc_chain;
249 /* Location which was last emitted to location list. */
252 /* The offset in the variable. */
253 HOST_WIDE_INT offset;
256 /* Maximum number of location parts. */
257 #define MAX_VAR_PARTS 16
259 /* Structure describing where the variable is located. */
260 typedef struct variable_def
262 /* The declaration of the variable. */
265 /* Reference count. */
268 /* Number of variable parts. */
271 /* The variable parts. */
272 variable_part var_part[MAX_VAR_PARTS];
274 typedef const struct variable_def *const_variable;
276 /* Hash function for DECL for VARIABLE_HTAB. */
277 #define VARIABLE_HASH_VAL(decl) (DECL_UID (decl))
279 /* Pointer to the BB's information specific to variable tracking pass. */
280 #define VTI(BB) ((variable_tracking_info) (BB)->aux)
282 /* Macro to access MEM_OFFSET as an HOST_WIDE_INT. Evaluates MEM twice. */
283 #define INT_MEM_OFFSET(mem) (MEM_OFFSET (mem) ? INTVAL (MEM_OFFSET (mem)) : 0)
285 /* Alloc pool for struct attrs_def. */
286 static alloc_pool attrs_pool;
288 /* Alloc pool for struct variable_def. */
289 static alloc_pool var_pool;
291 /* Alloc pool for struct location_chain_def. */
292 static alloc_pool loc_chain_pool;
294 /* Alloc pool for struct shared_hash_def. */
295 static alloc_pool shared_hash_pool;
297 /* Changed variables, notes will be emitted for them. */
298 static htab_t changed_variables;
300 /* Shall notes be emitted? */
301 static bool emit_notes;
303 /* Empty shared hashtable. */
304 static shared_hash empty_shared_hash;
306 /* Local function prototypes. */
307 static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
309 static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
311 static void bb_stack_adjust_offset (basic_block);
312 static bool vt_stack_adjustments (void);
313 static rtx adjust_stack_reference (rtx, HOST_WIDE_INT);
314 static hashval_t variable_htab_hash (const void *);
315 static int variable_htab_eq (const void *, const void *);
316 static void variable_htab_free (void *);
318 static void init_attrs_list_set (attrs *);
319 static void attrs_list_clear (attrs *);
320 static attrs attrs_list_member (attrs, tree, HOST_WIDE_INT);
321 static void attrs_list_insert (attrs *, tree, HOST_WIDE_INT, rtx);
322 static void attrs_list_copy (attrs *, attrs);
323 static void attrs_list_union (attrs *, attrs);
325 static variable unshare_variable (dataflow_set *set, variable var,
326 enum var_init_status);
327 static int vars_copy_1 (void **, void *);
328 static void vars_copy (htab_t, htab_t);
329 static tree var_debug_decl (tree);
330 static void var_reg_set (dataflow_set *, rtx, enum var_init_status, rtx);
331 static void var_reg_delete_and_set (dataflow_set *, rtx, bool,
332 enum var_init_status, rtx);
333 static void var_reg_delete (dataflow_set *, rtx, bool);
334 static void var_regno_delete (dataflow_set *, int);
335 static void var_mem_set (dataflow_set *, rtx, enum var_init_status, rtx);
336 static void var_mem_delete_and_set (dataflow_set *, rtx, bool,
337 enum var_init_status, rtx);
338 static void var_mem_delete (dataflow_set *, rtx, bool);
340 static void dataflow_set_init (dataflow_set *);
341 static void dataflow_set_clear (dataflow_set *);
342 static void dataflow_set_copy (dataflow_set *, dataflow_set *);
343 static int variable_union_info_cmp_pos (const void *, const void *);
344 static int variable_union (void **, void *);
345 static int variable_canonicalize (void **, void *);
346 static void dataflow_set_union (dataflow_set *, dataflow_set *);
347 static bool variable_part_different_p (variable_part *, variable_part *);
348 static bool variable_different_p (variable, variable, bool);
349 static int dataflow_set_different_1 (void **, void *);
350 static int dataflow_set_different_2 (void **, void *);
351 static bool dataflow_set_different (dataflow_set *, dataflow_set *);
352 static void dataflow_set_destroy (dataflow_set *);
354 static bool contains_symbol_ref (rtx);
355 static bool track_expr_p (tree);
356 static bool same_variable_part_p (rtx, tree, HOST_WIDE_INT);
357 static int count_uses (rtx *, void *);
358 static void count_uses_1 (rtx *, void *);
359 static void count_stores (rtx, const_rtx, void *);
360 static int add_uses (rtx *, void *);
361 static void add_uses_1 (rtx *, void *);
362 static void add_stores (rtx, const_rtx, void *);
363 static bool compute_bb_dataflow (basic_block);
364 static void vt_find_locations (void);
366 static void dump_attrs_list (attrs);
367 static int dump_variable (void **, void *);
368 static void dump_vars (htab_t);
369 static void dump_dataflow_set (dataflow_set *);
370 static void dump_dataflow_sets (void);
372 static void variable_was_changed (variable, dataflow_set *);
373 static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT,
374 enum var_init_status, rtx);
375 static void clobber_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT,
377 static void delete_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
378 static int emit_note_insn_var_location (void **, void *);
379 static void emit_notes_for_changes (rtx, enum emit_note_where);
380 static int emit_notes_for_differences_1 (void **, void *);
381 static int emit_notes_for_differences_2 (void **, void *);
382 static void emit_notes_for_differences (rtx, dataflow_set *, dataflow_set *);
383 static void emit_notes_in_bb (basic_block);
384 static void vt_emit_notes (void);
386 static bool vt_get_decl_and_offset (rtx, tree *, HOST_WIDE_INT *);
387 static void vt_add_function_parameters (void);
388 static void vt_initialize (void);
389 static void vt_finalize (void);
391 /* Given a SET, calculate the amount of stack adjustment it contains
392 PRE- and POST-modifying stack pointer.
393 This function is similar to stack_adjust_offset. */
396 stack_adjust_offset_pre_post (rtx pattern, HOST_WIDE_INT *pre,
399 rtx src = SET_SRC (pattern);
400 rtx dest = SET_DEST (pattern);
403 if (dest == stack_pointer_rtx)
405 /* (set (reg sp) (plus (reg sp) (const_int))) */
406 code = GET_CODE (src);
407 if (! (code == PLUS || code == MINUS)
408 || XEXP (src, 0) != stack_pointer_rtx
409 || GET_CODE (XEXP (src, 1)) != CONST_INT)
413 *post += INTVAL (XEXP (src, 1));
415 *post -= INTVAL (XEXP (src, 1));
417 else if (MEM_P (dest))
419 /* (set (mem (pre_dec (reg sp))) (foo)) */
420 src = XEXP (dest, 0);
421 code = GET_CODE (src);
427 if (XEXP (src, 0) == stack_pointer_rtx)
429 rtx val = XEXP (XEXP (src, 1), 1);
430 /* We handle only adjustments by constant amount. */
431 gcc_assert (GET_CODE (XEXP (src, 1)) == PLUS &&
432 GET_CODE (val) == CONST_INT);
434 if (code == PRE_MODIFY)
435 *pre -= INTVAL (val);
437 *post -= INTVAL (val);
443 if (XEXP (src, 0) == stack_pointer_rtx)
445 *pre += GET_MODE_SIZE (GET_MODE (dest));
451 if (XEXP (src, 0) == stack_pointer_rtx)
453 *post += GET_MODE_SIZE (GET_MODE (dest));
459 if (XEXP (src, 0) == stack_pointer_rtx)
461 *pre -= GET_MODE_SIZE (GET_MODE (dest));
467 if (XEXP (src, 0) == stack_pointer_rtx)
469 *post -= GET_MODE_SIZE (GET_MODE (dest));
480 /* Given an INSN, calculate the amount of stack adjustment it contains
481 PRE- and POST-modifying stack pointer. */
484 insn_stack_adjust_offset_pre_post (rtx insn, HOST_WIDE_INT *pre,
492 pattern = PATTERN (insn);
493 if (RTX_FRAME_RELATED_P (insn))
495 rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
497 pattern = XEXP (expr, 0);
500 if (GET_CODE (pattern) == SET)
501 stack_adjust_offset_pre_post (pattern, pre, post);
502 else if (GET_CODE (pattern) == PARALLEL
503 || GET_CODE (pattern) == SEQUENCE)
507 /* There may be stack adjustments inside compound insns. Search
509 for ( i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
510 if (GET_CODE (XVECEXP (pattern, 0, i)) == SET)
511 stack_adjust_offset_pre_post (XVECEXP (pattern, 0, i), pre, post);
515 /* Compute stack adjustment in basic block BB. */
518 bb_stack_adjust_offset (basic_block bb)
520 HOST_WIDE_INT offset;
523 offset = VTI (bb)->in.stack_adjust;
524 for (i = 0; i < VTI (bb)->n_mos; i++)
526 if (VTI (bb)->mos[i].type == MO_ADJUST)
527 offset += VTI (bb)->mos[i].u.adjust;
528 else if (VTI (bb)->mos[i].type != MO_CALL)
530 if (MEM_P (VTI (bb)->mos[i].u.loc))
532 VTI (bb)->mos[i].u.loc
533 = adjust_stack_reference (VTI (bb)->mos[i].u.loc, -offset);
537 VTI (bb)->out.stack_adjust = offset;
540 /* Compute stack adjustments for all blocks by traversing DFS tree.
541 Return true when the adjustments on all incoming edges are consistent.
542 Heavily borrowed from pre_and_rev_post_order_compute. */
545 vt_stack_adjustments (void)
547 edge_iterator *stack;
550 /* Initialize entry block. */
551 VTI (ENTRY_BLOCK_PTR)->visited = true;
552 VTI (ENTRY_BLOCK_PTR)->out.stack_adjust = INCOMING_FRAME_SP_OFFSET;
554 /* Allocate stack for back-tracking up CFG. */
555 stack = XNEWVEC (edge_iterator, n_basic_blocks + 1);
558 /* Push the first edge on to the stack. */
559 stack[sp++] = ei_start (ENTRY_BLOCK_PTR->succs);
567 /* Look at the edge on the top of the stack. */
569 src = ei_edge (ei)->src;
570 dest = ei_edge (ei)->dest;
572 /* Check if the edge destination has been visited yet. */
573 if (!VTI (dest)->visited)
575 VTI (dest)->visited = true;
576 VTI (dest)->in.stack_adjust = VTI (src)->out.stack_adjust;
577 bb_stack_adjust_offset (dest);
579 if (EDGE_COUNT (dest->succs) > 0)
580 /* Since the DEST node has been visited for the first
581 time, check its successors. */
582 stack[sp++] = ei_start (dest->succs);
586 /* Check whether the adjustments on the edges are the same. */
587 if (VTI (dest)->in.stack_adjust != VTI (src)->out.stack_adjust)
593 if (! ei_one_before_end_p (ei))
594 /* Go to the next edge. */
595 ei_next (&stack[sp - 1]);
597 /* Return to previous level if there are no more edges. */
606 /* Adjust stack reference MEM by ADJUSTMENT bytes and make it relative
607 to the argument pointer. Return the new rtx. */
610 adjust_stack_reference (rtx mem, HOST_WIDE_INT adjustment)
614 #ifdef FRAME_POINTER_CFA_OFFSET
615 adjustment -= FRAME_POINTER_CFA_OFFSET (current_function_decl);
616 cfa = plus_constant (frame_pointer_rtx, adjustment);
618 adjustment -= ARG_POINTER_CFA_OFFSET (current_function_decl);
619 cfa = plus_constant (arg_pointer_rtx, adjustment);
622 addr = replace_rtx (copy_rtx (XEXP (mem, 0)), stack_pointer_rtx, cfa);
623 tmp = simplify_rtx (addr);
627 return replace_equiv_address_nv (mem, addr);
630 /* The hash function for variable_htab, computes the hash value
631 from the declaration of variable X. */
634 variable_htab_hash (const void *x)
636 const_variable const v = (const_variable) x;
638 return (VARIABLE_HASH_VAL (v->decl));
641 /* Compare the declaration of variable X with declaration Y. */
644 variable_htab_eq (const void *x, const void *y)
646 const_variable const v = (const_variable) x;
647 const_tree const decl = (const_tree) y;
649 return (VARIABLE_HASH_VAL (v->decl) == VARIABLE_HASH_VAL (decl));
652 /* Free the element of VARIABLE_HTAB (its type is struct variable_def). */
655 variable_htab_free (void *elem)
658 variable var = (variable) elem;
659 location_chain node, next;
661 gcc_assert (var->refcount > 0);
664 if (var->refcount > 0)
667 for (i = 0; i < var->n_var_parts; i++)
669 for (node = var->var_part[i].loc_chain; node; node = next)
672 pool_free (loc_chain_pool, node);
674 var->var_part[i].loc_chain = NULL;
676 pool_free (var_pool, var);
679 /* Initialize the set (array) SET of attrs to empty lists. */
682 init_attrs_list_set (attrs *set)
686 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
690 /* Make the list *LISTP empty. */
693 attrs_list_clear (attrs *listp)
697 for (list = *listp; list; list = next)
700 pool_free (attrs_pool, list);
705 /* Return true if the pair of DECL and OFFSET is the member of the LIST. */
708 attrs_list_member (attrs list, tree decl, HOST_WIDE_INT offset)
710 for (; list; list = list->next)
711 if (list->decl == decl && list->offset == offset)
716 /* Insert the triplet DECL, OFFSET, LOC to the list *LISTP. */
719 attrs_list_insert (attrs *listp, tree decl, HOST_WIDE_INT offset, rtx loc)
723 list = (attrs) pool_alloc (attrs_pool);
726 list->offset = offset;
731 /* Copy all nodes from SRC and create a list *DSTP of the copies. */
734 attrs_list_copy (attrs *dstp, attrs src)
738 attrs_list_clear (dstp);
739 for (; src; src = src->next)
741 n = (attrs) pool_alloc (attrs_pool);
744 n->offset = src->offset;
750 /* Add all nodes from SRC which are not in *DSTP to *DSTP. */
753 attrs_list_union (attrs *dstp, attrs src)
755 for (; src; src = src->next)
757 if (!attrs_list_member (*dstp, src->decl, src->offset))
758 attrs_list_insert (dstp, src->decl, src->offset, src->loc);
762 /* Shared hashtable support. */
764 /* Return true if VARS is shared. */
767 shared_hash_shared (shared_hash vars)
769 return vars->refcount > 1;
772 /* Return the hash table for VARS. */
775 shared_hash_htab (shared_hash vars)
780 /* Copy variables into a new hash table. */
783 shared_hash_unshare (shared_hash vars)
785 shared_hash new_vars = (shared_hash) pool_alloc (shared_hash_pool);
786 gcc_assert (vars->refcount > 1);
787 new_vars->refcount = 1;
789 = htab_create (htab_elements (vars->htab) + 3, variable_htab_hash,
790 variable_htab_eq, variable_htab_free);
791 vars_copy (new_vars->htab, vars->htab);
796 /* Increment reference counter on VARS and return it. */
798 static inline shared_hash
799 shared_hash_copy (shared_hash vars)
805 /* Decrement reference counter and destroy hash table if not shared
809 shared_hash_destroy (shared_hash vars)
811 gcc_assert (vars->refcount > 0);
812 if (--vars->refcount == 0)
814 htab_delete (vars->htab);
815 pool_free (shared_hash_pool, vars);
819 /* Unshare *PVARS if shared and return slot for DECL. If INS is
820 INSERT, insert it if not already present. */
822 static inline void **
823 shared_hash_find_slot_unshare (shared_hash *pvars, tree decl,
824 enum insert_option ins)
826 if (shared_hash_shared (*pvars))
827 *pvars = shared_hash_unshare (*pvars);
828 return htab_find_slot_with_hash (shared_hash_htab (*pvars), decl,
829 VARIABLE_HASH_VAL (decl), ins);
832 /* Return slot for DECL, if it is already present in the hash table.
833 If it is not present, insert it only VARS is not shared, otherwise
836 static inline void **
837 shared_hash_find_slot (shared_hash vars, tree decl)
839 return htab_find_slot_with_hash (shared_hash_htab (vars), decl,
840 VARIABLE_HASH_VAL (decl),
841 shared_hash_shared (vars)
842 ? NO_INSERT : INSERT);
845 /* Return slot for DECL only if it is already present in the hash table. */
847 static inline void **
848 shared_hash_find_slot_noinsert (shared_hash vars, tree decl)
850 return htab_find_slot_with_hash (shared_hash_htab (vars), decl,
851 VARIABLE_HASH_VAL (decl), NO_INSERT);
854 /* Return variable for DECL or NULL if not already present in the hash
857 static inline variable
858 shared_hash_find (shared_hash vars, tree decl)
861 htab_find_with_hash (shared_hash_htab (vars), decl,
862 VARIABLE_HASH_VAL (decl));
865 /* Return a copy of a variable VAR and insert it to dataflow set SET. */
868 unshare_variable (dataflow_set *set, variable var,
869 enum var_init_status initialized)
875 new_var = (variable) pool_alloc (var_pool);
876 new_var->decl = var->decl;
877 new_var->refcount = 1;
879 new_var->n_var_parts = var->n_var_parts;
881 for (i = 0; i < var->n_var_parts; i++)
884 location_chain *nextp;
886 new_var->var_part[i].offset = var->var_part[i].offset;
887 nextp = &new_var->var_part[i].loc_chain;
888 for (node = var->var_part[i].loc_chain; node; node = node->next)
890 location_chain new_lc;
892 new_lc = (location_chain) pool_alloc (loc_chain_pool);
894 if (node->init > initialized)
895 new_lc->init = node->init;
897 new_lc->init = initialized;
898 if (node->set_src && !(MEM_P (node->set_src)))
899 new_lc->set_src = node->set_src;
901 new_lc->set_src = NULL;
902 new_lc->loc = node->loc;
905 nextp = &new_lc->next;
908 /* We are at the basic block boundary when copying variable description
909 so set the CUR_LOC to be the first element of the chain. */
910 if (new_var->var_part[i].loc_chain)
911 new_var->var_part[i].cur_loc = new_var->var_part[i].loc_chain->loc;
913 new_var->var_part[i].cur_loc = NULL;
916 slot = shared_hash_find_slot_unshare (&set->vars, new_var->decl, INSERT);
921 /* Add a variable from *SLOT to hash table DATA and increase its reference
925 vars_copy_1 (void **slot, void *data)
927 htab_t dst = (htab_t) data;
930 src = *(variable *) slot;
933 dstp = (variable *) htab_find_slot_with_hash (dst, src->decl,
934 VARIABLE_HASH_VAL (src->decl),
938 /* Continue traversing the hash table. */
942 /* Copy all variables from hash table SRC to hash table DST. */
945 vars_copy (htab_t dst, htab_t src)
947 htab_traverse_noresize (src, vars_copy_1, dst);
950 /* Map a decl to its main debug decl. */
953 var_debug_decl (tree decl)
955 if (decl && DECL_P (decl)
956 && DECL_DEBUG_EXPR_IS_FROM (decl) && DECL_DEBUG_EXPR (decl)
957 && DECL_P (DECL_DEBUG_EXPR (decl)))
958 decl = DECL_DEBUG_EXPR (decl);
963 /* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). */
966 var_reg_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
969 tree decl = REG_EXPR (loc);
970 HOST_WIDE_INT offset = REG_OFFSET (loc);
973 decl = var_debug_decl (decl);
975 for (node = set->regs[REGNO (loc)]; node; node = node->next)
976 if (node->decl == decl && node->offset == offset)
979 attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc);
980 set_variable_part (set, loc, decl, offset, initialized, set_src);
983 static enum var_init_status
984 get_init_value (dataflow_set *set, rtx loc, tree decl)
988 enum var_init_status ret_val = VAR_INIT_STATUS_UNKNOWN;
990 if (! flag_var_tracking_uninit)
991 return VAR_INIT_STATUS_INITIALIZED;
993 var = shared_hash_find (set->vars, decl);
996 for (i = 0; i < var->n_var_parts && ret_val == VAR_INIT_STATUS_UNKNOWN; i++)
998 location_chain nextp;
999 for (nextp = var->var_part[i].loc_chain; nextp; nextp = nextp->next)
1000 if (rtx_equal_p (nextp->loc, loc))
1002 ret_val = nextp->init;
1011 /* Delete current content of register LOC in dataflow set SET and set
1012 the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). If
1013 MODIFY is true, any other live copies of the same variable part are
1014 also deleted from the dataflow set, otherwise the variable part is
1015 assumed to be copied from another location holding the same
1019 var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify,
1020 enum var_init_status initialized, rtx set_src)
1022 tree decl = REG_EXPR (loc);
1023 HOST_WIDE_INT offset = REG_OFFSET (loc);
1027 decl = var_debug_decl (decl);
1029 if (initialized == VAR_INIT_STATUS_UNKNOWN)
1030 initialized = get_init_value (set, loc, decl);
1032 nextp = &set->regs[REGNO (loc)];
1033 for (node = *nextp; node; node = next)
1036 if (node->decl != decl || node->offset != offset)
1038 delete_variable_part (set, node->loc, node->decl, node->offset);
1039 pool_free (attrs_pool, node);
1045 nextp = &node->next;
1049 clobber_variable_part (set, loc, decl, offset, set_src);
1050 var_reg_set (set, loc, initialized, set_src);
1053 /* Delete current content of register LOC in dataflow set SET. If
1054 CLOBBER is true, also delete any other live copies of the same
1058 var_reg_delete (dataflow_set *set, rtx loc, bool clobber)
1060 attrs *reg = &set->regs[REGNO (loc)];
1065 tree decl = REG_EXPR (loc);
1066 HOST_WIDE_INT offset = REG_OFFSET (loc);
1068 decl = var_debug_decl (decl);
1070 clobber_variable_part (set, NULL, decl, offset, NULL);
1073 for (node = *reg; node; node = next)
1076 delete_variable_part (set, node->loc, node->decl, node->offset);
1077 pool_free (attrs_pool, node);
1082 /* Delete content of register with number REGNO in dataflow set SET. */
1085 var_regno_delete (dataflow_set *set, int regno)
1087 attrs *reg = &set->regs[regno];
1090 for (node = *reg; node; node = next)
1093 delete_variable_part (set, node->loc, node->decl, node->offset);
1094 pool_free (attrs_pool, node);
1099 /* Set the location part of variable MEM_EXPR (LOC) in dataflow set
1101 Adjust the address first if it is stack pointer based. */
1104 var_mem_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1107 tree decl = MEM_EXPR (loc);
1108 HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
1110 decl = var_debug_decl (decl);
1112 set_variable_part (set, loc, decl, offset, initialized, set_src);
1115 /* Delete and set the location part of variable MEM_EXPR (LOC) in
1116 dataflow set SET to LOC. If MODIFY is true, any other live copies
1117 of the same variable part are also deleted from the dataflow set,
1118 otherwise the variable part is assumed to be copied from another
1119 location holding the same part.
1120 Adjust the address first if it is stack pointer based. */
1123 var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify,
1124 enum var_init_status initialized, rtx set_src)
1126 tree decl = MEM_EXPR (loc);
1127 HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
1129 decl = var_debug_decl (decl);
1131 if (initialized == VAR_INIT_STATUS_UNKNOWN)
1132 initialized = get_init_value (set, loc, decl);
1135 clobber_variable_part (set, NULL, decl, offset, set_src);
1136 var_mem_set (set, loc, initialized, set_src);
1139 /* Delete the location part LOC from dataflow set SET. If CLOBBER is
1140 true, also delete any other live copies of the same variable part.
1141 Adjust the address first if it is stack pointer based. */
1144 var_mem_delete (dataflow_set *set, rtx loc, bool clobber)
1146 tree decl = MEM_EXPR (loc);
1147 HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
1149 decl = var_debug_decl (decl);
1151 clobber_variable_part (set, NULL, decl, offset, NULL);
1152 delete_variable_part (set, loc, decl, offset);
1155 /* Initialize dataflow set SET to be empty.
1156 VARS_SIZE is the initial size of hash table VARS. */
1159 dataflow_set_init (dataflow_set *set)
1161 init_attrs_list_set (set->regs);
1162 set->vars = shared_hash_copy (empty_shared_hash);
1163 set->stack_adjust = 0;
1166 /* Delete the contents of dataflow set SET. */
1169 dataflow_set_clear (dataflow_set *set)
1173 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1174 attrs_list_clear (&set->regs[i]);
1176 shared_hash_destroy (set->vars);
1177 set->vars = shared_hash_copy (empty_shared_hash);
1180 /* Copy the contents of dataflow set SRC to DST. */
1183 dataflow_set_copy (dataflow_set *dst, dataflow_set *src)
1187 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1188 attrs_list_copy (&dst->regs[i], src->regs[i]);
1190 shared_hash_destroy (dst->vars);
1191 dst->vars = shared_hash_copy (src->vars);
1192 dst->stack_adjust = src->stack_adjust;
1195 /* Information for merging lists of locations for a given offset of variable.
1197 struct variable_union_info
1199 /* Node of the location chain. */
1202 /* The sum of positions in the input chains. */
1205 /* The position in the chains of SRC and DST dataflow sets. */
1210 /* Compare function for qsort, order the structures by POS element. */
1213 variable_union_info_cmp_pos (const void *n1, const void *n2)
1215 const struct variable_union_info *const i1 =
1216 (const struct variable_union_info *) n1;
1217 const struct variable_union_info *const i2 =
1218 ( const struct variable_union_info *) n2;
1220 if (i1->pos != i2->pos)
1221 return i1->pos - i2->pos;
1223 return (i1->pos_dst - i2->pos_dst);
1226 /* Compute union of location parts of variable *SLOT and the same variable
1227 from hash table DATA. Compute "sorted" union of the location chains
1228 for common offsets, i.e. the locations of a variable part are sorted by
1229 a priority where the priority is the sum of the positions in the 2 chains
1230 (if a location is only in one list the position in the second list is
1231 defined to be larger than the length of the chains).
1232 When we are updating the location parts the newest location is in the
1233 beginning of the chain, so when we do the described "sorted" union
1234 we keep the newest locations in the beginning. */
1237 variable_union (void **slot, void *data)
1241 dataflow_set *set = (dataflow_set *) data;
1244 src = *(variable *) slot;
1245 dstp = shared_hash_find_slot (set->vars, src->decl);
1246 if (!dstp || !*dstp)
1250 /* If CUR_LOC of some variable part is not the first element of
1251 the location chain we are going to change it so we have to make
1252 a copy of the variable. */
1253 for (k = 0; k < src->n_var_parts; k++)
1255 gcc_assert (!src->var_part[k].loc_chain
1256 == !src->var_part[k].cur_loc);
1257 if (src->var_part[k].loc_chain)
1259 gcc_assert (src->var_part[k].cur_loc);
1260 if (src->var_part[k].cur_loc != src->var_part[k].loc_chain->loc)
1264 if (k < src->n_var_parts)
1266 enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
1268 if (! flag_var_tracking_uninit)
1269 status = VAR_INIT_STATUS_INITIALIZED;
1272 *dstp = (void *) src;
1273 unshare_variable (set, src, status);
1278 dstp = shared_hash_find_slot_unshare (&set->vars, src->decl,
1280 *dstp = (void *) src;
1283 /* Continue traversing the hash table. */
1287 dst = (variable) *dstp;
1289 gcc_assert (src->n_var_parts);
1291 /* Count the number of location parts, result is K. */
1292 for (i = 0, j = 0, k = 0;
1293 i < src->n_var_parts && j < dst->n_var_parts; k++)
1295 if (src->var_part[i].offset == dst->var_part[j].offset)
1300 else if (src->var_part[i].offset < dst->var_part[j].offset)
1305 k += src->n_var_parts - i;
1306 k += dst->n_var_parts - j;
1308 /* We track only variables whose size is <= MAX_VAR_PARTS bytes
1309 thus there are at most MAX_VAR_PARTS different offsets. */
1310 gcc_assert (k <= MAX_VAR_PARTS);
1312 if ((dst->refcount > 1 || shared_hash_shared (set->vars))
1313 && dst->n_var_parts != k)
1315 enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
1317 if (! flag_var_tracking_uninit)
1318 status = VAR_INIT_STATUS_INITIALIZED;
1319 dst = unshare_variable (set, dst, status);
1322 i = src->n_var_parts - 1;
1323 j = dst->n_var_parts - 1;
1324 dst->n_var_parts = k;
1326 for (k--; k >= 0; k--)
1328 location_chain node, node2;
1330 if (i >= 0 && j >= 0
1331 && src->var_part[i].offset == dst->var_part[j].offset)
1333 /* Compute the "sorted" union of the chains, i.e. the locations which
1334 are in both chains go first, they are sorted by the sum of
1335 positions in the chains. */
1338 struct variable_union_info *vui;
1340 /* If DST is shared compare the location chains.
1341 If they are different we will modify the chain in DST with
1342 high probability so make a copy of DST. */
1343 if (dst->refcount > 1 || shared_hash_shared (set->vars))
1345 for (node = src->var_part[i].loc_chain,
1346 node2 = dst->var_part[j].loc_chain; node && node2;
1347 node = node->next, node2 = node2->next)
1349 if (!((REG_P (node2->loc)
1350 && REG_P (node->loc)
1351 && REGNO (node2->loc) == REGNO (node->loc))
1352 || rtx_equal_p (node2->loc, node->loc)))
1354 if (node2->init < node->init)
1355 node2->init = node->init;
1360 dst = unshare_variable (set, dst, VAR_INIT_STATUS_UNKNOWN);
1364 for (node = src->var_part[i].loc_chain; node; node = node->next)
1367 for (node = dst->var_part[j].loc_chain; node; node = node->next)
1369 vui = XCNEWVEC (struct variable_union_info, src_l + dst_l);
1371 /* Fill in the locations from DST. */
1372 for (node = dst->var_part[j].loc_chain, jj = 0; node;
1373 node = node->next, jj++)
1376 vui[jj].pos_dst = jj;
1378 /* Value larger than a sum of 2 valid positions. */
1379 vui[jj].pos_src = src_l + dst_l;
1382 /* Fill in the locations from SRC. */
1384 for (node = src->var_part[i].loc_chain, ii = 0; node;
1385 node = node->next, ii++)
1387 /* Find location from NODE. */
1388 for (jj = 0; jj < dst_l; jj++)
1390 if ((REG_P (vui[jj].lc->loc)
1391 && REG_P (node->loc)
1392 && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
1393 || rtx_equal_p (vui[jj].lc->loc, node->loc))
1395 vui[jj].pos_src = ii;
1399 if (jj >= dst_l) /* The location has not been found. */
1401 location_chain new_node;
1403 /* Copy the location from SRC. */
1404 new_node = (location_chain) pool_alloc (loc_chain_pool);
1405 new_node->loc = node->loc;
1406 new_node->init = node->init;
1407 if (!node->set_src || MEM_P (node->set_src))
1408 new_node->set_src = NULL;
1410 new_node->set_src = node->set_src;
1411 vui[n].lc = new_node;
1412 vui[n].pos_src = ii;
1413 vui[n].pos_dst = src_l + dst_l;
1418 for (ii = 0; ii < src_l + dst_l; ii++)
1419 vui[ii].pos = vui[ii].pos_src + vui[ii].pos_dst;
1421 qsort (vui, n, sizeof (struct variable_union_info),
1422 variable_union_info_cmp_pos);
1424 /* Reconnect the nodes in sorted order. */
1425 for (ii = 1; ii < n; ii++)
1426 vui[ii - 1].lc->next = vui[ii].lc;
1427 vui[n - 1].lc->next = NULL;
1429 dst->var_part[k].loc_chain = vui[0].lc;
1430 dst->var_part[k].offset = dst->var_part[j].offset;
1436 else if ((i >= 0 && j >= 0
1437 && src->var_part[i].offset < dst->var_part[j].offset)
1440 dst->var_part[k] = dst->var_part[j];
1443 else if ((i >= 0 && j >= 0
1444 && src->var_part[i].offset > dst->var_part[j].offset)
1447 location_chain *nextp;
1449 /* Copy the chain from SRC. */
1450 nextp = &dst->var_part[k].loc_chain;
1451 for (node = src->var_part[i].loc_chain; node; node = node->next)
1453 location_chain new_lc;
1455 new_lc = (location_chain) pool_alloc (loc_chain_pool);
1456 new_lc->next = NULL;
1457 new_lc->init = node->init;
1458 if (!node->set_src || MEM_P (node->set_src))
1459 new_lc->set_src = NULL;
1461 new_lc->set_src = node->set_src;
1462 new_lc->loc = node->loc;
1465 nextp = &new_lc->next;
1468 dst->var_part[k].offset = src->var_part[i].offset;
1472 /* We are at the basic block boundary when computing union
1473 so set the CUR_LOC to be the first element of the chain. */
1474 if (dst->var_part[k].loc_chain)
1475 dst->var_part[k].cur_loc = dst->var_part[k].loc_chain->loc;
1477 dst->var_part[k].cur_loc = NULL;
1480 for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
1482 location_chain node, node2;
1483 for (node = src->var_part[i].loc_chain; node; node = node->next)
1484 for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
1485 if (rtx_equal_p (node->loc, node2->loc))
1487 if (node->init > node2->init)
1488 node2->init = node->init;
1492 /* Continue traversing the hash table. */
1496 /* Like variable_union, but only used when doing dataflow_set_union
1497 into an empty hashtab. To allow sharing, dst is initially shared
1498 with src (so all variables are "copied" from src to dst hashtab),
1499 so only unshare_variable for variables that need canonicalization
1503 variable_canonicalize (void **slot, void *data)
1506 dataflow_set *set = (dataflow_set *) data;
1509 src = *(variable *) slot;
1511 /* If CUR_LOC of some variable part is not the first element of
1512 the location chain we are going to change it so we have to make
1513 a copy of the variable. */
1514 for (k = 0; k < src->n_var_parts; k++)
1516 gcc_assert (!src->var_part[k].loc_chain == !src->var_part[k].cur_loc);
1517 if (src->var_part[k].loc_chain)
1519 gcc_assert (src->var_part[k].cur_loc);
1520 if (src->var_part[k].cur_loc != src->var_part[k].loc_chain->loc)
1524 if (k < src->n_var_parts)
1526 enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
1528 if (! flag_var_tracking_uninit)
1529 status = VAR_INIT_STATUS_INITIALIZED;
1531 unshare_variable (set, src, status);
1536 /* Compute union of dataflow sets SRC and DST and store it to DST. */
1539 dataflow_set_union (dataflow_set *dst, dataflow_set *src)
1543 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1544 attrs_list_union (&dst->regs[i], src->regs[i]);
1546 if (dst->vars == empty_shared_hash)
1548 shared_hash_destroy (dst->vars);
1549 dst->vars = shared_hash_copy (src->vars);
1550 htab_traverse (shared_hash_htab (src->vars), variable_canonicalize, dst);
1553 htab_traverse (shared_hash_htab (src->vars), variable_union, dst);
1556 /* Flag whether two dataflow sets being compared contain different data. */
1558 dataflow_set_different_value;
1561 variable_part_different_p (variable_part *vp1, variable_part *vp2)
1563 location_chain lc1, lc2;
1565 for (lc1 = vp1->loc_chain; lc1; lc1 = lc1->next)
1567 for (lc2 = vp2->loc_chain; lc2; lc2 = lc2->next)
1569 if (REG_P (lc1->loc) && REG_P (lc2->loc))
1571 if (REGNO (lc1->loc) == REGNO (lc2->loc))
1574 if (rtx_equal_p (lc1->loc, lc2->loc))
1583 /* Return true if variables VAR1 and VAR2 are different.
1584 If COMPARE_CURRENT_LOCATION is true compare also the cur_loc of each
1588 variable_different_p (variable var1, variable var2,
1589 bool compare_current_location)
1596 if (var1->n_var_parts != var2->n_var_parts)
1599 for (i = 0; i < var1->n_var_parts; i++)
1601 if (var1->var_part[i].offset != var2->var_part[i].offset)
1603 if (compare_current_location)
1605 if (!((REG_P (var1->var_part[i].cur_loc)
1606 && REG_P (var2->var_part[i].cur_loc)
1607 && (REGNO (var1->var_part[i].cur_loc)
1608 == REGNO (var2->var_part[i].cur_loc)))
1609 || rtx_equal_p (var1->var_part[i].cur_loc,
1610 var2->var_part[i].cur_loc)))
1613 if (variable_part_different_p (&var1->var_part[i], &var2->var_part[i]))
1615 if (variable_part_different_p (&var2->var_part[i], &var1->var_part[i]))
1621 /* Compare variable *SLOT with the same variable in hash table DATA
1622 and set DATAFLOW_SET_DIFFERENT_VALUE if they are different. */
1625 dataflow_set_different_1 (void **slot, void *data)
1627 htab_t htab = (htab_t) data;
1628 variable var1, var2;
1630 var1 = *(variable *) slot;
1631 var2 = (variable) htab_find_with_hash (htab, var1->decl,
1632 VARIABLE_HASH_VAL (var1->decl));
1635 dataflow_set_different_value = true;
1637 /* Stop traversing the hash table. */
1641 if (variable_different_p (var1, var2, false))
1643 dataflow_set_different_value = true;
1645 /* Stop traversing the hash table. */
1649 /* Continue traversing the hash table. */
1653 /* Compare variable *SLOT with the same variable in hash table DATA
1654 and set DATAFLOW_SET_DIFFERENT_VALUE if they are different. */
1657 dataflow_set_different_2 (void **slot, void *data)
1659 htab_t htab = (htab_t) data;
1660 variable var1, var2;
1662 var1 = *(variable *) slot;
1663 var2 = (variable) htab_find_with_hash (htab, var1->decl,
1664 VARIABLE_HASH_VAL (var1->decl));
1667 dataflow_set_different_value = true;
1669 /* Stop traversing the hash table. */
1673 /* If both variables are defined they have been already checked for
1675 gcc_assert (!variable_different_p (var1, var2, false));
1677 /* Continue traversing the hash table. */
1681 /* Return true if dataflow sets OLD_SET and NEW_SET differ. */
1684 dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
1686 if (old_set->vars == new_set->vars)
1689 if (htab_elements (shared_hash_htab (old_set->vars))
1690 != htab_elements (shared_hash_htab (new_set->vars)))
1693 dataflow_set_different_value = false;
1695 htab_traverse (shared_hash_htab (old_set->vars), dataflow_set_different_1,
1696 shared_hash_htab (new_set->vars));
1697 if (!dataflow_set_different_value)
1699 /* We have compared the variables which are in both hash tables
1700 so now only check whether there are some variables in NEW_SET->VARS
1701 which are not in OLD_SET->VARS. */
1702 htab_traverse (shared_hash_htab (new_set->vars), dataflow_set_different_2,
1703 shared_hash_htab (old_set->vars));
1705 return dataflow_set_different_value;
1708 /* Free the contents of dataflow set SET. */
1711 dataflow_set_destroy (dataflow_set *set)
1715 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1716 attrs_list_clear (&set->regs[i]);
1718 shared_hash_destroy (set->vars);
1722 /* Return true if RTL X contains a SYMBOL_REF. */
1725 contains_symbol_ref (rtx x)
1734 code = GET_CODE (x);
1735 if (code == SYMBOL_REF)
1738 fmt = GET_RTX_FORMAT (code);
1739 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1743 if (contains_symbol_ref (XEXP (x, i)))
1746 else if (fmt[i] == 'E')
1749 for (j = 0; j < XVECLEN (x, i); j++)
1750 if (contains_symbol_ref (XVECEXP (x, i, j)))
1758 /* Shall EXPR be tracked? */
1761 track_expr_p (tree expr)
1766 /* If EXPR is not a parameter or a variable do not track it. */
1767 if (TREE_CODE (expr) != VAR_DECL && TREE_CODE (expr) != PARM_DECL)
1770 /* It also must have a name... */
1771 if (!DECL_NAME (expr))
1774 /* ... and a RTL assigned to it. */
1775 decl_rtl = DECL_RTL_IF_SET (expr);
1779 /* If this expression is really a debug alias of some other declaration, we
1780 don't need to track this expression if the ultimate declaration is
1783 if (DECL_DEBUG_EXPR_IS_FROM (realdecl) && DECL_DEBUG_EXPR (realdecl))
1785 realdecl = DECL_DEBUG_EXPR (realdecl);
1786 /* ??? We don't yet know how to emit DW_OP_piece for variable
1787 that has been SRA'ed. */
1788 if (!DECL_P (realdecl))
1792 /* Do not track EXPR if REALDECL it should be ignored for debugging
1794 if (DECL_IGNORED_P (realdecl))
1797 /* Do not track global variables until we are able to emit correct location
1799 if (TREE_STATIC (realdecl))
1802 /* When the EXPR is a DECL for alias of some variable (see example)
1803 the TREE_STATIC flag is not used. Disable tracking all DECLs whose
1804 DECL_RTL contains SYMBOL_REF.
1807 extern char **_dl_argv_internal __attribute__ ((alias ("_dl_argv")));
1810 if (MEM_P (decl_rtl)
1811 && contains_symbol_ref (XEXP (decl_rtl, 0)))
1814 /* If RTX is a memory it should not be very large (because it would be
1815 an array or struct). */
1816 if (MEM_P (decl_rtl))
1818 /* Do not track structures and arrays. */
1819 if (GET_MODE (decl_rtl) == BLKmode
1820 || AGGREGATE_TYPE_P (TREE_TYPE (realdecl)))
1822 if (MEM_SIZE (decl_rtl)
1823 && INTVAL (MEM_SIZE (decl_rtl)) > MAX_VAR_PARTS)
1830 /* Determine whether a given LOC refers to the same variable part as
1834 same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset)
1837 HOST_WIDE_INT offset2;
1839 if (! DECL_P (expr))
1844 expr2 = REG_EXPR (loc);
1845 offset2 = REG_OFFSET (loc);
1847 else if (MEM_P (loc))
1849 expr2 = MEM_EXPR (loc);
1850 offset2 = INT_MEM_OFFSET (loc);
1855 if (! expr2 || ! DECL_P (expr2))
1858 expr = var_debug_decl (expr);
1859 expr2 = var_debug_decl (expr2);
1861 return (expr == expr2 && offset == offset2);
1864 /* LOC is a REG or MEM that we would like to track if possible.
1865 If EXPR is null, we don't know what expression LOC refers to,
1866 otherwise it refers to EXPR + OFFSET. STORE_REG_P is true if
1867 LOC is an lvalue register.
1869 Return true if EXPR is nonnull and if LOC, or some lowpart of it,
1870 is something we can track. When returning true, store the mode of
1871 the lowpart we can track in *MODE_OUT (if nonnull) and its offset
1872 from EXPR in *OFFSET_OUT (if nonnull). */
1875 track_loc_p (rtx loc, tree expr, HOST_WIDE_INT offset, bool store_reg_p,
1876 enum machine_mode *mode_out, HOST_WIDE_INT *offset_out)
1878 enum machine_mode mode;
1880 if (expr == NULL || !track_expr_p (expr))
1883 /* If REG was a paradoxical subreg, its REG_ATTRS will describe the
1884 whole subreg, but only the old inner part is really relevant. */
1885 mode = GET_MODE (loc);
1886 if (REG_P (loc) && !HARD_REGISTER_NUM_P (ORIGINAL_REGNO (loc)))
1888 enum machine_mode pseudo_mode;
1890 pseudo_mode = PSEUDO_REGNO_MODE (ORIGINAL_REGNO (loc));
1891 if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (pseudo_mode))
1893 offset += byte_lowpart_offset (pseudo_mode, mode);
1898 /* If LOC is a paradoxical lowpart of EXPR, refer to EXPR itself.
1899 Do the same if we are storing to a register and EXPR occupies
1900 the whole of register LOC; in that case, the whole of EXPR is
1901 being changed. We exclude complex modes from the second case
1902 because the real and imaginary parts are represented as separate
1903 pseudo registers, even if the whole complex value fits into one
1905 if ((GET_MODE_SIZE (mode) > GET_MODE_SIZE (DECL_MODE (expr))
1907 && !COMPLEX_MODE_P (DECL_MODE (expr))
1908 && hard_regno_nregs[REGNO (loc)][DECL_MODE (expr)] == 1))
1909 && offset + byte_lowpart_offset (DECL_MODE (expr), mode) == 0)
1911 mode = DECL_MODE (expr);
1915 if (offset < 0 || offset >= MAX_VAR_PARTS)
1921 *offset_out = offset;
1925 /* Return the MODE lowpart of LOC, or null if LOC is not something we
1926 want to track. When returning nonnull, make sure that the attributes
1927 on the returned value are updated. */
1930 var_lowpart (enum machine_mode mode, rtx loc)
1932 unsigned int offset, reg_offset, regno;
1934 if (!REG_P (loc) && !MEM_P (loc))
1937 if (GET_MODE (loc) == mode)
1940 offset = byte_lowpart_offset (mode, GET_MODE (loc));
1943 return adjust_address_nv (loc, mode, offset);
1945 reg_offset = subreg_lowpart_offset (mode, GET_MODE (loc));
1946 regno = REGNO (loc) + subreg_regno_offset (REGNO (loc), GET_MODE (loc),
1948 return gen_rtx_REG_offset (loc, mode, regno, offset);
1951 /* Count uses (register and memory references) LOC which will be tracked.
1952 INSN is instruction which the LOC is part of. */
1955 count_uses (rtx *loc, void *insn)
1957 basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
1961 gcc_assert (REGNO (*loc) < FIRST_PSEUDO_REGISTER);
1964 else if (MEM_P (*loc)
1965 && track_loc_p (*loc, MEM_EXPR (*loc), INT_MEM_OFFSET (*loc),
1974 /* Helper function for finding all uses of REG/MEM in X in insn INSN. */
1977 count_uses_1 (rtx *x, void *insn)
1979 for_each_rtx (x, count_uses, insn);
1982 /* Count stores (register and memory references) LOC which will be tracked.
1983 INSN is instruction which the LOC is part of. */
1986 count_stores (rtx loc, const_rtx expr ATTRIBUTE_UNUSED, void *insn)
1988 count_uses (&loc, insn);
1991 /* Add uses (register and memory references) LOC which will be tracked
1992 to VTI (bb)->mos. INSN is instruction which the LOC is part of. */
1995 add_uses (rtx *loc, void *insn)
1997 enum machine_mode mode;
2001 basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
2002 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
2004 if (track_loc_p (*loc, REG_EXPR (*loc), REG_OFFSET (*loc),
2005 false, &mode, NULL))
2008 mo->u.loc = var_lowpart (mode, *loc);
2012 mo->type = MO_USE_NO_VAR;
2015 mo->insn = (rtx) insn;
2017 else if (MEM_P (*loc)
2018 && track_loc_p (*loc, MEM_EXPR (*loc), INT_MEM_OFFSET (*loc),
2019 false, &mode, NULL))
2021 basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
2022 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
2025 mo->u.loc = var_lowpart (mode, *loc);
2026 mo->insn = (rtx) insn;
2032 /* Helper function for finding all uses of REG/MEM in X in insn INSN. */
2035 add_uses_1 (rtx *x, void *insn)
2037 for_each_rtx (x, add_uses, insn);
2040 /* Add stores (register and memory references) LOC which will be tracked
2041 to VTI (bb)->mos. EXPR is the RTL expression containing the store.
2042 INSN is instruction which the LOC is part of. */
2045 add_stores (rtx loc, const_rtx expr, void *insn)
2047 enum machine_mode mode;
2051 basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
2052 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
2054 if (GET_CODE (expr) == CLOBBER
2055 || !track_loc_p (loc, REG_EXPR (loc), REG_OFFSET (loc),
2058 mo->type = MO_CLOBBER;
2065 if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
2066 src = var_lowpart (mode, SET_SRC (expr));
2067 loc = var_lowpart (mode, loc);
2076 if (SET_SRC (expr) != src)
2077 expr = gen_rtx_SET (VOIDmode, loc, src);
2078 if (same_variable_part_p (src, REG_EXPR (loc), REG_OFFSET (loc)))
2082 mo->u.loc = CONST_CAST_RTX (expr);
2085 mo->insn = (rtx) insn;
2087 else if (MEM_P (loc)
2088 && track_loc_p (loc, MEM_EXPR (loc), INT_MEM_OFFSET (loc),
2089 false, &mode, NULL))
2091 basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
2092 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
2094 if (GET_CODE (expr) == CLOBBER)
2096 mo->type = MO_CLOBBER;
2097 mo->u.loc = var_lowpart (mode, loc);
2103 if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
2104 src = var_lowpart (mode, SET_SRC (expr));
2105 loc = var_lowpart (mode, loc);
2114 if (SET_SRC (expr) != src)
2115 expr = gen_rtx_SET (VOIDmode, loc, src);
2116 if (same_variable_part_p (SET_SRC (expr),
2118 INT_MEM_OFFSET (loc)))
2122 mo->u.loc = CONST_CAST_RTX (expr);
2125 mo->insn = (rtx) insn;
2129 static enum var_init_status
2130 find_src_status (dataflow_set *in, rtx src)
2132 tree decl = NULL_TREE;
2133 enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
2135 if (! flag_var_tracking_uninit)
2136 status = VAR_INIT_STATUS_INITIALIZED;
2138 if (src && REG_P (src))
2139 decl = var_debug_decl (REG_EXPR (src));
2140 else if (src && MEM_P (src))
2141 decl = var_debug_decl (MEM_EXPR (src));
2144 status = get_init_value (in, src, decl);
2149 /* SRC is the source of an assignment. Use SET to try to find what
2150 was ultimately assigned to SRC. Return that value if known,
2151 otherwise return SRC itself. */
2154 find_src_set_src (dataflow_set *set, rtx src)
2156 tree decl = NULL_TREE; /* The variable being copied around. */
2157 rtx set_src = NULL_RTX; /* The value for "decl" stored in "src". */
2159 location_chain nextp;
2163 if (src && REG_P (src))
2164 decl = var_debug_decl (REG_EXPR (src));
2165 else if (src && MEM_P (src))
2166 decl = var_debug_decl (MEM_EXPR (src));
2170 var = shared_hash_find (set->vars, decl);
2174 for (i = 0; i < var->n_var_parts && !found; i++)
2175 for (nextp = var->var_part[i].loc_chain; nextp && !found;
2176 nextp = nextp->next)
2177 if (rtx_equal_p (nextp->loc, src))
2179 set_src = nextp->set_src;
2189 /* Compute the changes of variable locations in the basic block BB. */
2192 compute_bb_dataflow (basic_block bb)
2196 dataflow_set old_out;
2197 dataflow_set *in = &VTI (bb)->in;
2198 dataflow_set *out = &VTI (bb)->out;
2200 dataflow_set_init (&old_out);
2201 dataflow_set_copy (&old_out, out);
2202 dataflow_set_copy (out, in);
2204 n = VTI (bb)->n_mos;
2205 for (i = 0; i < n; i++)
2207 switch (VTI (bb)->mos[i].type)
2210 for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
2211 if (TEST_HARD_REG_BIT (call_used_reg_set, r))
2212 var_regno_delete (out, r);
2217 rtx loc = VTI (bb)->mos[i].u.loc;
2218 enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
2220 if (! flag_var_tracking_uninit)
2221 status = VAR_INIT_STATUS_INITIALIZED;
2223 if (GET_CODE (loc) == REG)
2224 var_reg_set (out, loc, status, NULL);
2225 else if (GET_CODE (loc) == MEM)
2226 var_mem_set (out, loc, status, NULL);
2232 rtx loc = VTI (bb)->mos[i].u.loc;
2235 if (GET_CODE (loc) == SET)
2237 set_src = SET_SRC (loc);
2238 loc = SET_DEST (loc);
2242 var_reg_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
2244 else if (MEM_P (loc))
2245 var_mem_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
2252 rtx loc = VTI (bb)->mos[i].u.loc;
2253 enum var_init_status src_status;
2256 if (GET_CODE (loc) == SET)
2258 set_src = SET_SRC (loc);
2259 loc = SET_DEST (loc);
2262 if (! flag_var_tracking_uninit)
2263 src_status = VAR_INIT_STATUS_INITIALIZED;
2265 src_status = find_src_status (in, set_src);
2267 if (src_status == VAR_INIT_STATUS_UNKNOWN)
2268 src_status = find_src_status (out, set_src);
2270 set_src = find_src_set_src (in, set_src);
2273 var_reg_delete_and_set (out, loc, false, src_status, set_src);
2274 else if (MEM_P (loc))
2275 var_mem_delete_and_set (out, loc, false, src_status, set_src);
2281 rtx loc = VTI (bb)->mos[i].u.loc;
2284 var_reg_delete (out, loc, false);
2285 else if (MEM_P (loc))
2286 var_mem_delete (out, loc, false);
2292 rtx loc = VTI (bb)->mos[i].u.loc;
2295 var_reg_delete (out, loc, true);
2296 else if (MEM_P (loc))
2297 var_mem_delete (out, loc, true);
2302 out->stack_adjust += VTI (bb)->mos[i].u.adjust;
2307 changed = dataflow_set_different (&old_out, out);
2308 dataflow_set_destroy (&old_out);
2312 /* Find the locations of variables in the whole function. */
2315 vt_find_locations (void)
2317 fibheap_t worklist, pending, fibheap_swap;
2318 sbitmap visited, in_worklist, in_pending, sbitmap_swap;
2325 /* Compute reverse completion order of depth first search of the CFG
2326 so that the data-flow runs faster. */
2327 rc_order = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
2328 bb_order = XNEWVEC (int, last_basic_block);
2329 pre_and_rev_post_order_compute (NULL, rc_order, false);
2330 for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
2331 bb_order[rc_order[i]] = i;
2334 worklist = fibheap_new ();
2335 pending = fibheap_new ();
2336 visited = sbitmap_alloc (last_basic_block);
2337 in_worklist = sbitmap_alloc (last_basic_block);
2338 in_pending = sbitmap_alloc (last_basic_block);
2339 sbitmap_zero (in_worklist);
2342 fibheap_insert (pending, bb_order[bb->index], bb);
2343 sbitmap_ones (in_pending);
2345 while (!fibheap_empty (pending))
2347 fibheap_swap = pending;
2349 worklist = fibheap_swap;
2350 sbitmap_swap = in_pending;
2351 in_pending = in_worklist;
2352 in_worklist = sbitmap_swap;
2354 sbitmap_zero (visited);
2356 while (!fibheap_empty (worklist))
2358 bb = (basic_block) fibheap_extract_min (worklist);
2359 RESET_BIT (in_worklist, bb->index);
2360 if (!TEST_BIT (visited, bb->index))
2365 SET_BIT (visited, bb->index);
2367 /* Calculate the IN set as union of predecessor OUT sets. */
2368 dataflow_set_clear (&VTI (bb)->in);
2369 FOR_EACH_EDGE (e, ei, bb->preds)
2371 dataflow_set_union (&VTI (bb)->in, &VTI (e->src)->out);
2374 changed = compute_bb_dataflow (bb);
2377 FOR_EACH_EDGE (e, ei, bb->succs)
2379 if (e->dest == EXIT_BLOCK_PTR)
2385 if (TEST_BIT (visited, e->dest->index))
2387 if (!TEST_BIT (in_pending, e->dest->index))
2389 /* Send E->DEST to next round. */
2390 SET_BIT (in_pending, e->dest->index);
2391 fibheap_insert (pending,
2392 bb_order[e->dest->index],
2396 else if (!TEST_BIT (in_worklist, e->dest->index))
2398 /* Add E->DEST to current round. */
2399 SET_BIT (in_worklist, e->dest->index);
2400 fibheap_insert (worklist, bb_order[e->dest->index],
2410 fibheap_delete (worklist);
2411 fibheap_delete (pending);
2412 sbitmap_free (visited);
2413 sbitmap_free (in_worklist);
2414 sbitmap_free (in_pending);
2417 /* Print the content of the LIST to dump file. */
2420 dump_attrs_list (attrs list)
2422 for (; list; list = list->next)
2424 print_mem_expr (dump_file, list->decl);
2425 fprintf (dump_file, "+" HOST_WIDE_INT_PRINT_DEC, list->offset);
2427 fprintf (dump_file, "\n");
2430 /* Print the information about variable *SLOT to dump file. */
2433 dump_variable (void **slot, void *data ATTRIBUTE_UNUSED)
2435 variable var = *(variable *) slot;
2437 location_chain node;
2439 fprintf (dump_file, " name: %s",
2440 IDENTIFIER_POINTER (DECL_NAME (var->decl)));
2441 if (dump_flags & TDF_UID)
2442 fprintf (dump_file, " D.%u\n", DECL_UID (var->decl));
2444 fprintf (dump_file, "\n");
2446 for (i = 0; i < var->n_var_parts; i++)
2448 fprintf (dump_file, " offset %ld\n",
2449 (long) var->var_part[i].offset);
2450 for (node = var->var_part[i].loc_chain; node; node = node->next)
2452 fprintf (dump_file, " ");
2453 if (node->init == VAR_INIT_STATUS_UNINITIALIZED)
2454 fprintf (dump_file, "[uninit]");
2455 print_rtl_single (dump_file, node->loc);
2459 /* Continue traversing the hash table. */
2463 /* Print the information about variables from hash table VARS to dump file. */
2466 dump_vars (htab_t vars)
2468 if (htab_elements (vars) > 0)
2470 fprintf (dump_file, "Variables:\n");
2471 htab_traverse (vars, dump_variable, NULL);
2475 /* Print the dataflow set SET to dump file. */
2478 dump_dataflow_set (dataflow_set *set)
2482 fprintf (dump_file, "Stack adjustment: " HOST_WIDE_INT_PRINT_DEC "\n",
2484 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2488 fprintf (dump_file, "Reg %d:", i);
2489 dump_attrs_list (set->regs[i]);
2492 dump_vars (shared_hash_htab (set->vars));
2493 fprintf (dump_file, "\n");
2496 /* Print the IN and OUT sets for each basic block to dump file. */
2499 dump_dataflow_sets (void)
2505 fprintf (dump_file, "\nBasic block %d:\n", bb->index);
2506 fprintf (dump_file, "IN:\n");
2507 dump_dataflow_set (&VTI (bb)->in);
2508 fprintf (dump_file, "OUT:\n");
2509 dump_dataflow_set (&VTI (bb)->out);
2513 /* Add variable VAR to the hash table of changed variables and
2514 if it has no locations delete it from SET's hash table. */
2517 variable_was_changed (variable var, dataflow_set *set)
2519 hashval_t hash = VARIABLE_HASH_VAL (var->decl);
2525 slot = (variable *) htab_find_slot_with_hash (changed_variables,
2526 var->decl, hash, INSERT);
2528 if (set && var->n_var_parts == 0)
2532 empty_var = (variable) pool_alloc (var_pool);
2533 empty_var->decl = var->decl;
2534 empty_var->refcount = 1;
2535 empty_var->n_var_parts = 0;
2548 if (var->n_var_parts == 0)
2553 slot = shared_hash_find_slot_noinsert (set->vars, var->decl);
2556 if (shared_hash_shared (set->vars))
2557 slot = shared_hash_find_slot_unshare (&set->vars, var->decl,
2559 htab_clear_slot (shared_hash_htab (set->vars), slot);
2565 /* Look for the index in VAR->var_part corresponding to OFFSET.
2566 Return -1 if not found. If INSERTION_POINT is non-NULL, the
2567 referenced int will be set to the index that the part has or should
2568 have, if it should be inserted. */
2571 find_variable_location_part (variable var, HOST_WIDE_INT offset,
2572 int *insertion_point)
2576 /* Find the location part. */
2578 high = var->n_var_parts;
2581 pos = (low + high) / 2;
2582 if (var->var_part[pos].offset < offset)
2589 if (insertion_point)
2590 *insertion_point = pos;
2592 if (pos < var->n_var_parts && var->var_part[pos].offset == offset)
2598 /* Set the part of variable's location in the dataflow set SET. The variable
2599 part is specified by variable's declaration DECL and offset OFFSET and the
2600 part's location by LOC. */
2603 set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset,
2604 enum var_init_status initialized, rtx set_src)
2607 location_chain node, next;
2608 location_chain *nextp;
2610 void **slot = shared_hash_find_slot (set->vars, decl);
2612 if (!slot || !*slot)
2615 slot = shared_hash_find_slot_unshare (&set->vars, decl, INSERT);
2616 /* Create new variable information. */
2617 var = (variable) pool_alloc (var_pool);
2620 var->n_var_parts = 1;
2621 var->var_part[0].offset = offset;
2622 var->var_part[0].loc_chain = NULL;
2623 var->var_part[0].cur_loc = NULL;
2631 var = (variable) *slot;
2633 pos = find_variable_location_part (var, offset, &inspos);
2637 node = var->var_part[pos].loc_chain;
2640 && ((REG_P (node->loc) && REG_P (loc)
2641 && REGNO (node->loc) == REGNO (loc))
2642 || rtx_equal_p (node->loc, loc)))
2644 /* LOC is in the beginning of the chain so we have nothing
2646 if (node->init < initialized)
2647 node->init = initialized;
2648 if (set_src != NULL)
2649 node->set_src = set_src;
2655 /* We have to make a copy of a shared variable. */
2656 if (var->refcount > 1 || shared_hash_shared (set->vars))
2657 var = unshare_variable (set, var, initialized);
2662 /* We have not found the location part, new one will be created. */
2664 /* We have to make a copy of the shared variable. */
2665 if (var->refcount > 1 || shared_hash_shared (set->vars))
2666 var = unshare_variable (set, var, initialized);
2668 /* We track only variables whose size is <= MAX_VAR_PARTS bytes
2669 thus there are at most MAX_VAR_PARTS different offsets. */
2670 gcc_assert (var->n_var_parts < MAX_VAR_PARTS);
2672 /* We have to move the elements of array starting at index
2673 inspos to the next position. */
2674 for (pos = var->n_var_parts; pos > inspos; pos--)
2675 var->var_part[pos] = var->var_part[pos - 1];
2678 var->var_part[pos].offset = offset;
2679 var->var_part[pos].loc_chain = NULL;
2680 var->var_part[pos].cur_loc = NULL;
2684 /* Delete the location from the list. */
2685 nextp = &var->var_part[pos].loc_chain;
2686 for (node = var->var_part[pos].loc_chain; node; node = next)
2689 if ((REG_P (node->loc) && REG_P (loc)
2690 && REGNO (node->loc) == REGNO (loc))
2691 || rtx_equal_p (node->loc, loc))
2693 /* Save these values, to assign to the new node, before
2694 deleting this one. */
2695 if (node->init > initialized)
2696 initialized = node->init;
2697 if (node->set_src != NULL && set_src == NULL)
2698 set_src = node->set_src;
2699 pool_free (loc_chain_pool, node);
2704 nextp = &node->next;
2707 /* Add the location to the beginning. */
2708 node = (location_chain) pool_alloc (loc_chain_pool);
2710 node->init = initialized;
2711 node->set_src = set_src;
2712 node->next = var->var_part[pos].loc_chain;
2713 var->var_part[pos].loc_chain = node;
2715 /* If no location was emitted do so. */
2716 if (var->var_part[pos].cur_loc == NULL)
2718 var->var_part[pos].cur_loc = loc;
2719 variable_was_changed (var, set);
2723 /* Remove all recorded register locations for the given variable part
2724 from dataflow set SET, except for those that are identical to loc.
2725 The variable part is specified by variable's declaration DECL and
2729 clobber_variable_part (dataflow_set *set, rtx loc, tree decl,
2730 HOST_WIDE_INT offset, rtx set_src)
2734 if (! decl || ! DECL_P (decl))
2737 var = shared_hash_find (set->vars, decl);
2740 int pos = find_variable_location_part (var, offset, NULL);
2744 location_chain node, next;
2746 /* Remove the register locations from the dataflow set. */
2747 next = var->var_part[pos].loc_chain;
2748 for (node = next; node; node = next)
2751 if (node->loc != loc
2752 && (!flag_var_tracking_uninit
2755 || !rtx_equal_p (set_src, node->set_src)))
2757 if (REG_P (node->loc))
2762 /* Remove the variable part from the register's
2763 list, but preserve any other variable parts
2764 that might be regarded as live in that same
2766 anextp = &set->regs[REGNO (node->loc)];
2767 for (anode = *anextp; anode; anode = anext)
2769 anext = anode->next;
2770 if (anode->decl == decl
2771 && anode->offset == offset)
2773 pool_free (attrs_pool, anode);
2777 anextp = &anode->next;
2781 delete_variable_part (set, node->loc, decl, offset);
2788 /* Delete the part of variable's location from dataflow set SET. The variable
2789 part is specified by variable's declaration DECL and offset OFFSET and the
2790 part's location by LOC. */
2793 delete_variable_part (dataflow_set *set, rtx loc, tree decl,
2794 HOST_WIDE_INT offset)
2796 variable var = shared_hash_find (set->vars, decl);;
2799 int pos = find_variable_location_part (var, offset, NULL);
2803 location_chain node, next;
2804 location_chain *nextp;
2807 if (var->refcount > 1 || shared_hash_shared (set->vars))
2809 /* If the variable contains the location part we have to
2810 make a copy of the variable. */
2811 for (node = var->var_part[pos].loc_chain; node;
2814 if ((REG_P (node->loc) && REG_P (loc)
2815 && REGNO (node->loc) == REGNO (loc))
2816 || rtx_equal_p (node->loc, loc))
2818 enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
2819 if (! flag_var_tracking_uninit)
2820 status = VAR_INIT_STATUS_INITIALIZED;
2821 var = unshare_variable (set, var, status);
2827 /* Delete the location part. */
2828 nextp = &var->var_part[pos].loc_chain;
2829 for (node = *nextp; node; node = next)
2832 if ((REG_P (node->loc) && REG_P (loc)
2833 && REGNO (node->loc) == REGNO (loc))
2834 || rtx_equal_p (node->loc, loc))
2836 pool_free (loc_chain_pool, node);
2841 nextp = &node->next;
2844 /* If we have deleted the location which was last emitted
2845 we have to emit new location so add the variable to set
2846 of changed variables. */
2847 if (var->var_part[pos].cur_loc
2849 && REG_P (var->var_part[pos].cur_loc)
2850 && REGNO (loc) == REGNO (var->var_part[pos].cur_loc))
2851 || rtx_equal_p (loc, var->var_part[pos].cur_loc)))
2854 if (var->var_part[pos].loc_chain)
2855 var->var_part[pos].cur_loc = var->var_part[pos].loc_chain->loc;
2860 if (var->var_part[pos].loc_chain == NULL)
2863 while (pos < var->n_var_parts)
2865 var->var_part[pos] = var->var_part[pos + 1];
2870 variable_was_changed (var, set);
2875 /* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP. DATA contains
2876 additional parameters: WHERE specifies whether the note shall be emitted
2877 before of after instruction INSN. */
2880 emit_note_insn_var_location (void **varp, void *data)
2882 variable var = *(variable *) varp;
2883 rtx insn = ((emit_note_data *)data)->insn;
2884 enum emit_note_where where = ((emit_note_data *)data)->where;
2886 int i, j, n_var_parts;
2888 enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED;
2889 HOST_WIDE_INT last_limit;
2890 tree type_size_unit;
2891 HOST_WIDE_INT offsets[MAX_VAR_PARTS];
2892 rtx loc[MAX_VAR_PARTS];
2894 gcc_assert (var->decl);
2896 if (! flag_var_tracking_uninit)
2897 initialized = VAR_INIT_STATUS_INITIALIZED;
2902 for (i = 0; i < var->n_var_parts; i++)
2904 enum machine_mode mode, wider_mode;
2906 if (last_limit < var->var_part[i].offset)
2911 else if (last_limit > var->var_part[i].offset)
2913 offsets[n_var_parts] = var->var_part[i].offset;
2914 loc[n_var_parts] = var->var_part[i].loc_chain->loc;
2915 mode = GET_MODE (loc[n_var_parts]);
2916 initialized = var->var_part[i].loc_chain->init;
2917 last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
2919 /* Attempt to merge adjacent registers or memory. */
2920 wider_mode = GET_MODE_WIDER_MODE (mode);
2921 for (j = i + 1; j < var->n_var_parts; j++)
2922 if (last_limit <= var->var_part[j].offset)
2924 if (j < var->n_var_parts
2925 && wider_mode != VOIDmode
2926 && GET_CODE (loc[n_var_parts])
2927 == GET_CODE (var->var_part[j].loc_chain->loc)
2928 && mode == GET_MODE (var->var_part[j].loc_chain->loc)
2929 && last_limit == var->var_part[j].offset)
2932 rtx loc2 = var->var_part[j].loc_chain->loc;
2934 if (REG_P (loc[n_var_parts])
2935 && hard_regno_nregs[REGNO (loc[n_var_parts])][mode] * 2
2936 == hard_regno_nregs[REGNO (loc[n_var_parts])][wider_mode]
2937 && end_hard_regno (mode, REGNO (loc[n_var_parts]))
2940 if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
2941 new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
2943 else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
2944 new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
2947 if (!REG_P (new_loc)
2948 || REGNO (new_loc) != REGNO (loc[n_var_parts]))
2951 REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
2954 else if (MEM_P (loc[n_var_parts])
2955 && GET_CODE (XEXP (loc2, 0)) == PLUS
2956 && GET_CODE (XEXP (XEXP (loc2, 0), 0)) == REG
2957 && GET_CODE (XEXP (XEXP (loc2, 0), 1)) == CONST_INT)
2959 if ((GET_CODE (XEXP (loc[n_var_parts], 0)) == REG
2960 && rtx_equal_p (XEXP (loc[n_var_parts], 0),
2961 XEXP (XEXP (loc2, 0), 0))
2962 && INTVAL (XEXP (XEXP (loc2, 0), 1))
2963 == GET_MODE_SIZE (mode))
2964 || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
2965 && GET_CODE (XEXP (XEXP (loc[n_var_parts], 0), 1))
2967 && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
2968 XEXP (XEXP (loc2, 0), 0))
2969 && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
2970 + GET_MODE_SIZE (mode)
2971 == INTVAL (XEXP (XEXP (loc2, 0), 1))))
2972 new_loc = adjust_address_nv (loc[n_var_parts],
2978 loc[n_var_parts] = new_loc;
2980 last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
2986 type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (var->decl));
2987 if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
2990 if (where == EMIT_NOTE_AFTER_INSN)
2991 note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
2993 note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
2995 if (! flag_var_tracking_uninit)
2996 initialized = VAR_INIT_STATUS_INITIALIZED;
3000 NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
3001 NULL_RTX, (int) initialized);
3003 else if (n_var_parts == 1)
3006 = gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
3008 NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
3012 else if (n_var_parts)
3016 for (i = 0; i < n_var_parts; i++)
3018 = gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));
3020 parallel = gen_rtx_PARALLEL (VOIDmode,
3021 gen_rtvec_v (n_var_parts, loc));
3022 NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
3027 htab_clear_slot (changed_variables, varp);
3029 /* Continue traversing the hash table. */
3033 /* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
3034 CHANGED_VARIABLES and delete this chain. WHERE specifies whether the notes
3035 shall be emitted before of after instruction INSN. */
3038 emit_notes_for_changes (rtx insn, enum emit_note_where where)
3040 emit_note_data data;
3044 htab_traverse (changed_variables, emit_note_insn_var_location, &data);
3047 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
3048 same variable in hash table DATA or is not there at all. */
3051 emit_notes_for_differences_1 (void **slot, void *data)
3053 htab_t new_vars = (htab_t) data;
3054 variable old_var, new_var;
3056 old_var = *(variable *) slot;
3057 new_var = (variable) htab_find_with_hash (new_vars, old_var->decl,
3058 VARIABLE_HASH_VAL (old_var->decl));
3062 /* Variable has disappeared. */
3065 empty_var = (variable) pool_alloc (var_pool);
3066 empty_var->decl = old_var->decl;
3067 empty_var->refcount = 0;
3068 empty_var->n_var_parts = 0;
3069 variable_was_changed (empty_var, NULL);
3071 else if (variable_different_p (old_var, new_var, true))
3073 variable_was_changed (new_var, NULL);
3076 /* Continue traversing the hash table. */
3080 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
3084 emit_notes_for_differences_2 (void **slot, void *data)
3086 htab_t old_vars = (htab_t) data;
3087 variable old_var, new_var;
3089 new_var = *(variable *) slot;
3090 old_var = (variable) htab_find_with_hash (old_vars, new_var->decl,
3091 VARIABLE_HASH_VAL (new_var->decl));
3094 /* Variable has appeared. */
3095 variable_was_changed (new_var, NULL);
3098 /* Continue traversing the hash table. */
3102 /* Emit notes before INSN for differences between dataflow sets OLD_SET and
3106 emit_notes_for_differences (rtx insn, dataflow_set *old_set,
3107 dataflow_set *new_set)
3109 htab_traverse (shared_hash_htab (old_set->vars),
3110 emit_notes_for_differences_1,
3111 shared_hash_htab (new_set->vars));
3112 htab_traverse (shared_hash_htab (new_set->vars),
3113 emit_notes_for_differences_2,
3114 shared_hash_htab (old_set->vars));
3115 emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
3118 /* Emit the notes for changes of location parts in the basic block BB. */
3121 emit_notes_in_bb (basic_block bb)
3126 dataflow_set_init (&set);
3127 dataflow_set_copy (&set, &VTI (bb)->in);
3129 for (i = 0; i < VTI (bb)->n_mos; i++)
3131 rtx insn = VTI (bb)->mos[i].insn;
3133 switch (VTI (bb)->mos[i].type)
3139 for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
3140 if (TEST_HARD_REG_BIT (call_used_reg_set, r))
3142 var_regno_delete (&set, r);
3144 emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
3150 rtx loc = VTI (bb)->mos[i].u.loc;
3152 enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
3153 if (! flag_var_tracking_uninit)
3154 status = VAR_INIT_STATUS_INITIALIZED;
3155 if (GET_CODE (loc) == REG)
3156 var_reg_set (&set, loc, status, NULL);
3158 var_mem_set (&set, loc, status, NULL);
3160 emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
3166 rtx loc = VTI (bb)->mos[i].u.loc;
3169 if (GET_CODE (loc) == SET)
3171 set_src = SET_SRC (loc);
3172 loc = SET_DEST (loc);
3176 var_reg_delete_and_set (&set, loc, true, VAR_INIT_STATUS_INITIALIZED,
3179 var_mem_delete_and_set (&set, loc, true, VAR_INIT_STATUS_INITIALIZED,
3182 emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN);
3188 rtx loc = VTI (bb)->mos[i].u.loc;
3189 enum var_init_status src_status;
3192 if (GET_CODE (loc) == SET)
3194 set_src = SET_SRC (loc);
3195 loc = SET_DEST (loc);
3198 src_status = find_src_status (&set, set_src);
3199 set_src = find_src_set_src (&set, set_src);
3202 var_reg_delete_and_set (&set, loc, false, src_status, set_src);
3204 var_mem_delete_and_set (&set, loc, false, src_status, set_src);
3206 emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN);
3212 rtx loc = VTI (bb)->mos[i].u.loc;
3215 var_reg_delete (&set, loc, false);
3217 var_mem_delete (&set, loc, false);
3219 emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
3225 rtx loc = VTI (bb)->mos[i].u.loc;
3228 var_reg_delete (&set, loc, true);
3230 var_mem_delete (&set, loc, true);
3232 emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN);
3237 set.stack_adjust += VTI (bb)->mos[i].u.adjust;
3241 dataflow_set_destroy (&set);
3244 /* Emit notes for the whole function. */
3247 vt_emit_notes (void)
3250 dataflow_set *last_out;
3253 gcc_assert (!htab_elements (changed_variables));
3255 /* Enable emitting notes by functions (mainly by set_variable_part and
3256 delete_variable_part). */
3259 dataflow_set_init (&empty);
3264 /* Emit the notes for changes of variable locations between two
3265 subsequent basic blocks. */
3266 emit_notes_for_differences (BB_HEAD (bb), last_out, &VTI (bb)->in);
3268 /* Emit the notes for the changes in the basic block itself. */
3269 emit_notes_in_bb (bb);
3271 last_out = &VTI (bb)->out;
3273 dataflow_set_destroy (&empty);
3277 /* If there is a declaration and offset associated with register/memory RTL
3278 assign declaration to *DECLP and offset to *OFFSETP, and return true. */
3281 vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
3285 if (REG_ATTRS (rtl))
3287 *declp = REG_EXPR (rtl);
3288 *offsetp = REG_OFFSET (rtl);
3292 else if (MEM_P (rtl))
3294 if (MEM_ATTRS (rtl))
3296 *declp = MEM_EXPR (rtl);
3297 *offsetp = INT_MEM_OFFSET (rtl);
3304 /* Insert function parameters to IN and OUT sets of ENTRY_BLOCK. */
3307 vt_add_function_parameters (void)
3311 for (parm = DECL_ARGUMENTS (current_function_decl);
3312 parm; parm = TREE_CHAIN (parm))
3314 rtx decl_rtl = DECL_RTL_IF_SET (parm);
3315 rtx incoming = DECL_INCOMING_RTL (parm);
3317 enum machine_mode mode;
3318 HOST_WIDE_INT offset;
3321 if (TREE_CODE (parm) != PARM_DECL)
3324 if (!DECL_NAME (parm))
3327 if (!decl_rtl || !incoming)
3330 if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
3333 if (!vt_get_decl_and_offset (incoming, &decl, &offset))
3335 if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
3337 offset += byte_lowpart_offset (GET_MODE (incoming),
3338 GET_MODE (decl_rtl));
3346 /* Assume that DECL_RTL was a pseudo that got spilled to
3347 memory. The spill slot sharing code will force the
3348 memory to reference spill_slot_decl (%sfp), so we don't
3349 match above. That's ok, the pseudo must have referenced
3350 the entire parameter, so just reset OFFSET. */
3351 gcc_assert (decl == get_spill_slot_decl (false));
3355 if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
3358 out = &VTI (ENTRY_BLOCK_PTR)->out;
3360 if (REG_P (incoming))
3362 incoming = var_lowpart (mode, incoming);
3363 gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
3364 attrs_list_insert (&out->regs[REGNO (incoming)],
3365 parm, offset, incoming);
3366 set_variable_part (out, incoming, parm, offset, VAR_INIT_STATUS_INITIALIZED,
3369 else if (MEM_P (incoming))
3371 incoming = var_lowpart (mode, incoming);
3372 set_variable_part (out, incoming, parm, offset,
3373 VAR_INIT_STATUS_INITIALIZED, NULL);
3378 /* Allocate and initialize the data structures for variable tracking
3379 and parse the RTL to get the micro operations. */
3382 vt_initialize (void)
3386 alloc_aux_for_blocks (sizeof (struct variable_tracking_info_def));
3391 HOST_WIDE_INT pre, post = 0;
3393 /* Count the number of micro operations. */
3394 VTI (bb)->n_mos = 0;
3395 for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
3396 insn = NEXT_INSN (insn))
3400 if (!frame_pointer_needed)
3402 insn_stack_adjust_offset_pre_post (insn, &pre, &post);
3408 note_uses (&PATTERN (insn), count_uses_1, insn);
3409 note_stores (PATTERN (insn), count_stores, insn);
3415 /* Add the micro-operations to the array. */
3416 VTI (bb)->mos = XNEWVEC (micro_operation, VTI (bb)->n_mos);
3417 VTI (bb)->n_mos = 0;
3418 for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
3419 insn = NEXT_INSN (insn))
3425 if (!frame_pointer_needed)
3427 insn_stack_adjust_offset_pre_post (insn, &pre, &post);
3430 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
3432 mo->type = MO_ADJUST;
3438 n1 = VTI (bb)->n_mos;
3439 note_uses (&PATTERN (insn), add_uses_1, insn);
3440 n2 = VTI (bb)->n_mos - 1;
3442 /* Order the MO_USEs to be before MO_USE_NO_VARs. */
3445 while (n1 < n2 && VTI (bb)->mos[n1].type == MO_USE)
3447 while (n1 < n2 && VTI (bb)->mos[n2].type == MO_USE_NO_VAR)
3453 sw = VTI (bb)->mos[n1];
3454 VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
3455 VTI (bb)->mos[n2] = sw;
3461 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
3467 n1 = VTI (bb)->n_mos;
3468 /* This will record NEXT_INSN (insn), such that we can
3469 insert notes before it without worrying about any
3470 notes that MO_USEs might emit after the insn. */
3471 note_stores (PATTERN (insn), add_stores, insn);
3472 n2 = VTI (bb)->n_mos - 1;
3474 /* Order the MO_CLOBBERs to be before MO_SETs. */
3477 while (n1 < n2 && VTI (bb)->mos[n1].type == MO_CLOBBER)
3479 while (n1 < n2 && (VTI (bb)->mos[n2].type == MO_SET
3480 || VTI (bb)->mos[n2].type == MO_COPY))
3486 sw = VTI (bb)->mos[n1];
3487 VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
3488 VTI (bb)->mos[n2] = sw;
3492 if (!frame_pointer_needed && post)
3494 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
3496 mo->type = MO_ADJUST;
3497 mo->u.adjust = post;
3504 attrs_pool = create_alloc_pool ("attrs_def pool",
3505 sizeof (struct attrs_def), 1024);
3506 var_pool = create_alloc_pool ("variable_def pool",
3507 sizeof (struct variable_def), 64);
3508 loc_chain_pool = create_alloc_pool ("location_chain_def pool",
3509 sizeof (struct location_chain_def),
3511 shared_hash_pool = create_alloc_pool ("shared_hash_def pool",
3512 sizeof (struct shared_hash_def), 256);
3513 empty_shared_hash = (shared_hash) pool_alloc (shared_hash_pool);
3514 empty_shared_hash->refcount = 1;
3515 empty_shared_hash->htab
3516 = htab_create (1, variable_htab_hash, variable_htab_eq,
3517 variable_htab_free);
3518 changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
3519 variable_htab_free);
3521 /* Init the IN and OUT sets. */
3524 VTI (bb)->visited = false;
3525 dataflow_set_init (&VTI (bb)->in);
3526 dataflow_set_init (&VTI (bb)->out);
3529 vt_add_function_parameters ();
3532 /* Free the data structures needed for variable tracking. */
3541 free (VTI (bb)->mos);
3546 dataflow_set_destroy (&VTI (bb)->in);
3547 dataflow_set_destroy (&VTI (bb)->out);
3549 free_aux_for_blocks ();
3550 htab_delete (empty_shared_hash->htab);
3551 htab_delete (changed_variables);
3552 free_alloc_pool (attrs_pool);
3553 free_alloc_pool (var_pool);
3554 free_alloc_pool (loc_chain_pool);
3555 free_alloc_pool (shared_hash_pool);
3558 /* The entry point to variable tracking pass. */
3561 variable_tracking_main (void)
3563 if (n_basic_blocks > 500 && n_edges / n_basic_blocks >= 20)
3566 mark_dfs_back_edges ();
3568 if (!frame_pointer_needed)
3570 if (!vt_stack_adjustments ())
3577 vt_find_locations ();
3580 if (dump_file && (dump_flags & TDF_DETAILS))
3582 dump_dataflow_sets ();
3583 dump_flow_info (dump_file, dump_flags);
3591 gate_handle_var_tracking (void)
3593 return (flag_var_tracking);
3598 struct rtl_opt_pass pass_variable_tracking =
3602 "vartrack", /* name */
3603 gate_handle_var_tracking, /* gate */
3604 variable_tracking_main, /* execute */
3607 0, /* static_pass_number */
3608 TV_VAR_TRACKING, /* tv_id */
3609 0, /* properties_required */
3610 0, /* properties_provided */
3611 0, /* properties_destroyed */
3612 0, /* todo_flags_start */
3613 TODO_dump_func | TODO_verify_rtl_sharing/* todo_flags_finish */