X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=heuristical.c;h=f9c0132cd4a1d4475ba6bd3009900acf79265eb2;hb=42c981c6b53e8474a41b053247d90dcb6059b850;hp=440373d7f9746ba703851735634a99836d64826f;hpb=80f7ef3c3ca406cc656fe8886b1d8d3bbad771fc;p=libfirm diff --git a/heuristical.c b/heuristical.c index 440373d7f..f9c0132cd 100644 --- a/heuristical.c +++ b/heuristical.c @@ -17,13 +17,6 @@ static pbqp_node **node_buckets[4]; static pbqp_node **reduced_bucket = NULL; static int buckets_filled = 0; -static num add(num x, num y) -{ - if (x == INF_COSTS || y == INF_COSTS) return INF_COSTS; - - return x + y; -} - static void init_buckets(void) { int i; @@ -36,6 +29,20 @@ static void init_buckets(void) } } +static void free_buckets(void) +{ + int i; + + for (i = 0; i < 4; ++i) { + DEL_ARR_F(node_buckets[i]); + } + + DEL_ARR_F(edge_bucket); + DEL_ARR_F(reduced_bucket); + + buckets_filled = 0; +} + static void fill_node_buckets(pbqp *pbqp) { unsigned node_index; @@ -103,7 +110,7 @@ static void normalize_towards_source(pbqp *pbqp, pbqp_edge *edge) if (min != 0) { pbqp_matrix_sub_row_value(mat, src_index, tgt_vec, min); - src_vec->entries[src_index].data = add( + src_vec->entries[src_index].data = pbqp_add( src_vec->entries[src_index].data, min); // TODO add to edge_list if inf @@ -148,7 +155,7 @@ static void normalize_towards_target(pbqp *pbqp, pbqp_edge *edge) if (min != 0) { pbqp_matrix_sub_col_value(mat, tgt_index, src_vec, min); - tgt_vec->entries[tgt_index].data = add( + tgt_vec->entries[tgt_index].data = pbqp_add( tgt_vec->entries[tgt_index].data, min); // TODO add to edge_list if inf @@ -307,9 +314,9 @@ void solve_pbqp_heuristical(pbqp *pbqp) if (ARR_LEN(edge_bucket) > 0) { panic("Please implement edge simplification"); } else if (ARR_LEN(node_buckets[1]) > 0) { - applyRI(pbqp); + apply_RI(pbqp); } else if (ARR_LEN(node_buckets[2]) > 0) { - panic("Please implement RII simplification"); + apply_RII(pbqp); } else if (ARR_LEN(node_buckets[3]) > 0) { panic("Please implement RN simplification"); } else { @@ -329,7 +336,7 @@ void solve_pbqp_heuristical(pbqp *pbqp) assert(node); node->solution = vector_get_min_index(node->costs); - pbqp->solution = add(pbqp->solution, + pbqp->solution = pbqp_add(pbqp->solution, node->costs->entries[node->solution].data); if (pbqp->dump_file) { fprintf(pbqp->dump_file, "node n%d is set to %d
\n", node->index, node->solution); @@ -354,16 +361,18 @@ void solve_pbqp_heuristical(pbqp *pbqp) back_propagate_RI(pbqp, node); break; case 2: - panic("Please implement back propagation for RII"); + back_propagate_RII(pbqp, node); break; default: panic("Only nodes with degree one or two should be in this bucket"); break; } } + + free_buckets(); } -void applyRI(pbqp *pbqp) +void apply_RI(pbqp *pbqp) { pbqp_node **bucket = node_buckets[1]; unsigned bucket_len = ARR_LEN(bucket); @@ -413,9 +422,9 @@ void applyRI(pbqp *pbqp) ARR_APP1(pbqp_node *, reduced_bucket, node); } -void applyRII(pbqp *pbqp) +void apply_RII(pbqp *pbqp) { - pbqp_node **bucket = node_buckets[1]; + pbqp_node **bucket = node_buckets[2]; unsigned bucket_len = ARR_LEN(bucket); pbqp_node *node = bucket[bucket_len - 1]; pbqp_edge *src_edge = node->edges[0]; @@ -437,6 +446,8 @@ void applyRII(pbqp *pbqp) unsigned row_len; unsigned node_len; + assert(pbqp); + if (src_is_src) { src_node = src_edge->tgt; } else { @@ -466,6 +477,19 @@ void applyRII(pbqp *pbqp) tgt_is_src = tgt_edge->src == node; } + if (pbqp->dump_file) { + char txt[100]; + sprintf(txt, "RII-Reduktion of Node n%d", node->index); + dump_section(pbqp->dump_file, 2, txt); + pbqp_dump_graph(pbqp); + fputs("
\nBefore reduction:
\n", pbqp->dump_file); + dump_node(pbqp, src_node); + dump_edge(pbqp, src_edge); + dump_node(pbqp, node); + dump_edge(pbqp, tgt_edge); + dump_node(pbqp, tgt_node); + } + src_mat = src_edge->costs; tgt_mat = tgt_edge->costs; @@ -473,9 +497,9 @@ void applyRII(pbqp *pbqp) tgt_vec = tgt_node->costs; node_vec = node->costs; - row_len = ARR_LEN(src_vec); - col_len = ARR_LEN(tgt_vec); - node_len = ARR_LEN(node_vec); + row_len = src_vec->len; + col_len = tgt_vec->len; + node_len = node_vec->len; mat = pbqp_matrix_alloc(pbqp, row_len, col_len); @@ -495,12 +519,25 @@ void applyRII(pbqp *pbqp) vector_add_matrix_row(vec, tgt_mat, col_index); } - mat->entries[row_index * col_len + col_index] = vector_get_min_index(vec); + mat->entries[row_index * col_len + col_index] = vector_get_min(vec); + + obstack_free(&pbqp->obstack, vec); } } pbqp_edge *edge = get_edge(pbqp, src_node->index, tgt_node->index); + /* Disconnect node. */ + disconnect_edge(src_node, src_edge); + disconnect_edge(tgt_node, tgt_edge); + + /* Remove node from bucket... */ + ARR_SHRINKLEN(bucket, (int)bucket_len - 1); + + /* ...and add it to back propagation list. */ + node->bucket_index = ARR_LEN(reduced_bucket); + ARR_APP1(pbqp_node *, reduced_bucket, node); + if (edge == NULL) { edge = alloc_edge(pbqp, src_node->index, tgt_node->index, mat); } else { @@ -508,11 +545,15 @@ void applyRII(pbqp *pbqp) /* Free local matrix. */ obstack_free(&pbqp->obstack, mat); + + reorder_node(src_node); + reorder_node(tgt_node); } - /* Disconnect node. */ - disconnect_edge(src_node, src_edge); - disconnect_edge(tgt_node, tgt_edge); + if (pbqp->dump_file) { + fputs("
\nAfter reduction:
\n", pbqp->dump_file); + dump_edge(pbqp, edge); + } /* Edge has changed so we simplify it. */ simplify_edge(pbqp, edge); @@ -550,6 +591,82 @@ void back_propagate_RI(pbqp *pbqp, pbqp_node *node) } } +void back_propagate_RII(pbqp *pbqp, pbqp_node *node) +{ + pbqp_edge *src_edge = node->edges[0]; + pbqp_edge *tgt_edge = node->edges[1]; + int src_is_src = src_edge->src == node; + int tgt_is_src = tgt_edge->src == node; + pbqp_matrix *src_mat; + pbqp_matrix *tgt_mat; + pbqp_node *src_node; + pbqp_node *tgt_node; + vector *vec; + vector *node_vec; + unsigned col_index; + unsigned row_index; + + assert(pbqp); + + if (src_is_src) { + src_node = src_edge->tgt; + } else { + src_node = src_edge->src; + } + + if (tgt_is_src) { + tgt_node = tgt_edge->tgt; + } else { + tgt_node = tgt_edge->src; + } + + /* Swap nodes if necessary. */ + if (tgt_node->index < src_node->index) { + pbqp_node *tmp_node; + pbqp_edge *tmp_edge; + + tmp_node = src_node; + src_node = tgt_node; + tgt_node = tmp_node; + + tmp_edge = src_edge; + src_edge = tgt_edge; + tgt_edge = tmp_edge; + + src_is_src = src_edge->src == node; + tgt_is_src = tgt_edge->src == node; + } + + src_mat = src_edge->costs; + tgt_mat = tgt_edge->costs; + + node_vec = node->costs; + + row_index = src_node->solution; + col_index = tgt_node->solution; + + vec = vector_copy(pbqp, node_vec); + + if (src_is_src) { + vector_add_matrix_col(vec, src_mat, row_index); + } else { + vector_add_matrix_row(vec, src_mat, row_index); + } + + if (tgt_is_src) { + vector_add_matrix_col(vec, tgt_mat, col_index); + } else { + vector_add_matrix_row(vec, tgt_mat, col_index); + } + + node->solution = vector_get_min_index(vec); + if (pbqp->dump_file) { + fprintf(pbqp->dump_file, "node n%d is set to %d
\n", node->index, node->solution); + } + + obstack_free(&pbqp->obstack, vec); +} + int node_is_reduced(pbqp_node *node) { if (!reduced_bucket) return 0;