Cosmetic changes to the chordal register allocator
[libfirm] / ir / be / bera.c
1 /**
2  * Base routines for register allocation.
3  * @author Sebastian Hack
4  * @date 22.11.2004
5  */
6 #ifdef HAVE_CONFIG_H
7 #include "config.h"
8 #endif
9
10 #include "pset.h"
11 #include "impl.h"
12
13 #include "irnode.h"
14 #include "irmode.h"
15 #include "irdom.h"
16
17 #include "besched_t.h"
18 #include "belive_t.h"
19
20 static INLINE int values_interfere_dom(const ir_node *a, const ir_node *b)
21 {
22         const ir_node *b1 = get_nodes_block(a);
23         const ir_node *b2 = get_nodes_block(b);
24         int lo_a, lo_b;
25
26         assert(block_dominates(b1, b2));
27
28         /*
29          * if the two blocks are not equal, a and b can only interfere if a is
30          * live in at b2.
31          */
32         if(b1 != b2 && !is_live_in(b2, a))
33                 return 0;
34
35         lo_a = is_live_end(b2, a);
36         lo_b = is_live_end(b2, b);
37
38         /*
39          * If the two blocks are the same and one value is live out and the
40          * definition of the other is after the definition ov the live out
41          * value, they interfere.
42          */
43         if(b1 == b2) {
44                 int pos_a = sched_get_time_step(a);
45                 int pos_b = sched_get_time_step(b);
46
47                 if((pos_a < pos_b && lo_a) || (pos_b < pos_a && lo_b))
48                         return 1;
49         }
50
51         /*
52          * Now it is left to check, if the sequence from the last use of 'b'
53          * (or the end of the block b2, if b is live out)
54          * to the def of 'b' contains a use and NOT the def of 'a'. Then they
55          * also interfere
56          */
57         {
58                 const ir_node *irn;
59
60                 /* Initialize the liveness. */
61                 int a_live = lo_a;
62                 int b_live = lo_b;
63
64                 /* Go from the end of block b2 and try to detect the liveness. */
65                 sched_foreach_reverse(b2, irn) {
66                         int i, n;
67
68                         /*
69                          * If the definition of 'a' was found 'a' and 'b' interfere, if
70                          * 'b' is live here.
71                          */
72                         if(irn == a)
73                                 return b_live;
74
75                         /* Same goes for 'b'. */
76                         if(irn == b)
77                                 return a_live;
78
79                         /* If 'a' is not yet live, search for a use. */
80                         if(!a_live) {
81                                 for(i = 0, n = get_irn_arity(irn); i < n; ++i)
82                                         if(get_irn_n(irn, i) == a) {
83                                                 a_live = 1;
84                                                 break;
85                                 }
86                         }
87
88                         /* Same for 'b' */
89                         if(!b_live) {
90                                 for(i = 0, n = get_irn_arity(irn); i < n; ++i)
91                                         if(get_irn_n(irn, i) == b) {
92                                                 b_live = 1;
93                                                 break;
94                                         }
95                         }
96
97                 }
98         }
99
100         assert(0 && "You may never reach this place");
101
102         /* This is never reached */
103         return 0;
104 }
105
106 int values_interfere(const ir_node *a, const ir_node *b)
107 {
108         const ir_node *b1 = get_nodes_block(a);
109         const ir_node *b2 = get_nodes_block(b);
110
111         if(block_dominates(b1, b2))
112                 return values_interfere_dom(a, b);
113         else if(block_dominates(b2, b1))
114                 return values_interfere_dom(b, a);
115         else
116                 return 0;
117 }