1/* Infrastructure for tracking user variable locations and values
2   throughout compilation.
3   Copyright (C) 2010-2015 Free Software Foundation, Inc.
4   Contributed by Alexandre Oliva <aoliva@redhat.com>.
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3.  If not see
20<http://www.gnu.org/licenses/>.  */
21
22#ifndef GCC_VALTRACK_H
23#define GCC_VALTRACK_H
24
25#include "bitmap.h"
26#include "df.h"
27#include "rtl.h"
28#include "hash-table.h"
29
30/* Debug uses of dead regs.  */
31
32/* Entry that maps a dead pseudo (REG) used in a debug insns that dies
33   at different blocks to the debug temp (DTEMP) it was replaced
34   with.  */
35
36struct dead_debug_global_entry
37{
38  rtx reg;
39  rtx dtemp;
40};
41
42/* Descriptor for hash_table to hash by dead_debug_global_entry's REG
43   and map to DTEMP.  */
44
45struct dead_debug_hash_descr
46{
47  /* The hash table contains pointers to entries of this type.  */
48  typedef struct dead_debug_global_entry value_type;
49  typedef struct dead_debug_global_entry compare_type;
50  /* Hash on the pseudo number.  */
51  static inline hashval_t hash (const value_type *my);
52  /* Entries are identical if they refer to the same pseudo.  */
53  static inline bool equal (const value_type *my, const compare_type *other);
54  /* Release entries when they're removed.  */
55  static inline void remove (value_type *p);
56};
57
58/* Hash on the pseudo number.  */
59inline hashval_t
60dead_debug_hash_descr::hash (const value_type *my)
61{
62  return REGNO (my->reg);
63}
64
65/* Entries are identical if they refer to the same pseudo.  */
66inline bool
67dead_debug_hash_descr::equal (const value_type *my, const compare_type *other)
68{
69  return my->reg == other->reg;
70}
71
72/* Release entries when they're removed.  */
73inline void
74dead_debug_hash_descr::remove (value_type *p)
75{
76  XDELETE (p);
77}
78
79/* Maintain a global table of pseudos used in debug insns after their
80   deaths in other blocks, and debug temps their deathpoint values are
81   to be bound to.  */
82
83struct dead_debug_global
84{
85  /* This hash table that maps pseudos to debug temps.  */
86  hash_table<dead_debug_hash_descr> *htab;
87  /* For each entry in htab, the bit corresponding to its REGNO will
88     be set.  */
89  bitmap used;
90};
91
92/* Node of a linked list of uses of dead REGs in debug insns.  */
93
94struct dead_debug_use
95{
96  df_ref use;
97  struct dead_debug_use *next;
98};
99
100/* Linked list of the above, with a bitmap of the REGs in the
101   list.  */
102
103struct dead_debug_local
104{
105  /* The first dead_debug_use entry in the list.  */
106  struct dead_debug_use *head;
107  /* A pointer to the global tracking data structure.  */
108  struct dead_debug_global *global;
109  /* A bitmap that has bits set for each REG used in the
110     dead_debug_use list, and for each entry in the global hash
111     table.  */
112  bitmap used;
113  /* A bitmap that has bits set for each INSN that is to be
114     rescanned.  */
115  bitmap to_rescan;
116};
117
118/* This type controls the behavior of dead_debug_insert_temp WRT
119   UREGNO and INSN.  */
120
121enum debug_temp_where
122  {
123    /* Bind a newly-created debug temporary to a REG for UREGNO, and
124       insert the debug insn before INSN.  REG is expected to die at
125       INSN.  */
126    DEBUG_TEMP_BEFORE_WITH_REG = -1,
127    /* Bind a newly-created debug temporary to the value INSN stores
128       in REG, and insert the debug insn before INSN.  */
129    DEBUG_TEMP_BEFORE_WITH_VALUE = 0,
130    /* Bind a newly-created debug temporary to a REG for UREGNO, and
131       insert the debug insn after INSN.  REG is expected to be set at
132       INSN.  */
133    DEBUG_TEMP_AFTER_WITH_REG = 1,
134    /* Like DEBUG_TEMP_AFTER_WITH_REG, but force addition of a debug
135       temporary even if there is just a single debug use.  This is used
136       on regs that are becoming REG_DEAD on INSN and so uses of the
137       reg later on are invalid.  */
138    DEBUG_TEMP_AFTER_WITH_REG_FORCE = 2
139  };
140
141extern void dead_debug_global_init (struct dead_debug_global *, bitmap);
142extern void dead_debug_global_finish (struct dead_debug_global *, bitmap);
143extern void dead_debug_local_init (struct dead_debug_local *, bitmap,
144				   struct dead_debug_global *);
145extern void dead_debug_local_finish (struct dead_debug_local *, bitmap);
146extern void dead_debug_add (struct dead_debug_local *, df_ref, unsigned int);
147extern int dead_debug_insert_temp (struct dead_debug_local *,
148				   unsigned int uregno, rtx_insn *insn,
149				   enum debug_temp_where);
150
151extern void propagate_for_debug (rtx_insn *, rtx_insn *, rtx, rtx, basic_block);
152
153
154#endif /* GCC_VALTRACK_H */
155