OSDN Git Service

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