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