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