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