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