verifier: Check that Div has a num mode, not a data mode.
[libfirm] / ir / ir / irverify.c
1 /*
2  * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief    Check irnodes for correctness.
23  * @author   Christian Schaefer, Goetz Lindenmaier, Till Riedel, Michael Beck
24  */
25 #include "config.h"
26
27 #include "irprog.h"
28 #include "irop_t.h"
29 #include "irgraph_t.h"
30 #include "irverify_t.h"
31 #include "irgwalk.h"
32 #include "irdump.h"
33 #include "irdom_t.h"
34 #include "irprintf.h"
35 #include "irouts.h"
36 #include "irflag_t.h"
37 #include "irpass_t.h"
38 #include "irnodeset.h"
39 #include "ircons.h"
40
41 const char *firm_verify_failure_msg;
42
43 #ifndef NDEBUG
44
45 /**
46  * little helper for NULL modes
47  */
48 static const char *get_mode_name_ex(ir_mode *mode)
49 {
50         if (! mode)
51                 return "<no mode>";
52         return get_mode_name(mode);
53 }
54
55 /** the last IRG, on which a verification error was found */
56 static ir_graph *last_irg_error = NULL;
57
58 /**
59  * print the name of the entity of an verification failure
60  *
61  * @param node  the node caused the failure
62  */
63 static void show_entity_failure(const ir_node *node)
64 {
65         ir_graph *irg = get_irn_irg(node);
66
67         if (last_irg_error == irg)
68                 return;
69
70         last_irg_error = irg;
71
72         if (irg == get_const_code_irg()) {
73                 fprintf(stderr, "\nFIRM: irn_verify_irg() <of CONST_CODE_IRG> failed\n");
74         } else {
75                 ir_entity *ent = get_irg_entity(irg);
76
77                 if (ent) {
78                         ir_type *ent_type = get_entity_owner(ent);
79
80                         if (ent_type) {
81                                 ir_fprintf(stderr, "\nFIRM: irn_verify_irg() %+F::%s failed\n",
82                                            ent_type, get_entity_name(ent));
83                         } else {
84                                 fprintf(stderr, "\nFIRM: irn_verify_irg() <NULL>::%s failed\n", get_entity_name(ent));
85                         }
86                 } else {
87                         fprintf(stderr, "\nFIRM: irn_verify_irg() <IRG %p> failed\n", (void *)irg);
88                 }
89         }
90 }
91
92 static const char *get_irn_modename(const ir_node *node)
93 {
94         ir_mode *mode = get_irn_mode(node);
95         return get_mode_name(mode);
96 }
97
98 /**
99  * Prints a failure for a Node
100  */
101 static void show_node_failure(const ir_node *n)
102 {
103         show_entity_failure(n);
104         fprintf(stderr, "  node %ld %s%s\n" ,
105                 get_irn_node_nr(n),
106                 get_irn_opname(n), get_irn_modename(n)
107         );
108 }
109
110 /**
111  * Prints a failure message for a binop
112  */
113 static void show_binop_failure(const ir_node *n, const char *text)
114 {
115         ir_node *left  = get_binop_left(n);
116         ir_node *right = get_binop_right(n);
117
118         show_entity_failure(n);
119         fprintf(stderr, "  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(const ir_node *n, const char *text)
131 {
132         ir_node *op  = get_unop_op(n);
133
134         show_entity_failure(n);
135         fprintf(stderr, "  node %ld %s%s(%s%s) did not match (%s)\n",
136                 get_irn_node_nr(n),
137                 get_irn_opname(n), get_irn_modename(n),
138                 get_irn_opname(op), get_irn_modename(op),
139                 text);
140 }
141
142 /**
143  * Prints a failure message for an op with 3 operands
144  */
145 static void show_triop_failure(const ir_node *n, const char *text)
146 {
147         ir_node *op0  = get_irn_n(n, 0);
148         ir_node *op1  = get_irn_n(n, 1);
149         ir_node *op2  = get_irn_n(n, 2);
150
151         show_entity_failure(n);
152         fprintf(stderr, "  of node %ld %s%s(%s%s, %s%s, %s%s) did not match (%s)\n",
153                 get_irn_node_nr(n),
154                 get_irn_opname(n), get_irn_modename(n),
155                 get_irn_opname(op0), get_irn_modename(op0),
156                 get_irn_opname(op1), get_irn_modename(op1),
157                 get_irn_opname(op2), get_irn_modename(op2),
158                 text);
159 }
160
161 /**
162  * Prints a failure message for a proj
163  */
164 static void show_proj_failure(const ir_node *n)
165 {
166         ir_node *op  = get_Proj_pred(n);
167         int proj     = get_Proj_proj(n);
168
169         show_entity_failure(n);
170         fprintf(stderr, "  node %ld %s%s %d(%s%s) failed\n" ,
171                 get_irn_node_nr(n),
172                 get_irn_opname(n), get_irn_modename(n), proj,
173                 get_irn_opname(op), get_irn_modename(op));
174 }
175
176 /**
177  * Prints a failure message for a proj from Start
178  */
179 static void show_proj_mode_failure(const ir_node *n, ir_type *ty)
180 {
181         long proj  = get_Proj_proj(n);
182         ir_mode *m = get_type_mode(ty);
183         char type_name[256];
184         ir_print_type(type_name, sizeof(type_name), ty);
185
186         show_entity_failure(n);
187         fprintf(stderr, "  Proj %ld mode %s proj %ld (type %s mode %s) failed\n" ,
188                 get_irn_node_nr(n),
189                 get_irn_modename(n),
190                 proj,
191                 type_name,
192                 get_mode_name_ex(m));
193 }
194
195 /**
196  * Show a node and a graph
197  */
198 static void show_node_on_graph(const ir_graph *irg, const ir_node *n)
199 {
200         ir_fprintf(stderr, "\nFIRM: irn_verify_irg() of %+F, node %+F\n", irg, n);
201 }
202
203 /**
204  * Show call parameters
205  */
206 static void show_call_param(const ir_node *n, ir_type *mt)
207 {
208         char type_name[256];
209         ir_print_type(type_name, sizeof(type_name), mt);
210
211         show_entity_failure(n);
212         fprintf(stderr, "  Call type-check failed: %s(", type_name);
213         size_t n_method_params = get_method_n_params(mt);
214         for (size_t i = 0; i < n_method_params; ++i) {
215                 fprintf(stderr, "%s ", get_mode_name_ex(get_type_mode(get_method_param_type(mt, i))));
216         }
217         fprintf(stderr, ") != CALL(");
218
219         int n_params = get_Call_n_params(n);
220         for (int i = 0; i < n_params; ++i) {
221                 fprintf(stderr, "%s ", get_mode_name_ex(get_irn_mode(get_Call_param(n, i))));
222         }
223         fprintf(stderr, ")\n");
224 }
225
226 /**
227  * Show return modes
228  */
229 static void show_return_modes(const ir_graph *irg, const ir_node *n,
230                               ir_type *mt, int i)
231 {
232         ir_entity *ent = get_irg_entity(irg);
233
234         show_entity_failure(n);
235         fprintf(stderr, "  Return node %ld in entity \"%s\" mode %s different from type mode %s\n",
236                 get_irn_node_nr(n), get_entity_name(ent),
237                 get_mode_name_ex(get_irn_mode(get_Return_res(n, i))),
238                 get_mode_name_ex(get_type_mode(get_method_res_type(mt, i)))
239         );
240 }
241
242 /**
243  * Show return number of results
244  */
245 static void show_return_nres(const ir_graph *irg, const ir_node *n, ir_type *mt)
246 {
247         ir_entity *ent = get_irg_entity(irg);
248
249         show_entity_failure(n);
250         fprintf(stderr, "  Return node %ld in entity \"%s\" has %lu results different from type %lu\n",
251                 get_irn_node_nr(n), get_entity_name(ent),
252                 (unsigned long) get_Return_n_ress(n),
253                 (unsigned long) get_method_n_ress(mt));
254 }
255
256 /**
257  * Show Phi input
258  */
259 static void show_phi_failure(const ir_node *phi, const ir_node *pred, int pos)
260 {
261         (void) pos;
262         show_entity_failure(phi);
263         fprintf(stderr, "  Phi node %ld has mode %s different from predeccessor node %ld mode %s\n",
264                 get_irn_node_nr(phi), get_mode_name_ex(get_irn_mode(phi)),
265                 get_irn_node_nr(pred), get_mode_name_ex(get_irn_mode(pred)));
266 }
267
268 /**
269  * Show Phi inputs
270  */
271 static void show_phi_inputs(const ir_node *phi, const ir_node *block)
272 {
273         show_entity_failure(phi);
274         fprintf(stderr, "  Phi node %ld has %d inputs, its Block %ld has %d\n",
275                 get_irn_node_nr(phi),   get_irn_arity(phi),
276                 get_irn_node_nr(block), get_irn_arity(block));
277 }
278
279 #endif /* #ifndef NDEBUG */
280
281 /**
282  * verify a Proj(Start) node
283  */
284 static int verify_node_Proj_Start(const ir_node *p)
285 {
286         ir_mode *mode = get_irn_mode(p);
287         long proj     = get_Proj_proj(p);
288
289         ASSERT_AND_RET_DBG(
290                 (
291                         (proj == pn_Start_X_initial_exec && mode == mode_X) ||
292                         (proj == pn_Start_M              && mode == mode_M) ||
293                         (proj == pn_Start_P_frame_base   && mode_is_reference(mode)) ||
294                         (proj == pn_Start_T_args         && mode == mode_T)
295                 ),
296                 "wrong Proj from Start", 0,
297                 show_proj_failure(p);
298         );
299         return 1;
300 }
301
302 /**
303  * verify a Proj(Cond) node
304  */
305 static int verify_node_Proj_Cond(const ir_node *p)
306 {
307         ir_mode *mode = get_irn_mode(p);
308         long     proj = get_Proj_proj(p);
309
310         ASSERT_AND_RET_DBG(
311                 mode == mode_X && (proj == pn_Cond_false || proj == pn_Cond_true),
312                 "wrong Proj from Cond", 0,
313                 show_proj_failure(p);
314         );
315         return 1;
316 }
317
318 static int verify_node_Proj_Switch(const ir_node *p)
319 {
320         ir_mode *mode = get_irn_mode(p);
321         long     pn   = get_Proj_proj(p);
322         ir_node *pred = get_Proj_pred(p);
323         ASSERT_AND_RET_DBG(
324                 mode == mode_X && (pn >= 0 && pn < (long)get_Switch_n_outs(pred)),
325                 "wrong Proj from Switch", 0,
326                 show_proj_failure(p);
327         );
328         return 1;
329 }
330
331 /**
332  * verify a Proj(Raise) node
333  */
334 static int verify_node_Proj_Raise(const ir_node *p)
335 {
336         ir_mode *mode = get_irn_mode(p);
337         long proj     = get_Proj_proj(p);
338
339         ASSERT_AND_RET_DBG(
340                 ((proj == pn_Raise_X && mode == mode_X) || (proj == pn_Raise_M && mode == mode_M)),
341                 "wrong Proj from Raise", 0,
342                 show_proj_failure(p);
343         );
344         return 1;
345 }
346
347 /**
348  * verify a Proj(InstOf) node
349  */
350 static int verify_node_Proj_InstOf(const ir_node *p)
351 {
352         ir_mode *mode = get_irn_mode(p);
353         long proj     = get_Proj_proj(p);
354
355         ASSERT_AND_RET_DBG(
356                 (
357                         (proj == pn_InstOf_M         && mode == mode_M) ||
358                         (proj == pn_InstOf_X_regular && mode == mode_X) ||
359                         (proj == pn_InstOf_X_except  && mode == mode_X) ||
360                         (proj == pn_InstOf_res       && mode_is_reference(mode))
361                 ),
362                 "wrong Proj from InstOf", 0,
363                 show_proj_failure(p);
364         );
365         return 1;
366 }
367
368 /**
369  * verify a Proj(Call) node
370  */
371 static int verify_node_Proj_Call(const ir_node *p)
372 {
373         ir_mode *mode = get_irn_mode(p);
374         ir_node *n    = get_Proj_pred(p);
375         long proj     = get_Proj_proj(p);
376
377         ASSERT_AND_RET_DBG(
378                 (
379                         (proj == pn_Call_M                && mode == mode_M) ||
380                         (proj == pn_Call_X_regular        && mode == mode_X) ||
381                         (proj == pn_Call_X_except         && mode == mode_X) ||
382                         (proj == pn_Call_T_result         && mode == mode_T)
383                 ),
384                 "wrong Proj from Call", 0,
385                 show_proj_failure(p);
386         );
387         /* if we have exception flow, we must have a real Memory input */
388         if (proj == pn_Call_X_regular)
389                 ASSERT_AND_RET(
390                         !is_NoMem(get_Call_mem(n)),
391                         "Regular Proj from FunctionCall", 0);
392         else if (proj == pn_Call_X_except)
393                 ASSERT_AND_RET(
394                         !is_NoMem(get_Call_mem(n)),
395                         "Exception Proj from FunctionCall", 0);
396         return 1;
397 }
398
399 /**
400  * verify a Proj(Div) node
401  */
402 static int verify_node_Proj_Div(const ir_node *p)
403 {
404         ir_mode *mode = get_irn_mode(p);
405         ir_node *n    = get_Proj_pred(p);
406         long proj     = get_Proj_proj(p);
407
408         ASSERT_AND_RET_DBG(
409                 (
410                         (proj == pn_Div_M         && mode == mode_M) ||
411                         (proj == pn_Div_X_regular && mode == mode_X) ||
412                         (proj == pn_Div_X_except  && mode == mode_X) ||
413                         (proj == pn_Div_res       && mode_is_data(mode) && mode == get_Div_resmode(n))
414                 ),
415                 "wrong Proj from Div", 0,
416                 show_proj_failure(p);
417         );
418         if (proj == pn_Div_X_regular)
419                 ASSERT_AND_RET(
420                         get_irn_pinned(n) == op_pin_state_pinned,
421                         "Regular Proj from unpinned Div", 0);
422         else if (proj == pn_Div_X_except)
423                 ASSERT_AND_RET(
424                         get_irn_pinned(n) == op_pin_state_pinned,
425                         "Exception Proj from unpinned Div", 0);
426         else if (proj == pn_Div_M)
427                 ASSERT_AND_RET(
428                         get_irn_pinned(n) == op_pin_state_pinned,
429                         "Memory Proj from unpinned Div", 0);
430         return 1;
431 }
432
433 /**
434  * verify a Proj(Mod) node
435  */
436 static int verify_node_Proj_Mod(const ir_node *p)
437 {
438         ir_mode *mode = get_irn_mode(p);
439         ir_node *n    = get_Proj_pred(p);
440         long proj     = get_Proj_proj(p);
441
442         ASSERT_AND_RET_DBG(
443                 (
444                         (proj == pn_Mod_M         && mode == mode_M) ||
445                         (proj == pn_Mod_X_regular && mode == mode_X) ||
446                         (proj == pn_Mod_X_except  && mode == mode_X) ||
447                         (proj == pn_Mod_res       && mode == get_Mod_resmode(n))
448                 ),
449                 "wrong Proj from Mod", 0,
450                 show_proj_failure(p);
451         );
452         if (proj == pn_Mod_X_regular)
453                 ASSERT_AND_RET(
454                         get_irn_pinned(n) == op_pin_state_pinned,
455                         "Regular Proj from unpinned Mod", 0);
456         else if (proj == pn_Mod_X_except)
457                 ASSERT_AND_RET(
458                         get_irn_pinned(n) == op_pin_state_pinned,
459                         "Exception Proj from unpinned Mod", 0);
460         else if (proj == pn_Mod_M)
461                 ASSERT_AND_RET(
462                         get_irn_pinned(n) == op_pin_state_pinned,
463                         "Memory Proj from unpinned Div", 0);
464         return 1;
465 }
466
467 /**
468  * verify a Proj(Load) node
469  */
470 static int verify_node_Proj_Load(const ir_node *p)
471 {
472         ir_mode *mode = get_irn_mode(p);
473         ir_node *n    = get_Proj_pred(p);
474         long proj     = get_Proj_proj(p);
475
476         if (proj == pn_Load_res) {
477                 ASSERT_AND_RET_DBG(
478                         mode_is_data(mode) && mode == get_Load_mode(n),
479                         "wrong data Proj from Load", 0,
480                         show_proj_failure(p);
481                 );
482         } else {
483                 ASSERT_AND_RET_DBG(
484                         (
485                                 (proj == pn_Load_M         && mode == mode_M) ||
486                                 (proj == pn_Load_X_regular && mode == mode_X) ||
487                                 (proj == pn_Load_X_except  && mode == mode_X)
488                         ),
489                         "wrong Proj from Load", 0,
490                         show_proj_failure(p);
491                 );
492         }
493         if (proj == pn_Load_X_regular) {
494                 ASSERT_AND_RET(
495                         get_irn_pinned(n) == op_pin_state_pinned,
496                         "Regular Proj from unpinned Load", 0);
497         } else if (proj == pn_Load_X_except) {
498                 ASSERT_AND_RET(
499                         get_irn_pinned(n) == op_pin_state_pinned,
500                         "Exception Proj from unpinned Load", 0);
501         }
502         return 1;
503 }
504
505 /**
506  * verify a Proj(Store) node
507  */
508 static int verify_node_Proj_Store(const ir_node *p)
509 {
510         ir_mode *mode = get_irn_mode(p);
511         ir_node *n    = get_Proj_pred(p);
512         long proj     = get_Proj_proj(p);
513
514         ASSERT_AND_RET_DBG(
515                 (
516                         (proj == pn_Store_M         && mode == mode_M) ||
517                         (proj == pn_Store_X_regular && mode == mode_X) ||
518                         (proj == pn_Store_X_except  && mode == mode_X)
519                 ),
520                 "wrong Proj from Store", 0,
521                 show_proj_failure(p);
522         );
523         if (proj == pn_Store_X_regular) {
524                 ASSERT_AND_RET(
525                         get_irn_pinned(n) == op_pin_state_pinned,
526                         "Regular Proj from unpinned Store", 0);
527         } else if (proj == pn_Store_X_except) {
528                 ASSERT_AND_RET(
529                         get_irn_pinned(n) == op_pin_state_pinned,
530                         "Exception Proj from unpinned Store", 0);
531         }
532         return 1;
533 }
534
535 /**
536  * verify a Proj(Alloc) node
537  */
538 static int verify_node_Proj_Alloc(const ir_node *p)
539 {
540         ir_mode *mode = get_irn_mode(p);
541         long proj     = get_Proj_proj(p);
542
543         ASSERT_AND_RET_DBG(
544                 (
545                         (proj == pn_Alloc_M         && mode == mode_M) ||
546                         (proj == pn_Alloc_X_regular && mode == mode_X) ||
547                         (proj == pn_Alloc_X_except  && mode == mode_X) ||
548                         (proj == pn_Alloc_res       && mode_is_reference(mode))
549                 ),
550                 "wrong Proj from Alloc", 0,
551                 show_proj_failure(p);
552         );
553         return 1;
554 }
555
556 /**
557  * verify a Proj(Proj) node
558  */
559 static int verify_node_Proj_Proj(const ir_node *p)
560 {
561         ir_mode *mode = get_irn_mode(p);
562         ir_node *pred = get_Proj_pred(p);
563         long proj     = get_Proj_proj(p);
564         long nr       = get_Proj_proj(pred);
565         ir_type *mt; /* A method type */
566
567         pred = skip_Id(get_Proj_pred(pred));
568         ASSERT_AND_RET((get_irn_mode(pred) == mode_T), "Proj from something not a tuple", 0);
569
570         switch (get_irn_opcode(pred)) {
571         case iro_Start:
572                 mt = get_entity_type(get_irg_entity(get_irn_irg(pred)));
573
574                 if (nr == pn_Start_T_args) {
575                         ASSERT_AND_RET(
576                                 (proj >= 0 && mode_is_datab(mode)),
577                                 "wrong Proj from Proj from Start", 0);
578                         ASSERT_AND_RET(
579                                 (proj < (int)get_method_n_params(mt)),
580                                 "More Projs for args than args in type", 0
581                                 );
582                         if ((mode_is_reference(mode)) && is_compound_type(get_method_param_type(mt, proj)))
583                                 /* value argument */ break;
584
585                         if (!irg_is_constrained(get_irn_irg(pred), IR_GRAPH_CONSTRAINT_BACKEND)) {
586                                 ASSERT_AND_RET_DBG(
587                                                 (mode == get_type_mode(get_method_param_type(mt, proj))),
588                                                 "Mode of Proj from Start doesn't match mode of param type.", 0,
589                                                 show_proj_mode_failure(p, get_method_param_type(mt, proj));
590                                                 );
591                         }
592                 }
593                 break;
594
595         case iro_Call:
596                 {
597                         ASSERT_AND_RET(
598                                 (proj >= 0 && mode_is_datab(mode)),
599                                 "wrong Proj from Proj from Call", 0);
600                         mt = get_Call_type(pred);
601                         ASSERT_AND_RET(is_unknown_type(mt) || is_Method_type(mt),
602                                         "wrong call type on call", 0);
603                         ASSERT_AND_RET(
604                                 (proj < (int)get_method_n_ress(mt)),
605                                 "More Projs for results than results in type.", 0);
606                         if ((mode_is_reference(mode)) && is_compound_type(get_method_res_type(mt, proj)))
607                                 /* value result */ break;
608
609                                 ASSERT_AND_RET(
610                                 (mode == get_type_mode(get_method_res_type(mt, proj))),
611                                 "Mode of Proj from Call doesn't match mode of result type.", 0);
612                 }
613                 break;
614
615         case iro_Tuple:
616                 /* We don't test */
617                 break;
618
619         default:
620                 /* ASSERT_AND_RET(0, "Unknown opcode", 0); */
621                 break;
622         }
623         return 1;
624 }
625
626 /**
627  * verify a Proj(Tuple) node
628  */
629 static int verify_node_Proj_Tuple(const ir_node *p)
630 {
631         (void) p;
632         /* We don't test */
633         return 1;
634 }
635
636 /**
637  * verify a Proj(CopyB) node
638  */
639 static int verify_node_Proj_CopyB(const ir_node *p)
640 {
641         ir_mode *mode = get_irn_mode(p);
642         ir_node *n    = get_Proj_pred(p);
643         long proj     = get_Proj_proj(p);
644
645         ASSERT_AND_RET_DBG(
646                 (
647                         (proj == pn_CopyB_M         && mode == mode_M) ||
648                         (proj == pn_CopyB_X_regular && mode == mode_X) ||
649                         (proj == pn_CopyB_X_except  && mode == mode_X)
650                 ),
651                 "wrong Proj from CopyB", 0,
652                 show_proj_failure(p);
653         );
654         if (proj == pn_CopyB_X_regular)
655                 ASSERT_AND_RET(
656                         get_irn_pinned(n) == op_pin_state_pinned,
657                         "Regular Proj from unpinned CopyB", 0);
658         else if (proj == pn_CopyB_X_except)
659                 ASSERT_AND_RET(
660                         get_irn_pinned(n) == op_pin_state_pinned,
661                         "Exception Proj from unpinned CopyB", 0);
662         return 1;
663 }
664
665 /**
666  * verify a Proj(Bound) node
667  */
668 static int verify_node_Proj_Bound(const ir_node *p)
669 {
670         ir_mode *mode = get_irn_mode(p);
671         ir_node *n    = get_Proj_pred(p);
672         long proj     = get_Proj_proj(p);
673
674         ASSERT_AND_RET_DBG(
675                 (
676                         (proj == pn_Bound_M         && mode == mode_M) ||
677                         (proj == pn_Bound_X_regular && mode == mode_X) ||
678                         (proj == pn_Bound_X_except  && mode == mode_X) ||
679                         (proj == pn_Bound_res       && mode == get_irn_mode(get_Bound_index(n)))
680                 ),
681                 "wrong Proj from Bound", 0,
682                 show_proj_failure(p);
683         );
684         return 1;
685 }
686
687 static int verify_node_Proj_fragile(const ir_node *node)
688 {
689         ir_node *pred             = get_Proj_pred(node);
690         int      throws_exception = ir_throws_exception(pred);
691         ASSERT_AND_RET((!is_x_except_Proj(node) || throws_exception)
692             && (!is_x_regular_Proj(node) || throws_exception),
693             "X_except und X_regular Proj only allowed when throws_exception is set",
694             0);
695         return 1;
696 }
697
698 /**
699  * verify a Proj node
700  */
701 static int verify_node_Proj(const ir_node *p)
702 {
703         ir_graph *irg = get_irn_irg(p);
704         ir_node *pred;
705         ir_op *op;
706
707         pred = skip_Id(get_Proj_pred(p));
708         ASSERT_AND_RET(get_irn_mode(pred) == mode_T, "mode of a 'projed' node is not Tuple", 0);
709         ASSERT_AND_RET(get_irg_pinned(irg) == op_pin_state_floats || get_nodes_block(pred) == get_nodes_block(p), "Proj must be in same block as its predecessor", 0);
710
711         if (is_fragile_op(pred)) {
712                 int res = verify_node_Proj_fragile(p);
713                 if (res != 1)
714                         return res;
715         }
716
717         op = get_irn_op(pred);
718         if (op->ops.verify_proj_node)
719                 return op->ops.verify_proj_node(p);
720
721         /* all went ok */
722         return 1;
723 }
724
725 /**
726  * verify a Block node
727  */
728 static int verify_node_Block(const ir_node *n)
729 {
730         ir_graph *irg = get_irn_irg(n);
731         int i;
732
733         for (i = get_Block_n_cfgpreds(n) - 1; i >= 0; --i) {
734                 ir_node *pred         = get_Block_cfgpred(n, i);
735                 ir_node *skipped_pred = skip_Proj(skip_Tuple(pred));
736                 ASSERT_AND_RET(get_irn_mode(pred) == mode_X,
737                         "Block node must have a mode_X predecessor", 0);
738                 ASSERT_AND_RET(is_cfop(skipped_pred) || is_Bad(skipped_pred), "Block predecessor must be a cfop (or Bad)", 0);
739         }
740
741         if (n == get_irg_start_block(irg)) {
742                 ASSERT_AND_RET(get_Block_n_cfgpreds(n) == 0, "Start Block node", 0);
743         }
744
745         if (n == get_irg_end_block(irg) && !irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
746                 /* End block may only have Return, Raise or fragile ops as preds. */
747                 for (i = get_Block_n_cfgpreds(n) - 1; i >= 0; --i) {
748                         ir_node *pred =  skip_Proj(get_Block_cfgpred(n, i));
749                         if (is_Proj(pred) || is_Tuple(pred))
750                                 break;   /*  We can not test properly.  How many tuples are there? */
751                         ASSERT_AND_RET(
752                                 (
753                                         is_Return(pred) ||
754                                         is_Bad(pred)    ||
755                                         is_Raise(pred)  ||
756                                         is_fragile_op(pred)
757                                 ),
758                                 "End Block node", 0);
759                 }
760         }
761         /*  irg attr must == graph we are in. */
762         ASSERT_AND_RET(((get_irn_irg(n) && get_irn_irg(n) == irg)), "Block node has wrong irg attribute", 0);
763         return 1;
764 }
765
766 /**
767  * verify a Start node
768  */
769 static int verify_node_Start(const ir_node *n)
770 {
771         ir_mode *mymode = get_irn_mode(n);
772
773         ASSERT_AND_RET(
774                 /* Start: BB --> X x M x ref x data1 x ... x datan x ref */
775                 mymode == mode_T, "Start node", 0
776                 );
777         return 1;
778 }
779
780 /**
781  * verify a Jmp node
782  */
783 static int verify_node_Jmp(const ir_node *n)
784 {
785         ir_mode *mymode = get_irn_mode(n);
786
787         ASSERT_AND_RET(
788                 /* Jmp: BB --> X */
789                 mymode == mode_X, "Jmp node", 0
790         );
791         return 1;
792 }
793
794 /**
795  * verify an IJmp node
796  */
797 static int verify_node_IJmp(const ir_node *n)
798 {
799         ir_mode *mymode  = get_irn_mode(n);
800         ir_mode *op1mode = get_irn_mode(get_IJmp_target(n));
801
802         ASSERT_AND_RET(
803                 /* IJmp: BB x ref --> X */
804                 mymode == mode_X && mode_is_reference(op1mode), "IJmp node", 0
805         );
806         return 1;
807 }
808
809 /**
810  * verify a Cond node
811  */
812 static int verify_node_Cond(const ir_node *n)
813 {
814         ir_mode *mymode  = get_irn_mode(n);
815         ir_mode *op1mode = get_irn_mode(get_Cond_selector(n));
816
817         ASSERT_AND_RET(op1mode == mode_b, "Cond operand not mode_b", 0);
818         ASSERT_AND_RET(mymode == mode_T, "Cond mode is not a tuple", 0);
819         return 1;
820 }
821
822 static int verify_switch_table(const ir_node *n)
823 {
824         const ir_switch_table *table     = get_Switch_table(n);
825         unsigned               n_outs    = get_Switch_n_outs(n);
826         ir_node               *selector  = get_Switch_selector(n);
827         ir_mode               *mode      = get_irn_mode(selector);
828         size_t                 n_entries;
829         size_t                 e;
830
831         ASSERT_AND_RET(table != NULL, "switch table is NULL", 0);
832
833         n_entries = ir_switch_table_get_n_entries(table);
834         for (e = 0; e < n_entries; ++e) {
835                 const ir_switch_table_entry *entry
836                         = ir_switch_table_get_entry_const(table, e);
837                 if (entry->pn == 0)
838                         continue;
839                 ASSERT_AND_RET(entry->min != NULL && entry->max != NULL,
840                                "switch table entry without min+max value", 0);
841                 ASSERT_AND_RET(get_tarval_mode(entry->min) == mode &&
842                                get_tarval_mode(entry->max) == mode,
843                                "switch table entry with wrong modes", 0);
844                 ASSERT_AND_RET(tarval_cmp(entry->min, entry->max) != ir_relation_greater,
845                                "switch table entry without min+max value", 0);
846                 ASSERT_AND_RET(entry->pn >= 0 && entry->pn < (long)n_outs,
847                                            "switch table entry with invalid proj number", 0);
848         }
849         return 1;
850 }
851
852 static int verify_node_Switch(const ir_node *n)
853 {
854         ir_mode *mymode  = get_irn_mode(n);
855         ir_mode *op1mode = get_irn_mode(get_Switch_selector(n));
856         if (!verify_switch_table(n))
857                 return 0;
858
859         ASSERT_AND_RET(mode_is_int(op1mode), "Switch operand not integer", 0);
860         ASSERT_AND_RET(mymode == mode_T, "Switch mode is not a tuple", 0);
861         return 1;
862 }
863
864 /**
865  * verify a Return node
866  */
867 static int verify_node_Return(const ir_node *n)
868 {
869         ir_graph *irg      = get_irn_irg(n);
870         ir_mode  *mymode   = get_irn_mode(n);
871         ir_mode  *mem_mode = get_irn_mode(get_Return_mem(n));
872         ir_type  *mt;
873         int       i;
874
875         /* Return: BB x M x data1 x ... x datan --> X */
876
877         ASSERT_AND_RET( mem_mode == mode_M, "Return node", 0 );  /* operand M */
878
879         for (i = get_Return_n_ress(n) - 1; i >= 0; --i) {
880                 ASSERT_AND_RET( mode_is_datab(get_irn_mode(get_Return_res(n, i))), "Return node", 0 );  /* operand datai */
881         }
882         ASSERT_AND_RET( mymode == mode_X, "Result X", 0 );   /* result X */
883         /* Compare returned results with result types of method type */
884         mt = get_entity_type(get_irg_entity(irg));
885         ASSERT_AND_RET_DBG(get_Return_n_ress(n) == get_method_n_ress(mt),
886                 "Number of results for Return doesn't match number of results in type.", 0,
887                 show_return_nres(irg, n, mt););
888         for (i = get_Return_n_ress(n) - 1; i >= 0; --i) {
889                 ir_type *res_type = get_method_res_type(mt, i);
890
891                 if (irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
892                         if (is_atomic_type(res_type)) {
893                                 ASSERT_AND_RET_DBG(
894                                         get_irn_mode(get_Return_res(n, i)) == get_type_mode(res_type),
895                                         "Mode of result for Return doesn't match mode of result type.", 0,
896                                         show_return_modes(irg, n, mt, i);
897                                 );
898                         } else {
899                                 ASSERT_AND_RET_DBG(
900                                         mode_is_reference(get_irn_mode(get_Return_res(n, i))),
901                                         "Mode of result for Return doesn't match mode of result type.", 0,
902                                         show_return_modes(irg, n, mt, i);
903                                 );
904                         }
905                 }
906         }
907         return 1;
908 }
909
910 /**
911  * verify a Raise node
912  */
913 static int verify_node_Raise(const ir_node *n)
914 {
915         ir_mode *mymode  = get_irn_mode(n);
916         ir_mode *op1mode = get_irn_mode(get_Raise_mem(n));
917         ir_mode *op2mode = get_irn_mode(get_Raise_exo_ptr(n));
918
919         ASSERT_AND_RET(
920                 /* Sel: BB x M x ref --> X x M */
921                 op1mode == mode_M && mode_is_reference(op2mode) &&
922                 mymode == mode_T, "Raise node", 0
923         );
924         return 1;
925 }
926
927 /**
928  * verify a Const node
929  */
930 static int verify_node_Const(const ir_node *n)
931 {
932         ir_mode *mymode = get_irn_mode(n);
933
934         ASSERT_AND_RET(
935                 /* Const: BB --> data */
936                 (mode_is_data(mymode) ||
937                 mymode == mode_b)      /* we want boolean constants for static evaluation */
938                 ,"Const node", 0       /* of Cmp. */
939         );
940         ASSERT_AND_RET(
941                 /* the modes of the constant and teh tarval must match */
942                 mymode == get_tarval_mode(get_Const_tarval(n)),
943                 "Const node, tarval and node mode mismatch", 0
944         );
945         return 1;
946 }
947
948 /**
949  * verify a SymConst node
950  */
951 static int verify_node_SymConst(const ir_node *n)
952 {
953         ir_mode *mymode = get_irn_mode(n);
954
955         ASSERT_AND_RET(
956                 /* SymConst: BB --> int*/
957                 (mode_is_int(mymode) ||
958                 /* SymConst: BB --> ref */
959                 mode_is_reference(mymode))
960                 ,"SymConst node", 0);
961         return 1;
962 }
963
964 /**
965  * verify a Sel node
966  */
967 static int verify_node_Sel(const ir_node *n)
968 {
969         int i;
970         ir_mode *mymode  = get_irn_mode(n);
971         ir_mode *op1mode = get_irn_mode(get_Sel_mem(n));
972         ir_mode *op2mode = get_irn_mode(get_Sel_ptr(n));
973         ir_entity *ent;
974
975         ASSERT_AND_RET_DBG(
976                 /* Sel: BB x M x ref x int^n --> ref */
977                 (op1mode == mode_M && op2mode == mymode && mode_is_reference(mymode)),
978                 "Sel node", 0, show_node_failure(n);
979         );
980
981         for (i = get_Sel_n_indexs(n) - 1; i >= 0; --i) {
982                 ASSERT_AND_RET_DBG(mode_is_int(get_irn_mode(get_Sel_index(n, i))), "Sel node", 0, show_node_failure(n););
983         }
984         ent = get_Sel_entity(n);
985         ASSERT_AND_RET_DBG(ent, "Sel node with empty entity", 0, show_node_failure(n););
986         return 1;
987 }
988
989 /**
990  * verify an InstOf node
991  */
992 static int verify_node_InstOf(const ir_node *n)
993 {
994         ir_mode *mymode  = get_irn_mode(n);
995         ir_mode *op1mode = get_irn_mode(get_InstOf_obj(n));
996
997         ASSERT_AND_RET(mode_T == mymode, "mode of Instof is not a tuple", 0);
998         ASSERT_AND_RET(mode_is_data(op1mode), "Instof not on data", 0);
999         return 1;
1000 }
1001
1002 /**
1003  * Check if the pinned state is right.
1004  */
1005 static int verify_right_pinned(const ir_node *n)
1006 {
1007         ir_node *mem;
1008
1009         if (get_irn_pinned(n) == op_pin_state_pinned)
1010                 return 1;
1011         mem = get_Call_mem(n);
1012
1013         /* if it's not pinned, its memory predecessor must be NoMem or Pin */
1014         if (is_NoMem(mem) || is_Pin(mem))
1015                 return 1;
1016         return 0;
1017 }
1018
1019 /**
1020  * verify a Call node
1021  */
1022 static int verify_node_Call(const ir_node *n)
1023 {
1024         ir_graph *irg     = get_irn_irg(n);
1025         ir_mode  *mymode  = get_irn_mode(n);
1026         ir_mode  *op1mode = get_irn_mode(get_Call_mem(n));
1027         ir_mode  *op2mode = get_irn_mode(get_Call_ptr(n));
1028         ir_type  *mt;
1029         size_t    i;
1030         size_t    n_params;
1031
1032         /* Call: BB x M x ref x data1 x ... x datan
1033         --> M x datan+1 x ... x data n+m */
1034         ASSERT_AND_RET( op1mode == mode_M && mode_is_reference(op2mode), "Call node", 0 );  /* operand M x ref */
1035
1036         /* NoMem nodes are only allowed as memory input if the Call is NOT pinned */
1037         ASSERT_AND_RET(verify_right_pinned(n),"Call node with wrong memory input", 0 );
1038
1039         mt = get_Call_type(n);
1040         if (get_unknown_type() == mt) {
1041                 return 1;
1042         }
1043
1044         n_params = get_Call_n_params(n);
1045         for (i = 0; i < n_params; ++i) {
1046                 ASSERT_AND_RET( mode_is_datab(get_irn_mode(get_Call_param(n, i))), "Call node", 0 );  /* operand datai */
1047         }
1048
1049         ASSERT_AND_RET( mymode == mode_T, "Call result not a tuple", 0 );   /* result T */
1050         /* Compare arguments of node with those of type */
1051
1052         if (get_method_variadicity(mt) == variadicity_variadic) {
1053                 ASSERT_AND_RET_DBG(
1054                         (size_t)get_Call_n_params(n) >= get_method_n_params(mt),
1055                         "Number of args for Call doesn't match number of args in variadic type.",
1056                         0,
1057                         ir_fprintf(stderr, "Call %+F has %d params, type %d\n",
1058                         n, get_Call_n_params(n), get_method_n_params(mt));
1059                 );
1060         } else {
1061                 ASSERT_AND_RET_DBG(
1062                         (size_t)get_Call_n_params(n) == get_method_n_params(mt),
1063                         "Number of args for Call doesn't match number of args in non variadic type.",
1064                         0,
1065                         ir_fprintf(stderr, "Call %+F has %d params, type %d\n",
1066                         n, get_Call_n_params(n), get_method_n_params(mt));
1067                 );
1068         }
1069
1070         for (i = 0; i < get_method_n_params(mt); i++) {
1071                 ir_type *t = get_method_param_type(mt, i);
1072
1073                 if (irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
1074                         if (is_atomic_type(t)) {
1075                                 ASSERT_AND_RET_DBG(
1076                                         get_irn_mode(get_Call_param(n, i)) == get_type_mode(t),
1077                                         "Mode of arg for Call doesn't match mode of arg type.", 0,
1078                                         show_call_param(n, mt);
1079                                 );
1080                         } else {
1081                                 /* call with a compound type, mode must be reference */
1082                                 ASSERT_AND_RET_DBG(
1083                                         mode_is_reference(get_irn_mode(get_Call_param(n, i))),
1084                                         "Mode of arg for Call doesn't match mode of arg type.", 0,
1085                                         show_call_param(n, mt);
1086                                 );
1087                         }
1088                 }
1089         }
1090
1091         return 1;
1092 }
1093
1094 /**
1095  * verify an Add node
1096  */
1097 static int verify_node_Add(const ir_node *n)
1098 {
1099         ir_mode *mymode  = get_irn_mode(n);
1100         ir_mode *op1mode = get_irn_mode(get_Add_left(n));
1101         ir_mode *op2mode = get_irn_mode(get_Add_right(n));
1102
1103         ASSERT_AND_RET_DBG(
1104                 (
1105                         /* common Add: BB x numP x numP --> numP */
1106                         (op1mode == mymode && op2mode == op1mode && mode_is_data(mymode)) ||
1107                         /* Pointer Add: BB x ref x int --> ref */
1108                         (mode_is_reference(op1mode) && mode_is_int(op2mode) && op1mode == mymode) ||
1109                         /* Pointer Add: BB x int x ref --> ref */
1110                         (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode))
1111                 ),
1112                 "Add node", 0,
1113                 show_binop_failure(n, "/* common Add: BB x numP x numP --> numP */ |\n"
1114                         "/* Pointer Add: BB x ref x int --> ref */   |\n"
1115                         "/* Pointer Add: BB x int x ref --> ref */");
1116         );
1117         return 1;
1118 }
1119
1120 /**
1121  * verify a Sub node
1122  */
1123 static int verify_node_Sub(const ir_node *n)
1124 {
1125         ir_mode *mymode  = get_irn_mode(n);
1126         ir_mode *op1mode = get_irn_mode(get_Sub_left(n));
1127         ir_mode *op2mode = get_irn_mode(get_Sub_right(n));
1128
1129         ASSERT_AND_RET_DBG(
1130                 (
1131                         /* common Sub: BB x numP x numP --> numP */
1132                         (mymode ==op1mode && mymode == op2mode && mode_is_data(op1mode)) ||
1133                         /* Pointer Sub: BB x ref x int --> ref */
1134                         (op1mode == mymode && mode_is_int(op2mode) && mode_is_reference(mymode)) ||
1135                         /* Pointer Sub: BB x ref x ref --> int */
1136                         (op1mode == op2mode && mode_is_reference(op2mode) && mode_is_int(mymode))
1137                 ),
1138                 "Sub node", 0,
1139                 show_binop_failure(n, "/* common Sub: BB x numP x numP --> numP */ |\n"
1140                         "/* Pointer Sub: BB x ref x int --> ref */   |\n"
1141                         "/* Pointer Sub: BB x ref x ref --> int */" );
1142                 );
1143         return 1;
1144 }
1145
1146 /**
1147  * verify a Minus node
1148  */
1149 static int verify_node_Minus(const ir_node *n)
1150 {
1151         ir_mode *mymode  = get_irn_mode(n);
1152         ir_mode *op1mode = get_irn_mode(get_Minus_op(n));
1153
1154         ASSERT_AND_RET_DBG(
1155                 /* Minus: BB x num --> num */
1156                 op1mode == mymode && mode_is_num(op1mode), "Minus node", 0,
1157                 show_unop_failure(n , "/* Minus: BB x num --> num */");
1158         );
1159         return 1;
1160 }
1161
1162 /**
1163  * verify a Mul node
1164  */
1165 static int verify_node_Mul(const ir_node *n)
1166 {
1167         ir_mode *mymode  = get_irn_mode(n);
1168         ir_mode *op1mode = get_irn_mode(get_Mul_left(n));
1169         ir_mode *op2mode = get_irn_mode(get_Mul_right(n));
1170
1171         ASSERT_AND_RET_DBG(
1172                 (
1173                         /* Mul: BB x int_n x int_n --> int_n|int_2n */
1174                         (mode_is_int(op1mode)   && op2mode == op1mode && mode_is_int(mymode) &&
1175                          (op1mode == mymode || get_mode_size_bits(op1mode) * 2 == get_mode_size_bits(mymode))) ||
1176                         /* Mul: BB x float x float --> float */
1177                         (mode_is_float(op1mode) && op2mode == op1mode && mymode == op1mode)
1178                 ),
1179                 "Mul node",0,
1180                 show_binop_failure(n, "/* Mul: BB x int_n x int_n --> int_n|int_2n */ |\n"
1181                 "/* Mul: BB x float x float --> float */");
1182         );
1183         return 1;
1184 }
1185
1186 /**
1187  * verify a Mulh node
1188  */
1189 static int verify_node_Mulh(const ir_node *n)
1190 {
1191         ir_mode *mymode  = get_irn_mode(n);
1192         ir_mode *op1mode = get_irn_mode(get_Mulh_left(n));
1193         ir_mode *op2mode = get_irn_mode(get_Mulh_right(n));
1194
1195         ASSERT_AND_RET_DBG(
1196                 (
1197                         /* Mulh: BB x int x int --> int */
1198                         (mode_is_int(op1mode) && op2mode == op1mode && op1mode == mymode)
1199                 ),
1200                 "Mulh node",0,
1201                 show_binop_failure(n, "/* Mulh: BB x int x int --> int */");
1202         );
1203         return 1;
1204 }
1205
1206 /**
1207  * verify a Div node
1208  */
1209 static int verify_node_Div(const ir_node *n)
1210 {
1211         ir_mode *mymode  = get_irn_mode(n);
1212         ir_mode *op1mode = get_irn_mode(get_Div_mem(n));
1213         ir_mode *op2mode = get_irn_mode(get_Div_left(n));
1214         ir_mode *op3mode = get_irn_mode(get_Div_right(n));
1215
1216         ASSERT_AND_RET(
1217                 /* Div: BB x M x num x num --> M x X x num */
1218                 op1mode == mode_M &&
1219                 op2mode == op3mode &&
1220                 mode_is_num(op2mode) &&
1221                 mymode == mode_T,
1222                 "Div node", 0
1223                 );
1224         return 1;
1225 }
1226
1227 /**
1228  * verify a Mod node
1229  */
1230 static int verify_node_Mod(const ir_node *n)
1231 {
1232         ir_mode *mymode  = get_irn_mode(n);
1233         ir_mode *op1mode = get_irn_mode(get_Mod_mem(n));
1234         ir_mode *op2mode = get_irn_mode(get_Mod_left(n));
1235         ir_mode *op3mode = get_irn_mode(get_Mod_right(n));
1236
1237         ASSERT_AND_RET(
1238                 /* Mod: BB x M x int x int --> M x X x int */
1239                 op1mode == mode_M &&
1240                 op2mode == op3mode &&
1241                 mode_is_int(op2mode) &&
1242                 mymode == mode_T,
1243                 "Mod node", 0
1244                 );
1245         return 1;
1246 }
1247
1248 /**
1249  * verify a logical And, Or, Eor node
1250  */
1251 static int verify_node_Logic(const ir_node *n)
1252 {
1253         ir_mode *mymode  = get_irn_mode(n);
1254         ir_mode *op1mode = get_irn_mode(get_binop_left(n));
1255         ir_mode *op2mode = get_irn_mode(get_binop_right(n));
1256
1257         ASSERT_AND_RET_DBG(
1258                 /* And or Or or Eor: BB x int x int --> int */
1259                 (mode_is_int(mymode) || mode_is_reference(mymode) || mymode == mode_b) &&
1260                 op2mode == op1mode &&
1261                 mymode == op2mode,
1262                 "And, Or or Eor node", 0,
1263                 show_binop_failure(n, "/* And or Or or Eor: BB x int x int --> int */");
1264         );
1265         return 1;
1266 }
1267
1268 static int verify_node_And(const ir_node *n)
1269 {
1270         return verify_node_Logic(n);
1271 }
1272
1273 static int verify_node_Or(const ir_node *n)
1274 {
1275         return verify_node_Logic(n);
1276 }
1277
1278 static int verify_node_Eor(const ir_node *n)
1279 {
1280         return verify_node_Logic(n);
1281 }
1282
1283 /**
1284  * verify a Not node
1285  */
1286 static int verify_node_Not(const ir_node *n)
1287 {
1288         ir_mode *mymode  = get_irn_mode(n);
1289         ir_mode *op1mode = get_irn_mode(get_Not_op(n));
1290
1291         ASSERT_AND_RET_DBG(
1292                 /* Not: BB x int --> int */
1293                 (mode_is_int(mymode) || mymode == mode_b) &&
1294                 mymode == op1mode,
1295                 "Not node", 0,
1296                 show_unop_failure(n, "/* Not: BB x int --> int */");
1297         );
1298         return 1;
1299 }
1300
1301 /**
1302  * verify a Cmp node
1303  */
1304 static int verify_node_Cmp(const ir_node *n)
1305 {
1306         ir_mode *mymode  = get_irn_mode(n);
1307         ir_mode *op1mode = get_irn_mode(get_Cmp_left(n));
1308         ir_mode *op2mode = get_irn_mode(get_Cmp_right(n));
1309
1310         ASSERT_AND_RET_DBG(
1311                 /* Cmp: BB x datab x datab --> b16 */
1312                 mode_is_datab(op1mode) &&
1313                 op2mode == op1mode &&
1314                 mymode == mode_b,
1315                 "Cmp node", 0,
1316                 show_binop_failure(n, "/* Cmp: BB x datab x datab --> b16 */");
1317         );
1318         return 1;
1319 }
1320
1321 /**
1322  * verify a Shift node
1323  */
1324 static int verify_node_Shift(const ir_node *n)
1325 {
1326         ir_mode *mymode  = get_irn_mode(n);
1327         ir_mode *op1mode = get_irn_mode(get_binop_left(n));
1328         ir_mode *op2mode = get_irn_mode(get_binop_right(n));
1329
1330         ASSERT_AND_RET_DBG(
1331                 /* Shl, Shr or Shrs: BB x int x int_u --> int */
1332                 mode_is_int(op1mode) &&
1333                 mode_is_int(op2mode) &&
1334                 !mode_is_signed(op2mode) &&
1335                 mymode == op1mode,
1336                 "Shl, Shr or Shrs node", 0,
1337                 show_binop_failure(n, "/* Shl, Shr or Shrs: BB x int x int_u --> int */");
1338         );
1339         return 1;
1340 }
1341
1342 static int verify_node_Shl(const ir_node *n)
1343 {
1344         return verify_node_Shift(n);
1345 }
1346
1347 static int verify_node_Shr(const ir_node *n)
1348 {
1349         return verify_node_Shift(n);
1350 }
1351
1352 static int verify_node_Shrs(const ir_node *n)
1353 {
1354         return verify_node_Shift(n);
1355 }
1356
1357 /**
1358  * verify a Rotl node
1359  */
1360 static int verify_node_Rotl(const ir_node *n)
1361 {
1362         ir_mode *mymode  = get_irn_mode(n);
1363         ir_mode *op1mode = get_irn_mode(get_Rotl_left(n));
1364         ir_mode *op2mode = get_irn_mode(get_Rotl_right(n));
1365
1366         ASSERT_AND_RET_DBG(
1367                 /* Rotl: BB x int x int --> int */
1368                 mode_is_int(op1mode) &&
1369                 mode_is_int(op2mode) &&
1370                 mymode == op1mode,
1371                 "Rotl node", 0,
1372                 show_binop_failure(n, "/* Rotl: BB x int x int --> int */");
1373         );
1374         return 1;
1375 }
1376
1377 /**
1378  * verify a Conv node
1379  */
1380 static int verify_node_Conv(const ir_node *n)
1381 {
1382         ir_mode *mymode  = get_irn_mode(n);
1383         ir_mode *op1mode = get_irn_mode(get_Conv_op(n));
1384
1385         ASSERT_AND_RET_DBG(mode_is_data(op1mode) && mode_is_data(mymode),
1386                 "Conv node", 0,
1387                 show_unop_failure(n, "/* Conv: BB x data --> data */");
1388         );
1389         return 1;
1390 }
1391
1392 /**
1393  * verify a Cast node
1394  */
1395 static int verify_node_Cast(const ir_node *n)
1396 {
1397         ir_mode *mymode  = get_irn_mode(n);
1398         ir_mode *op1mode = get_irn_mode(get_Cast_op(n));
1399
1400         ASSERT_AND_RET_DBG(
1401                 /* Conv: BB x datab1 --> datab2 */
1402                 mode_is_data(op1mode) && op1mode == mymode,
1403                 "Cast node", 0,
1404                 show_unop_failure(n, "/* Conv: BB x datab1 --> datab2 */");
1405         );
1406         return 1;
1407 }
1408
1409 /**
1410  * verify a Phi node
1411  */
1412 static int verify_node_Phi(const ir_node *n)
1413 {
1414         ir_mode *mymode = get_irn_mode(n);
1415         ir_node *block  = get_nodes_block(n);
1416         int i;
1417
1418         /* a Phi node MUST have the same number of inputs as its block
1419          * Exception is a phi with 0 inputs which is used when (re)constructing the
1420          * SSA form */
1421         if (! is_Bad(block)
1422             && !irg_is_constrained(get_irn_irg(n), IR_GRAPH_CONSTRAINT_CONSTRUCTION)
1423             && get_irn_arity(n) > 0) {
1424                 ASSERT_AND_RET_DBG(
1425                         get_irn_arity(n) == get_irn_arity(block),
1426                         "wrong number of inputs in Phi node", 0,
1427                         show_phi_inputs(n, block);
1428                 );
1429         }
1430
1431         /* Phi: BB x dataM^n --> dataM */
1432         for (i = get_Phi_n_preds(n) - 1; i >= 0; --i) {
1433                 ir_node *pred = get_Phi_pred(n, i);
1434                 ASSERT_AND_RET_DBG(get_irn_mode(pred) == mymode,
1435                                    "Phi node", 0, show_phi_failure(n, pred, i);
1436                 );
1437         }
1438         ASSERT_AND_RET(mode_is_dataM(mymode) || mymode == mode_b, "Phi node", 0 );
1439
1440         return 1;
1441 }
1442
1443 /**
1444  * verify a Load node
1445  */
1446 static int verify_node_Load(const ir_node *n)
1447 {
1448         ir_graph *irg     = get_irn_irg(n);
1449         ir_mode  *mymode  = get_irn_mode(n);
1450         ir_mode  *op1mode = get_irn_mode(get_Load_mem(n));
1451         ir_mode  *op2mode = get_irn_mode(get_Load_ptr(n));
1452
1453         ASSERT_AND_RET(op1mode == mode_M, "Load node", 0);
1454         if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
1455                 ASSERT_AND_RET(mode_is_reference(op2mode), "Load node", 0 );
1456         }
1457         ASSERT_AND_RET( mymode == mode_T, "Load node", 0 );
1458
1459         return 1;
1460 }
1461
1462 /**
1463  * verify a Store node
1464  */
1465 static int verify_node_Store(const ir_node *n)
1466 {
1467         ir_graph  *irg = get_irn_irg(n);
1468
1469         ir_mode *mymode  = get_irn_mode(n);
1470         ir_mode *op1mode = get_irn_mode(get_Store_mem(n));
1471         ir_mode *op2mode = get_irn_mode(get_Store_ptr(n));
1472         ir_mode *op3mode = get_irn_mode(get_Store_value(n));
1473
1474         ASSERT_AND_RET(op1mode == mode_M && mode_is_datab(op3mode), "Store node", 0 );
1475         if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
1476                 ASSERT_AND_RET(mode_is_reference(op2mode), "Store node", 0 );
1477         }
1478         ASSERT_AND_RET(mymode == mode_T, "Store node", 0);
1479
1480         return 1;
1481 }
1482
1483 /**
1484  * verify an Alloc node
1485  */
1486 static int verify_node_Alloc(const ir_node *n)
1487 {
1488         ir_mode *mymode  = get_irn_mode(n);
1489         ir_mode *op1mode = get_irn_mode(get_Alloc_mem(n));
1490         ir_mode *op2mode = get_irn_mode(get_Alloc_count(n));
1491
1492         ASSERT_AND_RET_DBG(
1493                 /* Alloc: BB x M x int_u --> M x X x ref */
1494                 op1mode == mode_M &&
1495                 mode_is_int(op2mode) &&
1496                 !mode_is_signed(op2mode) &&
1497                 mymode == mode_T,
1498                 "Alloc node", 0,
1499                 show_node_failure(n);
1500         );
1501         return 1;
1502 }
1503
1504 /**
1505  * verify a Free node
1506  */
1507 static int verify_node_Free(const ir_node *n)
1508 {
1509         ir_mode *mymode  = get_irn_mode(n);
1510         ir_mode *op1mode = get_irn_mode(get_Free_mem(n));
1511         ir_mode *op2mode = get_irn_mode(get_Free_ptr(n));
1512         ir_mode *op3mode = get_irn_mode(get_Free_count(n));
1513
1514         ASSERT_AND_RET_DBG(
1515                 /* Free: BB x M x ref x int_u --> M */
1516                 op1mode == mode_M && mode_is_reference(op2mode) &&
1517                 mode_is_int(op3mode) &&
1518                 !mode_is_signed(op3mode) &&
1519                 mymode == mode_M,
1520                 "Free node", 0,
1521                 show_triop_failure(n, "/* Free: BB x M x ref x int_u --> M */");
1522         );
1523         return 1;
1524 }
1525
1526 /**
1527  * verify a Sync node
1528  */
1529 static int verify_node_Sync(const ir_node *n)
1530 {
1531         int i;
1532         ir_mode *mymode  = get_irn_mode(n);
1533
1534         /* Sync: BB x M^n --> M */
1535         for (i = get_Sync_n_preds(n) - 1; i >= 0; --i) {
1536                 ASSERT_AND_RET( get_irn_mode(get_Sync_pred(n, i)) == mode_M, "Sync node", 0 );
1537         }
1538         ASSERT_AND_RET( mymode == mode_M, "Sync node", 0 );
1539         return 1;
1540 }
1541
1542 /**
1543  * verify a Confirm node
1544  */
1545 static int verify_node_Confirm(const ir_node *n)
1546 {
1547         ir_mode *mymode  = get_irn_mode(n);
1548         ir_mode *op1mode = get_irn_mode(get_Confirm_value(n));
1549         ir_mode *op2mode = get_irn_mode(get_Confirm_bound(n));
1550
1551         ASSERT_AND_RET_DBG(
1552                 /* Confirm: BB x T x T --> T */
1553                 op1mode == mymode &&
1554                 op2mode == mymode,
1555                 "Confirm node", 0,
1556                 show_binop_failure(n, "/* Confirm: BB x T x T --> T */");
1557         );
1558         return 1;
1559 }
1560
1561 /**
1562  * verify a Mux node
1563  */
1564 static int verify_node_Mux(const ir_node *n)
1565 {
1566         ir_mode *mymode  = get_irn_mode(n);
1567         ir_mode *op1mode = get_irn_mode(get_Mux_sel(n));
1568         ir_mode *op2mode = get_irn_mode(get_Mux_true(n));
1569         ir_mode *op3mode = get_irn_mode(get_Mux_false(n));
1570
1571         ASSERT_AND_RET(
1572                 /* Mux: BB x b x datab x datab --> datab */
1573                 op1mode == mode_b &&
1574                 op2mode == mymode &&
1575                 op3mode == mymode &&
1576                 mode_is_datab(mymode),
1577                 "Mux node", 0
1578                 );
1579         return 1;
1580 }
1581
1582 /**
1583  * verify a CopyB node
1584  */
1585 static int verify_node_CopyB(const ir_node *n)
1586 {
1587         ir_graph *irg     = get_irn_irg(n);
1588         ir_mode  *mymode  = get_irn_mode(n);
1589         ir_mode  *op1mode = get_irn_mode(get_CopyB_mem(n));
1590         ir_mode  *op2mode = get_irn_mode(get_CopyB_dst(n));
1591         ir_mode  *op3mode = get_irn_mode(get_CopyB_src(n));
1592         ir_type  *t = get_CopyB_type(n);
1593
1594         /* CopyB: BB x M x ref x ref --> M x X */
1595         ASSERT_AND_RET(mymode == mode_T && op1mode == mode_M, "CopyB node", 0);
1596         if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
1597                 ASSERT_AND_RET(mode_is_reference(op2mode) && mode_is_reference(op3mode),
1598                         "CopyB node", 0 );
1599         }
1600
1601         ASSERT_AND_RET(
1602                 is_compound_type(t) || is_Array_type(t),
1603                 "CopyB node should copy compound types only", 0 );
1604
1605         /* NoMem nodes are only allowed as memory input if the CopyB is NOT pinned.
1606            This should happen RARELY, as CopyB COPIES MEMORY */
1607         ASSERT_AND_RET(verify_right_pinned(n), "CopyB node with wrong memory input", 0 );
1608         return 1;
1609 }
1610
1611 /**
1612  * verify a Bound node
1613  */
1614 static int verify_node_Bound(const ir_node *n)
1615 {
1616         ir_mode *mymode  = get_irn_mode(n);
1617         ir_mode *op1mode = get_irn_mode(get_Bound_mem(n));
1618         ir_mode *op2mode = get_irn_mode(get_Bound_index(n));
1619         ir_mode *op3mode = get_irn_mode(get_Bound_lower(n));
1620         ir_mode *op4mode = get_irn_mode(get_Bound_upper(n));
1621
1622         /* Bound: BB x M x int x int x int --> M x X */
1623         ASSERT_AND_RET(
1624                 mymode == mode_T &&
1625                 op1mode == mode_M &&
1626                 op2mode == op3mode &&
1627                 op3mode == op4mode &&
1628                 mode_is_int(op3mode),
1629                 "Bound node", 0 );
1630         return 1;
1631 }
1632
1633 /**
1634  * Check dominance.
1635  * For each usage of a node, it is checked, if the block of the
1636  * node dominates the block of the usage (for phis: the predecessor
1637  * block of the phi for the corresponding edge).
1638  *
1639  * @return non-zero on success, 0 on dominance error
1640  */
1641 static int check_dominance_for_node(const ir_node *use)
1642 {
1643         /* This won't work for blocks and the end node */
1644         if (!is_Block(use) && !is_End(use) && !is_Anchor(use)) {
1645                 int i;
1646                 ir_node *bl = get_nodes_block(use);
1647
1648                 for (i = get_irn_arity(use) - 1; i >= 0; --i) {
1649                         ir_node  *def    = get_irn_n(use, i);
1650                         ir_node  *def_bl = get_nodes_block(def);
1651                         ir_node  *use_bl = bl;
1652                         ir_graph *irg;
1653
1654                         /* we have no dominance relation for unreachable blocks, so we can't
1655                          * check the dominance property there */
1656                         if (!is_Block(def_bl) || get_Block_dom_depth(def_bl) == -1)
1657                                 continue;
1658
1659                         if (is_Phi(use)) {
1660                                 if (is_Bad(def))
1661                                         continue;
1662                                 use_bl = get_Block_cfgpred_block(bl, i);
1663                         }
1664
1665                         if (!is_Block(use_bl) || get_Block_dom_depth(use_bl) == -1)
1666                                 continue;
1667
1668                         irg = get_irn_irg(use);
1669                         ASSERT_AND_RET_DBG(
1670                                 block_dominates(def_bl, use_bl),
1671                                 "the definition of a value used violates the dominance property", 0,
1672                                 ir_fprintf(stderr,
1673                                 "graph %+F: %+F of %+F must dominate %+F of user %+F input %d\n",
1674                                 irg, def_bl, def, use_bl, use, i
1675                                 );
1676                         );
1677                 }
1678         }
1679         return 1;
1680 }
1681
1682 int irn_verify_irg(const ir_node *n, ir_graph *irg)
1683 {
1684         ir_op *op;
1685
1686         if (!get_node_verification_mode())
1687                 return 1;
1688
1689         /*
1690          * do NOT check placement in interprocedural view, as we don't always
1691          * know the "right" graph ...
1692          */
1693
1694 #ifndef NDEBUG
1695         /* this is an expensive check for large graphs (it has a quadratic
1696          * runtime but with a small constant); so do NOT run it in release mode
1697          */
1698         ASSERT_AND_RET_DBG(
1699                 node_is_in_irgs_storage(irg, n),
1700                 "Node is not stored on proper IR graph!", 0,
1701                 show_node_on_graph(irg, n);
1702         );
1703 #endif
1704         assert(get_irn_irg(n) == irg);
1705         {
1706                 unsigned idx           = get_irn_idx(n);
1707                 ir_node *node_from_map = get_idx_irn(irg, idx);
1708                 ASSERT_AND_RET_DBG(node_from_map == n, "Node index and index map entry differ", 0,
1709                         ir_printf("node %+F node in map %+F(%p)\n", n, node_from_map, node_from_map);
1710                 );
1711         }
1712
1713         op = get_irn_op(n);
1714
1715         if (get_op_pinned(op) >= op_pin_state_exc_pinned) {
1716                 op_pin_state state = get_irn_pinned(n);
1717                 ASSERT_AND_RET_DBG(
1718                         state == op_pin_state_floats ||
1719                         state == op_pin_state_pinned,
1720                         "invalid pin state", 0,
1721                         ir_printf("node %+F", n);
1722                 );
1723         } else if (!is_Block(n) && is_irn_pinned_in_irg(n)
1724                    && irg_has_properties(irg, IR_GRAPH_PROPERTY_NO_BADS)) {
1725                 ASSERT_AND_RET_DBG(is_Block(get_nodes_block(n)) || is_Anchor(n),
1726                                 "block input is not a block", 0,
1727                                 ir_printf("node %+F", n);
1728                 );
1729         }
1730
1731         if (op->ops.verify_node)
1732                 return op->ops.verify_node(n);
1733
1734         /* All went ok */
1735         return 1;
1736 }
1737
1738 int irn_verify(const ir_node *n)
1739 {
1740 #ifdef DEBUG_libfirm
1741         return irn_verify_irg(n, get_irn_irg(n));
1742 #else
1743         (void)n;
1744         return 1;
1745 #endif
1746 }
1747
1748 /*-----------------------------------------------------------------*/
1749 /* Verify the whole graph.                                         */
1750 /*-----------------------------------------------------------------*/
1751
1752 #ifdef DEBUG_libfirm
1753 /**
1754  * Walker to check every node
1755  */
1756 static void verify_wrap(ir_node *node, void *env)
1757 {
1758         int *res = (int*)env;
1759         *res = irn_verify_irg(node, get_irn_irg(node));
1760 }
1761
1762 /**
1763  * Walker to check every node including SSA property.
1764  * Only called if dominance info is available.
1765  */
1766 static void verify_wrap_ssa(ir_node *node, void *env)
1767 {
1768         int *res = (int*)env;
1769
1770         *res = irn_verify_irg(node, get_irn_irg(node));
1771         if (*res) {
1772                 *res = check_dominance_for_node(node);
1773         }
1774 }
1775
1776 #endif /* DEBUG_libfirm */
1777
1778 typedef struct check_cfg_env_t {
1779         pmap *branch_nodes; /**< map blocks to their branching nodes,
1780                                  map mode_X nodes to the blocks they branch to */
1781         int   res;
1782         ir_nodeset_t reachable_blocks;
1783         ir_nodeset_t kept_nodes;
1784         ir_nodeset_t true_projs;
1785         ir_nodeset_t false_projs;
1786 } check_cfg_env_t;
1787
1788 static int check_block_cfg(const ir_node *block, check_cfg_env_t *env)
1789 {
1790         pmap *branch_nodes;
1791         int   n_cfgpreds;
1792         int   i;
1793
1794         ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->reachable_blocks, block),
1795                            "Block is not reachable by blockwalker (endless loop with no kept block?)", 0,
1796                            ir_printf("block %+F\n", block);
1797         );
1798
1799         n_cfgpreds   = get_Block_n_cfgpreds(block);
1800         branch_nodes = env->branch_nodes;
1801         for (i = 0; i < n_cfgpreds; ++i) {
1802                 /* check that each mode_X node is only connected
1803                  * to 1 user */
1804                 ir_node *branch = get_Block_cfgpred(block, i);
1805                 ir_node *former_dest;
1806                 ir_node *former_branch;
1807                 ir_node *branch_proj;
1808                 ir_node *branch_block;
1809                 branch = skip_Tuple(branch);
1810                 if (is_Bad(branch))
1811                         continue;
1812                 former_dest = pmap_get(ir_node, branch_nodes, branch);
1813                 ASSERT_AND_RET_DBG(former_dest==NULL || is_unknown_jump(skip_Proj(branch)),
1814                                                    "Multiple users on mode_X node", 0,
1815                                                    ir_printf("node %+F\n", branch);
1816                 );
1817                 pmap_insert(branch_nodes, branch, (void*)block);
1818
1819                 /* check that there's only 1 branching instruction in each block */
1820                 branch_block = get_nodes_block(branch);
1821                 branch_proj  = branch;
1822                 if (is_Proj(branch)) {
1823                         branch = skip_Proj(branch);
1824                 }
1825                 former_branch = pmap_get(ir_node, branch_nodes, branch_block);
1826
1827                 ASSERT_AND_RET_DBG(former_branch == NULL || former_branch == branch,
1828                                                    "Multiple branching nodes in a block", 0,
1829                                                    ir_printf("nodes %+F,%+F in block %+F\n",
1830                                                                          branch, former_branch, branch_block);
1831                 );
1832                 pmap_insert(branch_nodes, branch_block, branch);
1833
1834                 if (is_Cond(branch)) {
1835                         long pn = get_Proj_proj(branch_proj);
1836                         if (pn == pn_Cond_true)
1837                                 ir_nodeset_insert(&env->true_projs, branch);
1838                         if (pn == pn_Cond_false)
1839                                 ir_nodeset_insert(&env->false_projs, branch);
1840                 } else if (is_Switch(branch)) {
1841                         long pn = get_Proj_proj(branch_proj);
1842                         if (pn == pn_Switch_default)
1843                                 ir_nodeset_insert(&env->true_projs, branch);
1844                 }
1845         }
1846
1847         return 1;
1848 }
1849
1850 static void check_cfg_walk_func(ir_node *node, void *data)
1851 {
1852         check_cfg_env_t *env = (check_cfg_env_t*)data;
1853         if (!is_Block(node))
1854                 return;
1855         env->res &= check_block_cfg(node, env);
1856 }
1857
1858 static int verify_block_branch(const ir_node *block, check_cfg_env_t *env)
1859 {
1860         ir_node *branch = pmap_get(ir_node, env->branch_nodes, block);
1861         ASSERT_AND_RET_DBG(branch != NULL
1862                            || ir_nodeset_contains(&env->kept_nodes, block)
1863                            || block == get_irg_end_block(get_irn_irg(block)),
1864                            "block contains no cfop", 0,
1865                            ir_printf("block %+F\n", block);
1866         );
1867         return 1;
1868 }
1869
1870 static int verify_cond_projs(const ir_node *cond, check_cfg_env_t *env)
1871 {
1872         ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->true_projs, cond),
1873                                            "Cond node lacks true proj", 0,
1874                                            ir_printf("Cond %+F\n", cond);
1875         );
1876         ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->false_projs, cond),
1877                                            "Cond node lacks false proj", 0,
1878                                            ir_printf("Cond %+F\n", cond);
1879         );
1880         return 1;
1881 }
1882
1883 static int verify_switch_projs(const ir_node *sw, check_cfg_env_t *env)
1884 {
1885         ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->true_projs, sw),
1886                                            "Switch node lacks default Proj", 0,
1887                                            ir_printf("Switch %+F\n", sw);
1888         );
1889         return 1;
1890 }
1891
1892 static void assert_branch(ir_node *node, void *data)
1893 {
1894         check_cfg_env_t *env = (check_cfg_env_t*)data;
1895         if (is_Block(node)) {
1896                 env->res &= verify_block_branch(node, env);
1897         } else if (is_Cond(node)) {
1898                 env->res &= verify_cond_projs(node, env);
1899         } else if (is_Switch(node)) {
1900                 env->res &= verify_switch_projs(node, env);
1901         }
1902 }
1903
1904 static void collect_reachable_blocks(ir_node *block, void *data)
1905 {
1906         ir_nodeset_t *reachable_blocks = (ir_nodeset_t*) data;
1907         ir_nodeset_insert(reachable_blocks, block);
1908 }
1909
1910 /**
1911  * Checks CFG well-formedness
1912  */
1913 static int check_cfg(ir_graph *irg)
1914 {
1915         check_cfg_env_t env;
1916         env.branch_nodes = pmap_create(); /**< map blocks to branch nodes */
1917         env.res          = 1;
1918         ir_nodeset_init(&env.reachable_blocks);
1919         ir_nodeset_init(&env.true_projs);
1920         ir_nodeset_init(&env.false_projs);
1921
1922         irg_block_walk_graph(irg, collect_reachable_blocks, NULL,
1923                              &env.reachable_blocks);
1924
1925         /* note that we do not use irg_walk_block because it will miss these
1926          * invalid blocks without a jump instruction which we want to detect
1927          * here */
1928         irg_walk_graph(irg, check_cfg_walk_func, NULL, &env);
1929
1930         ir_nodeset_init(&env.kept_nodes);
1931         {
1932                 ir_node *end   = get_irg_end(irg);
1933                 int      arity = get_irn_arity(end);
1934                 int      i;
1935                 for (i = 0; i < arity; ++i) {
1936                         ir_node *n = get_irn_n(end, i);
1937                         ir_nodeset_insert(&env.kept_nodes, n);
1938                 }
1939         }
1940         irg_walk_graph(irg, assert_branch, NULL, &env);
1941
1942         ir_nodeset_destroy(&env.false_projs);
1943         ir_nodeset_destroy(&env.true_projs);
1944         ir_nodeset_destroy(&env.kept_nodes);
1945         ir_nodeset_destroy(&env.reachable_blocks);
1946         pmap_destroy(env.branch_nodes);
1947         return env.res;
1948 }
1949
1950 int irg_verify(ir_graph *irg, unsigned flags)
1951 {
1952         int res = 1;
1953 #ifdef DEBUG_libfirm
1954         int pinned = get_irg_pinned(irg) == op_pin_state_pinned;
1955
1956 #ifndef NDEBUG
1957         last_irg_error = NULL;
1958 #endif /* NDEBUG */
1959
1960         if (pinned && !check_cfg(irg))
1961                 res = 0;
1962
1963         if (res == 1 && (flags & VERIFY_ENFORCE_SSA) && pinned)
1964                 compute_doms(irg);
1965
1966         irg_walk_anchors(
1967                 irg,
1968                 pinned && irg_has_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE)
1969                         ? verify_wrap_ssa : verify_wrap,
1970                 NULL,
1971                 &res
1972         );
1973
1974         if (get_node_verification_mode() == FIRM_VERIFICATION_REPORT && ! res) {
1975                 ir_entity *ent = get_irg_entity(irg);
1976
1977                 if (ent)
1978                         fprintf(stderr, "irg_verify: Verifying graph %s failed\n", get_entity_name(ent));
1979                 else
1980                         fprintf(stderr, "irg_verify: Verifying graph %p failed\n", (void *)irg);
1981         }
1982
1983 #else
1984         (void)irg;
1985         (void)flags;
1986 #endif /* DEBUG_libfirm */
1987
1988         return res;
1989 }
1990
1991 typedef struct pass_t {
1992         ir_graph_pass_t pass;
1993         unsigned        flags;
1994 } pass_t;
1995
1996 /**
1997  * Wrapper to irg_verify to be run as an ir_graph pass.
1998  */
1999 static int irg_verify_wrapper(ir_graph *irg, void *context)
2000 {
2001         pass_t *pass = (pass_t*)context;
2002         irg_verify(irg, pass->flags);
2003         /* do NOT rerun the pass if verify is ok :-) */
2004         return 0;
2005 }
2006
2007 ir_graph_pass_t *irg_verify_pass(const char *name, unsigned flags)
2008 {
2009         pass_t *pass = XMALLOCZ(pass_t);
2010
2011         def_graph_pass_constructor(
2012                 &pass->pass, name ? name : "irg_verify", irg_verify_wrapper);
2013
2014         /* neither dump for verify */
2015         pass->pass.dump_irg   = (DUMP_ON_IRG_FUNC)ir_prog_no_dump;
2016         pass->pass.verify_irg = (RUN_ON_IRG_FUNC)ir_prog_no_verify;
2017
2018         pass->flags = flags;
2019         return &pass->pass;
2020 }
2021
2022 int irn_verify_irg_dump(const ir_node *n, ir_graph *irg,
2023                         const char **bad_string)
2024 {
2025         int res;
2026         firm_verification_t old = get_node_verification_mode();
2027
2028         firm_verify_failure_msg = NULL;
2029         do_node_verification(FIRM_VERIFICATION_ERROR_ONLY);
2030         res = irn_verify_irg(n, irg);
2031         if (res && irg_has_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE) &&
2032             get_irg_pinned(irg) == op_pin_state_pinned)
2033                 res = check_dominance_for_node(n);
2034         do_node_verification(old);
2035         *bad_string = firm_verify_failure_msg;
2036
2037         return res;
2038 }
2039
2040 typedef struct verify_bad_env_t {
2041         int flags;
2042         int res;
2043 } verify_bad_env_t;
2044
2045 /**
2046  * Pre-Walker: check Bad predecessors of node.
2047  */
2048 static void check_bads(ir_node *node, void *env)
2049 {
2050         verify_bad_env_t *venv = (verify_bad_env_t*)env;
2051         int i, arity = get_irn_arity(node);
2052         ir_graph *irg = get_irn_irg(node);
2053
2054         if (is_Block(node)) {
2055                 if ((venv->flags & BAD_CF) == 0) {
2056
2057                         /* check for Bad Block predecessor */
2058                         for (i = 0; i < arity; ++i) {
2059                                 ir_node *pred = get_irn_n(node, i);
2060
2061                                 if (is_Bad(pred)) {
2062                                         venv->res |= BAD_CF;
2063
2064                                         if (get_node_verification_mode() == FIRM_VERIFICATION_REPORT) {
2065                                                 fprintf(stderr, "irg_verify_bads: Block %ld has Bad predecessor\n", get_irn_node_nr(node));
2066                                         }
2067                                         if (get_node_verification_mode() == FIRM_VERIFICATION_ON) {
2068                                                 dump_ir_graph(irg, "assert");
2069                                                 assert(0 && "Bad CF detected");
2070                                         }
2071                                 }
2072                         }
2073                 }
2074         } else {
2075                 if ((venv->flags & BAD_BLOCK) == 0) {
2076
2077                         /* check for Bad Block */
2078                         if (is_Bad(get_nodes_block(node))) {
2079                                 venv->res |= BAD_BLOCK;
2080
2081                                 if (get_node_verification_mode() == FIRM_VERIFICATION_REPORT) {
2082                                         fprintf(stderr, "irg_verify_bads: node %ld has Bad Block\n", get_irn_node_nr(node));
2083                                 }
2084                                 if (get_node_verification_mode() == FIRM_VERIFICATION_ON) {
2085                                         dump_ir_graph(irg, "assert");
2086                                         assert(0 && "Bad CF detected");
2087                                 }
2088                         }
2089                 }
2090
2091                 if ((venv->flags & TUPLE) == 0) {
2092                         if (is_Tuple(node)) {
2093                                 venv->res |= TUPLE;
2094
2095                                 if (get_node_verification_mode() == FIRM_VERIFICATION_REPORT) {
2096                                         fprintf(stderr, "irg_verify_bads: node %ld is a Tuple\n", get_irn_node_nr(node));
2097                                 }
2098                                 if (get_node_verification_mode() == FIRM_VERIFICATION_ON) {
2099                                         dump_ir_graph(irg, "assert");
2100                                         assert(0 && "Tuple detected");
2101                                 }
2102                         }
2103                 }
2104
2105                 for (i = 0; i < arity; ++i) {
2106                         ir_node *pred = get_irn_n(node, i);
2107
2108                         if (is_Bad(pred)) {
2109                                 /* check for Phi with Bad inputs */
2110                                 if (is_Phi(node) && !is_Bad(get_nodes_block(node)) && is_Bad(get_irn_n(get_nodes_block(node), i))) {
2111                                         if (venv->flags & BAD_CF)
2112                                                 continue;
2113                                         else {
2114                                                 venv->res |= BAD_CF;
2115
2116                                                 if (get_node_verification_mode() == FIRM_VERIFICATION_REPORT) {
2117                                                         fprintf(stderr, "irg_verify_bads: Phi %ld has Bad Input\n", get_irn_node_nr(node));
2118                                                 }
2119                                                 if (get_node_verification_mode() == FIRM_VERIFICATION_ON) {
2120                                                         dump_ir_graph(irg, "assert");
2121                                                         assert(0 && "Bad CF detected");
2122                                                 }
2123                                         }
2124                                 }
2125
2126                                 /* Bad node input */
2127                                 if ((venv->flags & BAD_DF) == 0) {
2128                                         venv->res |= BAD_DF;
2129
2130                                         if (get_node_verification_mode() == FIRM_VERIFICATION_REPORT) {
2131                                                 fprintf(stderr, "irg_verify_bads: node %ld has Bad Input\n", get_irn_node_nr(node));
2132                                         }
2133                                         if (get_node_verification_mode() == FIRM_VERIFICATION_ON) {
2134                                                 dump_ir_graph(irg, "assert");
2135                                                 assert(0 && "Bad NON-CF detected");
2136                                         }
2137                                 }
2138                         }
2139                 }
2140         }
2141 }
2142
2143 int irg_verify_bads(ir_graph *irg, int flags)
2144 {
2145         verify_bad_env_t env;
2146
2147         env.flags = flags;
2148         env.res   = 0;
2149
2150         irg_walk_graph(irg, check_bads, NULL, &env);
2151
2152         return env.res;
2153 }
2154
2155 static void register_verify_node_func(ir_op *op, verify_node_func func)
2156 {
2157         op->ops.verify_node = func;
2158 }
2159
2160 static void register_verify_node_func_proj(ir_op *op, verify_node_func func)
2161 {
2162         op->ops.verify_proj_node = func;
2163 }
2164
2165 void ir_register_verify_node_ops(void)
2166 {
2167         register_verify_node_func(op_Add,      verify_node_Add);
2168         register_verify_node_func(op_Alloc,    verify_node_Alloc);
2169         register_verify_node_func(op_And,      verify_node_And);
2170         register_verify_node_func(op_Block,    verify_node_Block);
2171         register_verify_node_func(op_Bound,    verify_node_Bound);
2172         register_verify_node_func(op_Call,     verify_node_Call);
2173         register_verify_node_func(op_Cast,     verify_node_Cast);
2174         register_verify_node_func(op_Cmp,      verify_node_Cmp);
2175         register_verify_node_func(op_Cond,     verify_node_Cond);
2176         register_verify_node_func(op_Confirm,  verify_node_Confirm);
2177         register_verify_node_func(op_Const,    verify_node_Const);
2178         register_verify_node_func(op_Conv,     verify_node_Conv);
2179         register_verify_node_func(op_CopyB,    verify_node_CopyB);
2180         register_verify_node_func(op_Div,      verify_node_Div);
2181         register_verify_node_func(op_Eor,      verify_node_Eor);
2182         register_verify_node_func(op_Free,     verify_node_Free);
2183         register_verify_node_func(op_IJmp,     verify_node_IJmp);
2184         register_verify_node_func(op_InstOf,   verify_node_InstOf);
2185         register_verify_node_func(op_Jmp,      verify_node_Jmp);
2186         register_verify_node_func(op_Load,     verify_node_Load);
2187         register_verify_node_func(op_Minus,    verify_node_Minus);
2188         register_verify_node_func(op_Mod,      verify_node_Mod);
2189         register_verify_node_func(op_Mul,      verify_node_Mul);
2190         register_verify_node_func(op_Mulh,     verify_node_Mulh);
2191         register_verify_node_func(op_Mux,      verify_node_Mux);
2192         register_verify_node_func(op_Not,      verify_node_Not);
2193         register_verify_node_func(op_Or,       verify_node_Or);
2194         register_verify_node_func(op_Phi,      verify_node_Phi);
2195         register_verify_node_func(op_Proj,     verify_node_Proj);
2196         register_verify_node_func(op_Raise,    verify_node_Raise);
2197         register_verify_node_func(op_Return,   verify_node_Return);
2198         register_verify_node_func(op_Rotl,     verify_node_Rotl);
2199         register_verify_node_func(op_Sel,      verify_node_Sel);
2200         register_verify_node_func(op_Shl,      verify_node_Shl);
2201         register_verify_node_func(op_Shr,      verify_node_Shr);
2202         register_verify_node_func(op_Shrs,     verify_node_Shrs);
2203         register_verify_node_func(op_Start,    verify_node_Start);
2204         register_verify_node_func(op_Store,    verify_node_Store);
2205         register_verify_node_func(op_Sub,      verify_node_Sub);
2206         register_verify_node_func(op_Switch,   verify_node_Switch);
2207         register_verify_node_func(op_SymConst, verify_node_SymConst);
2208         register_verify_node_func(op_Sync,     verify_node_Sync);
2209
2210         register_verify_node_func_proj(op_Alloc,  verify_node_Proj_Alloc);
2211         register_verify_node_func_proj(op_Bound,  verify_node_Proj_Bound);
2212         register_verify_node_func_proj(op_Call,   verify_node_Proj_Call);
2213         register_verify_node_func_proj(op_Cond,   verify_node_Proj_Cond);
2214         register_verify_node_func_proj(op_CopyB,  verify_node_Proj_CopyB);
2215         register_verify_node_func_proj(op_Div,    verify_node_Proj_Div);
2216         register_verify_node_func_proj(op_InstOf, verify_node_Proj_InstOf);
2217         register_verify_node_func_proj(op_Load,   verify_node_Proj_Load);
2218         register_verify_node_func_proj(op_Mod,    verify_node_Proj_Mod);
2219         register_verify_node_func_proj(op_Proj,   verify_node_Proj_Proj);
2220         register_verify_node_func_proj(op_Raise,  verify_node_Proj_Raise);
2221         register_verify_node_func_proj(op_Start,  verify_node_Proj_Start);
2222         register_verify_node_func_proj(op_Store,  verify_node_Proj_Store);
2223         register_verify_node_func_proj(op_Switch, verify_node_Proj_Switch);
2224         register_verify_node_func_proj(op_Tuple,  verify_node_Proj_Tuple);
2225 }