6ee42f87332d6aeda1a415346b8f777dc670639c
[libfirm] / ir / ir / irvrfy.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/irvrfy.c
4  * Purpose:     Check irnodes for correctness.
5  * Author:      Christian Schaefer
6  * Modified by: Goetz Lindenmaier. Till Riedel
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 #ifdef HAVE_CONFIG_H
14 # include <config.h>
15 #endif
16
17 # include "irgraph_t.h"
18 # include "irvrfy.h"
19 # include "irgwalk.h"
20
21 #ifdef NDEBUG
22 /*
23  * in RELEASE mode, returns ret if the expression expr evaluates to zero
24  * in ASSERT mode, asserts the expression expr (and the string string).
25  */
26 #define ASSERT_AND_RET(expr, string, ret)               if (!(expr)) return (ret)
27
28 /*
29  * in RELEASE mode, returns ret if the expression expr evaluates to zero
30  * in ASSERT mode, executes blk if the expression expr evaluates to zero and asserts
31  */
32 #define ASSERT_AND_RET_DBG(expr, string, ret, blk)      if (!(expr)) return (ret)
33 #else
34 #define ASSERT_AND_RET(expr, string, ret)               do { assert((expr) && string); if (!(expr)) return (ret); } while(0)
35 #define ASSERT_AND_RET_DBG(expr, string, ret, blk)      do { if (!(expr)) { { blk } assert(0 && string); return (ret); } } while(0)
36 #endif
37
38 /* @@@ replace use of array "in" by access functions. */
39 ir_node **get_irn_in(ir_node *node);
40
41 bool opt_do_node_verification = 1;
42 void do_node_verification(bool b) {
43   opt_do_node_verification = b;
44 }
45
46
47 INLINE static int
48 vrfy_Proj_proj(ir_node *p, ir_graph *irg) {
49   ir_node *pred;
50   ir_mode *mode;
51   int proj;
52
53   pred = skip_nop(get_Proj_pred(p));
54   assert(get_irn_mode(pred) == mode_T);
55   mode = get_irn_mode(p);
56   proj = get_Proj_proj(p);
57
58   switch (get_irn_opcode(pred)) {
59     case iro_Start:
60       ASSERT_AND_RET(
61           (
62            (proj == pns_initial_exec   && mode == mode_X) ||
63            (proj == pns_global_store   && mode == mode_M) ||
64            (proj == pns_frame_base     && mode_is_reference(mode)) ||
65            (proj == pns_globals        && mode_is_reference(mode)) ||
66            (proj == pns_args           && mode == mode_T) ||
67            (proj == pns_value_arg_base && mode_is_reference(mode))
68           ),
69           "wrong Proj from Start", 0);
70       break;
71
72     case iro_Cond:
73       ASSERT_AND_RET( (proj >= 0 && mode == mode_X), "wrong Proj from Cond", 0);
74       break;
75
76     case iro_Raise:
77       ASSERT_AND_RET(
78           ((proj == 0 && mode == mode_X) ||
79            (proj == 1 && mode == mode_M)),
80           "wrong Proj from Raise", 0);
81       break;
82
83     case iro_InstOf:
84       ASSERT_AND_RET( (proj >= 0 && mode == mode_X), "wrong Proj from InstOf", 0);
85       break;
86
87     case iro_Call:
88       ASSERT_AND_RET(
89           ((proj == 0 && mode == mode_M) ||
90            (proj == 1 && mode == mode_X) ||
91            (proj == 2 && mode == mode_T) ||
92            (proj == 3 && mode == mode_M)),
93           "wrong Proj from Call", 0);
94       break;
95
96     case iro_Quot:
97       ASSERT_AND_RET(
98           ((proj == 0 && mode == mode_M) ||
99            (proj == 1 && mode == mode_X) ||
100            (proj == 2 && mode_is_float(mode))),
101           "wrong Proj from Quot", 0);
102       break;
103
104     case iro_DivMod:
105       ASSERT_AND_RET(
106           ((proj == 0 && mode == mode_M) ||
107            (proj == 1 && mode == mode_X) ||
108            (proj == 2 && mode == mode_Is) ||
109            (proj == 3 && mode_is_int(mode))),
110           "wrong Proj from DivMod", 0);
111       break;
112
113     case iro_Div:
114     case iro_Mod:
115       ASSERT_AND_RET(
116           ((proj == 0 && mode == mode_M) ||
117            (proj == 1 && mode == mode_X) ||
118            (proj == 2 && mode_is_int(mode))),
119           "wrong Proj from Div or Mod", 0);
120       break;
121
122     case iro_Cmp:
123       ASSERT_AND_RET(
124           (proj >= 0 && proj <= 15 && mode == mode_b),
125           "wrong Proj from Cmp", 0);
126       break;
127
128     case iro_Load:
129       if (proj == pn_Load_res) {
130         ir_node *ptr = get_Load_ptr(pred);
131         entity *ent = NULL;
132         if (get_irn_op(ptr) == op_Sel) {
133           ent = get_Sel_entity(ptr);
134         } /*
135         We may not test this, after lowering and optimization the Const can
136         have an unexpected type.
137     else if ((get_irn_op(ptr) == op_Const) &&
138                    tarval_is_entity(get_Const_tarval(ptr))) {
139           ent = get_tarval_entity(get_Const_tarval(ptr));
140         } */
141         if (ent)
142           ASSERT_AND_RET((mode == get_type_mode(get_entity_type(ent))),
143                          "wrong data Proj from Load", 0);
144         else
145           ASSERT_AND_RET(mode_is_data(mode),
146                          "wrong data Proj from Load", 0);
147       } else {
148         ASSERT_AND_RET(((proj == pn_Load_M        && mode == mode_M) ||
149                         (proj == pn_Load_X_except && mode == mode_X)),
150                        "wrong Proj from Load", 0);
151       }
152       break;
153
154     case iro_Store:
155       ASSERT_AND_RET(
156           ((proj == 0 && mode == mode_M) ||
157            (proj == 1 && mode == mode_X)),
158           "wrong Proj from Store", 0);
159       break;
160
161     case iro_Alloc:
162       ASSERT_AND_RET(
163           (
164            (proj == 0 && mode == mode_M) ||
165            (proj == 1 /* && mode == mode_X*/) ||
166            (proj == 2 && mode_is_reference(mode))
167           ),
168           "wrong Proj from Alloc", 0);
169       break;
170
171     case iro_Proj:
172       {
173         type *mt; /* A method type */
174         pred = skip_nop(get_Proj_pred(pred));
175         ASSERT_AND_RET((get_irn_mode(pred) == mode_T), "Proj from something not a tuple", 0);
176         switch (get_irn_opcode(pred))
177         {
178           case iro_Start:
179             {
180               ASSERT_AND_RET(
181                   (proj >= 0 && mode_is_data(mode)),
182                   "wrong Proj from Proj from Start", 0);
183               mt = get_entity_type(get_irg_ent(irg));
184               ASSERT_AND_RET(
185                   (proj < get_method_n_params(mt)),
186                   "More Projs for args than args in type", 0);
187               if ((mode_is_reference(mode)) && is_compound_type(get_method_param_type(mt, proj)))
188                 /* value argument */ break;
189
190               ASSERT_AND_RET(
191                   (mode == get_type_mode(get_method_param_type(mt, proj))),
192                   "Mode of Proj from Start doesn't match mode of param type.", 0);
193             }
194             break;
195
196           case iro_Call:
197             {
198               ASSERT_AND_RET(
199                   (proj >= 0 && mode_is_data(mode)),
200                   "wrong Proj from Proj from Call", 0);
201               mt = get_Call_type(pred);
202               ASSERT_AND_RET(
203                   (proj < get_method_n_ress(mt)),
204                   "More Projs for results than results in type.", 0);
205               if ((mode_is_reference(mode)) && is_compound_type(get_method_res_type(mt, proj)))
206                 /* value result */ break;
207
208               ASSERT_AND_RET(
209                   (mode == get_type_mode(get_method_res_type(mt, proj))),
210                   "Mode of Proj from Call doesn't match mode of result type.", 0);
211             }
212             break;
213
214           case iro_Tuple:
215             /* We don't test */
216             break;
217
218           default:
219             ASSERT_AND_RET(0, "Unknown opcode", 0);
220         }
221         break;
222
223       }
224     case iro_Tuple:
225       /* We don't test */
226       break;
227
228     case iro_CallBegin:
229       break;
230
231     case iro_EndReg:
232       break;
233
234     case iro_EndExcept:
235       break;
236
237     default:
238       ASSERT_AND_RET(0, "Unknown opcode", 0);
239   }
240
241   /* all went ok */
242   return 1;
243 }
244
245 int irn_vrfy_irg(ir_node *n, ir_graph *irg)
246 {
247   int i;
248   int opcode, opcode1;
249   ir_mode *mymode, *op1mode = NULL, *op2mode, *op3mode;
250   int op_is_symmetric = 1;  /*  0: asymmetric
251                                 1: operands have identical modes
252                                 2: modes of operands == mode of this node */
253   type *mt; /* A method type */
254
255   ir_node **in;
256
257   if (!opt_do_node_verification) return 1;
258
259   if (! interprocedural_view) {
260     /*
261      * do NOT check placement in interprocedural view, as we don't always know
262      * the "right" graph ...
263      */
264     ASSERT_AND_RET(node_is_in_irgs_storage(irg, n), "Node is not stored on proper IR graph!", 0);
265   }
266
267   opcode = get_irn_opcode (n);
268
269   /* We don't want to test nodes whose predecessors are Bad or Unknown,
270      as we would have to special case that for each operation. */
271   if (opcode != iro_Phi && opcode != iro_Block)
272     for (i = 0; i < get_irn_arity(n); i++) {
273       opcode1 = get_irn_opcode(get_irn_n(n, i));
274       if (opcode1 == iro_Bad || opcode1 == iro_Unknown)
275         return 1;
276     }
277
278   mymode = get_irn_mode (n);
279   in = get_irn_in (n);
280
281   switch (opcode)
282   {
283
284     case iro_Block:
285       for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
286         ir_node *pred =  get_Block_cfgpred(n, i);
287         ASSERT_AND_RET((is_Bad(pred)                     ||
288                         (get_irn_op(pred) == op_Unknown) ||
289                         (get_irn_mode(pred) == mode_X)     ),
290                        "Block node", 0);
291       }
292       // End block may only have Return, Raise or fragile ops as preds.
293       if (n == get_irg_end_block(irg))
294         for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
295           ir_node *pred =  skip_Proj(get_Block_cfgpred(n, i));
296           if (is_Proj(pred) || get_irn_op(pred) == op_Tuple)
297             break;   // We can not test properly.  How many tuples are there?
298           ASSERT_AND_RET(((get_irn_op(pred) == op_Return) ||
299                           is_Bad(pred)                    ||
300                           (get_irn_op(pred) == op_Raise)  ||
301                           is_fragile_op(pred)               ),
302                          "End Block node", 0);
303         }
304       // irg attr must == graph we are in.
305       if (! interprocedural_view) {
306         ASSERT_AND_RET(((get_irn_irg(n) && get_irn_irg(n) == irg)), "", 0);
307       }
308
309       break;
310
311     case iro_Start:
312       ASSERT_AND_RET(
313           /* Start: BB --> X x M x ref x data1 x ... x datan x ref */
314           mymode == mode_T, "Start node", 0
315           );
316       break;
317
318     case iro_Jmp:
319       ASSERT_AND_RET(
320           /* Jmp: BB --> X */
321           mymode == mode_X, "Jmp node", 0
322           );
323       break;
324
325     case iro_Break:
326       ASSERT_AND_RET(
327           /* Jmp: BB --> X */
328           mymode == mode_X, "Jmp node", 0
329           );
330       break;
331
332     case iro_Cond:
333       op1mode = get_irn_mode(in[1]);
334       ASSERT_AND_RET(
335           /* Cond: BB x b --> X x X */
336           (op1mode == mode_b ||
337            /* Cond: BB x int --> X^n */
338            mode_is_int(op1mode) ),  "Cond node", 0
339           );
340       ASSERT_AND_RET(mymode == mode_T, "Cond mode is not a tuple", 0);
341       break;
342
343     case iro_Return:
344       op1mode = get_irn_mode(in[1]);
345       /* Return: BB x M x data1 x ... x datan --> X */
346       /* printf("mode: %s, code %s\n", ID_TO_STR(n->mode->name), ID_TO_STR(n->op->name));*/
347       ASSERT_AND_RET( op1mode == mode_M, "Return node", 0 );  /* operand M */
348       for (i=2; i < get_irn_arity(n); i++) {
349         ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Return node", 0 );  /* operand datai */
350       };
351       ASSERT_AND_RET( mymode == mode_X, "Result X", 0 );   /* result X */
352       /* Compare returned results with result types of method type */
353       mt = get_entity_type(get_irg_ent(irg));
354       ASSERT_AND_RET( get_Return_n_ress(n) == get_method_n_ress(mt),
355           "Number of results for Return doesn't match number of results in type.", 0 );
356       for (i = 0; i < get_Return_n_ress(n); i++)
357         ASSERT_AND_RET(
358             get_irn_mode(get_Return_res(n, i)) == get_type_mode(get_method_res_type(mt, i)),
359             "Mode of result for Return doesn't match mode of result type.", 0);
360       break;
361
362     case iro_Raise:
363       op1mode = get_irn_mode(in[1]);
364       op2mode = get_irn_mode(in[2]);
365       ASSERT_AND_RET(
366           /* Sel: BB x M x ref --> X x M */
367           op1mode == mode_M && mode_is_reference(op2mode) &&
368           mymode == mode_T, "Raise node", 0
369           );
370       break;
371
372     case iro_Const:
373       ASSERT_AND_RET(
374           /* Const: BB --> data */
375           (mode_is_data (mymode) ||
376            mymode == mode_b)      /* we want boolean constants for static evaluation */
377           ,"Const node", 0        /* of Cmp. */
378           );
379       break;
380
381     case iro_SymConst:
382       ASSERT_AND_RET(
383           /* SymConst: BB --> int*/
384           (mode_is_int(mymode) ||
385            /* SymConst: BB --> ref */
386            mode_is_reference(mymode))
387           ,"SymConst node", 0);
388       break;
389
390     case iro_Sel:
391       op1mode = get_irn_mode(in[1]);
392       op2mode = get_irn_mode(in[2]);
393       ASSERT_AND_RET(
394           /* Sel: BB x M x ref x int^n --> ref */
395           (op1mode == mode_M && op2mode == mymode && mode_is_reference(mymode)),
396           "Sel node", 0
397           );
398       for (i=3; i < get_irn_arity(n); i++)
399       {
400         ASSERT_AND_RET(mode_is_int(get_irn_mode(in[i])), "Sel node", 0);
401       }
402       break;
403
404     case iro_InstOf:
405       ASSERT_AND_RET(mode_T == mymode, "mode of Instof is not a tuple", 0);
406       ASSERT_AND_RET(mode_is_data(op1mode), "Instof not on data", 0);
407       break;
408
409     case iro_Call:
410       op1mode = get_irn_mode(in[1]);
411       op2mode = get_irn_mode(in[2]);
412       /* Call: BB x M x ref x data1 x ... x datan
413          --> M x datan+1 x ... x data n+m */
414       ASSERT_AND_RET( op1mode == mode_M && mode_is_reference(op2mode), "Call node", 0 );  /* operand M x ref */
415       for (i=3; i < get_irn_arity(n); i++) {
416         ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Call node", 0 );  /* operand datai */
417       };
418       ASSERT_AND_RET( mymode == mode_T, "Call result not a tuple", 0 );   /* result T */
419       /* Compare arguments of node with those of type */
420       mt = get_Call_type(n);
421
422       if (get_method_variadicity(mt) == variadicity_variadic) {
423         ASSERT_AND_RET(
424             get_Call_n_params(n) >= get_method_n_params(mt),
425             "Number of args for Call doesn't match number of args in variadic type.",
426             0);
427       }
428       else {
429         ASSERT_AND_RET(
430             get_Call_n_params(n) == get_method_n_params(mt),
431             "Number of args for Call doesn't match number of args in non variadic type.",
432             0);
433       }
434
435       for (i = 0; i < get_method_n_params(mt); i++) {
436         ASSERT_AND_RET_DBG(
437             get_irn_mode(get_Call_param(n, i)) == get_type_mode(get_method_param_type(mt, i)),
438             "Mode of arg for Call doesn't match mode of arg type.", 0,
439             {
440               int i;
441
442               fprintf(stderr, "Assertion for Call type-check failed: %s(", get_type_name(mt));
443               for (i = 0; i < get_method_n_params(mt); ++i) {
444                 fprintf(stderr, "%s ", get_mode_name(get_type_mode(get_method_param_type(mt, i))));
445               }
446               fprintf(stderr, ") != CALL(");
447
448               for (i = 0; i < get_Call_n_params(n); ++i) {
449                 fprintf(stderr, "%s ", get_mode_name(get_irn_mode(get_Call_param(n, i))));
450               }
451               fprintf(stderr, ")\n");
452
453             }
454             );
455       }
456       break;
457
458     case iro_Add:
459       op1mode = get_irn_mode(in[1]);
460       op2mode = get_irn_mode(in[2]);
461       ASSERT_AND_RET(
462           (
463            /* common Add: BB x numP x numP --> numP */
464            (op1mode == mymode && op2mode == op1mode && mode_is_numP(mymode)) ||
465            /* Pointer Add: BB x ref x int --> ref */
466            (mode_is_reference(op1mode) && mode_is_int(op2mode) && op1mode == mymode) ||
467            /* Pointer Add: BB x int x ref --> ref */
468            (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode))
469           ),
470           "Add node", 0
471           );
472       if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
473         /* BB x ref x int --> ref or BB x int x ref --> ref */
474         op_is_symmetric = 0;
475       } else {
476         /* BB x num x num --> num or BB x ref x ref */
477         op_is_symmetric = 2;
478       }
479       break;
480
481     case iro_Sub:
482       op1mode = get_irn_mode(in[1]);
483       op2mode = get_irn_mode(in[2]);
484       ASSERT_AND_RET(
485           /* common Sub: BB x numP x numP --> numP */
486           ((mymode ==op1mode && mymode == op2mode && mode_is_numP(op1mode)) ||
487            /* Pointer Sub: BB x ref x int --> ref */
488            (op1mode == mymode && mode_is_int(op2mode) && mode_is_reference(mymode)) ||
489            /* Pointer Sub: BB x int x ref --> ref */
490            (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode)) ||
491            /* Pointer Sub: BB x ref x ref --> int */
492            (op1mode == op2mode && mode_is_reference(op2mode) && mode_is_int(mymode))),
493           "Sub node", 0
494           );
495       if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
496         op_is_symmetric = 0;
497       } else {
498         op_is_symmetric = 2;
499       }
500       break;
501
502     case iro_Minus:
503       op1mode = get_irn_mode(in[1]);
504       ASSERT_AND_RET(
505           /* Minus: BB x float --> float */
506           op1mode == mymode && get_mode_sort(op1mode) == irms_float_number, "Minus node", 0
507           );
508       op_is_symmetric = 2;
509       break;
510
511     case iro_Mul:
512       op1mode = get_irn_mode(in[1]);
513       op2mode = get_irn_mode(in[2]);
514       ASSERT_AND_RET(
515           /* Mul: BB x int1 x int1 --> int2 */
516           ((mode_is_int(op1mode)   && op2mode == op1mode && mode_is_int(mymode)) ||
517            (mode_is_float(op1mode) && op2mode == op1mode && mymode == op1mode)),
518           "Mul node",0
519           );
520       op_is_symmetric = 2;
521       break;
522
523     case iro_Quot:
524       op1mode = get_irn_mode(in[1]);
525       op2mode = get_irn_mode(in[2]);
526       op3mode = get_irn_mode(in[3]);
527       ASSERT_AND_RET(
528           /* Quot: BB x M x float x float --> M x X x float */
529           op1mode == mode_M && op2mode == op3mode &&
530           get_mode_sort(op2mode) == irms_float_number &&
531           mymode == mode_T,
532           "Quot node",0
533           );
534       op_is_symmetric = 2;
535       break;
536
537     case iro_DivMod:
538       op1mode = get_irn_mode(in[1]);
539       op2mode = get_irn_mode(in[2]);
540       op3mode = get_irn_mode(in[3]);
541       ASSERT_AND_RET(
542           /* DivMod: BB x M x int x int --> M x X x int x int */
543           op1mode == mode_M &&
544           mode_is_int(op2mode) &&
545           op3mode == op2mode &&
546           mymode == mode_T,
547           "DivMod node", 0
548           );
549       op_is_symmetric = 1;
550       break;
551
552     case iro_Div:
553     case iro_Mod:
554       op1mode = get_irn_mode(in[1]);
555       op2mode = get_irn_mode(in[2]);
556       op3mode = get_irn_mode(in[3]);
557       ASSERT_AND_RET(
558           /* Div or Mod: BB x M x int x int --> M x X x int */
559           op1mode == mode_M &&
560           op2mode == op3mode &&
561           mode_is_int(op2mode) &&
562           mymode == mode_T,
563           "Div or Mod node", 0
564           );
565       op_is_symmetric = 1;
566       break;
567
568     case iro_Abs:
569       op1mode = get_irn_mode(in[1]);
570       ASSERT_AND_RET(
571           /* Abs: BB x num --> num */
572           op1mode == mymode &&
573           mode_is_num (op1mode),
574           "Abs node",0
575           );
576       op_is_symmetric = 2;
577       break;
578
579     case iro_And:
580     case iro_Or:
581     case iro_Eor:
582       op1mode = get_irn_mode(in[1]);
583       op2mode = get_irn_mode(in[2]);
584       ASSERT_AND_RET(
585           /* And or Or or Eor: BB x int x int --> int */
586           mode_is_int(mymode) &&
587           op2mode == op1mode &&
588           mymode == op2mode,
589           "And, Or or Eor node", 0
590           );
591       op_is_symmetric = 2;
592       break;
593
594     case iro_Not:
595       op1mode = get_irn_mode(in[1]);
596       ASSERT_AND_RET(
597           /* Not: BB x int --> int */
598           mode_is_int(mymode) &&
599           mymode == op1mode,
600           "Not node", 0
601           );
602       op_is_symmetric = 2;
603       break;
604
605
606     case iro_Cmp:
607       op1mode = get_irn_mode(in[1]);
608       op2mode = get_irn_mode(in[2]);
609       ASSERT_AND_RET(
610           /* Cmp: BB x datab x datab --> b16 */
611           mode_is_data (op1mode) &&
612           op2mode == op1mode &&
613           mymode == mode_T,
614           "Cmp node", 0
615           );
616       break;
617
618     case iro_Shl:
619     case iro_Shr:
620     case iro_Shrs:
621       op1mode = get_irn_mode(in[1]);
622       op2mode = get_irn_mode(in[2]);
623       assert(
624           /* Shl, Shr or Shrs: BB x int x int_u --> int */
625           mode_is_int(op1mode) &&
626           mode_is_int(op2mode) &&
627           !mode_is_signed(op2mode) &&
628           mymode == op1mode &&
629           "Shl, Shr, Shr or Rot node"
630           );
631       break;
632
633     case iro_Rot:
634       op1mode = get_irn_mode(in[1]);
635       op2mode = get_irn_mode(in[2]);
636       ASSERT_AND_RET(
637           /* Rot: BB x int x int --> int */
638           mode_is_int(op1mode) &&
639           mode_is_int(op2mode) &&
640           mymode == op1mode,
641           "Rot node",0
642           );
643       break;
644
645     case iro_Conv:
646       op1mode = get_irn_mode(in[1]);
647       ASSERT_AND_RET(
648           /* Conv: BB x datab1 --> datab2 */
649           mode_is_datab(op1mode) && mode_is_data(mymode),
650           "Conv node", 0
651           );
652       break;
653
654     case iro_Cast:
655       op1mode = get_irn_mode(in[1]);
656       ASSERT_AND_RET(
657           /* Conv: BB x datab1 --> datab2 */
658           mode_is_data(op1mode) && op1mode == mymode,
659           "Cast node", 0
660           );
661       break;
662
663     case iro_Phi:
664       /* Phi: BB x dataM^n --> dataM */
665       /* for some reason "<=" aborts. int there a problem with get_store? */
666       for (i=1; i < get_irn_arity(n); i++) {
667         if (!is_Bad(in[i]) && (get_irn_op(in[i]) != op_Unknown))
668           ASSERT_AND_RET( get_irn_mode(in[i]) == mymode, "Phi node", 0);
669       };
670       ASSERT_AND_RET( mode_is_dataM(mymode), "Phi node", 0 );
671       break;
672
673     case iro_Load:
674       op1mode = get_irn_mode(in[1]);
675       op2mode = get_irn_mode(in[2]);
676       ASSERT_AND_RET(
677           /* Load: BB x M x ref --> M x X x data */
678           op1mode == mode_M && mode_is_reference(op2mode),
679           "Load node", 0
680           );
681       ASSERT_AND_RET( mymode == mode_T, "Load node", 0 );
682       break;
683
684     case iro_Store:
685       op1mode = get_irn_mode(in[1]);
686       op2mode = get_irn_mode(in[2]);
687       op3mode = get_irn_mode(in[3]);
688       ASSERT_AND_RET(
689           /* Load: BB x M x ref data --> M x X */
690           op1mode == mode_M && mode_is_reference(op2mode) && mode_is_data(op3mode),
691           "Store node", 0
692           );
693       ASSERT_AND_RET(mymode == mode_T, "Store node", 0);
694       break;
695
696     case iro_Alloc:
697       op1mode = get_irn_mode(in[1]);
698       op2mode = get_irn_mode(in[2]);
699       ASSERT_AND_RET(
700           /* Alloc: BB x M x int_u --> M x X x ref */
701           op1mode == mode_M &&
702           mode_is_int(op2mode) &&
703           !mode_is_signed(op2mode) &&
704           mymode == mode_T,
705           "Alloc node", 0
706           );
707       break;
708
709     case iro_Free:
710       op1mode = get_irn_mode(in[1]);
711       op2mode = get_irn_mode(in[2]);
712       ASSERT_AND_RET(
713           /* Free: BB x M x ref --> M */
714           op1mode == mode_M && mode_is_reference(op2mode) &&
715           mymode == mode_M,
716           "Free node", 0
717           );
718       break;
719
720     case iro_Sync:
721       /* Sync: BB x M^n --> M */
722       for (i=1; i < get_irn_arity(n); i++) {
723         ASSERT_AND_RET( get_irn_mode(in[i]) == mode_M, "Sync node", 0 );
724       };
725       ASSERT_AND_RET( mymode == mode_M, "Sync node", 0 );
726       break;
727
728     case iro_Proj:
729       return vrfy_Proj_proj(n, irg);
730       break;
731
732     case iro_Confirm:
733       op1mode = get_irn_mode(in[1]);
734       op2mode = get_irn_mode(in[2]);
735       ASSERT_AND_RET(
736           /* Confirm: BB x T x T --> T */
737           op1mode == mymode &&
738           op2mode == mymode,
739           "Confirm node", 0
740           );
741
742       break;
743
744     default:
745       break;
746   }
747
748   /* All went ok */
749   return 1;
750 }
751
752 int irn_vrfy(ir_node *n)
753 {
754   return irn_vrfy_irg(n, current_ir_graph);
755 }
756
757 /*******************************************************************/
758 /* Verify the whole graph.                                         */
759 /*******************************************************************/
760
761 static void vrfy_wrap(ir_node *node, void *env)
762 {
763   int *res = env;
764
765   *res = irn_vrfy(node);
766 }
767
768 int irg_vrfy(ir_graph *irg)
769 {
770   int res = 1;
771   ir_graph *rem;
772
773   rem = current_ir_graph;
774   current_ir_graph = irg;
775
776   assert(get_irg_pinned(irg) == pinned);
777
778   irg_walk(irg->end, vrfy_wrap, NULL, &res);
779
780   current_ir_graph = rem;
781
782   return res;
783 }