1/* Variable tracking routines for the GNU compiler.
2   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3
4   This file is part of GCC.
5
6   GCC is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   GCC is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14   License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with GCC; see the file COPYING.  If not, write to the Free
18   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19   02110-1301, USA.  */
20
21/* This file contains the variable tracking pass.  It computes where
22   variables are located (which registers or where in memory) at each position
23   in instruction stream and emits notes describing the locations.
24   Debug information (DWARF2 location lists) is finally generated from
25   these notes.
26   With this debug information, it is possible to show variables
27   even when debugging optimized code.
28
29   How does the variable tracking pass work?
30
31   First, it scans RTL code for uses, stores and clobbers (register/memory
32   references in instructions), for call insns and for stack adjustments
33   separately for each basic block and saves them to an array of micro
34   operations.
35   The micro operations of one instruction are ordered so that
36   pre-modifying stack adjustment < use < use with no var < call insn <
37     < set < clobber < post-modifying stack adjustment
38
39   Then, a forward dataflow analysis is performed to find out how locations
40   of variables change through code and to propagate the variable locations
41   along control flow graph.
42   The IN set for basic block BB is computed as a union of OUT sets of BB's
43   predecessors, the OUT set for BB is copied from the IN set for BB and
44   is changed according to micro operations in BB.
45
46   The IN and OUT sets for basic blocks consist of a current stack adjustment
47   (used for adjusting offset of variables addressed using stack pointer),
48   the table of structures describing the locations of parts of a variable
49   and for each physical register a linked list for each physical register.
50   The linked list is a list of variable parts stored in the register,
51   i.e. it is a list of triplets (reg, decl, offset) where decl is
52   REG_EXPR (reg) and offset is REG_OFFSET (reg).  The linked list is used for
53   effective deleting appropriate variable parts when we set or clobber the
54   register.
55
56   There may be more than one variable part in a register.  The linked lists
57   should be pretty short so it is a good data structure here.
58   For example in the following code, register allocator may assign same
59   register to variables A and B, and both of them are stored in the same
60   register in CODE:
61
62     if (cond)
63       set A;
64     else
65       set B;
66     CODE;
67     if (cond)
68       use A;
69     else
70       use B;
71
72   Finally, the NOTE_INSN_VAR_LOCATION notes describing the variable locations
73   are emitted to appropriate positions in RTL code.  Each such a note describes
74   the location of one variable at the point in instruction stream where the
75   note is.  There is no need to emit a note for each variable before each
76   instruction, we only emit these notes where the location of variable changes
77   (this means that we also emit notes for changes between the OUT set of the
78   previous block and the IN set of the current block).
79
80   The notes consist of two parts:
81   1. the declaration (from REG_EXPR or MEM_EXPR)
82   2. the location of a variable - it is either a simple register/memory
83      reference (for simple variables, for example int),
84      or a parallel of register/memory references (for a large variables
85      which consist of several parts, for example long long).
86
87*/
88
89#include "config.h"
90#include "system.h"
91#include "coretypes.h"
92#include "tm.h"
93#include "rtl.h"
94#include "tree.h"
95#include "hard-reg-set.h"
96#include "basic-block.h"
97#include "flags.h"
98#include "output.h"
99#include "insn-config.h"
100#include "reload.h"
101#include "sbitmap.h"
102#include "alloc-pool.h"
103#include "fibheap.h"
104#include "hashtab.h"
105#include "regs.h"
106#include "expr.h"
107#include "timevar.h"
108#include "tree-pass.h"
109
110/* Type of micro operation.  */
111enum micro_operation_type
112{
113  MO_USE,	/* Use location (REG or MEM).  */
114  MO_USE_NO_VAR,/* Use location which is not associated with a variable
115		   or the variable is not trackable.  */
116  MO_SET,	/* Set location.  */
117  MO_COPY,	/* Copy the same portion of a variable from one
118		   location to another.  */
119  MO_CLOBBER,	/* Clobber location.  */
120  MO_CALL,	/* Call insn.  */
121  MO_ADJUST	/* Adjust stack pointer.  */
122};
123
124/* Where shall the note be emitted?  BEFORE or AFTER the instruction.  */
125enum emit_note_where
126{
127  EMIT_NOTE_BEFORE_INSN,
128  EMIT_NOTE_AFTER_INSN
129};
130
131/* Structure holding information about micro operation.  */
132typedef struct micro_operation_def
133{
134  /* Type of micro operation.  */
135  enum micro_operation_type type;
136
137  union {
138    /* Location.  */
139    rtx loc;
140
141    /* Stack adjustment.  */
142    HOST_WIDE_INT adjust;
143  } u;
144
145  /* The instruction which the micro operation is in, for MO_USE,
146     MO_USE_NO_VAR, MO_CALL and MO_ADJUST, or the subsequent
147     instruction or note in the original flow (before any var-tracking
148     notes are inserted, to simplify emission of notes), for MO_SET
149     and MO_CLOBBER.  */
150  rtx insn;
151} micro_operation;
152
153/* Structure for passing some other parameters to function
154   emit_note_insn_var_location.  */
155typedef struct emit_note_data_def
156{
157  /* The instruction which the note will be emitted before/after.  */
158  rtx insn;
159
160  /* Where the note will be emitted (before/after insn)?  */
161  enum emit_note_where where;
162} emit_note_data;
163
164/* Description of location of a part of a variable.  The content of a physical
165   register is described by a chain of these structures.
166   The chains are pretty short (usually 1 or 2 elements) and thus
167   chain is the best data structure.  */
168typedef struct attrs_def
169{
170  /* Pointer to next member of the list.  */
171  struct attrs_def *next;
172
173  /* The rtx of register.  */
174  rtx loc;
175
176  /* The declaration corresponding to LOC.  */
177  tree decl;
178
179  /* Offset from start of DECL.  */
180  HOST_WIDE_INT offset;
181} *attrs;
182
183/* Structure holding the IN or OUT set for a basic block.  */
184typedef struct dataflow_set_def
185{
186  /* Adjustment of stack offset.  */
187  HOST_WIDE_INT stack_adjust;
188
189  /* Attributes for registers (lists of attrs).  */
190  attrs regs[FIRST_PSEUDO_REGISTER];
191
192  /* Variable locations.  */
193  htab_t vars;
194} dataflow_set;
195
196/* The structure (one for each basic block) containing the information
197   needed for variable tracking.  */
198typedef struct variable_tracking_info_def
199{
200  /* Number of micro operations stored in the MOS array.  */
201  int n_mos;
202
203  /* The array of micro operations.  */
204  micro_operation *mos;
205
206  /* The IN and OUT set for dataflow analysis.  */
207  dataflow_set in;
208  dataflow_set out;
209
210  /* Has the block been visited in DFS?  */
211  bool visited;
212} *variable_tracking_info;
213
214/* Structure for chaining the locations.  */
215typedef struct location_chain_def
216{
217  /* Next element in the chain.  */
218  struct location_chain_def *next;
219
220  /* The location (REG or MEM).  */
221  rtx loc;
222} *location_chain;
223
224/* Structure describing one part of variable.  */
225typedef struct variable_part_def
226{
227  /* Chain of locations of the part.  */
228  location_chain loc_chain;
229
230  /* Location which was last emitted to location list.  */
231  rtx cur_loc;
232
233  /* The offset in the variable.  */
234  HOST_WIDE_INT offset;
235} variable_part;
236
237/* Maximum number of location parts.  */
238#define MAX_VAR_PARTS 16
239
240/* Structure describing where the variable is located.  */
241typedef struct variable_def
242{
243  /* The declaration of the variable.  */
244  tree decl;
245
246  /* Reference count.  */
247  int refcount;
248
249  /* Number of variable parts.  */
250  int n_var_parts;
251
252  /* The variable parts.  */
253  variable_part var_part[MAX_VAR_PARTS];
254} *variable;
255
256/* Hash function for DECL for VARIABLE_HTAB.  */
257#define VARIABLE_HASH_VAL(decl) (DECL_UID (decl))
258
259/* Pointer to the BB's information specific to variable tracking pass.  */
260#define VTI(BB) ((variable_tracking_info) (BB)->aux)
261
262/* Macro to access MEM_OFFSET as an HOST_WIDE_INT.  Evaluates MEM twice.  */
263#define INT_MEM_OFFSET(mem) (MEM_OFFSET (mem) ? INTVAL (MEM_OFFSET (mem)) : 0)
264
265/* Alloc pool for struct attrs_def.  */
266static alloc_pool attrs_pool;
267
268/* Alloc pool for struct variable_def.  */
269static alloc_pool var_pool;
270
271/* Alloc pool for struct location_chain_def.  */
272static alloc_pool loc_chain_pool;
273
274/* Changed variables, notes will be emitted for them.  */
275static htab_t changed_variables;
276
277/* Shall notes be emitted?  */
278static bool emit_notes;
279
280/* Local function prototypes.  */
281static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
282					  HOST_WIDE_INT *);
283static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
284					       HOST_WIDE_INT *);
285static void bb_stack_adjust_offset (basic_block);
286static bool vt_stack_adjustments (void);
287static rtx adjust_stack_reference (rtx, HOST_WIDE_INT);
288static hashval_t variable_htab_hash (const void *);
289static int variable_htab_eq (const void *, const void *);
290static void variable_htab_free (void *);
291
292static void init_attrs_list_set (attrs *);
293static void attrs_list_clear (attrs *);
294static attrs attrs_list_member (attrs, tree, HOST_WIDE_INT);
295static void attrs_list_insert (attrs *, tree, HOST_WIDE_INT, rtx);
296static void attrs_list_copy (attrs *, attrs);
297static void attrs_list_union (attrs *, attrs);
298
299static void vars_clear (htab_t);
300static variable unshare_variable (dataflow_set *set, variable var);
301static int vars_copy_1 (void **, void *);
302static void vars_copy (htab_t, htab_t);
303static tree var_debug_decl (tree);
304static void var_reg_set (dataflow_set *, rtx);
305static void var_reg_delete_and_set (dataflow_set *, rtx, bool);
306static void var_reg_delete (dataflow_set *, rtx, bool);
307static void var_regno_delete (dataflow_set *, int);
308static void var_mem_set (dataflow_set *, rtx);
309static void var_mem_delete_and_set (dataflow_set *, rtx, bool);
310static void var_mem_delete (dataflow_set *, rtx, bool);
311
312static void dataflow_set_init (dataflow_set *, int);
313static void dataflow_set_clear (dataflow_set *);
314static void dataflow_set_copy (dataflow_set *, dataflow_set *);
315static int variable_union_info_cmp_pos (const void *, const void *);
316static int variable_union (void **, void *);
317static void dataflow_set_union (dataflow_set *, dataflow_set *);
318static bool variable_part_different_p (variable_part *, variable_part *);
319static bool variable_different_p (variable, variable, bool);
320static int dataflow_set_different_1 (void **, void *);
321static int dataflow_set_different_2 (void **, void *);
322static bool dataflow_set_different (dataflow_set *, dataflow_set *);
323static void dataflow_set_destroy (dataflow_set *);
324
325static bool contains_symbol_ref (rtx);
326static bool track_expr_p (tree);
327static bool same_variable_part_p (rtx, tree, HOST_WIDE_INT);
328static int count_uses (rtx *, void *);
329static void count_uses_1 (rtx *, void *);
330static void count_stores (rtx, rtx, void *);
331static int add_uses (rtx *, void *);
332static void add_uses_1 (rtx *, void *);
333static void add_stores (rtx, rtx, void *);
334static bool compute_bb_dataflow (basic_block);
335static void vt_find_locations (void);
336
337static void dump_attrs_list (attrs);
338static int dump_variable (void **, void *);
339static void dump_vars (htab_t);
340static void dump_dataflow_set (dataflow_set *);
341static void dump_dataflow_sets (void);
342
343static void variable_was_changed (variable, htab_t);
344static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
345static void clobber_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
346static void delete_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
347static int emit_note_insn_var_location (void **, void *);
348static void emit_notes_for_changes (rtx, enum emit_note_where);
349static int emit_notes_for_differences_1 (void **, void *);
350static int emit_notes_for_differences_2 (void **, void *);
351static void emit_notes_for_differences (rtx, dataflow_set *, dataflow_set *);
352static void emit_notes_in_bb (basic_block);
353static void vt_emit_notes (void);
354
355static bool vt_get_decl_and_offset (rtx, tree *, HOST_WIDE_INT *);
356static void vt_add_function_parameters (void);
357static void vt_initialize (void);
358static void vt_finalize (void);
359
360/* Given a SET, calculate the amount of stack adjustment it contains
361   PRE- and POST-modifying stack pointer.
362   This function is similar to stack_adjust_offset.  */
363
364static void
365stack_adjust_offset_pre_post (rtx pattern, HOST_WIDE_INT *pre,
366			      HOST_WIDE_INT *post)
367{
368  rtx src = SET_SRC (pattern);
369  rtx dest = SET_DEST (pattern);
370  enum rtx_code code;
371
372  if (dest == stack_pointer_rtx)
373    {
374      /* (set (reg sp) (plus (reg sp) (const_int))) */
375      code = GET_CODE (src);
376      if (! (code == PLUS || code == MINUS)
377	  || XEXP (src, 0) != stack_pointer_rtx
378	  || GET_CODE (XEXP (src, 1)) != CONST_INT)
379	return;
380
381      if (code == MINUS)
382	*post += INTVAL (XEXP (src, 1));
383      else
384	*post -= INTVAL (XEXP (src, 1));
385    }
386  else if (MEM_P (dest))
387    {
388      /* (set (mem (pre_dec (reg sp))) (foo)) */
389      src = XEXP (dest, 0);
390      code = GET_CODE (src);
391
392      switch (code)
393	{
394	case PRE_MODIFY:
395	case POST_MODIFY:
396	  if (XEXP (src, 0) == stack_pointer_rtx)
397	    {
398	      rtx val = XEXP (XEXP (src, 1), 1);
399	      /* We handle only adjustments by constant amount.  */
400	      gcc_assert (GET_CODE (XEXP (src, 1)) == PLUS &&
401			  GET_CODE (val) == CONST_INT);
402
403	      if (code == PRE_MODIFY)
404		*pre -= INTVAL (val);
405	      else
406		*post -= INTVAL (val);
407	      break;
408	    }
409	  return;
410
411	case PRE_DEC:
412	  if (XEXP (src, 0) == stack_pointer_rtx)
413	    {
414	      *pre += GET_MODE_SIZE (GET_MODE (dest));
415	      break;
416	    }
417	  return;
418
419	case POST_DEC:
420	  if (XEXP (src, 0) == stack_pointer_rtx)
421	    {
422	      *post += GET_MODE_SIZE (GET_MODE (dest));
423	      break;
424	    }
425	  return;
426
427	case PRE_INC:
428	  if (XEXP (src, 0) == stack_pointer_rtx)
429	    {
430	      *pre -= GET_MODE_SIZE (GET_MODE (dest));
431	      break;
432	    }
433	  return;
434
435	case POST_INC:
436	  if (XEXP (src, 0) == stack_pointer_rtx)
437	    {
438	      *post -= GET_MODE_SIZE (GET_MODE (dest));
439	      break;
440	    }
441	  return;
442
443	default:
444	  return;
445	}
446    }
447}
448
449/* Given an INSN, calculate the amount of stack adjustment it contains
450   PRE- and POST-modifying stack pointer.  */
451
452static void
453insn_stack_adjust_offset_pre_post (rtx insn, HOST_WIDE_INT *pre,
454				   HOST_WIDE_INT *post)
455{
456  *pre = 0;
457  *post = 0;
458
459  if (GET_CODE (PATTERN (insn)) == SET)
460    stack_adjust_offset_pre_post (PATTERN (insn), pre, post);
461  else if (GET_CODE (PATTERN (insn)) == PARALLEL
462	   || GET_CODE (PATTERN (insn)) == SEQUENCE)
463    {
464      int i;
465
466      /* There may be stack adjustments inside compound insns.  Search
467	 for them.  */
468      for ( i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
469	if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
470	  stack_adjust_offset_pre_post (XVECEXP (PATTERN (insn), 0, i),
471					pre, post);
472    }
473}
474
475/* Compute stack adjustment in basic block BB.  */
476
477static void
478bb_stack_adjust_offset (basic_block bb)
479{
480  HOST_WIDE_INT offset;
481  int i;
482
483  offset = VTI (bb)->in.stack_adjust;
484  for (i = 0; i < VTI (bb)->n_mos; i++)
485    {
486      if (VTI (bb)->mos[i].type == MO_ADJUST)
487	offset += VTI (bb)->mos[i].u.adjust;
488      else if (VTI (bb)->mos[i].type != MO_CALL)
489	{
490	  if (MEM_P (VTI (bb)->mos[i].u.loc))
491	    {
492	      VTI (bb)->mos[i].u.loc
493		= adjust_stack_reference (VTI (bb)->mos[i].u.loc, -offset);
494	    }
495	}
496    }
497  VTI (bb)->out.stack_adjust = offset;
498}
499
500/* Compute stack adjustments for all blocks by traversing DFS tree.
501   Return true when the adjustments on all incoming edges are consistent.
502   Heavily borrowed from pre_and_rev_post_order_compute.  */
503
504static bool
505vt_stack_adjustments (void)
506{
507  edge_iterator *stack;
508  int sp;
509
510  /* Initialize entry block.  */
511  VTI (ENTRY_BLOCK_PTR)->visited = true;
512  VTI (ENTRY_BLOCK_PTR)->out.stack_adjust = INCOMING_FRAME_SP_OFFSET;
513
514  /* Allocate stack for back-tracking up CFG.  */
515  stack = XNEWVEC (edge_iterator, n_basic_blocks + 1);
516  sp = 0;
517
518  /* Push the first edge on to the stack.  */
519  stack[sp++] = ei_start (ENTRY_BLOCK_PTR->succs);
520
521  while (sp)
522    {
523      edge_iterator ei;
524      basic_block src;
525      basic_block dest;
526
527      /* Look at the edge on the top of the stack.  */
528      ei = stack[sp - 1];
529      src = ei_edge (ei)->src;
530      dest = ei_edge (ei)->dest;
531
532      /* Check if the edge destination has been visited yet.  */
533      if (!VTI (dest)->visited)
534	{
535	  VTI (dest)->visited = true;
536	  VTI (dest)->in.stack_adjust = VTI (src)->out.stack_adjust;
537	  bb_stack_adjust_offset (dest);
538
539	  if (EDGE_COUNT (dest->succs) > 0)
540	    /* Since the DEST node has been visited for the first
541	       time, check its successors.  */
542	    stack[sp++] = ei_start (dest->succs);
543	}
544      else
545	{
546	  /* Check whether the adjustments on the edges are the same.  */
547	  if (VTI (dest)->in.stack_adjust != VTI (src)->out.stack_adjust)
548	    {
549	      free (stack);
550	      return false;
551	    }
552
553	  if (! ei_one_before_end_p (ei))
554	    /* Go to the next edge.  */
555	    ei_next (&stack[sp - 1]);
556	  else
557	    /* Return to previous level if there are no more edges.  */
558	    sp--;
559	}
560    }
561
562  free (stack);
563  return true;
564}
565
566/* Adjust stack reference MEM by ADJUSTMENT bytes and make it relative
567   to the argument pointer.  Return the new rtx.  */
568
569static rtx
570adjust_stack_reference (rtx mem, HOST_WIDE_INT adjustment)
571{
572  rtx addr, cfa, tmp;
573
574#ifdef FRAME_POINTER_CFA_OFFSET
575  adjustment -= FRAME_POINTER_CFA_OFFSET (current_function_decl);
576  cfa = plus_constant (frame_pointer_rtx, adjustment);
577#else
578  adjustment -= ARG_POINTER_CFA_OFFSET (current_function_decl);
579  cfa = plus_constant (arg_pointer_rtx, adjustment);
580#endif
581
582  addr = replace_rtx (copy_rtx (XEXP (mem, 0)), stack_pointer_rtx, cfa);
583  tmp = simplify_rtx (addr);
584  if (tmp)
585    addr = tmp;
586
587  return replace_equiv_address_nv (mem, addr);
588}
589
590/* The hash function for variable_htab, computes the hash value
591   from the declaration of variable X.  */
592
593static hashval_t
594variable_htab_hash (const void *x)
595{
596  const variable v = (const variable) x;
597
598  return (VARIABLE_HASH_VAL (v->decl));
599}
600
601/* Compare the declaration of variable X with declaration Y.  */
602
603static int
604variable_htab_eq (const void *x, const void *y)
605{
606  const variable v = (const variable) x;
607  const tree decl = (const tree) y;
608
609  return (VARIABLE_HASH_VAL (v->decl) == VARIABLE_HASH_VAL (decl));
610}
611
612/* Free the element of VARIABLE_HTAB (its type is struct variable_def).  */
613
614static void
615variable_htab_free (void *elem)
616{
617  int i;
618  variable var = (variable) elem;
619  location_chain node, next;
620
621  gcc_assert (var->refcount > 0);
622
623  var->refcount--;
624  if (var->refcount > 0)
625    return;
626
627  for (i = 0; i < var->n_var_parts; i++)
628    {
629      for (node = var->var_part[i].loc_chain; node; node = next)
630	{
631	  next = node->next;
632	  pool_free (loc_chain_pool, node);
633	}
634      var->var_part[i].loc_chain = NULL;
635    }
636  pool_free (var_pool, var);
637}
638
639/* Initialize the set (array) SET of attrs to empty lists.  */
640
641static void
642init_attrs_list_set (attrs *set)
643{
644  int i;
645
646  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
647    set[i] = NULL;
648}
649
650/* Make the list *LISTP empty.  */
651
652static void
653attrs_list_clear (attrs *listp)
654{
655  attrs list, next;
656
657  for (list = *listp; list; list = next)
658    {
659      next = list->next;
660      pool_free (attrs_pool, list);
661    }
662  *listp = NULL;
663}
664
665/* Return true if the pair of DECL and OFFSET is the member of the LIST.  */
666
667static attrs
668attrs_list_member (attrs list, tree decl, HOST_WIDE_INT offset)
669{
670  for (; list; list = list->next)
671    if (list->decl == decl && list->offset == offset)
672      return list;
673  return NULL;
674}
675
676/* Insert the triplet DECL, OFFSET, LOC to the list *LISTP.  */
677
678static void
679attrs_list_insert (attrs *listp, tree decl, HOST_WIDE_INT offset, rtx loc)
680{
681  attrs list;
682
683  list = pool_alloc (attrs_pool);
684  list->loc = loc;
685  list->decl = decl;
686  list->offset = offset;
687  list->next = *listp;
688  *listp = list;
689}
690
691/* Copy all nodes from SRC and create a list *DSTP of the copies.  */
692
693static void
694attrs_list_copy (attrs *dstp, attrs src)
695{
696  attrs n;
697
698  attrs_list_clear (dstp);
699  for (; src; src = src->next)
700    {
701      n = pool_alloc (attrs_pool);
702      n->loc = src->loc;
703      n->decl = src->decl;
704      n->offset = src->offset;
705      n->next = *dstp;
706      *dstp = n;
707    }
708}
709
710/* Add all nodes from SRC which are not in *DSTP to *DSTP.  */
711
712static void
713attrs_list_union (attrs *dstp, attrs src)
714{
715  for (; src; src = src->next)
716    {
717      if (!attrs_list_member (*dstp, src->decl, src->offset))
718	attrs_list_insert (dstp, src->decl, src->offset, src->loc);
719    }
720}
721
722/* Delete all variables from hash table VARS.  */
723
724static void
725vars_clear (htab_t vars)
726{
727  htab_empty (vars);
728}
729
730/* Return a copy of a variable VAR and insert it to dataflow set SET.  */
731
732static variable
733unshare_variable (dataflow_set *set, variable var)
734{
735  void **slot;
736  variable new_var;
737  int i;
738
739  new_var = pool_alloc (var_pool);
740  new_var->decl = var->decl;
741  new_var->refcount = 1;
742  var->refcount--;
743  new_var->n_var_parts = var->n_var_parts;
744
745  for (i = 0; i < var->n_var_parts; i++)
746    {
747      location_chain node;
748      location_chain *nextp;
749
750      new_var->var_part[i].offset = var->var_part[i].offset;
751      nextp = &new_var->var_part[i].loc_chain;
752      for (node = var->var_part[i].loc_chain; node; node = node->next)
753	{
754	  location_chain new_lc;
755
756	  new_lc = pool_alloc (loc_chain_pool);
757	  new_lc->next = NULL;
758	  new_lc->loc = node->loc;
759
760	  *nextp = new_lc;
761	  nextp = &new_lc->next;
762	}
763
764      /* We are at the basic block boundary when copying variable description
765	 so set the CUR_LOC to be the first element of the chain.  */
766      if (new_var->var_part[i].loc_chain)
767	new_var->var_part[i].cur_loc = new_var->var_part[i].loc_chain->loc;
768      else
769	new_var->var_part[i].cur_loc = NULL;
770    }
771
772  slot = htab_find_slot_with_hash (set->vars, new_var->decl,
773				   VARIABLE_HASH_VAL (new_var->decl),
774				   INSERT);
775  *slot = new_var;
776  return new_var;
777}
778
779/* Add a variable from *SLOT to hash table DATA and increase its reference
780   count.  */
781
782static int
783vars_copy_1 (void **slot, void *data)
784{
785  htab_t dst = (htab_t) data;
786  variable src, *dstp;
787
788  src = *(variable *) slot;
789  src->refcount++;
790
791  dstp = (variable *) htab_find_slot_with_hash (dst, src->decl,
792						VARIABLE_HASH_VAL (src->decl),
793						INSERT);
794  *dstp = src;
795
796  /* Continue traversing the hash table.  */
797  return 1;
798}
799
800/* Copy all variables from hash table SRC to hash table DST.  */
801
802static void
803vars_copy (htab_t dst, htab_t src)
804{
805  vars_clear (dst);
806  htab_traverse (src, vars_copy_1, dst);
807}
808
809/* Map a decl to its main debug decl.  */
810
811static inline tree
812var_debug_decl (tree decl)
813{
814  if (decl && DECL_P (decl)
815      && DECL_DEBUG_EXPR_IS_FROM (decl) && DECL_DEBUG_EXPR (decl)
816      && DECL_P (DECL_DEBUG_EXPR (decl)))
817    decl = DECL_DEBUG_EXPR (decl);
818
819  return decl;
820}
821
822/* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  */
823
824static void
825var_reg_set (dataflow_set *set, rtx loc)
826{
827  tree decl = REG_EXPR (loc);
828  HOST_WIDE_INT offset = REG_OFFSET (loc);
829  attrs node;
830
831  decl = var_debug_decl (decl);
832
833  for (node = set->regs[REGNO (loc)]; node; node = node->next)
834    if (node->decl == decl && node->offset == offset)
835      break;
836  if (!node)
837    attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc);
838  set_variable_part (set, loc, decl, offset);
839}
840
841/* Delete current content of register LOC in dataflow set SET and set
842   the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  If
843   MODIFY is true, any other live copies of the same variable part are
844   also deleted from the dataflow set, otherwise the variable part is
845   assumed to be copied from another location holding the same
846   part.  */
847
848static void
849var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify)
850{
851  tree decl = REG_EXPR (loc);
852  HOST_WIDE_INT offset = REG_OFFSET (loc);
853  attrs node, next;
854  attrs *nextp;
855
856  decl = var_debug_decl (decl);
857
858  nextp = &set->regs[REGNO (loc)];
859  for (node = *nextp; node; node = next)
860    {
861      next = node->next;
862      if (node->decl != decl || node->offset != offset)
863	{
864	  delete_variable_part (set, node->loc, node->decl, node->offset);
865	  pool_free (attrs_pool, node);
866	  *nextp = next;
867	}
868      else
869	{
870	  node->loc = loc;
871	  nextp = &node->next;
872	}
873    }
874  if (modify)
875    clobber_variable_part (set, loc, decl, offset);
876  var_reg_set (set, loc);
877}
878
879/* Delete current content of register LOC in dataflow set SET.  If
880   CLOBBER is true, also delete any other live copies of the same
881   variable part.  */
882
883static void
884var_reg_delete (dataflow_set *set, rtx loc, bool clobber)
885{
886  attrs *reg = &set->regs[REGNO (loc)];
887  attrs node, next;
888
889  if (clobber)
890    {
891      tree decl = REG_EXPR (loc);
892      HOST_WIDE_INT offset = REG_OFFSET (loc);
893
894      decl = var_debug_decl (decl);
895
896      clobber_variable_part (set, NULL, decl, offset);
897    }
898
899  for (node = *reg; node; node = next)
900    {
901      next = node->next;
902      delete_variable_part (set, node->loc, node->decl, node->offset);
903      pool_free (attrs_pool, node);
904    }
905  *reg = NULL;
906}
907
908/* Delete content of register with number REGNO in dataflow set SET.  */
909
910static void
911var_regno_delete (dataflow_set *set, int regno)
912{
913  attrs *reg = &set->regs[regno];
914  attrs node, next;
915
916  for (node = *reg; node; node = next)
917    {
918      next = node->next;
919      delete_variable_part (set, node->loc, node->decl, node->offset);
920      pool_free (attrs_pool, node);
921    }
922  *reg = NULL;
923}
924
925/* Set the location part of variable MEM_EXPR (LOC) in dataflow set
926   SET to LOC.
927   Adjust the address first if it is stack pointer based.  */
928
929static void
930var_mem_set (dataflow_set *set, rtx loc)
931{
932  tree decl = MEM_EXPR (loc);
933  HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
934
935  decl = var_debug_decl (decl);
936
937  set_variable_part (set, loc, decl, offset);
938}
939
940/* Delete and set the location part of variable MEM_EXPR (LOC) in
941   dataflow set SET to LOC.  If MODIFY is true, any other live copies
942   of the same variable part are also deleted from the dataflow set,
943   otherwise the variable part is assumed to be copied from another
944   location holding the same part.
945   Adjust the address first if it is stack pointer based.  */
946
947static void
948var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify)
949{
950  tree decl = MEM_EXPR (loc);
951  HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
952
953  decl = var_debug_decl (decl);
954
955  if (modify)
956    clobber_variable_part (set, NULL, decl, offset);
957  var_mem_set (set, loc);
958}
959
960/* Delete the location part LOC from dataflow set SET.  If CLOBBER is
961   true, also delete any other live copies of the same variable part.
962   Adjust the address first if it is stack pointer based.  */
963
964static void
965var_mem_delete (dataflow_set *set, rtx loc, bool clobber)
966{
967  tree decl = MEM_EXPR (loc);
968  HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
969
970  decl = var_debug_decl (decl);
971  if (clobber)
972    clobber_variable_part (set, NULL, decl, offset);
973  delete_variable_part (set, loc, decl, offset);
974}
975
976/* Initialize dataflow set SET to be empty.
977   VARS_SIZE is the initial size of hash table VARS.  */
978
979static void
980dataflow_set_init (dataflow_set *set, int vars_size)
981{
982  init_attrs_list_set (set->regs);
983  set->vars = htab_create (vars_size, variable_htab_hash, variable_htab_eq,
984			   variable_htab_free);
985  set->stack_adjust = 0;
986}
987
988/* Delete the contents of dataflow set SET.  */
989
990static void
991dataflow_set_clear (dataflow_set *set)
992{
993  int i;
994
995  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
996    attrs_list_clear (&set->regs[i]);
997
998  vars_clear (set->vars);
999}
1000
1001/* Copy the contents of dataflow set SRC to DST.  */
1002
1003static void
1004dataflow_set_copy (dataflow_set *dst, dataflow_set *src)
1005{
1006  int i;
1007
1008  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1009    attrs_list_copy (&dst->regs[i], src->regs[i]);
1010
1011  vars_copy (dst->vars, src->vars);
1012  dst->stack_adjust = src->stack_adjust;
1013}
1014
1015/* Information for merging lists of locations for a given offset of variable.
1016 */
1017struct variable_union_info
1018{
1019  /* Node of the location chain.  */
1020  location_chain lc;
1021
1022  /* The sum of positions in the input chains.  */
1023  int pos;
1024
1025  /* The position in the chains of SRC and DST dataflow sets.  */
1026  int pos_src;
1027  int pos_dst;
1028};
1029
1030/* Compare function for qsort, order the structures by POS element.  */
1031
1032static int
1033variable_union_info_cmp_pos (const void *n1, const void *n2)
1034{
1035  const struct variable_union_info *i1 = n1;
1036  const struct variable_union_info *i2 = n2;
1037
1038  if (i1->pos != i2->pos)
1039    return i1->pos - i2->pos;
1040
1041  return (i1->pos_dst - i2->pos_dst);
1042}
1043
1044/* Compute union of location parts of variable *SLOT and the same variable
1045   from hash table DATA.  Compute "sorted" union of the location chains
1046   for common offsets, i.e. the locations of a variable part are sorted by
1047   a priority where the priority is the sum of the positions in the 2 chains
1048   (if a location is only in one list the position in the second list is
1049   defined to be larger than the length of the chains).
1050   When we are updating the location parts the newest location is in the
1051   beginning of the chain, so when we do the described "sorted" union
1052   we keep the newest locations in the beginning.  */
1053
1054static int
1055variable_union (void **slot, void *data)
1056{
1057  variable src, dst, *dstp;
1058  dataflow_set *set = (dataflow_set *) data;
1059  int i, j, k;
1060
1061  src = *(variable *) slot;
1062  dstp = (variable *) htab_find_slot_with_hash (set->vars, src->decl,
1063						VARIABLE_HASH_VAL (src->decl),
1064						INSERT);
1065  if (!*dstp)
1066    {
1067      src->refcount++;
1068
1069      /* If CUR_LOC of some variable part is not the first element of
1070	 the location chain we are going to change it so we have to make
1071	 a copy of the variable.  */
1072      for (k = 0; k < src->n_var_parts; k++)
1073	{
1074	  gcc_assert (!src->var_part[k].loc_chain
1075		      == !src->var_part[k].cur_loc);
1076	  if (src->var_part[k].loc_chain)
1077	    {
1078	      gcc_assert (src->var_part[k].cur_loc);
1079	      if (src->var_part[k].cur_loc != src->var_part[k].loc_chain->loc)
1080		break;
1081	    }
1082	}
1083      if (k < src->n_var_parts)
1084	unshare_variable (set, src);
1085      else
1086	*dstp = src;
1087
1088      /* Continue traversing the hash table.  */
1089      return 1;
1090    }
1091  else
1092    dst = *dstp;
1093
1094  gcc_assert (src->n_var_parts);
1095
1096  /* Count the number of location parts, result is K.  */
1097  for (i = 0, j = 0, k = 0;
1098       i < src->n_var_parts && j < dst->n_var_parts; k++)
1099    {
1100      if (src->var_part[i].offset == dst->var_part[j].offset)
1101	{
1102	  i++;
1103	  j++;
1104	}
1105      else if (src->var_part[i].offset < dst->var_part[j].offset)
1106	i++;
1107      else
1108	j++;
1109    }
1110  k += src->n_var_parts - i;
1111  k += dst->n_var_parts - j;
1112
1113  /* We track only variables whose size is <= MAX_VAR_PARTS bytes
1114     thus there are at most MAX_VAR_PARTS different offsets.  */
1115  gcc_assert (k <= MAX_VAR_PARTS);
1116
1117  if (dst->refcount > 1 && dst->n_var_parts != k)
1118    dst = unshare_variable (set, dst);
1119
1120  i = src->n_var_parts - 1;
1121  j = dst->n_var_parts - 1;
1122  dst->n_var_parts = k;
1123
1124  for (k--; k >= 0; k--)
1125    {
1126      location_chain node, node2;
1127
1128      if (i >= 0 && j >= 0
1129	  && src->var_part[i].offset == dst->var_part[j].offset)
1130	{
1131	  /* Compute the "sorted" union of the chains, i.e. the locations which
1132	     are in both chains go first, they are sorted by the sum of
1133	     positions in the chains.  */
1134	  int dst_l, src_l;
1135	  int ii, jj, n;
1136	  struct variable_union_info *vui;
1137
1138	  /* If DST is shared compare the location chains.
1139	     If they are different we will modify the chain in DST with
1140	     high probability so make a copy of DST.  */
1141	  if (dst->refcount > 1)
1142	    {
1143	      for (node = src->var_part[i].loc_chain,
1144		   node2 = dst->var_part[j].loc_chain; node && node2;
1145		   node = node->next, node2 = node2->next)
1146		{
1147		  if (!((REG_P (node2->loc)
1148			 && REG_P (node->loc)
1149			 && REGNO (node2->loc) == REGNO (node->loc))
1150			|| rtx_equal_p (node2->loc, node->loc)))
1151		    break;
1152		}
1153	      if (node || node2)
1154		dst = unshare_variable (set, dst);
1155	    }
1156
1157	  src_l = 0;
1158	  for (node = src->var_part[i].loc_chain; node; node = node->next)
1159	    src_l++;
1160	  dst_l = 0;
1161	  for (node = dst->var_part[j].loc_chain; node; node = node->next)
1162	    dst_l++;
1163	  vui = XCNEWVEC (struct variable_union_info, src_l + dst_l);
1164
1165	  /* Fill in the locations from DST.  */
1166	  for (node = dst->var_part[j].loc_chain, jj = 0; node;
1167	       node = node->next, jj++)
1168	    {
1169	      vui[jj].lc = node;
1170	      vui[jj].pos_dst = jj;
1171
1172	      /* Value larger than a sum of 2 valid positions.  */
1173	      vui[jj].pos_src = src_l + dst_l;
1174	    }
1175
1176	  /* Fill in the locations from SRC.  */
1177	  n = dst_l;
1178	  for (node = src->var_part[i].loc_chain, ii = 0; node;
1179	       node = node->next, ii++)
1180	    {
1181	      /* Find location from NODE.  */
1182	      for (jj = 0; jj < dst_l; jj++)
1183		{
1184		  if ((REG_P (vui[jj].lc->loc)
1185		       && REG_P (node->loc)
1186		       && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
1187		      || rtx_equal_p (vui[jj].lc->loc, node->loc))
1188		    {
1189		      vui[jj].pos_src = ii;
1190		      break;
1191		    }
1192		}
1193	      if (jj >= dst_l)	/* The location has not been found.  */
1194		{
1195		  location_chain new_node;
1196
1197		  /* Copy the location from SRC.  */
1198		  new_node = pool_alloc (loc_chain_pool);
1199		  new_node->loc = node->loc;
1200		  vui[n].lc = new_node;
1201		  vui[n].pos_src = ii;
1202		  vui[n].pos_dst = src_l + dst_l;
1203		  n++;
1204		}
1205	    }
1206
1207	  for (ii = 0; ii < src_l + dst_l; ii++)
1208	    vui[ii].pos = vui[ii].pos_src + vui[ii].pos_dst;
1209
1210	  qsort (vui, n, sizeof (struct variable_union_info),
1211		 variable_union_info_cmp_pos);
1212
1213	  /* Reconnect the nodes in sorted order.  */
1214	  for (ii = 1; ii < n; ii++)
1215	    vui[ii - 1].lc->next = vui[ii].lc;
1216	  vui[n - 1].lc->next = NULL;
1217
1218	  dst->var_part[k].loc_chain = vui[0].lc;
1219	  dst->var_part[k].offset = dst->var_part[j].offset;
1220
1221	  free (vui);
1222	  i--;
1223	  j--;
1224	}
1225      else if ((i >= 0 && j >= 0
1226		&& src->var_part[i].offset < dst->var_part[j].offset)
1227	       || i < 0)
1228	{
1229	  dst->var_part[k] = dst->var_part[j];
1230	  j--;
1231	}
1232      else if ((i >= 0 && j >= 0
1233		&& src->var_part[i].offset > dst->var_part[j].offset)
1234	       || j < 0)
1235	{
1236	  location_chain *nextp;
1237
1238	  /* Copy the chain from SRC.  */
1239	  nextp = &dst->var_part[k].loc_chain;
1240	  for (node = src->var_part[i].loc_chain; node; node = node->next)
1241	    {
1242	      location_chain new_lc;
1243
1244	      new_lc = pool_alloc (loc_chain_pool);
1245	      new_lc->next = NULL;
1246	      new_lc->loc = node->loc;
1247
1248	      *nextp = new_lc;
1249	      nextp = &new_lc->next;
1250	    }
1251
1252	  dst->var_part[k].offset = src->var_part[i].offset;
1253	  i--;
1254	}
1255
1256      /* We are at the basic block boundary when computing union
1257	 so set the CUR_LOC to be the first element of the chain.  */
1258      if (dst->var_part[k].loc_chain)
1259	dst->var_part[k].cur_loc = dst->var_part[k].loc_chain->loc;
1260      else
1261	dst->var_part[k].cur_loc = NULL;
1262    }
1263
1264  /* Continue traversing the hash table.  */
1265  return 1;
1266}
1267
1268/* Compute union of dataflow sets SRC and DST and store it to DST.  */
1269
1270static void
1271dataflow_set_union (dataflow_set *dst, dataflow_set *src)
1272{
1273  int i;
1274
1275  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1276    attrs_list_union (&dst->regs[i], src->regs[i]);
1277
1278  htab_traverse (src->vars, variable_union, dst);
1279}
1280
1281/* Flag whether two dataflow sets being compared contain different data.  */
1282static bool
1283dataflow_set_different_value;
1284
1285static bool
1286variable_part_different_p (variable_part *vp1, variable_part *vp2)
1287{
1288  location_chain lc1, lc2;
1289
1290  for (lc1 = vp1->loc_chain; lc1; lc1 = lc1->next)
1291    {
1292      for (lc2 = vp2->loc_chain; lc2; lc2 = lc2->next)
1293	{
1294	  if (REG_P (lc1->loc) && REG_P (lc2->loc))
1295	    {
1296	      if (REGNO (lc1->loc) == REGNO (lc2->loc))
1297		break;
1298	    }
1299	  if (rtx_equal_p (lc1->loc, lc2->loc))
1300	    break;
1301	}
1302      if (!lc2)
1303	return true;
1304    }
1305  return false;
1306}
1307
1308/* Return true if variables VAR1 and VAR2 are different.
1309   If COMPARE_CURRENT_LOCATION is true compare also the cur_loc of each
1310   variable part.  */
1311
1312static bool
1313variable_different_p (variable var1, variable var2,
1314		      bool compare_current_location)
1315{
1316  int i;
1317
1318  if (var1 == var2)
1319    return false;
1320
1321  if (var1->n_var_parts != var2->n_var_parts)
1322    return true;
1323
1324  for (i = 0; i < var1->n_var_parts; i++)
1325    {
1326      if (var1->var_part[i].offset != var2->var_part[i].offset)
1327	return true;
1328      if (compare_current_location)
1329	{
1330	  if (!((REG_P (var1->var_part[i].cur_loc)
1331		 && REG_P (var2->var_part[i].cur_loc)
1332		 && (REGNO (var1->var_part[i].cur_loc)
1333		     == REGNO (var2->var_part[i].cur_loc)))
1334		|| rtx_equal_p (var1->var_part[i].cur_loc,
1335				var2->var_part[i].cur_loc)))
1336	    return true;
1337	}
1338      if (variable_part_different_p (&var1->var_part[i], &var2->var_part[i]))
1339	return true;
1340      if (variable_part_different_p (&var2->var_part[i], &var1->var_part[i]))
1341	return true;
1342    }
1343  return false;
1344}
1345
1346/* Compare variable *SLOT with the same variable in hash table DATA
1347   and set DATAFLOW_SET_DIFFERENT_VALUE if they are different.  */
1348
1349static int
1350dataflow_set_different_1 (void **slot, void *data)
1351{
1352  htab_t htab = (htab_t) data;
1353  variable var1, var2;
1354
1355  var1 = *(variable *) slot;
1356  var2 = htab_find_with_hash (htab, var1->decl,
1357			      VARIABLE_HASH_VAL (var1->decl));
1358  if (!var2)
1359    {
1360      dataflow_set_different_value = true;
1361
1362      /* Stop traversing the hash table.  */
1363      return 0;
1364    }
1365
1366  if (variable_different_p (var1, var2, false))
1367    {
1368      dataflow_set_different_value = true;
1369
1370      /* Stop traversing the hash table.  */
1371      return 0;
1372    }
1373
1374  /* Continue traversing the hash table.  */
1375  return 1;
1376}
1377
1378/* Compare variable *SLOT with the same variable in hash table DATA
1379   and set DATAFLOW_SET_DIFFERENT_VALUE if they are different.  */
1380
1381static int
1382dataflow_set_different_2 (void **slot, void *data)
1383{
1384  htab_t htab = (htab_t) data;
1385  variable var1, var2;
1386
1387  var1 = *(variable *) slot;
1388  var2 = htab_find_with_hash (htab, var1->decl,
1389			      VARIABLE_HASH_VAL (var1->decl));
1390  if (!var2)
1391    {
1392      dataflow_set_different_value = true;
1393
1394      /* Stop traversing the hash table.  */
1395      return 0;
1396    }
1397
1398  /* If both variables are defined they have been already checked for
1399     equivalence.  */
1400  gcc_assert (!variable_different_p (var1, var2, false));
1401
1402  /* Continue traversing the hash table.  */
1403  return 1;
1404}
1405
1406/* Return true if dataflow sets OLD_SET and NEW_SET differ.  */
1407
1408static bool
1409dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
1410{
1411  dataflow_set_different_value = false;
1412
1413  htab_traverse (old_set->vars, dataflow_set_different_1, new_set->vars);
1414  if (!dataflow_set_different_value)
1415    {
1416      /* We have compared the variables which are in both hash tables
1417	 so now only check whether there are some variables in NEW_SET->VARS
1418	 which are not in OLD_SET->VARS.  */
1419      htab_traverse (new_set->vars, dataflow_set_different_2, old_set->vars);
1420    }
1421  return dataflow_set_different_value;
1422}
1423
1424/* Free the contents of dataflow set SET.  */
1425
1426static void
1427dataflow_set_destroy (dataflow_set *set)
1428{
1429  int i;
1430
1431  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1432    attrs_list_clear (&set->regs[i]);
1433
1434  htab_delete (set->vars);
1435  set->vars = NULL;
1436}
1437
1438/* Return true if RTL X contains a SYMBOL_REF.  */
1439
1440static bool
1441contains_symbol_ref (rtx x)
1442{
1443  const char *fmt;
1444  RTX_CODE code;
1445  int i;
1446
1447  if (!x)
1448    return false;
1449
1450  code = GET_CODE (x);
1451  if (code == SYMBOL_REF)
1452    return true;
1453
1454  fmt = GET_RTX_FORMAT (code);
1455  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1456    {
1457      if (fmt[i] == 'e')
1458	{
1459	  if (contains_symbol_ref (XEXP (x, i)))
1460	    return true;
1461	}
1462      else if (fmt[i] == 'E')
1463	{
1464	  int j;
1465	  for (j = 0; j < XVECLEN (x, i); j++)
1466	    if (contains_symbol_ref (XVECEXP (x, i, j)))
1467	      return true;
1468	}
1469    }
1470
1471  return false;
1472}
1473
1474/* Shall EXPR be tracked?  */
1475
1476static bool
1477track_expr_p (tree expr)
1478{
1479  rtx decl_rtl;
1480  tree realdecl;
1481
1482  /* If EXPR is not a parameter or a variable do not track it.  */
1483  if (TREE_CODE (expr) != VAR_DECL && TREE_CODE (expr) != PARM_DECL)
1484    return 0;
1485
1486  /* It also must have a name...  */
1487  if (!DECL_NAME (expr))
1488    return 0;
1489
1490  /* ... and a RTL assigned to it.  */
1491  decl_rtl = DECL_RTL_IF_SET (expr);
1492  if (!decl_rtl)
1493    return 0;
1494
1495  /* If this expression is really a debug alias of some other declaration, we
1496     don't need to track this expression if the ultimate declaration is
1497     ignored.  */
1498  realdecl = expr;
1499  if (DECL_DEBUG_EXPR_IS_FROM (realdecl) && DECL_DEBUG_EXPR (realdecl))
1500    {
1501      realdecl = DECL_DEBUG_EXPR (realdecl);
1502      /* ??? We don't yet know how to emit DW_OP_piece for variable
1503	 that has been SRA'ed.  */
1504      if (!DECL_P (realdecl))
1505	return 0;
1506    }
1507
1508  /* Do not track EXPR if REALDECL it should be ignored for debugging
1509     purposes.  */
1510  if (DECL_IGNORED_P (realdecl))
1511    return 0;
1512
1513  /* Do not track global variables until we are able to emit correct location
1514     list for them.  */
1515  if (TREE_STATIC (realdecl))
1516    return 0;
1517
1518  /* When the EXPR is a DECL for alias of some variable (see example)
1519     the TREE_STATIC flag is not used.  Disable tracking all DECLs whose
1520     DECL_RTL contains SYMBOL_REF.
1521
1522     Example:
1523     extern char **_dl_argv_internal __attribute__ ((alias ("_dl_argv")));
1524     char **_dl_argv;
1525  */
1526  if (MEM_P (decl_rtl)
1527      && contains_symbol_ref (XEXP (decl_rtl, 0)))
1528    return 0;
1529
1530  /* If RTX is a memory it should not be very large (because it would be
1531     an array or struct).  */
1532  if (MEM_P (decl_rtl))
1533    {
1534      /* Do not track structures and arrays.  */
1535      if (GET_MODE (decl_rtl) == BLKmode
1536	  || AGGREGATE_TYPE_P (TREE_TYPE (realdecl)))
1537	return 0;
1538      if (MEM_SIZE (decl_rtl)
1539	  && INTVAL (MEM_SIZE (decl_rtl)) > MAX_VAR_PARTS)
1540	return 0;
1541    }
1542
1543  return 1;
1544}
1545
1546/* Return true if OFFSET is a valid offset for a register or memory
1547   access we want to track.  This is used to reject out-of-bounds
1548   accesses that can cause assertions to fail later.  Note that we
1549   don't reject negative offsets because they can be generated for
1550   paradoxical subregs on big-endian architectures.  */
1551
1552static inline bool
1553offset_valid_for_tracked_p (HOST_WIDE_INT offset)
1554{
1555  return (-MAX_VAR_PARTS < offset) && (offset < MAX_VAR_PARTS);
1556}
1557
1558/* Determine whether a given LOC refers to the same variable part as
1559   EXPR+OFFSET.  */
1560
1561static bool
1562same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset)
1563{
1564  tree expr2;
1565  HOST_WIDE_INT offset2;
1566
1567  if (! DECL_P (expr))
1568    return false;
1569
1570  if (REG_P (loc))
1571    {
1572      expr2 = REG_EXPR (loc);
1573      offset2 = REG_OFFSET (loc);
1574    }
1575  else if (MEM_P (loc))
1576    {
1577      expr2 = MEM_EXPR (loc);
1578      offset2 = INT_MEM_OFFSET (loc);
1579    }
1580  else
1581    return false;
1582
1583  if (! expr2 || ! DECL_P (expr2))
1584    return false;
1585
1586  expr = var_debug_decl (expr);
1587  expr2 = var_debug_decl (expr2);
1588
1589  return (expr == expr2 && offset == offset2);
1590}
1591
1592
1593/* Count uses (register and memory references) LOC which will be tracked.
1594   INSN is instruction which the LOC is part of.  */
1595
1596static int
1597count_uses (rtx *loc, void *insn)
1598{
1599  basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
1600
1601  if (REG_P (*loc))
1602    {
1603      gcc_assert (REGNO (*loc) < FIRST_PSEUDO_REGISTER);
1604      VTI (bb)->n_mos++;
1605    }
1606  else if (MEM_P (*loc)
1607	   && MEM_EXPR (*loc)
1608	   && track_expr_p (MEM_EXPR (*loc))
1609	   && offset_valid_for_tracked_p (INT_MEM_OFFSET (*loc)))
1610    {
1611      VTI (bb)->n_mos++;
1612    }
1613
1614  return 0;
1615}
1616
1617/* Helper function for finding all uses of REG/MEM in X in insn INSN.  */
1618
1619static void
1620count_uses_1 (rtx *x, void *insn)
1621{
1622  for_each_rtx (x, count_uses, insn);
1623}
1624
1625/* Count stores (register and memory references) LOC which will be tracked.
1626   INSN is instruction which the LOC is part of.  */
1627
1628static void
1629count_stores (rtx loc, rtx expr ATTRIBUTE_UNUSED, void *insn)
1630{
1631  count_uses (&loc, insn);
1632}
1633
1634/* Add uses (register and memory references) LOC which will be tracked
1635   to VTI (bb)->mos.  INSN is instruction which the LOC is part of.  */
1636
1637static int
1638add_uses (rtx *loc, void *insn)
1639{
1640  if (REG_P (*loc))
1641    {
1642      basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
1643      micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
1644
1645      if (REG_EXPR (*loc)
1646	  && track_expr_p (REG_EXPR (*loc))
1647	  && offset_valid_for_tracked_p (REG_OFFSET (*loc)))
1648	mo->type = MO_USE;
1649      else
1650	mo->type = MO_USE_NO_VAR;
1651      mo->u.loc = *loc;
1652      mo->insn = (rtx) insn;
1653    }
1654  else if (MEM_P (*loc)
1655	   && MEM_EXPR (*loc)
1656	   && track_expr_p (MEM_EXPR (*loc))
1657	   && offset_valid_for_tracked_p (INT_MEM_OFFSET (*loc)))
1658    {
1659      basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
1660      micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
1661
1662      mo->type = MO_USE;
1663      mo->u.loc = *loc;
1664      mo->insn = (rtx) insn;
1665    }
1666
1667  return 0;
1668}
1669
1670/* Helper function for finding all uses of REG/MEM in X in insn INSN.  */
1671
1672static void
1673add_uses_1 (rtx *x, void *insn)
1674{
1675  for_each_rtx (x, add_uses, insn);
1676}
1677
1678/* Add stores (register and memory references) LOC which will be tracked
1679   to VTI (bb)->mos. EXPR is the RTL expression containing the store.
1680   INSN is instruction which the LOC is part of.  */
1681
1682static void
1683add_stores (rtx loc, rtx expr, void *insn)
1684{
1685  if (REG_P (loc))
1686    {
1687      basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
1688      micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
1689
1690      if (GET_CODE (expr) == CLOBBER
1691	  || !(REG_EXPR (loc)
1692	       && track_expr_p (REG_EXPR (loc))
1693	       && offset_valid_for_tracked_p (REG_OFFSET (loc))))
1694	mo->type = MO_CLOBBER;
1695      else if (GET_CODE (expr) == SET
1696	       && SET_DEST (expr) == loc
1697	       && same_variable_part_p (SET_SRC (expr),
1698					REG_EXPR (loc),
1699					REG_OFFSET (loc)))
1700	mo->type = MO_COPY;
1701      else
1702	mo->type = MO_SET;
1703      mo->u.loc = loc;
1704      mo->insn = NEXT_INSN ((rtx) insn);
1705    }
1706  else if (MEM_P (loc)
1707	   && MEM_EXPR (loc)
1708	   && track_expr_p (MEM_EXPR (loc))
1709	   && offset_valid_for_tracked_p (INT_MEM_OFFSET (loc)))
1710    {
1711      basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
1712      micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
1713
1714      if (GET_CODE (expr) == CLOBBER)
1715	mo->type = MO_CLOBBER;
1716      else if (GET_CODE (expr) == SET
1717	       && SET_DEST (expr) == loc
1718	       && same_variable_part_p (SET_SRC (expr),
1719					MEM_EXPR (loc),
1720					INT_MEM_OFFSET (loc)))
1721	mo->type = MO_COPY;
1722      else
1723	mo->type = MO_SET;
1724      mo->u.loc = loc;
1725      mo->insn = NEXT_INSN ((rtx) insn);
1726    }
1727}
1728
1729/* Compute the changes of variable locations in the basic block BB.  */
1730
1731static bool
1732compute_bb_dataflow (basic_block bb)
1733{
1734  int i, n, r;
1735  bool changed;
1736  dataflow_set old_out;
1737  dataflow_set *in = &VTI (bb)->in;
1738  dataflow_set *out = &VTI (bb)->out;
1739
1740  dataflow_set_init (&old_out, htab_elements (VTI (bb)->out.vars) + 3);
1741  dataflow_set_copy (&old_out, out);
1742  dataflow_set_copy (out, in);
1743
1744  n = VTI (bb)->n_mos;
1745  for (i = 0; i < n; i++)
1746    {
1747      switch (VTI (bb)->mos[i].type)
1748	{
1749	  case MO_CALL:
1750	    for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
1751	      if (TEST_HARD_REG_BIT (call_used_reg_set, r))
1752		var_regno_delete (out, r);
1753	    break;
1754
1755	  case MO_USE:
1756	    {
1757	      rtx loc = VTI (bb)->mos[i].u.loc;
1758
1759	      if (GET_CODE (loc) == REG)
1760		var_reg_set (out, loc);
1761	      else if (GET_CODE (loc) == MEM)
1762		var_mem_set (out, loc);
1763	    }
1764	    break;
1765
1766	  case MO_SET:
1767	    {
1768	      rtx loc = VTI (bb)->mos[i].u.loc;
1769
1770	      if (REG_P (loc))
1771		var_reg_delete_and_set (out, loc, true);
1772	      else if (MEM_P (loc))
1773		var_mem_delete_and_set (out, loc, true);
1774	    }
1775	    break;
1776
1777	  case MO_COPY:
1778	    {
1779	      rtx loc = VTI (bb)->mos[i].u.loc;
1780
1781	      if (REG_P (loc))
1782		var_reg_delete_and_set (out, loc, false);
1783	      else if (MEM_P (loc))
1784		var_mem_delete_and_set (out, loc, false);
1785	    }
1786	    break;
1787
1788	  case MO_USE_NO_VAR:
1789	    {
1790	      rtx loc = VTI (bb)->mos[i].u.loc;
1791
1792	      if (REG_P (loc))
1793		var_reg_delete (out, loc, false);
1794	      else if (MEM_P (loc))
1795		var_mem_delete (out, loc, false);
1796	    }
1797	    break;
1798
1799	  case MO_CLOBBER:
1800	    {
1801	      rtx loc = VTI (bb)->mos[i].u.loc;
1802
1803	      if (REG_P (loc))
1804		var_reg_delete (out, loc, true);
1805	      else if (MEM_P (loc))
1806		var_mem_delete (out, loc, true);
1807	    }
1808	    break;
1809
1810	  case MO_ADJUST:
1811	    out->stack_adjust += VTI (bb)->mos[i].u.adjust;
1812	    break;
1813	}
1814    }
1815
1816  changed = dataflow_set_different (&old_out, out);
1817  dataflow_set_destroy (&old_out);
1818  return changed;
1819}
1820
1821/* Find the locations of variables in the whole function.  */
1822
1823static void
1824vt_find_locations (void)
1825{
1826  fibheap_t worklist, pending, fibheap_swap;
1827  sbitmap visited, in_worklist, in_pending, sbitmap_swap;
1828  basic_block bb;
1829  edge e;
1830  int *bb_order;
1831  int *rc_order;
1832  int i;
1833
1834  /* Compute reverse completion order of depth first search of the CFG
1835     so that the data-flow runs faster.  */
1836  rc_order = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
1837  bb_order = XNEWVEC (int, last_basic_block);
1838  pre_and_rev_post_order_compute (NULL, rc_order, false);
1839  for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
1840    bb_order[rc_order[i]] = i;
1841  free (rc_order);
1842
1843  worklist = fibheap_new ();
1844  pending = fibheap_new ();
1845  visited = sbitmap_alloc (last_basic_block);
1846  in_worklist = sbitmap_alloc (last_basic_block);
1847  in_pending = sbitmap_alloc (last_basic_block);
1848  sbitmap_zero (in_worklist);
1849
1850  FOR_EACH_BB (bb)
1851    fibheap_insert (pending, bb_order[bb->index], bb);
1852  sbitmap_ones (in_pending);
1853
1854  while (!fibheap_empty (pending))
1855    {
1856      fibheap_swap = pending;
1857      pending = worklist;
1858      worklist = fibheap_swap;
1859      sbitmap_swap = in_pending;
1860      in_pending = in_worklist;
1861      in_worklist = sbitmap_swap;
1862
1863      sbitmap_zero (visited);
1864
1865      while (!fibheap_empty (worklist))
1866	{
1867	  bb = fibheap_extract_min (worklist);
1868	  RESET_BIT (in_worklist, bb->index);
1869	  if (!TEST_BIT (visited, bb->index))
1870	    {
1871	      bool changed;
1872	      edge_iterator ei;
1873
1874	      SET_BIT (visited, bb->index);
1875
1876	      /* Calculate the IN set as union of predecessor OUT sets.  */
1877	      dataflow_set_clear (&VTI (bb)->in);
1878	      FOR_EACH_EDGE (e, ei, bb->preds)
1879		{
1880		  dataflow_set_union (&VTI (bb)->in, &VTI (e->src)->out);
1881		}
1882
1883	      changed = compute_bb_dataflow (bb);
1884	      if (changed)
1885		{
1886		  FOR_EACH_EDGE (e, ei, bb->succs)
1887		    {
1888		      if (e->dest == EXIT_BLOCK_PTR)
1889			continue;
1890
1891		      if (e->dest == bb)
1892			continue;
1893
1894		      if (TEST_BIT (visited, e->dest->index))
1895			{
1896			  if (!TEST_BIT (in_pending, e->dest->index))
1897			    {
1898			      /* Send E->DEST to next round.  */
1899			      SET_BIT (in_pending, e->dest->index);
1900			      fibheap_insert (pending,
1901					      bb_order[e->dest->index],
1902					      e->dest);
1903			    }
1904			}
1905		      else if (!TEST_BIT (in_worklist, e->dest->index))
1906			{
1907			  /* Add E->DEST to current round.  */
1908			  SET_BIT (in_worklist, e->dest->index);
1909			  fibheap_insert (worklist, bb_order[e->dest->index],
1910					  e->dest);
1911			}
1912		    }
1913		}
1914	    }
1915	}
1916    }
1917
1918  free (bb_order);
1919  fibheap_delete (worklist);
1920  fibheap_delete (pending);
1921  sbitmap_free (visited);
1922  sbitmap_free (in_worklist);
1923  sbitmap_free (in_pending);
1924}
1925
1926/* Print the content of the LIST to dump file.  */
1927
1928static void
1929dump_attrs_list (attrs list)
1930{
1931  for (; list; list = list->next)
1932    {
1933      print_mem_expr (dump_file, list->decl);
1934      fprintf (dump_file, "+" HOST_WIDE_INT_PRINT_DEC, list->offset);
1935    }
1936  fprintf (dump_file, "\n");
1937}
1938
1939/* Print the information about variable *SLOT to dump file.  */
1940
1941static int
1942dump_variable (void **slot, void *data ATTRIBUTE_UNUSED)
1943{
1944  variable var = *(variable *) slot;
1945  int i;
1946  location_chain node;
1947
1948  fprintf (dump_file, "  name: %s\n",
1949	   IDENTIFIER_POINTER (DECL_NAME (var->decl)));
1950  for (i = 0; i < var->n_var_parts; i++)
1951    {
1952      fprintf (dump_file, "    offset %ld\n",
1953	       (long) var->var_part[i].offset);
1954      for (node = var->var_part[i].loc_chain; node; node = node->next)
1955	{
1956	  fprintf (dump_file, "      ");
1957	  print_rtl_single (dump_file, node->loc);
1958	}
1959    }
1960
1961  /* Continue traversing the hash table.  */
1962  return 1;
1963}
1964
1965/* Print the information about variables from hash table VARS to dump file.  */
1966
1967static void
1968dump_vars (htab_t vars)
1969{
1970  if (htab_elements (vars) > 0)
1971    {
1972      fprintf (dump_file, "Variables:\n");
1973      htab_traverse (vars, dump_variable, NULL);
1974    }
1975}
1976
1977/* Print the dataflow set SET to dump file.  */
1978
1979static void
1980dump_dataflow_set (dataflow_set *set)
1981{
1982  int i;
1983
1984  fprintf (dump_file, "Stack adjustment: " HOST_WIDE_INT_PRINT_DEC "\n",
1985	   set->stack_adjust);
1986  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1987    {
1988      if (set->regs[i])
1989	{
1990	  fprintf (dump_file, "Reg %d:", i);
1991	  dump_attrs_list (set->regs[i]);
1992	}
1993    }
1994  dump_vars (set->vars);
1995  fprintf (dump_file, "\n");
1996}
1997
1998/* Print the IN and OUT sets for each basic block to dump file.  */
1999
2000static void
2001dump_dataflow_sets (void)
2002{
2003  basic_block bb;
2004
2005  FOR_EACH_BB (bb)
2006    {
2007      fprintf (dump_file, "\nBasic block %d:\n", bb->index);
2008      fprintf (dump_file, "IN:\n");
2009      dump_dataflow_set (&VTI (bb)->in);
2010      fprintf (dump_file, "OUT:\n");
2011      dump_dataflow_set (&VTI (bb)->out);
2012    }
2013}
2014
2015/* Add variable VAR to the hash table of changed variables and
2016   if it has no locations delete it from hash table HTAB.  */
2017
2018static void
2019variable_was_changed (variable var, htab_t htab)
2020{
2021  hashval_t hash = VARIABLE_HASH_VAL (var->decl);
2022
2023  if (emit_notes)
2024    {
2025      variable *slot;
2026
2027      slot = (variable *) htab_find_slot_with_hash (changed_variables,
2028						    var->decl, hash, INSERT);
2029
2030      if (htab && var->n_var_parts == 0)
2031	{
2032	  variable empty_var;
2033	  void **old;
2034
2035	  empty_var = pool_alloc (var_pool);
2036	  empty_var->decl = var->decl;
2037	  empty_var->refcount = 1;
2038	  empty_var->n_var_parts = 0;
2039	  *slot = empty_var;
2040
2041	  old = htab_find_slot_with_hash (htab, var->decl, hash,
2042					  NO_INSERT);
2043	  if (old)
2044	    htab_clear_slot (htab, old);
2045	}
2046      else
2047	{
2048	  *slot = var;
2049	}
2050    }
2051  else
2052    {
2053      gcc_assert (htab);
2054      if (var->n_var_parts == 0)
2055	{
2056	  void **slot = htab_find_slot_with_hash (htab, var->decl, hash,
2057						  NO_INSERT);
2058	  if (slot)
2059	    htab_clear_slot (htab, slot);
2060	}
2061    }
2062}
2063
2064/* Look for the index in VAR->var_part corresponding to OFFSET.
2065   Return -1 if not found.  If INSERTION_POINT is non-NULL, the
2066   referenced int will be set to the index that the part has or should
2067   have, if it should be inserted.  */
2068
2069static inline int
2070find_variable_location_part (variable var, HOST_WIDE_INT offset,
2071			     int *insertion_point)
2072{
2073  int pos, low, high;
2074
2075  /* Find the location part.  */
2076  low = 0;
2077  high = var->n_var_parts;
2078  while (low != high)
2079    {
2080      pos = (low + high) / 2;
2081      if (var->var_part[pos].offset < offset)
2082	low = pos + 1;
2083      else
2084	high = pos;
2085    }
2086  pos = low;
2087
2088  if (insertion_point)
2089    *insertion_point = pos;
2090
2091  if (pos < var->n_var_parts && var->var_part[pos].offset == offset)
2092    return pos;
2093
2094  return -1;
2095}
2096
2097/* Set the part of variable's location in the dataflow set SET.  The variable
2098   part is specified by variable's declaration DECL and offset OFFSET and the
2099   part's location by LOC.  */
2100
2101static void
2102set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset)
2103{
2104  int pos;
2105  location_chain node, next;
2106  location_chain *nextp;
2107  variable var;
2108  void **slot;
2109
2110  slot = htab_find_slot_with_hash (set->vars, decl,
2111				   VARIABLE_HASH_VAL (decl), INSERT);
2112  if (!*slot)
2113    {
2114      /* Create new variable information.  */
2115      var = pool_alloc (var_pool);
2116      var->decl = decl;
2117      var->refcount = 1;
2118      var->n_var_parts = 1;
2119      var->var_part[0].offset = offset;
2120      var->var_part[0].loc_chain = NULL;
2121      var->var_part[0].cur_loc = NULL;
2122      *slot = var;
2123      pos = 0;
2124    }
2125  else
2126    {
2127      int inspos = 0;
2128
2129      var = (variable) *slot;
2130
2131      pos = find_variable_location_part (var, offset, &inspos);
2132
2133      if (pos >= 0)
2134	{
2135	  node = var->var_part[pos].loc_chain;
2136
2137	  if (node
2138	      && ((REG_P (node->loc) && REG_P (loc)
2139		   && REGNO (node->loc) == REGNO (loc))
2140		  || rtx_equal_p (node->loc, loc)))
2141	    {
2142	      /* LOC is in the beginning of the chain so we have nothing
2143		 to do.  */
2144	      return;
2145	    }
2146	  else
2147	    {
2148	      /* We have to make a copy of a shared variable.  */
2149	      if (var->refcount > 1)
2150		var = unshare_variable (set, var);
2151	    }
2152	}
2153      else
2154	{
2155	  /* We have not found the location part, new one will be created.  */
2156
2157	  /* We have to make a copy of the shared variable.  */
2158	  if (var->refcount > 1)
2159	    var = unshare_variable (set, var);
2160
2161	  /* We track only variables whose size is <= MAX_VAR_PARTS bytes
2162	     thus there are at most MAX_VAR_PARTS different offsets.  */
2163	  gcc_assert (var->n_var_parts < MAX_VAR_PARTS);
2164
2165	  /* We have to move the elements of array starting at index
2166	     inspos to the next position.  */
2167	  for (pos = var->n_var_parts; pos > inspos; pos--)
2168	    var->var_part[pos] = var->var_part[pos - 1];
2169
2170	  var->n_var_parts++;
2171	  var->var_part[pos].offset = offset;
2172	  var->var_part[pos].loc_chain = NULL;
2173	  var->var_part[pos].cur_loc = NULL;
2174	}
2175    }
2176
2177  /* Delete the location from the list.  */
2178  nextp = &var->var_part[pos].loc_chain;
2179  for (node = var->var_part[pos].loc_chain; node; node = next)
2180    {
2181      next = node->next;
2182      if ((REG_P (node->loc) && REG_P (loc)
2183	   && REGNO (node->loc) == REGNO (loc))
2184	  || rtx_equal_p (node->loc, loc))
2185	{
2186	  pool_free (loc_chain_pool, node);
2187	  *nextp = next;
2188	  break;
2189	}
2190      else
2191	nextp = &node->next;
2192    }
2193
2194  /* Add the location to the beginning.  */
2195  node = pool_alloc (loc_chain_pool);
2196  node->loc = loc;
2197  node->next = var->var_part[pos].loc_chain;
2198  var->var_part[pos].loc_chain = node;
2199
2200  /* If no location was emitted do so.  */
2201  if (var->var_part[pos].cur_loc == NULL)
2202    {
2203      var->var_part[pos].cur_loc = loc;
2204      variable_was_changed (var, set->vars);
2205    }
2206}
2207
2208/* Remove all recorded register locations for the given variable part
2209   from dataflow set SET, except for those that are identical to loc.
2210   The variable part is specified by variable's declaration DECL and
2211   offset OFFSET.  */
2212
2213static void
2214clobber_variable_part (dataflow_set *set, rtx loc, tree decl,
2215		      HOST_WIDE_INT offset)
2216{
2217  void **slot;
2218
2219  if (! decl || ! DECL_P (decl))
2220    return;
2221
2222  slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
2223				   NO_INSERT);
2224  if (slot)
2225    {
2226      variable var = (variable) *slot;
2227      int pos = find_variable_location_part (var, offset, NULL);
2228
2229      if (pos >= 0)
2230	{
2231	  location_chain node, next;
2232
2233	  /* Remove the register locations from the dataflow set.  */
2234	  next = var->var_part[pos].loc_chain;
2235	  for (node = next; node; node = next)
2236	    {
2237	      next = node->next;
2238	      if (node->loc != loc)
2239		{
2240		  if (REG_P (node->loc))
2241		    {
2242		      attrs anode, anext;
2243		      attrs *anextp;
2244
2245		      /* Remove the variable part from the register's
2246			 list, but preserve any other variable parts
2247			 that might be regarded as live in that same
2248			 register.  */
2249		      anextp = &set->regs[REGNO (node->loc)];
2250		      for (anode = *anextp; anode; anode = anext)
2251			{
2252			  anext = anode->next;
2253			  if (anode->decl == decl
2254			      && anode->offset == offset)
2255			    {
2256			      pool_free (attrs_pool, anode);
2257			      *anextp = anext;
2258			    }
2259			}
2260		    }
2261
2262		  delete_variable_part (set, node->loc, decl, offset);
2263		}
2264	    }
2265	}
2266    }
2267}
2268
2269/* Delete the part of variable's location from dataflow set SET.  The variable
2270   part is specified by variable's declaration DECL and offset OFFSET and the
2271   part's location by LOC.  */
2272
2273static void
2274delete_variable_part (dataflow_set *set, rtx loc, tree decl,
2275		      HOST_WIDE_INT offset)
2276{
2277  void **slot;
2278
2279  slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
2280				   NO_INSERT);
2281  if (slot)
2282    {
2283      variable var = (variable) *slot;
2284      int pos = find_variable_location_part (var, offset, NULL);
2285
2286      if (pos >= 0)
2287	{
2288	  location_chain node, next;
2289	  location_chain *nextp;
2290	  bool changed;
2291
2292	  if (var->refcount > 1)
2293	    {
2294	      /* If the variable contains the location part we have to
2295		 make a copy of the variable.  */
2296	      for (node = var->var_part[pos].loc_chain; node;
2297		   node = node->next)
2298		{
2299		  if ((REG_P (node->loc) && REG_P (loc)
2300		       && REGNO (node->loc) == REGNO (loc))
2301		      || rtx_equal_p (node->loc, loc))
2302		    {
2303		      var = unshare_variable (set, var);
2304		      break;
2305		    }
2306		}
2307	    }
2308
2309	  /* Delete the location part.  */
2310	  nextp = &var->var_part[pos].loc_chain;
2311	  for (node = *nextp; node; node = next)
2312	    {
2313	      next = node->next;
2314	      if ((REG_P (node->loc) && REG_P (loc)
2315		   && REGNO (node->loc) == REGNO (loc))
2316		  || rtx_equal_p (node->loc, loc))
2317		{
2318		  pool_free (loc_chain_pool, node);
2319		  *nextp = next;
2320		  break;
2321		}
2322	      else
2323		nextp = &node->next;
2324	    }
2325
2326	  /* If we have deleted the location which was last emitted
2327	     we have to emit new location so add the variable to set
2328	     of changed variables.  */
2329	  if (var->var_part[pos].cur_loc
2330	      && ((REG_P (loc)
2331		   && REG_P (var->var_part[pos].cur_loc)
2332		   && REGNO (loc) == REGNO (var->var_part[pos].cur_loc))
2333		  || rtx_equal_p (loc, var->var_part[pos].cur_loc)))
2334	    {
2335	      changed = true;
2336	      if (var->var_part[pos].loc_chain)
2337		var->var_part[pos].cur_loc = var->var_part[pos].loc_chain->loc;
2338	    }
2339	  else
2340	    changed = false;
2341
2342	  if (var->var_part[pos].loc_chain == NULL)
2343	    {
2344	      var->n_var_parts--;
2345	      while (pos < var->n_var_parts)
2346		{
2347		  var->var_part[pos] = var->var_part[pos + 1];
2348		  pos++;
2349		}
2350	    }
2351	  if (changed)
2352	    variable_was_changed (var, set->vars);
2353	}
2354    }
2355}
2356
2357/* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP.  DATA contains
2358   additional parameters: WHERE specifies whether the note shall be emitted
2359   before of after instruction INSN.  */
2360
2361static int
2362emit_note_insn_var_location (void **varp, void *data)
2363{
2364  variable var = *(variable *) varp;
2365  rtx insn = ((emit_note_data *)data)->insn;
2366  enum emit_note_where where = ((emit_note_data *)data)->where;
2367  rtx note;
2368  int i, j, n_var_parts;
2369  bool complete;
2370  HOST_WIDE_INT last_limit;
2371  tree type_size_unit;
2372  HOST_WIDE_INT offsets[MAX_VAR_PARTS];
2373  rtx loc[MAX_VAR_PARTS];
2374
2375  gcc_assert (var->decl);
2376
2377  complete = true;
2378  last_limit = 0;
2379  n_var_parts = 0;
2380  for (i = 0; i < var->n_var_parts; i++)
2381    {
2382      enum machine_mode mode, wider_mode;
2383
2384      if (last_limit < var->var_part[i].offset)
2385	{
2386	  complete = false;
2387	  break;
2388	}
2389      else if (last_limit > var->var_part[i].offset)
2390	continue;
2391      offsets[n_var_parts] = var->var_part[i].offset;
2392      loc[n_var_parts] = var->var_part[i].loc_chain->loc;
2393      mode = GET_MODE (loc[n_var_parts]);
2394      last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
2395
2396      /* Attempt to merge adjacent registers or memory.  */
2397      wider_mode = GET_MODE_WIDER_MODE (mode);
2398      for (j = i + 1; j < var->n_var_parts; j++)
2399	if (last_limit <= var->var_part[j].offset)
2400	  break;
2401      if (j < var->n_var_parts
2402	  && wider_mode != VOIDmode
2403	  && GET_CODE (loc[n_var_parts])
2404	     == GET_CODE (var->var_part[j].loc_chain->loc)
2405	  && mode == GET_MODE (var->var_part[j].loc_chain->loc)
2406	  && last_limit == var->var_part[j].offset)
2407	{
2408	  rtx new_loc = NULL;
2409	  rtx loc2 = var->var_part[j].loc_chain->loc;
2410
2411	  if (REG_P (loc[n_var_parts])
2412	      && hard_regno_nregs[REGNO (loc[n_var_parts])][mode] * 2
2413		 == hard_regno_nregs[REGNO (loc[n_var_parts])][wider_mode]
2414	      && REGNO (loc[n_var_parts])
2415		 + hard_regno_nregs[REGNO (loc[n_var_parts])][mode]
2416		 == REGNO (loc2))
2417	    {
2418	      if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
2419		new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
2420					   mode, 0);
2421	      else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
2422		new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
2423	      if (new_loc)
2424		{
2425		  if (!REG_P (new_loc)
2426		      || REGNO (new_loc) != REGNO (loc[n_var_parts]))
2427		    new_loc = NULL;
2428		  else
2429		    REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
2430		}
2431	    }
2432	  else if (MEM_P (loc[n_var_parts])
2433		   && GET_CODE (XEXP (loc2, 0)) == PLUS
2434		   && GET_CODE (XEXP (XEXP (loc2, 0), 0)) == REG
2435		   && GET_CODE (XEXP (XEXP (loc2, 0), 1)) == CONST_INT)
2436	    {
2437	      if ((GET_CODE (XEXP (loc[n_var_parts], 0)) == REG
2438		   && rtx_equal_p (XEXP (loc[n_var_parts], 0),
2439				   XEXP (XEXP (loc2, 0), 0))
2440		   && INTVAL (XEXP (XEXP (loc2, 0), 1))
2441		      == GET_MODE_SIZE (mode))
2442		  || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
2443		      && GET_CODE (XEXP (XEXP (loc[n_var_parts], 0), 1))
2444			 == CONST_INT
2445		      && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
2446				      XEXP (XEXP (loc2, 0), 0))
2447		      && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
2448			 + GET_MODE_SIZE (mode)
2449			 == INTVAL (XEXP (XEXP (loc2, 0), 1))))
2450		new_loc = adjust_address_nv (loc[n_var_parts],
2451					     wider_mode, 0);
2452	    }
2453
2454	  if (new_loc)
2455	    {
2456	      loc[n_var_parts] = new_loc;
2457	      mode = wider_mode;
2458	      last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
2459	      i = j;
2460	    }
2461	}
2462      ++n_var_parts;
2463    }
2464  type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (var->decl));
2465  if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
2466    complete = false;
2467
2468  if (where == EMIT_NOTE_AFTER_INSN)
2469    note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
2470  else
2471    note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
2472
2473  if (!complete)
2474    {
2475      NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
2476						       NULL_RTX);
2477    }
2478  else if (n_var_parts == 1)
2479    {
2480      rtx expr_list
2481	= gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
2482
2483      NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
2484						       expr_list);
2485    }
2486  else if (n_var_parts)
2487    {
2488      rtx parallel;
2489
2490      for (i = 0; i < n_var_parts; i++)
2491	loc[i]
2492	  = gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));
2493
2494      parallel = gen_rtx_PARALLEL (VOIDmode,
2495				   gen_rtvec_v (n_var_parts, loc));
2496      NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
2497						       parallel);
2498    }
2499
2500  htab_clear_slot (changed_variables, varp);
2501
2502  /* When there are no location parts the variable has been already
2503     removed from hash table and a new empty variable was created.
2504     Free the empty variable.  */
2505  if (var->n_var_parts == 0)
2506    {
2507      pool_free (var_pool, var);
2508    }
2509
2510  /* Continue traversing the hash table.  */
2511  return 1;
2512}
2513
2514/* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
2515   CHANGED_VARIABLES and delete this chain.  WHERE specifies whether the notes
2516   shall be emitted before of after instruction INSN.  */
2517
2518static void
2519emit_notes_for_changes (rtx insn, enum emit_note_where where)
2520{
2521  emit_note_data data;
2522
2523  data.insn = insn;
2524  data.where = where;
2525  htab_traverse (changed_variables, emit_note_insn_var_location, &data);
2526}
2527
2528/* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
2529   same variable in hash table DATA or is not there at all.  */
2530
2531static int
2532emit_notes_for_differences_1 (void **slot, void *data)
2533{
2534  htab_t new_vars = (htab_t) data;
2535  variable old_var, new_var;
2536
2537  old_var = *(variable *) slot;
2538  new_var = htab_find_with_hash (new_vars, old_var->decl,
2539				 VARIABLE_HASH_VAL (old_var->decl));
2540
2541  if (!new_var)
2542    {
2543      /* Variable has disappeared.  */
2544      variable empty_var;
2545
2546      empty_var = pool_alloc (var_pool);
2547      empty_var->decl = old_var->decl;
2548      empty_var->refcount = 1;
2549      empty_var->n_var_parts = 0;
2550      variable_was_changed (empty_var, NULL);
2551    }
2552  else if (variable_different_p (old_var, new_var, true))
2553    {
2554      variable_was_changed (new_var, NULL);
2555    }
2556
2557  /* Continue traversing the hash table.  */
2558  return 1;
2559}
2560
2561/* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
2562   table DATA.  */
2563
2564static int
2565emit_notes_for_differences_2 (void **slot, void *data)
2566{
2567  htab_t old_vars = (htab_t) data;
2568  variable old_var, new_var;
2569
2570  new_var = *(variable *) slot;
2571  old_var = htab_find_with_hash (old_vars, new_var->decl,
2572				 VARIABLE_HASH_VAL (new_var->decl));
2573  if (!old_var)
2574    {
2575      /* Variable has appeared.  */
2576      variable_was_changed (new_var, NULL);
2577    }
2578
2579  /* Continue traversing the hash table.  */
2580  return 1;
2581}
2582
2583/* Emit notes before INSN for differences between dataflow sets OLD_SET and
2584   NEW_SET.  */
2585
2586static void
2587emit_notes_for_differences (rtx insn, dataflow_set *old_set,
2588			    dataflow_set *new_set)
2589{
2590  htab_traverse (old_set->vars, emit_notes_for_differences_1, new_set->vars);
2591  htab_traverse (new_set->vars, emit_notes_for_differences_2, old_set->vars);
2592  emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
2593}
2594
2595/* Emit the notes for changes of location parts in the basic block BB.  */
2596
2597static void
2598emit_notes_in_bb (basic_block bb)
2599{
2600  int i;
2601  dataflow_set set;
2602
2603  dataflow_set_init (&set, htab_elements (VTI (bb)->in.vars) + 3);
2604  dataflow_set_copy (&set, &VTI (bb)->in);
2605
2606  for (i = 0; i < VTI (bb)->n_mos; i++)
2607    {
2608      rtx insn = VTI (bb)->mos[i].insn;
2609
2610      switch (VTI (bb)->mos[i].type)
2611	{
2612	  case MO_CALL:
2613	    {
2614	      int r;
2615
2616	      for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
2617		if (TEST_HARD_REG_BIT (call_used_reg_set, r))
2618		  {
2619		    var_regno_delete (&set, r);
2620		  }
2621	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
2622	    }
2623	    break;
2624
2625	  case MO_USE:
2626	    {
2627	      rtx loc = VTI (bb)->mos[i].u.loc;
2628
2629	      if (GET_CODE (loc) == REG)
2630		var_reg_set (&set, loc);
2631	      else
2632		var_mem_set (&set, loc);
2633
2634	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
2635	    }
2636	    break;
2637
2638	  case MO_SET:
2639	    {
2640	      rtx loc = VTI (bb)->mos[i].u.loc;
2641
2642	      if (REG_P (loc))
2643		var_reg_delete_and_set (&set, loc, true);
2644	      else
2645		var_mem_delete_and_set (&set, loc, true);
2646
2647	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
2648	    }
2649	    break;
2650
2651	  case MO_COPY:
2652	    {
2653	      rtx loc = VTI (bb)->mos[i].u.loc;
2654
2655	      if (REG_P (loc))
2656		var_reg_delete_and_set (&set, loc, false);
2657	      else
2658		var_mem_delete_and_set (&set, loc, false);
2659
2660	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
2661	    }
2662	    break;
2663
2664	  case MO_USE_NO_VAR:
2665	    {
2666	      rtx loc = VTI (bb)->mos[i].u.loc;
2667
2668	      if (REG_P (loc))
2669		var_reg_delete (&set, loc, false);
2670	      else
2671		var_mem_delete (&set, loc, false);
2672
2673	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
2674	    }
2675	    break;
2676
2677	  case MO_CLOBBER:
2678	    {
2679	      rtx loc = VTI (bb)->mos[i].u.loc;
2680
2681	      if (REG_P (loc))
2682		var_reg_delete (&set, loc, true);
2683	      else
2684		var_mem_delete (&set, loc, true);
2685
2686	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
2687	    }
2688	    break;
2689
2690	  case MO_ADJUST:
2691	    set.stack_adjust += VTI (bb)->mos[i].u.adjust;
2692	    break;
2693	}
2694    }
2695  dataflow_set_destroy (&set);
2696}
2697
2698/* Emit notes for the whole function.  */
2699
2700static void
2701vt_emit_notes (void)
2702{
2703  basic_block bb;
2704  dataflow_set *last_out;
2705  dataflow_set empty;
2706
2707  gcc_assert (!htab_elements (changed_variables));
2708
2709  /* Enable emitting notes by functions (mainly by set_variable_part and
2710     delete_variable_part).  */
2711  emit_notes = true;
2712
2713  dataflow_set_init (&empty, 7);
2714  last_out = &empty;
2715
2716  FOR_EACH_BB (bb)
2717    {
2718      /* Emit the notes for changes of variable locations between two
2719	 subsequent basic blocks.  */
2720      emit_notes_for_differences (BB_HEAD (bb), last_out, &VTI (bb)->in);
2721
2722      /* Emit the notes for the changes in the basic block itself.  */
2723      emit_notes_in_bb (bb);
2724
2725      last_out = &VTI (bb)->out;
2726    }
2727  dataflow_set_destroy (&empty);
2728  emit_notes = false;
2729}
2730
2731/* If there is a declaration and offset associated with register/memory RTL
2732   assign declaration to *DECLP and offset to *OFFSETP, and return true.  */
2733
2734static bool
2735vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
2736{
2737  if (REG_P (rtl))
2738    {
2739      if (REG_ATTRS (rtl))
2740	{
2741	  *declp = REG_EXPR (rtl);
2742	  *offsetp = REG_OFFSET (rtl);
2743	  return true;
2744	}
2745    }
2746  else if (MEM_P (rtl))
2747    {
2748      if (MEM_ATTRS (rtl))
2749	{
2750	  *declp = MEM_EXPR (rtl);
2751	  *offsetp = INT_MEM_OFFSET (rtl);
2752	  return true;
2753	}
2754    }
2755  return false;
2756}
2757
2758/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */
2759
2760static void
2761vt_add_function_parameters (void)
2762{
2763  tree parm;
2764
2765  for (parm = DECL_ARGUMENTS (current_function_decl);
2766       parm; parm = TREE_CHAIN (parm))
2767    {
2768      rtx decl_rtl = DECL_RTL_IF_SET (parm);
2769      rtx incoming = DECL_INCOMING_RTL (parm);
2770      tree decl;
2771      HOST_WIDE_INT offset;
2772      dataflow_set *out;
2773
2774      if (TREE_CODE (parm) != PARM_DECL)
2775	continue;
2776
2777      if (!DECL_NAME (parm))
2778	continue;
2779
2780      if (!decl_rtl || !incoming)
2781	continue;
2782
2783      if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
2784	continue;
2785
2786      if (!vt_get_decl_and_offset (incoming, &decl, &offset))
2787	if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
2788	  continue;
2789
2790      if (!decl)
2791	continue;
2792
2793      gcc_assert (parm == decl);
2794
2795      out = &VTI (ENTRY_BLOCK_PTR)->out;
2796
2797      if (REG_P (incoming))
2798	{
2799	  gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
2800	  attrs_list_insert (&out->regs[REGNO (incoming)],
2801			     parm, offset, incoming);
2802	  set_variable_part (out, incoming, parm, offset);
2803	}
2804      else if (MEM_P (incoming))
2805	set_variable_part (out, incoming, parm, offset);
2806    }
2807}
2808
2809/* Allocate and initialize the data structures for variable tracking
2810   and parse the RTL to get the micro operations.  */
2811
2812static void
2813vt_initialize (void)
2814{
2815  basic_block bb;
2816
2817  alloc_aux_for_blocks (sizeof (struct variable_tracking_info_def));
2818
2819  FOR_EACH_BB (bb)
2820    {
2821      rtx insn;
2822      HOST_WIDE_INT pre, post = 0;
2823
2824      /* Count the number of micro operations.  */
2825      VTI (bb)->n_mos = 0;
2826      for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
2827	   insn = NEXT_INSN (insn))
2828	{
2829	  if (INSN_P (insn))
2830	    {
2831	      if (!frame_pointer_needed)
2832		{
2833		  insn_stack_adjust_offset_pre_post (insn, &pre, &post);
2834		  if (pre)
2835		    VTI (bb)->n_mos++;
2836		  if (post)
2837		    VTI (bb)->n_mos++;
2838		}
2839	      note_uses (&PATTERN (insn), count_uses_1, insn);
2840	      note_stores (PATTERN (insn), count_stores, insn);
2841	      if (CALL_P (insn))
2842		VTI (bb)->n_mos++;
2843	    }
2844	}
2845
2846      /* Add the micro-operations to the array.  */
2847      VTI (bb)->mos = XNEWVEC (micro_operation, VTI (bb)->n_mos);
2848      VTI (bb)->n_mos = 0;
2849      for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
2850	   insn = NEXT_INSN (insn))
2851	{
2852	  if (INSN_P (insn))
2853	    {
2854	      int n1, n2;
2855
2856	      if (!frame_pointer_needed)
2857		{
2858		  insn_stack_adjust_offset_pre_post (insn, &pre, &post);
2859		  if (pre)
2860		    {
2861		      micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
2862
2863		      mo->type = MO_ADJUST;
2864		      mo->u.adjust = pre;
2865		      mo->insn = insn;
2866		    }
2867		}
2868
2869	      n1 = VTI (bb)->n_mos;
2870	      note_uses (&PATTERN (insn), add_uses_1, insn);
2871	      n2 = VTI (bb)->n_mos - 1;
2872
2873	      /* Order the MO_USEs to be before MO_USE_NO_VARs.  */
2874	      while (n1 < n2)
2875		{
2876		  while (n1 < n2 && VTI (bb)->mos[n1].type == MO_USE)
2877		    n1++;
2878		  while (n1 < n2 && VTI (bb)->mos[n2].type == MO_USE_NO_VAR)
2879		    n2--;
2880		  if (n1 < n2)
2881		    {
2882		      micro_operation sw;
2883
2884		      sw = VTI (bb)->mos[n1];
2885		      VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
2886		      VTI (bb)->mos[n2] = sw;
2887		    }
2888		}
2889
2890	      if (CALL_P (insn))
2891		{
2892		  micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
2893
2894		  mo->type = MO_CALL;
2895		  mo->insn = insn;
2896		}
2897
2898	      n1 = VTI (bb)->n_mos;
2899	      /* This will record NEXT_INSN (insn), such that we can
2900		 insert notes before it without worrying about any
2901		 notes that MO_USEs might emit after the insn.  */
2902	      note_stores (PATTERN (insn), add_stores, insn);
2903	      n2 = VTI (bb)->n_mos - 1;
2904
2905	      /* Order the MO_CLOBBERs to be before MO_SETs.  */
2906	      while (n1 < n2)
2907		{
2908		  while (n1 < n2 && VTI (bb)->mos[n1].type == MO_CLOBBER)
2909		    n1++;
2910		  while (n1 < n2 && (VTI (bb)->mos[n2].type == MO_SET
2911				     || VTI (bb)->mos[n2].type == MO_COPY))
2912		    n2--;
2913		  if (n1 < n2)
2914		    {
2915		      micro_operation sw;
2916
2917		      sw = VTI (bb)->mos[n1];
2918		      VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
2919		      VTI (bb)->mos[n2] = sw;
2920		    }
2921		}
2922
2923	      if (!frame_pointer_needed && post)
2924		{
2925		  micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
2926
2927		  mo->type = MO_ADJUST;
2928		  mo->u.adjust = post;
2929		  mo->insn = insn;
2930		}
2931	    }
2932	}
2933    }
2934
2935  /* Init the IN and OUT sets.  */
2936  FOR_ALL_BB (bb)
2937    {
2938      VTI (bb)->visited = false;
2939      dataflow_set_init (&VTI (bb)->in, 7);
2940      dataflow_set_init (&VTI (bb)->out, 7);
2941    }
2942
2943  attrs_pool = create_alloc_pool ("attrs_def pool",
2944				  sizeof (struct attrs_def), 1024);
2945  var_pool = create_alloc_pool ("variable_def pool",
2946				sizeof (struct variable_def), 64);
2947  loc_chain_pool = create_alloc_pool ("location_chain_def pool",
2948				      sizeof (struct location_chain_def),
2949				      1024);
2950  changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
2951				   NULL);
2952  vt_add_function_parameters ();
2953}
2954
2955/* Free the data structures needed for variable tracking.  */
2956
2957static void
2958vt_finalize (void)
2959{
2960  basic_block bb;
2961
2962  FOR_EACH_BB (bb)
2963    {
2964      free (VTI (bb)->mos);
2965    }
2966
2967  FOR_ALL_BB (bb)
2968    {
2969      dataflow_set_destroy (&VTI (bb)->in);
2970      dataflow_set_destroy (&VTI (bb)->out);
2971    }
2972  free_aux_for_blocks ();
2973  free_alloc_pool (attrs_pool);
2974  free_alloc_pool (var_pool);
2975  free_alloc_pool (loc_chain_pool);
2976  htab_delete (changed_variables);
2977}
2978
2979/* The entry point to variable tracking pass.  */
2980
2981unsigned int
2982variable_tracking_main (void)
2983{
2984  if (n_basic_blocks > 500 && n_edges / n_basic_blocks >= 20)
2985    return 0;
2986
2987  mark_dfs_back_edges ();
2988  vt_initialize ();
2989  if (!frame_pointer_needed)
2990    {
2991      if (!vt_stack_adjustments ())
2992	{
2993	  vt_finalize ();
2994	  return 0;
2995	}
2996    }
2997
2998  vt_find_locations ();
2999  vt_emit_notes ();
3000
3001  if (dump_file && (dump_flags & TDF_DETAILS))
3002    {
3003      dump_dataflow_sets ();
3004      dump_flow_info (dump_file, dump_flags);
3005    }
3006
3007  vt_finalize ();
3008  return 0;
3009}
3010
3011static bool
3012gate_handle_var_tracking (void)
3013{
3014  return (flag_var_tracking);
3015}
3016
3017
3018
3019struct tree_opt_pass pass_variable_tracking =
3020{
3021  "vartrack",                           /* name */
3022  gate_handle_var_tracking,             /* gate */
3023  variable_tracking_main,               /* execute */
3024  NULL,                                 /* sub */
3025  NULL,                                 /* next */
3026  0,                                    /* static_pass_number */
3027  TV_VAR_TRACKING,                      /* tv_id */
3028  0,                                    /* properties_required */
3029  0,                                    /* properties_provided */
3030  0,                                    /* properties_destroyed */
3031  0,                                    /* todo_flags_start */
3032  TODO_dump_func,                       /* todo_flags_finish */
3033  'V'                                   /* letter */
3034};
3035
3036