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