]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-modref-tree.c
Correct a function pre/postcondition [PR102403].
[thirdparty/gcc.git] / gcc / ipa-modref-tree.c
CommitLineData
d119f34c 1/* Data structure for the modref pass.
99dee823 2 Copyright (C) 2020-2021 Free Software Foundation, Inc.
d119f34c
JH
3 Contributed by David Cepelik and Jan Hubicka
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "backend.h"
25#include "tree.h"
26#include "ipa-modref-tree.h"
27#include "selftest.h"
28
29#if CHECKING_P
30
39b3b1bd 31namespace selftest {
d119f34c
JH
32
33static void
34test_insert_search_collapse ()
35{
36 modref_base_node<alias_set_type> *base_node;
37 modref_ref_node<alias_set_type> *ref_node;
c34db4b6 38 modref_access_node a = unspecified_modref_access_node;
d119f34c 39
c33f4742 40 modref_tree<alias_set_type> *t = new modref_tree<alias_set_type>(1, 2, 2);
d119f34c
JH
41 ASSERT_FALSE (t->every_base);
42
43 /* Insert into an empty tree. */
5c85f295 44 t->insert (1, 2, a, false);
d119f34c
JH
45 ASSERT_NE (t->bases, NULL);
46 ASSERT_EQ (t->bases->length (), 1);
47 ASSERT_FALSE (t->every_base);
48 ASSERT_EQ (t->search (2), NULL);
49
50 base_node = t->search (1);
51 ASSERT_NE (base_node, NULL);
52 ASSERT_EQ (base_node->base, 1);
53 ASSERT_NE (base_node->refs, NULL);
54 ASSERT_EQ (base_node->refs->length (), 1);
55 ASSERT_EQ (base_node->search (1), NULL);
56
57 ref_node = base_node->search (2);
58 ASSERT_NE (ref_node, NULL);
59 ASSERT_EQ (ref_node->ref, 2);
60
61 /* Insert when base exists but ref does not. */
5c85f295 62 t->insert (1, 3, a, false);
d119f34c
JH
63 ASSERT_NE (t->bases, NULL);
64 ASSERT_EQ (t->bases->length (), 1);
65 ASSERT_EQ (t->search (1), base_node);
66 ASSERT_EQ (t->search (2), NULL);
67 ASSERT_NE (base_node->refs, NULL);
68 ASSERT_EQ (base_node->refs->length (), 2);
69
70 ref_node = base_node->search (3);
71 ASSERT_NE (ref_node, NULL);
72
73 /* Insert when base and ref exist, but access is not dominated by nor
74 dominates other accesses. */
5c85f295 75 t->insert (1, 2, a, false);
d119f34c
JH
76 ASSERT_EQ (t->bases->length (), 1);
77 ASSERT_EQ (t->search (1), base_node);
78
79 ref_node = base_node->search (2);
80 ASSERT_NE (ref_node, NULL);
81
82 /* Insert when base and ref exist and access is dominated. */
5c85f295 83 t->insert (1, 2, a, false);
d119f34c
JH
84 ASSERT_EQ (t->search (1), base_node);
85 ASSERT_EQ (base_node->search (2), ref_node);
86
87 /* Insert ref to trigger ref list collapse for base 1. */
5c85f295 88 t->insert (1, 4, a, false);
d119f34c
JH
89 ASSERT_EQ (t->search (1), base_node);
90 ASSERT_EQ (base_node->refs, NULL);
91 ASSERT_EQ (base_node->search (2), NULL);
92 ASSERT_EQ (base_node->search (3), NULL);
93 ASSERT_TRUE (base_node->every_ref);
94
95 /* Further inserts to collapsed ref list are ignored. */
5c85f295 96 t->insert (1, 5, a, false);
d119f34c
JH
97 ASSERT_EQ (t->search (1), base_node);
98 ASSERT_EQ (base_node->refs, NULL);
99 ASSERT_EQ (base_node->search (2), NULL);
100 ASSERT_EQ (base_node->search (3), NULL);
101 ASSERT_TRUE (base_node->every_ref);
102
103 /* Insert base to trigger base list collapse. */
e28ac73a 104 t->insert (5, 0, a, false);
d119f34c
JH
105 ASSERT_TRUE (t->every_base);
106 ASSERT_EQ (t->bases, NULL);
107 ASSERT_EQ (t->search (1), NULL);
108
109 /* Further inserts to collapsed base list are ignored. */
5c85f295 110 t->insert (7, 8, a, false);
d119f34c
JH
111 ASSERT_TRUE (t->every_base);
112 ASSERT_EQ (t->bases, NULL);
113 ASSERT_EQ (t->search (1), NULL);
e14c2bdc
DM
114
115 delete t;
d119f34c
JH
116}
117
118static void
119test_merge ()
120{
121 modref_tree<alias_set_type> *t1, *t2;
122 modref_base_node<alias_set_type> *base_node;
c34db4b6 123 modref_access_node a = unspecified_modref_access_node;
c33f4742
JH
124
125 t1 = new modref_tree<alias_set_type>(3, 4, 1);
5c85f295
JH
126 t1->insert (1, 1, a, false);
127 t1->insert (1, 2, a, false);
128 t1->insert (1, 3, a, false);
129 t1->insert (2, 1, a, false);
130 t1->insert (3, 1, a, false);
c33f4742
JH
131
132 t2 = new modref_tree<alias_set_type>(10, 10, 10);
5c85f295
JH
133 t2->insert (1, 2, a, false);
134 t2->insert (1, 3, a, false);
135 t2->insert (1, 4, a, false);
136 t2->insert (3, 2, a, false);
137 t2->insert (3, 3, a, false);
138 t2->insert (3, 4, a, false);
139 t2->insert (3, 5, a, false);
140
141 t1->merge (t2, NULL, false);
d119f34c
JH
142
143 ASSERT_FALSE (t1->every_base);
144 ASSERT_NE (t1->bases, NULL);
145 ASSERT_EQ (t1->bases->length (), 3);
146
147 base_node = t1->search (1);
148 ASSERT_NE (base_node->refs, NULL);
149 ASSERT_FALSE (base_node->every_ref);
150 ASSERT_EQ (base_node->refs->length (), 4);
151
152 base_node = t1->search (2);
153 ASSERT_NE (base_node->refs, NULL);
154 ASSERT_FALSE (base_node->every_ref);
155 ASSERT_EQ (base_node->refs->length (), 1);
156
157 base_node = t1->search (3);
158 ASSERT_EQ (base_node->refs, NULL);
159 ASSERT_TRUE (base_node->every_ref);
e14c2bdc
DM
160
161 delete t1;
162 delete t2;
d119f34c
JH
163}
164
165
166void
39b3b1bd 167ipa_modref_tree_c_tests ()
d119f34c
JH
168{
169 test_insert_search_collapse ();
170 test_merge ();
171}
172
39b3b1bd
JH
173} // namespace selftest
174
d119f34c
JH
175#endif
176
177void
178gt_ggc_mx (modref_tree < int >*const &tt)
179{
180 if (tt->bases)
181 {
182 ggc_test_and_set_mark (tt->bases);
183 gt_ggc_mx (tt->bases);
184 }
185}
186
187void
188gt_ggc_mx (modref_tree < tree_node * >*const &tt)
189{
190 if (tt->bases)
191 {
192 ggc_test_and_set_mark (tt->bases);
193 gt_ggc_mx (tt->bases);
194 }
195}
196
197void gt_pch_nx (modref_tree<int>* const&) {}
198void gt_pch_nx (modref_tree<tree_node*>* const&) {}
199void gt_pch_nx (modref_tree<int>* const&, gt_pointer_operator, void *) {}
200void gt_pch_nx (modref_tree<tree_node*>* const&, gt_pointer_operator, void *) {}
201
202void gt_ggc_mx (modref_base_node<int>* &b)
203{
204 ggc_test_and_set_mark (b);
205 if (b->refs)
206 {
207 ggc_test_and_set_mark (b->refs);
208 gt_ggc_mx (b->refs);
209 }
210}
211
212void gt_ggc_mx (modref_base_node<tree_node*>* &b)
213{
214 ggc_test_and_set_mark (b);
215 if (b->refs)
216 {
217 ggc_test_and_set_mark (b->refs);
218 gt_ggc_mx (b->refs);
219 }
220 if (b->base)
221 gt_ggc_mx (b->base);
222}
223
224void gt_pch_nx (modref_base_node<int>*) {}
225void gt_pch_nx (modref_base_node<tree_node*>*) {}
226void gt_pch_nx (modref_base_node<int>*, gt_pointer_operator, void *) {}
227void gt_pch_nx (modref_base_node<tree_node*>*, gt_pointer_operator, void *) {}
228
229void gt_ggc_mx (modref_ref_node<int>* &r)
230{
231 ggc_test_and_set_mark (r);
c33f4742
JH
232 if (r->accesses)
233 {
234 ggc_test_and_set_mark (r->accesses);
235 gt_ggc_mx (r->accesses);
236 }
d119f34c
JH
237}
238
239void gt_ggc_mx (modref_ref_node<tree_node*>* &r)
240{
241 ggc_test_and_set_mark (r);
c33f4742
JH
242 if (r->accesses)
243 {
244 ggc_test_and_set_mark (r->accesses);
245 gt_ggc_mx (r->accesses);
246 }
d119f34c
JH
247 if (r->ref)
248 gt_ggc_mx (r->ref);
249}
250
251void gt_pch_nx (modref_ref_node<int>* ) {}
252void gt_pch_nx (modref_ref_node<tree_node*>*) {}
253void gt_pch_nx (modref_ref_node<int>*, gt_pointer_operator, void *) {}
254void gt_pch_nx (modref_ref_node<tree_node*>*, gt_pointer_operator, void *) {}
255
c33f4742
JH
256void gt_ggc_mx (modref_access_node &)
257{
258}