0ac0c70ef8d98297e981171ddac49a7e8b1f8e94
[libfirm] / ir / ir / irvrfy.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Authors: Christian Schaefer
5 **
6 x**
7 */
8
9 #ifdef HAVE_CONFIG_H
10 # include <config.h>
11 #endif
12
13 # include "irgraph_t.h"
14 # include "irvrfy.h"
15 # include "irgwalk.h"
16
17 void
18 irn_vrfy (ir_node *n)
19 {
20   int i;
21   int opcode;
22   ir_mode *mymode, *op1mode, *op2mode, *op3mode;
23   int op_is_symmetric = 1;      /* 0: asymmetric
24                                    1: operands have identical modes
25                                    2: modes of operands == mode of this node */
26
27   ir_node **in;
28
29   opcode = get_irn_opcode (n);
30
31   if (opcode != iro_Phi && opcode != iro_Block)
32     for (i = 0; i < get_irn_arity(n); i++)
33       if (get_irn_opcode(get_irn_n(n, i)) == iro_Bad)
34         return;
35
36   mymode = get_irn_mode (n);
37   in = get_irn_in (n);
38
39   switch (opcode) {
40
41   case iro_Start:
42     assert (
43             /* Start: BB --> X x M x P x data1 x ... x datan */
44             mymode == mode_T
45            );
46     break;
47   case iro_Jmp:
48     assert (
49             /* Jmp: BB --> X */
50             mymode == mode_X
51            );
52     break;
53   case iro_Cond:
54     op1mode = get_irn_mode(in[1]);
55     assert (
56             /* Cond: BB x b --> X x X */
57             (op1mode == mode_b
58             /* Cond: BB x Iu --> X^n */
59             || op1mode == mode_I)
60            );
61             assert (mymode == mode_T);
62     break;
63   case iro_Return:
64     op1mode = get_irn_mode(in[1]);
65     /* Return: BB x M x data1 x ... x datan --> X */
66     /* printf("mode: %s, code %s\n", ID_TO_STR(n->mode->name), ID_TO_STR(n->op->name));*/
67     assert ( op1mode == mode_M );  /* operand M */
68     for (i=2; i < get_irn_arity(n); i++) {
69       assert ( mode_is_data(get_irn_mode(in[i])) );  /* operand datai */
70     };
71     assert ( mymode == mode_X );   /* result X */
72     break;
73   case iro_Raise:
74     op1mode = get_irn_mode(in[1]);
75     op2mode = get_irn_mode(in[2]);
76     assert (
77             /* Sel: BB x M x P --> X x M */
78             op1mode == mode_M && op2mode == mode_p
79             && mymode == mode_T
80            );
81     break;
82   case iro_Const:
83     assert (
84             /* Const: BB --> data */
85             mode_is_data (mymode) ||
86             mymode == mode_b      /* we want boolean constants for static evaluation
87                                      of Cmp. */
88            );
89     break;
90   case iro_SymConst:
91     assert (
92             /* SymConst: BB --> Iu or
93                          BB --> P */
94             (mymode == mode_I) || (mymode == mode_p)
95            );
96     break;
97   case iro_Sel:
98     op1mode = get_irn_mode(in[1]);
99     op2mode = get_irn_mode(in[2]);
100     assert (
101             /* Sel: BB x M x P x Iu^n --> P */
102             op1mode == mode_M && op2mode == mode_p
103             && mymode == mode_p
104            );
105     for (i=3; i < get_irn_arity(n); i++) {
106             assert (get_irn_mode(in[i]) == mode_I); }
107     break;
108   case iro_Call:
109     op1mode = get_irn_mode(in[1]);
110     op2mode = get_irn_mode(in[2]);
111       /* Call: BB x M x P x data1 x ... x datan
112                  --> M x datan+1 x ... x data n+m */
113     assert ( op1mode == mode_M && op2mode == mode_p );  /* operand M x P */
114     for (i=3; i < get_irn_arity(n); i++) {
115       assert ( mode_is_data(get_irn_mode(in[i])) );  /* operand datai */
116     };
117     assert ( mymode == mode_T );   /* result T */
118     break;
119   case iro_Add:
120     op1mode = get_irn_mode(in[1]);
121     op2mode = get_irn_mode(in[2]);
122     assert (
123             /* common Add: BB x num x num --> num */
124             (mymode == op1mode && mymode == op2mode
125              && mode_is_num(mymode))
126             ||  /* Pointer Add: BB x P x Is --> P */
127             (op1mode == mode_p && op2mode == mode_i && mymode == mode_p)
128             ||  /* Pointer Add: BB x Is x P --> P */
129             (op1mode == mode_i && op2mode == mode_p && mymode == mode_p)
130            );
131       if (op1mode == mode_p || op2mode == mode_p) {
132         /* BB x P x Is --> P or BB x Is x P --> P */
133         op_is_symmetric = 0; /* ArmRoq */
134       } else {
135         /* BB x num x num --> num */
136         op_is_symmetric = 2;
137       }
138     break;
139   case iro_Sub:
140     op1mode = get_irn_mode(in[1]);
141     op2mode = get_irn_mode(in[2]);
142     assert (
143             /* common Sub: BB x num x num --> num */
144             (mymode ==op1mode && mymode == op2mode
145              && mode_is_num(op1mode))
146             ||  /* Pointer Sub: BB x P x Is --> P */
147             (op1mode == mode_p && op2mode == mode_i && mymode == mode_p)
148             ||  /* Pointer Sub: BB x Is x P --> P */
149             (op1mode == mode_i && op2mode == mode_p && mymode == mode_p)
150             ||  /* Pointer Sub: BB x P x P --> Is */
151             (op1mode == mode_p && op2mode == mode_p && mymode == mode_i)
152            );
153       if (op1mode == mode_p && op2mode == mode_p) {
154         op_is_symmetric = 1; /* ArmRoq */
155       } else if (op1mode == mode_p || op2mode == mode_p) {
156         op_is_symmetric = 0; /* ArmRoq */
157       } else {
158         op_is_symmetric = 2;
159       }
160     break;
161   case iro_Minus:
162     op1mode = get_irn_mode(in[1]);
163     assert (
164             /* Minus: BB x float --> float */
165             op1mode == mymode && mode_is_float (op1mode)
166            );
167     op_is_symmetric = 2;
168     break;
169   case iro_Mul:
170     op1mode = get_irn_mode(in[1]);
171     op2mode = get_irn_mode(in[2]);
172     assert (
173             /* Mul: BB x num x num --> num */
174             mymode == op1mode && mymode == op2mode
175             && mode_is_num (op1mode)
176            );
177     op_is_symmetric = 2;
178     break;
179   case iro_Quot:
180     op1mode = get_irn_mode(in[1]);
181     op2mode = get_irn_mode(in[2]);
182     op3mode = get_irn_mode(in[3]);
183     assert (
184             /* Quot: BB x M x float x float --> M x X x float */
185             op1mode == mode_M && op2mode == op3mode
186             && mode_is_float(op2mode) && mymode == mode_T
187            );
188     op_is_symmetric = 2;
189     break;
190   case iro_DivMod:;
191     op1mode = get_irn_mode(in[1]);
192     op2mode = get_irn_mode(in[2]);
193     op3mode = get_irn_mode(in[3]);
194     assert (
195             /* DivMod: BB x M x num x num --> M x X x Is x Is */
196             op1mode == mode_M && op2mode == op3mode
197             && mode_is_num (op2mode) && mymode == mode_T
198            );
199     op_is_symmetric = 1;
200     break;
201   case iro_Div:
202   case iro_Mod:
203     op1mode = get_irn_mode(in[1]);
204     op2mode = get_irn_mode(in[2]);
205     op3mode = get_irn_mode(in[3]);
206     assert (
207             /* Div or Mod: BB x M x num x num --> M x X x Is */
208             op1mode == mode_M && op2mode == op3mode &&
209             mode_is_num (op2mode) && mymode == mode_T
210            );
211     op_is_symmetric = 1;
212     break;
213   case iro_Abs:
214     op1mode = get_irn_mode(in[1]);
215     assert (
216             /* Abs: BB x num --> num */
217             op1mode == mymode && mode_is_num (op1mode)
218            );
219     op_is_symmetric = 2;
220     break;
221   case iro_And:
222   case iro_Or:
223   case iro_Eor:
224     op1mode = get_irn_mode(in[1]);
225     op2mode = get_irn_mode(in[2]);
226     assert(
227            /* And or Or or Eor: BB x int x int --> int */
228            mymode == op1mode && mymode == op2mode
229            && mode_is_int (mymode)
230           );
231     op_is_symmetric = 2;
232     break;
233   case iro_Not:
234     op1mode = get_irn_mode(in[1]);
235     assert(
236            /* Not: BB x int --> int */
237            mymode == op1mode
238            && mode_is_int (mymode)
239           );
240     op_is_symmetric = 2;
241     break;
242
243   case iro_Cmp:
244     op1mode = get_irn_mode(in[1]);
245     op2mode = get_irn_mode(in[2]);
246     assert(
247            /* Cmp: BB x datab x datab --> b16 */
248            op1mode == op2mode && mode_is_data (op1mode)
249            && mymode == mode_T
250           );
251     break;
252   case iro_Shl:
253   case iro_Shr:
254   case iro_Shrs:
255   case iro_Rot:
256     op1mode = get_irn_mode(in[1]);
257     op2mode = get_irn_mode(in[2]);
258     assert(
259            /* Shl, Shr, Shrs or Rot: BB x int x Iu --> int */
260            mode_is_int (op1mode) && op2mode == mode_I
261            && op1mode == mymode
262           );
263     break;
264   case iro_Conv:
265     op1mode = get_irn_mode(in[1]);
266     assert(
267            /* Conv: BB x datab1 --> datab2 */
268            mode_is_datab (op1mode)
269            && mode_is_data (mymode)
270           );
271     break;
272   case iro_Phi:
273            /* Phi: BB x dataM^n --> dataM */
274     /* for some reason "<=" aborts. Is there a problem with get_store? */
275     for (i=1; i < get_irn_arity(n); i++) {
276       if (!is_Bad(in[i]))
277         assert ( get_irn_mode(in[i]) == mymode );
278     };
279     assert ( mode_is_dataM(mymode) );
280     break;
281   case iro_Load:
282     op1mode = get_irn_mode(in[1]);
283     op2mode = get_irn_mode(in[2]);
284     assert(
285            /* Load: BB x M x P --> M x X x data */
286            op1mode == mode_M && op2mode == mode_p
287           );
288     assert ( mymode == mode_T );
289     break;
290   case iro_Store:
291     op1mode = get_irn_mode(in[1]);
292     op2mode = get_irn_mode(in[2]);
293     op3mode = get_irn_mode(in[3]);
294     assert(
295            /* Load: BB x M x P x data --> M x X */
296            op1mode == mode_M && op2mode == mode_p
297            && mode_is_data (op3mode)
298           );
299     assert(mymode == mode_T);
300     break;
301   case iro_Alloc:
302     op1mode = get_irn_mode(in[1]);
303     op2mode = get_irn_mode(in[2]);
304     assert(
305            /* Alloc: BB x M x Iu --> M x X x P */
306            op1mode == mode_M && op2mode == mode_I
307            && mymode == mode_T
308           );
309     break;
310   case iro_Free:
311     op1mode = get_irn_mode(in[1]);
312     op2mode = get_irn_mode(in[2]);
313     op3mode = get_irn_mode(in[3]);
314     assert(
315            /* Free: BB x M x P x Iu --> M */
316            op1mode == mode_M && op2mode == mode_p && op3mode == mode_I
317            && mymode == mode_M
318           );
319     break;
320   case iro_Sync:
321            /* Sync: BB x M^n --> M */
322     for (i=1; i < get_irn_arity(n); i++) {
323       assert ( get_irn_mode(in[i]) == mode_M );
324     };
325     assert ( mymode == mode_M );
326     break;
327
328   default: ;
329   }
330 }
331
332 /*******************************************************************/
333 /* Verify the whole graph.                                         */
334 /*******************************************************************/
335
336 void
337 vrfy_wrap (ir_node *node, void *env) {
338   irn_vrfy(node);
339 }
340
341 void
342 irg_vrfy (ir_graph *irg)
343 {
344   ir_graph *rem;
345   rem = current_ir_graph;
346   current_ir_graph = irg;
347
348   irg_walk(irg->end, vrfy_wrap, NULL, NULL);
349
350   current_ir_graph = rem;
351 }