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