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