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