Fixed 'inline' lossage --flo
[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_FuncCall:
281       ASSERT_AND_RET_DBG(
282         ((proj == pn_Call_M_regular        && mode == mode_M) ||
283          (proj == pn_Call_X_except         && mode == mode_X) ||
284          (proj == pn_Call_T_result         && mode == mode_T) ||
285          (proj == pn_Call_M_except         && mode == mode_M) ||
286      (proj == pn_Call_P_value_res_base && mode == mode_P)),
287         "wrong Proj from FuncCall", 0,
288         show_proj_failure(p);
289       );
290       break;
291
292     case iro_Quot:
293       ASSERT_AND_RET_DBG(
294         ((proj == pn_Quot_M        && mode == mode_M) ||
295          (proj == pn_Quot_X_except && mode == mode_X) ||
296          (proj == pn_Quot_res      && mode_is_float(mode))),
297         "wrong Proj from Quot", 0,
298     show_proj_failure(p);
299       );
300       break;
301
302     case iro_DivMod:
303       ASSERT_AND_RET_DBG(
304         ((proj == pn_DivMod_M        && mode == mode_M) ||
305          (proj == pn_DivMod_X_except && mode == mode_X) ||
306          (proj == pn_DivMod_res_div  && mode_is_int(mode)) ||
307          (proj == pn_DivMod_res_mod  && mode_is_int(mode))),
308         "wrong Proj from DivMod", 0,
309     show_proj_failure(p);
310       );
311       break;
312
313     case iro_Div:
314       ASSERT_AND_RET_DBG(
315         ((proj == pn_Div_M        && mode == mode_M) ||
316          (proj == pn_Div_X_except && mode == mode_X) ||
317          (proj == pn_Div_res      && mode_is_int(mode))),
318         "wrong Proj from Div or Mod", 0,
319     show_proj_failure(p);
320       );
321       break;
322
323     case iro_Mod:
324       ASSERT_AND_RET_DBG(
325         ((proj == pn_Mod_M        && mode == mode_M) ||
326          (proj == pn_Mod_X_except && mode == mode_X) ||
327          (proj == pn_Mod_res      && mode_is_int(mode))),
328         "wrong Proj from Div or Mod", 0,
329     show_proj_failure(p);
330       );
331       break;
332
333     case iro_Cmp:
334       ASSERT_AND_RET_DBG(
335         (proj >= 0 && proj <= 15 && mode == mode_b),
336         "wrong Proj from Cmp", 0,
337     show_proj_failure(p);
338       );
339       break;
340
341     case iro_Load:
342       if (proj == pn_Load_res) {
343     ir_node *ptr = get_Load_ptr(pred);
344     entity *ent = NULL;
345     if (get_irn_op(ptr) == op_Sel) {
346       ent = get_Sel_entity(ptr);
347     } /*
348         We may not test this, after lowering and optimization the Const can
349         have an unexpected type.
350     else if ((get_irn_op(ptr) == op_Const) &&
351            tarval_is_entity(get_Const_tarval(ptr))) {
352       ent = get_tarval_entity(get_Const_tarval(ptr));
353     } */
354     if (ent) {
355       ASSERT_AND_RET_DBG(
356         (mode == get_type_mode(get_entity_type(ent))),
357         "wrong data Proj from Load, entity type_mode failed", 0,
358         show_proj_failure_ent(p, ent);
359       );
360     }
361     else {
362       ASSERT_AND_RET_DBG(
363         mode_is_data(mode),
364        "wrong data Proj from Load", 0,
365        show_proj_failure(p);
366      );
367     }
368       } else {
369     ASSERT_AND_RET_DBG(
370       ((proj == pn_Load_M        && mode == mode_M) ||
371        (proj == pn_Load_X_except && mode == mode_X)),
372           "wrong Proj from Load", 0,
373       show_proj_failure(p);
374     );
375       }
376       break;
377
378     case iro_Store:
379       ASSERT_AND_RET_DBG(
380         ((proj == pn_Store_M        && mode == mode_M) ||
381          (proj == pn_Store_X_except && mode == mode_X)),
382         "wrong Proj from Store", 0,
383     show_proj_failure(p);
384       );
385       break;
386
387     case iro_Alloc:
388       ASSERT_AND_RET_DBG(
389         (
390          (proj == pn_Alloc_M        && mode == mode_M) ||
391          (proj == pn_Alloc_X_except /* && mode == mode_X*/) ||
392          (proj == pn_Alloc_res      && mode_is_reference(mode))
393         ),
394         "wrong Proj from Alloc", 0,
395         show_proj_failure(p);
396       );
397       break;
398
399     case iro_Proj:
400       {
401         type *mt; /* A method type */
402         pred = skip_nop(get_Proj_pred(pred));
403         ASSERT_AND_RET((get_irn_mode(pred) == mode_T), "Proj from something not a tuple", 0);
404         switch (get_irn_opcode(pred))
405         {
406           case iro_Start:
407             {
408               ASSERT_AND_RET(
409                   (proj >= 0 && mode_is_data(mode)),
410                   "wrong Proj from Proj from Start", 0);
411               mt = get_entity_type(get_irg_ent(irg));
412               ASSERT_AND_RET(
413                 (proj < get_method_n_params(mt)),
414                 "More Projs for args than args in type", 0
415           );
416               if ((mode_is_reference(mode)) && is_compound_type(get_method_param_type(mt, proj)))
417                 /* value argument */ break;
418
419               ASSERT_AND_RET(
420                   (mode == get_type_mode(get_method_param_type(mt, proj))),
421                   "Mode of Proj from Start doesn't match mode of param type.", 0);
422             }
423             break;
424
425           case iro_Call:
426             {
427               ASSERT_AND_RET(
428                   (proj >= 0 && mode_is_data(mode)),
429                   "wrong Proj from Proj from Call", 0);
430               mt = get_Call_type(pred);
431               ASSERT_AND_RET(
432                   (proj < get_method_n_ress(mt)),
433                   "More Projs for results than results in type.", 0);
434               if ((mode_is_reference(mode)) && is_compound_type(get_method_res_type(mt, proj)))
435                 /* value result */ break;
436
437               ASSERT_AND_RET(
438                   (mode == get_type_mode(get_method_res_type(mt, proj))),
439                   "Mode of Proj from Call doesn't match mode of result type.", 0);
440             }
441             break;
442
443           case iro_FuncCall:
444             {
445               ASSERT_AND_RET(
446                   (proj >= 0 && mode_is_data(mode)),
447                   "wrong Proj from Proj from FuncCall", 0);
448               mt = get_FuncCall_type(pred);
449               ASSERT_AND_RET(
450                   (proj < get_method_n_ress(mt)),
451                   "More Projs for results than results in type.", 0);
452               if ((mode_is_reference(mode)) && is_compound_type(get_method_res_type(mt, proj)))
453                 /* value result */ break;
454
455               ASSERT_AND_RET(
456                   (mode == get_type_mode(get_method_res_type(mt, proj))),
457                   "Mode of Proj from FuncCall doesn't match mode of result type.", 0);
458             }
459             break;
460
461           case iro_Tuple:
462             /* We don't test */
463             break;
464
465           default:
466             ASSERT_AND_RET(0, "Unknown opcode", 0);
467         }
468         break;
469
470       }
471     case iro_Tuple:
472       /* We don't test */
473       break;
474
475     case iro_CallBegin:
476       break;
477
478     case iro_EndReg:
479       break;
480
481     case iro_EndExcept:
482       break;
483
484     default:
485       ASSERT_AND_RET(0, "Unknown opcode", 0);
486   }
487
488   /* all went ok */
489   return 1;
490 }
491
492 int irn_vrfy_irg(ir_node *n, ir_graph *irg)
493 {
494   int i;
495   int opcode, opcode1;
496   ir_mode *mymode, *op1mode = NULL, *op2mode, *op3mode;
497   int op_is_symmetric = 1;  /*  0: asymmetric
498                 1: operands have identical modes
499                 2: modes of operands == mode of this node */
500   type *mt;                 /* A method type */
501   entity *ent;
502
503   ir_node **in;
504
505   if (!opt_do_node_verification) return 1;
506
507   if (! interprocedural_view) {
508     /*
509      * do NOT check placement in interprocedural view, as we don't always know
510      * the "right" graph ...
511      */
512     ASSERT_AND_RET_DBG(
513       node_is_in_irgs_storage(irg, n),
514       "Node is not stored on proper IR graph!", 0,
515       show_node_on_graph(irg, n);
516     );
517   }
518
519   opcode = get_irn_opcode(n);
520
521   /* We don't want to test nodes whose predecessors are Bad or Unknown,
522      as we would have to special case that for each operation. */
523   if (opcode != iro_Phi && opcode != iro_Block)
524     for (i = 0; i < get_irn_arity(n); i++) {
525       opcode1 = get_irn_opcode(get_irn_n(n, i));
526       if (opcode1 == iro_Bad /*|| opcode1 == iro_Unknown*/)  /* GL: for analyses mode must be correct. */
527         return 1;
528     }
529
530   mymode = get_irn_mode(n);
531   in = get_irn_in(n);
532
533   switch (opcode)
534   {
535
536     case iro_Block:
537       for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
538     ir_node *pred =  get_Block_cfgpred(n, i);
539     ASSERT_AND_RET(
540       (is_Bad(pred)     ||
541        is_Unknown(pred) ||
542        (get_irn_mode(pred) == mode_X)
543       ), "Block node", 0);
544       }
545       // End block may only have Return, Raise or fragile ops as preds.
546       if (n == get_irg_end_block(irg))
547     for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
548       ir_node *pred =  skip_Proj(get_Block_cfgpred(n, i));
549       if (is_Proj(pred) || get_irn_op(pred) == op_Tuple)
550         break;   // We can not test properly.  How many tuples are there?
551       ASSERT_AND_RET(((get_irn_op(pred) == op_Return) ||
552               is_Bad(pred)                    ||
553               (get_irn_op(pred) == op_Raise)  ||
554               is_fragile_op(pred)               ),
555              "End Block node", 0);
556     }
557       // irg attr must == graph we are in.
558       if (! interprocedural_view) {
559     ASSERT_AND_RET(((get_irn_irg(n) && get_irn_irg(n) == irg)), "Block node has wrong irg attribute", 0);
560       }
561
562       break;
563
564     case iro_Start:
565       ASSERT_AND_RET(
566           /* Start: BB --> X x M x ref x data1 x ... x datan x ref */
567           mymode == mode_T, "Start node", 0
568           );
569       break;
570
571     case iro_Jmp:
572       ASSERT_AND_RET(
573           /* Jmp: BB --> X */
574           mymode == mode_X, "Jmp node", 0
575           );
576       break;
577
578     case iro_Break:
579       ASSERT_AND_RET(
580           /* Jmp: BB --> X */
581           mymode == mode_X, "Jmp node", 0
582           );
583       break;
584
585     case iro_Cond:
586       op1mode = get_irn_mode(in[1]);
587       ASSERT_AND_RET(
588           /* Cond: BB x b --> X x X */
589           (op1mode == mode_b ||
590            /* Cond: BB x int --> X^n */
591            mode_is_int(op1mode) ),  "Cond node", 0
592           );
593       ASSERT_AND_RET(mymode == mode_T, "Cond mode is not a tuple", 0);
594       break;
595
596     case iro_Return:
597       op1mode = get_irn_mode(in[1]);
598       /* Return: BB x M x data1 x ... x datan --> X */
599       /* printf("mode: %s, code %s\n", ID_TO_STR(n->mode->name), ID_TO_STR(n->op->name));*/
600       ASSERT_AND_RET( op1mode == mode_M, "Return node", 0 );  /* operand M */
601       for (i=2; i < get_irn_arity(n); i++) {
602         ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Return node", 0 );  /* operand datai */
603       };
604       ASSERT_AND_RET( mymode == mode_X, "Result X", 0 );   /* result X */
605       /* Compare returned results with result types of method type */
606       mt = get_entity_type(get_irg_ent(irg));
607       ASSERT_AND_RET_DBG( get_Return_n_ress(n) == get_method_n_ress(mt),
608         "Number of results for Return doesn't match number of results in type.", 0,
609     show_return_nres(irg, n, mt););
610       for (i = 0; i < get_Return_n_ress(n); i++)
611         ASSERT_AND_RET_DBG(
612           get_irn_mode(get_Return_res(n, i)) == get_type_mode(get_method_res_type(mt, i)),
613           "Mode of result for Return doesn't match mode of result type.", 0,
614        show_return_modes(irg, n, mt, i););
615       break;
616
617     case iro_Raise:
618       op1mode = get_irn_mode(in[1]);
619       op2mode = get_irn_mode(in[2]);
620       ASSERT_AND_RET(
621           /* Sel: BB x M x ref --> X x M */
622           op1mode == mode_M && mode_is_reference(op2mode) &&
623           mymode == mode_T, "Raise node", 0
624           );
625       break;
626
627     case iro_Const:
628       ASSERT_AND_RET(
629           /* Const: BB --> data */
630           (mode_is_data (mymode) ||
631            mymode == mode_b)      /* we want boolean constants for static evaluation */
632           ,"Const node", 0        /* of Cmp. */
633           );
634       break;
635
636     case iro_SymConst:
637       ASSERT_AND_RET(
638           /* SymConst: BB --> int*/
639           (mode_is_int(mymode) ||
640            /* SymConst: BB --> ref */
641            mode_is_reference(mymode))
642           ,"SymConst node", 0);
643       break;
644
645     case iro_Sel:
646       op1mode = get_irn_mode(in[1]);
647       op2mode = get_irn_mode(in[2]);
648       ASSERT_AND_RET_DBG(
649           /* Sel: BB x M x ref x int^n --> ref */
650           (op1mode == mode_M && op2mode == mymode && mode_is_reference(mymode)),
651       "Sel node", 0, show_node_failure(n)
652           );
653       for (i=3; i < get_irn_arity(n); i++)
654       {
655         ASSERT_AND_RET_DBG(mode_is_int(get_irn_mode(in[i])), "Sel node", 0, show_node_failure(n));
656       }
657       ent = get_Sel_entity(n);
658       ASSERT_AND_RET_DBG(ent, "Sel node with empty entity", 0, show_node_failure(n));
659       break;
660
661     case iro_InstOf:
662       ASSERT_AND_RET(mode_T == mymode, "mode of Instof is not a tuple", 0);
663       ASSERT_AND_RET(mode_is_data(op1mode), "Instof not on data", 0);
664       break;
665
666     case iro_Call:
667       op1mode = get_irn_mode(in[1]);
668       op2mode = get_irn_mode(in[2]);
669       /* Call: BB x M x ref x data1 x ... x datan
670          --> M x datan+1 x ... x data n+m */
671       ASSERT_AND_RET( op1mode == mode_M && mode_is_reference(op2mode), "Call node", 0 );  /* operand M x ref */
672       for (i=3; i < get_irn_arity(n); i++) {
673         ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Call node", 0 );  /* operand datai */
674       };
675       ASSERT_AND_RET( mymode == mode_T, "Call result not a tuple", 0 );   /* result T */
676       /* Compare arguments of node with those of type */
677       mt = get_Call_type(n);
678
679       if (get_method_variadicity(mt) == variadicity_variadic) {
680         ASSERT_AND_RET_DBG(
681             get_Call_n_params(n) >= get_method_n_params(mt),
682             "Number of args for Call doesn't match number of args in variadic type.",
683             0,
684         fprintf(stderr, "Call has %d params, method %s type %d\n",
685           get_Call_n_params(n), get_type_name(mt), get_method_n_params(mt));
686         );
687       }
688       else {
689         ASSERT_AND_RET(
690             get_Call_n_params(n) == get_method_n_params(mt),
691             "Number of args for Call doesn't match number of args in non variadic type.",
692             0);
693       }
694
695       for (i = 0; i < get_method_n_params(mt); i++) {
696         ASSERT_AND_RET_DBG(
697             get_irn_mode(get_Call_param(n, i)) == get_type_mode(get_method_param_type(mt, i)),
698             "Mode of arg for Call doesn't match mode of arg type.", 0,
699         show_call_param(n, mt);
700         );
701       }
702       break;
703
704     case iro_Add:
705       op1mode = get_irn_mode(in[1]);
706       op2mode = get_irn_mode(in[2]);
707       ASSERT_AND_RET_DBG(
708           (
709            /* common Add: BB x numP x numP --> numP */
710        (op1mode == mymode && op2mode == op1mode && mode_is_numP(mymode)) ||
711            /* Pointer Add: BB x ref x int --> ref */
712            (mode_is_reference(op1mode) && mode_is_int(op2mode) && op1mode == mymode) ||
713            /* Pointer Add: BB x int x ref --> ref */
714            (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode))
715       ),
716           "Add node", 0,
717       show_binop_failure(n, "/* common Add: BB x numP x numP --> numP */ |\n"
718                             "/* Pointer Add: BB x ref x int --> ref */   |\n"
719                                 "/* Pointer Add: BB x int x ref --> ref */");
720           );
721       if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
722         /* BB x ref x int --> ref or BB x int x ref --> ref */
723         op_is_symmetric = 0;
724       } else {
725         /* BB x num x num --> num or BB x ref x ref */
726         op_is_symmetric = 2;
727       }
728       break;
729
730     case iro_Sub:
731       op1mode = get_irn_mode(in[1]);
732       op2mode = get_irn_mode(in[2]);
733       ASSERT_AND_RET_DBG(
734           /* common Sub: BB x numP x numP --> numP */
735           ((mymode ==op1mode && mymode == op2mode && mode_is_numP(op1mode)) ||
736            /* Pointer Sub: BB x ref x int --> ref */
737            (op1mode == mymode && mode_is_int(op2mode) && mode_is_reference(mymode)) ||
738            /* Pointer Sub: BB x int x ref --> ref */
739            (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode)) ||
740            /* Pointer Sub: BB x ref x ref --> int */
741            (op1mode == op2mode && mode_is_reference(op2mode) && mode_is_int(mymode))),
742           "Sub node", 0,
743       show_binop_failure(n, "/* common Sub: BB x numP x numP --> numP */ |\n"
744                             "/* Pointer Sub: BB x ref x int --> ref */   |\n"
745                             "/* Pointer Sub: BB x int x ref --> ref */   |\n"
746                             "/* Pointer Sub: BB x ref x ref --> int */" );
747           );
748       if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
749         op_is_symmetric = 0;
750       } else {
751         op_is_symmetric = 2;
752       }
753       break;
754
755     case iro_Minus:
756       op1mode = get_irn_mode(in[1]);
757       ASSERT_AND_RET_DBG(
758           /* Minus: BB x float --> float */
759           op1mode == mymode && get_mode_sort(op1mode) == irms_float_number, "Minus node", 0,
760       show_unop_failure(n , "/* Minus: BB x float --> float */");
761           );
762       op_is_symmetric = 2;
763       break;
764
765     case iro_Mul:
766       op1mode = get_irn_mode(in[1]);
767       op2mode = get_irn_mode(in[2]);
768       ASSERT_AND_RET_DBG(
769           /* Mul: BB x int1 x int1 --> int2 */
770           ((mode_is_int(op1mode)   && op2mode == op1mode && mode_is_int(mymode)) ||
771        (mode_is_float(op1mode) && op2mode == op1mode && mymode == op1mode)),
772           "Mul node",0,
773       show_binop_failure(n, "/* Mul: BB x int1 x int1 --> int2 */");
774           );
775       op_is_symmetric = 2;
776       break;
777
778     case iro_Quot:
779       op1mode = get_irn_mode(in[1]);
780       op2mode = get_irn_mode(in[2]);
781       op3mode = get_irn_mode(in[3]);
782       ASSERT_AND_RET_DBG(
783           /* Quot: BB x M x float x float --> M x X x float */
784           op1mode == mode_M && op2mode == op3mode &&
785           get_mode_sort(op2mode) == irms_float_number &&
786           mymode == mode_T,
787           "Quot node",0,
788       show_binop_failure(n, "/* Quot: BB x M x float x float --> M x X x float */");
789           );
790       op_is_symmetric = 2;
791       break;
792
793     case iro_DivMod:
794       op1mode = get_irn_mode(in[1]);
795       op2mode = get_irn_mode(in[2]);
796       op3mode = get_irn_mode(in[3]);
797       ASSERT_AND_RET(
798           /* DivMod: BB x M x int x int --> M x X x int x int */
799           op1mode == mode_M &&
800           mode_is_int(op2mode) &&
801           op3mode == op2mode &&
802           mymode == mode_T,
803           "DivMod node", 0
804           );
805       op_is_symmetric = 1;
806       break;
807
808     case iro_Div:
809     case iro_Mod:
810       op1mode = get_irn_mode(in[1]);
811       op2mode = get_irn_mode(in[2]);
812       op3mode = get_irn_mode(in[3]);
813       ASSERT_AND_RET(
814           /* Div or Mod: BB x M x int x int --> M x X x int */
815           op1mode == mode_M &&
816           op2mode == op3mode &&
817           mode_is_int(op2mode) &&
818           mymode == mode_T,
819           "Div or Mod node", 0
820           );
821       op_is_symmetric = 1;
822       break;
823
824     case iro_Abs:
825       op1mode = get_irn_mode(in[1]);
826       ASSERT_AND_RET_DBG(
827     /* Abs: BB x num --> num */
828     op1mode == mymode &&
829     mode_is_num (op1mode),
830     "Abs node", 0,
831     show_unop_failure(n, "/* Abs: BB x num --> num */");
832       );
833       op_is_symmetric = 2;
834       break;
835
836     case iro_And:
837     case iro_Or:
838     case iro_Eor:
839       op1mode = get_irn_mode(in[1]);
840       op2mode = get_irn_mode(in[2]);
841       ASSERT_AND_RET_DBG(
842     /* And or Or or Eor: BB x int x int --> int */
843     mode_is_int(mymode) &&
844     op2mode == op1mode &&
845     mymode == op2mode,
846     "And, Or or Eor node", 0,
847     show_binop_failure(n, "/* And or Or or Eor: BB x int x int --> int */");
848       );
849       op_is_symmetric = 2;
850       break;
851
852     case iro_Not:
853       op1mode = get_irn_mode(in[1]);
854       ASSERT_AND_RET_DBG(
855     /* Not: BB x int --> int */
856     mode_is_int(mymode) &&
857     mymode == op1mode,
858     "Not node", 0,
859     show_unop_failure(n, "/* Not: BB x int --> int */");
860       );
861       op_is_symmetric = 2;
862       break;
863
864
865     case iro_Cmp:
866       op1mode = get_irn_mode(in[1]);
867       op2mode = get_irn_mode(in[2]);
868       ASSERT_AND_RET_DBG(
869     /* Cmp: BB x datab x datab --> b16 */
870     mode_is_data (op1mode) &&
871     op2mode == op1mode &&
872     mymode == mode_T,
873     "Cmp node", 0,
874     show_binop_failure(n, "/* Cmp: BB x datab x datab --> b16 */");
875       );
876       break;
877
878     case iro_Shl:
879     case iro_Shr:
880     case iro_Shrs:
881       op1mode = get_irn_mode(in[1]);
882       op2mode = get_irn_mode(in[2]);
883       ASSERT_AND_RET_DBG(
884     /* Shl, Shr or Shrs: BB x int x int_u --> int */
885     mode_is_int(op1mode) &&
886     mode_is_int(op2mode) &&
887     !mode_is_signed(op2mode) &&
888     mymode == op1mode,
889     "Shl, Shr, Shr or Rot node", 0,
890     show_binop_failure(n, "/* Shl, Shr or Shrs: BB x int x int_u --> int */");
891       );
892       break;
893
894     case iro_Rot:
895       op1mode = get_irn_mode(in[1]);
896       op2mode = get_irn_mode(in[2]);
897       ASSERT_AND_RET_DBG(
898     /* Rot: BB x int x int --> int */
899     mode_is_int(op1mode) &&
900     mode_is_int(op2mode) &&
901     mymode == op1mode,
902     "Rot node", 0,
903     show_binop_failure(n, "/* Rot: BB x int x int --> int */");
904       );
905       break;
906
907     case iro_Conv:
908       op1mode = get_irn_mode(in[1]);
909       ASSERT_AND_RET_DBG(
910     /* Conv: BB x datab1 --> datab2 */
911     mode_is_datab(op1mode) && mode_is_data(mymode),
912     "Conv node", 0,
913     show_unop_failure(n, "/* Conv: BB x datab1 --> datab2 */");
914       );
915       break;
916
917     case iro_Cast:
918       op1mode = get_irn_mode(in[1]);
919       ASSERT_AND_RET_DBG(
920     /* Conv: BB x datab1 --> datab2 */
921     mode_is_data(op1mode) && op1mode == mymode,
922     "Cast node", 0,
923     show_unop_failure(n, "/* Conv: BB x datab1 --> datab2 */");
924       );
925       break;
926
927     case iro_Phi:
928       /* Phi: BB x dataM^n --> dataM */
929       for (i = 1; i < get_irn_arity(n); i++) {
930         if (!is_Bad(in[i]) && (get_irn_op(in[i]) != op_Unknown))
931           ASSERT_AND_RET_DBG(
932           get_irn_mode(in[i]) == mymode,
933           "Phi node", 0,
934           show_phi_failure(n, in[i], i);
935       );
936       };
937       ASSERT_AND_RET( mode_is_dataM(mymode), "Phi node", 0 );
938       break;
939
940     case iro_Load:
941       op1mode = get_irn_mode(in[1]);
942       op2mode = get_irn_mode(in[2]);
943       ASSERT_AND_RET(
944           /* Load: BB x M x ref --> M x X x data */
945           op1mode == mode_M && mode_is_reference(op2mode),
946           "Load node", 0
947           );
948       ASSERT_AND_RET( mymode == mode_T, "Load node", 0 );
949       break;
950
951     case iro_Store:
952       op1mode = get_irn_mode(in[1]);
953       op2mode = get_irn_mode(in[2]);
954       op3mode = get_irn_mode(in[3]);
955       ASSERT_AND_RET(
956           /* Load: BB x M x ref data --> M x X */
957           op1mode == mode_M && mode_is_reference(op2mode) && mode_is_data(op3mode),
958           "Store node", 0
959           );
960       ASSERT_AND_RET(mymode == mode_T, "Store node", 0);
961       break;
962
963     case iro_Alloc:
964       op1mode = get_irn_mode(in[1]);
965       op2mode = get_irn_mode(in[2]);
966       ASSERT_AND_RET_DBG(
967     /* Alloc: BB x M x int_u --> M x X x ref */
968     op1mode == mode_M &&
969     mode_is_int(op2mode) &&
970     !mode_is_signed(op2mode) &&
971     mymode == mode_T,
972     "Alloc node", 0,
973     show_binop_failure(n, "/* Alloc: BB x M x int_u --> M x X x ref */");
974       );
975       break;
976
977     case iro_Free:
978       op1mode = get_irn_mode(in[1]);
979       op2mode = get_irn_mode(in[2]);
980       ASSERT_AND_RET_DBG(
981     /* Free: BB x M x ref --> M */
982     op1mode == mode_M && mode_is_reference(op2mode) &&
983     mymode == mode_M,
984     "Free node", 0,
985     show_binop_failure(n, "/* Free: BB x M x ref --> M */");
986       );
987       break;
988
989     case iro_Sync:
990       /* Sync: BB x M^n --> M */
991       for (i=1; i < get_irn_arity(n); i++) {
992         ASSERT_AND_RET( get_irn_mode(in[i]) == mode_M, "Sync node", 0 );
993       };
994       ASSERT_AND_RET( mymode == mode_M, "Sync node", 0 );
995       break;
996
997     case iro_Proj:
998       return vrfy_Proj_proj(n, irg);
999       break;
1000
1001     case iro_Confirm:
1002       op1mode = get_irn_mode(in[1]);
1003       op2mode = get_irn_mode(in[2]);
1004       ASSERT_AND_RET_DBG(
1005     /* Confirm: BB x T x T --> T */
1006     op1mode == mymode &&
1007     op2mode == mymode,
1008     "Confirm node", 0,
1009     show_binop_failure(n, "/* Confirm: BB x T x T --> T */");
1010       );
1011       break;
1012
1013     default:
1014       break;
1015   }
1016
1017   /* All went ok */
1018   return 1;
1019 }
1020
1021 int irn_vrfy(ir_node *n)
1022 {
1023   int res = 1;
1024 #ifdef DEBUG_libfirm
1025   res = irn_vrfy_irg(n, current_ir_graph);
1026 #endif
1027   return res;
1028 }
1029
1030 /*******************************************************************/
1031 /* Verify the whole graph.                                         */
1032 /*******************************************************************/
1033
1034 /* This *is* used, except gcc doesn't notice that */
1035 static void vrfy_wrap(ir_node *node, void *env)
1036 {
1037   int *res = env;
1038
1039   *res = irn_vrfy(node);
1040 }
1041
1042 int irg_vrfy(ir_graph *irg)
1043 {
1044   int res = 1;
1045 #ifdef DEBUG_libfirm
1046   ir_graph *rem;
1047
1048   rem = current_ir_graph;
1049   current_ir_graph = irg;
1050
1051   assert(get_irg_pinned(irg) == pinned);
1052
1053   irg_walk(irg->end, vrfy_wrap, NULL, &res);
1054
1055   current_ir_graph = rem;
1056
1057   if (opt_do_node_verification == NODE_VERIFICATION_REPORT && ! res) {
1058     entity *ent = get_irg_entity(current_ir_graph);
1059
1060     if (ent)
1061       fprintf(stderr, "irg_verify: Verifying graph %s failed\n", get_entity_name(ent));
1062     else
1063       fprintf(stderr, "irg_verify: Verifying graph %p failed\n", (void *)current_ir_graph);
1064   }
1065
1066 #endif
1067   return res;
1068 }
1069
1070 int irn_vrfy_irg_dump(ir_node *n, ir_graph *irg, const char **bad_string)
1071 {
1072   int res;
1073   node_verification_t old = opt_do_node_verification;
1074
1075   bad_msg = NULL;
1076   opt_do_node_verification = NODE_VERIFICATION_ERROR_ONLY;
1077   res = irn_vrfy_irg(n, irg);
1078   opt_do_node_verification = old;
1079   *bad_string = bad_msg;
1080
1081   return res;
1082 }