1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
4 * Authors: Christian Schaefer
15 # include "irgraph_t.h"
20 #define ASSERT_AND_RET(expr, string, ret) if (!(expr)) return (ret)
22 #define ASSERT_AND_RET(expr, string, ret) do { assert((expr) && string); if (!(expr)) return (ret); } while(0)
25 /* @@@ replace use of array "in" by access functions. */
26 ir_node **get_irn_in(ir_node *node);
29 vrfy_Proj_proj(ir_node *p, ir_graph *irg) {
34 pred = skip_nop(get_Proj_pred(p));
35 assert(get_irn_mode(pred) == mode_T);
36 mode = get_irn_mode(p);
37 proj = get_Proj_proj(p);
39 switch (get_irn_opcode(pred)) {
43 (proj == pns_initial_exec && mode == mode_X) ||
44 (proj == pns_global_store && mode == mode_M) ||
45 (proj == pns_frame_base && mode_is_reference(mode)) ||
46 (proj == pns_globals && mode_is_reference(mode)) ||
47 (proj == pns_args && mode == mode_T) ||
48 (proj == pns_value_arg_base && mode_is_reference(mode))
50 "wrong Proj from Start", 0);
54 ASSERT_AND_RET( (proj >= 0 && mode == mode_X), "wrong Proj from Cond", 0);
59 ((proj == 0 && mode == mode_X) ||
60 (proj == 1 && mode == mode_M)),
61 "wrong Proj from Raise", 0);
65 ASSERT_AND_RET( (proj >= 0 && mode == mode_X), "wrong Proj from InstOf", 0);
70 ((proj == 0 && mode == mode_M) ||
71 (proj == 1 && mode == mode_X) ||
72 (proj == 2 && mode == mode_T) ||
73 (proj == 3 && mode == mode_M)),
74 "wrong Proj from Call", 0);
79 ((proj == 0 && mode == mode_M) ||
80 (proj == 1 && mode == mode_X) ||
81 (proj == 2 && mode_is_float(mode))),
82 "wrong Proj from Quot", 0);
87 ((proj == 0 && mode == mode_M) ||
88 (proj == 1 && mode == mode_X) ||
89 (proj == 2 && mode == mode_Is) ||
90 (proj == 3 && mode_is_int(mode))),
91 "wrong Proj from DivMod", 0);
97 ((proj == 0 && mode == mode_M) ||
98 (proj == 1 && mode == mode_X) ||
99 (proj == 2 && mode_is_int(mode))),
100 "wrong Proj from Div or Mod", 0);
105 (proj >= 0 && proj <= 15 && mode == mode_b),
106 "wrong Proj from Cmp", 0);
111 ((proj == 0 && mode == mode_M) ||
112 (proj == 1 && mode == mode_X) ||
113 (proj == 2 && mode_is_data(mode))),
114 "wrong Proj from Load", 0);
119 ((proj == 0 && mode == mode_M) ||
120 (proj == 1 && mode == mode_X)),
121 "wrong Proj from Store", 0);
127 (proj == 0 && mode == mode_M) ||
128 (proj == 1 /* && mode == mode_X*/) ||
129 (proj == 2 && mode_is_reference(mode))
131 "wrong Proj from Alloc", 0);
136 type *mt; /* A method type */
137 pred = skip_nop(get_Proj_pred(pred));
138 ASSERT_AND_RET((get_irn_mode(pred) == mode_T), "Proj from something not a tuple", 0);
139 switch (get_irn_opcode(pred))
144 (proj >= 0 && mode_is_data(mode)),
145 "wrong Proj from Proj from Start", 0);
146 mt = get_entity_type(get_irg_ent(irg));
148 (proj < get_method_n_params(mt)),
149 "More Projs for args than args in type", 0);
150 if ((mode_is_reference(mode)) && is_compound_type(get_method_param_type(mt, proj)))
151 /* value argument */ break;
154 (mode == get_type_mode(get_method_param_type(mt, proj))),
155 "Mode of Proj from Start doesn't match mode of param type.", 0);
162 (proj >= 0 && mode_is_data(mode)),
163 "wrong Proj from Proj from Call", 0);
164 mt = get_Call_type(pred);
166 (proj < get_method_n_ress(mt)),
167 "More Projs for results than results in type.", 0);
168 if ((mode_is_reference(mode)) && is_compound_type(get_method_res_type(mt, proj)))
169 /* value result */ break;
172 (mode == get_type_mode(get_method_res_type(mt, proj))),
173 "Mode of Proj from Call doesn't match mode of result type.", 0);
182 ASSERT_AND_RET(0, "Unknown opcode", 0);
201 ASSERT_AND_RET(0, "Unknown opcode", 0);
208 int irn_vrfy_irg(ir_node *n, ir_graph *irg)
212 ir_mode *mymode, *op1mode = NULL, *op2mode, *op3mode;
213 int op_is_symmetric = 1; /* 0: asymmetric
214 1: operands have identical modes
215 2: modes of operands == mode of this node */
216 type *mt; /* A method type */
220 if (! interprocedural_view) {
222 * do NOT check placement in interprocedural view, as we don't always know
223 * the "right" graph ...
225 ASSERT_AND_RET(node_is_in_irgs_storage(irg, n), "Node is not stored on proper IR graph!", 0);
228 opcode = get_irn_opcode (n);
230 /* We don't want to test nodes whose predecessors are Bad or Unknown,
231 as we would have to special case that for each operation. */
232 if (opcode != iro_Phi && opcode != iro_Block)
233 for (i = 0; i < get_irn_arity(n); i++) {
234 opcode1 = get_irn_opcode(get_irn_n(n, i));
235 if (opcode1 == iro_Bad || opcode1 == iro_Unknown)
239 mymode = get_irn_mode (n);
246 /* Start: BB --> X x M x ref x data1 x ... x datan x ref */
247 mymode == mode_T, "Start node", 0
254 mymode == mode_X, "Jmp node", 0
261 mymode == mode_X, "Jmp node", 0
266 op1mode = get_irn_mode(in[1]);
268 /* Cond: BB x b --> X x X */
269 (op1mode == mode_b ||
270 /* Cond: BB x int --> X^n */
271 mode_is_int(op1mode) ), "Cond node", 0
273 ASSERT_AND_RET(mymode == mode_T, "Cond mode is not a tuple", 0);
277 op1mode = get_irn_mode(in[1]);
278 /* Return: BB x M x data1 x ... x datan --> X */
279 /* printf("mode: %s, code %s\n", ID_TO_STR(n->mode->name), ID_TO_STR(n->op->name));*/
280 ASSERT_AND_RET( op1mode == mode_M, "Return node", 0 ); /* operand M */
281 for (i=2; i < get_irn_arity(n); i++) {
282 ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Return node", 0 ); /* operand datai */
284 ASSERT_AND_RET( mymode == mode_X, "Result X", 0 ); /* result X */
285 /* Compare returned results with result types of method type */
286 mt = get_entity_type(get_irg_ent(irg));
287 ASSERT_AND_RET( get_Return_n_ress(n) == get_method_n_ress(mt),
288 "Number of results for Return doesn't match number of results in type.", 0 );
289 for (i = 0; i < get_Return_n_ress(n); i++)
291 get_irn_mode(get_Return_res(n, i)) == get_type_mode(get_method_res_type(mt, i)),
292 "Mode of result for Return doesn't match mode of result type.", 0);
296 op1mode = get_irn_mode(in[1]);
297 op2mode = get_irn_mode(in[2]);
299 /* Sel: BB x M x ref --> X x M */
300 op1mode == mode_M && mode_is_reference(op2mode) &&
301 mymode == mode_T, "Raise node", 0
307 /* Const: BB --> data */
308 (mode_is_data (mymode) ||
309 mymode == mode_b) /* we want boolean constants for static evaluation */
310 ,"Const node", 0 /* of Cmp. */
316 /* SymConst: BB --> int*/
317 (mode_is_int(mymode) ||
318 /* SymConst: BB --> ref */
319 mode_is_reference(mymode))
320 ,"SymConst node", 0);
324 op1mode = get_irn_mode(in[1]);
325 op2mode = get_irn_mode(in[2]);
327 /* Sel: BB x M x ref x int^n --> ref */
328 (op1mode == mode_M && op2mode == mymode && mode_is_reference(mymode)),
331 for (i=3; i < get_irn_arity(n); i++)
333 ASSERT_AND_RET(mode_is_int(get_irn_mode(in[i])), "Sel node", 0);
338 ASSERT_AND_RET(mode_T == mymode, "mode of Instof is not a tuple", 0);
339 ASSERT_AND_RET(mode_is_data(op1mode), "Instof not on data", 0);
343 op1mode = get_irn_mode(in[1]);
344 op2mode = get_irn_mode(in[2]);
345 /* Call: BB x M x ref x data1 x ... x datan
346 --> M x datan+1 x ... x data n+m */
347 ASSERT_AND_RET( op1mode == mode_M && mode_is_reference(op2mode), "Call node", 0 ); /* operand M x ref */
348 for (i=3; i < get_irn_arity(n); i++) {
349 ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Call node", 0 ); /* operand datai */
351 ASSERT_AND_RET( mymode == mode_T, "Call result not a tuple", 0 ); /* result T */
352 /* Compare arguments of node with those of type */
353 mt = get_Call_type(n);
355 if (get_method_variadicity(mt) == variadic) {
357 get_Call_n_params(n) >= get_method_n_params(mt),
358 "Number of args for Call doesn't match number of args in variadic type.",
363 get_Call_n_params(n) == get_method_n_params(mt),
364 "Number of args for Call doesn't match number of args in non variadic type.",
368 for (i = 0; i < get_method_n_params(mt); i++) {
370 get_irn_mode(get_Call_param(n, i)) == get_type_mode(get_method_param_type(mt, i)),
371 "Mode of arg for Call doesn't match mode of arg type.", 0);
376 op1mode = get_irn_mode(in[1]);
377 op2mode = get_irn_mode(in[2]);
380 /* common Add: BB x numP x numP --> numP */
381 (op1mode == mymode && op2mode == op1mode && mode_is_numP(mymode)) ||
382 /* Pointer Add: BB x ref x int --> ref */
383 (mode_is_reference(op1mode) && mode_is_int(op2mode) && op1mode == mymode) ||
384 /* Pointer Add: BB x int x ref --> ref */
385 (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode))
389 if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
390 /* BB x ref x int --> ref or BB x int x ref --> ref */
391 op_is_symmetric = 0; /* ArmRoq */
393 /* BB x num x num --> num or BB x ref x ref */
399 op1mode = get_irn_mode(in[1]);
400 op2mode = get_irn_mode(in[2]);
402 /* common Sub: BB x numP x numP --> numP */
403 ((mymode ==op1mode && mymode == op2mode && mode_is_numP(op1mode)) ||
404 /* Pointer Sub: BB x ref x int --> ref */
405 (op1mode == mymode && mode_is_int(op2mode) && mode_is_reference(mymode)) ||
406 /* Pointer Sub: BB x int x ref --> ref */
407 (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode)) ||
408 /* Pointer Sub: BB x ref x ref --> int */
409 (op1mode == op2mode && mode_is_reference(op2mode) && mode_is_int(mymode))),
412 if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
413 op_is_symmetric = 0; /* ArmRoq */
420 op1mode = get_irn_mode(in[1]);
422 /* Minus: BB x float --> float */
423 op1mode == mymode && get_mode_sort(op1mode) == irms_float_number, "Minus node", 0
429 op1mode = get_irn_mode(in[1]);
430 op2mode = get_irn_mode(in[2]);
432 /* Mul: BB x int1 x int1 --> int2 */
433 ((mode_is_int(op1mode) && op2mode == op1mode && mode_is_int(mymode)) ||
434 (mode_is_float(op1mode) && op2mode == op1mode && mymode == op1mode)),
441 op1mode = get_irn_mode(in[1]);
442 op2mode = get_irn_mode(in[2]);
443 op3mode = get_irn_mode(in[3]);
445 /* Quot: BB x M x float x float --> M x X x float */
446 op1mode == mode_M && op2mode == op3mode &&
447 get_mode_sort(op2mode) == irms_float_number &&
455 op1mode = get_irn_mode(in[1]);
456 op2mode = get_irn_mode(in[2]);
457 op3mode = get_irn_mode(in[3]);
459 /* DivMod: BB x M x int x int --> M x X x int x int */
461 mode_is_int(op2mode) &&
462 op3mode == op2mode &&
471 op1mode = get_irn_mode(in[1]);
472 op2mode = get_irn_mode(in[2]);
473 op3mode = get_irn_mode(in[3]);
475 /* Div or Mod: BB x M x int x int --> M x X x int */
477 op2mode == op3mode &&
478 mode_is_int(op2mode) &&
486 op1mode = get_irn_mode(in[1]);
488 /* Abs: BB x num --> num */
490 mode_is_num (op1mode),
499 op1mode = get_irn_mode(in[1]);
500 op2mode = get_irn_mode(in[2]);
502 /* And or Or or Eor: BB x int x int --> int */
503 mode_is_int(mymode) &&
504 op2mode == op1mode &&
506 "And, Or or Eor node", 0
512 op1mode = get_irn_mode(in[1]);
514 /* Not: BB x int --> int */
515 mode_is_int(mymode) &&
524 op1mode = get_irn_mode(in[1]);
525 op2mode = get_irn_mode(in[2]);
527 /* Cmp: BB x datab x datab --> b16 */
528 mode_is_data (op1mode) &&
529 op2mode == op1mode &&
538 op1mode = get_irn_mode(in[1]);
539 op2mode = get_irn_mode(in[2]);
541 /* Shl, Shr or Shrs: BB x int x int_u --> int */
542 mode_is_int(op1mode) &&
543 mode_is_int(op2mode) &&
544 !mode_is_signed(op2mode) &&
546 "Shl, Shr, Shr or Rot node"
551 op1mode = get_irn_mode(in[1]);
552 op2mode = get_irn_mode(in[2]);
554 /* Rot: BB x int x int --> int */
555 mode_is_int(op1mode) &&
556 mode_is_int(op2mode) &&
563 op1mode = get_irn_mode(in[1]);
565 /* Conv: BB x datab1 --> datab2 */
566 mode_is_datab(op1mode) && mode_is_data(mymode),
572 /* Phi: BB x dataM^n --> dataM */
573 /* for some reason "<=" aborts. int there a problem with get_store? */
574 for (i=1; i < get_irn_arity(n); i++) {
575 if (!is_Bad(in[i]) && (get_irn_op(in[i]) != op_Unknown))
576 ASSERT_AND_RET( get_irn_mode(in[i]) == mymode, "Phi node", 0);
578 ASSERT_AND_RET( mode_is_dataM(mymode), "Phi node", 0 );
582 op1mode = get_irn_mode(in[1]);
583 op2mode = get_irn_mode(in[2]);
585 /* Load: BB x M x ref --> M x X x data */
586 op1mode == mode_M && mode_is_reference(op2mode),
589 ASSERT_AND_RET( mymode == mode_T, "Load node", 0 );
593 op1mode = get_irn_mode(in[1]);
594 op2mode = get_irn_mode(in[2]);
595 op3mode = get_irn_mode(in[3]);
597 /* Load: BB x M x ref data --> M x X */
598 op1mode == mode_M && mode_is_reference(op2mode) && mode_is_data(op3mode),
601 ASSERT_AND_RET(mymode == mode_T, "Store node", 0);
605 op1mode = get_irn_mode(in[1]);
606 op2mode = get_irn_mode(in[2]);
608 /* Alloc: BB x M x int_u --> M x X x ref */
610 mode_is_int(op2mode) &&
611 !mode_is_signed(op2mode) &&
618 op1mode = get_irn_mode(in[1]);
619 op2mode = get_irn_mode(in[2]);
621 /* Free: BB x M x ref --> M */
622 op1mode == mode_M && mode_is_reference(op2mode) &&
629 /* Sync: BB x M^n --> M */
630 for (i=1; i < get_irn_arity(n); i++) {
631 ASSERT_AND_RET( get_irn_mode(in[i]) == mode_M, "Sync node", 0 );
633 ASSERT_AND_RET( mymode == mode_M, "Sync node", 0 );
637 return vrfy_Proj_proj(n, irg);
648 int irn_vrfy(ir_node *n)
650 return irn_vrfy_irg(n, current_ir_graph);
653 /*******************************************************************/
654 /* Verify the whole graph. */
655 /*******************************************************************/
657 static void vrfy_wrap(ir_node *node, void *env)
661 *res = irn_vrfy(node);
664 int irg_vrfy(ir_graph *irg)
669 rem = current_ir_graph;
670 current_ir_graph = irg;
672 assert(get_irg_pinned(irg) == pinned);
674 irg_walk(irg->end, vrfy_wrap, NULL, &res);
676 current_ir_graph = rem;