1 /*
2 * Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #include "gbldefs.h"
19 #include "error.h"
20 #include "global.h"
21 #include "symtab.h"
22 #include "verify.h"
23 #include "ili.h"
24 #include "iliutil.h"
25
26 #if DEBUG
27
28 #define VERIFY(cond, message) ((cond)?(void)0 : verify_failure(__LINE__, #cond, message))
29
30 /* Out-of-line helper for macro VERIFY. */
31 static void
verify_failure(int line,const char * cond,const char * message)32 verify_failure(int line, const char *cond, const char *message) {
33 if (XBIT(160, 2)) {
34 fprintf(stderr, "%s:%d: VERIFY(%s): %s\n", __FILE__, line, cond, message);
35 interr(message, 0, error_max_severity());
36 }
37 }
38
39 typedef unsigned char epoch_t;
40
41 /* A visit_info holds information about an ILI node */
42 typedef struct {
43 /* This record is considered absent unless epoch==current_epoch. */
44 epoch_t epoch;
45 } visit_info;
46
47 static visit_info *visited_ili;
48 static size_t visited_size; /* Number of elements pointed to by visited_ili. */
49 static epoch_t current_epoch;
50 static int walk_depth;
51
52 /* If doing deep ILI verification, prepare for remembering which ILI have
53 already been walked. Must be paired with end_walk(level).
54 No-op if level does not require any remembering. */
55 static void
begin_walk(VERIFY_LEVEL level)56 begin_walk(VERIFY_LEVEL level)
57 {
58 if (level >= VERIFY_ILI_DEEP) {
59 if (++walk_depth == 1) {
60 ++current_epoch;
61 if (current_epoch == 0) {
62 int i;
63 /* epoch wrapped - wipe the slate clean */
64 for (i = 0; i < visited_size; ++i)
65 visited_ili[i].epoch = 0;
66 current_epoch = 1;
67 }
68 }
69 }
70 }
71
72 /* If at outermost walk, forget which ILI have already been walked.
73 The level *must* match the level in the corresponding call to begin_walk().
74 */
75 static void
end_walk(VERIFY_LEVEL level)76 end_walk(VERIFY_LEVEL level)
77 {
78 if (level >= VERIFY_ILI_DEEP) {
79 VERIFY(walk_depth >= 1, "walk not started?");
80 --walk_depth;
81 }
82 }
83
84 static void
ili_mark_first_visit(int ilix)85 ili_mark_first_visit(int ilix)
86 {
87 size_t old_size;
88 visit_info *v;
89 DEBUG_ASSERT(walk_depth > 0, "internal error in verifier: not in a walk");
90 DEBUG_ASSERT(0 < ilix, "internal error in verifier itself");
91 old_size = visited_size;
92 if (ilix >= old_size) {
93 int i;
94 int new_size = 1;
95 while (ilix >= new_size)
96 new_size *= 2;
97 NEED(ilix + 1, visited_ili, visit_info, visited_size, new_size);
98 for (i = old_size; i < visited_size; ++i)
99 visited_ili[i].epoch = 0;
100 }
101 DEBUG_ASSERT(ilix < visited_size, "internal error in verifier itself");
102 v = &visited_ili[ilix];
103 VERIFY(v->epoch != current_epoch, "ILI already visited!");
104 v->epoch = current_epoch;
105 }
106
107 /** NULL if ilix has not been visited yet. */
108 static visit_info *
ili_visit_info(int ilix)109 ili_visit_info(int ilix)
110 {
111 DEBUG_ASSERT(walk_depth > 0, "internal error in verifier: not in a walk");
112 if (0 < ilix && ilix < visited_size &&
113 visited_ili[ilix].epoch == current_epoch)
114 return &visited_ili[ilix];
115 else
116 return NULL;
117 }
118
119 /** Return true if jth operand of opc is allowed to have operation j_opc
120 contrary to expectations of IL_OPRFLAG(opc, j). This routine
121 is called infrequently so consider readability over speed when
122 adding another case. */
123 static bool
is_known_bug(ILI_OP opc,int j,ILI_OP j_opc)124 is_known_bug(ILI_OP opc, int j, ILI_OP j_opc)
125 {
126 /* r is the kind of operand supplied. */
127 ILIA_RESULT r = IL_RES(j_opc);
128 /* o is the kind of operand expected. */
129 ILIO_KIND o = IL_OPRFLAG(opc, j);
130 if (opc == IL_KNEG && o == ILIO_KRLNK && r == ILIA_AR)
131 return true;
132 if (opc == IL_KADD && o == ILIO_KRLNK && r == ILIA_IR)
133 return true;
134 #ifdef TARGET_X86
135 if ((opc == IL_DASPSP || opc == IL_MVSPSP) && o == ILIO_DPLNK && r == ILIA_CS)
136 return true;
137 #endif
138 if (opc == IL_STKR && o == ILIO_KRLNK && (r == ILIA_IR || r == ILIA_AR) &&
139 j == 1)
140 return true;
141 if ((opc == IL_FREEIR || opc == IL_CSEIR) && o == ILIO_IRLNK && r == ILIA_KR)
142 return true;
143 if (opc == IL_UKADD && o == ILIO_KRLNK && r == ILIA_IR)
144 return true;
145 if (opc == IL_ST && o == ILIO_IRLNK && r == ILIA_KR && j == 1)
146 return true;
147 if (opc == IL_IMUL && o == ILIO_IRLNK && r == ILIA_KR && j == 2)
148 return true;
149 if (opc == IL_IDIV && o == ILIO_IRLNK && r == ILIA_KR && j == 2)
150 return true;
151 if ((opc == IL_UKCMP || opc == IL_UKCJMP) && o == ILIO_KRLNK && r == ILIA_AR)
152 return true;
153 if (opc == IL_STKR && o == ILIO_KRLNK && r == ILIA_IR && j == 1)
154 return true;
155 if (opc == IL_AADD && o == ILIO_ARLNK && r == ILIA_IR && j == 1)
156 return true;
157 if (opc == IL_ST && o == ILIO_IRLNK && r == ILIA_AR && j == 1)
158 return true;
159 if (opc == IL_UKNEG && o == ILIO_KRLNK && r == ILIA_IR && j == 1)
160 return true;
161 if ((opc == IL_KMUL || opc == IL_IADD || opc == IL_IKMV) && j_opc == IL_ACCLDSYM)
162 return true;
163 if ((opc == IL_ACMPZ || opc == IL_ACJMPZ || opc == IL_LDA) && o == ILIO_ARLNK && r == ILIA_KR && j == 1)
164 return true;
165 if (opc == IL_IMUL && o == ILIO_IRLNK && r == ILIA_KR && j == 1)
166 return true;
167 if (opc == IL_DAIR && o == ILIO_IRLNK && j_opc == IL_KCON)
168 return true;
169 if ((opc == IL_IADD || opc == IL_IAMV) && o == ILIO_IRLNK && j_opc==IL_DFRKR)
170 return true;
171 if (opc == IL_KXOR && o == ILIO_KRLNK && j_opc == IL_ICMPZ)
172 return true;
173 if ((opc == IL_KCMP || opc == IL_KCJMP) && o == ILIO_KRLNK && j_opc == IL_LDDP)
174 return true;
175 if (opc == IL_PI8MV_LOW && o == ILIO_KRLNK && r == ILIA_AR)
176 return true;
177 #ifdef IL_PI8BROADCAST
178 if (opc == IL_PI8BROADCAST && o == ILIO_KRLNK && r == ILIA_AR)
179 return true;
180 #endif
181 if (opc == IL_IMUL && o == ILIO_IRLNK && j_opc == IL_KCON)
182 return true;
183 if (opc == IL_IKMV && o == ILIO_IRLNK && j_opc == IL_KCON)
184 return true;
185 if (opc == IL_IADD && o == ILIO_IRLNK && j_opc == IL_LDKR)
186 return true;
187 if (opc == IL_KIMV && o == ILIO_KRLNK && r == ILIA_IR)
188 return true;
189 return false;
190 }
191
192 /** Check that operation opc can have jth operand that has operation operand_opc. */
193 static void
verify_compatible(ILI_OP opc,int j,ILI_OP j_opc)194 verify_compatible(ILI_OP opc, int j, ILI_OP j_opc)
195 {
196 ILIA_RESULT r = IL_RES(j_opc);
197 ILIO_KIND o = IL_OPRFLAG(opc, j);
198 ILIA_RESULT expected = (ILIA_RESULT)(-1);
199 if (j_opc == IL_ACCLDSYM)
200 return; /* satisfies any kind of link. used in device code only */
201 switch (o) {
202 case ILIO_LNK:
203 /* Any kind of link allowed. */
204 return;
205 case ILIO_IRLNK:
206 expected = ILIA_IR;
207 break;
208 case ILIO_SPLNK:
209 expected = ILIA_SP;
210 break;
211 case ILIO_DPLNK:
212 expected = ILIA_DP;
213 break;
214 case ILIO_KRLNK:
215 expected = ILIA_KR;
216 break;
217 case ILIO_ARLNK:
218 expected = ILIA_AR;
219 break;
220 case ILIO_QPLNK:
221 expected = ILIA_QP;
222 break;
223 case ILIO_CSLNK:
224 expected = ILIA_CS;
225 break;
226 case ILIO_CDLNK:
227 expected = ILIA_CD;
228 break;
229 case ILIO_CQLNK:
230 expected = ILIA_CQ;
231 break;
232 case ILIO_128LNK:
233 expected = ILIA_128;
234 break;
235 case ILIO_256LNK:
236 expected = ILIA_256;
237 break;
238 case ILIO_512LNK:
239 expected = ILIA_512;
240 break;
241 case ILIO_FLOAT128LNK:
242 expected = ILIA_FLOAT128;
243 break;
244 case ILIO_X87LNK:
245 expected = ILIA_X87;
246 break;
247 case ILIO_DOUBLEDOUBLELNK:
248 expected = ILIA_DOUBLEDOUBLE;
249 break;
250 default:
251 VERIFY(false, "unexpected ILIO_KIND");
252 break;
253 }
254 VERIFY(r == expected || is_known_bug(opc, j, j_opc),
255 "IL_RES of ILI is incompatible with context");
256 }
257
258 /** \brief Ad-hoc operand checks.
259
260 This routine does ad-hoc checking of the operands that needs
261 to be specific to an operation. This routine is called from
262 verify_ili_aux after generic checks have been done. */
263 static void
verify_ili_ad_hoc(int ilix)264 verify_ili_ad_hoc(int ilix)
265 {
266 ILI_OP opc = ILI_OPC(ilix);
267 switch (opc) {
268 default:
269 break;
270 case IL_STSP:
271 VERIFY(ILI_OPND(ilix, 4) == MSZ_F4, "4th operand to STSP must be MSZ_F4");
272 break;
273 case IL_STDP:
274 VERIFY(ILI_OPND(ilix, 4) == MSZ_F8, "4th operand to STDP must be MSZ_F8");
275 break;
276 #ifdef IL_STSPSP
277 case IL_STSPSP: {
278 ILI_OP opc1 = ILI_OPC(ILI_OPND(ilix, 1));
279 VERIFY(opc1 == IL_DFRDP || opc1 == IL_DPDF, "1st operand to STSPSP must be DFRDP or DPDF");
280 VERIFY(ILI_OPND(ilix, 4) == MSZ_F8, "4th operand to STSPSP must be MSZ_F8");
281 break;
282 }
283 #endif
284 #ifdef LONG_DOUBLE_FLOAT128
285 case IL_FLOAT128ST:
286 VERIFY(ILI_OPND(ilix, 4) == MSZ_F16, "4th operand to FLOAT128ST must be MSZ_16");
287 break;
288 case IL_FLOAT128LD:
289 VERIFY(ILI_OPND(ilix, 3) == MSZ_F16, "3rd operand to FLOAT128LD must be MSZ_F16");
290 break;
291 #endif /* LONG_DOUBLE_FLAOT128 */
292 }
293 }
294
295 /** Recursive helper routine for verifying ILI. Because it is recursive,
296 please try to keep it relatively uncluttered so that the control flow
297 remains clear. */
298 static void
verify_ili_aux(int ilix,ILIO_KIND context,VERIFY_LEVEL level)299 verify_ili_aux(int ilix, ILIO_KIND context, VERIFY_LEVEL level)
300 {
301 ILI_OP opc;
302 int noprs, j;
303
304 VERIFY(1 <= ilix, "unexpected zero or negative ili index");
305 VERIFY(ilix < ilib.stg_avail, "out of bounds ili index");
306 if (level < VERIFY_ILI_SHALLOW)
307 return;
308
309 if (level >= VERIFY_ILI_DEEP && ili_visit_info(ilix))
310 /* Already checked this node. */
311 return;
312
313 /* General operand checks */
314 opc = ILI_OPC(ilix);
315 noprs = ilis[opc].oprs;
316 for (j = 1; j <= noprs; ++j) {
317 if (ILIO_ISLINK(IL_OPRFLAG(opc, j))) {
318 int operand = ILI_OPND(ilix, j);
319 verify_compatible(opc, j, ILI_OPC(operand));
320 if (level >= VERIFY_ILI_DEEP)
321 verify_ili_aux(operand, IL_OPRFLAG(opc, j), level);
322 }
323 }
324
325 verify_ili_ad_hoc(ilix);
326
327 if (level >= VERIFY_ILI_DEEP)
328 ili_mark_first_visit(ilix);
329 }
330
331 void
verify_ili(int ilix,VERIFY_LEVEL level)332 verify_ili(int ilix, VERIFY_LEVEL level)
333 {
334 begin_walk(level);
335 verify_ili_aux(ilix, ILIO_LNK, level);
336 end_walk(level);
337 }
338
339 /** Check if iltx is store of first result of a pair of results returned by a
340 JSR. This is a helper for verify_ilt, and assumes that iltx is index of
341 ILT of type ILTY_STORE and ili_throw_label(iltx)!=0. */
342 static bool
is_first_store_of_pair(int iltx1)343 is_first_store_of_pair(int iltx1)
344 {
345 int iltx2 = ILT_NEXT(iltx1);
346 if (iltx2) {
347 int ilix1 = ILT_ILIP(iltx1);
348 int ilix2 = ILT_ILIP(iltx2);
349 if (IL_TYPE(ILI_OPC(ilix2)) == ILTY_STORE) {
350 if (ili_throw_label(ilix2)) {
351 /* At this point, we know that ilix and ilix2 are both stores of results
352 from JSR/JSRA operations that can throw. Extract the JSR/JSRA
353 "pointers" and check that they are equal. */
354 int throw_jsr1 = ILI_OPND(ILI_OPND(ilix1, 1), 1);
355 int throw_jsr2 = ILI_OPND(ILI_OPND(ilix2, 1), 1);
356 /* there are cases where the following is not necessarily true; change to
357 only check the equality of throw labels for now */
358 /* return throw_jsr1 == throw_jsr2; */
359 return ili_throw_label(ilix1) == ili_throw_label(ilix2);
360 }
361 }
362 }
363 return false;
364 }
365
366 void
verify_ilt(int iltx,VERIFY_LEVEL level)367 verify_ilt(int iltx, VERIFY_LEVEL level)
368 {
369 int ilix, throw_label;
370 VERIFY(0 < iltx && iltx < iltb.stg_size, "invalid ILT index");
371
372 if (level < VERIFY_ILT)
373 return;
374
375 begin_walk(level);
376
377 ilix = ILT_ILIP(iltx);
378 verify_ili_aux(ilix, ILIO_LNK, level);
379
380 /* Check that ILT_CAN_THROW is set correctly. */
381 switch (IL_TYPE(ILI_OPC(ilix))) {
382 case ILTY_STORE:
383 throw_label = ili_throw_label(ilix);
384 if (!throw_label) {
385 VERIFY(!ILT_CAN_THROW(iltx), "ILT_CAN_THROW should be false for "
386 "ILTY_STORE that does not store result of "
387 "JSR that can throw");
388 } /* is_first_store_of_pair() does not always reliably return the correct
389 answer. We need to sort that out before invoking the following
390 else if (is_first_store_of_pair(iltx)) {
391 VERIFY(!ILT_CAN_THROW(iltx), "ILT_CAN_THROW should be false for "
392 "ILTY_STORE that stores first of a pair of "
393 "results from a JSR that can throw");
394
395 } else {
396 VERIFY(ILT_CAN_THROW(iltx), "ILT_CAN_THROW should be true for ILTY_STORE "
397 "that stores sole or second result of a JSR "
398 "that can throw");
399 } */
400 break;
401 case ILTY_PROC:
402 throw_label = ili_throw_label(ilix);
403 if (throw_label)
404 VERIFY(ILT_CAN_THROW(iltx),
405 "ILT_CAN_THROW should be true for ILTY_PROC that can throw");
406 else
407 VERIFY(!ILT_CAN_THROW(iltx),
408 "ILT_CAN_THROW should be false for ILTY_PROC that cannot throw");
409 break;
410 default:
411 VERIFY(!ILT_CAN_THROW(iltx),
412 "ILT_CAN_THROW can be true only for store or call");
413 break;
414 }
415
416 /* With non-extended basic blocks, an ILT that can throw terminates the
417 block. */
418 if (flg.opt >= 2 && ILT_NEXT(iltx)) {
419 VERIFY(!ILT_CAN_THROW(iltx), "ILT_CAN_THROW should be false at -O2 "
420 "if ILT is not last in block");
421 }
422
423 end_walk(level);
424 }
425
426 void
verify_block(int bihx,VERIFY_LEVEL level)427 verify_block(int bihx, VERIFY_LEVEL level)
428 {
429 int iltx;
430
431 VERIFY(0 < bihx && bihx < bihb.stg_size, "invalid BIH index");
432 begin_walk(level);
433 for (iltx = BIH_ILTFIRST(bihx); iltx; iltx = ILT_NEXT(iltx)) {
434 verify_ilt(iltx, level);
435 }
436 end_walk(level);
437 }
438
439 void
verify_function_ili(VERIFY_LEVEL level)440 verify_function_ili(VERIFY_LEVEL level)
441 {
442 int bih;
443 begin_walk(level);
444 for (bih = gbl.entbih; bih; bih = BIH_NEXT(bih))
445 verify_block(bih, level);
446 end_walk(level);
447 }
448
449 #endif /* DEBUG */
450