Bad and Unknown are pinned instructions yet, speeding up code placement
[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 # include "irdump.h"
22
23 #ifdef NDEBUG
24 /*
25  * in RELEASE mode, returns ret if the expression expr evaluates to zero
26  * in ASSERT mode, asserts the expression expr (and the string string).
27  */
28 #define ASSERT_AND_RET(expr, string, ret)       if (!(expr)) return (ret)
29
30 /*
31  * in RELEASE mode, returns ret if the expression expr evaluates to zero
32  * in ASSERT mode, executes blk if the expression expr evaluates to zero and asserts expr
33  */
34 #define ASSERT_AND_RET_DBG(expr, string, ret, blk)      if (!(expr)) return (ret)
35 #else
36 #define ASSERT_AND_RET(expr, string, ret) \
37 do { \
38   if (opt_do_node_verification == NODE_VERIFICATION_ON) {\
39     if (!(expr)) dump_ir_block_graph(current_ir_graph, "-assert"); \
40     assert((expr) && string); } \
41   if (!(expr)) { \
42     if (opt_do_node_verification == NODE_VERIFICATION_REPORT) \
43       fprintf(stderr, #expr " : " string "\n"); \
44     bad_msg = #expr " && " string; \
45     return (ret); \
46   } \
47 } while(0)
48
49 #define ASSERT_AND_RET_DBG(expr, string, ret, blk) \
50 do { \
51   if (!(expr)) { \
52     bad_msg = #expr " && " string; \
53     if (opt_do_node_verification != NODE_VERIFICATION_ERROR_ONLY) { blk; } \
54     if (opt_do_node_verification == NODE_VERIFICATION_REPORT) \
55       fprintf(stderr, #expr " : " string "\n"); \
56     else if (opt_do_node_verification == NODE_VERIFICATION_ON) \
57       assert((expr) && string); \
58     return (ret); \
59   } \
60 } while(0)
61
62 #endif
63
64 /* @@@ replace use of array "in" by access functions. */
65 ir_node **get_irn_in(ir_node *node);
66
67 static node_verification_t opt_do_node_verification = NODE_VERIFICATION_ON;
68 static const char *bad_msg;
69
70 /**
71  * little helper for NULL modes
72  */
73 static const char *get_mode_name_ex(ir_mode *mode)
74 {
75   if (! mode)
76     return "<no mode>";
77   return get_mode_name(mode);
78 }
79
80 void do_node_verification(node_verification_t mode)
81 {
82   opt_do_node_verification = mode;
83 }
84
85 /**
86  * Prints a failure for a Node
87  */
88 static void show_node_failure(ir_node *n)
89 {
90   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s\n" ,
91     get_irn_node_nr(n),
92     get_irn_opname(n), get_irn_modename(n)
93   );
94 }
95
96 /**
97  * Prints a failure message for a binop
98  */
99 static void show_binop_failure(ir_node *n, const char *text)
100 {
101   ir_node *left  = get_binop_left(n);
102   ir_node *right = get_binop_right(n);
103
104   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s(%s%s, %s%s) did not match (%s)\n",
105       get_irn_node_nr(n),
106       get_irn_opname(n), get_irn_modename(n),
107       get_irn_opname(left), get_irn_modename(left),
108       get_irn_opname(right), get_irn_modename(right),
109       text);
110 }
111
112 /**
113  * Prints a failure message for an unop
114  */
115 static void show_unop_failure(ir_node *n, const char *text)
116 {
117   ir_node *op  = get_unop_op(n);
118
119   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %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(op), get_irn_modename(op),
123       text);
124 }
125
126 /**
127  * Prints a failure message for a proj
128  */
129 static void show_proj_failure(ir_node *n)
130 {
131   ir_node *op  = get_Proj_pred(n);
132   int proj     = get_Proj_proj(n);
133
134   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s %d(%s%s) failed\n" ,
135       get_irn_node_nr(n),
136       get_irn_opname(n), get_irn_modename(n), proj,
137       get_irn_opname(op), get_irn_modename(op));
138 }
139
140 /**
141  * Prints a failure message for a proj
142  */
143 static void show_proj_failure_ent(ir_node *n, entity *ent)
144 {
145   ir_node *op  = get_Proj_pred(n);
146   int proj     = get_Proj_proj(n);
147   ir_mode *m   = get_type_mode(get_entity_type(ent));
148
149   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s %d(%s%s) entity %s(type %s mode %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       get_entity_name(ent), get_type_name(get_entity_type(ent)),
154       get_mode_name_ex(m));
155 }
156
157 /**
158  * Show a node and a graph
159  */
160 static void show_node_on_graph(ir_graph *irg, ir_node *n)
161 {
162   entity *ent = get_irg_entity(irg);
163
164   if (ent)
165     fprintf(stderr, "\nFIRM: irn_vrfy_irg() of entity %s, node %ld %s%s\n",
166       get_entity_name(ent),
167       get_irn_node_nr(n), get_irn_opname(n), get_irn_modename(n));
168   else
169     fprintf(stderr, "\nFIRM: irn_vrfy_irg() of graph %p, node %ld %s%s\n",
170       (void *)irg,
171       get_irn_node_nr(n), get_irn_opname(n), get_irn_modename(n));
172 }
173
174 /**
175  * Show call params
176  */
177 static void show_call_param(ir_node *n, type *mt)
178 {
179   int i;
180
181   fprintf(stderr, "\nFIRM: irn_vrfy_irg() Call type-check failed: %s(", get_type_name(mt));
182   for (i = 0; i < get_method_n_params(mt); ++i) {
183     fprintf(stderr, "%s ", get_mode_name_ex(get_type_mode(get_method_param_type(mt, i))));
184   }
185   fprintf(stderr, ") != CALL(");
186
187   for (i = 0; i < get_Call_n_params(n); ++i) {
188     fprintf(stderr, "%s ", get_mode_name_ex(get_irn_mode(get_Call_param(n, i))));
189   }
190   fprintf(stderr, ")\n");
191
192 }
193
194 /**
195  * Show return modes
196  */
197 static void show_return_modes(ir_graph *irg, ir_node *n, type *mt, int i)
198 {
199   entity *ent = get_irg_entity(irg);
200
201   fprintf(stderr, "\nFIRM: irn_vrfy_irg() Return node %ld in entity \"%s\" mode %s different from type mode %s\n",
202     get_irn_node_nr(n), get_entity_name(ent),
203     get_mode_name_ex(get_irn_mode(get_Return_res(n, i))),
204     get_mode_name_ex(get_type_mode(get_method_res_type(mt, i)))
205   );
206 }
207
208 /**
209  * Show return number of results
210  */
211 static void show_return_nres(ir_graph *irg, ir_node *n, type *mt)
212 {
213   entity *ent = get_irg_entity(irg);
214
215   fprintf(stderr, "\nFIRM: irn_vrfy_irg() Return node %ld in entity \"%s\" has %d results different from type %d\n",
216     get_irn_node_nr(n), get_entity_name(ent),
217     get_Return_n_ress(n), get_method_n_ress(mt));
218 }
219
220 /**
221  * Show Phi input
222  */
223 static void show_phi_failure(ir_node *phi, ir_node *pred, int pos)
224 {
225   fprintf(stderr, "\nFIRM: irn_vrfy_irg() Phi node %ld has mode %s different from predeccessor node %ld mode %s\n",
226     get_irn_node_nr(phi), get_mode_name_ex(get_irn_mode(phi)),
227     get_irn_node_nr(pred), get_mode_name_ex(get_irn_mode(pred)));
228 }
229
230 /**
231  * verify the Proj number
232  */
233 static int
234 vrfy_Proj_proj(ir_node *p, ir_graph *irg) {
235   ir_node *pred;
236   ir_mode *mode;
237   int proj;
238
239   pred = skip_Id(get_Proj_pred(p));
240   ASSERT_AND_RET(get_irn_mode(pred) == mode_T, "mode of a 'projed' node is not Tuple", 0);
241   mode = get_irn_mode(p);
242   proj = get_Proj_proj(p);
243
244   switch (get_irn_opcode(pred)) {
245     case iro_Start:
246       ASSERT_AND_RET_DBG(
247           (
248            (proj == pn_Start_X_initial_exec && mode == mode_X) ||
249            (proj == pn_Start_M         && mode == mode_M) ||
250            (proj == pn_Start_P_frame_base && mode_is_reference(mode)) ||
251            (proj == pn_Start_P_globals && mode_is_reference(mode)) ||
252            (proj == pn_Start_T_args    && mode == mode_T) ||
253            (proj == pn_Start_P_value_arg_base && mode_is_reference(mode)) ||
254            (proj == pn_Start_P_value_arg_base && mode == mode_T)    /* FIXME: only one of those */
255           ),
256           "wrong Proj from Start", 0,
257       show_proj_failure(p);
258       );
259       break;
260
261     case iro_Cond:
262       ASSERT_AND_RET_DBG(
263         (
264           (proj >= 0 && mode == mode_X && get_irn_mode(get_Cond_selector(pred)) == mode_b) ||   /* compare */
265           (mode == mode_X && mode_is_int(get_irn_mode(get_Cond_selector(pred))))                /* switch */
266         ),
267         "wrong Proj from Cond", 0,
268         show_proj_failure(p);
269       );
270       break;
271
272     case iro_Raise:
273       ASSERT_AND_RET_DBG(
274         ((proj == pn_Raise_X && mode == mode_X) || (proj == pn_Raise_M && mode == mode_M)),
275         "wrong Proj from Raise", 0,
276     show_proj_failure(p);
277       );
278       break;
279
280     case iro_InstOf:
281       ASSERT_AND_RET_DBG(
282     (proj >= 0 && mode == mode_X),
283     "wrong Proj from InstOf", 0,
284     show_proj_failure(p);
285       );
286       break;
287
288     case iro_Call:
289       ASSERT_AND_RET_DBG(
290         ((proj == pn_Call_M_regular        && mode == mode_M) ||
291          (proj == pn_Call_X_except         && mode == mode_X) ||
292          (proj == pn_Call_T_result         && mode == mode_T) ||
293          (proj == pn_Call_M_except         && mode == mode_M) ||
294      (proj == pn_Call_P_value_res_base && mode == mode_P)),
295         "wrong Proj from Call", 0,
296         show_proj_failure(p);
297       );
298       break;
299
300     case iro_FuncCall:
301       ASSERT_AND_RET_DBG(
302         ((proj == pn_Call_M_regular        && mode == mode_M) ||
303          (proj == pn_Call_X_except         && mode == mode_X) ||
304          (proj == pn_Call_T_result         && mode == mode_T) ||
305          (proj == pn_Call_M_except         && mode == mode_M) ||
306      (proj == pn_Call_P_value_res_base && mode == mode_P)),
307         "wrong Proj from FuncCall", 0,
308         show_proj_failure(p);
309       );
310       break;
311
312     case iro_Quot:
313       ASSERT_AND_RET_DBG(
314         ((proj == pn_Quot_M        && mode == mode_M) ||
315          (proj == pn_Quot_X_except && mode == mode_X) ||
316          (proj == pn_Quot_res      && mode_is_float(mode))),
317         "wrong Proj from Quot", 0,
318     show_proj_failure(p);
319       );
320       break;
321
322     case iro_DivMod:
323       ASSERT_AND_RET_DBG(
324         ((proj == pn_DivMod_M        && mode == mode_M) ||
325          (proj == pn_DivMod_X_except && mode == mode_X) ||
326          (proj == pn_DivMod_res_div  && mode_is_int(mode)) ||
327          (proj == pn_DivMod_res_mod  && mode_is_int(mode))),
328         "wrong Proj from DivMod", 0,
329     show_proj_failure(p);
330       );
331       break;
332
333     case iro_Div:
334       ASSERT_AND_RET_DBG(
335         ((proj == pn_Div_M        && mode == mode_M) ||
336          (proj == pn_Div_X_except && mode == mode_X) ||
337          (proj == pn_Div_res      && mode_is_int(mode))),
338         "wrong Proj from Div or Mod", 0,
339     show_proj_failure(p);
340       );
341       break;
342
343     case iro_Mod:
344       ASSERT_AND_RET_DBG(
345         ((proj == pn_Mod_M        && mode == mode_M) ||
346          (proj == pn_Mod_X_except && mode == mode_X) ||
347          (proj == pn_Mod_res      && mode_is_int(mode))),
348         "wrong Proj from Div or Mod", 0,
349     show_proj_failure(p);
350       );
351       break;
352
353     case iro_Cmp:
354       ASSERT_AND_RET_DBG(
355         (proj >= 0 && proj <= 15 && mode == mode_b),
356         "wrong Proj from Cmp", 0,
357     show_proj_failure(p);
358       );
359       break;
360
361     case iro_Load:
362       if (proj == pn_Load_res) {
363     ir_node *ptr = get_Load_ptr(pred);
364     entity *ent = NULL;
365     if (get_irn_op(ptr) == op_Sel) {
366       ent = get_Sel_entity(ptr);
367     } /*
368         We may not test this, after lowering and optimization the Const can
369         have an unexpected type.
370     else if ((get_irn_op(ptr) == op_Const) &&
371            tarval_is_entity(get_Const_tarval(ptr))) {
372       ent = get_tarval_entity(get_Const_tarval(ptr));
373     } */
374     if (ent) {
375       ASSERT_AND_RET_DBG(
376         (mode == get_type_mode(get_entity_type(ent))),
377         "wrong data Proj from Load, entity type_mode failed", 0,
378         show_proj_failure_ent(p, ent);
379       );
380     }
381     else {
382       ASSERT_AND_RET_DBG(
383         mode_is_data(mode),
384        "wrong data Proj from Load", 0,
385        show_proj_failure(p);
386      );
387     }
388       } else {
389     ASSERT_AND_RET_DBG(
390       ((proj == pn_Load_M        && mode == mode_M) ||
391        (proj == pn_Load_X_except && mode == mode_X)),
392           "wrong Proj from Load", 0,
393       show_proj_failure(p);
394     );
395       }
396       break;
397
398     case iro_Store:
399       ASSERT_AND_RET_DBG(
400         ((proj == pn_Store_M        && mode == mode_M) ||
401          (proj == pn_Store_X_except && mode == mode_X)),
402         "wrong Proj from Store", 0,
403     show_proj_failure(p);
404       );
405       break;
406
407     case iro_Alloc:
408       ASSERT_AND_RET_DBG(
409         (
410          (proj == pn_Alloc_M        && mode == mode_M) ||
411          (proj == pn_Alloc_X_except /* && mode == mode_X*/) ||
412          (proj == pn_Alloc_res      && mode_is_reference(mode))
413         ),
414         "wrong Proj from Alloc", 0,
415         show_proj_failure(p);
416       );
417       break;
418
419     case iro_Proj:
420       {
421         type *mt; /* A method type */
422         long nr = get_Proj_proj(pred);
423
424         pred = skip_Id(get_Proj_pred(pred));
425         ASSERT_AND_RET((get_irn_mode(pred) == mode_T), "Proj from something not a tuple", 0);
426         switch (get_irn_opcode(pred))
427         {
428           case iro_Start:
429             mt = get_entity_type(get_irg_entity(irg));
430
431         if (nr == pn_Start_T_args) {
432               ASSERT_AND_RET(
433                   (proj >= 0 && mode_is_data(mode)),
434                   "wrong Proj from Proj from Start", 0);
435               ASSERT_AND_RET(
436                 (proj < get_method_n_params(mt)),
437                 "More Projs for args than args in type", 0
438               );
439               if ((mode_is_reference(mode)) && is_compound_type(get_method_param_type(mt, proj)))
440                 /* value argument */ break;
441
442               ASSERT_AND_RET(
443                   (mode == get_type_mode(get_method_param_type(mt, proj))),
444                   "Mode of Proj from Start doesn't match mode of param type.", 0);
445             }
446         else if (nr == pn_Start_P_value_arg_base) {
447           ASSERT_AND_RET(
448                   (proj >= 0 && mode_is_reference(mode)),
449                   "wrong Proj from Proj from Start", 0
450               );
451               ASSERT_AND_RET(
452                 (proj < get_method_n_params(mt)),
453                 "More Projs for args than args in type", 0
454               );
455         }
456             break;
457
458           case iro_Call:
459             {
460               ASSERT_AND_RET(
461                   (proj >= 0 && mode_is_data(mode)),
462                   "wrong Proj from Proj from Call", 0);
463               mt = get_Call_type(pred);
464               ASSERT_AND_RET(
465                   (proj < get_method_n_ress(mt)),
466                   "More Projs for results than results in type.", 0);
467               if ((mode_is_reference(mode)) && is_compound_type(get_method_res_type(mt, proj)))
468                 /* value result */ break;
469
470               ASSERT_AND_RET(
471                   (mode == get_type_mode(get_method_res_type(mt, proj))),
472                   "Mode of Proj from Call doesn't match mode of result type.", 0);
473             }
474             break;
475
476           case iro_FuncCall:
477             {
478               ASSERT_AND_RET(
479                   (proj >= 0 && mode_is_data(mode)),
480                   "wrong Proj from Proj from FuncCall", 0);
481               mt = get_FuncCall_type(pred);
482               ASSERT_AND_RET(
483                   (proj < get_method_n_ress(mt)),
484                   "More Projs for results than results in type.", 0);
485               if ((mode_is_reference(mode)) && is_compound_type(get_method_res_type(mt, proj)))
486                 /* value result */ break;
487
488               ASSERT_AND_RET(
489                   (mode == get_type_mode(get_method_res_type(mt, proj))),
490                   "Mode of Proj from FuncCall doesn't match mode of result type.", 0);
491             }
492             break;
493
494           case iro_Tuple:
495             /* We don't test */
496             break;
497
498           default:
499             ASSERT_AND_RET(0, "Unknown opcode", 0);
500         }
501         break;
502
503       }
504     case iro_Tuple:
505       /* We don't test */
506       break;
507
508     case iro_CallBegin:
509       break;
510
511     case iro_EndReg:
512       break;
513
514     case iro_EndExcept:
515       break;
516
517     default:
518       ASSERT_AND_RET(0, "Unknown opcode", 0);
519   }
520
521   /* all went ok */
522   return 1;
523 }
524
525 int irn_vrfy_irg(ir_node *n, ir_graph *irg)
526 {
527   int i;
528   int opcode, opcode1;
529   ir_mode *mymode, *op1mode = NULL, *op2mode, *op3mode;
530   int op_is_symmetric = 1;  /*  0: asymmetric
531                                 1: operands have identical modes
532                                 2: modes of operands == mode of this node */
533   type *mt;                 /* A method type */
534   entity *ent;
535
536   ir_node **in;
537
538   if (!opt_do_node_verification) return 1;
539
540   if (! interprocedural_view) {
541     /*
542      * do NOT check placement in interprocedural view, as we don't always know
543      * the "right" graph ...
544      */
545     ASSERT_AND_RET_DBG(
546                        node_is_in_irgs_storage(irg, n),
547                        "Node is not stored on proper IR graph!", 0,
548                        show_node_on_graph(irg, n);
549                        );
550   }
551
552   opcode = get_irn_opcode(n);
553
554   /* We don't want to test nodes whose predecessors are Bad or Unknown,
555      as we would have to special case that for each operation. */
556   if (opcode != iro_Phi && opcode != iro_Block)
557     for (i = 0; i < get_irn_arity(n); i++) {
558       opcode1 = get_irn_opcode(get_irn_n(n, i));
559       if (opcode1 == iro_Bad /*|| opcode1 == iro_Unknown*/)  /* GL: for analyses mode must be correct. */
560         return 1;
561     }
562
563   mymode = get_irn_mode(n);
564   in = get_irn_in(n);
565
566   switch (opcode) {
567
568     case iro_Block:
569       for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
570         ir_node *pred =  get_Block_cfgpred(n, i);
571         ASSERT_AND_RET(
572                        (is_Bad(pred)     ||
573                         is_Unknown(pred) ||
574                         (get_irn_mode(pred) == mode_X)
575                         ), "Block node", 0);
576       }
577       /*  End block may only have Return, Raise or fragile ops as preds. */
578       if (n == get_irg_end_block(irg))
579         for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
580           ir_node *pred =  skip_Proj(get_Block_cfgpred(n, i));
581           if (is_Proj(pred) || get_irn_op(pred) == op_Tuple)
582             break;   /*  We can not test properly.  How many tuples are there? */
583           ASSERT_AND_RET(((get_irn_op(pred) == op_Return) ||
584                           is_Bad(pred)                    ||
585                           (get_irn_op(pred) == op_Raise)  ||
586                           is_fragile_op(pred)               ),
587                          "End Block node", 0);
588         }
589       /*  irg attr must == graph we are in. */
590       if (! interprocedural_view) {
591         ASSERT_AND_RET(((get_irn_irg(n) && get_irn_irg(n) == irg)), "Block node has wrong irg attribute", 0);
592       }
593
594       break;
595
596     case iro_Start:
597       ASSERT_AND_RET(
598                      /* Start: BB --> X x M x ref x data1 x ... x datan x ref */
599                      mymode == mode_T, "Start node", 0
600                      );
601       break;
602
603     case iro_Jmp:
604       ASSERT_AND_RET(
605                      /* Jmp: BB --> X */
606                      mymode == mode_X, "Jmp node", 0
607                      );
608       break;
609
610     case iro_Break:
611       ASSERT_AND_RET(
612                      /* Jmp: BB --> X */
613                      mymode == mode_X, "Jmp node", 0
614                      );
615       break;
616
617     case iro_Cond:
618       op1mode = get_irn_mode(in[1]);
619       ASSERT_AND_RET(
620                      /* Cond: BB x b --> X x X */
621                      (op1mode == mode_b ||
622                       /* Cond: BB x int --> X^n */
623                       mode_is_int(op1mode) ),  "Cond node", 0
624                      );
625       ASSERT_AND_RET(mymode == mode_T, "Cond mode is not a tuple", 0);
626       break;
627
628     case iro_Return:
629       op1mode = get_irn_mode(in[1]);
630       /* Return: BB x M x data1 x ... x datan --> X */
631       /* printf("mode: %s, code %s\n", ID_TO_STR(n->mode->name), ID_TO_STR(n->op->name));*/
632       ASSERT_AND_RET( op1mode == mode_M, "Return node", 0 );  /* operand M */
633       for (i = 2; i < get_irn_arity(n); i++) {
634         ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Return node", 0 );  /* operand datai */
635       };
636       ASSERT_AND_RET( mymode == mode_X, "Result X", 0 );   /* result X */
637       /* Compare returned results with result types of method type */
638       mt = get_entity_type(get_irg_entity(irg));
639       ASSERT_AND_RET_DBG( get_Return_n_ress(n) == get_method_n_ress(mt),
640         "Number of results for Return doesn't match number of results in type.", 0,
641       show_return_nres(irg, n, mt););
642       for (i = 0; i < get_Return_n_ress(n); i++) {
643     type *res_type = get_method_res_type(mt, i);
644
645         if (is_atomic_type(res_type)) {
646       ASSERT_AND_RET_DBG(
647         get_irn_mode(get_Return_res(n, i)) == get_type_mode(res_type),
648         "Mode of result for Return doesn't match mode of result type.", 0,
649         show_return_modes(irg, n, mt, i);
650       );
651     }
652     else {
653       ASSERT_AND_RET_DBG(
654         mode_is_reference(get_irn_mode(get_Return_res(n, i))),
655         "Mode of result for Return doesn't match mode of result type.", 0,
656         show_return_modes(irg, n, mt, i);
657       );
658     }
659       }
660       break;
661
662     case iro_Raise:
663       op1mode = get_irn_mode(in[1]);
664       op2mode = get_irn_mode(in[2]);
665       ASSERT_AND_RET(
666                      /* Sel: BB x M x ref --> X x M */
667                      op1mode == mode_M && mode_is_reference(op2mode) &&
668                      mymode == mode_T, "Raise node", 0
669                      );
670       break;
671
672     case iro_Const: {
673       ASSERT_AND_RET(
674                      /* Const: BB --> data */
675                      (mode_is_data (mymode) ||
676                       mymode == mode_b)      /* we want boolean constants for static evaluation */
677                      ,"Const node", 0        /* of Cmp. */
678                      );
679       } break;
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 1
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 && mode_is_float(op1mode), "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 }