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