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)) {
42 ((proj == 0 && mode == mode_X) ||
43 (proj == 1 && mode == mode_M) ||
44 (proj == 2 && mode == mode_P) ||
45 (proj == 3 && mode == mode_P) ||
46 (proj == 4 && mode == mode_T)),
47 "wrong Proj from Start", 0);
50 ASSERT_AND_RET( (proj >= 0 && mode == mode_X), "wrong Proj from Cond", 0);
53 ASSERT_AND_RET( ((proj == 0 && mode == mode_X) || (proj == 1 && mode == mode_M)),
54 "wrong Proj from Raise", 0);
57 ASSERT_AND_RET( (proj >= 0 && mode == mode_X), "wrong Proj from InstOf", 0);
61 ((proj == 0 && mode == mode_M) ||
62 (proj == 1 && mode == mode_X) ||
63 (proj == 2 && mode == mode_T) ||
64 (proj == 3 && mode == mode_M)),
65 "wrong Proj from Call", 0);
69 ((proj == 0 && mode == mode_M) ||
70 (proj == 1 && mode == mode_X) ||
71 (proj == 2 && mode_is_float(mode))),
72 "wrong Proj from Quot", 0);
76 ((proj == 0 && mode == mode_M) ||
77 (proj == 1 && mode == mode_X) ||
78 (proj == 2 && mode == mode_Is) ||
79 (proj == 3 && mode == mode_Is)),
80 "wrong Proj from DivMod", 0);
85 ((proj == 0 && mode == mode_M) ||
86 (proj == 1 && mode == mode_X) ||
87 (proj == 2 && mode == mode_Is)),
88 "wrong Proj from Div or Mod", 0);
92 (proj >= 0 && proj <= 15 && mode == mode_b),
93 "wrong Proj from Cmp", 0);
97 ((proj == 0 && mode == mode_M) ||
98 (proj == 1 && mode == mode_X) ||
99 (proj == 2 && mode_is_data(mode))),
100 "wrong Proj from Load", 0);
104 ((proj == 0 && mode == mode_M) ||
105 (proj == 1 && mode == mode_X)),
106 "wrong Proj from Store", 0);
110 ((proj == 0 && mode == mode_M) ||
111 (proj == 1 /* && mode == mode_X*/) ||
112 (proj == 2 && mode == mode_P)),
113 "wrong Proj from Alloc", 0);
116 type *mt; /* A method type */
117 pred = skip_nop(get_Proj_pred(pred));
118 ASSERT_AND_RET((get_irn_mode(pred) == mode_T), "Proj from something not a tuple", 0);
119 switch (get_irn_opcode(pred)) {
122 (proj >= 0 && mode_is_data(mode)),
123 "wrong Proj from Proj from Start", 0);
124 mt = get_entity_type(get_irg_ent(irg));
126 (proj < get_method_n_params(mt)),
127 "More Projs for args than args in type", 0);
128 if ((mode == mode_P) && is_compound_type(get_method_param_type(mt, proj)))
129 /* value argument */ break;
131 (mode == get_type_mode(get_method_param_type(mt, proj))),
132 "Mode of Proj from Start doesn't match mode of param type.", 0);
136 (proj >= 0 && mode_is_data(mode)),
137 "wrong Proj from Proj from Call", 0);
138 mt = get_Call_type(pred);
140 (proj < get_method_n_ress(mt)),
141 "More Projs for results than results in type.", 0);
142 if ((mode == mode_P) && is_compound_type(get_method_res_type(mt, proj)))
143 /* value result */ break;
145 (mode == get_type_mode(get_method_res_type(mt, proj))),
146 "Mode of Proj from Call doesn't match mode of result type.", 0);
152 ASSERT_AND_RET(0, "Unknown opcode", 0);
165 ASSERT_AND_RET(0, "Unknown opcode", 0);
172 int irn_vrfy_irg(ir_node *n, ir_graph *irg)
176 ir_mode *mymode, *op1mode = NULL, *op2mode, *op3mode;
177 int op_is_symmetric = 1; /* 0: asymmetric
178 1: operands have identical modes
179 2: modes of operands == mode of this node */
180 type *mt; /* A method type */
184 if (! interprocedural_view) {
186 * do NOT check placement in interprocedural view, as we don't always know
187 * the "right" graph ...
189 ASSERT_AND_RET(node_is_in_irgs_storage(irg, n), "Node is not stored on proper IR graph!", 0);
192 opcode = get_irn_opcode (n);
194 /* We don't want to test nodes whose predecessors are Bad or Unknown,
195 as we would have to special case that for each operation. */
196 if (opcode != iro_Phi && opcode != iro_Block)
197 for (i = 0; i < get_irn_arity(n); i++) {
198 opcode1 = get_irn_opcode(get_irn_n(n, i));
199 if (opcode1 == iro_Bad || opcode1 == iro_Unknown)
203 mymode = get_irn_mode (n);
210 /* Start: BB --> X x M x P x data1 x ... x datan */
211 mymode == mode_T, "Start node", 0
217 mymode == mode_X, "Jmp node", 0
223 mymode == mode_X, "Jmp node", 0
227 op1mode = get_irn_mode(in[1]);
229 /* Cond: BB x b --> X x X */
231 /* Cond: BB x Iu --> X^n */
232 || op1mode == mode_Iu), "Cond node", 0
234 ASSERT_AND_RET(mymode == mode_T, "Cond mode is not a tuple", 0);
237 op1mode = get_irn_mode(in[1]);
238 /* Return: BB x M x data1 x ... x datan --> X */
239 /* printf("mode: %s, code %s\n", ID_TO_STR(n->mode->name), ID_TO_STR(n->op->name));*/
240 ASSERT_AND_RET( op1mode == mode_M, "Return node", 0 ); /* operand M */
241 for (i=2; i < get_irn_arity(n); i++) {
242 ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Return node", 0 ); /* operand datai */
244 ASSERT_AND_RET( mymode == mode_X, "Result X", 0 ); /* result X */
245 /* Compare returned results with result types of method type */
246 mt = get_entity_type(get_irg_ent(irg));
247 ASSERT_AND_RET( get_Return_n_ress(n) == get_method_n_ress(mt),
248 "Number of results for Return doesn't match number of results in type.", 0 );
249 for (i = 0; i < get_Return_n_ress(n); i++)
251 get_irn_mode(get_Return_res(n, i)) == get_type_mode(get_method_res_type(mt, i)),
252 "Mode of result for Return doesn't match mode of result type.", 0);
255 op1mode = get_irn_mode(in[1]);
256 op2mode = get_irn_mode(in[2]);
258 /* Sel: BB x M x P --> X x M */
259 op1mode == mode_M && op2mode == mode_P
260 && mymode == mode_T, "Raise node", 0
265 /* Const: BB --> data */
266 (mode_is_data (mymode) ||
267 mymode == mode_b) /* we want boolean constants for static evaluation */
268 ,"Const node", 0 /* of Cmp. */
273 /* SymConst: BB --> Iu or
275 ((mymode == mode_Iu) || (mymode == mode_P)), "SymConst node", 0
279 op1mode = get_irn_mode(in[1]);
280 op2mode = get_irn_mode(in[2]);
282 /* Sel: BB x M x P x Iu^n --> P */
283 op1mode == mode_M && op2mode == mode_P
284 && mymode == mode_P, "Sel node", 0
286 for (i=3; i < get_irn_arity(n); i++) {
287 ASSERT_AND_RET(get_irn_mode(in[i]) == mode_Iu, "Sel node", 0);
291 ASSERT_AND_RET(mode_T == mymode, "mode of Instof is not a tuple", 0);
292 ASSERT_AND_RET(mode_is_data(op1mode), "Instof not on data", 0);
295 op1mode = get_irn_mode(in[1]);
296 op2mode = get_irn_mode(in[2]);
297 /* Call: BB x M x P x data1 x ... x datan
298 --> M x datan+1 x ... x data n+m */
299 ASSERT_AND_RET( op1mode == mode_M && op2mode == mode_P, "Call node", 0 ); /* operand M x P */
300 for (i=3; i < get_irn_arity(n); i++) {
301 ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Call node", 0 ); /* operand datai */
303 ASSERT_AND_RET( mymode == mode_T, "Call result not a tuple", 0 ); /* result T */
304 /* Compare arguments of node with those of type */
305 mt = get_Call_type(n);
307 if (get_method_variadicity(mt) == variadic) {
309 get_Call_n_params(n) >= get_method_n_params(mt),
310 "Number of args for Call doesn't match number of args in variadic type.",
315 get_Call_n_params(n) == get_method_n_params(mt),
316 "Number of args for Call doesn't match number of args in non variadic type.",
320 for (i = 0; i < get_method_n_params(mt); i++) {
322 get_irn_mode(get_Call_param(n, i)) == get_type_mode(get_method_param_type(mt, i)),
323 "Mode of arg for Call doesn't match mode of arg type.", 0);
327 op1mode = get_irn_mode(in[1]);
328 op2mode = get_irn_mode(in[2]);
330 /* common Add: BB x num x num --> num */
331 ((mymode == op1mode && mymode == op2mode
332 && (mode_is_num(mymode) || mymode == mode_P))
333 || /* Pointer Add: BB x P x Is --> P */
334 (op1mode == mode_P && op2mode == mode_Is && mymode == mode_P)
335 || /* Pointer Add: BB x Is x P --> P */
336 (op1mode == mode_Is && op2mode == mode_P && mymode == mode_P)),
339 if (op1mode == mode_P || op2mode == mode_P) {
340 /* BB x P x Is --> P or BB x Is x P --> P */
341 op_is_symmetric = 0; /* ArmRoq */
343 /* BB x num x num --> num */
348 op1mode = get_irn_mode(in[1]);
349 op2mode = get_irn_mode(in[2]);
351 /* common Sub: BB x num x num --> num */
352 ((mymode ==op1mode && mymode == op2mode
353 && mode_is_num(op1mode))
354 || /* Pointer Sub: BB x P x Is --> P */
355 (op1mode == mode_P && op2mode == mode_Is && mymode == mode_P)
356 || /* Pointer Sub: BB x Is x P --> P */
357 (op1mode == mode_Is && op2mode == mode_P && mymode == mode_P)
358 || /* Pointer Sub: BB x P x P --> Is */
359 (op1mode == mode_P && op2mode == mode_P && mymode == mode_Is)),
362 if (op1mode == mode_P && op2mode == mode_P) {
363 op_is_symmetric = 1; /* ArmRoq */
364 } else if (op1mode == mode_P || op2mode == mode_P) {
365 op_is_symmetric = 0; /* ArmRoq */
371 op1mode = get_irn_mode(in[1]);
373 /* Minus: BB x float --> float */
374 op1mode == mymode && mode_is_float(op1mode), "Minus node", 0
379 op1mode = get_irn_mode(in[1]);
380 op2mode = get_irn_mode(in[2]);
382 /* Mul: BB x num x num --> num */
383 mymode == op1mode && mymode == op2mode && mode_is_num(op1mode),
389 op1mode = get_irn_mode(in[1]);
390 op2mode = get_irn_mode(in[2]);
391 op3mode = get_irn_mode(in[3]);
393 /* Quot: BB x M x float x float --> M x X x float */
394 op1mode == mode_M && op2mode == op3mode
395 && mode_is_float(op2mode) && mymode == mode_T,
401 op1mode = get_irn_mode(in[1]);
402 op2mode = get_irn_mode(in[2]);
403 op3mode = get_irn_mode(in[3]);
405 /* DivMod: BB x M x num x num --> M x X x Is x Is */
406 op1mode == mode_M && op2mode == op3mode
407 && mode_is_num (op2mode) && mymode == mode_T,
414 op1mode = get_irn_mode(in[1]);
415 op2mode = get_irn_mode(in[2]);
416 op3mode = get_irn_mode(in[3]);
418 /* Div or Mod: BB x M x num x num --> M x X x Is */
419 op1mode == mode_M && op2mode == op3mode &&
420 mode_is_num (op2mode) && mymode == mode_T,
426 op1mode = get_irn_mode(in[1]);
428 /* Abs: BB x num --> num */
429 op1mode == mymode && mode_is_num (op1mode), "Abs node", 0
436 op1mode = get_irn_mode(in[1]);
437 op2mode = get_irn_mode(in[2]);
439 /* And or Or or Eor: BB x int x int --> int */
440 mymode == op1mode && mymode == op2mode && mode_is_int(mymode),
441 "And, Or or Eor node", 0
446 op1mode = get_irn_mode(in[1]);
448 /* Not: BB x int --> int */
449 mymode == op1mode && mode_is_int(mymode),
456 op1mode = get_irn_mode(in[1]);
457 op2mode = get_irn_mode(in[2]);
459 /* Cmp: BB x datab x datab --> b16 */
460 op1mode == op2mode && mode_is_data(op1mode) && mymode == mode_T,
468 op1mode = get_irn_mode(in[1]);
469 op2mode = get_irn_mode(in[2]);
471 /* Shl, Shr, Shrs or Rot: BB x int x Iu --> int */
472 mode_is_int(op1mode) && op2mode == mode_Iu && op1mode == mymode,
473 "Shl, Shr, Shr or Rot node", 0
477 op1mode = get_irn_mode(in[1]);
479 /* Conv: BB x datab1 --> datab2 */
480 mode_is_datab(op1mode) && mode_is_data(mymode),
485 /* Phi: BB x dataM^n --> dataM */
486 /* for some reason "<=" aborts. Is there a problem with get_store? */
487 for (i=1; i < get_irn_arity(n); i++) {
488 if (!is_Bad(in[i]) && (get_irn_op(in[i]) != op_Unknown))
489 ASSERT_AND_RET( get_irn_mode(in[i]) == mymode, "Phi node", 0);
491 ASSERT_AND_RET( mode_is_dataM(mymode), "Phi node", 0 );
494 op1mode = get_irn_mode(in[1]);
495 op2mode = get_irn_mode(in[2]);
497 /* Load: BB x M x P --> M x X x data */
498 op1mode == mode_M && op2mode == mode_P,
501 ASSERT_AND_RET( mymode == mode_T, "Load node", 0 );
504 op1mode = get_irn_mode(in[1]);
505 op2mode = get_irn_mode(in[2]);
506 op3mode = get_irn_mode(in[3]);
508 /* Load: BB x M x P x data --> M x X */
509 op1mode == mode_M && op2mode == mode_P && mode_is_data(op3mode),
512 ASSERT_AND_RET(mymode == mode_T, "Store node", 0);
515 op1mode = get_irn_mode(in[1]);
516 op2mode = get_irn_mode(in[2]);
518 /* Alloc: BB x M x Iu --> M x X x P */
519 op1mode == mode_M && op2mode == mode_Iu && mymode == mode_T,
524 op1mode = get_irn_mode(in[1]);
525 op2mode = get_irn_mode(in[2]);
526 op3mode = get_irn_mode(in[3]);
528 /* Free: BB x M x P x Iu --> M */
529 op1mode == mode_M && op2mode == mode_P && op3mode == mode_Iu && mymode == mode_M,
534 /* Sync: BB x M^n --> M */
535 for (i=1; i < get_irn_arity(n); i++) {
536 ASSERT_AND_RET( get_irn_mode(in[i]) == mode_M, "Sync node", 0 );
538 ASSERT_AND_RET( mymode == mode_M, "Sync node", 0 );
541 return vrfy_Proj_proj(n, irg);
550 int irn_vrfy(ir_node *n)
552 return irn_vrfy_irg(n, current_ir_graph);
555 /*******************************************************************/
556 /* Verify the whole graph. */
557 /*******************************************************************/
559 static void vrfy_wrap(ir_node *node, void *env)
563 *res = irn_vrfy(node);
566 int irg_vrfy(ir_graph *irg)
571 rem = current_ir_graph;
572 current_ir_graph = irg;
574 assert(get_irg_pinned(irg) == pinned);
576 irg_walk(irg->end, vrfy_wrap, NULL, &res);
578 current_ir_graph = rem;