4 * Created on: Aug 28, 2009
15 #include "html_dumper.h"
16 #include "heuristical.h"
17 #include "pbqp_node_t.h"
19 #include "becopyopt_t.h"
23 #include "irprintf_t.h"
29 static FILE *my_open(const be_chordal_env_t *env, const char *prefix, const char *suffix)
36 n = strlen(env->birg->main_env->cup_name);
37 tu_name = XMALLOCN(char, n + 1);
38 strcpy(tu_name, env->birg->main_env->cup_name);
39 for (i = 0; i < n; ++i)
40 if (tu_name[i] == '.')
43 ir_snprintf(buf, sizeof(buf), "%s%s_%F_%s%s", prefix, tu_name, env->irg, env->cls->name, suffix);
45 result = fopen(buf, "wt");
47 panic("Couldn't open '%s' for writing.", buf);
53 static int co_solve_heuristic_pbqp(copy_opt_t *co) {
54 void *nodes_it = be_ifg_nodes_iter_alloca(co->cenv->ifg);
55 void *neigh_it = be_ifg_neighbours_iter_alloca(co->cenv->ifg);
56 ir_node *ifg_node, *if_neighb_node;
59 unsigned number_registers = co->cls->n_regs;
60 unsigned number_nodes = 0;
61 unsigned int nodeIdx = 0;
63 bitset_t *ignore_registers;
67 be_ifg_foreach_node(co->cenv->ifg, nodes_it, ifg_node) {
71 // create empty PBQP instance
72 pbqp_problem = alloc_pbqp(number_nodes);
75 ignore_registers = bitset_malloc(number_registers);
76 be_put_ignore_regs(co->cenv->birg, co->cls, ignore_registers);
79 map = pmap_create_ex(number_nodes);
81 // add costs vector to nodes
83 be_ifg_foreach_node(co->cenv->ifg, nodes_it, ifg_node) {
84 // create costs vector
85 struct vector *costs_vector = vector_alloc(pbqp_problem, number_registers);
89 for(cnt = 0; cnt < costs_vector->len; cnt++) {
90 if (bitset_is_set(ignore_registers,cnt)) {
91 vector_set(costs_vector, cnt, INF_COSTS);
94 if (!arch_reg_out_is_allocatable(ifg_node, arch_register_for_index(co->cls, cnt)))
96 vector_set(costs_vector, cnt, INF_COSTS);
99 vector_set(costs_vector, cnt, 0);
104 vector_set_description(costs_vector, cnt, arch_register_for_index(co->cls, cnt)->name);
107 // add costs vector to node
108 add_node_costs(pbqp_problem, nodeIdx, costs_vector);
110 // insert ir_node and pbqp_node into map
111 pmap_insert(map, ifg_node, get_node(pbqp_problem,nodeIdx));
113 // increment nodeIndex
117 be_ifg_foreach_node(co->cenv->ifg, nodes_it, ifg_node) {
118 pbqp_node *src_node = pmap_find(map,ifg_node)->value;
119 unsigned int srcNodeIdx = src_node->index;
121 // add costs matrix between nodes (interference edge)
122 be_ifg_foreach_neighbour(co->cenv->ifg, neigh_it, ifg_node, if_neighb_node) {
123 pbqp_node *trg_node = pmap_find(map,if_neighb_node)->value;
124 if(get_edge(pbqp_problem, srcNodeIdx, trg_node->index) == NULL) {
125 // create costs matrix
126 struct pbqp_matrix *matrix = pbqp_matrix_alloc(pbqp_problem, number_registers, number_registers);
130 for(row = 0; row < number_registers; row++) {
131 for(col = 0; col < number_registers; col++) {
133 pbqp_matrix_set(matrix, row, col, INF_COSTS);
136 pbqp_matrix_set(matrix, row, col, 2);
141 // add costs matrix to interference edge
142 add_edge_costs(pbqp_problem, srcNodeIdx, trg_node->index , matrix);
146 // add costs matrix between nodes (affinety edge)
147 affinity_node_t *aff_node = get_affinity_info(co, ifg_node);
148 neighb_t *aff_neighb_node;
149 if(aff_node != NULL) {
150 co_gs_foreach_neighb(aff_node, aff_neighb_node) {
151 pbqp_node *trg_node = pmap_find(map,aff_neighb_node->irn)->value;
152 if(get_edge(pbqp_problem, srcNodeIdx, trg_node->index) == NULL) {
153 // create costs matrix
154 struct pbqp_matrix *matrix = pbqp_matrix_alloc(pbqp_problem, number_registers, number_registers);
158 for(row = 0; row < number_registers; row++) {
159 for(col = 0; col < number_registers; col++) {
161 pbqp_matrix_set(matrix, row, col, 0);
164 pbqp_matrix_set(matrix, row, col, 2);
169 // add costs matrix to interference edge
170 add_edge_costs(pbqp_problem, srcNodeIdx, trg_node->index , matrix);
177 // dump graph before solving pbqp
178 FILE *file_before = my_open(co->cenv, "", "-before.html");
179 set_dumpfile(pbqp_problem, file_before);
180 pbqp_dump_input(pbqp_problem);
184 // solve pbqp problem
185 solve_pbqp_heuristical(pbqp_problem);
186 //solve_pbqp_brute_force(pbqp_problem);
187 num solution = get_solution(pbqp_problem);
189 assert(solution != INF_COSTS && "No PBQP solution found");
191 // printf("Solution (%s): %d\n",co->name, (int)solution);
194 be_ifg_foreach_node(co->cenv->ifg, nodes_it, ifg_node) {
195 pbqp_node *node = pmap_find(map,ifg_node)->value;
196 num index = get_node_solution(pbqp_problem, node->index);
197 const arch_register_t *reg = arch_register_for_index(co->cls, index);
198 arch_set_irn_register(ifg_node, reg);
202 // dump graph after solving pbqp
203 FILE *file_after = my_open(co->cenv, "", "-after.html");
204 set_dumpfile(pbqp_problem, file_after);
205 pbqp_dump_input(pbqp_problem);
209 // free pbqp resources
214 bitset_free(ignore_registers);
216 free_pbqp(pbqp_problem);
221 void be_init_copypbqp(void)
223 static co_algo_info copyheur = {
224 co_solve_heuristic_pbqp, 0
227 be_register_copyopt("pbqp", ©heur);
230 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_copypbqp);