Code cleanup in VRP code
[libfirm] / ir / ana / vrp.c
1 /*
2  * Copyright (C) 1995-2009 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       analyze graph to provide value range information
23  * @author      Jonas Fietz
24  * @version     $Id$
25  */
26 #include "config.h"
27
28 #include "config.h"
29 #include "irtypes.h"
30 #include "vrp.h"
31 #include "irouts.h"
32 #include "irgraph_t.h"
33 #include "irpass.h"
34 #include "irgwalk.h"
35 #include "iredges.h"
36 #include "tv.h"
37 #include "irop.h"
38 #include "pdeq.h"
39
40
41 static char v;
42 static void *VISITED = &v;
43
44 struct vrp_env_t {
45         waitq *workqueue;
46 };
47
48 static int update_vrp_data(ir_node *node)
49 {
50
51         tarval *new_bits_set = get_tarval_bad();
52         tarval *new_bits_not_set = get_tarval_bad();
53         tarval *new_range_bottom = get_tarval_bad();
54         tarval *new_range_top = get_tarval_bad();
55         ir_node *new_bits_node = NULL;
56         ir_node *new_range_node = NULL;
57         enum range_types new_range_type = VRP_UNDEFINED;
58         enum range_ops new_range_op = VRP_NONE;
59         int something_changed = 0;
60
61
62         node->vrp.valid = 1;
63         /* TODO: Check if all predecessors have valid VRP information*/
64
65
66         if (!mode_is_int(get_irn_mode(node))) {
67                 return 0; /* we don't optimize for non-int-nodes*/
68         }
69
70         switch (get_irn_opcode(node)) {
71         case iro_Const: {
72                 tarval *tv = get_Const_tarval(node);
73                 new_bits_set = tv;
74                 new_bits_not_set = tarval_not(tv);
75                 new_range_bottom = tv;
76                 new_range_top = tv;
77                 new_range_type = VRP_RANGE;
78                 break;
79         }
80
81         case iro_And: {
82                 ir_node *left, *right;
83                 tarval *tmp_tv;
84
85                 left = get_And_left(node);
86                 right = get_And_right(node);
87
88                 new_bits_set = tarval_and(left->vrp.bits_set, right->vrp.bits_set);
89                 new_bits_not_set = tarval_or(left->vrp.bits_not_set, right->vrp.bits_not_set);
90
91                 tmp_tv = tarval_not(left->vrp.bits_set);
92                 tmp_tv = tarval_eor(left->vrp.bits_not_set, tmp_tv);
93                 /*check if one of the predecessors is completely determined*/
94                 if (tarval_is_null(tmp_tv)) {
95                         new_bits_node = right;
96                 }
97
98                 tmp_tv = tarval_not(right->vrp.bits_set);
99                 tmp_tv = tarval_eor(right->vrp.bits_not_set, tmp_tv);
100                 if (tarval_is_null(tmp_tv)) {
101                         new_bits_node = left;
102                 }
103                 break;
104         }
105
106         case iro_Add: {
107                 ir_node *left, *right;
108                 left = get_Add_left(node);
109                 right = get_Add_right(node);
110                 int overflow_top, overflow_bottom;
111                 tarval *new_top, *new_bottom;
112
113                 if (left->vrp.range_type == VRP_UNDEFINED || right->vrp.range_type ==
114                                 VRP_UNDEFINED || left->vrp.range_type == VRP_VARYING ||
115                                 right->vrp.range_type == VRP_VARYING) {
116                         return 0;
117                 }
118
119                 new_top = tarval_add(left->vrp.range_top, right->vrp.range_top);
120                 overflow_top = tarval_carry();
121                 new_bottom = tarval_add(left->vrp.range_bottom, right->vrp.range_bottom);
122                 overflow_bottom = tarval_carry();
123
124                 if (!overflow_top && !overflow_bottom && left->vrp.range_type == VRP_RANGE
125                                 &&right->vrp.range_type == VRP_RANGE) {
126                         new_range_bottom = new_bottom;
127                         new_range_top = new_top;
128                         new_range_type = VRP_RANGE;
129                 }
130
131                 if (overflow_top || overflow_bottom) {
132                         /* TODO Implement overflow handling*/
133                         new_range_type = VRP_UNDEFINED;
134                 }
135                 break;
136         }
137
138         case iro_Sub: {
139                 ir_node *left, *right;
140                 left = get_Sub_left(node);
141                 right = get_Sub_right(node);
142                 int overflow_top, overflow_bottom;
143                 tarval *new_top, *new_bottom;
144
145                 if (left->vrp.range_type == VRP_UNDEFINED || right->vrp.range_type ==
146                                 VRP_UNDEFINED) {
147                         return 0;
148                 }
149
150                 new_top = tarval_sub(left->vrp.range_top, right->vrp.range_top, NULL);
151                 overflow_top = tarval_carry();
152                 new_bottom = tarval_sub(left->vrp.range_bottom, right->vrp.range_bottom, NULL);
153                 overflow_bottom = tarval_carry();
154
155                 if (!overflow_top && !overflow_bottom && left->vrp.range_type == VRP_RANGE
156                                 &&right->vrp.range_type == VRP_RANGE) {
157                         new_range_bottom = new_bottom;
158                         new_range_top = new_top;
159                         new_range_type = VRP_RANGE;
160                 }
161
162                 if (overflow_top || overflow_bottom) {
163                         /* TODO Implement overflow handling*/
164                 }
165                 break;
166         }
167
168         case iro_Or: {
169                 ir_node *left, *right;
170                 tarval *tmp_tv;
171
172                 left = get_Or_left(node);
173                 right = get_Or_right(node);
174
175                 new_bits_set = tarval_or(left->vrp.bits_set, right->vrp.bits_set);
176                 new_bits_not_set = tarval_and(left->vrp.bits_not_set, right->vrp.bits_not_set);
177
178                 tmp_tv = tarval_not(left->vrp.bits_set);
179                 tmp_tv = tarval_eor(left->vrp.bits_not_set, tmp_tv);
180                 /*check if one of the predecessors is completely determined*/
181                 if (tarval_is_null(tmp_tv)) {
182                         new_bits_node = right;
183                 }
184
185                 tmp_tv = tarval_not(right->vrp.bits_set);
186                 tmp_tv = tarval_eor(right->vrp.bits_not_set, tmp_tv);
187                 if (tarval_is_null(tmp_tv)) {
188                         new_bits_node = left;
189                 }
190                 break;
191         }
192
193         case iro_Rotl: {
194                 ir_node *left, *right;
195
196                 left = get_Rotl_left(node);
197                 right = get_Rotl_right(node);
198
199                 /* We can only compute this if the right value is a constant*/
200                 if (is_Const(right)) {
201                         tarval *bits_set, *bits_not_set;
202                         bits_set = tarval_rotl(left->vrp.bits_set, get_Const_tarval(right));
203                         bits_not_set = tarval_rotl(left->vrp.bits_not_set, get_Const_tarval(right));
204
205                         new_bits_set = tarval_or(bits_set, node->vrp.bits_set);
206                         new_bits_not_set = tarval_or(bits_not_set, node->vrp.bits_not_set);
207                 }
208                 break;
209         }
210
211         case iro_Shl: {
212                 ir_node *left, *right;
213                 left = get_Shl_left(node);
214                 right = get_Shl_right(node);
215
216                 /* We can only compute this if the right value is a constant*/
217                 if (is_Const(right)) {
218                         tarval *bits_set, *bits_not_set;
219                         ir_mode *m = get_tarval_mode(node->vrp.bits_not_set);
220                         bits_set = tarval_shl(left->vrp.bits_set, get_Const_tarval(right));
221                         bits_not_set = tarval_shl(left->vrp.bits_not_set, get_Const_tarval(right));
222
223                         new_bits_set = tarval_or(bits_set, node->vrp.bits_set);
224                         new_bits_not_set = tarval_or(bits_not_set, node->vrp.bits_not_set);
225
226                         bits_not_set = tarval_not( tarval_shl(
227                                                                                 get_mode_all_one(m),
228                                                                                 get_Const_tarval(right)));
229                         new_bits_not_set = tarval_or(bits_not_set, new_bits_not_set);
230
231                 }
232                 break;
233         }
234
235         case iro_Shr: {
236                 ir_node *left, *right;
237
238                 left = get_Shr_left(node);
239                 right = get_Shr_right(node);
240
241                 /* We can only compute this if the right value is a constant*/
242                 if (is_Const(right)) {
243                         tarval *bits_set, *bits_not_set;
244                         ir_mode *m = get_tarval_mode(node->vrp.bits_not_set);
245                         bits_set = tarval_shr(left->vrp.bits_set, get_Const_tarval(right));
246                         bits_not_set = tarval_shr(left->vrp.bits_not_set, get_Const_tarval(right));
247
248                         new_bits_set = tarval_or(bits_set, node->vrp.bits_set);
249                         new_bits_not_set = tarval_or(bits_not_set, node->vrp.bits_not_set);
250
251                         bits_not_set = tarval_not( tarval_shr(
252                                                                                 get_mode_all_one(m),
253                                                                                 get_Const_tarval(right)));
254                         new_bits_not_set = tarval_or(bits_not_set, new_bits_not_set);
255                 }
256                 break;
257         }
258
259         case iro_Shrs: {
260                 ir_node *left, *right;
261
262                 left = get_Shrs_left(node);
263                 right = get_Shrs_right(node);
264
265                 /* We can only compute this if the right value is a constant*/
266                 if (is_Const(right)) {
267                         tarval *bits_set, *bits_not_set;
268                         ir_mode *m = get_tarval_mode(node->vrp.bits_not_set);
269                         bits_set = tarval_shrs(left->vrp.bits_set, get_Const_tarval(right));
270                         bits_not_set = tarval_shrs(left->vrp.bits_not_set, get_Const_tarval(right));
271
272                         new_bits_set = tarval_or(bits_set, node->vrp.bits_set);
273                         new_bits_not_set = tarval_or(bits_not_set, node->vrp.bits_not_set);
274
275                         bits_not_set = tarval_not( tarval_shrs(
276                                                                                 get_mode_all_one(m),
277                                                                                 get_Const_tarval(right)));
278                         new_bits_not_set = tarval_or(bits_not_set, new_bits_not_set);
279                 }
280                 break;
281         }
282
283         case iro_Eor: {
284                 ir_node *left, *right;
285
286                 left = get_Eor_left(node);
287                 right = get_Eor_right(node);
288
289                 tarval *bits_set, *bits_not_set;
290                 bits_not_set = tarval_or(
291                                                         tarval_and(left->vrp.bits_set, right->vrp.bits_set),
292                                                         tarval_and(left->vrp.bits_not_set,
293                                                                 right->vrp.bits_not_set));
294
295                 bits_set = tarval_or(
296                                                 tarval_and(left->vrp.bits_set, right->vrp.bits_not_set),
297                                                 tarval_and(left->vrp.bits_not_set, right->vrp.bits_set));
298
299                 new_bits_set = tarval_or(bits_set, node->vrp.bits_set);
300                 new_bits_not_set = tarval_or(bits_not_set, node->vrp.bits_not_set);
301                 break;
302         }
303
304         case iro_Id: {
305                 ir_node *pred = get_Id_pred(node);
306                 new_bits_set = pred->vrp.bits_set;
307                 new_bits_not_set = pred->vrp.bits_not_set;
308                 new_range_top = pred->vrp.range_top;
309                 new_range_bottom = pred->vrp.range_bottom;
310                 new_range_type = pred->vrp.range_type;
311                 break;
312         }
313
314         case iro_Not: {
315                 ir_node *pred = get_Not_op(node);
316                 new_bits_set = tarval_or(pred->vrp.bits_not_set, node->vrp.bits_set);
317                 new_bits_not_set = tarval_or(pred->vrp.bits_set, node->vrp.bits_not_set);
318                 break;
319         }
320
321         case iro_Conv: {
322                 ir_node *pred = get_Conv_op(node);
323                 ir_mode *old_mode = get_irn_mode(pred);
324
325                 ir_mode *new_mode;
326                 tarval *bits_not_set;
327
328                 if (!mode_is_int(old_mode))
329                         return 0;
330
331                 new_mode = get_irn_mode(node);
332
333                 /* The second and is needed if target type is smaller*/
334                 bits_not_set = tarval_not(
335                                                         tarval_convert_to(get_mode_all_one(old_mode),
336                                                                 new_mode
337                                                                 ));
338                 bits_not_set = tarval_or(bits_not_set, tarval_convert_to(pred->vrp.bits_not_set, new_mode));
339                 new_bits_not_set = tarval_or(bits_not_set, node->vrp.bits_not_set);
340                 new_bits_set = tarval_and(
341                                 tarval_not(bits_not_set), tarval_convert_to(pred->vrp.bits_set, new_mode));
342
343                 if (tarval_cmp(pred->vrp.range_top, get_mode_max(new_mode)) == pn_Cmp_Le) {
344                         node->vrp.range_top = pred->vrp.range_top;
345                 }
346
347                 if (tarval_cmp(pred->vrp.range_bottom, get_mode_min(new_mode)) == pn_Cmp_Ge) {
348                         node->vrp.range_bottom = pred->vrp.range_bottom;
349                 }
350                 break;
351         }
352
353         case iro_Confirm: {
354                 pn_Cmp cmp = get_Confirm_cmp(node);
355                 ir_node *bound = get_Confirm_bound(node);
356
357                 /** @todo: Handle non-Const bounds */
358
359                 if (cmp == pn_Cmp_Lg) {
360                         /** @todo: Is there some way to preserve the information? */
361                         new_range_type = VRP_ANTIRANGE;
362                         if (is_Const(bound)) {
363                                 new_range_top = get_Const_tarval(bound);
364                                 new_range_bottom = get_Const_tarval(bound);
365                         }
366                 } else if (cmp == pn_Cmp_Le) {
367                         if (node->vrp.range_type == VRP_UNDEFINED) {
368                                 new_range_type = VRP_RANGE;
369                                 if (is_Const(bound)) {
370                                         new_range_top = get_Const_tarval(bound);
371                                 }
372                                 new_range_bottom = get_tarval_min(get_irn_mode(node));
373                         } else if (node->vrp.range_type == VRP_RANGE) {
374                                 if (is_Const(bound)) {
375                                         if (tarval_cmp(node->vrp.range_top,
376                                                                 get_Const_tarval(bound)) == pn_Cmp_Le) {
377                                                 new_range_top = get_Const_tarval(bound);
378                                         }
379                                         new_range_bottom = get_tarval_min(get_irn_mode(node));
380
381                                 } else if (node->vrp.range_type == VRP_ANTIRANGE) {
382                                         /** @todo: How do we manage not to get a never ending loop? */
383                                 }
384                         }
385                 }
386                 break;
387         }
388
389         case iro_Phi: {
390                 /* combine all ranges*/
391
392                 ir_node *pred = get_Phi_pred(node,0);
393                 new_range_top = pred->vrp.range_top;
394                 new_range_bottom = pred->vrp.range_bottom;
395                 new_range_type = pred->vrp.range_type;
396                 new_bits_set = pred->vrp.bits_set;
397                 new_bits_not_set = pred->vrp.bits_not_set;
398
399                 int num = get_Phi_n_preds(node);
400                 pn_Cmp cmp;
401                 int i;
402
403                 assert(num > 0);
404
405
406                 for (i = 1; i < num; i++) {
407                         pred = get_Phi_pred(node, i);
408                         if (new_range_type == VRP_RANGE && pred->vrp.range_type ==
409                                         VRP_RANGE) {
410                                 cmp = tarval_cmp(new_range_top, pred->vrp.range_top);
411                                 if (cmp == pn_Cmp_Lt) {
412                                         new_range_top = pred->vrp.range_top;
413                                 }
414                                 cmp = tarval_cmp(new_range_bottom, pred->vrp.range_bottom);
415                                 if (cmp == pn_Cmp_Gt) {
416                                         new_range_bottom = pred->vrp.range_bottom;
417                                 }
418                         } else {
419                                 new_range_type = VRP_VARYING;
420                                 break;
421                         }
422                 }
423
424                 break;
425         }
426
427         default:
428                 /* unhandled, therefore never updated */
429                 break;
430         }
431
432
433
434         /* TODO: Check, if there can be information derived from any of these:
435         is_Abs(node) is_Alloc(node) is_Anchor(node) is_Borrow(node) is_Bound(node)
436         is_Break(node) is_Builtin(node) is_Call(node) is_CallBegin(node)
437         is_Carry(node) is_Cast(node) is_Cmp(node) is_Cond(node)
438         is_CopyB(node) is_Div(node) is_DivMod(node) is_Dummy(node)
439         is_End(node) is_EndExcept(node) is_EndReg(node) is_Filter(node) is_Free(node)
440         is_IJmp(node) is_InstOf(node) is_Jmp(node) is_Load(node) is_Minus(node)
441         is_Mod(node) is_Mul(node) is_Mulh(node) is_Mux(node) is_NoMem(node)
442         is_Pin(node) is_Proj(node) is_Quot(node)
443         is_Raise(node) is_Return(node) is_Sel(node) is_Start(node) is_Store(node)
444         is_SymConst(node) is_Sync(node) is_Tuple(node)
445         */
446
447         /* Merge the newly calculated values with those that might already exist*/
448
449         if (new_bits_set != tarval_bad) {
450                 new_bits_set = tarval_or(new_bits_set, node->vrp.bits_set);
451                 if (tarval_cmp(new_bits_set, node->vrp.bits_set) != pn_Cmp_Eq) {
452                         something_changed = 1;
453                         node->vrp.bits_set = new_bits_set;
454                 }
455         }
456
457         if (new_bits_not_set != tarval_bad) {
458                 new_bits_not_set = tarval_or(new_bits_not_set, node->vrp.bits_not_set);
459
460                 if (tarval_cmp(new_bits_not_set, node->vrp.bits_not_set) != pn_Cmp_Eq) {
461                         something_changed = 1;
462                         node->vrp.bits_not_set = new_bits_not_set;
463                 }
464         }
465
466         if (node->vrp.bits_node == NULL && new_bits_node != NULL) {
467                 something_changed = 1;
468                 node->vrp.bits_node = new_bits_node;
469         }
470
471         if (node->vrp.range_type == VRP_UNDEFINED &&
472                         new_range_type != VRP_UNDEFINED) {
473                 something_changed = 1;
474                 node->vrp.range_type = new_range_type;
475                 node->vrp.range_bottom = new_range_bottom;
476                 node->vrp.range_top = new_range_top;
477                 node->vrp.range_op = new_range_op;
478                 node->vrp.range_node = new_range_node;
479
480         } else if (node->vrp.range_type == VRP_RANGE) {
481                 if (new_range_type == VRP_RANGE) {
482                         if ((new_range_node == NULL && node->vrp.range_node == NULL) ||
483                                         (new_range_node == node->vrp.range_node &&
484                                          new_range_op == node->vrp.range_op)) {
485                                 if (tarval_cmp(node->vrp.range_bottom, new_range_bottom) == pn_Cmp_Lt) {
486                                         something_changed = 1;
487                                         node->vrp.range_bottom = new_range_bottom;
488                                 }
489                                 if (tarval_cmp(node->vrp.range_top, new_range_top) == pn_Cmp_Gt) {
490                                         something_changed = 1;
491                                         node->vrp.range_top = new_range_top;
492                                 }
493                         }
494
495                         /* prefer the absolute value*/
496                         if (new_range_node == NULL && node->vrp.range_node != NULL) {
497                                 something_changed = 1;
498                                 node->vrp.range_node = NULL;
499                                 node->vrp.range_top = new_range_top;
500                                 node->vrp.range_bottom = new_range_bottom;
501                         }
502                 }
503
504                 if (new_range_type == VRP_ANTIRANGE) {
505                         /* if they are overlapping, cut the range.*/
506                         /* TODO: Maybe we can preserve more information here*/
507                         if (new_range_node == NULL && node->vrp.range_node == NULL) {
508                                 if (tarval_cmp(node->vrp.range_bottom, new_range_top) == pn_Cmp_Gt &&
509                                                 tarval_cmp(node->vrp.range_bottom, new_range_bottom) == pn_Cmp_Gt) {
510                                         something_changed = 1;
511                                         node->vrp.range_bottom = new_range_top;
512
513                                 } else if (tarval_cmp(node->vrp.range_top, new_range_bottom) == pn_Cmp_Gt &&
514                                                 tarval_cmp(node->vrp.range_top, new_range_top) == pn_Cmp_Lt) {
515                                         something_changed = 1;
516                                         node->vrp.range_top = new_range_bottom;
517                                 }
518
519                                 /* We can not handle the case where the anti range is in the*/
520                                 /* range*/
521                         }
522
523                         /* prefer the absolute value*/
524                         if (new_range_node == NULL && node->vrp.range_node != NULL) {
525                                 something_changed = 1;
526                                 node->vrp.range_node = NULL;
527                                 node->vrp.range_top = new_range_top;
528                                 node->vrp.range_bottom = new_range_bottom;
529                         }
530                 }
531         } else if (node->vrp.range_type == VRP_ANTIRANGE) {
532                 if (new_range_type == VRP_ANTIRANGE) {
533                         if ((new_range_node == NULL && node->vrp.range_node == NULL) ||
534                                         (new_range_node == node->vrp.range_node &&
535                                          new_range_op == node->vrp.range_op)) {
536                                 if (tarval_cmp(node->vrp.range_bottom, new_range_bottom) == pn_Cmp_Gt) {
537                                         something_changed = 1;
538                                         node->vrp.range_bottom = new_range_bottom;
539                                 }
540                                 if (tarval_cmp(node->vrp.range_top, new_range_top) == pn_Cmp_Lt) {
541                                         something_changed = 1;
542                                         node->vrp.range_top = new_range_top;
543                                 }
544                         }
545
546                         /* prefer the absolute value*/
547                         if (new_range_node == NULL && node->vrp.range_node != NULL) {
548                                 something_changed = 1;
549                                 node->vrp.range_node = NULL;
550                                 node->vrp.range_top = new_range_top;
551                                 node->vrp.range_bottom = new_range_bottom;
552                         }
553                 }
554
555                 if (new_range_type == VRP_RANGE) {
556                         if ((new_range_node == NULL && node->vrp.range_node == NULL) ||
557                                         (new_range_node == node->vrp.range_node &&
558                                          new_range_op == node->vrp.range_op)) {
559                                 if (tarval_cmp(node->vrp.range_bottom, new_range_top) == pn_Cmp_Gt) {
560                                         something_changed = 1;
561                                         node->vrp.range_bottom = new_range_top;
562                                 }
563                                 if (tarval_cmp(node->vrp.range_top, new_range_bottom) == pn_Cmp_Lt) {
564                                         something_changed = 1;
565                                         node->vrp.range_top = new_range_bottom;
566                                 }
567                         }
568
569                         /* prefer the absolute value*/
570                         if (new_range_node == NULL && node->vrp.range_node != NULL) {
571                                 something_changed = 1;
572                                 node->vrp.range_node = NULL;
573                                 node->vrp.range_top = new_range_top;
574                                 node->vrp.range_bottom = new_range_bottom;
575                         }
576                 }
577         }
578
579         assert(tarval_is_null(
580                                 tarval_and(node->vrp.bits_set, node->vrp.bits_not_set)));
581
582         return something_changed;
583 }
584
585 static void vrp_first_pass(ir_node *n, void *e)
586 {
587         ir_node *succ;
588         int i;
589         struct vrp_env_t *env = e;
590
591         if (is_Block(n))
592                 return;
593
594         set_irn_link(n, VISITED);
595
596         update_vrp_data(n);
597
598         for (i = get_irn_n_outs(n) - 1; i >=0; --i) {
599                 succ =  get_irn_out(n, i);
600                 if (get_irn_link(succ) == VISITED) {
601                         /* we found a loop*/
602                         waitq_put(env->workqueue, n);
603                 }
604         }
605 }
606
607
608 void set_vrp_data(ir_graph *irg)
609 {
610
611         ir_node *succ, *node;
612         int i;
613         struct vrp_env_t env;
614
615         if (!irg) {
616                 /* no graph, skip */
617                 return;
618         }
619
620         assure_irg_outs(irg); /* ensure that out edges are consistent*/
621
622         env.workqueue = new_waitq();
623         irg_walk_graph(irg, NULL, vrp_first_pass, &env);
624
625         /* while there are entries in the worklist, continue*/
626         while (!waitq_empty(env.workqueue)) {
627                 node = waitq_get(env.workqueue);
628
629                 if (update_vrp_data(node)) {
630                         /* if something changed, add successors to worklist*/
631                         for (i = get_irn_n_outs(node) - 1; i >=0; --i) {
632                                 succ =  get_irn_out(node, i);
633                                 waitq_put(env.workqueue, node);
634                         }
635                 }
636         }
637         del_waitq(env.workqueue);
638 }
639
640
641 ir_graph_pass_t *set_vrp_pass(const char *name)
642 {
643         return def_graph_pass(name ? name : "set_vrp", set_vrp_data);
644 }
645
646 pn_Cmp vrp_cmp(ir_node *left, ir_node *right)
647 {
648         if (!left->vrp.valid || !right->vrp.valid) {
649                 return pn_Cmp_False;
650         }
651
652         if (left->vrp.range_type == VRP_RANGE && right->vrp.range_type == VRP_RANGE) {
653                 if (tarval_cmp(left->vrp.range_top, right->vrp.range_bottom) == pn_Cmp_Lt) {
654                         return pn_Cmp_Lt;
655                 }
656                 if (tarval_cmp(left->vrp.range_bottom, right->vrp.range_top) == pn_Cmp_Gt) {
657                         return pn_Cmp_Gt;
658                 }
659         }
660
661         if (!tarval_is_null(tarval_and(left->vrp.bits_set, right->vrp.bits_not_set)) ||
662                         !tarval_is_null(tarval_and(left->vrp.bits_not_set, right->vrp.bits_set))) {
663                 return pn_Cmp_Lg;
664         }
665         /* TODO: We can get way more information here*/
666
667         return pn_Cmp_False;
668 }