3a3458465332e5ca22f7aa729c2723765afd30e4
[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) \
35 do { \
36   bad_msg = #expr " && " string; \
37   if (opt_do_node_verification == NODE_VERIFICATION_ON) \
38     assert((expr) && string); \
39   if (!(expr)) { \
40     if (opt_do_node_verification == NODE_VERIFICATION_REPORT) \
41       fprintf(stderr, #expr " : " string "\n"); \
42     return (ret); \
43   } \
44 } while(0)
45
46 #define ASSERT_AND_RET_DBG(expr, string, ret, blk) \
47 do { \
48   if (!(expr)) { \
49     bad_msg = #expr " && " string; \
50     if (opt_do_node_verification != NODE_VERIFICATION_ERROR_ONLY) { blk; } \
51     if (opt_do_node_verification == NODE_VERIFICATION_REPORT) \
52       fprintf(stderr, #expr " : " string "\n"); \
53     else if (opt_do_node_verification == NODE_VERIFICATION_ON) \
54       assert((expr) && string); \
55     return (ret); \
56   } \
57 } while(0)
58
59 #endif
60
61 /* @@@ replace use of array "in" by access functions. */
62 ir_node **get_irn_in(ir_node *node);
63
64 static node_verification_t opt_do_node_verification = NODE_VERIFICATION_ON;
65 static const char *bad_msg;
66
67 void do_node_verification(node_verification_t mode)
68 {
69   opt_do_node_verification = mode;
70 }
71
72 /**
73  * Prints a failure for a Node
74  */
75 static void show_node_failure(ir_node *n)
76 {
77   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s\n" ,
78     get_irn_node_nr(n),
79     get_irn_opname(n), get_irn_modename(n)
80   );
81 }
82
83 /**
84  * Prints a failure message for a binop
85  */
86 static void show_binop_failure(ir_node *n, const char *text)
87 {
88   ir_node *left  = get_binop_left(n);
89   ir_node *right = get_binop_right(n);
90
91   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s(%s%s, %s%s) did not match (%s)\n",
92       get_irn_node_nr(n),
93       get_irn_opname(n), get_irn_modename(n),
94       get_irn_opname(left), get_irn_modename(left),
95       get_irn_opname(right), get_irn_modename(right),
96       text);
97 }
98
99 /**
100  * Prints a failure message for an unop
101  */
102 static void show_unop_failure(ir_node *n, const char *text)
103 {
104   ir_node *op  = get_unop_op(n);
105
106   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s(%s%s) did not match (%s)\n",
107       get_irn_node_nr(n),
108       get_irn_opname(n), get_irn_modename(n),
109       get_irn_opname(op), get_irn_modename(op),
110       text);
111 }
112
113 /**
114  * Prints a failure message for a proj
115  */
116 static void show_proj_failure(ir_node *n)
117 {
118   ir_node *op  = get_Proj_pred(n);
119   int proj     = get_Proj_proj(n);
120
121   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s %d(%s%s) failed\n" ,
122       get_irn_node_nr(n),
123       get_irn_opname(n), get_irn_modename(n), proj,
124       get_irn_opname(op), get_irn_modename(op));
125 }
126
127 /**
128  * Prints a failure message for a proj
129  */
130 static void show_proj_failure_ent(ir_node *n, entity *ent)
131 {
132   ir_node *op  = get_Proj_pred(n);
133   int proj     = get_Proj_proj(n);
134   ir_mode *m   = get_type_mode(get_entity_type(ent));
135
136   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s %d(%s%s) entity %s(type %s mode %s)failed\n" ,
137       get_irn_node_nr(n),
138       get_irn_opname(n), get_irn_modename(n), proj,
139       get_irn_opname(op), get_irn_modename(op),
140       get_entity_name(ent), get_type_name(get_entity_type(ent)),
141       m ? get_mode_name(m) : "<no mode>");
142 }
143
144 /**
145  * Show a node and a graph
146  */
147 static void show_node_on_graph(ir_graph *irg, ir_node *n)
148 {
149   entity *ent = get_irg_ent(irg);
150
151   if (ent)
152     fprintf(stderr, "\nFIRM: irn_vrfy_irg() of entity %s, node %ld %s%s\n",
153       get_entity_name(ent),
154       get_irn_node_nr(n), get_irn_opname(n), get_irn_modename(n));
155   else
156     fprintf(stderr, "\nFIRM: irn_vrfy_irg() of graph %p, node %ld %s%s\n",
157       (void *)irg,
158       get_irn_node_nr(n), get_irn_opname(n), get_irn_modename(n));
159 }
160
161 /**
162  * Show call params
163  */
164 static void show_call_param(ir_node *n, type *mt)
165 {
166   int i;
167
168   fprintf(stderr, "\nFIRM: irn_vrfy_irg() Call type-check failed: %s(", get_type_name(mt));
169   for (i = 0; i < get_method_n_params(mt); ++i) {
170     fprintf(stderr, "%s ", get_mode_name(get_type_mode(get_method_param_type(mt, i))));
171   }
172   fprintf(stderr, ") != CALL(");
173
174   for (i = 0; i < get_Call_n_params(n); ++i) {
175     fprintf(stderr, "%s ", get_mode_name(get_irn_mode(get_Call_param(n, i))));
176   }
177   fprintf(stderr, ")\n");
178
179 }
180
181 /**
182  * Show return modes
183  */
184 static void show_return_modes(ir_graph *irg, ir_node *n, type *mt, int i)
185 {
186   entity *ent = get_irg_ent(irg);
187
188   fprintf(stderr, "\nFIRM: irn_vrfy_irg() Return node %ld in entity \"%s\" mode %s different from type mode %s\n",
189     get_irn_node_nr(n), get_entity_name(ent),
190     get_mode_name(get_irn_mode(get_Return_res(n, i))),
191     get_mode_name(get_type_mode(get_method_res_type(mt, i)))
192   );
193 }
194
195 /**
196  * Show return number of results
197  */
198 static void show_return_nres(ir_graph *irg, ir_node *n, type *mt)
199 {
200   entity *ent = get_irg_ent(irg);
201
202   fprintf(stderr, "\nFIRM: irn_vrfy_irg() Return node %ld in entity \"%s\" has %d results different from type %d\n",
203     get_irn_node_nr(n), get_entity_name(ent),
204     get_Return_n_ress(n), get_method_n_ress(mt));
205 }
206
207 /**
208  * Show Phi input
209  */
210 static void show_phi_failure(ir_node *phi, ir_node *pred, int pos)
211 {
212   fprintf(stderr, "\nFIRM: irn_vrfy_irg() Phi node %ld has mode %s different from predeccessor node %ld mode %s\n",
213     get_irn_node_nr(phi), get_mode_name(get_irn_mode(phi)),
214     get_irn_node_nr(pred), get_mode_name(get_irn_mode(pred)));
215 }
216
217 INLINE static int
218 vrfy_Proj_proj(ir_node *p, ir_graph *irg) {
219   ir_node *pred;
220   ir_mode *mode;
221   int proj;
222
223   pred = skip_nop(get_Proj_pred(p));
224   assert(get_irn_mode(pred) == mode_T);
225   mode = get_irn_mode(p);
226   proj = get_Proj_proj(p);
227
228   switch (get_irn_opcode(pred)) {
229     case iro_Start:
230       ASSERT_AND_RET_DBG(
231           (
232            (proj == pns_initial_exec   && mode == mode_X) ||
233            (proj == pns_global_store   && mode == mode_M) ||
234            (proj == pns_frame_base     && mode_is_reference(mode)) ||
235            (proj == pns_globals        && mode_is_reference(mode)) ||
236            (proj == pns_args           && mode == mode_T) ||
237            (proj == pns_value_arg_base && mode_is_reference(mode))
238           ),
239           "wrong Proj from Start", 0,
240           show_proj_failure(p);
241       );
242       break;
243
244     case iro_Cond:
245       ASSERT_AND_RET_DBG(
246         (proj >= 0 && mode == mode_X),
247         "wrong Proj from Cond", 0,
248         show_proj_failure(p);
249       );
250       break;
251
252     case iro_Raise:
253       ASSERT_AND_RET_DBG(
254         ((proj == pn_Raise_X && mode == mode_X) || (proj == pn_Raise_M && mode == mode_M)),
255         "wrong Proj from Raise", 0,
256         show_proj_failure(p);
257       );
258       break;
259
260     case iro_InstOf:
261       ASSERT_AND_RET_DBG(
262         (proj >= 0 && mode == mode_X),
263         "wrong Proj from InstOf", 0,
264         show_proj_failure(p);
265       );
266       break;
267
268     case iro_Call:
269       ASSERT_AND_RET_DBG(
270         ((proj == pn_Call_M_regular        && mode == mode_M) ||
271          (proj == pn_Call_X_except         && mode == mode_X) ||
272          (proj == pn_Call_T_result         && mode == mode_T) ||
273          (proj == pn_Call_M_except         && mode == mode_M) ||
274          (proj == pn_Call_P_value_res_base && mode == mode_P)),
275         "wrong Proj from Call", 0,
276         show_proj_failure(p);
277       );
278       break;
279
280     case iro_Quot:
281       ASSERT_AND_RET_DBG(
282         ((proj == pn_Quot_M        && mode == mode_M) ||
283          (proj == pn_Quot_X_except && mode == mode_X) ||
284          (proj == pn_Quot_res      && mode_is_float(mode))),
285         "wrong Proj from Quot", 0,
286         show_proj_failure(p);
287       );
288       break;
289
290     case iro_DivMod:
291       ASSERT_AND_RET_DBG(
292         ((proj == pn_DivMod_M        && mode == mode_M) ||
293          (proj == pn_DivMod_X_except && mode == mode_X) ||
294          (proj == pn_DivMod_res_div  && mode_is_int(mode)) ||
295          (proj == pn_DivMod_res_mod  && mode_is_int(mode))),
296         "wrong Proj from DivMod", 0,
297         show_proj_failure(p);
298       );
299       break;
300
301     case iro_Div:
302       ASSERT_AND_RET_DBG(
303         ((proj == pn_Div_M        && mode == mode_M) ||
304          (proj == pn_Div_X_except && mode == mode_X) ||
305          (proj == pn_Div_res      && mode_is_int(mode))),
306         "wrong Proj from Div or Mod", 0,
307         show_proj_failure(p);
308       );
309       break;
310
311     case iro_Mod:
312       ASSERT_AND_RET_DBG(
313         ((proj == pn_Mod_M        && mode == mode_M) ||
314          (proj == pn_Mod_X_except && mode == mode_X) ||
315          (proj == pn_Mod_res      && mode_is_int(mode))),
316         "wrong Proj from Div or Mod", 0,
317         show_proj_failure(p);
318       );
319       break;
320
321     case iro_Cmp:
322       ASSERT_AND_RET_DBG(
323         (proj >= 0 && proj <= 15 && mode == mode_b),
324         "wrong Proj from Cmp", 0,
325         show_proj_failure(p);
326       );
327       break;
328
329     case iro_Load:
330       if (proj == pn_Load_res) {
331         ir_node *ptr = get_Load_ptr(pred);
332         entity *ent = NULL;
333         if (get_irn_op(ptr) == op_Sel) {
334           ent = get_Sel_entity(ptr);
335         } /*
336         We may not test this, after lowering and optimization the Const can
337         have an unexpected type.
338     else if ((get_irn_op(ptr) == op_Const) &&
339                    tarval_is_entity(get_Const_tarval(ptr))) {
340           ent = get_tarval_entity(get_Const_tarval(ptr));
341         } */
342         if (ent) {
343           ASSERT_AND_RET_DBG(
344             (mode == get_type_mode(get_entity_type(ent))),
345             "wrong data Proj from Load, entity type_mode failed", 0,
346             show_proj_failure_ent(p, ent);
347           );
348         }
349         else {
350           ASSERT_AND_RET_DBG(
351             mode_is_data(mode),
352            "wrong data Proj from Load", 0,
353            show_proj_failure(p);
354          );
355         }
356       } else {
357         ASSERT_AND_RET_DBG(
358           ((proj == pn_Load_M        && mode == mode_M) ||
359            (proj == pn_Load_X_except && mode == mode_X)),
360           "wrong Proj from Load", 0,
361           show_proj_failure(p);
362         );
363       }
364       break;
365
366     case iro_Store:
367       ASSERT_AND_RET_DBG(
368         ((proj == pn_Store_M        && mode == mode_M) ||
369          (proj == pn_Store_X_except && mode == mode_X)),
370         "wrong Proj from Store", 0,
371         show_proj_failure(p);
372       );
373       break;
374
375     case iro_Alloc:
376       ASSERT_AND_RET_DBG(
377         (
378          (proj == pn_Alloc_M        && mode == mode_M) ||
379          (proj == pn_Alloc_X_except /* && mode == mode_X*/) ||
380          (proj == pn_Alloc_res      && mode_is_reference(mode))
381         ),
382         "wrong Proj from Alloc", 0,
383         show_proj_failure(p);
384       );
385       break;
386
387     case iro_Proj:
388       {
389         type *mt; /* A method type */
390         pred = skip_nop(get_Proj_pred(pred));
391         ASSERT_AND_RET((get_irn_mode(pred) == mode_T), "Proj from something not a tuple", 0);
392         switch (get_irn_opcode(pred))
393         {
394           case iro_Start:
395             {
396               ASSERT_AND_RET(
397                   (proj >= 0 && mode_is_data(mode)),
398                   "wrong Proj from Proj from Start", 0);
399               mt = get_entity_type(get_irg_ent(irg));
400               ASSERT_AND_RET(
401                 (proj < get_method_n_params(mt)),
402                 "More Projs for args than args in type", 0
403               );
404               if ((mode_is_reference(mode)) && is_compound_type(get_method_param_type(mt, proj)))
405                 /* value argument */ break;
406
407               ASSERT_AND_RET(
408                   (mode == get_type_mode(get_method_param_type(mt, proj))),
409                   "Mode of Proj from Start doesn't match mode of param type.", 0);
410             }
411             break;
412
413           case iro_Call:
414             {
415               ASSERT_AND_RET(
416                   (proj >= 0 && mode_is_data(mode)),
417                   "wrong Proj from Proj from Call", 0);
418               mt = get_Call_type(pred);
419               ASSERT_AND_RET(
420                   (proj < get_method_n_ress(mt)),
421                   "More Projs for results than results in type.", 0);
422               if ((mode_is_reference(mode)) && is_compound_type(get_method_res_type(mt, proj)))
423                 /* value result */ break;
424
425               ASSERT_AND_RET(
426                   (mode == get_type_mode(get_method_res_type(mt, proj))),
427                   "Mode of Proj from Call doesn't match mode of result type.", 0);
428             }
429             break;
430
431           case iro_Tuple:
432             /* We don't test */
433             break;
434
435           default:
436             ASSERT_AND_RET(0, "Unknown opcode", 0);
437         }
438         break;
439
440       }
441     case iro_Tuple:
442       /* We don't test */
443       break;
444
445     case iro_CallBegin:
446       break;
447
448     case iro_EndReg:
449       break;
450
451     case iro_EndExcept:
452       break;
453
454     default:
455       ASSERT_AND_RET(0, "Unknown opcode", 0);
456   }
457
458   /* all went ok */
459   return 1;
460 }
461
462 int irn_vrfy_irg(ir_node *n, ir_graph *irg)
463 {
464   int i;
465   int opcode, opcode1;
466   ir_mode *mymode, *op1mode = NULL, *op2mode, *op3mode;
467   int op_is_symmetric = 1;  /*  0: asymmetric
468                                 1: operands have identical modes
469                                 2: modes of operands == mode of this node */
470   type *mt;                 /* A method type */
471   entity *ent;
472
473   ir_node **in;
474
475   if (!opt_do_node_verification) return 1;
476
477   if (! interprocedural_view) {
478     /*
479      * do NOT check placement in interprocedural view, as we don't always know
480      * the "right" graph ...
481      */
482     ASSERT_AND_RET_DBG(
483       node_is_in_irgs_storage(irg, n),
484       "Node is not stored on proper IR graph!", 0,
485       show_node_on_graph(irg, n);
486     );
487   }
488
489   opcode = get_irn_opcode(n);
490
491   /* We don't want to test nodes whose predecessors are Bad or Unknown,
492      as we would have to special case that for each operation. */
493   if (opcode != iro_Phi && opcode != iro_Block)
494     for (i = 0; i < get_irn_arity(n); i++) {
495       opcode1 = get_irn_opcode(get_irn_n(n, i));
496       if (opcode1 == iro_Bad /*|| opcode1 == iro_Unknown*/)  /* GL: for analyses mode must be correct. */
497         return 1;
498     }
499
500   mymode = get_irn_mode(n);
501   in = get_irn_in(n);
502
503   switch (opcode)
504   {
505
506     case iro_Block:
507       for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
508         ir_node *pred =  get_Block_cfgpred(n, i);
509         ASSERT_AND_RET(
510           (is_Bad(pred)     ||
511            is_Unknown(pred) ||
512            (get_irn_mode(pred) == mode_X)
513           ), "Block node", 0);
514       }
515       // End block may only have Return, Raise or fragile ops as preds.
516       if (n == get_irg_end_block(irg))
517         for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
518           ir_node *pred =  skip_Proj(get_Block_cfgpred(n, i));
519           if (is_Proj(pred) || get_irn_op(pred) == op_Tuple)
520             break;   // We can not test properly.  How many tuples are there?
521           ASSERT_AND_RET(((get_irn_op(pred) == op_Return) ||
522                           is_Bad(pred)                    ||
523                           (get_irn_op(pred) == op_Raise)  ||
524                           is_fragile_op(pred)               ),
525                          "End Block node", 0);
526         }
527       // irg attr must == graph we are in.
528       if (! interprocedural_view) {
529         ASSERT_AND_RET(((get_irn_irg(n) && get_irn_irg(n) == irg)), "Block node has wrong irg attribute", 0);
530       }
531
532       break;
533
534     case iro_Start:
535       ASSERT_AND_RET(
536           /* Start: BB --> X x M x ref x data1 x ... x datan x ref */
537           mymode == mode_T, "Start node", 0
538           );
539       break;
540
541     case iro_Jmp:
542       ASSERT_AND_RET(
543           /* Jmp: BB --> X */
544           mymode == mode_X, "Jmp node", 0
545           );
546       break;
547
548     case iro_Break:
549       ASSERT_AND_RET(
550           /* Jmp: BB --> X */
551           mymode == mode_X, "Jmp node", 0
552           );
553       break;
554
555     case iro_Cond:
556       op1mode = get_irn_mode(in[1]);
557       ASSERT_AND_RET(
558           /* Cond: BB x b --> X x X */
559           (op1mode == mode_b ||
560            /* Cond: BB x int --> X^n */
561            mode_is_int(op1mode) ),  "Cond node", 0
562           );
563       ASSERT_AND_RET(mymode == mode_T, "Cond mode is not a tuple", 0);
564       break;
565
566     case iro_Return:
567       op1mode = get_irn_mode(in[1]);
568       /* Return: BB x M x data1 x ... x datan --> X */
569       /* printf("mode: %s, code %s\n", ID_TO_STR(n->mode->name), ID_TO_STR(n->op->name));*/
570       ASSERT_AND_RET( op1mode == mode_M, "Return node", 0 );  /* operand M */
571       for (i=2; i < get_irn_arity(n); i++) {
572         ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Return node", 0 );  /* operand datai */
573       };
574       ASSERT_AND_RET( mymode == mode_X, "Result X", 0 );   /* result X */
575       /* Compare returned results with result types of method type */
576       mt = get_entity_type(get_irg_ent(irg));
577       ASSERT_AND_RET_DBG( get_Return_n_ress(n) == get_method_n_ress(mt),
578         "Number of results for Return doesn't match number of results in type.", 0,
579         show_return_nres(irg, n, mt););
580       for (i = 0; i < get_Return_n_ress(n); i++)
581         ASSERT_AND_RET_DBG(
582           get_irn_mode(get_Return_res(n, i)) == get_type_mode(get_method_res_type(mt, i)),
583           "Mode of result for Return doesn't match mode of result type.", 0,
584            show_return_modes(irg, n, mt, i););
585       break;
586
587     case iro_Raise:
588       op1mode = get_irn_mode(in[1]);
589       op2mode = get_irn_mode(in[2]);
590       ASSERT_AND_RET(
591           /* Sel: BB x M x ref --> X x M */
592           op1mode == mode_M && mode_is_reference(op2mode) &&
593           mymode == mode_T, "Raise node", 0
594           );
595       break;
596
597     case iro_Const:
598       ASSERT_AND_RET(
599           /* Const: BB --> data */
600           (mode_is_data (mymode) ||
601            mymode == mode_b)      /* we want boolean constants for static evaluation */
602           ,"Const node", 0        /* of Cmp. */
603           );
604       break;
605
606     case iro_SymConst:
607       ASSERT_AND_RET(
608           /* SymConst: BB --> int*/
609           (mode_is_int(mymode) ||
610            /* SymConst: BB --> ref */
611            mode_is_reference(mymode))
612           ,"SymConst node", 0);
613       break;
614
615     case iro_Sel:
616       op1mode = get_irn_mode(in[1]);
617       op2mode = get_irn_mode(in[2]);
618       ASSERT_AND_RET_DBG(
619           /* Sel: BB x M x ref x int^n --> ref */
620           (op1mode == mode_M && op2mode == mymode && mode_is_reference(mymode)),
621           "Sel node", 0, show_node_failure(n)
622           );
623       for (i=3; i < get_irn_arity(n); i++)
624       {
625         ASSERT_AND_RET_DBG(mode_is_int(get_irn_mode(in[i])), "Sel node", 0, show_node_failure(n));
626       }
627       ent = get_Sel_entity(n);
628       ASSERT_AND_RET_DBG(ent, "Sel node with empty entity", 0, show_node_failure(n));
629       break;
630
631     case iro_InstOf:
632       ASSERT_AND_RET(mode_T == mymode, "mode of Instof is not a tuple", 0);
633       ASSERT_AND_RET(mode_is_data(op1mode), "Instof not on data", 0);
634       break;
635
636     case iro_Call:
637       op1mode = get_irn_mode(in[1]);
638       op2mode = get_irn_mode(in[2]);
639       /* Call: BB x M x ref x data1 x ... x datan
640          --> M x datan+1 x ... x data n+m */
641       ASSERT_AND_RET( op1mode == mode_M && mode_is_reference(op2mode), "Call node", 0 );  /* operand M x ref */
642       for (i=3; i < get_irn_arity(n); i++) {
643         ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Call node", 0 );  /* operand datai */
644       };
645       ASSERT_AND_RET( mymode == mode_T, "Call result not a tuple", 0 );   /* result T */
646       /* Compare arguments of node with those of type */
647       mt = get_Call_type(n);
648
649       if (get_method_variadicity(mt) == variadicity_variadic) {
650         ASSERT_AND_RET_DBG(
651             get_Call_n_params(n) >= get_method_n_params(mt),
652             "Number of args for Call doesn't match number of args in variadic type.",
653             0,
654             fprintf(stderr, "Call has %d params, method %s type %d\n",
655               get_Call_n_params(n), get_type_name(mt), get_method_n_params(mt));
656             );
657       }
658       else {
659         ASSERT_AND_RET(
660             get_Call_n_params(n) == get_method_n_params(mt),
661             "Number of args for Call doesn't match number of args in non variadic type.",
662             0);
663       }
664
665       for (i = 0; i < get_method_n_params(mt); i++) {
666         ASSERT_AND_RET_DBG(
667             get_irn_mode(get_Call_param(n, i)) == get_type_mode(get_method_param_type(mt, i)),
668             "Mode of arg for Call doesn't match mode of arg type.", 0,
669             show_call_param(n, mt);
670             );
671       }
672       break;
673
674     case iro_Add:
675       op1mode = get_irn_mode(in[1]);
676       op2mode = get_irn_mode(in[2]);
677       ASSERT_AND_RET_DBG(
678           (
679            /* common Add: BB x numP x numP --> numP */
680            (op1mode == mymode && op2mode == op1mode && mode_is_numP(mymode)) ||
681            /* Pointer Add: BB x ref x int --> ref */
682            (mode_is_reference(op1mode) && mode_is_int(op2mode) && op1mode == mymode) ||
683            /* Pointer Add: BB x int x ref --> ref */
684            (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode))
685           ),
686           "Add node", 0,
687           show_binop_failure(n, "/* common Add: BB x numP x numP --> numP */ |\n"
688                                 "/* Pointer Add: BB x ref x int --> ref */   |\n"
689                                 "/* Pointer Add: BB x int x ref --> ref */");
690           );
691       if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
692         /* BB x ref x int --> ref or BB x int x ref --> ref */
693         op_is_symmetric = 0;
694       } else {
695         /* BB x num x num --> num or BB x ref x ref */
696         op_is_symmetric = 2;
697       }
698       break;
699
700     case iro_Sub:
701       op1mode = get_irn_mode(in[1]);
702       op2mode = get_irn_mode(in[2]);
703       ASSERT_AND_RET_DBG(
704           /* common Sub: BB x numP x numP --> numP */
705           ((mymode ==op1mode && mymode == op2mode && mode_is_numP(op1mode)) ||
706            /* Pointer Sub: BB x ref x int --> ref */
707            (op1mode == mymode && mode_is_int(op2mode) && mode_is_reference(mymode)) ||
708            /* Pointer Sub: BB x int x ref --> ref */
709            (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode)) ||
710            /* Pointer Sub: BB x ref x ref --> int */
711            (op1mode == op2mode && mode_is_reference(op2mode) && mode_is_int(mymode))),
712           "Sub node", 0,
713           show_binop_failure(n, "/* common Sub: BB x numP x numP --> numP */ |\n"
714                                 "/* Pointer Sub: BB x ref x int --> ref */   |\n"
715                                 "/* Pointer Sub: BB x int x ref --> ref */   |\n"
716                                 "/* Pointer Sub: BB x ref x ref --> int */" );
717           );
718       if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
719         op_is_symmetric = 0;
720       } else {
721         op_is_symmetric = 2;
722       }
723       break;
724
725     case iro_Minus:
726       op1mode = get_irn_mode(in[1]);
727       ASSERT_AND_RET_DBG(
728           /* Minus: BB x float --> float */
729           op1mode == mymode && get_mode_sort(op1mode) == irms_float_number, "Minus node", 0,
730           show_unop_failure(n , "/* Minus: BB x float --> float */");
731           );
732       op_is_symmetric = 2;
733       break;
734
735     case iro_Mul:
736       op1mode = get_irn_mode(in[1]);
737       op2mode = get_irn_mode(in[2]);
738       ASSERT_AND_RET_DBG(
739           /* Mul: BB x int1 x int1 --> int2 */
740           ((mode_is_int(op1mode)   && op2mode == op1mode && mode_is_int(mymode)) ||
741            (mode_is_float(op1mode) && op2mode == op1mode && mymode == op1mode)),
742           "Mul node",0,
743           show_binop_failure(n, "/* Mul: BB x int1 x int1 --> int2 */");
744           );
745       op_is_symmetric = 2;
746       break;
747
748     case iro_Quot:
749       op1mode = get_irn_mode(in[1]);
750       op2mode = get_irn_mode(in[2]);
751       op3mode = get_irn_mode(in[3]);
752       ASSERT_AND_RET_DBG(
753           /* Quot: BB x M x float x float --> M x X x float */
754           op1mode == mode_M && op2mode == op3mode &&
755           get_mode_sort(op2mode) == irms_float_number &&
756           mymode == mode_T,
757           "Quot node",0,
758           show_binop_failure(n, "/* Quot: BB x M x float x float --> M x X x float */");
759           );
760       op_is_symmetric = 2;
761       break;
762
763     case iro_DivMod:
764       op1mode = get_irn_mode(in[1]);
765       op2mode = get_irn_mode(in[2]);
766       op3mode = get_irn_mode(in[3]);
767       ASSERT_AND_RET(
768           /* DivMod: BB x M x int x int --> M x X x int x int */
769           op1mode == mode_M &&
770           mode_is_int(op2mode) &&
771           op3mode == op2mode &&
772           mymode == mode_T,
773           "DivMod node", 0
774           );
775       op_is_symmetric = 1;
776       break;
777
778     case iro_Div:
779     case iro_Mod:
780       op1mode = get_irn_mode(in[1]);
781       op2mode = get_irn_mode(in[2]);
782       op3mode = get_irn_mode(in[3]);
783       ASSERT_AND_RET(
784           /* Div or Mod: BB x M x int x int --> M x X x int */
785           op1mode == mode_M &&
786           op2mode == op3mode &&
787           mode_is_int(op2mode) &&
788           mymode == mode_T,
789           "Div or Mod node", 0
790           );
791       op_is_symmetric = 1;
792       break;
793
794     case iro_Abs:
795       op1mode = get_irn_mode(in[1]);
796       ASSERT_AND_RET_DBG(
797         /* Abs: BB x num --> num */
798         op1mode == mymode &&
799         mode_is_num (op1mode),
800         "Abs node", 0,
801         show_unop_failure(n, "/* Abs: BB x num --> num */");
802       );
803       op_is_symmetric = 2;
804       break;
805
806     case iro_And:
807     case iro_Or:
808     case iro_Eor:
809       op1mode = get_irn_mode(in[1]);
810       op2mode = get_irn_mode(in[2]);
811       ASSERT_AND_RET_DBG(
812         /* And or Or or Eor: BB x int x int --> int */
813         mode_is_int(mymode) &&
814         op2mode == op1mode &&
815         mymode == op2mode,
816         "And, Or or Eor node", 0,
817         show_binop_failure(n, "/* And or Or or Eor: BB x int x int --> int */");
818       );
819       op_is_symmetric = 2;
820       break;
821
822     case iro_Not:
823       op1mode = get_irn_mode(in[1]);
824       ASSERT_AND_RET_DBG(
825         /* Not: BB x int --> int */
826         mode_is_int(mymode) &&
827         mymode == op1mode,
828         "Not node", 0,
829         show_unop_failure(n, "/* Not: BB x int --> int */");
830       );
831       op_is_symmetric = 2;
832       break;
833
834
835     case iro_Cmp:
836       op1mode = get_irn_mode(in[1]);
837       op2mode = get_irn_mode(in[2]);
838       ASSERT_AND_RET_DBG(
839         /* Cmp: BB x datab x datab --> b16 */
840         mode_is_data (op1mode) &&
841         op2mode == op1mode &&
842         mymode == mode_T,
843         "Cmp node", 0,
844         show_binop_failure(n, "/* Cmp: BB x datab x datab --> b16 */");
845       );
846       break;
847
848     case iro_Shl:
849     case iro_Shr:
850     case iro_Shrs:
851       op1mode = get_irn_mode(in[1]);
852       op2mode = get_irn_mode(in[2]);
853       ASSERT_AND_RET_DBG(
854         /* Shl, Shr or Shrs: BB x int x int_u --> int */
855         mode_is_int(op1mode) &&
856         mode_is_int(op2mode) &&
857         !mode_is_signed(op2mode) &&
858         mymode == op1mode,
859         "Shl, Shr, Shr or Rot node", 0,
860         show_binop_failure(n, "/* Shl, Shr or Shrs: BB x int x int_u --> int */");
861       );
862       break;
863
864     case iro_Rot:
865       op1mode = get_irn_mode(in[1]);
866       op2mode = get_irn_mode(in[2]);
867       ASSERT_AND_RET_DBG(
868         /* Rot: BB x int x int --> int */
869         mode_is_int(op1mode) &&
870         mode_is_int(op2mode) &&
871         mymode == op1mode,
872         "Rot node", 0,
873         show_binop_failure(n, "/* Rot: BB x int x int --> int */");
874       );
875       break;
876
877     case iro_Conv:
878       op1mode = get_irn_mode(in[1]);
879       ASSERT_AND_RET_DBG(
880         /* Conv: BB x datab1 --> datab2 */
881         mode_is_datab(op1mode) && mode_is_data(mymode),
882         "Conv node", 0,
883         show_unop_failure(n, "/* Conv: BB x datab1 --> datab2 */");
884       );
885       break;
886
887     case iro_Cast:
888       op1mode = get_irn_mode(in[1]);
889       ASSERT_AND_RET_DBG(
890         /* Conv: BB x datab1 --> datab2 */
891         mode_is_data(op1mode) && op1mode == mymode,
892         "Cast node", 0,
893         show_unop_failure(n, "/* Conv: BB x datab1 --> datab2 */");
894       );
895       break;
896
897     case iro_Phi:
898       /* Phi: BB x dataM^n --> dataM */
899       for (i = 1; i < get_irn_arity(n); i++) {
900         if (!is_Bad(in[i]) && (get_irn_op(in[i]) != op_Unknown))
901           ASSERT_AND_RET_DBG(
902               get_irn_mode(in[i]) == mymode,
903               "Phi node", 0,
904               show_phi_failure(n, in[i], i);
905           );
906       };
907       ASSERT_AND_RET( mode_is_dataM(mymode), "Phi node", 0 );
908       break;
909
910     case iro_Load:
911       op1mode = get_irn_mode(in[1]);
912       op2mode = get_irn_mode(in[2]);
913       ASSERT_AND_RET(
914           /* Load: BB x M x ref --> M x X x data */
915           op1mode == mode_M && mode_is_reference(op2mode),
916           "Load node", 0
917           );
918       ASSERT_AND_RET( mymode == mode_T, "Load node", 0 );
919       break;
920
921     case iro_Store:
922       op1mode = get_irn_mode(in[1]);
923       op2mode = get_irn_mode(in[2]);
924       op3mode = get_irn_mode(in[3]);
925       ASSERT_AND_RET(
926           /* Load: BB x M x ref data --> M x X */
927           op1mode == mode_M && mode_is_reference(op2mode) && mode_is_data(op3mode),
928           "Store node", 0
929           );
930       ASSERT_AND_RET(mymode == mode_T, "Store node", 0);
931       break;
932
933     case iro_Alloc:
934       op1mode = get_irn_mode(in[1]);
935       op2mode = get_irn_mode(in[2]);
936       ASSERT_AND_RET_DBG(
937         /* Alloc: BB x M x int_u --> M x X x ref */
938         op1mode == mode_M &&
939         mode_is_int(op2mode) &&
940         !mode_is_signed(op2mode) &&
941         mymode == mode_T,
942         "Alloc node", 0,
943         show_binop_failure(n, "/* Alloc: BB x M x int_u --> M x X x ref */");
944       );
945       break;
946
947     case iro_Free:
948       op1mode = get_irn_mode(in[1]);
949       op2mode = get_irn_mode(in[2]);
950       ASSERT_AND_RET_DBG(
951         /* Free: BB x M x ref --> M */
952         op1mode == mode_M && mode_is_reference(op2mode) &&
953         mymode == mode_M,
954         "Free node", 0,
955         show_binop_failure(n, "/* Free: BB x M x ref --> M */");
956       );
957       break;
958
959     case iro_Sync:
960       /* Sync: BB x M^n --> M */
961       for (i=1; i < get_irn_arity(n); i++) {
962         ASSERT_AND_RET( get_irn_mode(in[i]) == mode_M, "Sync node", 0 );
963       };
964       ASSERT_AND_RET( mymode == mode_M, "Sync node", 0 );
965       break;
966
967     case iro_Proj:
968       return vrfy_Proj_proj(n, irg);
969       break;
970
971     case iro_Confirm:
972       op1mode = get_irn_mode(in[1]);
973       op2mode = get_irn_mode(in[2]);
974       ASSERT_AND_RET_DBG(
975         /* Confirm: BB x T x T --> T */
976         op1mode == mymode &&
977         op2mode == mymode,
978         "Confirm node", 0,
979         show_binop_failure(n, "/* Confirm: BB x T x T --> T */");
980       );
981       break;
982
983     default:
984       break;
985   }
986
987   /* All went ok */
988   return 1;
989 }
990
991 int irn_vrfy(ir_node *n)
992 {
993   int res = 1;
994 #ifdef DEBUG_libfirm
995   res = irn_vrfy_irg(n, current_ir_graph);
996 #endif
997   return res;
998 }
999
1000 /*******************************************************************/
1001 /* Verify the whole graph.                                         */
1002 /*******************************************************************/
1003
1004 static void vrfy_wrap(ir_node *node, void *env)
1005 {
1006   int *res = env;
1007
1008   *res = irn_vrfy(node);
1009 }
1010
1011 int irg_vrfy(ir_graph *irg)
1012 {
1013   int res = 1;
1014 #ifdef DEBUG_libfirm
1015   ir_graph *rem;
1016
1017   rem = current_ir_graph;
1018   current_ir_graph = irg;
1019
1020   assert(get_irg_pinned(irg) == pinned);
1021
1022   irg_walk(irg->end, vrfy_wrap, NULL, &res);
1023
1024   current_ir_graph = rem;
1025
1026   if (opt_do_node_verification == NODE_VERIFICATION_REPORT && ! res) {
1027     entity *ent = get_irg_entity(current_ir_graph);
1028
1029     if (ent)
1030       fprintf(stderr, "irg_verify: Verifying graph %s failed\n", get_entity_name(ent));
1031     else
1032       fprintf(stderr, "irg_verify: Verifying graph %p failed\n", (void *)current_ir_graph);
1033   }
1034
1035 #endif
1036   return res;
1037 }
1038
1039 int irn_vrfy_irg_dump(ir_node *n, ir_graph *irg, const char **bad_string)
1040 {
1041   int res;
1042   node_verification_t old = opt_do_node_verification;
1043
1044   bad_msg = NULL;
1045   opt_do_node_verification = NODE_VERIFICATION_ERROR_ONLY;
1046   res = irn_vrfy_irg(n, irg);
1047   opt_do_node_verification = old;
1048   *bad_string = bad_msg;
1049
1050   return res;
1051 }