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"
112 /* Type of micro operation. */
113 enum micro_operation_type
115 MO_USE, /* Use location (REG or MEM). */
116 MO_USE_NO_VAR,/* Use location which is not associated with a variable
117 or the variable is not trackable. */
118 MO_VAL_USE, /* Use location which is associated with a value. */
119 MO_VAL_LOC, /* Use location which appears in a debug insn. */
120 MO_VAL_SET, /* Set location associated with a value. */
121 MO_SET, /* Set location. */
122 MO_COPY, /* Copy the same portion of a variable from one
123 location to another. */
124 MO_CLOBBER, /* Clobber location. */
125 MO_CALL, /* Call insn. */
126 MO_ADJUST /* Adjust stack pointer. */
130 static const char * const ATTRIBUTE_UNUSED
131 micro_operation_type_name[] = {
144 /* Where shall the note be emitted? BEFORE or AFTER the instruction.
145 Notes emitted as AFTER_CALL are to take effect during the call,
146 rather than after the call. */
149 EMIT_NOTE_BEFORE_INSN,
150 EMIT_NOTE_AFTER_INSN,
151 EMIT_NOTE_AFTER_CALL_INSN
154 /* Structure holding information about micro operation. */
155 typedef struct micro_operation_def
157 /* Type of micro operation. */
158 enum micro_operation_type type;
161 /* Location. For MO_SET and MO_COPY, this is the SET that
162 performs the assignment, if known, otherwise it is the target
163 of the assignment. For MO_VAL_USE and MO_VAL_SET, it is a
164 CONCAT of the VALUE and the LOC associated with it. For
165 MO_VAL_LOC, it is a CONCAT of the VALUE and the VAR_LOCATION
166 associated with it. */
169 /* Stack adjustment. */
170 HOST_WIDE_INT adjust;
173 /* The instruction which the micro operation is in, for MO_USE,
174 MO_USE_NO_VAR, MO_CALL and MO_ADJUST, or the subsequent
175 instruction or note in the original flow (before any var-tracking
176 notes are inserted, to simplify emission of notes), for MO_SET
181 /* A declaration of a variable, or an RTL value being handled like a
183 typedef void *decl_or_value;
185 /* Structure for passing some other parameters to function
186 emit_note_insn_var_location. */
187 typedef struct emit_note_data_def
189 /* The instruction which the note will be emitted before/after. */
192 /* Where the note will be emitted (before/after insn)? */
193 enum emit_note_where where;
195 /* The variables and values active at this point. */
199 /* Description of location of a part of a variable. The content of a physical
200 register is described by a chain of these structures.
201 The chains are pretty short (usually 1 or 2 elements) and thus
202 chain is the best data structure. */
203 typedef struct attrs_def
205 /* Pointer to next member of the list. */
206 struct attrs_def *next;
208 /* The rtx of register. */
211 /* The declaration corresponding to LOC. */
214 /* Offset from start of DECL. */
215 HOST_WIDE_INT offset;
218 /* Structure holding a refcounted hash table. If refcount > 1,
219 it must be first unshared before modified. */
220 typedef struct shared_hash_def
222 /* Reference count. */
225 /* Actual hash table. */
229 /* Structure holding the IN or OUT set for a basic block. */
230 typedef struct dataflow_set_def
232 /* Adjustment of stack offset. */
233 HOST_WIDE_INT stack_adjust;
235 /* Attributes for registers (lists of attrs). */
236 attrs regs[FIRST_PSEUDO_REGISTER];
238 /* Variable locations. */
241 /* Vars that is being traversed. */
242 shared_hash traversed_vars;
245 /* The structure (one for each basic block) containing the information
246 needed for variable tracking. */
247 typedef struct variable_tracking_info_def
249 /* Number of micro operations stored in the MOS array. */
252 /* The array of micro operations. */
253 micro_operation *mos;
255 /* The IN and OUT set for dataflow analysis. */
259 /* The permanent-in dataflow set for this block. This is used to
260 hold values for which we had to compute entry values. ??? This
261 should probably be dynamically allocated, to avoid using more
262 memory in non-debug builds. */
265 /* Has the block been visited in DFS? */
268 /* Has the block been flooded in VTA? */
271 } *variable_tracking_info;
273 /* Structure for chaining the locations. */
274 typedef struct location_chain_def
276 /* Next element in the chain. */
277 struct location_chain_def *next;
279 /* The location (REG, MEM or VALUE). */
282 /* The "value" stored in this location. */
286 enum var_init_status init;
289 /* Structure describing one part of variable. */
290 typedef struct variable_part_def
292 /* Chain of locations of the part. */
293 location_chain loc_chain;
295 /* Location which was last emitted to location list. */
298 /* The offset in the variable. */
299 HOST_WIDE_INT offset;
302 /* Maximum number of location parts. */
303 #define MAX_VAR_PARTS 16
305 /* Structure describing where the variable is located. */
306 typedef struct variable_def
308 /* The declaration of the variable, or an RTL value being handled
309 like a declaration. */
312 /* Reference count. */
315 /* Number of variable parts. */
318 /* The variable parts. */
319 variable_part var_part[1];
321 typedef const struct variable_def *const_variable;
323 /* Structure for chaining backlinks from referenced VALUEs to
324 DVs that are referencing them. */
325 typedef struct value_chain_def
327 /* Next value_chain entry. */
328 struct value_chain_def *next;
330 /* The declaration of the variable, or an RTL value
331 being handled like a declaration, whose var_parts[0].loc_chain
332 references the VALUE owning this value_chain. */
335 /* Reference count. */
338 typedef const struct value_chain_def *const_value_chain;
340 /* Hash function for DECL for VARIABLE_HTAB. */
341 #define VARIABLE_HASH_VAL(decl) (DECL_UID (decl))
343 /* Pointer to the BB's information specific to variable tracking pass. */
344 #define VTI(BB) ((variable_tracking_info) (BB)->aux)
346 /* Macro to access MEM_OFFSET as an HOST_WIDE_INT. Evaluates MEM twice. */
347 #define INT_MEM_OFFSET(mem) (MEM_OFFSET (mem) ? INTVAL (MEM_OFFSET (mem)) : 0)
349 /* Alloc pool for struct attrs_def. */
350 static alloc_pool attrs_pool;
352 /* Alloc pool for struct variable_def with MAX_VAR_PARTS entries. */
353 static alloc_pool var_pool;
355 /* Alloc pool for struct variable_def with a single var_part entry. */
356 static alloc_pool valvar_pool;
358 /* Alloc pool for struct location_chain_def. */
359 static alloc_pool loc_chain_pool;
361 /* Alloc pool for struct shared_hash_def. */
362 static alloc_pool shared_hash_pool;
364 /* Alloc pool for struct value_chain_def. */
365 static alloc_pool value_chain_pool;
367 /* Changed variables, notes will be emitted for them. */
368 static htab_t changed_variables;
370 /* Links from VALUEs to DVs referencing them in their current loc_chains. */
371 static htab_t value_chains;
373 /* Shall notes be emitted? */
374 static bool emit_notes;
376 /* Empty shared hashtable. */
377 static shared_hash empty_shared_hash;
379 /* Scratch register bitmap used by cselib_expand_value_rtx. */
380 static bitmap scratch_regs = NULL;
382 /* Variable used to tell whether cselib_process_insn called our hook. */
383 static bool cselib_hook_called;
385 /* Local function prototypes. */
386 static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
388 static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
390 static void bb_stack_adjust_offset (basic_block);
391 static bool vt_stack_adjustments (void);
392 static rtx adjust_stack_reference (rtx, HOST_WIDE_INT);
393 static hashval_t variable_htab_hash (const void *);
394 static int variable_htab_eq (const void *, const void *);
395 static void variable_htab_free (void *);
397 static void init_attrs_list_set (attrs *);
398 static void attrs_list_clear (attrs *);
399 static attrs attrs_list_member (attrs, decl_or_value, HOST_WIDE_INT);
400 static void attrs_list_insert (attrs *, decl_or_value, HOST_WIDE_INT, rtx);
401 static void attrs_list_copy (attrs *, attrs);
402 static void attrs_list_union (attrs *, attrs);
404 static void **unshare_variable (dataflow_set *set, void **slot, variable var,
405 enum var_init_status);
406 static int vars_copy_1 (void **, void *);
407 static void vars_copy (htab_t, htab_t);
408 static tree var_debug_decl (tree);
409 static void var_reg_set (dataflow_set *, rtx, enum var_init_status, rtx);
410 static void var_reg_delete_and_set (dataflow_set *, rtx, bool,
411 enum var_init_status, rtx);
412 static void var_reg_delete (dataflow_set *, rtx, bool);
413 static void var_regno_delete (dataflow_set *, int);
414 static void var_mem_set (dataflow_set *, rtx, enum var_init_status, rtx);
415 static void var_mem_delete_and_set (dataflow_set *, rtx, bool,
416 enum var_init_status, rtx);
417 static void var_mem_delete (dataflow_set *, rtx, bool);
419 static void dataflow_set_init (dataflow_set *);
420 static void dataflow_set_clear (dataflow_set *);
421 static void dataflow_set_copy (dataflow_set *, dataflow_set *);
422 static int variable_union_info_cmp_pos (const void *, const void *);
423 static int variable_union (void **, void *);
424 static int variable_canonicalize (void **, void *);
425 static void dataflow_set_union (dataflow_set *, dataflow_set *);
426 static location_chain find_loc_in_1pdv (rtx, variable, htab_t);
427 static bool canon_value_cmp (rtx, rtx);
428 static int loc_cmp (rtx, rtx);
429 static bool variable_part_different_p (variable_part *, variable_part *);
430 static bool onepart_variable_different_p (variable, variable);
431 static bool variable_different_p (variable, variable, bool);
432 static int dataflow_set_different_1 (void **, void *);
433 static bool dataflow_set_different (dataflow_set *, dataflow_set *);
434 static void dataflow_set_destroy (dataflow_set *);
436 static bool contains_symbol_ref (rtx);
437 static bool track_expr_p (tree, bool);
438 static bool same_variable_part_p (rtx, tree, HOST_WIDE_INT);
439 static int count_uses (rtx *, void *);
440 static void count_uses_1 (rtx *, void *);
441 static void count_stores (rtx, const_rtx, void *);
442 static int add_uses (rtx *, void *);
443 static void add_uses_1 (rtx *, void *);
444 static void add_stores (rtx, const_rtx, void *);
445 static bool compute_bb_dataflow (basic_block);
446 static void vt_find_locations (void);
448 static void dump_attrs_list (attrs);
449 static int dump_variable_slot (void **, void *);
450 static void dump_variable (variable);
451 static void dump_vars (htab_t);
452 static void dump_dataflow_set (dataflow_set *);
453 static void dump_dataflow_sets (void);
455 static void variable_was_changed (variable, dataflow_set *);
456 static void **set_slot_part (dataflow_set *, rtx, void **,
457 decl_or_value, HOST_WIDE_INT,
458 enum var_init_status, rtx);
459 static void set_variable_part (dataflow_set *, rtx,
460 decl_or_value, HOST_WIDE_INT,
461 enum var_init_status, rtx, enum insert_option);
462 static void **clobber_slot_part (dataflow_set *, rtx,
463 void **, HOST_WIDE_INT, rtx);
464 static void clobber_variable_part (dataflow_set *, rtx,
465 decl_or_value, HOST_WIDE_INT, rtx);
466 static void **delete_slot_part (dataflow_set *, rtx, void **, HOST_WIDE_INT);
467 static void delete_variable_part (dataflow_set *, rtx,
468 decl_or_value, HOST_WIDE_INT);
469 static int emit_note_insn_var_location (void **, void *);
470 static void emit_notes_for_changes (rtx, enum emit_note_where, shared_hash);
471 static int emit_notes_for_differences_1 (void **, void *);
472 static int emit_notes_for_differences_2 (void **, void *);
473 static void emit_notes_for_differences (rtx, dataflow_set *, dataflow_set *);
474 static void emit_notes_in_bb (basic_block, dataflow_set *);
475 static void vt_emit_notes (void);
477 static bool vt_get_decl_and_offset (rtx, tree *, HOST_WIDE_INT *);
478 static void vt_add_function_parameters (void);
479 static void vt_initialize (void);
480 static void vt_finalize (void);
482 /* Given a SET, calculate the amount of stack adjustment it contains
483 PRE- and POST-modifying stack pointer.
484 This function is similar to stack_adjust_offset. */
487 stack_adjust_offset_pre_post (rtx pattern, HOST_WIDE_INT *pre,
490 rtx src = SET_SRC (pattern);
491 rtx dest = SET_DEST (pattern);
494 if (dest == stack_pointer_rtx)
496 /* (set (reg sp) (plus (reg sp) (const_int))) */
497 code = GET_CODE (src);
498 if (! (code == PLUS || code == MINUS)
499 || XEXP (src, 0) != stack_pointer_rtx
500 || !CONST_INT_P (XEXP (src, 1)))
504 *post += INTVAL (XEXP (src, 1));
506 *post -= INTVAL (XEXP (src, 1));
508 else if (MEM_P (dest))
510 /* (set (mem (pre_dec (reg sp))) (foo)) */
511 src = XEXP (dest, 0);
512 code = GET_CODE (src);
518 if (XEXP (src, 0) == stack_pointer_rtx)
520 rtx val = XEXP (XEXP (src, 1), 1);
521 /* We handle only adjustments by constant amount. */
522 gcc_assert (GET_CODE (XEXP (src, 1)) == PLUS &&
525 if (code == PRE_MODIFY)
526 *pre -= INTVAL (val);
528 *post -= INTVAL (val);
534 if (XEXP (src, 0) == stack_pointer_rtx)
536 *pre += GET_MODE_SIZE (GET_MODE (dest));
542 if (XEXP (src, 0) == stack_pointer_rtx)
544 *post += GET_MODE_SIZE (GET_MODE (dest));
550 if (XEXP (src, 0) == stack_pointer_rtx)
552 *pre -= GET_MODE_SIZE (GET_MODE (dest));
558 if (XEXP (src, 0) == stack_pointer_rtx)
560 *post -= GET_MODE_SIZE (GET_MODE (dest));
571 /* Given an INSN, calculate the amount of stack adjustment it contains
572 PRE- and POST-modifying stack pointer. */
575 insn_stack_adjust_offset_pre_post (rtx insn, HOST_WIDE_INT *pre,
583 pattern = PATTERN (insn);
584 if (RTX_FRAME_RELATED_P (insn))
586 rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
588 pattern = XEXP (expr, 0);
591 if (GET_CODE (pattern) == SET)
592 stack_adjust_offset_pre_post (pattern, pre, post);
593 else if (GET_CODE (pattern) == PARALLEL
594 || GET_CODE (pattern) == SEQUENCE)
598 /* There may be stack adjustments inside compound insns. Search
600 for ( i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
601 if (GET_CODE (XVECEXP (pattern, 0, i)) == SET)
602 stack_adjust_offset_pre_post (XVECEXP (pattern, 0, i), pre, post);
606 /* Compute stack adjustment in basic block BB. */
609 bb_stack_adjust_offset (basic_block bb)
611 HOST_WIDE_INT offset;
614 offset = VTI (bb)->in.stack_adjust;
615 for (i = 0; i < VTI (bb)->n_mos; i++)
617 if (VTI (bb)->mos[i].type == MO_ADJUST)
618 offset += VTI (bb)->mos[i].u.adjust;
619 else if (VTI (bb)->mos[i].type != MO_CALL)
621 if (MEM_P (VTI (bb)->mos[i].u.loc))
623 VTI (bb)->mos[i].u.loc
624 = adjust_stack_reference (VTI (bb)->mos[i].u.loc, -offset);
628 VTI (bb)->out.stack_adjust = offset;
631 /* Compute stack adjustments for all blocks by traversing DFS tree.
632 Return true when the adjustments on all incoming edges are consistent.
633 Heavily borrowed from pre_and_rev_post_order_compute. */
636 vt_stack_adjustments (void)
638 edge_iterator *stack;
641 /* Initialize entry block. */
642 VTI (ENTRY_BLOCK_PTR)->visited = true;
643 VTI (ENTRY_BLOCK_PTR)->out.stack_adjust = INCOMING_FRAME_SP_OFFSET;
645 /* Allocate stack for back-tracking up CFG. */
646 stack = XNEWVEC (edge_iterator, n_basic_blocks + 1);
649 /* Push the first edge on to the stack. */
650 stack[sp++] = ei_start (ENTRY_BLOCK_PTR->succs);
658 /* Look at the edge on the top of the stack. */
660 src = ei_edge (ei)->src;
661 dest = ei_edge (ei)->dest;
663 /* Check if the edge destination has been visited yet. */
664 if (!VTI (dest)->visited)
666 VTI (dest)->visited = true;
667 VTI (dest)->in.stack_adjust = VTI (src)->out.stack_adjust;
668 bb_stack_adjust_offset (dest);
670 if (EDGE_COUNT (dest->succs) > 0)
671 /* Since the DEST node has been visited for the first
672 time, check its successors. */
673 stack[sp++] = ei_start (dest->succs);
677 /* Check whether the adjustments on the edges are the same. */
678 if (VTI (dest)->in.stack_adjust != VTI (src)->out.stack_adjust)
684 if (! ei_one_before_end_p (ei))
685 /* Go to the next edge. */
686 ei_next (&stack[sp - 1]);
688 /* Return to previous level if there are no more edges. */
697 /* Adjust stack reference MEM by ADJUSTMENT bytes and make it relative
698 to the argument pointer. Return the new rtx. */
701 adjust_stack_reference (rtx mem, HOST_WIDE_INT adjustment)
705 #ifdef FRAME_POINTER_CFA_OFFSET
706 adjustment -= FRAME_POINTER_CFA_OFFSET (current_function_decl);
707 cfa = plus_constant (frame_pointer_rtx, adjustment);
709 adjustment -= ARG_POINTER_CFA_OFFSET (current_function_decl);
710 cfa = plus_constant (arg_pointer_rtx, adjustment);
713 addr = replace_rtx (copy_rtx (XEXP (mem, 0)), stack_pointer_rtx, cfa);
714 tmp = simplify_rtx (addr);
718 return replace_equiv_address_nv (mem, addr);
721 /* Return true if a decl_or_value DV is a DECL or NULL. */
723 dv_is_decl_p (decl_or_value dv)
728 /* Make sure relevant codes don't overlap. */
729 switch ((int)TREE_CODE ((tree)dv))
733 case (int)RESULT_DECL:
734 case (int)FUNCTION_DECL:
735 case (int)COMPONENT_REF:
746 /* Return true if a decl_or_value is a VALUE rtl. */
748 dv_is_value_p (decl_or_value dv)
750 return dv && !dv_is_decl_p (dv);
753 /* Return the decl in the decl_or_value. */
755 dv_as_decl (decl_or_value dv)
757 gcc_assert (dv_is_decl_p (dv));
761 /* Return the value in the decl_or_value. */
763 dv_as_value (decl_or_value dv)
765 gcc_assert (dv_is_value_p (dv));
769 /* Return the opaque pointer in the decl_or_value. */
771 dv_as_opaque (decl_or_value dv)
776 /* Return true if a decl_or_value must not have more than one variable
779 dv_onepart_p (decl_or_value dv)
783 if (!MAY_HAVE_DEBUG_INSNS)
786 if (dv_is_value_p (dv))
789 decl = dv_as_decl (dv);
794 return (target_for_debug_bind (decl) != NULL_TREE);
797 /* Return the variable pool to be used for dv, depending on whether it
798 can have multiple parts or not. */
799 static inline alloc_pool
800 dv_pool (decl_or_value dv)
802 return dv_onepart_p (dv) ? valvar_pool : var_pool;
805 /* Build a decl_or_value out of a decl. */
806 static inline decl_or_value
807 dv_from_decl (tree decl)
811 gcc_assert (dv_is_decl_p (dv));
815 /* Build a decl_or_value out of a value. */
816 static inline decl_or_value
817 dv_from_value (rtx value)
821 gcc_assert (dv_is_value_p (dv));
825 static inline hashval_t
826 dv_htab_hash (decl_or_value dv)
828 if (dv_is_value_p (dv))
829 return -(hashval_t)(CSELIB_VAL_PTR (dv_as_value (dv))->value);
831 return (VARIABLE_HASH_VAL (dv_as_decl (dv)));
834 /* The hash function for variable_htab, computes the hash value
835 from the declaration of variable X. */
838 variable_htab_hash (const void *x)
840 const_variable const v = (const_variable) x;
842 return dv_htab_hash (v->dv);
845 /* Compare the declaration of variable X with declaration Y. */
848 variable_htab_eq (const void *x, const void *y)
850 const_variable const v = (const_variable) x;
851 decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y);
853 if (dv_as_opaque (v->dv) == dv_as_opaque (dv))
860 visv = dv_is_value_p (v->dv);
861 dvisv = dv_is_value_p (dv);
867 gcc_assert (CSELIB_VAL_PTR (dv_as_value (v->dv))
868 != CSELIB_VAL_PTR (dv_as_value (dv)));
870 gcc_assert (VARIABLE_HASH_VAL (dv_as_decl (v->dv))
871 != VARIABLE_HASH_VAL (dv_as_decl (dv)));
878 /* Free the element of VARIABLE_HTAB (its type is struct variable_def). */
881 variable_htab_free (void *elem)
884 variable var = (variable) elem;
885 location_chain node, next;
887 gcc_assert (var->refcount > 0);
890 if (var->refcount > 0)
893 for (i = 0; i < var->n_var_parts; i++)
895 for (node = var->var_part[i].loc_chain; node; node = next)
898 pool_free (loc_chain_pool, node);
900 var->var_part[i].loc_chain = NULL;
902 pool_free (dv_pool (var->dv), var);
905 /* The hash function for value_chains htab, computes the hash value
909 value_chain_htab_hash (const void *x)
911 const_value_chain const v = (const_value_chain) x;
913 return dv_htab_hash (v->dv);
916 /* Compare the VALUE X with VALUE Y. */
919 value_chain_htab_eq (const void *x, const void *y)
921 const_value_chain const v = (const_value_chain) x;
922 decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y);
924 return dv_as_opaque (v->dv) == dv_as_opaque (dv);
927 /* Initialize the set (array) SET of attrs to empty lists. */
930 init_attrs_list_set (attrs *set)
934 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
938 /* Make the list *LISTP empty. */
941 attrs_list_clear (attrs *listp)
945 for (list = *listp; list; list = next)
948 pool_free (attrs_pool, list);
953 /* Return true if the pair of DECL and OFFSET is the member of the LIST. */
956 attrs_list_member (attrs list, decl_or_value dv, HOST_WIDE_INT offset)
958 for (; list; list = list->next)
959 if (dv_as_opaque (list->dv) == dv_as_opaque (dv) && list->offset == offset)
964 /* Insert the triplet DECL, OFFSET, LOC to the list *LISTP. */
967 attrs_list_insert (attrs *listp, decl_or_value dv,
968 HOST_WIDE_INT offset, rtx loc)
972 list = (attrs) pool_alloc (attrs_pool);
975 list->offset = offset;
980 /* Copy all nodes from SRC and create a list *DSTP of the copies. */
983 attrs_list_copy (attrs *dstp, attrs src)
987 attrs_list_clear (dstp);
988 for (; src; src = src->next)
990 n = (attrs) pool_alloc (attrs_pool);
993 n->offset = src->offset;
999 /* Add all nodes from SRC which are not in *DSTP to *DSTP. */
1002 attrs_list_union (attrs *dstp, attrs src)
1004 for (; src; src = src->next)
1006 if (!attrs_list_member (*dstp, src->dv, src->offset))
1007 attrs_list_insert (dstp, src->dv, src->offset, src->loc);
1011 /* Combine nodes that are not onepart nodes from SRC and SRC2 into
1015 attrs_list_mpdv_union (attrs *dstp, attrs src, attrs src2)
1017 gcc_assert (!*dstp);
1018 for (; src; src = src->next)
1020 if (!dv_onepart_p (src->dv))
1021 attrs_list_insert (dstp, src->dv, src->offset, src->loc);
1023 for (src = src2; src; src = src->next)
1025 if (!dv_onepart_p (src->dv)
1026 && !attrs_list_member (*dstp, src->dv, src->offset))
1027 attrs_list_insert (dstp, src->dv, src->offset, src->loc);
1031 /* Shared hashtable support. */
1033 /* Return true if VARS is shared. */
1036 shared_hash_shared (shared_hash vars)
1038 return vars->refcount > 1;
1041 /* Return the hash table for VARS. */
1043 static inline htab_t
1044 shared_hash_htab (shared_hash vars)
1049 /* Copy variables into a new hash table. */
1052 shared_hash_unshare (shared_hash vars)
1054 shared_hash new_vars = (shared_hash) pool_alloc (shared_hash_pool);
1055 gcc_assert (vars->refcount > 1);
1056 new_vars->refcount = 1;
1058 = htab_create (htab_elements (vars->htab) + 3, variable_htab_hash,
1059 variable_htab_eq, variable_htab_free);
1060 vars_copy (new_vars->htab, vars->htab);
1065 /* Increment reference counter on VARS and return it. */
1067 static inline shared_hash
1068 shared_hash_copy (shared_hash vars)
1074 /* Decrement reference counter and destroy hash table if not shared
1078 shared_hash_destroy (shared_hash vars)
1080 gcc_assert (vars->refcount > 0);
1081 if (--vars->refcount == 0)
1083 htab_delete (vars->htab);
1084 pool_free (shared_hash_pool, vars);
1088 /* Unshare *PVARS if shared and return slot for DV. If INS is
1089 INSERT, insert it if not already present. */
1091 static inline void **
1092 shared_hash_find_slot_unshare_1 (shared_hash *pvars, decl_or_value dv,
1093 hashval_t dvhash, enum insert_option ins)
1095 if (shared_hash_shared (*pvars))
1096 *pvars = shared_hash_unshare (*pvars);
1097 return htab_find_slot_with_hash (shared_hash_htab (*pvars), dv, dvhash, ins);
1100 static inline void **
1101 shared_hash_find_slot_unshare (shared_hash *pvars, decl_or_value dv,
1102 enum insert_option ins)
1104 return shared_hash_find_slot_unshare_1 (pvars, dv, dv_htab_hash (dv), ins);
1107 /* Return slot for DV, if it is already present in the hash table.
1108 If it is not present, insert it only VARS is not shared, otherwise
1111 static inline void **
1112 shared_hash_find_slot_1 (shared_hash vars, decl_or_value dv, hashval_t dvhash)
1114 return htab_find_slot_with_hash (shared_hash_htab (vars), dv, dvhash,
1115 shared_hash_shared (vars)
1116 ? NO_INSERT : INSERT);
1119 static inline void **
1120 shared_hash_find_slot (shared_hash vars, decl_or_value dv)
1122 return shared_hash_find_slot_1 (vars, dv, dv_htab_hash (dv));
1125 /* Return slot for DV only if it is already present in the hash table. */
1127 static inline void **
1128 shared_hash_find_slot_noinsert_1 (shared_hash vars, decl_or_value dv,
1131 return htab_find_slot_with_hash (shared_hash_htab (vars), dv, dvhash,
1135 static inline void **
1136 shared_hash_find_slot_noinsert (shared_hash vars, decl_or_value dv)
1138 return shared_hash_find_slot_noinsert_1 (vars, dv, dv_htab_hash (dv));
1141 /* Return variable for DV or NULL if not already present in the hash
1144 static inline variable
1145 shared_hash_find_1 (shared_hash vars, decl_or_value dv, hashval_t dvhash)
1147 return (variable) htab_find_with_hash (shared_hash_htab (vars), dv, dvhash);
1150 static inline variable
1151 shared_hash_find (shared_hash vars, decl_or_value dv)
1153 return shared_hash_find_1 (vars, dv, dv_htab_hash (dv));
1156 /* Determine a total order between two distinct pointers. Compare the
1157 pointers as integral types if size_t is wide enough, otherwise
1158 resort to bitwise memory compare. The actual order does not
1159 matter, we just need to be consistent, so endianness is
1163 tie_break_pointers (const void *p1, const void *p2)
1165 gcc_assert (p1 != p2);
1167 if (sizeof (size_t) >= sizeof (void*))
1168 return (size_t)p1 < (size_t)p2 ? -1 : 1;
1170 return memcmp (&p1, &p2, sizeof (p1));
1173 /* Return true if TVAL is better than CVAL as a canonival value. We
1174 choose lowest-numbered VALUEs, using the RTX address as a
1175 tie-breaker. The idea is to arrange them into a star topology,
1176 such that all of them are at most one step away from the canonical
1177 value, and the canonical value has backlinks to all of them, in
1178 addition to all the actual locations. We don't enforce this
1179 topology throughout the entire dataflow analysis, though.
1183 canon_value_cmp (rtx tval, rtx cval)
1186 || CSELIB_VAL_PTR (tval)->value < CSELIB_VAL_PTR (cval)->value
1187 || (CSELIB_VAL_PTR (tval)->value == CSELIB_VAL_PTR (cval)->value
1188 && tie_break_pointers (tval, cval) < 0);
1191 static bool dst_can_be_shared;
1193 /* Return a copy of a variable VAR and insert it to dataflow set SET. */
1196 unshare_variable (dataflow_set *set, void **slot, variable var,
1197 enum var_init_status initialized)
1202 new_var = (variable) pool_alloc (dv_pool (var->dv));
1203 new_var->dv = var->dv;
1204 new_var->refcount = 1;
1206 new_var->n_var_parts = var->n_var_parts;
1208 if (! flag_var_tracking_uninit)
1209 initialized = VAR_INIT_STATUS_INITIALIZED;
1211 for (i = 0; i < var->n_var_parts; i++)
1213 location_chain node;
1214 location_chain *nextp;
1216 new_var->var_part[i].offset = var->var_part[i].offset;
1217 nextp = &new_var->var_part[i].loc_chain;
1218 for (node = var->var_part[i].loc_chain; node; node = node->next)
1220 location_chain new_lc;
1222 new_lc = (location_chain) pool_alloc (loc_chain_pool);
1223 new_lc->next = NULL;
1224 if (node->init > initialized)
1225 new_lc->init = node->init;
1227 new_lc->init = initialized;
1228 if (node->set_src && !(MEM_P (node->set_src)))
1229 new_lc->set_src = node->set_src;
1231 new_lc->set_src = NULL;
1232 new_lc->loc = node->loc;
1235 nextp = &new_lc->next;
1238 /* We are at the basic block boundary when copying variable description
1239 so set the CUR_LOC to be the first element of the chain. */
1240 if (new_var->var_part[i].loc_chain)
1241 new_var->var_part[i].cur_loc = new_var->var_part[i].loc_chain->loc;
1243 new_var->var_part[i].cur_loc = NULL;
1246 dst_can_be_shared = false;
1247 if (shared_hash_shared (set->vars))
1248 slot = shared_hash_find_slot_unshare (&set->vars, var->dv, NO_INSERT);
1249 else if (set->traversed_vars && set->vars != set->traversed_vars)
1250 slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
1255 /* Add a variable from *SLOT to hash table DATA and increase its reference
1259 vars_copy_1 (void **slot, void *data)
1261 htab_t dst = (htab_t) data;
1265 src = (variable) *slot;
1268 dstp = htab_find_slot_with_hash (dst, src->dv,
1269 dv_htab_hash (src->dv),
1273 /* Continue traversing the hash table. */
1277 /* Copy all variables from hash table SRC to hash table DST. */
1280 vars_copy (htab_t dst, htab_t src)
1282 htab_traverse_noresize (src, vars_copy_1, dst);
1285 /* Map a decl to its main debug decl. */
1288 var_debug_decl (tree decl)
1290 if (decl && DECL_P (decl)
1291 && DECL_DEBUG_EXPR_IS_FROM (decl) && DECL_DEBUG_EXPR (decl)
1292 && DECL_P (DECL_DEBUG_EXPR (decl)))
1293 decl = DECL_DEBUG_EXPR (decl);
1298 /* Set the register LOC to contain DV, OFFSET. */
1301 var_reg_decl_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1302 decl_or_value dv, HOST_WIDE_INT offset, rtx set_src,
1303 enum insert_option iopt)
1306 bool decl_p = dv_is_decl_p (dv);
1309 dv = dv_from_decl (var_debug_decl (dv_as_decl (dv)));
1311 for (node = set->regs[REGNO (loc)]; node; node = node->next)
1312 if (dv_as_opaque (node->dv) == dv_as_opaque (dv)
1313 && node->offset == offset)
1316 attrs_list_insert (&set->regs[REGNO (loc)], dv, offset, loc);
1317 set_variable_part (set, loc, dv, offset, initialized, set_src, iopt);
1320 /* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). */
1323 var_reg_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1326 tree decl = REG_EXPR (loc);
1327 HOST_WIDE_INT offset = REG_OFFSET (loc);
1329 var_reg_decl_set (set, loc, initialized,
1330 dv_from_decl (decl), offset, set_src, INSERT);
1333 static enum var_init_status
1334 get_init_value (dataflow_set *set, rtx loc, decl_or_value dv)
1338 enum var_init_status ret_val = VAR_INIT_STATUS_UNKNOWN;
1340 if (! flag_var_tracking_uninit)
1341 return VAR_INIT_STATUS_INITIALIZED;
1343 var = shared_hash_find (set->vars, dv);
1346 for (i = 0; i < var->n_var_parts && ret_val == VAR_INIT_STATUS_UNKNOWN; i++)
1348 location_chain nextp;
1349 for (nextp = var->var_part[i].loc_chain; nextp; nextp = nextp->next)
1350 if (rtx_equal_p (nextp->loc, loc))
1352 ret_val = nextp->init;
1361 /* Delete current content of register LOC in dataflow set SET and set
1362 the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). If
1363 MODIFY is true, any other live copies of the same variable part are
1364 also deleted from the dataflow set, otherwise the variable part is
1365 assumed to be copied from another location holding the same
1369 var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify,
1370 enum var_init_status initialized, rtx set_src)
1372 tree decl = REG_EXPR (loc);
1373 HOST_WIDE_INT offset = REG_OFFSET (loc);
1377 decl = var_debug_decl (decl);
1379 if (initialized == VAR_INIT_STATUS_UNKNOWN)
1380 initialized = get_init_value (set, loc, dv_from_decl (decl));
1382 nextp = &set->regs[REGNO (loc)];
1383 for (node = *nextp; node; node = next)
1386 if (dv_as_opaque (node->dv) != decl || node->offset != offset)
1388 delete_variable_part (set, node->loc, node->dv, node->offset);
1389 pool_free (attrs_pool, node);
1395 nextp = &node->next;
1399 clobber_variable_part (set, loc, dv_from_decl (decl), offset, set_src);
1400 var_reg_set (set, loc, initialized, set_src);
1403 /* Delete current content of register LOC in dataflow set SET. If
1404 CLOBBER is true, also delete any other live copies of the same
1408 var_reg_delete (dataflow_set *set, rtx loc, bool clobber)
1410 attrs *reg = &set->regs[REGNO (loc)];
1415 tree decl = REG_EXPR (loc);
1416 HOST_WIDE_INT offset = REG_OFFSET (loc);
1418 decl = var_debug_decl (decl);
1420 clobber_variable_part (set, NULL, dv_from_decl (decl), offset, NULL);
1423 for (node = *reg; node; node = next)
1426 delete_variable_part (set, node->loc, node->dv, node->offset);
1427 pool_free (attrs_pool, node);
1432 /* Delete content of register with number REGNO in dataflow set SET. */
1435 var_regno_delete (dataflow_set *set, int regno)
1437 attrs *reg = &set->regs[regno];
1440 for (node = *reg; node; node = next)
1443 delete_variable_part (set, node->loc, node->dv, node->offset);
1444 pool_free (attrs_pool, node);
1449 /* Set the location of DV, OFFSET as the MEM LOC. */
1452 var_mem_decl_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1453 decl_or_value dv, HOST_WIDE_INT offset, rtx set_src,
1454 enum insert_option iopt)
1456 if (dv_is_decl_p (dv))
1457 dv = dv_from_decl (var_debug_decl (dv_as_decl (dv)));
1459 set_variable_part (set, loc, dv, offset, initialized, set_src, iopt);
1462 /* Set the location part of variable MEM_EXPR (LOC) in dataflow set
1464 Adjust the address first if it is stack pointer based. */
1467 var_mem_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1470 tree decl = MEM_EXPR (loc);
1471 HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
1473 var_mem_decl_set (set, loc, initialized,
1474 dv_from_decl (decl), offset, set_src, INSERT);
1477 /* Delete and set the location part of variable MEM_EXPR (LOC) in
1478 dataflow set SET to LOC. If MODIFY is true, any other live copies
1479 of the same variable part are also deleted from the dataflow set,
1480 otherwise the variable part is assumed to be copied from another
1481 location holding the same part.
1482 Adjust the address first if it is stack pointer based. */
1485 var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify,
1486 enum var_init_status initialized, rtx set_src)
1488 tree decl = MEM_EXPR (loc);
1489 HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
1491 decl = var_debug_decl (decl);
1493 if (initialized == VAR_INIT_STATUS_UNKNOWN)
1494 initialized = get_init_value (set, loc, dv_from_decl (decl));
1497 clobber_variable_part (set, NULL, dv_from_decl (decl), offset, set_src);
1498 var_mem_set (set, loc, initialized, set_src);
1501 /* Delete the location part LOC from dataflow set SET. If CLOBBER is
1502 true, also delete any other live copies of the same variable part.
1503 Adjust the address first if it is stack pointer based. */
1506 var_mem_delete (dataflow_set *set, rtx loc, bool clobber)
1508 tree decl = MEM_EXPR (loc);
1509 HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
1511 decl = var_debug_decl (decl);
1513 clobber_variable_part (set, NULL, dv_from_decl (decl), offset, NULL);
1514 delete_variable_part (set, loc, dv_from_decl (decl), offset);
1517 /* Map a value to a location it was just stored in. */
1520 val_store (dataflow_set *set, rtx val, rtx loc, rtx insn)
1522 cselib_val *v = CSELIB_VAL_PTR (val);
1524 gcc_assert (cselib_preserved_value_p (v));
1528 fprintf (dump_file, "%i: ", INSN_UID (insn));
1529 print_inline_rtx (dump_file, val, 0);
1530 fprintf (dump_file, " stored in ");
1531 print_inline_rtx (dump_file, loc, 0);
1534 struct elt_loc_list *l;
1535 for (l = v->locs; l; l = l->next)
1537 fprintf (dump_file, "\n%i: ", INSN_UID (l->setting_insn));
1538 print_inline_rtx (dump_file, l->loc, 0);
1541 fprintf (dump_file, "\n");
1546 var_regno_delete (set, REGNO (loc));
1547 var_reg_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
1548 dv_from_value (val), 0, NULL_RTX, INSERT);
1550 else if (MEM_P (loc))
1551 var_mem_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
1552 dv_from_value (val), 0, NULL_RTX, INSERT);
1554 set_variable_part (set, loc, dv_from_value (val), 0,
1555 VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
1558 /* Reset this node, detaching all its equivalences. Return the slot
1559 in the variable hash table that holds dv, if there is one. */
1562 val_reset (dataflow_set *set, decl_or_value dv)
1564 variable var = shared_hash_find (set->vars, dv) ;
1565 location_chain node;
1568 if (!var || !var->n_var_parts)
1571 gcc_assert (var->n_var_parts == 1);
1574 for (node = var->var_part[0].loc_chain; node; node = node->next)
1575 if (GET_CODE (node->loc) == VALUE
1576 && canon_value_cmp (node->loc, cval))
1579 for (node = var->var_part[0].loc_chain; node; node = node->next)
1580 if (GET_CODE (node->loc) == VALUE && cval != node->loc)
1582 /* Redirect the equivalence link to the new canonical
1583 value, or simply remove it if it would point at
1586 set_variable_part (set, cval, dv_from_value (node->loc),
1587 0, node->init, node->set_src, NO_INSERT);
1588 delete_variable_part (set, dv_as_value (dv),
1589 dv_from_value (node->loc), 0);
1594 decl_or_value cdv = dv_from_value (cval);
1596 /* Keep the remaining values connected, accummulating links
1597 in the canonical value. */
1598 for (node = var->var_part[0].loc_chain; node; node = node->next)
1600 if (node->loc == cval)
1602 else if (GET_CODE (node->loc) == REG)
1603 var_reg_decl_set (set, node->loc, node->init, cdv, 0,
1604 node->set_src, NO_INSERT);
1605 else if (GET_CODE (node->loc) == MEM)
1606 var_mem_decl_set (set, node->loc, node->init, cdv, 0,
1607 node->set_src, NO_INSERT);
1609 set_variable_part (set, node->loc, cdv, 0,
1610 node->init, node->set_src, NO_INSERT);
1614 /* We remove this last, to make sure that the canonical value is not
1615 removed to the point of requiring reinsertion. */
1617 delete_variable_part (set, dv_as_value (dv), dv_from_value (cval), 0);
1619 clobber_variable_part (set, NULL, dv, 0, NULL);
1621 /* ??? Should we make sure there aren't other available values or
1622 variables whose values involve this one other than by
1623 equivalence? E.g., at the very least we should reset MEMs, those
1624 shouldn't be too hard to find cselib-looking up the value as an
1625 address, then locating the resulting value in our own hash
1629 /* Find the values in a given location and map the val to another
1630 value, if it is unique, or add the location as one holding the
1634 val_resolve (dataflow_set *set, rtx val, rtx loc, rtx insn)
1636 decl_or_value dv = dv_from_value (val);
1638 if (dump_file && (dump_flags & TDF_DETAILS))
1641 fprintf (dump_file, "%i: ", INSN_UID (insn));
1643 fprintf (dump_file, "head: ");
1644 print_inline_rtx (dump_file, val, 0);
1645 fputs (" is at ", dump_file);
1646 print_inline_rtx (dump_file, loc, 0);
1647 fputc ('\n', dump_file);
1650 val_reset (set, dv);
1654 attrs node, found = NULL;
1656 for (node = set->regs[REGNO (loc)]; node; node = node->next)
1657 if (dv_is_value_p (node->dv)
1658 && GET_MODE (dv_as_value (node->dv)) == GET_MODE (loc))
1662 /* Map incoming equivalences. ??? Wouldn't it be nice if
1663 we just started sharing the location lists? Maybe a
1664 circular list ending at the value itself or some
1666 set_variable_part (set, dv_as_value (node->dv),
1667 dv_from_value (val), node->offset,
1668 VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
1669 set_variable_part (set, val, node->dv, node->offset,
1670 VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
1673 /* If we didn't find any equivalence, we need to remember that
1674 this value is held in the named register. */
1676 var_reg_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
1677 dv_from_value (val), 0, NULL_RTX, INSERT);
1679 else if (MEM_P (loc))
1680 /* ??? Merge equivalent MEMs. */
1681 var_mem_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
1682 dv_from_value (val), 0, NULL_RTX, INSERT);
1684 /* ??? Merge equivalent expressions. */
1685 set_variable_part (set, loc, dv_from_value (val), 0,
1686 VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
1689 /* Initialize dataflow set SET to be empty.
1690 VARS_SIZE is the initial size of hash table VARS. */
1693 dataflow_set_init (dataflow_set *set)
1695 init_attrs_list_set (set->regs);
1696 set->vars = shared_hash_copy (empty_shared_hash);
1697 set->stack_adjust = 0;
1698 set->traversed_vars = NULL;
1701 /* Delete the contents of dataflow set SET. */
1704 dataflow_set_clear (dataflow_set *set)
1708 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1709 attrs_list_clear (&set->regs[i]);
1711 shared_hash_destroy (set->vars);
1712 set->vars = shared_hash_copy (empty_shared_hash);
1715 /* Copy the contents of dataflow set SRC to DST. */
1718 dataflow_set_copy (dataflow_set *dst, dataflow_set *src)
1722 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1723 attrs_list_copy (&dst->regs[i], src->regs[i]);
1725 shared_hash_destroy (dst->vars);
1726 dst->vars = shared_hash_copy (src->vars);
1727 dst->stack_adjust = src->stack_adjust;
1730 /* Information for merging lists of locations for a given offset of variable.
1732 struct variable_union_info
1734 /* Node of the location chain. */
1737 /* The sum of positions in the input chains. */
1740 /* The position in the chain of DST dataflow set. */
1744 /* Buffer for location list sorting and its allocated size. */
1745 static struct variable_union_info *vui_vec;
1746 static int vui_allocated;
1748 /* Compare function for qsort, order the structures by POS element. */
1751 variable_union_info_cmp_pos (const void *n1, const void *n2)
1753 const struct variable_union_info *const i1 =
1754 (const struct variable_union_info *) n1;
1755 const struct variable_union_info *const i2 =
1756 ( const struct variable_union_info *) n2;
1758 if (i1->pos != i2->pos)
1759 return i1->pos - i2->pos;
1761 return (i1->pos_dst - i2->pos_dst);
1764 /* Compute union of location parts of variable *SLOT and the same variable
1765 from hash table DATA. Compute "sorted" union of the location chains
1766 for common offsets, i.e. the locations of a variable part are sorted by
1767 a priority where the priority is the sum of the positions in the 2 chains
1768 (if a location is only in one list the position in the second list is
1769 defined to be larger than the length of the chains).
1770 When we are updating the location parts the newest location is in the
1771 beginning of the chain, so when we do the described "sorted" union
1772 we keep the newest locations in the beginning. */
1775 variable_union (void **slot, void *data)
1779 dataflow_set *set = (dataflow_set *) data;
1782 src = (variable) *slot;
1783 dstp = shared_hash_find_slot (set->vars, src->dv);
1784 if (!dstp || !*dstp)
1788 dst_can_be_shared = false;
1790 dstp = shared_hash_find_slot_unshare (&set->vars, src->dv, INSERT);
1794 /* If CUR_LOC of some variable part is not the first element of
1795 the location chain we are going to change it so we have to make
1796 a copy of the variable. */
1797 for (k = 0; k < src->n_var_parts; k++)
1799 gcc_assert (!src->var_part[k].loc_chain
1800 == !src->var_part[k].cur_loc);
1801 if (src->var_part[k].loc_chain)
1803 gcc_assert (src->var_part[k].cur_loc);
1804 if (src->var_part[k].cur_loc != src->var_part[k].loc_chain->loc)
1808 if (k < src->n_var_parts)
1809 dstp = unshare_variable (set, dstp, src, VAR_INIT_STATUS_UNKNOWN);
1811 /* Continue traversing the hash table. */
1815 dst = (variable) *dstp;
1817 gcc_assert (src->n_var_parts);
1819 /* We can combine one-part variables very efficiently, because their
1820 entries are in canonical order. */
1821 if (dv_onepart_p (src->dv))
1823 location_chain *nodep, dnode, snode;
1825 gcc_assert (src->n_var_parts == 1);
1826 gcc_assert (dst->n_var_parts == 1);
1828 snode = src->var_part[0].loc_chain;
1831 restart_onepart_unshared:
1832 nodep = &dst->var_part[0].loc_chain;
1838 int r = dnode ? loc_cmp (dnode->loc, snode->loc) : 1;
1842 location_chain nnode;
1844 if (dst->refcount != 1 || shared_hash_shared (set->vars))
1846 dstp = unshare_variable (set, dstp, dst,
1847 VAR_INIT_STATUS_INITIALIZED);
1848 dst = (variable)*dstp;
1849 goto restart_onepart_unshared;
1852 *nodep = nnode = (location_chain) pool_alloc (loc_chain_pool);
1853 nnode->loc = snode->loc;
1854 nnode->init = snode->init;
1855 if (!snode->set_src || MEM_P (snode->set_src))
1856 nnode->set_src = NULL;
1858 nnode->set_src = snode->set_src;
1859 nnode->next = dnode;
1862 #ifdef ENABLE_CHECKING
1864 gcc_assert (rtx_equal_p (dnode->loc, snode->loc));
1868 snode = snode->next;
1870 nodep = &dnode->next;
1874 dst->var_part[0].cur_loc = dst->var_part[0].loc_chain->loc;
1879 /* Count the number of location parts, result is K. */
1880 for (i = 0, j = 0, k = 0;
1881 i < src->n_var_parts && j < dst->n_var_parts; k++)
1883 if (src->var_part[i].offset == dst->var_part[j].offset)
1888 else if (src->var_part[i].offset < dst->var_part[j].offset)
1893 k += src->n_var_parts - i;
1894 k += dst->n_var_parts - j;
1896 /* We track only variables whose size is <= MAX_VAR_PARTS bytes
1897 thus there are at most MAX_VAR_PARTS different offsets. */
1898 gcc_assert (dv_onepart_p (dst->dv) ? k == 1 : k <= MAX_VAR_PARTS);
1900 if ((dst->refcount > 1 || shared_hash_shared (set->vars))
1901 && dst->n_var_parts != k)
1903 dstp = unshare_variable (set, dstp, dst, VAR_INIT_STATUS_UNKNOWN);
1904 dst = (variable)*dstp;
1907 i = src->n_var_parts - 1;
1908 j = dst->n_var_parts - 1;
1909 dst->n_var_parts = k;
1911 for (k--; k >= 0; k--)
1913 location_chain node, node2;
1915 if (i >= 0 && j >= 0
1916 && src->var_part[i].offset == dst->var_part[j].offset)
1918 /* Compute the "sorted" union of the chains, i.e. the locations which
1919 are in both chains go first, they are sorted by the sum of
1920 positions in the chains. */
1923 struct variable_union_info *vui;
1925 /* If DST is shared compare the location chains.
1926 If they are different we will modify the chain in DST with
1927 high probability so make a copy of DST. */
1928 if (dst->refcount > 1 || shared_hash_shared (set->vars))
1930 for (node = src->var_part[i].loc_chain,
1931 node2 = dst->var_part[j].loc_chain; node && node2;
1932 node = node->next, node2 = node2->next)
1934 if (!((REG_P (node2->loc)
1935 && REG_P (node->loc)
1936 && REGNO (node2->loc) == REGNO (node->loc))
1937 || rtx_equal_p (node2->loc, node->loc)))
1939 if (node2->init < node->init)
1940 node2->init = node->init;
1946 dstp = unshare_variable (set, dstp, dst,
1947 VAR_INIT_STATUS_UNKNOWN);
1948 dst = (variable)*dstp;
1953 for (node = src->var_part[i].loc_chain; node; node = node->next)
1956 for (node = dst->var_part[j].loc_chain; node; node = node->next)
1961 /* The most common case, much simpler, no qsort is needed. */
1962 location_chain dstnode = dst->var_part[j].loc_chain;
1963 dst->var_part[k].loc_chain = dstnode;
1964 dst->var_part[k].offset = dst->var_part[j].offset;
1966 for (node = src->var_part[i].loc_chain; node; node = node->next)
1967 if (!((REG_P (dstnode->loc)
1968 && REG_P (node->loc)
1969 && REGNO (dstnode->loc) == REGNO (node->loc))
1970 || rtx_equal_p (dstnode->loc, node->loc)))
1972 location_chain new_node;
1974 /* Copy the location from SRC. */
1975 new_node = (location_chain) pool_alloc (loc_chain_pool);
1976 new_node->loc = node->loc;
1977 new_node->init = node->init;
1978 if (!node->set_src || MEM_P (node->set_src))
1979 new_node->set_src = NULL;
1981 new_node->set_src = node->set_src;
1982 node2->next = new_node;
1989 if (src_l + dst_l > vui_allocated)
1991 vui_allocated = MAX (vui_allocated * 2, src_l + dst_l);
1992 vui_vec = XRESIZEVEC (struct variable_union_info, vui_vec,
1997 /* Fill in the locations from DST. */
1998 for (node = dst->var_part[j].loc_chain, jj = 0; node;
1999 node = node->next, jj++)
2002 vui[jj].pos_dst = jj;
2004 /* Pos plus value larger than a sum of 2 valid positions. */
2005 vui[jj].pos = jj + src_l + dst_l;
2008 /* Fill in the locations from SRC. */
2010 for (node = src->var_part[i].loc_chain, ii = 0; node;
2011 node = node->next, ii++)
2013 /* Find location from NODE. */
2014 for (jj = 0; jj < dst_l; jj++)
2016 if ((REG_P (vui[jj].lc->loc)
2017 && REG_P (node->loc)
2018 && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
2019 || rtx_equal_p (vui[jj].lc->loc, node->loc))
2021 vui[jj].pos = jj + ii;
2025 if (jj >= dst_l) /* The location has not been found. */
2027 location_chain new_node;
2029 /* Copy the location from SRC. */
2030 new_node = (location_chain) pool_alloc (loc_chain_pool);
2031 new_node->loc = node->loc;
2032 new_node->init = node->init;
2033 if (!node->set_src || MEM_P (node->set_src))
2034 new_node->set_src = NULL;
2036 new_node->set_src = node->set_src;
2037 vui[n].lc = new_node;
2038 vui[n].pos_dst = src_l + dst_l;
2039 vui[n].pos = ii + src_l + dst_l;
2046 /* Special case still very common case. For dst_l == 2
2047 all entries dst_l ... n-1 are sorted, with for i >= dst_l
2048 vui[i].pos == i + src_l + dst_l. */
2049 if (vui[0].pos > vui[1].pos)
2051 /* Order should be 1, 0, 2... */
2052 dst->var_part[k].loc_chain = vui[1].lc;
2053 vui[1].lc->next = vui[0].lc;
2056 vui[0].lc->next = vui[2].lc;
2057 vui[n - 1].lc->next = NULL;
2060 vui[0].lc->next = NULL;
2065 dst->var_part[k].loc_chain = vui[0].lc;
2066 if (n >= 3 && vui[2].pos < vui[1].pos)
2068 /* Order should be 0, 2, 1, 3... */
2069 vui[0].lc->next = vui[2].lc;
2070 vui[2].lc->next = vui[1].lc;
2073 vui[1].lc->next = vui[3].lc;
2074 vui[n - 1].lc->next = NULL;
2077 vui[1].lc->next = NULL;
2082 /* Order should be 0, 1, 2... */
2084 vui[n - 1].lc->next = NULL;
2087 for (; ii < n; ii++)
2088 vui[ii - 1].lc->next = vui[ii].lc;
2092 qsort (vui, n, sizeof (struct variable_union_info),
2093 variable_union_info_cmp_pos);
2095 /* Reconnect the nodes in sorted order. */
2096 for (ii = 1; ii < n; ii++)
2097 vui[ii - 1].lc->next = vui[ii].lc;
2098 vui[n - 1].lc->next = NULL;
2099 dst->var_part[k].loc_chain = vui[0].lc;
2102 dst->var_part[k].offset = dst->var_part[j].offset;
2107 else if ((i >= 0 && j >= 0
2108 && src->var_part[i].offset < dst->var_part[j].offset)
2111 dst->var_part[k] = dst->var_part[j];
2114 else if ((i >= 0 && j >= 0
2115 && src->var_part[i].offset > dst->var_part[j].offset)
2118 location_chain *nextp;
2120 /* Copy the chain from SRC. */
2121 nextp = &dst->var_part[k].loc_chain;
2122 for (node = src->var_part[i].loc_chain; node; node = node->next)
2124 location_chain new_lc;
2126 new_lc = (location_chain) pool_alloc (loc_chain_pool);
2127 new_lc->next = NULL;
2128 new_lc->init = node->init;
2129 if (!node->set_src || MEM_P (node->set_src))
2130 new_lc->set_src = NULL;
2132 new_lc->set_src = node->set_src;
2133 new_lc->loc = node->loc;
2136 nextp = &new_lc->next;
2139 dst->var_part[k].offset = src->var_part[i].offset;
2143 /* We are at the basic block boundary when computing union
2144 so set the CUR_LOC to be the first element of the chain. */
2145 if (dst->var_part[k].loc_chain)
2146 dst->var_part[k].cur_loc = dst->var_part[k].loc_chain->loc;
2148 dst->var_part[k].cur_loc = NULL;
2151 if (flag_var_tracking_uninit)
2152 for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
2154 location_chain node, node2;
2155 for (node = src->var_part[i].loc_chain; node; node = node->next)
2156 for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
2157 if (rtx_equal_p (node->loc, node2->loc))
2159 if (node->init > node2->init)
2160 node2->init = node->init;
2164 /* Continue traversing the hash table. */
2168 /* Like variable_union, but only used when doing dataflow_set_union
2169 into an empty hashtab. To allow sharing, dst is initially shared
2170 with src (so all variables are "copied" from src to dst hashtab),
2171 so only unshare_variable for variables that need canonicalization
2175 variable_canonicalize (void **slot, void *data)
2178 dataflow_set *set = (dataflow_set *) data;
2181 src = *(variable *) slot;
2183 /* If CUR_LOC of some variable part is not the first element of
2184 the location chain we are going to change it so we have to make
2185 a copy of the variable. */
2186 for (k = 0; k < src->n_var_parts; k++)
2188 gcc_assert (!src->var_part[k].loc_chain == !src->var_part[k].cur_loc);
2189 if (src->var_part[k].loc_chain)
2191 gcc_assert (src->var_part[k].cur_loc);
2192 if (src->var_part[k].cur_loc != src->var_part[k].loc_chain->loc)
2196 if (k < src->n_var_parts)
2197 slot = unshare_variable (set, slot, src, VAR_INIT_STATUS_UNKNOWN);
2201 /* Compute union of dataflow sets SRC and DST and store it to DST. */
2204 dataflow_set_union (dataflow_set *dst, dataflow_set *src)
2208 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2209 attrs_list_union (&dst->regs[i], src->regs[i]);
2211 if (dst->vars == empty_shared_hash)
2213 shared_hash_destroy (dst->vars);
2214 dst->vars = shared_hash_copy (src->vars);
2215 dst->traversed_vars = dst->vars;
2216 htab_traverse (shared_hash_htab (dst->vars), variable_canonicalize, dst);
2217 dst->traversed_vars = NULL;
2220 htab_traverse (shared_hash_htab (src->vars), variable_union, dst);
2223 /* Whether the value is currently being expanded. */
2224 #define VALUE_RECURSED_INTO(x) \
2225 (RTL_FLAG_CHECK1 ("VALUE_RECURSED_INTO", (x), VALUE)->used)
2226 /* Whether the value is in changed_variables hash table. */
2227 #define VALUE_CHANGED(x) \
2228 (RTL_FLAG_CHECK1 ("VALUE_CHANGED", (x), VALUE)->frame_related)
2229 /* Whether the decl is in changed_variables hash table. */
2230 #define DECL_CHANGED(x) TREE_VISITED (x)
2232 /* Record that DV has been added into resp. removed from changed_variables
2236 set_dv_changed (decl_or_value dv, bool newv)
2238 if (dv_is_value_p (dv))
2239 VALUE_CHANGED (dv_as_value (dv)) = newv;
2241 DECL_CHANGED (dv_as_decl (dv)) = newv;
2244 /* Return true if DV is present in changed_variables hash table. */
2247 dv_changed_p (decl_or_value dv)
2249 return (dv_is_value_p (dv)
2250 ? VALUE_CHANGED (dv_as_value (dv))
2251 : DECL_CHANGED (dv_as_decl (dv)));
2254 /* Return a location list node whose loc is rtx_equal to LOC, in the
2255 location list of a one-part variable or value VAR, or in that of
2256 any values recursively mentioned in the location lists. */
2258 static location_chain
2259 find_loc_in_1pdv (rtx loc, variable var, htab_t vars)
2261 location_chain node;
2266 gcc_assert (dv_onepart_p (var->dv));
2268 if (!var->n_var_parts)
2271 gcc_assert (var->var_part[0].offset == 0);
2273 for (node = var->var_part[0].loc_chain; node; node = node->next)
2274 if (rtx_equal_p (loc, node->loc))
2276 else if (GET_CODE (node->loc) == VALUE
2277 && !VALUE_RECURSED_INTO (node->loc))
2279 decl_or_value dv = dv_from_value (node->loc);
2280 variable var = (variable)
2281 htab_find_with_hash (vars, dv, dv_htab_hash (dv));
2285 location_chain where;
2286 VALUE_RECURSED_INTO (node->loc) = true;
2287 if ((where = find_loc_in_1pdv (loc, var, vars)))
2289 VALUE_RECURSED_INTO (node->loc) = false;
2292 VALUE_RECURSED_INTO (node->loc) = false;
2299 /* Hash table iteration argument passed to variable_merge. */
2302 /* The set in which the merge is to be inserted. */
2304 /* The set that we're iterating in. */
2306 /* The set that may contain the other dv we are to merge with. */
2308 /* Number of onepart dvs in src. */
2309 int src_onepart_cnt;
2312 /* Insert LOC in *DNODE, if it's not there yet. The list must be in
2313 loc_cmp order, and it is maintained as such. */
2316 insert_into_intersection (location_chain *nodep, rtx loc,
2317 enum var_init_status status)
2319 location_chain node;
2322 for (node = *nodep; node; nodep = &node->next, node = *nodep)
2323 if ((r = loc_cmp (node->loc, loc)) == 0)
2325 node->init = MIN (node->init, status);
2331 node = (location_chain) pool_alloc (loc_chain_pool);
2334 node->set_src = NULL;
2335 node->init = status;
2336 node->next = *nodep;
2340 /* Insert in DEST the intersection the locations present in both
2341 S1NODE and S2VAR, directly or indirectly. S1NODE is from a
2342 variable in DSM->cur, whereas S2VAR is from DSM->src. dvar is in
2346 intersect_loc_chains (rtx val, location_chain *dest, struct dfset_merge *dsm,
2347 location_chain s1node, variable s2var)
2349 dataflow_set *s1set = dsm->cur;
2350 dataflow_set *s2set = dsm->src;
2351 location_chain found;
2353 for (; s1node; s1node = s1node->next)
2355 if (s1node->loc == val)
2358 if ((found = find_loc_in_1pdv (s1node->loc, s2var,
2359 shared_hash_htab (s2set->vars))))
2361 insert_into_intersection (dest, s1node->loc,
2362 MIN (s1node->init, found->init));
2366 if (GET_CODE (s1node->loc) == VALUE
2367 && !VALUE_RECURSED_INTO (s1node->loc))
2369 decl_or_value dv = dv_from_value (s1node->loc);
2370 variable svar = shared_hash_find (s1set->vars, dv);
2373 if (svar->n_var_parts == 1)
2375 VALUE_RECURSED_INTO (s1node->loc) = true;
2376 intersect_loc_chains (val, dest, dsm,
2377 svar->var_part[0].loc_chain,
2379 VALUE_RECURSED_INTO (s1node->loc) = false;
2384 /* ??? if the location is equivalent to any location in src,
2385 searched recursively
2387 add to dst the values needed to represent the equivalence
2389 telling whether locations S is equivalent to another dv's
2392 for each location D in the list
2394 if S and D satisfy rtx_equal_p, then it is present
2396 else if D is a value, recurse without cycles
2398 else if S and D have the same CODE and MODE
2400 for each operand oS and the corresponding oD
2402 if oS and oD are not equivalent, then S an D are not equivalent
2404 else if they are RTX vectors
2406 if any vector oS element is not equivalent to its respective oD,
2407 then S and D are not equivalent
2415 /* Return -1 if X should be before Y in a location list for a 1-part
2416 variable, 1 if Y should be before X, and 0 if they're equivalent
2417 and should not appear in the list. */
2420 loc_cmp (rtx x, rtx y)
2423 RTX_CODE code = GET_CODE (x);
2433 gcc_assert (GET_MODE (x) == GET_MODE (y));
2434 if (REGNO (x) == REGNO (y))
2436 else if (REGNO (x) < REGNO (y))
2449 gcc_assert (GET_MODE (x) == GET_MODE (y));
2450 return loc_cmp (XEXP (x, 0), XEXP (y, 0));
2456 if (GET_CODE (x) == VALUE)
2458 if (GET_CODE (y) != VALUE)
2460 gcc_assert (GET_MODE (x) == GET_MODE (y));
2461 if (canon_value_cmp (x, y))
2467 if (GET_CODE (y) == VALUE)
2470 if (GET_CODE (x) == GET_CODE (y))
2471 /* Compare operands below. */;
2472 else if (GET_CODE (x) < GET_CODE (y))
2477 gcc_assert (GET_MODE (x) == GET_MODE (y));
2479 fmt = GET_RTX_FORMAT (code);
2480 for (i = 0; i < GET_RTX_LENGTH (code); i++)
2484 if (XWINT (x, i) == XWINT (y, i))
2486 else if (XWINT (x, i) < XWINT (y, i))
2493 if (XINT (x, i) == XINT (y, i))
2495 else if (XINT (x, i) < XINT (y, i))
2502 /* Compare the vector length first. */
2503 if (XVECLEN (x, i) == XVECLEN (y, i))
2504 /* Compare the vectors elements. */;
2505 else if (XVECLEN (x, i) < XVECLEN (y, i))
2510 for (j = 0; j < XVECLEN (x, i); j++)
2511 if ((r = loc_cmp (XVECEXP (x, i, j),
2512 XVECEXP (y, i, j))))
2517 if ((r = loc_cmp (XEXP (x, i), XEXP (y, i))))
2523 if (XSTR (x, i) == XSTR (y, i))
2529 if ((r = strcmp (XSTR (x, i), XSTR (y, i))) == 0)
2537 /* These are just backpointers, so they don't matter. */
2544 /* It is believed that rtx's at this level will never
2545 contain anything but integers and other rtx's,
2546 except for within LABEL_REFs and SYMBOL_REFs. */
2554 /* If decl or value DVP refers to VALUE from *LOC, add backlinks
2555 from VALUE to DVP. */
2558 add_value_chain (rtx *loc, void *dvp)
2560 if (GET_CODE (*loc) == VALUE && (void *) *loc != dvp)
2562 decl_or_value dv = (decl_or_value) dvp;
2563 decl_or_value ldv = dv_from_value (*loc);
2564 value_chain vc, nvc;
2565 void **slot = htab_find_slot_with_hash (value_chains, ldv,
2566 dv_htab_hash (ldv), INSERT);
2569 vc = (value_chain) pool_alloc (value_chain_pool);
2573 *slot = (void *) vc;
2577 for (vc = ((value_chain) *slot)->next; vc; vc = vc->next)
2578 if (dv_as_opaque (vc->dv) == dv_as_opaque (dv))
2586 vc = (value_chain) *slot;
2587 nvc = (value_chain) pool_alloc (value_chain_pool);
2589 nvc->next = vc->next;
2596 /* If decl or value DVP refers to VALUEs from within LOC, add backlinks
2597 from those VALUEs to DVP. */
2600 add_value_chains (decl_or_value dv, rtx loc)
2602 if (GET_CODE (loc) == VALUE)
2604 add_value_chain (&loc, dv_as_opaque (dv));
2610 loc = XEXP (loc, 0);
2611 for_each_rtx (&loc, add_value_chain, dv_as_opaque (dv));
2614 /* If CSELIB_VAL_PTR of value DV refer to VALUEs, add backlinks from those
2618 add_cselib_value_chains (decl_or_value dv)
2620 struct elt_loc_list *l;
2622 for (l = CSELIB_VAL_PTR (dv_as_value (dv))->locs; l; l = l->next)
2623 for_each_rtx (&l->loc, add_value_chain, dv_as_opaque (dv));
2626 /* If decl or value DVP refers to VALUE from *LOC, remove backlinks
2627 from VALUE to DVP. */
2630 remove_value_chain (rtx *loc, void *dvp)
2632 if (GET_CODE (*loc) == VALUE && (void *) *loc != dvp)
2634 decl_or_value dv = (decl_or_value) dvp;
2635 decl_or_value ldv = dv_from_value (*loc);
2636 value_chain vc, dvc = NULL;
2637 void **slot = htab_find_slot_with_hash (value_chains, ldv,
2638 dv_htab_hash (ldv), NO_INSERT);
2639 for (vc = (value_chain) *slot; vc->next; vc = vc->next)
2640 if (dv_as_opaque (vc->next->dv) == dv_as_opaque (dv))
2643 gcc_assert (dvc->refcount > 0);
2644 if (--dvc->refcount == 0)
2646 vc->next = dvc->next;
2647 pool_free (value_chain_pool, dvc);
2648 if (vc->next == NULL && vc == (value_chain) *slot)
2650 pool_free (value_chain_pool, vc);
2651 htab_clear_slot (value_chains, slot);
2661 /* If decl or value DVP refers to VALUEs from within LOC, remove backlinks
2662 from those VALUEs to DVP. */
2665 remove_value_chains (decl_or_value dv, rtx loc)
2667 if (GET_CODE (loc) == VALUE)
2669 remove_value_chain (&loc, dv_as_opaque (dv));
2675 loc = XEXP (loc, 0);
2676 for_each_rtx (&loc, remove_value_chain, dv_as_opaque (dv));
2679 /* If CSELIB_VAL_PTR of value DV refer to VALUEs, remove backlinks from those
2683 remove_cselib_value_chains (decl_or_value dv)
2685 struct elt_loc_list *l;
2687 for (l = CSELIB_VAL_PTR (dv_as_value (dv))->locs; l; l = l->next)
2688 for_each_rtx (&l->loc, remove_value_chain, dv_as_opaque (dv));
2692 /* Check the order of entries in one-part variables. */
2695 canonicalize_loc_order_check (void **slot, void *data ATTRIBUTE_UNUSED)
2697 variable var = (variable) *slot;
2698 decl_or_value dv = var->dv;
2699 location_chain node, next;
2701 if (!dv_onepart_p (dv))
2704 gcc_assert (var->n_var_parts == 1);
2705 node = var->var_part[0].loc_chain;
2708 while ((next = node->next))
2710 gcc_assert (loc_cmp (node->loc, next->loc) < 0);
2718 /* Mark with VALUE_RECURSED_INTO values that have neighbors that are
2719 more likely to be chosen as canonical for an equivalence set.
2720 Ensure less likely values can reach more likely neighbors, making
2721 the connections bidirectional. */
2724 canonicalize_values_mark (void **slot, void *data)
2726 dataflow_set *set = (dataflow_set *)data;
2727 variable var = (variable) *slot;
2728 decl_or_value dv = var->dv;
2730 location_chain node;
2732 if (!dv_is_value_p (dv))
2735 gcc_assert (var->n_var_parts == 1);
2737 val = dv_as_value (dv);
2739 for (node = var->var_part[0].loc_chain; node; node = node->next)
2740 if (GET_CODE (node->loc) == VALUE)
2742 if (canon_value_cmp (node->loc, val))
2743 VALUE_RECURSED_INTO (val) = true;
2746 decl_or_value odv = dv_from_value (node->loc);
2747 void **oslot = shared_hash_find_slot_noinsert (set->vars, odv);
2749 oslot = set_slot_part (set, val, oslot, odv, 0,
2750 node->init, NULL_RTX);
2752 VALUE_RECURSED_INTO (node->loc) = true;
2759 /* Remove redundant entries from equivalence lists in onepart
2760 variables, canonicalizing equivalence sets into star shapes. */
2763 canonicalize_values_star (void **slot, void *data)
2765 dataflow_set *set = (dataflow_set *)data;
2766 variable var = (variable) *slot;
2767 decl_or_value dv = var->dv;
2768 location_chain node;
2775 if (!dv_onepart_p (dv))
2778 gcc_assert (var->n_var_parts == 1);
2780 if (dv_is_value_p (dv))
2782 cval = dv_as_value (dv);
2783 if (!VALUE_RECURSED_INTO (cval))
2785 VALUE_RECURSED_INTO (cval) = false;
2795 gcc_assert (var->n_var_parts == 1);
2797 for (node = var->var_part[0].loc_chain; node; node = node->next)
2798 if (GET_CODE (node->loc) == VALUE)
2801 if (VALUE_RECURSED_INTO (node->loc))
2803 if (canon_value_cmp (node->loc, cval))
2812 if (!has_marks || dv_is_decl_p (dv))
2815 /* Keep it marked so that we revisit it, either after visiting a
2816 child node, or after visiting a new parent that might be
2818 VALUE_RECURSED_INTO (val) = true;
2820 for (node = var->var_part[0].loc_chain; node; node = node->next)
2821 if (GET_CODE (node->loc) == VALUE
2822 && VALUE_RECURSED_INTO (node->loc))
2826 VALUE_RECURSED_INTO (cval) = false;
2827 dv = dv_from_value (cval);
2828 slot = shared_hash_find_slot_noinsert (set->vars, dv);
2831 gcc_assert (dv_is_decl_p (var->dv));
2832 /* The canonical value was reset and dropped.
2834 clobber_variable_part (set, NULL, var->dv, 0, NULL);
2837 var = (variable)*slot;
2838 gcc_assert (dv_is_value_p (var->dv));
2839 if (var->n_var_parts == 0)
2841 gcc_assert (var->n_var_parts == 1);
2845 VALUE_RECURSED_INTO (val) = false;
2850 /* Push values to the canonical one. */
2851 cdv = dv_from_value (cval);
2852 cslot = shared_hash_find_slot_noinsert (set->vars, cdv);
2854 for (node = var->var_part[0].loc_chain; node; node = node->next)
2855 if (node->loc != cval)
2857 cslot = set_slot_part (set, node->loc, cslot, cdv, 0,
2858 node->init, NULL_RTX);
2859 if (GET_CODE (node->loc) == VALUE)
2861 decl_or_value ndv = dv_from_value (node->loc);
2863 set_variable_part (set, cval, ndv, 0, node->init, NULL_RTX,
2866 if (canon_value_cmp (node->loc, val))
2868 /* If it could have been a local minimum, it's not any more,
2869 since it's now neighbor to cval, so it may have to push
2870 to it. Conversely, if it wouldn't have prevailed over
2871 val, then whatever mark it has is fine: if it was to
2872 push, it will now push to a more canonical node, but if
2873 it wasn't, then it has already pushed any values it might
2875 VALUE_RECURSED_INTO (node->loc) = true;
2876 /* Make sure we visit node->loc by ensuring we cval is
2878 VALUE_RECURSED_INTO (cval) = true;
2880 else if (!VALUE_RECURSED_INTO (node->loc))
2881 /* If we have no need to "recurse" into this node, it's
2882 already "canonicalized", so drop the link to the old
2884 clobber_variable_part (set, cval, ndv, 0, NULL);
2886 else if (GET_CODE (node->loc) == REG)
2888 attrs list = set->regs[REGNO (node->loc)], *listp;
2890 /* Change an existing attribute referring to dv so that it
2891 refers to cdv, removing any duplicate this might
2892 introduce, and checking that no previous duplicates
2893 existed, all in a single pass. */
2897 if (list->offset == 0
2898 && (dv_as_opaque (list->dv) == dv_as_opaque (dv)
2899 || dv_as_opaque (list->dv) == dv_as_opaque (cdv)))
2906 if (dv_as_opaque (list->dv) == dv_as_opaque (dv))
2909 for (listp = &list->next; (list = *listp); listp = &list->next)
2914 if (dv_as_opaque (list->dv) == dv_as_opaque (cdv))
2916 *listp = list->next;
2917 pool_free (attrs_pool, list);
2922 gcc_assert (dv_as_opaque (list->dv) != dv_as_opaque (dv));
2925 else if (dv_as_opaque (list->dv) == dv_as_opaque (cdv))
2927 for (listp = &list->next; (list = *listp); listp = &list->next)
2932 if (dv_as_opaque (list->dv) == dv_as_opaque (dv))
2934 *listp = list->next;
2935 pool_free (attrs_pool, list);
2940 gcc_assert (dv_as_opaque (list->dv) != dv_as_opaque (cdv));
2949 if (list->offset == 0
2950 && (dv_as_opaque (list->dv) == dv_as_opaque (dv)
2951 || dv_as_opaque (list->dv) == dv_as_opaque (cdv)))
2961 cslot = set_slot_part (set, val, cslot, cdv, 0,
2962 VAR_INIT_STATUS_INITIALIZED, NULL_RTX);
2964 slot = clobber_slot_part (set, cval, slot, 0, NULL);
2966 /* Variable may have been unshared. */
2967 var = (variable)*slot;
2968 gcc_assert (var->n_var_parts && var->var_part[0].loc_chain->loc == cval
2969 && var->var_part[0].loc_chain->next == NULL);
2971 if (VALUE_RECURSED_INTO (cval))
2972 goto restart_with_cval;
2977 /* Combine variable or value in *S1SLOT (in DSM->cur) with the
2978 corresponding entry in DSM->src. Multi-part variables are combined
2979 with variable_union, whereas onepart dvs are combined with
2983 variable_merge_over_cur (void **s1slot, void *data)
2985 struct dfset_merge *dsm = (struct dfset_merge *)data;
2986 dataflow_set *dst = dsm->dst;
2988 variable s1var = (variable) *s1slot;
2989 variable s2var, dvar = NULL;
2990 decl_or_value dv = s1var->dv;
2991 bool onepart = dv_onepart_p (dv);
2994 location_chain node, *nodep;
2996 /* If the incoming onepart variable has an empty location list, then
2997 the intersection will be just as empty. For other variables,
2998 it's always union. */
2999 gcc_assert (s1var->n_var_parts);
3000 gcc_assert (s1var->var_part[0].loc_chain);
3003 return variable_union (s1slot, dst);
3005 gcc_assert (s1var->n_var_parts == 1);
3006 gcc_assert (s1var->var_part[0].offset == 0);
3008 dvhash = dv_htab_hash (dv);
3009 if (dv_is_value_p (dv))
3010 val = dv_as_value (dv);
3014 s2var = shared_hash_find_1 (dsm->src->vars, dv, dvhash);
3017 dst_can_be_shared = false;
3021 dsm->src_onepart_cnt--;
3022 gcc_assert (s2var->var_part[0].loc_chain);
3023 gcc_assert (s2var->n_var_parts == 1);
3024 gcc_assert (s2var->var_part[0].offset == 0);
3026 dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3029 dvar = (variable)*dstslot;
3030 gcc_assert (dvar->refcount == 1);
3031 gcc_assert (dvar->n_var_parts == 1);
3032 gcc_assert (dvar->var_part[0].offset == 0);
3033 nodep = &dvar->var_part[0].loc_chain;
3041 if (!dstslot && !onepart_variable_different_p (s1var, s2var))
3043 dstslot = shared_hash_find_slot_unshare_1 (&dst->vars, dv,
3045 *dstslot = dvar = s2var;
3050 dst_can_be_shared = false;
3052 intersect_loc_chains (val, nodep, dsm,
3053 s1var->var_part[0].loc_chain, s2var);
3059 dvar = (variable) pool_alloc (dv_pool (dv));
3062 dvar->n_var_parts = 1;
3063 dvar->var_part[0].offset = 0;
3064 dvar->var_part[0].loc_chain = node;
3065 dvar->var_part[0].cur_loc = node->loc;
3068 = shared_hash_find_slot_unshare_1 (&dst->vars, dv, dvhash,
3070 gcc_assert (!*dstslot);
3078 nodep = &dvar->var_part[0].loc_chain;
3079 while ((node = *nodep))
3081 location_chain *nextp = &node->next;
3083 if (GET_CODE (node->loc) == REG)
3087 for (list = dst->regs[REGNO (node->loc)]; list; list = list->next)
3088 if (GET_MODE (node->loc) == GET_MODE (list->loc)
3089 && dv_is_value_p (list->dv))
3093 attrs_list_insert (&dst->regs[REGNO (node->loc)],
3095 /* If this value became canonical for another value that had
3096 this register, we want to leave it alone. */
3097 else if (dv_as_value (list->dv) != val)
3099 dstslot = set_slot_part (dst, dv_as_value (list->dv),
3101 node->init, NULL_RTX);
3102 dstslot = delete_slot_part (dst, node->loc, dstslot, 0);
3104 /* Since nextp points into the removed node, we can't
3105 use it. The pointer to the next node moved to nodep.
3106 However, if the variable we're walking is unshared
3107 during our walk, we'll keep walking the location list
3108 of the previously-shared variable, in which case the
3109 node won't have been removed, and we'll want to skip
3110 it. That's why we test *nodep here. */
3116 /* Canonicalization puts registers first, so we don't have to
3122 if (dvar != (variable)*dstslot)
3123 dvar = (variable)*dstslot;
3124 nodep = &dvar->var_part[0].loc_chain;
3128 /* Mark all referenced nodes for canonicalization, and make sure
3129 we have mutual equivalence links. */
3130 VALUE_RECURSED_INTO (val) = true;
3131 for (node = *nodep; node; node = node->next)
3132 if (GET_CODE (node->loc) == VALUE)
3134 VALUE_RECURSED_INTO (node->loc) = true;
3135 set_variable_part (dst, val, dv_from_value (node->loc), 0,
3136 node->init, NULL, INSERT);
3139 dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3140 gcc_assert (*dstslot == dvar);
3141 canonicalize_values_star (dstslot, dst);
3142 #ifdef ENABLE_CHECKING
3144 == shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash));
3146 dvar = (variable)*dstslot;
3150 bool has_value = false, has_other = false;
3152 /* If we have one value and anything else, we're going to
3153 canonicalize this, so make sure all values have an entry in
3154 the table and are marked for canonicalization. */
3155 for (node = *nodep; node; node = node->next)
3157 if (GET_CODE (node->loc) == VALUE)
3159 /* If this was marked during register canonicalization,
3160 we know we have to canonicalize values. */
3175 if (has_value && has_other)
3177 for (node = *nodep; node; node = node->next)
3179 if (GET_CODE (node->loc) == VALUE)
3181 decl_or_value dv = dv_from_value (node->loc);
3184 if (shared_hash_shared (dst->vars))
3185 slot = shared_hash_find_slot_noinsert (dst->vars, dv);
3187 slot = shared_hash_find_slot_unshare (&dst->vars, dv,
3191 variable var = (variable) pool_alloc (dv_pool (dv));
3194 var->n_var_parts = 1;
3195 var->var_part[0].offset = 0;
3196 var->var_part[0].loc_chain = NULL;
3197 var->var_part[0].cur_loc = NULL;
3201 VALUE_RECURSED_INTO (node->loc) = true;
3205 dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3206 gcc_assert (*dstslot == dvar);
3207 canonicalize_values_star (dstslot, dst);
3208 #ifdef ENABLE_CHECKING
3210 == shared_hash_find_slot_noinsert_1 (dst->vars,
3213 dvar = (variable)*dstslot;
3217 if (!onepart_variable_different_p (dvar, s2var))
3219 variable_htab_free (dvar);
3220 *dstslot = dvar = s2var;
3223 else if (s2var != s1var && !onepart_variable_different_p (dvar, s1var))
3225 variable_htab_free (dvar);
3226 *dstslot = dvar = s1var;
3228 dst_can_be_shared = false;
3232 if (dvar->refcount == 1)
3233 dvar->var_part[0].cur_loc = dvar->var_part[0].loc_chain->loc;
3234 dst_can_be_shared = false;
3240 /* Combine variable in *S1SLOT (in DSM->src) with the corresponding
3241 entry in DSM->src. Only multi-part variables are combined, using
3242 variable_union. onepart dvs were already combined with
3243 intersection in variable_merge_over_cur(). */
3246 variable_merge_over_src (void **s2slot, void *data)
3248 struct dfset_merge *dsm = (struct dfset_merge *)data;
3249 dataflow_set *dst = dsm->dst;
3250 variable s2var = (variable) *s2slot;
3251 decl_or_value dv = s2var->dv;
3252 bool onepart = dv_onepart_p (dv);
3256 void **dstp = shared_hash_find_slot (dst->vars, dv);
3259 return variable_canonicalize (dstp, dst);
3262 dsm->src_onepart_cnt++;
3266 /* Combine dataflow set information from SRC into DST, using PDST
3267 to carry over information across passes. */
3270 dataflow_set_merge (dataflow_set *dst, dataflow_set *src)
3272 dataflow_set src2 = *dst;
3273 struct dfset_merge dsm;
3275 size_t src_elems, dst_elems;
3277 src_elems = htab_elements (shared_hash_htab (src->vars));
3278 dst_elems = htab_elements (shared_hash_htab (src2.vars));
3279 dataflow_set_init (dst);
3280 dst->stack_adjust = src2.stack_adjust;
3281 shared_hash_destroy (dst->vars);
3282 dst->vars = (shared_hash) pool_alloc (shared_hash_pool);
3283 dst->vars->refcount = 1;
3285 = htab_create (MAX (src_elems, dst_elems), variable_htab_hash,
3286 variable_htab_eq, variable_htab_free);
3288 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3289 attrs_list_mpdv_union (&dst->regs[i], src->regs[i], src2.regs[i]);
3294 dsm.src_onepart_cnt = 0;
3296 htab_traverse (shared_hash_htab (dsm.src->vars), variable_merge_over_src,
3298 htab_traverse (shared_hash_htab (dsm.cur->vars), variable_merge_over_cur,
3301 if (dsm.src_onepart_cnt)
3302 dst_can_be_shared = false;
3304 dataflow_set_destroy (&src2);
3307 /* Mark register equivalences. */
3310 dataflow_set_equiv_regs (dataflow_set *set)
3315 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3317 rtx canon[NUM_MACHINE_MODES];
3319 memset (canon, 0, sizeof (canon));
3321 for (list = set->regs[i]; list; list = list->next)
3322 if (list->offset == 0 && dv_is_value_p (list->dv))
3324 rtx val = dv_as_value (list->dv);
3325 rtx *cvalp = &canon[(int)GET_MODE (val)];
3328 if (canon_value_cmp (val, cval))
3332 for (list = set->regs[i]; list; list = list->next)
3333 if (list->offset == 0 && dv_onepart_p (list->dv))
3335 rtx cval = canon[(int)GET_MODE (list->loc)];
3340 if (dv_is_value_p (list->dv))
3342 rtx val = dv_as_value (list->dv);
3347 VALUE_RECURSED_INTO (val) = true;
3348 set_variable_part (set, val, dv_from_value (cval), 0,
3349 VAR_INIT_STATUS_INITIALIZED,
3353 VALUE_RECURSED_INTO (cval) = true;
3354 set_variable_part (set, cval, list->dv, 0,
3355 VAR_INIT_STATUS_INITIALIZED, NULL, NO_INSERT);
3358 for (listp = &set->regs[i]; (list = *listp);
3359 listp = list ? &list->next : listp)
3360 if (list->offset == 0 && dv_onepart_p (list->dv))
3362 rtx cval = canon[(int)GET_MODE (list->loc)];
3368 if (dv_is_value_p (list->dv))
3370 rtx val = dv_as_value (list->dv);
3371 if (!VALUE_RECURSED_INTO (val))
3375 slot = shared_hash_find_slot_noinsert (set->vars, list->dv);
3376 canonicalize_values_star (slot, set);
3383 /* Remove any redundant values in the location list of VAR, which must
3384 be unshared and 1-part. */
3387 remove_duplicate_values (variable var)
3389 location_chain node, *nodep;
3391 gcc_assert (dv_onepart_p (var->dv));
3392 gcc_assert (var->n_var_parts == 1);
3393 gcc_assert (var->refcount == 1);
3395 for (nodep = &var->var_part[0].loc_chain; (node = *nodep); )
3397 if (GET_CODE (node->loc) == VALUE)
3399 if (VALUE_RECURSED_INTO (node->loc))
3401 /* Remove duplicate value node. */
3402 *nodep = node->next;
3403 pool_free (loc_chain_pool, node);
3407 VALUE_RECURSED_INTO (node->loc) = true;
3409 nodep = &node->next;
3412 for (node = var->var_part[0].loc_chain; node; node = node->next)
3413 if (GET_CODE (node->loc) == VALUE)
3415 gcc_assert (VALUE_RECURSED_INTO (node->loc));
3416 VALUE_RECURSED_INTO (node->loc) = false;
3421 /* Hash table iteration argument passed to variable_post_merge. */
3422 struct dfset_post_merge
3424 /* The new input set for the current block. */
3426 /* Pointer to the permanent input set for the current block, or
3428 dataflow_set **permp;
3431 /* Create values for incoming expressions associated with one-part
3432 variables that don't have value numbers for them. */
3435 variable_post_merge_new_vals (void **slot, void *info)
3437 struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info;
3438 dataflow_set *set = dfpm->set;
3439 variable var = (variable)*slot;
3440 location_chain node;
3442 if (!dv_onepart_p (var->dv) || !var->n_var_parts)
3445 gcc_assert (var->n_var_parts == 1);
3447 if (dv_is_decl_p (var->dv))
3449 bool check_dupes = false;
3452 for (node = var->var_part[0].loc_chain; node; node = node->next)
3454 if (GET_CODE (node->loc) == VALUE)
3455 gcc_assert (!VALUE_RECURSED_INTO (node->loc));
3456 else if (GET_CODE (node->loc) == REG)
3458 attrs att, *attp, *curp = NULL;
3460 if (var->refcount != 1)
3462 slot = unshare_variable (set, slot, var,
3463 VAR_INIT_STATUS_INITIALIZED);
3464 var = (variable)*slot;
3468 for (attp = &set->regs[REGNO (node->loc)]; (att = *attp);
3470 if (att->offset == 0
3471 && GET_MODE (att->loc) == GET_MODE (node->loc))
3473 if (dv_is_value_p (att->dv))
3475 rtx cval = dv_as_value (att->dv);
3480 else if (dv_as_opaque (att->dv) == dv_as_opaque (var->dv))
3488 if ((*curp)->offset == 0
3489 && GET_MODE ((*curp)->loc) == GET_MODE (node->loc)
3490 && dv_as_opaque ((*curp)->dv) == dv_as_opaque (var->dv))
3493 curp = &(*curp)->next;
3504 *dfpm->permp = XNEW (dataflow_set);
3505 dataflow_set_init (*dfpm->permp);
3508 for (att = (*dfpm->permp)->regs[REGNO (node->loc)];
3509 att; att = att->next)
3510 if (GET_MODE (att->loc) == GET_MODE (node->loc))
3512 gcc_assert (att->offset == 0);
3513 gcc_assert (dv_is_value_p (att->dv));
3514 val_reset (set, att->dv);
3521 cval = dv_as_value (cdv);
3525 /* Create a unique value to hold this register,
3526 that ought to be found and reused in
3527 subsequent rounds. */
3529 gcc_assert (!cselib_lookup (node->loc,
3530 GET_MODE (node->loc), 0));
3531 v = cselib_lookup (node->loc, GET_MODE (node->loc), 1);
3532 cselib_preserve_value (v);
3533 cselib_invalidate_rtx (node->loc);
3535 cdv = dv_from_value (cval);
3538 "Created new value %i for reg %i\n",
3539 v->value, REGNO (node->loc));
3542 var_reg_decl_set (*dfpm->permp, node->loc,
3543 VAR_INIT_STATUS_INITIALIZED,
3544 cdv, 0, NULL, INSERT);
3550 /* Remove attribute referring to the decl, which now
3551 uses the value for the register, already existing or
3552 to be added when we bring perm in. */
3555 pool_free (attrs_pool, att);
3560 remove_duplicate_values (var);
3566 /* Reset values in the permanent set that are not associated with the
3567 chosen expression. */
3570 variable_post_merge_perm_vals (void **pslot, void *info)
3572 struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info;
3573 dataflow_set *set = dfpm->set;
3574 variable pvar = (variable)*pslot, var;
3575 location_chain pnode;
3579 gcc_assert (dv_is_value_p (pvar->dv));
3580 gcc_assert (pvar->n_var_parts == 1);
3581 pnode = pvar->var_part[0].loc_chain;
3583 gcc_assert (!pnode->next);
3584 gcc_assert (REG_P (pnode->loc));
3588 var = shared_hash_find (set->vars, dv);
3591 if (find_loc_in_1pdv (pnode->loc, var, shared_hash_htab (set->vars)))
3593 val_reset (set, dv);
3596 for (att = set->regs[REGNO (pnode->loc)]; att; att = att->next)
3597 if (att->offset == 0
3598 && GET_MODE (att->loc) == GET_MODE (pnode->loc)
3599 && dv_is_value_p (att->dv))
3602 /* If there is a value associated with this register already, create
3604 if (att && dv_as_value (att->dv) != dv_as_value (dv))
3606 rtx cval = dv_as_value (att->dv);
3607 set_variable_part (set, cval, dv, 0, pnode->init, NULL, INSERT);
3608 set_variable_part (set, dv_as_value (dv), att->dv, 0, pnode->init,
3613 attrs_list_insert (&set->regs[REGNO (pnode->loc)],
3615 variable_union (pslot, set);
3621 /* Just checking stuff and registering register attributes for
3625 dataflow_post_merge_adjust (dataflow_set *set, dataflow_set **permp)
3627 struct dfset_post_merge dfpm;
3632 htab_traverse (shared_hash_htab (set->vars), variable_post_merge_new_vals,
3635 htab_traverse (shared_hash_htab ((*permp)->vars),
3636 variable_post_merge_perm_vals, &dfpm);
3637 htab_traverse (shared_hash_htab (set->vars), canonicalize_values_star, set);
3640 /* Return a node whose loc is a MEM that refers to EXPR in the
3641 location list of a one-part variable or value VAR, or in that of
3642 any values recursively mentioned in the location lists. */
3644 static location_chain
3645 find_mem_expr_in_1pdv (tree expr, rtx val, htab_t vars)
3647 location_chain node;
3650 location_chain where = NULL;
3655 gcc_assert (GET_CODE (val) == VALUE);
3657 gcc_assert (!VALUE_RECURSED_INTO (val));
3659 dv = dv_from_value (val);
3660 var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
3665 gcc_assert (dv_onepart_p (var->dv));
3667 if (!var->n_var_parts)
3670 gcc_assert (var->var_part[0].offset == 0);
3672 VALUE_RECURSED_INTO (val) = true;
3674 for (node = var->var_part[0].loc_chain; node; node = node->next)
3675 if (MEM_P (node->loc) && MEM_EXPR (node->loc) == expr
3676 && MEM_OFFSET (node->loc) == 0)
3681 else if (GET_CODE (node->loc) == VALUE
3682 && !VALUE_RECURSED_INTO (node->loc)
3683 && (where = find_mem_expr_in_1pdv (expr, node->loc, vars)))
3686 VALUE_RECURSED_INTO (val) = false;
3691 /* Remove all MEMs from the location list of a hash table entry for a
3692 one-part variable, except those whose MEM attributes map back to
3693 the variable itself, directly or within a VALUE.
3695 ??? We could also preserve MEMs that reference stack slots that are
3696 annotated as not addressable. This is arguably even more reliable
3697 than the current heuristic. */
3700 dataflow_set_preserve_mem_locs (void **slot, void *data)
3702 dataflow_set *set = (dataflow_set *) data;
3703 variable var = (variable) *slot;
3705 if (dv_is_decl_p (var->dv) && dv_onepart_p (var->dv))
3707 tree decl = dv_as_decl (var->dv);
3708 location_chain loc, *locp;
3710 if (!var->n_var_parts)
3713 gcc_assert (var->n_var_parts == 1);
3715 if (var->refcount > 1 || shared_hash_shared (set->vars))
3717 for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
3719 /* We want to remove a MEM that doesn't refer to DECL. */
3720 if (GET_CODE (loc->loc) == MEM
3721 && (MEM_EXPR (loc->loc) != decl
3722 || MEM_OFFSET (loc->loc)))
3724 /* We want to move here a MEM that does refer to DECL. */
3725 else if (GET_CODE (loc->loc) == VALUE
3726 && find_mem_expr_in_1pdv (decl, loc->loc,
3727 shared_hash_htab (set->vars)))
3734 slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
3735 var = (variable)*slot;
3736 gcc_assert (var->n_var_parts == 1);
3739 for (locp = &var->var_part[0].loc_chain, loc = *locp;
3742 rtx old_loc = loc->loc;
3743 if (GET_CODE (old_loc) == VALUE)
3745 location_chain mem_node
3746 = find_mem_expr_in_1pdv (decl, loc->loc,
3747 shared_hash_htab (set->vars));
3749 /* ??? This picks up only one out of multiple MEMs that
3750 refer to the same variable. Do we ever need to be
3751 concerned about dealing with more than one, or, given
3752 that they should all map to the same variable
3753 location, their addresses will have been merged and
3754 they will be regarded as equivalent? */
3757 loc->loc = mem_node->loc;
3758 loc->set_src = mem_node->set_src;
3759 loc->init = MIN (loc->init, mem_node->init);
3763 if (GET_CODE (loc->loc) != MEM
3764 || (MEM_EXPR (loc->loc) == decl
3765 && MEM_OFFSET (loc->loc) == 0))
3767 if (old_loc != loc->loc && emit_notes)
3769 add_value_chains (var->dv, loc->loc);
3770 remove_value_chains (var->dv, old_loc);
3777 remove_value_chains (var->dv, old_loc);
3779 pool_free (loc_chain_pool, loc);
3782 if (!var->var_part[0].loc_chain)
3785 if (emit_notes && dv_is_value_p (var->dv))
3786 remove_cselib_value_chains (var->dv);
3787 variable_was_changed (var, set);
3794 /* Remove all MEMs from the location list of a hash table entry for a
3798 dataflow_set_remove_mem_locs (void **slot, void *data)
3800 dataflow_set *set = (dataflow_set *) data;
3801 variable var = (variable) *slot;
3803 if (dv_is_value_p (var->dv))
3805 location_chain loc, *locp;
3806 bool changed = false;
3808 gcc_assert (var->n_var_parts == 1);
3810 if (var->refcount > 1 || shared_hash_shared (set->vars))
3812 for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
3813 if (GET_CODE (loc->loc) == MEM)
3819 slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
3820 var = (variable)*slot;
3821 gcc_assert (var->n_var_parts == 1);
3824 for (locp = &var->var_part[0].loc_chain, loc = *locp;
3827 if (GET_CODE (loc->loc) != MEM)
3834 remove_value_chains (var->dv, loc->loc);
3836 /* If we have deleted the location which was last emitted
3837 we have to emit new location so add the variable to set
3838 of changed variables. */
3839 if (var->var_part[0].cur_loc
3840 && rtx_equal_p (loc->loc, var->var_part[0].cur_loc))
3842 pool_free (loc_chain_pool, loc);
3845 if (!var->var_part[0].loc_chain)
3848 if (emit_notes && dv_is_value_p (var->dv))
3849 remove_cselib_value_chains (var->dv);
3850 gcc_assert (changed);
3854 if (var->n_var_parts && var->var_part[0].loc_chain)
3855 var->var_part[0].cur_loc = var->var_part[0].loc_chain->loc;
3856 variable_was_changed (var, set);
3863 /* Remove all variable-location information about call-clobbered
3864 registers, as well as associations between MEMs and VALUEs. */
3867 dataflow_set_clear_at_call (dataflow_set *set)
3871 for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
3872 if (TEST_HARD_REG_BIT (call_used_reg_set, r))
3873 var_regno_delete (set, r);
3875 if (MAY_HAVE_DEBUG_INSNS)
3877 set->traversed_vars = set->vars;
3878 htab_traverse (shared_hash_htab (set->vars),
3879 dataflow_set_preserve_mem_locs, set);
3880 set->traversed_vars = set->vars;
3881 htab_traverse (shared_hash_htab (set->vars), dataflow_set_remove_mem_locs,
3883 set->traversed_vars = NULL;
3887 /* Flag whether two dataflow sets being compared contain different data. */
3889 dataflow_set_different_value;
3892 variable_part_different_p (variable_part *vp1, variable_part *vp2)
3894 location_chain lc1, lc2;
3896 for (lc1 = vp1->loc_chain; lc1; lc1 = lc1->next)
3898 for (lc2 = vp2->loc_chain; lc2; lc2 = lc2->next)
3900 if (REG_P (lc1->loc) && REG_P (lc2->loc))
3902 if (REGNO (lc1->loc) == REGNO (lc2->loc))
3905 if (rtx_equal_p (lc1->loc, lc2->loc))
3914 /* Return true if one-part variables VAR1 and VAR2 are different.
3915 They must be in canonical order. */
3918 onepart_variable_different_p (variable var1, variable var2)
3920 location_chain lc1, lc2;
3925 gcc_assert (var1->n_var_parts == 1);
3926 gcc_assert (var2->n_var_parts == 1);
3928 lc1 = var1->var_part[0].loc_chain;
3929 lc2 = var2->var_part[0].loc_chain;
3936 if (loc_cmp (lc1->loc, lc2->loc))
3945 /* Return true if variables VAR1 and VAR2 are different.
3946 If COMPARE_CURRENT_LOCATION is true compare also the cur_loc of each
3950 variable_different_p (variable var1, variable var2,
3951 bool compare_current_location)
3958 if (var1->n_var_parts != var2->n_var_parts)
3961 for (i = 0; i < var1->n_var_parts; i++)
3963 if (var1->var_part[i].offset != var2->var_part[i].offset)
3965 if (compare_current_location)
3967 if (!((REG_P (var1->var_part[i].cur_loc)
3968 && REG_P (var2->var_part[i].cur_loc)
3969 && (REGNO (var1->var_part[i].cur_loc)
3970 == REGNO (var2->var_part[i].cur_loc)))
3971 || rtx_equal_p (var1->var_part[i].cur_loc,
3972 var2->var_part[i].cur_loc)))
3975 /* One-part values have locations in a canonical order. */
3976 if (i == 0 && var1->var_part[i].offset == 0 && dv_onepart_p (var1->dv))
3978 gcc_assert (var1->n_var_parts == 1);
3979 gcc_assert (dv_as_opaque (var1->dv) == dv_as_opaque (var2->dv));
3980 return onepart_variable_different_p (var1, var2);
3982 if (variable_part_different_p (&var1->var_part[i], &var2->var_part[i]))
3984 if (variable_part_different_p (&var2->var_part[i], &var1->var_part[i]))
3990 /* Compare variable *SLOT with the same variable in hash table DATA
3991 and set DATAFLOW_SET_DIFFERENT_VALUE if they are different. */
3994 dataflow_set_different_1 (void **slot, void *data)
3996 htab_t htab = (htab_t) data;
3997 variable var1, var2;
3999 var1 = (variable) *slot;
4000 var2 = (variable) htab_find_with_hash (htab, var1->dv,
4001 dv_htab_hash (var1->dv));
4004 dataflow_set_different_value = true;
4006 if (dump_file && (dump_flags & TDF_DETAILS))
4008 fprintf (dump_file, "dataflow difference found: removal of:\n");
4009 dump_variable (var1);
4012 /* Stop traversing the hash table. */
4016 if (variable_different_p (var1, var2, false))
4018 dataflow_set_different_value = true;
4020 if (dump_file && (dump_flags & TDF_DETAILS))
4022 fprintf (dump_file, "dataflow difference found: old and new follow:\n");
4023 dump_variable (var1);
4024 dump_variable (var2);
4027 /* Stop traversing the hash table. */
4031 /* Continue traversing the hash table. */
4035 /* Return true if dataflow sets OLD_SET and NEW_SET differ. */
4038 dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
4040 if (old_set->vars == new_set->vars)
4043 if (htab_elements (shared_hash_htab (old_set->vars))
4044 != htab_elements (shared_hash_htab (new_set->vars)))
4047 dataflow_set_different_value = false;
4049 htab_traverse (shared_hash_htab (old_set->vars), dataflow_set_different_1,
4050 shared_hash_htab (new_set->vars));
4051 /* No need to traverse the second hashtab, if both have the same number
4052 of elements and the second one had all entries found in the first one,
4053 then it can't have any extra entries. */
4054 return dataflow_set_different_value;
4057 /* Free the contents of dataflow set SET. */
4060 dataflow_set_destroy (dataflow_set *set)
4064 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4065 attrs_list_clear (&set->regs[i]);
4067 shared_hash_destroy (set->vars);
4071 /* Return true if RTL X contains a SYMBOL_REF. */
4074 contains_symbol_ref (rtx x)
4083 code = GET_CODE (x);
4084 if (code == SYMBOL_REF)
4087 fmt = GET_RTX_FORMAT (code);
4088 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4092 if (contains_symbol_ref (XEXP (x, i)))
4095 else if (fmt[i] == 'E')
4098 for (j = 0; j < XVECLEN (x, i); j++)
4099 if (contains_symbol_ref (XVECEXP (x, i, j)))
4107 /* Shall EXPR be tracked? */
4110 track_expr_p (tree expr, bool need_rtl)
4115 /* If EXPR is not a parameter or a variable do not track it. */
4116 if (TREE_CODE (expr) != VAR_DECL && TREE_CODE (expr) != PARM_DECL)
4119 /* It also must have a name... */
4120 if (!DECL_NAME (expr))
4123 /* ... and a RTL assigned to it. */
4124 decl_rtl = DECL_RTL_IF_SET (expr);
4125 if (!decl_rtl && need_rtl)
4128 /* If this expression is really a debug alias of some other declaration, we
4129 don't need to track this expression if the ultimate declaration is
4132 if (DECL_DEBUG_EXPR_IS_FROM (realdecl) && DECL_DEBUG_EXPR (realdecl))
4134 realdecl = DECL_DEBUG_EXPR (realdecl);
4135 /* ??? We don't yet know how to emit DW_OP_piece for variable
4136 that has been SRA'ed. */
4137 if (!DECL_P (realdecl))
4141 /* Do not track EXPR if REALDECL it should be ignored for debugging
4143 if (DECL_IGNORED_P (realdecl))
4146 /* Do not track global variables until we are able to emit correct location
4148 if (TREE_STATIC (realdecl))
4151 /* When the EXPR is a DECL for alias of some variable (see example)
4152 the TREE_STATIC flag is not used. Disable tracking all DECLs whose
4153 DECL_RTL contains SYMBOL_REF.
4156 extern char **_dl_argv_internal __attribute__ ((alias ("_dl_argv")));
4159 if (decl_rtl && MEM_P (decl_rtl)
4160 && contains_symbol_ref (XEXP (decl_rtl, 0)))
4163 /* If RTX is a memory it should not be very large (because it would be
4164 an array or struct). */
4165 if (decl_rtl && MEM_P (decl_rtl))
4167 /* Do not track structures and arrays. */
4168 if (GET_MODE (decl_rtl) == BLKmode
4169 || AGGREGATE_TYPE_P (TREE_TYPE (realdecl)))
4171 if (MEM_SIZE (decl_rtl)
4172 && INTVAL (MEM_SIZE (decl_rtl)) > MAX_VAR_PARTS)
4176 DECL_CHANGED (expr) = 0;
4177 DECL_CHANGED (realdecl) = 0;
4181 /* Determine whether a given LOC refers to the same variable part as
4185 same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset)
4188 HOST_WIDE_INT offset2;
4190 if (! DECL_P (expr))
4195 expr2 = REG_EXPR (loc);
4196 offset2 = REG_OFFSET (loc);
4198 else if (MEM_P (loc))
4200 expr2 = MEM_EXPR (loc);
4201 offset2 = INT_MEM_OFFSET (loc);
4206 if (! expr2 || ! DECL_P (expr2))
4209 expr = var_debug_decl (expr);
4210 expr2 = var_debug_decl (expr2);
4212 return (expr == expr2 && offset == offset2);
4215 /* LOC is a REG or MEM that we would like to track if possible.
4216 If EXPR is null, we don't know what expression LOC refers to,
4217 otherwise it refers to EXPR + OFFSET. STORE_REG_P is true if
4218 LOC is an lvalue register.
4220 Return true if EXPR is nonnull and if LOC, or some lowpart of it,
4221 is something we can track. When returning true, store the mode of
4222 the lowpart we can track in *MODE_OUT (if nonnull) and its offset
4223 from EXPR in *OFFSET_OUT (if nonnull). */
4226 track_loc_p (rtx loc, tree expr, HOST_WIDE_INT offset, bool store_reg_p,
4227 enum machine_mode *mode_out, HOST_WIDE_INT *offset_out)
4229 enum machine_mode mode;
4231 if (expr == NULL || !track_expr_p (expr, true))
4234 /* If REG was a paradoxical subreg, its REG_ATTRS will describe the
4235 whole subreg, but only the old inner part is really relevant. */
4236 mode = GET_MODE (loc);
4237 if (REG_P (loc) && !HARD_REGISTER_NUM_P (ORIGINAL_REGNO (loc)))
4239 enum machine_mode pseudo_mode;
4241 pseudo_mode = PSEUDO_REGNO_MODE (ORIGINAL_REGNO (loc));
4242 if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (pseudo_mode))
4244 offset += byte_lowpart_offset (pseudo_mode, mode);
4249 /* If LOC is a paradoxical lowpart of EXPR, refer to EXPR itself.
4250 Do the same if we are storing to a register and EXPR occupies
4251 the whole of register LOC; in that case, the whole of EXPR is
4252 being changed. We exclude complex modes from the second case
4253 because the real and imaginary parts are represented as separate
4254 pseudo registers, even if the whole complex value fits into one
4256 if ((GET_MODE_SIZE (mode) > GET_MODE_SIZE (DECL_MODE (expr))
4258 && !COMPLEX_MODE_P (DECL_MODE (expr))
4259 && hard_regno_nregs[REGNO (loc)][DECL_MODE (expr)] == 1))
4260 && offset + byte_lowpart_offset (DECL_MODE (expr), mode) == 0)
4262 mode = DECL_MODE (expr);
4266 if (offset < 0 || offset >= MAX_VAR_PARTS)
4272 *offset_out = offset;
4276 /* Return the MODE lowpart of LOC, or null if LOC is not something we
4277 want to track. When returning nonnull, make sure that the attributes
4278 on the returned value are updated. */
4281 var_lowpart (enum machine_mode mode, rtx loc)
4283 unsigned int offset, reg_offset, regno;
4285 if (!REG_P (loc) && !MEM_P (loc))
4288 if (GET_MODE (loc) == mode)
4291 offset = byte_lowpart_offset (mode, GET_MODE (loc));
4294 return adjust_address_nv (loc, mode, offset);
4296 reg_offset = subreg_lowpart_offset (mode, GET_MODE (loc));
4297 regno = REGNO (loc) + subreg_regno_offset (REGNO (loc), GET_MODE (loc),
4299 return gen_rtx_REG_offset (loc, mode, regno, offset);
4302 /* Carry information about uses and stores while walking rtx. */
4304 struct count_use_info
4306 /* The insn where the RTX is. */
4309 /* The basic block where insn is. */
4312 /* The array of n_sets sets in the insn, as determined by cselib. */
4313 struct cselib_set *sets;
4316 /* True if we're counting stores, false otherwise. */
4320 /* Find a VALUE corresponding to X. */
4322 static inline cselib_val *
4323 find_use_val (rtx x, enum machine_mode mode, struct count_use_info *cui)
4329 /* This is called after uses are set up and before stores are
4330 processed bycselib, so it's safe to look up srcs, but not
4331 dsts. So we look up expressions that appear in srcs or in
4332 dest expressions, but we search the sets array for dests of
4336 for (i = 0; i < cui->n_sets; i++)
4337 if (cui->sets[i].dest == x)
4338 return cui->sets[i].src_elt;
4341 return cselib_lookup (x, mode, 0);
4347 /* Replace all registers and addresses in an expression with VALUE
4348 expressions that map back to them, unless the expression is a
4349 register. If no mapping is or can be performed, returns NULL. */
4352 replace_expr_with_values (rtx loc)
4356 else if (MEM_P (loc))
4358 cselib_val *addr = cselib_lookup (XEXP (loc, 0), Pmode, 0);
4360 return replace_equiv_address_nv (loc, addr->val_rtx);
4365 return cselib_subst_to_values (loc);
4368 /* Determine what kind of micro operation to choose for a USE. Return
4369 MO_CLOBBER if no micro operation is to be generated. */
4371 static enum micro_operation_type
4372 use_type (rtx *loc, struct count_use_info *cui, enum machine_mode *modep)
4377 if (cui && cui->sets)
4379 if (GET_CODE (*loc) == VAR_LOCATION)
4381 if (track_expr_p (PAT_VAR_LOCATION_DECL (*loc), false))
4383 rtx ploc = PAT_VAR_LOCATION_LOC (*loc);
4384 cselib_val *val = cselib_lookup (ploc, GET_MODE (*loc), 1);
4386 /* ??? flag_float_store and volatile mems are never
4387 given values, but we could in theory use them for
4389 gcc_assert (val || 1);
4396 if ((REG_P (*loc) || MEM_P (*loc))
4397 && (val = find_use_val (*loc, GET_MODE (*loc), cui)))
4400 *modep = GET_MODE (*loc);
4404 || cselib_lookup (XEXP (*loc, 0), GET_MODE (*loc), 0))
4407 else if (!cselib_preserved_value_p (val))
4414 gcc_assert (REGNO (*loc) < FIRST_PSEUDO_REGISTER);
4416 expr = REG_EXPR (*loc);
4419 return MO_USE_NO_VAR;
4420 else if (target_for_debug_bind (var_debug_decl (expr)))
4422 else if (track_loc_p (*loc, expr, REG_OFFSET (*loc),
4423 false, modep, NULL))
4426 return MO_USE_NO_VAR;
4428 else if (MEM_P (*loc))
4430 expr = MEM_EXPR (*loc);
4434 else if (target_for_debug_bind (var_debug_decl (expr)))
4436 else if (track_loc_p (*loc, expr, INT_MEM_OFFSET (*loc),
4437 false, modep, NULL))
4446 /* Log to OUT information about micro-operation MOPT involving X in
4450 log_op_type (rtx x, basic_block bb, rtx insn,
4451 enum micro_operation_type mopt, FILE *out)
4453 fprintf (out, "bb %i op %i insn %i %s ",
4454 bb->index, VTI (bb)->n_mos - 1,
4455 INSN_UID (insn), micro_operation_type_name[mopt]);
4456 print_inline_rtx (out, x, 2);
4460 /* Count uses (register and memory references) LOC which will be tracked.
4461 INSN is instruction which the LOC is part of. */
4464 count_uses (rtx *loc, void *cuip)
4466 struct count_use_info *cui = (struct count_use_info *) cuip;
4467 enum micro_operation_type mopt = use_type (loc, cui, NULL);
4469 if (mopt != MO_CLOBBER)
4472 enum machine_mode mode = GET_MODE (*loc);
4474 VTI (cui->bb)->n_mos++;
4476 if (dump_file && (dump_flags & TDF_DETAILS))
4477 log_op_type (*loc, cui->bb, cui->insn, mopt, dump_file);
4482 loc = &PAT_VAR_LOCATION_LOC (*loc);
4483 if (VAR_LOC_UNKNOWN_P (*loc))
4490 && !REG_P (XEXP (*loc, 0)) && !MEM_P (XEXP (*loc, 0)))
4492 val = cselib_lookup (XEXP (*loc, 0), Pmode, false);
4494 if (val && !cselib_preserved_value_p (val))
4496 VTI (cui->bb)->n_mos++;
4497 cselib_preserve_value (val);
4501 val = find_use_val (*loc, mode, cui);
4503 cselib_preserve_value (val);
4505 gcc_assert (mopt == MO_VAL_LOC);
4517 /* Helper function for finding all uses of REG/MEM in X in CUI's
4521 count_uses_1 (rtx *x, void *cui)
4523 for_each_rtx (x, count_uses, cui);
4526 /* Count stores (register and memory references) LOC which will be
4527 tracked. CUI is a count_use_info object containing the instruction
4528 which the LOC is part of. */
4531 count_stores (rtx loc, const_rtx expr ATTRIBUTE_UNUSED, void *cui)
4533 count_uses (&loc, cui);
4536 /* Callback for cselib_record_sets_hook, that counts how many micro
4537 operations it takes for uses and stores in an insn after
4538 cselib_record_sets has analyzed the sets in an insn, but before it
4539 modifies the stored values in the internal tables, unless
4540 cselib_record_sets doesn't call it directly (perhaps because we're
4541 not doing cselib in the first place, in which case sets and n_sets
4545 count_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
4547 basic_block bb = BLOCK_FOR_INSN (insn);
4548 struct count_use_info cui;
4550 cselib_hook_called = true;
4555 cui.n_sets = n_sets;
4557 cui.store_p = false;
4558 note_uses (&PATTERN (insn), count_uses_1, &cui);
4560 note_stores (PATTERN (insn), count_stores, &cui);
4563 /* Tell whether the CONCAT used to holds a VALUE and its location
4564 needs value resolution, i.e., an attempt of mapping the location
4565 back to other incoming values. */
4566 #define VAL_NEEDS_RESOLUTION(x) \
4567 (RTL_FLAG_CHECK1 ("VAL_NEEDS_RESOLUTION", (x), CONCAT)->volatil)
4568 /* Whether the location in the CONCAT is a tracked expression, that
4569 should also be handled like a MO_USE. */
4570 #define VAL_HOLDS_TRACK_EXPR(x) \
4571 (RTL_FLAG_CHECK1 ("VAL_HOLDS_TRACK_EXPR", (x), CONCAT)->used)
4572 /* Whether the location in the CONCAT should be handled like a MO_COPY
4574 #define VAL_EXPR_IS_COPIED(x) \
4575 (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_COPIED", (x), CONCAT)->jump)
4576 /* Whether the location in the CONCAT should be handled like a
4577 MO_CLOBBER as well. */
4578 #define VAL_EXPR_IS_CLOBBERED(x) \
4579 (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_CLOBBERED", (x), CONCAT)->unchanging)
4581 /* Add uses (register and memory references) LOC which will be tracked
4582 to VTI (bb)->mos. INSN is instruction which the LOC is part of. */
4585 add_uses (rtx *loc, void *data)
4587 enum machine_mode mode = VOIDmode;
4588 struct count_use_info *cui = (struct count_use_info *)data;
4589 enum micro_operation_type type = use_type (loc, cui, &mode);
4591 if (type != MO_CLOBBER)
4593 basic_block bb = cui->bb;
4594 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
4597 mo->u.loc = type == MO_USE ? var_lowpart (mode, *loc) : *loc;
4598 mo->insn = cui->insn;
4600 if (type == MO_VAL_LOC)
4603 rtx vloc = PAT_VAR_LOCATION_LOC (oloc);
4606 gcc_assert (cui->sets);
4609 && !REG_P (XEXP (vloc, 0)) && !MEM_P (XEXP (vloc, 0)))
4612 cselib_val *val = cselib_lookup (XEXP (mloc, 0), Pmode, 0);
4614 if (val && !cselib_preserved_value_p (val))
4616 micro_operation *mon = VTI (bb)->mos + VTI (bb)->n_mos++;
4617 mon->type = mo->type;
4618 mon->u.loc = mo->u.loc;
4619 mon->insn = mo->insn;
4620 cselib_preserve_value (val);
4621 mo->type = MO_VAL_USE;
4622 mloc = cselib_subst_to_values (XEXP (mloc, 0));
4623 mo->u.loc = gen_rtx_CONCAT (Pmode, val->val_rtx, mloc);
4624 if (dump_file && (dump_flags & TDF_DETAILS))
4625 log_op_type (mo->u.loc, cui->bb, cui->insn,
4626 mo->type, dump_file);
4631 if (!VAR_LOC_UNKNOWN_P (vloc)
4632 && (val = find_use_val (vloc, GET_MODE (oloc), cui)))
4634 enum machine_mode mode2;
4635 enum micro_operation_type type2;
4636 rtx nloc = replace_expr_with_values (vloc);
4640 oloc = shallow_copy_rtx (oloc);
4641 PAT_VAR_LOCATION_LOC (oloc) = nloc;
4644 oloc = gen_rtx_CONCAT (mode, val->val_rtx, oloc);
4646 type2 = use_type (&vloc, 0, &mode2);
4648 gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
4649 || type2 == MO_CLOBBER);
4651 if (type2 == MO_CLOBBER
4652 && !cselib_preserved_value_p (val))
4654 VAL_NEEDS_RESOLUTION (oloc) = 1;
4655 cselib_preserve_value (val);
4658 else if (!VAR_LOC_UNKNOWN_P (vloc))
4660 oloc = shallow_copy_rtx (oloc);
4661 PAT_VAR_LOCATION_LOC (oloc) = gen_rtx_UNKNOWN_VAR_LOC ();
4666 else if (type == MO_VAL_USE)
4668 enum machine_mode mode2 = VOIDmode;
4669 enum micro_operation_type type2;
4670 cselib_val *val = find_use_val (*loc, GET_MODE (*loc), cui);
4671 rtx vloc, oloc = *loc, nloc;
4673 gcc_assert (cui->sets);
4676 && !REG_P (XEXP (oloc, 0)) && !MEM_P (XEXP (oloc, 0)))
4679 cselib_val *val = cselib_lookup (XEXP (mloc, 0), Pmode, 0);
4681 if (val && !cselib_preserved_value_p (val))
4683 micro_operation *mon = VTI (bb)->mos + VTI (bb)->n_mos++;
4684 mon->type = mo->type;
4685 mon->u.loc = mo->u.loc;
4686 mon->insn = mo->insn;
4687 cselib_preserve_value (val);
4688 mo->type = MO_VAL_USE;
4689 mloc = cselib_subst_to_values (XEXP (mloc, 0));
4690 mo->u.loc = gen_rtx_CONCAT (Pmode, val->val_rtx, mloc);
4691 mo->insn = cui->insn;
4692 if (dump_file && (dump_flags & TDF_DETAILS))
4693 log_op_type (mo->u.loc, cui->bb, cui->insn,
4694 mo->type, dump_file);
4699 type2 = use_type (loc, 0, &mode2);
4701 gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
4702 || type2 == MO_CLOBBER);
4704 if (type2 == MO_USE)
4705 vloc = var_lowpart (mode2, *loc);
4709 /* The loc of a MO_VAL_USE may have two forms:
4711 (concat val src): val is at src, a value-based
4714 (concat (concat val use) src): same as above, with use as
4715 the MO_USE tracked value, if it differs from src.
4719 nloc = replace_expr_with_values (*loc);
4724 oloc = gen_rtx_CONCAT (mode2, val->val_rtx, vloc);
4726 oloc = val->val_rtx;
4728 mo->u.loc = gen_rtx_CONCAT (mode, oloc, nloc);
4730 if (type2 == MO_USE)
4731 VAL_HOLDS_TRACK_EXPR (mo->u.loc) = 1;
4732 if (!cselib_preserved_value_p (val))
4734 VAL_NEEDS_RESOLUTION (mo->u.loc) = 1;
4735 cselib_preserve_value (val);
4739 gcc_assert (type == MO_USE || type == MO_USE_NO_VAR);
4741 if (dump_file && (dump_flags & TDF_DETAILS))
4742 log_op_type (mo->u.loc, cui->bb, cui->insn, mo->type, dump_file);
4748 /* Helper function for finding all uses of REG/MEM in X in insn INSN. */
4751 add_uses_1 (rtx *x, void *cui)
4753 for_each_rtx (x, add_uses, cui);
4756 /* Add stores (register and memory references) LOC which will be tracked
4757 to VTI (bb)->mos. EXPR is the RTL expression containing the store.
4758 CUIP->insn is instruction which the LOC is part of. */
4761 add_stores (rtx loc, const_rtx expr, void *cuip)
4763 enum machine_mode mode = VOIDmode, mode2;
4764 struct count_use_info *cui = (struct count_use_info *)cuip;
4765 basic_block bb = cui->bb;
4766 micro_operation *mo;
4767 rtx oloc = loc, nloc, src = NULL;
4768 enum micro_operation_type type = use_type (&loc, cui, &mode);
4769 bool track_p = false;
4771 bool resolve, preserve;
4773 if (type == MO_CLOBBER)
4780 mo = VTI (bb)->mos + VTI (bb)->n_mos++;
4782 if ((GET_CODE (expr) == CLOBBER && type != MO_VAL_SET)
4783 || !(track_p = use_type (&loc, NULL, &mode2) == MO_USE)
4784 || GET_CODE (expr) == CLOBBER)
4786 mo->type = MO_CLOBBER;
4791 if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
4792 src = var_lowpart (mode2, SET_SRC (expr));
4793 loc = var_lowpart (mode2, loc);
4802 if (SET_SRC (expr) != src)
4803 expr = gen_rtx_SET (VOIDmode, loc, src);
4804 if (same_variable_part_p (src, REG_EXPR (loc), REG_OFFSET (loc)))
4808 mo->u.loc = CONST_CAST_RTX (expr);
4811 mo->insn = cui->insn;
4813 else if (MEM_P (loc)
4814 && ((track_p = use_type (&loc, NULL, &mode2) == MO_USE)
4817 mo = VTI (bb)->mos + VTI (bb)->n_mos++;
4819 if (MEM_P (loc) && type == MO_VAL_SET
4820 && !REG_P (XEXP (loc, 0)) && !MEM_P (XEXP (loc, 0)))
4823 cselib_val *val = cselib_lookup (XEXP (mloc, 0), Pmode, 0);
4825 if (val && !cselib_preserved_value_p (val))
4827 cselib_preserve_value (val);
4828 mo->type = MO_VAL_USE;
4829 mloc = cselib_subst_to_values (XEXP (mloc, 0));
4830 mo->u.loc = gen_rtx_CONCAT (Pmode, val->val_rtx, mloc);
4831 mo->insn = cui->insn;
4832 if (dump_file && (dump_flags & TDF_DETAILS))
4833 log_op_type (mo->u.loc, cui->bb, cui->insn,
4834 mo->type, dump_file);
4835 mo = VTI (bb)->mos + VTI (bb)->n_mos++;
4839 if (GET_CODE (expr) == CLOBBER || !track_p)
4841 mo->type = MO_CLOBBER;
4842 mo->u.loc = track_p ? var_lowpart (mode2, loc) : loc;
4846 if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
4847 src = var_lowpart (mode2, SET_SRC (expr));
4848 loc = var_lowpart (mode2, loc);
4857 if (SET_SRC (expr) != src)
4858 expr = gen_rtx_SET (VOIDmode, loc, src);
4859 if (same_variable_part_p (SET_SRC (expr),
4861 INT_MEM_OFFSET (loc)))
4865 mo->u.loc = CONST_CAST_RTX (expr);
4868 mo->insn = cui->insn;
4873 if (type != MO_VAL_SET)
4874 goto log_and_return;
4876 v = find_use_val (oloc, mode, cui);
4878 resolve = preserve = !cselib_preserved_value_p (v);
4880 nloc = replace_expr_with_values (oloc);
4884 if (resolve && GET_CODE (mo->u.loc) == SET)
4886 nloc = replace_expr_with_values (SET_SRC (mo->u.loc));
4889 oloc = gen_rtx_SET (GET_MODE (mo->u.loc), oloc, nloc);
4892 if (oloc == SET_DEST (mo->u.loc))
4893 /* No point in duplicating. */
4895 if (!REG_P (SET_SRC (mo->u.loc)))
4901 if (GET_CODE (mo->u.loc) == SET
4902 && oloc == SET_DEST (mo->u.loc))
4903 /* No point in duplicating. */
4909 loc = gen_rtx_CONCAT (mode, v->val_rtx, oloc);
4911 if (mo->u.loc != oloc)
4912 loc = gen_rtx_CONCAT (GET_MODE (mo->u.loc), loc, mo->u.loc);
4914 /* The loc of a MO_VAL_SET may have various forms:
4916 (concat val dst): dst now holds val
4918 (concat val (set dst src)): dst now holds val, copied from src
4920 (concat (concat val dstv) dst): dst now holds val; dstv is dst
4921 after replacing mems and non-top-level regs with values.
4923 (concat (concat val dstv) (set dst src)): dst now holds val,
4924 copied from src. dstv is a value-based representation of dst, if
4925 it differs from dst. If resolution is needed, src is a REG.
4927 (concat (concat val (set dstv srcv)) (set dst src)): src
4928 copied to dst, holding val. dstv and srcv are value-based
4929 representations of dst and src, respectively.
4936 VAL_HOLDS_TRACK_EXPR (loc) = 1;
4939 VAL_NEEDS_RESOLUTION (loc) = resolve;
4940 cselib_preserve_value (v);
4942 if (mo->type == MO_CLOBBER)
4943 VAL_EXPR_IS_CLOBBERED (loc) = 1;
4944 if (mo->type == MO_COPY)
4945 VAL_EXPR_IS_COPIED (loc) = 1;
4947 mo->type = MO_VAL_SET;
4950 if (dump_file && (dump_flags & TDF_DETAILS))
4951 log_op_type (mo->u.loc, cui->bb, cui->insn, mo->type, dump_file);
4954 /* Callback for cselib_record_sets_hook, that records as micro
4955 operations uses and stores in an insn after cselib_record_sets has
4956 analyzed the sets in an insn, but before it modifies the stored
4957 values in the internal tables, unless cselib_record_sets doesn't
4958 call it directly (perhaps because we're not doing cselib in the
4959 first place, in which case sets and n_sets will be 0). */
4962 add_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
4964 basic_block bb = BLOCK_FOR_INSN (insn);
4966 struct count_use_info cui;
4968 cselib_hook_called = true;
4973 cui.n_sets = n_sets;
4975 n1 = VTI (bb)->n_mos;
4976 cui.store_p = false;
4977 note_uses (&PATTERN (insn), add_uses_1, &cui);
4978 n2 = VTI (bb)->n_mos - 1;
4980 /* Order the MO_USEs to be before MO_USE_NO_VARs and MO_VAL_USE, and
4984 while (n1 < n2 && VTI (bb)->mos[n1].type == MO_USE)
4986 while (n1 < n2 && VTI (bb)->mos[n2].type != MO_USE)
4992 sw = VTI (bb)->mos[n1];
4993 VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
4994 VTI (bb)->mos[n2] = sw;
4998 n2 = VTI (bb)->n_mos - 1;
5002 while (n1 < n2 && VTI (bb)->mos[n1].type != MO_VAL_LOC)
5004 while (n1 < n2 && VTI (bb)->mos[n2].type == MO_VAL_LOC)
5010 sw = VTI (bb)->mos[n1];
5011 VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
5012 VTI (bb)->mos[n2] = sw;
5018 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
5023 if (dump_file && (dump_flags & TDF_DETAILS))
5024 log_op_type (PATTERN (insn), bb, insn, mo->type, dump_file);
5027 n1 = VTI (bb)->n_mos;
5028 /* This will record NEXT_INSN (insn), such that we can
5029 insert notes before it without worrying about any
5030 notes that MO_USEs might emit after the insn. */
5032 note_stores (PATTERN (insn), add_stores, &cui);
5033 n2 = VTI (bb)->n_mos - 1;
5035 /* Order the MO_CLOBBERs to be before MO_SETs. */
5038 while (n1 < n2 && VTI (bb)->mos[n1].type == MO_CLOBBER)
5040 while (n1 < n2 && VTI (bb)->mos[n2].type != MO_CLOBBER)
5046 sw = VTI (bb)->mos[n1];
5047 VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
5048 VTI (bb)->mos[n2] = sw;
5053 static enum var_init_status
5054 find_src_status (dataflow_set *in, rtx src)
5056 tree decl = NULL_TREE;
5057 enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
5059 if (! flag_var_tracking_uninit)
5060 status = VAR_INIT_STATUS_INITIALIZED;
5062 if (src && REG_P (src))
5063 decl = var_debug_decl (REG_EXPR (src));
5064 else if (src && MEM_P (src))
5065 decl = var_debug_decl (MEM_EXPR (src));
5068 status = get_init_value (in, src, dv_from_decl (decl));
5073 /* SRC is the source of an assignment. Use SET to try to find what
5074 was ultimately assigned to SRC. Return that value if known,
5075 otherwise return SRC itself. */
5078 find_src_set_src (dataflow_set *set, rtx src)
5080 tree decl = NULL_TREE; /* The variable being copied around. */
5081 rtx set_src = NULL_RTX; /* The value for "decl" stored in "src". */
5083 location_chain nextp;
5087 if (src && REG_P (src))
5088 decl = var_debug_decl (REG_EXPR (src));
5089 else if (src && MEM_P (src))
5090 decl = var_debug_decl (MEM_EXPR (src));
5094 decl_or_value dv = dv_from_decl (decl);
5096 var = shared_hash_find (set->vars, dv);
5100 for (i = 0; i < var->n_var_parts && !found; i++)
5101 for (nextp = var->var_part[i].loc_chain; nextp && !found;
5102 nextp = nextp->next)
5103 if (rtx_equal_p (nextp->loc, src))
5105 set_src = nextp->set_src;
5115 /* Compute the changes of variable locations in the basic block BB. */
5118 compute_bb_dataflow (basic_block bb)
5122 dataflow_set old_out;
5123 dataflow_set *in = &VTI (bb)->in;
5124 dataflow_set *out = &VTI (bb)->out;
5126 dataflow_set_init (&old_out);
5127 dataflow_set_copy (&old_out, out);
5128 dataflow_set_copy (out, in);
5130 n = VTI (bb)->n_mos;
5131 for (i = 0; i < n; i++)
5133 rtx insn = VTI (bb)->mos[i].insn;
5135 switch (VTI (bb)->mos[i].type)
5138 dataflow_set_clear_at_call (out);
5143 rtx loc = VTI (bb)->mos[i].u.loc;
5146 var_reg_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
5147 else if (MEM_P (loc))
5148 var_mem_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
5154 rtx loc = VTI (bb)->mos[i].u.loc;
5158 if (GET_CODE (loc) == CONCAT)
5160 val = XEXP (loc, 0);
5161 vloc = XEXP (loc, 1);
5169 var = PAT_VAR_LOCATION_DECL (vloc);
5171 clobber_variable_part (out, NULL_RTX,
5172 dv_from_decl (var), 0, NULL_RTX);
5175 if (VAL_NEEDS_RESOLUTION (loc))
5176 val_resolve (out, val, PAT_VAR_LOCATION_LOC (vloc), insn);
5177 set_variable_part (out, val, dv_from_decl (var), 0,
5178 VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
5186 rtx loc = VTI (bb)->mos[i].u.loc;
5187 rtx val, vloc, uloc;
5189 vloc = uloc = XEXP (loc, 1);
5190 val = XEXP (loc, 0);
5192 if (GET_CODE (val) == CONCAT)
5194 uloc = XEXP (val, 1);
5195 val = XEXP (val, 0);
5198 if (VAL_NEEDS_RESOLUTION (loc))
5199 val_resolve (out, val, vloc, insn);
5201 if (VAL_HOLDS_TRACK_EXPR (loc))
5203 if (GET_CODE (uloc) == REG)
5204 var_reg_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
5206 else if (GET_CODE (uloc) == MEM)
5207 var_mem_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
5215 rtx loc = VTI (bb)->mos[i].u.loc;
5216 rtx val, vloc, uloc;
5218 vloc = uloc = XEXP (loc, 1);
5219 val = XEXP (loc, 0);
5221 if (GET_CODE (val) == CONCAT)
5223 vloc = XEXP (val, 1);
5224 val = XEXP (val, 0);
5227 if (GET_CODE (vloc) == SET)
5229 rtx vsrc = SET_SRC (vloc);
5231 gcc_assert (val != vsrc);
5232 gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
5234 vloc = SET_DEST (vloc);
5236 if (VAL_NEEDS_RESOLUTION (loc))
5237 val_resolve (out, val, vsrc, insn);
5239 else if (VAL_NEEDS_RESOLUTION (loc))
5241 gcc_assert (GET_CODE (uloc) == SET
5242 && GET_CODE (SET_SRC (uloc)) == REG);
5243 val_resolve (out, val, SET_SRC (uloc), insn);
5246 if (VAL_HOLDS_TRACK_EXPR (loc))
5248 if (VAL_EXPR_IS_CLOBBERED (loc))
5251 var_reg_delete (out, uloc, true);
5252 else if (MEM_P (uloc))
5253 var_mem_delete (out, uloc, true);
5257 bool copied_p = VAL_EXPR_IS_COPIED (loc);
5259 enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
5261 if (GET_CODE (uloc) == SET)
5263 set_src = SET_SRC (uloc);
5264 uloc = SET_DEST (uloc);
5269 if (flag_var_tracking_uninit)
5271 status = find_src_status (in, set_src);
5273 if (status == VAR_INIT_STATUS_UNKNOWN)
5274 status = find_src_status (out, set_src);
5277 set_src = find_src_set_src (in, set_src);
5281 var_reg_delete_and_set (out, uloc, !copied_p,
5283 else if (MEM_P (uloc))
5284 var_mem_delete_and_set (out, uloc, !copied_p,
5288 else if (REG_P (uloc))
5289 var_regno_delete (out, REGNO (uloc));
5291 val_store (out, val, vloc, insn);
5297 rtx loc = VTI (bb)->mos[i].u.loc;
5300 if (GET_CODE (loc) == SET)
5302 set_src = SET_SRC (loc);
5303 loc = SET_DEST (loc);
5307 var_reg_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
5309 else if (MEM_P (loc))
5310 var_mem_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
5317 rtx loc = VTI (bb)->mos[i].u.loc;
5318 enum var_init_status src_status;
5321 if (GET_CODE (loc) == SET)
5323 set_src = SET_SRC (loc);
5324 loc = SET_DEST (loc);
5327 if (! flag_var_tracking_uninit)
5328 src_status = VAR_INIT_STATUS_INITIALIZED;
5331 src_status = find_src_status (in, set_src);
5333 if (src_status == VAR_INIT_STATUS_UNKNOWN)
5334 src_status = find_src_status (out, set_src);
5337 set_src = find_src_set_src (in, set_src);
5340 var_reg_delete_and_set (out, loc, false, src_status, set_src);
5341 else if (MEM_P (loc))
5342 var_mem_delete_and_set (out, loc, false, src_status, set_src);
5348 rtx loc = VTI (bb)->mos[i].u.loc;
5351 var_reg_delete (out, loc, false);
5352 else if (MEM_P (loc))
5353 var_mem_delete (out, loc, false);
5359 rtx loc = VTI (bb)->mos[i].u.loc;
5362 var_reg_delete (out, loc, true);
5363 else if (MEM_P (loc))
5364 var_mem_delete (out, loc, true);
5369 out->stack_adjust += VTI (bb)->mos[i].u.adjust;
5374 if (MAY_HAVE_DEBUG_INSNS)
5376 dataflow_set_equiv_regs (out);
5377 htab_traverse (shared_hash_htab (out->vars), canonicalize_values_mark,
5379 htab_traverse (shared_hash_htab (out->vars), canonicalize_values_star,
5382 htab_traverse (shared_hash_htab (out->vars),
5383 canonicalize_loc_order_check, out);
5386 changed = dataflow_set_different (&old_out, out);
5387 dataflow_set_destroy (&old_out);
5391 /* Find the locations of variables in the whole function. */
5394 vt_find_locations (void)
5396 fibheap_t worklist, pending, fibheap_swap;
5397 sbitmap visited, in_worklist, in_pending, sbitmap_swap;
5405 /* Compute reverse completion order of depth first search of the CFG
5406 so that the data-flow runs faster. */
5407 rc_order = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
5408 bb_order = XNEWVEC (int, last_basic_block);
5409 pre_and_rev_post_order_compute (NULL, rc_order, false);
5410 for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
5411 bb_order[rc_order[i]] = i;
5414 worklist = fibheap_new ();
5415 pending = fibheap_new ();
5416 visited = sbitmap_alloc (last_basic_block);
5417 in_worklist = sbitmap_alloc (last_basic_block);
5418 in_pending = sbitmap_alloc (last_basic_block);
5419 sbitmap_zero (in_worklist);
5422 fibheap_insert (pending, bb_order[bb->index], bb);
5423 sbitmap_ones (in_pending);
5425 while (!fibheap_empty (pending))
5427 fibheap_swap = pending;
5429 worklist = fibheap_swap;
5430 sbitmap_swap = in_pending;
5431 in_pending = in_worklist;
5432 in_worklist = sbitmap_swap;
5434 sbitmap_zero (visited);
5436 while (!fibheap_empty (worklist))
5438 bb = (basic_block) fibheap_extract_min (worklist);
5439 RESET_BIT (in_worklist, bb->index);
5440 if (!TEST_BIT (visited, bb->index))
5444 int oldinsz, oldoutsz;
5446 SET_BIT (visited, bb->index);
5448 if (dump_file && VTI (bb)->in.vars)
5451 -= htab_size (shared_hash_htab (VTI (bb)->in.vars))
5452 + htab_size (shared_hash_htab (VTI (bb)->out.vars));
5454 = htab_elements (shared_hash_htab (VTI (bb)->in.vars));
5456 = htab_elements (shared_hash_htab (VTI (bb)->out.vars));
5459 oldinsz = oldoutsz = 0;
5461 if (MAY_HAVE_DEBUG_INSNS)
5463 dataflow_set *in = &VTI (bb)->in, *first_out = NULL;
5464 bool first = true, adjust = false;
5466 /* Calculate the IN set as the intersection of
5467 predecessor OUT sets. */
5469 dataflow_set_clear (in);
5470 dst_can_be_shared = true;
5472 FOR_EACH_EDGE (e, ei, bb->preds)
5473 if (!VTI (e->src)->flooded)
5474 gcc_assert (bb_order[bb->index]
5475 <= bb_order[e->src->index]);
5478 dataflow_set_copy (in, &VTI (e->src)->out);
5479 first_out = &VTI (e->src)->out;
5484 dataflow_set_merge (in, &VTI (e->src)->out);
5490 dataflow_post_merge_adjust (in, &VTI (bb)->permp);
5492 /* Merge and merge_adjust should keep entries in
5494 htab_traverse (shared_hash_htab (in->vars),
5495 canonicalize_loc_order_check,
5498 if (dst_can_be_shared)
5500 shared_hash_destroy (in->vars);
5501 in->vars = shared_hash_copy (first_out->vars);
5505 VTI (bb)->flooded = true;
5509 /* Calculate the IN set as union of predecessor OUT sets. */
5510 dataflow_set_clear (&VTI (bb)->in);
5511 FOR_EACH_EDGE (e, ei, bb->preds)
5512 dataflow_set_union (&VTI (bb)->in, &VTI (e->src)->out);
5515 changed = compute_bb_dataflow (bb);
5517 htabsz += htab_size (shared_hash_htab (VTI (bb)->in.vars))
5518 + htab_size (shared_hash_htab (VTI (bb)->out.vars));
5522 FOR_EACH_EDGE (e, ei, bb->succs)
5524 if (e->dest == EXIT_BLOCK_PTR)
5527 if (TEST_BIT (visited, e->dest->index))
5529 if (!TEST_BIT (in_pending, e->dest->index))
5531 /* Send E->DEST to next round. */
5532 SET_BIT (in_pending, e->dest->index);
5533 fibheap_insert (pending,
5534 bb_order[e->dest->index],
5538 else if (!TEST_BIT (in_worklist, e->dest->index))
5540 /* Add E->DEST to current round. */
5541 SET_BIT (in_worklist, e->dest->index);
5542 fibheap_insert (worklist, bb_order[e->dest->index],
5550 "BB %i: in %i (was %i), out %i (was %i), rem %i + %i, tsz %i\n",
5552 (int)htab_elements (shared_hash_htab (VTI (bb)->in.vars)),
5554 (int)htab_elements (shared_hash_htab (VTI (bb)->out.vars)),
5556 (int)worklist->nodes, (int)pending->nodes, htabsz);
5558 if (dump_file && (dump_flags & TDF_DETAILS))
5560 fprintf (dump_file, "BB %i IN:\n", bb->index);
5561 dump_dataflow_set (&VTI (bb)->in);
5562 fprintf (dump_file, "BB %i OUT:\n", bb->index);
5563 dump_dataflow_set (&VTI (bb)->out);
5569 if (MAY_HAVE_DEBUG_INSNS)
5571 gcc_assert (VTI (bb)->flooded);
5574 fibheap_delete (worklist);
5575 fibheap_delete (pending);
5576 sbitmap_free (visited);
5577 sbitmap_free (in_worklist);
5578 sbitmap_free (in_pending);
5581 /* Print the content of the LIST to dump file. */
5584 dump_attrs_list (attrs list)
5586 for (; list; list = list->next)
5588 if (dv_is_decl_p (list->dv))
5589 print_mem_expr (dump_file, dv_as_decl (list->dv));
5591 print_rtl_single (dump_file, dv_as_value (list->dv));
5592 fprintf (dump_file, "+" HOST_WIDE_INT_PRINT_DEC, list->offset);
5594 fprintf (dump_file, "\n");
5597 /* Print the information about variable *SLOT to dump file. */
5600 dump_variable_slot (void **slot, void *data ATTRIBUTE_UNUSED)
5602 variable var = (variable) *slot;
5604 dump_variable (var);
5606 /* Continue traversing the hash table. */
5610 /* Print the information about variable VAR to dump file. */
5613 dump_variable (variable var)
5616 location_chain node;
5618 if (dv_is_decl_p (var->dv))
5620 const_tree decl = dv_as_decl (var->dv);
5622 if (DECL_NAME (decl))
5623 fprintf (dump_file, " name: %s",
5624 IDENTIFIER_POINTER (DECL_NAME (decl)));
5626 fprintf (dump_file, " name: D.%u", DECL_UID (decl));
5627 if (dump_flags & TDF_UID)
5628 fprintf (dump_file, " D.%u\n", DECL_UID (decl));
5630 fprintf (dump_file, "\n");
5634 fputc (' ', dump_file);
5635 print_rtl_single (dump_file, dv_as_value (var->dv));
5638 for (i = 0; i < var->n_var_parts; i++)
5640 fprintf (dump_file, " offset %ld\n",
5641 (long) var->var_part[i].offset);
5642 for (node = var->var_part[i].loc_chain; node; node = node->next)
5644 fprintf (dump_file, " ");
5645 if (node->init == VAR_INIT_STATUS_UNINITIALIZED)
5646 fprintf (dump_file, "[uninit]");
5647 print_rtl_single (dump_file, node->loc);
5652 /* Print the information about variables from hash table VARS to dump file. */
5655 dump_vars (htab_t vars)
5657 if (htab_elements (vars) > 0)
5659 fprintf (dump_file, "Variables:\n");
5660 htab_traverse (vars, dump_variable_slot, NULL);
5664 /* Print the dataflow set SET to dump file. */
5667 dump_dataflow_set (dataflow_set *set)
5671 fprintf (dump_file, "Stack adjustment: " HOST_WIDE_INT_PRINT_DEC "\n",
5673 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
5677 fprintf (dump_file, "Reg %d:", i);
5678 dump_attrs_list (set->regs[i]);
5681 dump_vars (shared_hash_htab (set->vars));
5682 fprintf (dump_file, "\n");
5685 /* Print the IN and OUT sets for each basic block to dump file. */
5688 dump_dataflow_sets (void)
5694 fprintf (dump_file, "\nBasic block %d:\n", bb->index);
5695 fprintf (dump_file, "IN:\n");
5696 dump_dataflow_set (&VTI (bb)->in);
5697 fprintf (dump_file, "OUT:\n");
5698 dump_dataflow_set (&VTI (bb)->out);
5702 /* Add variable VAR to the hash table of changed variables and
5703 if it has no locations delete it from SET's hash table. */
5706 variable_was_changed (variable var, dataflow_set *set)
5708 hashval_t hash = dv_htab_hash (var->dv);
5714 /* Remember this decl or VALUE has been added to changed_variables. */
5715 set_dv_changed (var->dv, true);
5717 slot = htab_find_slot_with_hash (changed_variables,
5721 if (set && var->n_var_parts == 0)
5725 empty_var = (variable) pool_alloc (dv_pool (var->dv));
5726 empty_var->dv = var->dv;
5727 empty_var->refcount = 1;
5728 empty_var->n_var_parts = 0;
5741 if (var->n_var_parts == 0)
5746 slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
5749 if (shared_hash_shared (set->vars))
5750 slot = shared_hash_find_slot_unshare (&set->vars, var->dv,
5752 htab_clear_slot (shared_hash_htab (set->vars), slot);
5758 /* Look for the index in VAR->var_part corresponding to OFFSET.
5759 Return -1 if not found. If INSERTION_POINT is non-NULL, the
5760 referenced int will be set to the index that the part has or should
5761 have, if it should be inserted. */
5764 find_variable_location_part (variable var, HOST_WIDE_INT offset,
5765 int *insertion_point)
5769 /* Find the location part. */
5771 high = var->n_var_parts;
5774 pos = (low + high) / 2;
5775 if (var->var_part[pos].offset < offset)
5782 if (insertion_point)
5783 *insertion_point = pos;
5785 if (pos < var->n_var_parts && var->var_part[pos].offset == offset)
5792 set_slot_part (dataflow_set *set, rtx loc, void **slot,
5793 decl_or_value dv, HOST_WIDE_INT offset,
5794 enum var_init_status initialized, rtx set_src)
5797 location_chain node, next;
5798 location_chain *nextp;
5800 bool onepart = dv_onepart_p (dv);
5802 gcc_assert (offset == 0 || !onepart);
5803 gcc_assert (loc != dv_as_opaque (dv));
5805 var = (variable) *slot;
5807 if (! flag_var_tracking_uninit)
5808 initialized = VAR_INIT_STATUS_INITIALIZED;
5812 /* Create new variable information. */
5813 var = (variable) pool_alloc (dv_pool (dv));
5816 var->n_var_parts = 1;
5817 var->var_part[0].offset = offset;
5818 var->var_part[0].loc_chain = NULL;
5819 var->var_part[0].cur_loc = NULL;
5822 nextp = &var->var_part[0].loc_chain;
5823 if (emit_notes && dv_is_value_p (dv))
5824 add_cselib_value_chains (dv);
5830 gcc_assert (dv_as_opaque (var->dv) == dv_as_opaque (dv));
5834 if (GET_CODE (loc) == VALUE)
5836 for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
5837 nextp = &node->next)
5838 if (GET_CODE (node->loc) == VALUE)
5840 if (node->loc == loc)
5845 if (canon_value_cmp (node->loc, loc))
5853 else if (REG_P (node->loc) || MEM_P (node->loc))
5861 else if (REG_P (loc))
5863 for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
5864 nextp = &node->next)
5865 if (REG_P (node->loc))
5867 if (REGNO (node->loc) < REGNO (loc))
5871 if (REGNO (node->loc) == REGNO (loc))
5884 else if (MEM_P (loc))
5886 for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
5887 nextp = &node->next)
5888 if (REG_P (node->loc))
5890 else if (MEM_P (node->loc))
5892 if ((r = loc_cmp (XEXP (node->loc, 0), XEXP (loc, 0))) >= 0)
5904 for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
5905 nextp = &node->next)
5906 if ((r = loc_cmp (node->loc, loc)) >= 0)
5914 if (var->refcount > 1 || shared_hash_shared (set->vars))
5916 slot = unshare_variable (set, slot, var, initialized);
5917 var = (variable)*slot;
5918 for (nextp = &var->var_part[0].loc_chain; c;
5919 nextp = &(*nextp)->next)
5921 gcc_assert ((!node && !*nextp) || node->loc == (*nextp)->loc);
5928 gcc_assert (dv_as_decl (var->dv) == dv_as_decl (dv));
5930 pos = find_variable_location_part (var, offset, &inspos);
5934 node = var->var_part[pos].loc_chain;
5937 && ((REG_P (node->loc) && REG_P (loc)
5938 && REGNO (node->loc) == REGNO (loc))
5939 || rtx_equal_p (node->loc, loc)))
5941 /* LOC is in the beginning of the chain so we have nothing
5943 if (node->init < initialized)
5944 node->init = initialized;
5945 if (set_src != NULL)
5946 node->set_src = set_src;
5952 /* We have to make a copy of a shared variable. */
5953 if (var->refcount > 1 || shared_hash_shared (set->vars))
5955 slot = unshare_variable (set, slot, var, initialized);
5956 var = (variable)*slot;
5962 /* We have not found the location part, new one will be created. */
5964 /* We have to make a copy of the shared variable. */
5965 if (var->refcount > 1 || shared_hash_shared (set->vars))
5967 slot = unshare_variable (set, slot, var, initialized);
5968 var = (variable)*slot;
5971 /* We track only variables whose size is <= MAX_VAR_PARTS bytes
5972 thus there are at most MAX_VAR_PARTS different offsets. */
5973 gcc_assert (var->n_var_parts < MAX_VAR_PARTS
5974 && (!var->n_var_parts || !dv_onepart_p (var->dv)));
5976 /* We have to move the elements of array starting at index
5977 inspos to the next position. */
5978 for (pos = var->n_var_parts; pos > inspos; pos--)
5979 var->var_part[pos] = var->var_part[pos - 1];
5982 var->var_part[pos].offset = offset;
5983 var->var_part[pos].loc_chain = NULL;
5984 var->var_part[pos].cur_loc = NULL;
5987 /* Delete the location from the list. */
5988 nextp = &var->var_part[pos].loc_chain;
5989 for (node = var->var_part[pos].loc_chain; node; node = next)
5992 if ((REG_P (node->loc) && REG_P (loc)
5993 && REGNO (node->loc) == REGNO (loc))
5994 || rtx_equal_p (node->loc, loc))
5996 /* Save these values, to assign to the new node, before
5997 deleting this one. */
5998 if (node->init > initialized)
5999 initialized = node->init;
6000 if (node->set_src != NULL && set_src == NULL)
6001 set_src = node->set_src;
6002 pool_free (loc_chain_pool, node);
6007 nextp = &node->next;
6010 nextp = &var->var_part[pos].loc_chain;
6013 /* Add the location to the beginning. */
6014 node = (location_chain) pool_alloc (loc_chain_pool);
6016 node->init = initialized;
6017 node->set_src = set_src;
6018 node->next = *nextp;
6021 if (onepart && emit_notes)
6022 add_value_chains (var->dv, loc);
6024 /* If no location was emitted do so. */
6025 if (var->var_part[pos].cur_loc == NULL)
6027 var->var_part[pos].cur_loc = loc;
6028 variable_was_changed (var, set);
6034 /* Set the part of variable's location in the dataflow set SET. The
6035 variable part is specified by variable's declaration in DV and
6036 offset OFFSET and the part's location by LOC. IOPT should be
6037 NO_INSERT if the variable is known to be in SET already and the
6038 variable hash table must not be resized, and INSERT otherwise. */
6041 set_variable_part (dataflow_set *set, rtx loc,
6042 decl_or_value dv, HOST_WIDE_INT offset,
6043 enum var_init_status initialized, rtx set_src,
6044 enum insert_option iopt)
6048 if (iopt == NO_INSERT)
6049 slot = shared_hash_find_slot_noinsert (set->vars, dv);
6052 slot = shared_hash_find_slot (set->vars, dv);
6054 slot = shared_hash_find_slot_unshare (&set->vars, dv, iopt);
6056 slot = set_slot_part (set, loc, slot, dv, offset, initialized, set_src);
6059 /* Remove all recorded register locations for the given variable part
6060 from dataflow set SET, except for those that are identical to loc.
6061 The variable part is specified by variable's declaration or value
6062 DV and offset OFFSET. */
6065 clobber_slot_part (dataflow_set *set, rtx loc, void **slot,
6066 HOST_WIDE_INT offset, rtx set_src)
6068 variable var = (variable) *slot;
6069 int pos = find_variable_location_part (var, offset, NULL);
6073 location_chain node, next;
6075 /* Remove the register locations from the dataflow set. */
6076 next = var->var_part[pos].loc_chain;
6077 for (node = next; node; node = next)
6080 if (node->loc != loc
6081 && (!flag_var_tracking_uninit
6084 || !rtx_equal_p (set_src, node->set_src)))
6086 if (REG_P (node->loc))
6091 /* Remove the variable part from the register's
6092 list, but preserve any other variable parts
6093 that might be regarded as live in that same
6095 anextp = &set->regs[REGNO (node->loc)];
6096 for (anode = *anextp; anode; anode = anext)
6098 anext = anode->next;
6099 if (dv_as_opaque (anode->dv) == dv_as_opaque (var->dv)
6100 && anode->offset == offset)
6102 pool_free (attrs_pool, anode);
6106 anextp = &anode->next;
6110 slot = delete_slot_part (set, node->loc, slot, offset);
6118 /* Remove all recorded register locations for the given variable part
6119 from dataflow set SET, except for those that are identical to loc.
6120 The variable part is specified by variable's declaration or value
6121 DV and offset OFFSET. */
6124 clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
6125 HOST_WIDE_INT offset, rtx set_src)
6129 if (!dv_as_opaque (dv)
6130 || (!dv_is_value_p (dv) && ! DECL_P (dv_as_decl (dv))))
6133 slot = shared_hash_find_slot_noinsert (set->vars, dv);
6137 slot = clobber_slot_part (set, loc, slot, offset, set_src);
6140 /* Delete the part of variable's location from dataflow set SET. The
6141 variable part is specified by its SET->vars slot SLOT and offset
6142 OFFSET and the part's location by LOC. */
6145 delete_slot_part (dataflow_set *set, rtx loc, void **slot,
6146 HOST_WIDE_INT offset)
6148 variable var = (variable) *slot;
6149 int pos = find_variable_location_part (var, offset, NULL);
6153 location_chain node, next;
6154 location_chain *nextp;
6157 if (var->refcount > 1 || shared_hash_shared (set->vars))
6159 /* If the variable contains the location part we have to
6160 make a copy of the variable. */
6161 for (node = var->var_part[pos].loc_chain; node;
6164 if ((REG_P (node->loc) && REG_P (loc)
6165 && REGNO (node->loc) == REGNO (loc))
6166 || rtx_equal_p (node->loc, loc))
6168 slot = unshare_variable (set, slot, var,
6169 VAR_INIT_STATUS_UNKNOWN);
6170 var = (variable)*slot;
6176 /* Delete the location part. */
6177 nextp = &var->var_part[pos].loc_chain;
6178 for (node = *nextp; node; node = next)
6181 if ((REG_P (node->loc) && REG_P (loc)
6182 && REGNO (node->loc) == REGNO (loc))
6183 || rtx_equal_p (node->loc, loc))
6185 if (emit_notes && pos == 0 && dv_onepart_p (var->dv))
6186 remove_value_chains (var->dv, node->loc);
6187 pool_free (loc_chain_pool, node);
6192 nextp = &node->next;
6195 /* If we have deleted the location which was last emitted
6196 we have to emit new location so add the variable to set
6197 of changed variables. */
6198 if (var->var_part[pos].cur_loc
6200 && REG_P (var->var_part[pos].cur_loc)
6201 && REGNO (loc) == REGNO (var->var_part[pos].cur_loc))
6202 || rtx_equal_p (loc, var->var_part[pos].cur_loc)))
6205 if (var->var_part[pos].loc_chain)
6206 var->var_part[pos].cur_loc = var->var_part[pos].loc_chain->loc;
6211 if (var->var_part[pos].loc_chain == NULL)
6213 gcc_assert (changed);
6215 if (emit_notes && var->n_var_parts == 0 && dv_is_value_p (var->dv))
6216 remove_cselib_value_chains (var->dv);
6217 while (pos < var->n_var_parts)
6219 var->var_part[pos] = var->var_part[pos + 1];
6224 variable_was_changed (var, set);
6230 /* Delete the part of variable's location from dataflow set SET. The
6231 variable part is specified by variable's declaration or value DV
6232 and offset OFFSET and the part's location by LOC. */
6235 delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
6236 HOST_WIDE_INT offset)
6238 void **slot = shared_hash_find_slot_noinsert (set->vars, dv);
6242 slot = delete_slot_part (set, loc, slot, offset);
6245 /* Wrap result in CONST:MODE if needed to preserve the mode. */
6248 check_wrap_constant (enum machine_mode mode, rtx result)
6250 if (!result || GET_MODE (result) == mode)
6253 if (dump_file && (dump_flags & TDF_DETAILS))
6254 fprintf (dump_file, " wrapping result in const to preserve mode %s\n",
6255 GET_MODE_NAME (mode));
6257 result = wrap_constant (mode, result);
6258 gcc_assert (GET_MODE (result) == mode);
6263 /* Callback for cselib_expand_value, that looks for expressions
6264 holding the value in the var-tracking hash tables. Return X for
6265 standard processing, anything else is to be used as-is. */
6268 vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data)
6270 htab_t vars = (htab_t)data;
6276 if (GET_CODE (x) == SUBREG)
6278 rtx subreg = SUBREG_REG (x);
6280 if (GET_CODE (SUBREG_REG (x)) != VALUE)
6283 subreg = cselib_expand_value_rtx_cb (SUBREG_REG (x), regs,
6285 vt_expand_loc_callback, data);
6290 result = simplify_gen_subreg (GET_MODE (x), subreg,
6291 GET_MODE (SUBREG_REG (x)),
6294 /* Invalid SUBREGs are ok in debug info. ??? We could try
6295 alternate expansions for the VALUE as well. */
6296 if (!result && (REG_P (subreg) || MEM_P (subreg)))
6297 result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));
6302 if (GET_CODE (x) != VALUE)
6305 if (VALUE_RECURSED_INTO (x))
6308 dv = dv_from_value (x);
6309 var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
6314 if (var->n_var_parts == 0)
6317 gcc_assert (var->n_var_parts == 1);
6319 VALUE_RECURSED_INTO (x) = true;
6322 for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
6324 result = cselib_expand_value_rtx_cb (loc->loc, regs, max_depth,
6325 vt_expand_loc_callback, vars);
6326 result = check_wrap_constant (GET_MODE (loc->loc), result);
6331 VALUE_RECURSED_INTO (x) = false;
6338 /* Expand VALUEs in LOC, using VARS as well as cselib's equivalence
6342 vt_expand_loc (rtx loc, htab_t vars)
6346 if (!MAY_HAVE_DEBUG_INSNS)
6349 newloc = cselib_expand_value_rtx_cb (loc, scratch_regs, 5,
6350 vt_expand_loc_callback, vars);
6351 loc = check_wrap_constant (GET_MODE (loc), newloc);
6353 if (loc && MEM_P (loc))
6354 loc = targetm.delegitimize_address (loc);
6359 /* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP. DATA contains
6360 additional parameters: WHERE specifies whether the note shall be emitted
6361 before or after instruction INSN. */
6364 emit_note_insn_var_location (void **varp, void *data)
6366 variable var = (variable) *varp;
6367 rtx insn = ((emit_note_data *)data)->insn;
6368 enum emit_note_where where = ((emit_note_data *)data)->where;
6369 htab_t vars = ((emit_note_data *)data)->vars;
6371 int i, j, n_var_parts;
6373 enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED;
6374 HOST_WIDE_INT last_limit;
6375 tree type_size_unit;
6376 HOST_WIDE_INT offsets[MAX_VAR_PARTS];
6377 rtx loc[MAX_VAR_PARTS];
6380 if (dv_is_value_p (var->dv))
6383 decl = dv_as_decl (var->dv);
6390 for (i = 0; i < var->n_var_parts; i++)
6392 enum machine_mode mode, wider_mode;
6395 if (last_limit < var->var_part[i].offset)
6400 else if (last_limit > var->var_part[i].offset)
6402 offsets[n_var_parts] = var->var_part[i].offset;
6403 loc2 = vt_expand_loc (var->var_part[i].loc_chain->loc, vars);
6409 loc[n_var_parts] = loc2;
6410 mode = GET_MODE (loc[n_var_parts]);
6411 initialized = var->var_part[i].loc_chain->init;
6412 last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
6414 /* Attempt to merge adjacent registers or memory. */
6415 wider_mode = GET_MODE_WIDER_MODE (mode);
6416 for (j = i + 1; j < var->n_var_parts; j++)
6417 if (last_limit <= var->var_part[j].offset)
6419 if (j < var->n_var_parts
6420 && wider_mode != VOIDmode
6421 && (loc2 = vt_expand_loc (var->var_part[j].loc_chain->loc, vars))
6422 && GET_CODE (loc[n_var_parts]) == GET_CODE (loc2)
6423 && mode == GET_MODE (loc2)
6424 && last_limit == var->var_part[j].offset)
6428 if (REG_P (loc[n_var_parts])
6429 && hard_regno_nregs[REGNO (loc[n_var_parts])][mode] * 2
6430 == hard_regno_nregs[REGNO (loc[n_var_parts])][wider_mode]
6431 && end_hard_regno (mode, REGNO (loc[n_var_parts]))
6434 if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
6435 new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
6437 else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
6438 new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
6441 if (!REG_P (new_loc)
6442 || REGNO (new_loc) != REGNO (loc[n_var_parts]))
6445 REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
6448 else if (MEM_P (loc[n_var_parts])
6449 && GET_CODE (XEXP (loc2, 0)) == PLUS
6450 && REG_P (XEXP (XEXP (loc2, 0), 0))
6451 && CONST_INT_P (XEXP (XEXP (loc2, 0), 1)))
6453 if ((REG_P (XEXP (loc[n_var_parts], 0))
6454 && rtx_equal_p (XEXP (loc[n_var_parts], 0),
6455 XEXP (XEXP (loc2, 0), 0))
6456 && INTVAL (XEXP (XEXP (loc2, 0), 1))
6457 == GET_MODE_SIZE (mode))
6458 || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
6459 && CONST_INT_P (XEXP (XEXP (loc[n_var_parts], 0), 1))
6460 && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
6461 XEXP (XEXP (loc2, 0), 0))
6462 && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
6463 + GET_MODE_SIZE (mode)
6464 == INTVAL (XEXP (XEXP (loc2, 0), 1))))
6465 new_loc = adjust_address_nv (loc[n_var_parts],
6471 loc[n_var_parts] = new_loc;
6473 last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
6479 type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl));
6480 if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
6483 if (where != EMIT_NOTE_BEFORE_INSN)
6485 note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
6486 if (where == EMIT_NOTE_AFTER_CALL_INSN)
6487 NOTE_DURING_CALL_P (note) = true;
6490 note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
6492 if (! flag_var_tracking_uninit)
6493 initialized = VAR_INIT_STATUS_INITIALIZED;
6497 NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, decl,
6498 NULL_RTX, (int) initialized);
6500 else if (n_var_parts == 1)
6503 = gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
6505 NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, decl,
6509 else if (n_var_parts)
6513 for (i = 0; i < n_var_parts; i++)
6515 = gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));
6517 parallel = gen_rtx_PARALLEL (VOIDmode,
6518 gen_rtvec_v (n_var_parts, loc));
6519 NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, decl,
6525 set_dv_changed (var->dv, false);
6526 htab_clear_slot (changed_variables, varp);
6528 /* Continue traversing the hash table. */
6532 DEF_VEC_P (variable);
6533 DEF_VEC_ALLOC_P (variable, heap);
6535 /* Stack of variable_def pointers that need processing with
6536 check_changed_vars_2. */
6538 static VEC (variable, heap) *changed_variables_stack;
6540 /* Populate changed_variables_stack with variable_def pointers
6541 that need variable_was_changed called on them. */
6544 check_changed_vars_1 (void **slot, void *data)
6546 variable var = (variable) *slot;
6547 htab_t htab = (htab_t) data;
6549 if (dv_is_value_p (var->dv))
6552 = (value_chain) htab_find_with_hash (value_chains, var->dv,
6553 dv_htab_hash (var->dv));
6557 for (vc = vc->next; vc; vc = vc->next)
6558 if (!dv_changed_p (vc->dv))
6561 = (variable) htab_find_with_hash (htab, vc->dv,
6562 dv_htab_hash (vc->dv));
6564 VEC_safe_push (variable, heap, changed_variables_stack,
6571 /* Add VAR to changed_variables and also for VALUEs add recursively
6572 all DVs that aren't in changed_variables yet but reference the
6573 VALUE from its loc_chain. */
6576 check_changed_vars_2 (variable var, htab_t htab)
6578 variable_was_changed (var, NULL);
6579 if (dv_is_value_p (var->dv))
6582 = (value_chain) htab_find_with_hash (value_chains, var->dv,
6583 dv_htab_hash (var->dv));
6587 for (vc = vc->next; vc; vc = vc->next)
6588 if (!dv_changed_p (vc->dv))
6591 = (variable) htab_find_with_hash (htab, vc->dv,
6592 dv_htab_hash (vc->dv));
6594 check_changed_vars_2 (vcvar, htab);
6599 /* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
6600 CHANGED_VARIABLES and delete this chain. WHERE specifies whether the notes
6601 shall be emitted before of after instruction INSN. */
6604 emit_notes_for_changes (rtx insn, enum emit_note_where where,
6607 emit_note_data data;
6608 htab_t htab = shared_hash_htab (vars);
6610 if (!htab_elements (changed_variables))
6613 if (MAY_HAVE_DEBUG_INSNS)
6615 /* Unfortunately this has to be done in two steps, because
6616 we can't traverse a hashtab into which we are inserting
6617 through variable_was_changed. */
6618 htab_traverse (changed_variables, check_changed_vars_1, htab);
6619 while (VEC_length (variable, changed_variables_stack) > 0)
6620 check_changed_vars_2 (VEC_pop (variable, changed_variables_stack),
6628 htab_traverse (changed_variables, emit_note_insn_var_location, &data);
6631 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
6632 same variable in hash table DATA or is not there at all. */
6635 emit_notes_for_differences_1 (void **slot, void *data)
6637 htab_t new_vars = (htab_t) data;
6638 variable old_var, new_var;
6640 old_var = (variable) *slot;
6641 new_var = (variable) htab_find_with_hash (new_vars, old_var->dv,
6642 dv_htab_hash (old_var->dv));
6646 /* Variable has disappeared. */
6649 empty_var = (variable) pool_alloc (dv_pool (old_var->dv));
6650 empty_var->dv = old_var->dv;
6651 empty_var->refcount = 0;
6652 empty_var->n_var_parts = 0;
6653 if (dv_onepart_p (old_var->dv))
6657 gcc_assert (old_var->n_var_parts == 1);
6658 for (lc = old_var->var_part[0].loc_chain; lc; lc = lc->next)
6659 remove_value_chains (old_var->dv, lc->loc);
6660 if (dv_is_value_p (old_var->dv))
6661 remove_cselib_value_chains (old_var->dv);
6663 variable_was_changed (empty_var, NULL);
6665 else if (variable_different_p (old_var, new_var, true))
6667 if (dv_onepart_p (old_var->dv))
6669 location_chain lc1, lc2;
6671 gcc_assert (old_var->n_var_parts == 1);
6672 gcc_assert (new_var->n_var_parts == 1);
6673 lc1 = old_var->var_part[0].loc_chain;
6674 lc2 = new_var->var_part[0].loc_chain;
6677 && ((REG_P (lc1->loc) && REG_P (lc2->loc))
6678 || rtx_equal_p (lc1->loc, lc2->loc)))
6683 for (; lc2; lc2 = lc2->next)
6684 add_value_chains (old_var->dv, lc2->loc);
6685 for (; lc1; lc1 = lc1->next)
6686 remove_value_chains (old_var->dv, lc1->loc);
6688 variable_was_changed (new_var, NULL);
6691 /* Continue traversing the hash table. */
6695 /* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
6699 emit_notes_for_differences_2 (void **slot, void *data)
6701 htab_t old_vars = (htab_t) data;
6702 variable old_var, new_var;
6704 new_var = (variable) *slot;
6705 old_var = (variable) htab_find_with_hash (old_vars, new_var->dv,
6706 dv_htab_hash (new_var->dv));
6709 /* Variable has appeared. */
6710 if (dv_onepart_p (new_var->dv))
6714 gcc_assert (new_var->n_var_parts == 1);
6715 for (lc = new_var->var_part[0].loc_chain; lc; lc = lc->next)
6716 add_value_chains (new_var->dv, lc->loc);
6717 if (dv_is_value_p (new_var->dv))
6718 add_cselib_value_chains (new_var->dv);
6720 variable_was_changed (new_var, NULL);
6723 /* Continue traversing the hash table. */
6727 /* Emit notes before INSN for differences between dataflow sets OLD_SET and
6731 emit_notes_for_differences (rtx insn, dataflow_set *old_set,
6732 dataflow_set *new_set)
6734 htab_traverse (shared_hash_htab (old_set->vars),
6735 emit_notes_for_differences_1,
6736 shared_hash_htab (new_set->vars));
6737 htab_traverse (shared_hash_htab (new_set->vars),
6738 emit_notes_for_differences_2,
6739 shared_hash_htab (old_set->vars));
6740 emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, new_set->vars);
6743 /* Emit the notes for changes of location parts in the basic block BB. */
6746 emit_notes_in_bb (basic_block bb, dataflow_set *set)
6750 dataflow_set_clear (set);
6751 dataflow_set_copy (set, &VTI (bb)->in);
6753 for (i = 0; i < VTI (bb)->n_mos; i++)
6755 rtx insn = VTI (bb)->mos[i].insn;
6757 switch (VTI (bb)->mos[i].type)
6760 dataflow_set_clear_at_call (set);
6761 emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars);
6766 rtx loc = VTI (bb)->mos[i].u.loc;
6769 var_reg_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6771 var_mem_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6773 emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
6779 rtx loc = VTI (bb)->mos[i].u.loc;
6783 if (GET_CODE (loc) == CONCAT)
6785 val = XEXP (loc, 0);
6786 vloc = XEXP (loc, 1);
6794 var = PAT_VAR_LOCATION_DECL (vloc);
6796 clobber_variable_part (set, NULL_RTX,
6797 dv_from_decl (var), 0, NULL_RTX);
6800 if (VAL_NEEDS_RESOLUTION (loc))
6801 val_resolve (set, val, PAT_VAR_LOCATION_LOC (vloc), insn);
6802 set_variable_part (set, val, dv_from_decl (var), 0,
6803 VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
6807 emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
6813 rtx loc = VTI (bb)->mos[i].u.loc;
6814 rtx val, vloc, uloc;
6816 vloc = uloc = XEXP (loc, 1);
6817 val = XEXP (loc, 0);
6819 if (GET_CODE (val) == CONCAT)
6821 uloc = XEXP (val, 1);
6822 val = XEXP (val, 0);
6825 if (VAL_NEEDS_RESOLUTION (loc))
6826 val_resolve (set, val, vloc, insn);
6828 if (VAL_HOLDS_TRACK_EXPR (loc))
6830 if (GET_CODE (uloc) == REG)
6831 var_reg_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6833 else if (GET_CODE (uloc) == MEM)
6834 var_mem_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6838 emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
6844 rtx loc = VTI (bb)->mos[i].u.loc;
6845 rtx val, vloc, uloc;
6847 vloc = uloc = XEXP (loc, 1);
6848 val = XEXP (loc, 0);
6850 if (GET_CODE (val) == CONCAT)
6852 vloc = XEXP (val, 1);
6853 val = XEXP (val, 0);
6856 if (GET_CODE (vloc) == SET)
6858 rtx vsrc = SET_SRC (vloc);
6860 gcc_assert (val != vsrc);
6861 gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
6863 vloc = SET_DEST (vloc);
6865 if (VAL_NEEDS_RESOLUTION (loc))
6866 val_resolve (set, val, vsrc, insn);
6868 else if (VAL_NEEDS_RESOLUTION (loc))
6870 gcc_assert (GET_CODE (uloc) == SET
6871 && GET_CODE (SET_SRC (uloc)) == REG);
6872 val_resolve (set, val, SET_SRC (uloc), insn);
6875 if (VAL_HOLDS_TRACK_EXPR (loc))
6877 if (VAL_EXPR_IS_CLOBBERED (loc))
6880 var_reg_delete (set, uloc, true);
6881 else if (MEM_P (uloc))
6882 var_mem_delete (set, uloc, true);
6886 bool copied_p = VAL_EXPR_IS_COPIED (loc);
6888 enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
6890 if (GET_CODE (uloc) == SET)
6892 set_src = SET_SRC (uloc);
6893 uloc = SET_DEST (uloc);
6898 status = find_src_status (set, set_src);
6900 set_src = find_src_set_src (set, set_src);
6904 var_reg_delete_and_set (set, uloc, !copied_p,
6906 else if (MEM_P (uloc))
6907 var_mem_delete_and_set (set, uloc, !copied_p,
6911 else if (REG_P (uloc))
6912 var_regno_delete (set, REGNO (uloc));
6914 val_store (set, val, vloc, insn);
6916 emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
6923 rtx loc = VTI (bb)->mos[i].u.loc;
6926 if (GET_CODE (loc) == SET)
6928 set_src = SET_SRC (loc);
6929 loc = SET_DEST (loc);
6933 var_reg_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
6936 var_mem_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
6939 emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
6946 rtx loc = VTI (bb)->mos[i].u.loc;
6947 enum var_init_status src_status;
6950 if (GET_CODE (loc) == SET)
6952 set_src = SET_SRC (loc);
6953 loc = SET_DEST (loc);
6956 src_status = find_src_status (set, set_src);
6957 set_src = find_src_set_src (set, set_src);
6960 var_reg_delete_and_set (set, loc, false, src_status, set_src);
6962 var_mem_delete_and_set (set, loc, false, src_status, set_src);
6964 emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
6971 rtx loc = VTI (bb)->mos[i].u.loc;
6974 var_reg_delete (set, loc, false);
6976 var_mem_delete (set, loc, false);
6978 emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
6984 rtx loc = VTI (bb)->mos[i].u.loc;
6987 var_reg_delete (set, loc, true);
6989 var_mem_delete (set, loc, true);
6991 emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN,
6997 set->stack_adjust += VTI (bb)->mos[i].u.adjust;
7003 /* Emit notes for the whole function. */
7006 vt_emit_notes (void)
7011 gcc_assert (!htab_elements (changed_variables));
7013 /* Free memory occupied by the out hash tables, as they aren't used
7016 dataflow_set_clear (&VTI (bb)->out);
7018 /* Enable emitting notes by functions (mainly by set_variable_part and
7019 delete_variable_part). */
7022 if (MAY_HAVE_DEBUG_INSNS)
7023 changed_variables_stack = VEC_alloc (variable, heap, 40);
7025 dataflow_set_init (&cur);
7029 /* Emit the notes for changes of variable locations between two
7030 subsequent basic blocks. */
7031 emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
7033 /* Emit the notes for the changes in the basic block itself. */
7034 emit_notes_in_bb (bb, &cur);
7036 /* Free memory occupied by the in hash table, we won't need it
7038 dataflow_set_clear (&VTI (bb)->in);
7040 #ifdef ENABLE_CHECKING
7041 htab_traverse (shared_hash_htab (cur.vars),
7042 emit_notes_for_differences_1,
7043 shared_hash_htab (empty_shared_hash));
7044 if (MAY_HAVE_DEBUG_INSNS)
7045 gcc_assert (htab_elements (value_chains) == 0);
7047 dataflow_set_destroy (&cur);
7049 if (MAY_HAVE_DEBUG_INSNS)
7050 VEC_free (variable, heap, changed_variables_stack);
7055 /* If there is a declaration and offset associated with register/memory RTL
7056 assign declaration to *DECLP and offset to *OFFSETP, and return true. */
7059 vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
7063 if (REG_ATTRS (rtl))
7065 *declp = REG_EXPR (rtl);
7066 *offsetp = REG_OFFSET (rtl);
7070 else if (MEM_P (rtl))
7072 if (MEM_ATTRS (rtl))
7074 *declp = MEM_EXPR (rtl);
7075 *offsetp = INT_MEM_OFFSET (rtl);
7082 /* Insert function parameters to IN and OUT sets of ENTRY_BLOCK. */
7085 vt_add_function_parameters (void)
7089 for (parm = DECL_ARGUMENTS (current_function_decl);
7090 parm; parm = TREE_CHAIN (parm))
7092 rtx decl_rtl = DECL_RTL_IF_SET (parm);
7093 rtx incoming = DECL_INCOMING_RTL (parm);
7095 enum machine_mode mode;
7096 HOST_WIDE_INT offset;
7100 if (TREE_CODE (parm) != PARM_DECL)
7103 if (!DECL_NAME (parm))
7106 if (!decl_rtl || !incoming)
7109 if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
7112 if (!vt_get_decl_and_offset (incoming, &decl, &offset))
7114 if (REG_P (incoming) || MEM_P (incoming))
7116 /* This means argument is passed by invisible reference. */
7119 incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
7123 if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
7125 offset += byte_lowpart_offset (GET_MODE (incoming),
7126 GET_MODE (decl_rtl));
7135 /* Assume that DECL_RTL was a pseudo that got spilled to
7136 memory. The spill slot sharing code will force the
7137 memory to reference spill_slot_decl (%sfp), so we don't
7138 match above. That's ok, the pseudo must have referenced
7139 the entire parameter, so just reset OFFSET. */
7140 gcc_assert (decl == get_spill_slot_decl (false));
7144 if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
7147 out = &VTI (ENTRY_BLOCK_PTR)->out;
7149 dv = dv_from_decl (parm);
7151 if (target_for_debug_bind (parm)
7152 /* We can't deal with these right now, because this kind of
7153 variable is single-part. ??? We could handle parallels
7154 that describe multiple locations for the same single
7155 value, but ATM we don't. */
7156 && GET_CODE (incoming) != PARALLEL)
7160 /* ??? We shouldn't ever hit this, but it may happen because
7161 arguments passed by invisible reference aren't dealt with
7162 above: incoming-rtl will have Pmode rather than the
7163 expected mode for the type. */
7167 val = cselib_lookup (var_lowpart (mode, incoming), mode, true);
7169 /* ??? Float-typed values in memory are not handled by
7173 cselib_preserve_value (val);
7174 set_variable_part (out, val->val_rtx, dv, offset,
7175 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
7176 dv = dv_from_value (val->val_rtx);
7180 if (REG_P (incoming))
7182 incoming = var_lowpart (mode, incoming);
7183 gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
7184 attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
7186 set_variable_part (out, incoming, dv, offset,
7187 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
7189 else if (MEM_P (incoming))
7191 incoming = var_lowpart (mode, incoming);
7192 set_variable_part (out, incoming, dv, offset,
7193 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
7197 if (MAY_HAVE_DEBUG_INSNS)
7199 cselib_preserve_only_values (true);
7200 cselib_reset_table_with_next_value (cselib_get_next_unknown_value ());
7205 /* Allocate and initialize the data structures for variable tracking
7206 and parse the RTL to get the micro operations. */
7209 vt_initialize (void)
7213 alloc_aux_for_blocks (sizeof (struct variable_tracking_info_def));
7215 if (MAY_HAVE_DEBUG_INSNS)
7218 scratch_regs = BITMAP_ALLOC (NULL);
7219 valvar_pool = create_alloc_pool ("small variable_def pool",
7220 sizeof (struct variable_def), 256);
7224 scratch_regs = NULL;
7231 HOST_WIDE_INT pre, post = 0;
7233 unsigned int next_value_before = cselib_get_next_unknown_value ();
7234 unsigned int next_value_after = next_value_before;
7236 if (MAY_HAVE_DEBUG_INSNS)
7238 cselib_record_sets_hook = count_with_sets;
7239 if (dump_file && (dump_flags & TDF_DETAILS))
7240 fprintf (dump_file, "first value: %i\n",
7241 cselib_get_next_unknown_value ());
7244 /* Count the number of micro operations. */
7245 VTI (bb)->n_mos = 0;
7246 for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
7247 insn = NEXT_INSN (insn))
7251 if (!frame_pointer_needed)
7253 insn_stack_adjust_offset_pre_post (insn, &pre, &post);
7257 if (dump_file && (dump_flags & TDF_DETAILS))
7258 log_op_type (GEN_INT (pre), bb, insn,
7259 MO_ADJUST, dump_file);
7264 if (dump_file && (dump_flags & TDF_DETAILS))
7265 log_op_type (GEN_INT (post), bb, insn,
7266 MO_ADJUST, dump_file);
7269 cselib_hook_called = false;
7270 if (MAY_HAVE_DEBUG_INSNS)
7272 cselib_process_insn (insn);
7273 if (dump_file && (dump_flags & TDF_DETAILS))
7275 print_rtl_single (dump_file, insn);
7276 dump_cselib_table (dump_file);
7279 if (!cselib_hook_called)
7280 count_with_sets (insn, 0, 0);
7284 if (dump_file && (dump_flags & TDF_DETAILS))
7285 log_op_type (PATTERN (insn), bb, insn,
7286 MO_CALL, dump_file);
7291 count = VTI (bb)->n_mos;
7293 if (MAY_HAVE_DEBUG_INSNS)
7295 cselib_preserve_only_values (false);
7296 next_value_after = cselib_get_next_unknown_value ();
7297 cselib_reset_table_with_next_value (next_value_before);
7298 cselib_record_sets_hook = add_with_sets;
7299 if (dump_file && (dump_flags & TDF_DETAILS))
7300 fprintf (dump_file, "first value: %i\n",
7301 cselib_get_next_unknown_value ());
7304 /* Add the micro-operations to the array. */
7305 VTI (bb)->mos = XNEWVEC (micro_operation, VTI (bb)->n_mos);
7306 VTI (bb)->n_mos = 0;
7307 for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
7308 insn = NEXT_INSN (insn))
7312 if (!frame_pointer_needed)
7314 insn_stack_adjust_offset_pre_post (insn, &pre, &post);
7317 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
7319 mo->type = MO_ADJUST;
7323 if (dump_file && (dump_flags & TDF_DETAILS))
7324 log_op_type (PATTERN (insn), bb, insn,
7325 MO_ADJUST, dump_file);
7329 cselib_hook_called = false;
7330 if (MAY_HAVE_DEBUG_INSNS)
7332 cselib_process_insn (insn);
7333 if (dump_file && (dump_flags & TDF_DETAILS))
7335 print_rtl_single (dump_file, insn);
7336 dump_cselib_table (dump_file);
7339 if (!cselib_hook_called)
7340 add_with_sets (insn, 0, 0);
7342 if (!frame_pointer_needed && post)
7344 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
7346 mo->type = MO_ADJUST;
7347 mo->u.adjust = post;
7350 if (dump_file && (dump_flags & TDF_DETAILS))
7351 log_op_type (PATTERN (insn), bb, insn,
7352 MO_ADJUST, dump_file);
7356 gcc_assert (count == VTI (bb)->n_mos);
7357 if (MAY_HAVE_DEBUG_INSNS)
7359 cselib_preserve_only_values (true);
7360 gcc_assert (next_value_after == cselib_get_next_unknown_value ());
7361 cselib_reset_table_with_next_value (next_value_after);
7362 cselib_record_sets_hook = NULL;
7366 attrs_pool = create_alloc_pool ("attrs_def pool",
7367 sizeof (struct attrs_def), 1024);
7368 var_pool = create_alloc_pool ("variable_def pool",
7369 sizeof (struct variable_def)
7370 + (MAX_VAR_PARTS - 1)
7371 * sizeof (((variable)NULL)->var_part[0]), 64);
7372 loc_chain_pool = create_alloc_pool ("location_chain_def pool",
7373 sizeof (struct location_chain_def),
7375 shared_hash_pool = create_alloc_pool ("shared_hash_def pool",
7376 sizeof (struct shared_hash_def), 256);
7377 empty_shared_hash = (shared_hash) pool_alloc (shared_hash_pool);
7378 empty_shared_hash->refcount = 1;
7379 empty_shared_hash->htab
7380 = htab_create (1, variable_htab_hash, variable_htab_eq,
7381 variable_htab_free);
7382 changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
7383 variable_htab_free);
7384 if (MAY_HAVE_DEBUG_INSNS)
7386 value_chain_pool = create_alloc_pool ("value_chain_def pool",
7387 sizeof (struct value_chain_def),
7389 value_chains = htab_create (32, value_chain_htab_hash,
7390 value_chain_htab_eq, NULL);
7393 /* Init the IN and OUT sets. */
7396 VTI (bb)->visited = false;
7397 VTI (bb)->flooded = false;
7398 dataflow_set_init (&VTI (bb)->in);
7399 dataflow_set_init (&VTI (bb)->out);
7400 VTI (bb)->permp = NULL;
7403 VTI (ENTRY_BLOCK_PTR)->flooded = true;
7404 vt_add_function_parameters ();
7407 /* Get rid of all debug insns from the insn stream. */
7410 delete_debug_insns (void)
7415 if (!MAY_HAVE_DEBUG_INSNS)
7420 FOR_BB_INSNS_SAFE (bb, insn, next)
7421 if (DEBUG_INSN_P (insn))
7426 /* Run a fast, BB-local only version of var tracking, to take care of
7427 information that we don't do global analysis on, such that not all
7428 information is lost. If SKIPPED holds, we're skipping the global
7429 pass entirely, so we should try to use information it would have
7430 handled as well.. */
7433 vt_debug_insns_local (bool skipped ATTRIBUTE_UNUSED)
7435 /* ??? Just skip it all for now. */
7436 delete_debug_insns ();
7439 /* Free the data structures needed for variable tracking. */
7448 free (VTI (bb)->mos);
7453 dataflow_set_destroy (&VTI (bb)->in);
7454 dataflow_set_destroy (&VTI (bb)->out);
7455 if (VTI (bb)->permp)
7457 dataflow_set_destroy (VTI (bb)->permp);
7458 XDELETE (VTI (bb)->permp);
7461 free_aux_for_blocks ();
7462 htab_delete (empty_shared_hash->htab);
7463 htab_delete (changed_variables);
7464 free_alloc_pool (attrs_pool);
7465 free_alloc_pool (var_pool);
7466 free_alloc_pool (loc_chain_pool);
7467 free_alloc_pool (shared_hash_pool);
7469 if (MAY_HAVE_DEBUG_INSNS)
7471 htab_delete (value_chains);
7472 free_alloc_pool (value_chain_pool);
7473 free_alloc_pool (valvar_pool);
7475 BITMAP_FREE (scratch_regs);
7476 scratch_regs = NULL;
7480 XDELETEVEC (vui_vec);
7485 /* The entry point to variable tracking pass. */
7488 variable_tracking_main (void)
7490 if (flag_var_tracking_assignments < 0)
7492 delete_debug_insns ();
7496 if (n_basic_blocks > 500 && n_edges / n_basic_blocks >= 20)
7498 vt_debug_insns_local (true);
7502 mark_dfs_back_edges ();
7504 if (!frame_pointer_needed)
7506 if (!vt_stack_adjustments ())
7509 vt_debug_insns_local (true);
7514 vt_find_locations ();
7516 if (dump_file && (dump_flags & TDF_DETAILS))
7518 dump_dataflow_sets ();
7519 dump_flow_info (dump_file, dump_flags);
7525 vt_debug_insns_local (false);
7530 gate_handle_var_tracking (void)
7532 return (flag_var_tracking);
7537 struct rtl_opt_pass pass_variable_tracking =
7541 "vartrack", /* name */
7542 gate_handle_var_tracking, /* gate */
7543 variable_tracking_main, /* execute */
7546 0, /* static_pass_number */
7547 TV_VAR_TRACKING, /* tv_id */
7548 0, /* properties_required */
7549 0, /* properties_provided */
7550 0, /* properties_destroyed */
7551 0, /* todo_flags_start */
7552 TODO_dump_func | TODO_verify_rtl_sharing/* todo_flags_finish */