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