avoid new_NoMem in favor or get_irg_no_mem
[libfirm] / ir / kaps / pbqp_node.c
1 /*
2  * Copyright (C) 1995-2008 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   PBQP nodes.
23  * @date    02.10.2008
24  * @author  Sebastian Buchwald
25  * @version $Id$
26  */
27 #include "config.h"
28
29 #include "adt/array.h"
30
31 #include "assert.h"
32
33 #include "bucket.h"
34 #include "pbqp_edge.h"
35 #include "pbqp_edge_t.h"
36 #include "pbqp_node.h"
37 #include "pbqp_node_t.h"
38 #include "vector.h"
39
40 pbqp_node_t *alloc_node(pbqp_t *pbqp, unsigned node_index, vector_t *costs)
41 {
42         pbqp_node_t *node = OALLOC(&pbqp->obstack, pbqp_node_t);
43
44         node->edges = NEW_ARR_F(pbqp_edge_t *, 0);
45         node->costs = vector_copy(pbqp, costs);
46         node->bucket_index = UINT_MAX;
47         node->solution = UINT_MAX;
48         node->index = node_index;
49
50         return node;
51 }
52
53 int is_connected(pbqp_node_t *node, pbqp_edge_t *edge)
54 {
55         pbqp_edge_t **edges;
56         unsigned      edge_index;
57         unsigned      edge_len;
58
59         assert(node);
60         if (edge->src != node && edge->tgt != node) return 0;
61
62         edges = node->edges;
63         edge_len = ARR_LEN(edges);
64
65         for (edge_index = 0; edge_index < edge_len; ++edge_index) {
66                 pbqp_edge_t *edge_candidate = edges[edge_index];
67                 if (edge_candidate == edge) {
68                         return 1;
69                 }
70         }
71
72         return 0;
73 }
74
75 void disconnect_edge(pbqp_node_t *node, pbqp_edge_t *edge)
76 {
77         pbqp_edge_t **edges;
78         unsigned      edge_index;
79         unsigned      edge_len;
80
81         edges = node->edges;
82         edge_len = ARR_LEN(edges);
83
84         for (edge_index = 0; edge_index < edge_len; ++edge_index) {
85                 pbqp_edge_t *edge_candidate = edges[edge_index];
86                 if (edge_candidate == edge) {
87                         edges[edge_index] = edges[edge_len - 1];
88                         ARR_SHRINKLEN(edges, (int)edge_len - 1);
89                         break;
90                 }
91         }
92 }
93
94 unsigned pbqp_node_get_degree(pbqp_node_t *node)
95 {
96         return ARR_LEN(node->edges);
97 }
98
99 pbqp_node_t *pbqp_node_deep_copy(pbqp_t *pbqp, pbqp_node_bucket_t new_bucket,
100                                  pbqp_node_t *node)
101 {
102         unsigned     edge_index;
103         unsigned     edge_length = pbqp_node_get_degree(node);
104         pbqp_node_t *copy        = OALLOC(&pbqp->obstack, pbqp_node_t);
105
106         copy->edges        = NEW_ARR_F(pbqp_edge_t *, 0);
107         for (edge_index = 0; edge_index < edge_length; ++edge_index) {
108                 pbqp_edge_t *edge_copy = NULL;
109                 pbqp_edge_t *edge      = node->edges[edge_index];
110                 int          is_src    = edge->src == node;
111
112                 if (is_src) {
113                         unsigned other_index = edge->tgt->bucket_index;
114                         unsigned is_copied   = other_index < node->bucket_index;
115
116                         if (is_copied) {
117                                 pbqp_node_t *other_copy = new_bucket[other_index];
118                                 unsigned     degree     = pbqp_node_get_degree(other_copy);
119                                 unsigned     index;
120
121                                 for (index = 0; index < degree; ++index) {
122                                         if (other_copy->edges[index]->src == node) {
123                                                 edge_copy      = other_copy->edges[index];
124                                                 edge_copy->src = copy;
125                                                 break;
126                                         }
127                                 }
128                         } else {
129                                 edge_copy = pbqp_edge_deep_copy(pbqp, edge, copy, edge->tgt);
130                         }
131                 } else {
132                         unsigned other_index = edge->src->bucket_index;
133                         unsigned is_copied   = other_index < node->bucket_index;
134
135                         if (is_copied) {
136                                 pbqp_node_t *other_copy = new_bucket[other_index];
137                                 unsigned     degree     = pbqp_node_get_degree(other_copy);
138                                 unsigned     index;
139
140                                 for (index = 0; index < degree; ++index) {
141                                         if (other_copy->edges[index]->tgt == node) {
142                                                 edge_copy      = other_copy->edges[index];
143                                                 edge_copy->tgt = copy;
144                                                 break;
145                                         }
146                                 }
147                         } else {
148                                 edge_copy = pbqp_edge_deep_copy(pbqp, edge, edge->src, copy);
149                         }
150                 }
151                 ARR_APP1(pbqp_edge_t *, copy->edges, edge_copy);
152         }
153         copy->costs        = vector_copy(pbqp, node->costs);
154         copy->bucket_index = node->bucket_index;
155         copy->solution     = node->solution;
156         copy->index   = node->index;
157
158         return copy;
159 }