if (!bb->nexts)
goto error_nexts;
+ bb->entry_dn_delivery = scf_vector_alloc();
+ if (!bb->entry_dn_delivery)
+ goto error_entry_delivery;
+
+ bb->entry_dn_inactives = scf_vector_alloc();
+ if (!bb->entry_dn_inactives)
+ goto error_entry_inactive;
+
bb->entry_dn_actives = scf_vector_alloc();
if (!bb->entry_dn_actives)
- goto error_entry;
+ goto error_entry_active;
bb->exit_dn_actives = scf_vector_alloc();
if (!bb->exit_dn_actives)
scf_vector_free(bb->exit_dn_actives);
error_exit:
scf_vector_free(bb->entry_dn_actives);
-error_entry:
+error_entry_active:
+ scf_vector_free(bb->entry_dn_inactives);
+error_entry_inactive:
+ scf_vector_free(bb->entry_dn_delivery);
+error_entry_delivery:
scf_vector_free(bb->nexts);
error_nexts:
scf_vector_free(bb->prevs);
static int _copy_to_active_vars(scf_vector_t* active_vars, scf_vector_t* dag_nodes)
{
scf_dag_node_t* dn;
- scf_dn_status_t* status;
+ scf_dn_status_t* ds;
int i;
for (i = 0; i < dag_nodes->size; i++) {
+ dn = dag_nodes->data[i];
- dn = dag_nodes->data[i];
-
- status = scf_vector_find_cmp(active_vars, dn, scf_dn_status_cmp);
+ ds = scf_vector_find_cmp(active_vars, dn, scf_dn_status_cmp);
- if (!status) {
- status = scf_dn_status_alloc(dn);
- if (!status)
+ if (!ds) {
+ ds = scf_dn_status_alloc(dn);
+ if (!ds)
return -ENOMEM;
- int ret = scf_vector_add(active_vars, status);
+ int ret = scf_vector_add(active_vars, ds);
if (ret < 0) {
- scf_dn_status_free(status);
+ scf_dn_status_free(ds);
return ret;
}
}
#if 0
- status->alias = dn->alias;
- status->value = dn->value;
+ ds->alias = dn->alias;
+ ds->value = dn->value;
#endif
- status->active = dn->active;
- status->inited = dn->inited;
- status->updated = dn->updated;
-
- dn->inited = 0;
+ ds->active = dn->active;
+ ds->inited = dn->inited;
+ ds->updated = dn->updated;
+ dn->inited = 0;
}
return 0;
}
-static int _copy_from_active_vars(scf_vector_t* dag_nodes, scf_vector_t* active_vars)
+static int _copy_vars_by_active(scf_vector_t* dn_vec, scf_vector_t* ds_vars, int active)
{
- if (!dag_nodes)
+ if (!dn_vec)
return -EINVAL;
- if (!active_vars)
+ if (!ds_vars)
return 0;
+ scf_dn_status_t* ds;
+ scf_dag_node_t* dn;
+
int j;
- for (j = 0; j < active_vars->size; j++) {
- scf_dn_status_t* v = active_vars->data[j];
- scf_dag_node_t* dn = v->dag_node;
+
+ for (j = 0; j < ds_vars->size; j++) {
+ ds = ds_vars->data[j];
+
+ dn = ds->dag_node;
if (scf_variable_const(dn->var))
continue;
- if (!v->active)
- continue;
+ if (active == ds->active && scf_dn_through_bb(dn)) {
- if (scf_dn_through_bb(dn)) {
- int ret = scf_vector_add_unique(dag_nodes, dn);
+ int ret = scf_vector_add_unique(dn_vec, dn);
if (ret < 0)
return ret;
}
return 0;
}
-static int _copy_updated_vars(scf_vector_t* dag_nodes, scf_vector_t* active_vars)
+static int _copy_updated_vars(scf_vector_t* dn_vec, scf_vector_t* ds_vars)
{
- if (!dag_nodes)
+ if (!dn_vec)
return -EINVAL;
- if (!active_vars)
+ if (!ds_vars)
return 0;
+ scf_dn_status_t* ds;
+ scf_dag_node_t* dn;
+
int j;
- for (j = 0; j < active_vars->size; j++) {
- scf_dn_status_t* v = active_vars->data[j];
- scf_dag_node_t* dn = v->dag_node;
+
+ for (j = 0; j < ds_vars->size; j++) {
+ ds = ds_vars->data[j];
+
+ dn = ds->dag_node;
if (scf_variable_const(dn->var))
continue;
- if (!v->updated)
+ if (!ds->updated)
continue;
if (scf_dn_through_bb(dn)) {
- int ret = scf_vector_add_unique(dag_nodes, dn);
+ int ret = scf_vector_add_unique(dn_vec, dn);
if (ret < 0)
return ret;
}
l = scf_list_head(&bb->code_list_head);
c = scf_list_data(l, scf_3ac_code_t, list);
- ret = _copy_from_active_vars(bb->entry_dn_actives, c->active_vars);
+ ret = _copy_vars_by_active(bb->entry_dn_actives, c->active_vars, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = _copy_vars_by_active(bb->entry_dn_inactives, c->active_vars, 0);
if (ret < 0)
return ret;
#include"scf_optimizer.h"
-typedef int (*bb_find_pt)(scf_basic_block_t* bb, scf_vector_t* queue);
-
-static int _bb_prev_find(scf_basic_block_t* bb, scf_vector_t* queue)
+static int _bb_prev_find(scf_basic_block_t* bb, void* data, scf_vector_t* queue)
{
scf_basic_block_t* prev_bb;
scf_dag_node_t* dn;
int count = 0;
int ret;
int j;
+ int k;
+
+ for (k = 0; k < bb->exit_dn_actives->size; k++) {
+ dn = bb->exit_dn_actives->data[k];
+
+ if (scf_vector_find(bb->entry_dn_inactives, dn))
+ continue;
+
+ if (scf_vector_find(bb->entry_dn_actives, dn))
+ continue;
+
+ if (scf_vector_find(bb->entry_dn_delivery, dn))
+ continue;
+
+ ret = scf_vector_add(bb->entry_dn_delivery, dn);
+ if (ret < 0)
+ return ret;
+ ++count;
+ }
for (j = 0; j < bb->prevs->size; j++) {
prev_bb = bb->prevs->data[j];
- int k;
for (k = 0; k < bb->entry_dn_actives->size; k++) {
dn = bb->entry_dn_actives->data[k];
++count;
}
- ret = scf_vector_add(queue, prev_bb);
- if (ret < 0)
- return ret;
- }
- return count;
-}
-
-static int _bb_next_find(scf_basic_block_t* bb, scf_vector_t* queue)
-{
- scf_basic_block_t* next_bb;
- scf_dag_node_t* dn;
-
- int count = 0;
- int ret;
- int j;
-
- for (j = 0; j < bb->nexts->size; j++) {
- next_bb = bb->nexts->data[j];
-
- int k;
- for (k = 0; k < next_bb->exit_dn_actives->size; k++) {
- dn = next_bb->exit_dn_actives->data[k];
-
- if (scf_vector_find(next_bb->dn_updateds, dn))
- continue;
+ for (k = 0; k < bb->entry_dn_delivery->size; k++) {
+ dn = bb->entry_dn_delivery->data[k];
- if (scf_vector_find(bb->exit_dn_actives, dn))
+ if (scf_vector_find(prev_bb->exit_dn_actives, dn))
continue;
- ret = scf_vector_add(bb->exit_dn_actives, dn);
+ ret = scf_vector_add(prev_bb->exit_dn_actives, dn);
if (ret < 0)
return ret;
++count;
}
- ret = scf_vector_add(queue, next_bb);
+ ret = scf_vector_add(queue, prev_bb);
if (ret < 0)
return ret;
}
return count;
}
-static int _bb_search_bfs(scf_basic_block_t* root, bb_find_pt find)
-{
- if (!root)
- return -EINVAL;
-
- scf_vector_t* queue = scf_vector_alloc();
- if (!queue)
- return -ENOMEM;
-
- scf_vector_t* checked = scf_vector_alloc();
- if (!queue) {
- scf_vector_free(queue);
- return -ENOMEM;
- }
-
- int ret = scf_vector_add(queue, root);
- if (ret < 0)
- goto failed;
-
- int count = 0;
- int i = 0;
-
- while (i < queue->size) {
- scf_basic_block_t* bb = queue->data[i];
-
- int j;
- for (j = 0; j < checked->size; j++) {
- if (bb == checked->data[j])
- goto next;
- }
-
- ret = scf_vector_add(checked, bb);
- if (ret < 0)
- goto failed;
-
- ret = find(bb, queue);
- if (ret < 0)
- goto failed;
- count += ret;
-next:
- i++;
- }
-
- ret = count;
-failed:
- scf_vector_free(queue);
- scf_vector_free(checked);
- queue = NULL;
- checked = NULL;
- return ret;
-}
-
static int _optimize_active_vars(scf_ast_t* ast, scf_function_t* f, scf_list_t* bb_list_head, scf_vector_t* functions)
{
if (!f || !bb_list_head)
bb = scf_list_data(l, scf_basic_block_t, list);
assert(bb->end_flag);
- ret = _bb_search_bfs(bb, _bb_prev_find);
+ ret = scf_basic_block_search_bfs(bb, _bb_prev_find, NULL);
if (ret < 0)
return ret;
count = ret;
- l = scf_list_head(bb_list_head);
- bb = scf_list_data(l, scf_basic_block_t, list);
-
- ret = _bb_search_bfs(bb, _bb_next_find);
- if (ret < 0)
- return ret;
- count += ret;
} while (count > 0);
// scf_basic_block_print_list(bb_list_head);