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