OSDN Git Service

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