int j;
if (c->dsts) {
-
for (j = 0; j < c->dsts->size; j++) {
dst = c->dsts->data[j];
}
}
+ printf("\n");
return 0;
}
scf_3ac_operand_t* dst;
int ret = 0;
+ int i;
if (scf_type_is_assign(c->op->type)) {
|| scf_type_is_assign_dereference(c->op->type)
|| scf_type_is_assign_pointer(c->op->type)) {
- scf_dag_node_t* assign;
+ scf_dag_node_t* assign;
assert(c->srcs);
return -ENOMEM;
scf_list_add_tail(dag, &assign->list);
- int i;
for (i = 0; i < c->srcs->size; i++) {
- src = c->srcs->data[i];
- assert(src && src->node);
+ src = c->srcs->data[i];
ret = scf_dag_get_node(dag, src->node, &src->dag_node);
if (ret < 0)
} else if (SCF_OP_3AC_CMP == c->op->type
|| SCF_OP_3AC_TEQ == c->op->type) {
- scf_dag_node_t* dn_cmp = scf_dag_node_alloc(c->op->type, NULL, NULL);
+ scf_dag_node_t* dn_cmp = scf_dag_node_alloc(c->op->type, NULL, NULL);
scf_list_add_tail(dag, &dn_cmp->list);
assert(c->dsts && 1 == c->dsts->size);
dst = c->dsts->data[0];
- scf_dag_node_t* dn_setcc = scf_dag_node_alloc(c->op->type, NULL, NULL);
+ scf_dag_node_t* dn_setcc = scf_dag_node_alloc(c->op->type, NULL, NULL);
scf_list_add_tail(dag, &dn_setcc->list);
ret = scf_dag_get_node(dag, dst->node, &dst->dag_node);
|| SCF_OP_DEC_POST == c->op->type
|| SCF_OP_3AC_INC == c->op->type
|| SCF_OP_3AC_DEC == c->op->type) {
-
src = c->srcs->data[0];
assert(src->node->parent);
- scf_variable_t* v_parent = _scf_operand_get(src->node->parent);
- scf_dag_node_t* dn_parent = scf_dag_node_alloc(c->op->type, v_parent, NULL);
+
+ scf_variable_t* v_parent = _scf_operand_get(src->node->parent);
+ scf_dag_node_t* dn_parent = scf_dag_node_alloc(c->op->type, v_parent, NULL);
+
scf_list_add_tail(dag, &dn_parent->list);
ret = scf_dag_get_node(dag, src->node, &src->dag_node);
assert(dst->node);
dst->dag_node = dn_parent;
}
+
+ } else if (SCF_OP_TYPE_CAST == c->op->type) {
+
+ src = c->srcs->data[0];
+ dst = c->dsts->data[0];
+
+ ret = scf_dag_get_node(dag, src->node, &src->dag_node);
+ if (ret < 0)
+ return ret;
+
+ ret = scf_dag_get_node(dag, dst->node, &dst->dag_node);
+ if (ret < 0)
+ return ret;
+
+ if (!scf_dag_node_find_child(dst->dag_node, src->dag_node)) {
+
+ ret = scf_dag_node_add_child(dst->dag_node, src->dag_node);
+ if (ret < 0)
+ return ret;
+ }
+
} else if (SCF_OP_RETURN == c->op->type) {
if (c->srcs) {
- scf_dag_node_t* dn_return = scf_dag_node_alloc(c->op->type, NULL, NULL);
+ scf_dag_node_t* dn_return = scf_dag_node_alloc(c->op->type, NULL, NULL);
scf_list_add_tail(dag, &dn_return->list);
- int i;
for (i = 0; i < c->srcs->size; i++) {
src = c->srcs->data[i];
scf_logd("c->op: %d, name: %s\n", c->op->type, c->op->name);
} else {
- int nb_operands0 = -1;
- int nb_operands1 = -1;
+ int n_operands0 = -1;
+ int n_operands1 = -1;
if (c->dsts) {
dst = c->dsts->data[0];
assert(dst->node->op);
- nb_operands0 = dst->node->op->nb_operands;
- nb_operands1 = nb_operands0;
+ n_operands0 = dst->node->op->nb_operands;
+ n_operands1 = n_operands0;
switch (c->op->type) {
case SCF_OP_ARRAY_INDEX:
case SCF_OP_3AC_DEC_POST_ARRAY_INDEX:
case SCF_OP_VA_START:
case SCF_OP_VA_ARG:
- nb_operands0 = 3;
+ n_operands0 = 3;
break;
case SCF_OP_3AC_ADDRESS_OF_POINTER:
case SCF_OP_VA_END:
- nb_operands0 = 2;
+ n_operands0 = 2;
break;
case SCF_OP_CALL:
- nb_operands0 = c->srcs->size;
+ n_operands0 = c->srcs->size;
break;
default:
break;
};
}
- return _3ac_code_to_dag(c, dag, nb_operands0, nb_operands1);
+ return _3ac_code_to_dag(c, dag, n_operands0, n_operands1);
}
return 0;
return dn;
}
+int scf_dag_node_find_child(scf_dag_node_t* parent, scf_dag_node_t* child)
+{
+ if (parent->childs
+ && scf_vector_find(parent->childs, child))
+ return 1;
+ return 0;
+}
+
int scf_dag_node_add_child(scf_dag_node_t* parent, scf_dag_node_t* child)
{
if (!parent || !child)
scf_dag_node_t* scf_dag_node_alloc(int type, scf_variable_t* var, const scf_node_t* node);
int scf_dag_node_add_child (scf_dag_node_t* parent, scf_dag_node_t* child);
+int scf_dag_node_find_child(scf_dag_node_t* parent, scf_dag_node_t* child);
int scf_dag_node_same (scf_dag_node_t* dag_node, const scf_node_t* node);
void scf_dag_node_free (scf_dag_node_t* dag_node);
break;
case SCF_LEX_WORD_CONST_STRING:
+ if (w->data.s) {
+ w1->data.s = scf_string_clone(w->data.s);
- w1->data.s = scf_string_clone(w->data.s);
- if (!w1->data.s) {
- free(w1);
- return NULL;
+ if (!w1->data.s) {
+ free(w1);
+ return NULL;
+ }
}
break;
void scf_lex_word_free(scf_lex_word_t* w)
{
if (w) {
- if (SCF_LEX_WORD_CONST_STRING == w->type)
- scf_string_free(w->data.s);
+ if (SCF_LEX_WORD_CONST_STRING == w->type) {
+ if (w->data.s)
+ scf_string_free(w->data.s);
+ }
if (w->text)
scf_string_free(w->text);
int scf_dag_expr_calculate(scf_list_t* h, scf_dag_node_t* node)
{
- if (!node) {
+ if (!node)
return 0;
- }
if (!node->childs || 0 == node->childs->size) {
.flags = SCF_OPTIMIZER_LOCAL,
};
-
#include"scf_optimizer.h"
-static int _bb_dfs_del(scf_basic_block_t* bb, scf_function_t* f)
+static void __bb_dfs_del(scf_basic_block_t* bb, scf_function_t* f)
{
scf_3ac_operand_t* dst;
scf_basic_block_t* bb2;
for (i = 0; i < bb->nexts->size; ) {
bb2 = bb->nexts->data[i];
- assert(0 == scf_vector_del(bb ->nexts, bb2));
- assert(0 == scf_vector_del(bb2->prevs, bb));
+ assert(0 == scf_vector_del(bb->nexts, bb2));
- if (bb2->prevs->size > 0)
+ if (bb2->prevs->size > 1) {
+ assert(0 == scf_vector_del(bb2->prevs, bb));
continue;
+ }
assert(&bb2->list != scf_list_head(&f->basic_block_list_head));
- if (_bb_dfs_del(bb2, f) < 0)
- return -1;
+ __bb_dfs_del(bb2, f);
+
+ assert(0 == scf_vector_del(bb2->prevs, bb));
+
+ scf_logd("bb2: %#lx, bb2->index: %d, prevs->size: %d\n", 0xffff & (uintptr_t)bb2, bb2->index, bb2->prevs->size);
+
+ scf_list_del(&bb2->list);
+ scf_basic_block_free(bb2);
+ bb2 = NULL;
}
if (scf_list_prev(&bb->list) != sentinel &&
}
}
}
-
- scf_list_del(&bb->list);
- scf_basic_block_free(bb);
- bb = NULL;
- return 0;
}
static int __optimize_const_teq(scf_basic_block_t* bb, scf_function_t* f)
assert(0 == scf_vector_del(bb->nexts, bb2));
- if (0 == bb2->prevs->size) {
- if (_bb_dfs_del(bb2, f) < 0)
- return -1;
+ if (0 == bb2->prevs->size &&
+ &bb2->list != scf_list_head(&f->basic_block_list_head)) {
+
+ assert(0 == scf_vector_add(bb2->prevs, bb));
+
+ __bb_dfs_del(bb2, f);
+
+ assert(0 == scf_vector_del(bb2->prevs, bb));
+
+ scf_list_del(&bb2->list);
+ scf_basic_block_free(bb2);
+ bb2 = NULL;
}
}
scf_list_t* bb_list_head = &f->basic_block_list_head;
scf_list_t* l;
scf_basic_block_t* bb;
+ scf_basic_block_t* bb2;
if (scf_list_empty(bb_list_head))
return 0;
- for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head);
- l = scf_list_next(l)) {
-
- bb = scf_list_data(l, scf_basic_block_t, list);
+ for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); l = scf_list_next(l)) {
+ bb = scf_list_data(l, scf_basic_block_t, list);
if (!bb->cmp_flag)
continue;
int ret = __optimize_const_teq(bb, f);
- if (ret < 0) {
- scf_loge("\n");
+ if (ret < 0)
return ret;
+ }
+
+ for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); ) {
+ bb = scf_list_data(l, scf_basic_block_t, list);
+
+ l = scf_list_next(l);
+
+ if (!bb->cmp_flag)
+ continue;
+
+ if (0 == bb->prevs->size && scf_list_empty(&bb->code_list_head)) {
+
+ int i;
+ for (i = 0; i < bb->nexts->size; ) {
+ bb2 = bb->nexts->data[i];
+
+ assert(0 == scf_vector_del(bb ->nexts, bb2));
+ assert(0 == scf_vector_del(bb2->prevs, bb));
+ }
+
+ scf_list_del(&bb->list);
+ scf_basic_block_free(bb);
+ bb = NULL;
}
}
.flags = SCF_OPTIMIZER_LOCAL,
};
-
pointer = c->srcs->data[0];
- ret = scf_vector_del(c->srcs, pointer);
+ ret = scf_vector_del(c->srcs, pointer);
if (ret < 0) {
scf_loge("\n");
return ret;
if (1 == aliases->size) {
status = aliases->data[0];
- if (SCF_DN_ALIAS_VAR == status->alias_type) {
+ if (SCF_DN_ALIAS_VAR == status->alias_type && !scf_variable_const_integer(status->alias->var)) {
ret = _3ac_pointer_alias(status->alias, c, bb, bb_list_head);
scf_list_t* l2;
int ret;
- int i;
scf_logd("alias: v_%d_%d/%s\n", v->w->line, v->w->pos, v->w->text->data);
}
return ret;
- } else if (sizeof(void*) == dn_alias->var->size) {
+ } else if (sizeof(void*) == dn_alias->var->size || scf_variable_const_integer(dn_alias->var)) {
ds = scf_dn_status_null();
if (!ds)
--- /dev/null
+int printf(const char* fmt, ...);
+
+#define assert(x) \
+ do { \
+ if (!(x)) {\
+ printf("assert: '%s' failed. file: %s, line: %d\n", #x, __FILE__, __LINE__); \
+ *(int*)0 = 0; \
+ } \
+ } while (0)
+
+int main()
+{
+ assert(0);
+ return 0;
+}
if (w)
w->data.u64 = lex->nb_lines;
- } else if (!strcmp(s->data, "__func__")) {
+ } else if (!strcmp(s->data, "__FILE__")) {
w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_STRING);
+ if (w)
+ w->data.s = scf_string_clone(lex->file);
+
+ } else if (!strcmp(s->data, "__func__")) {
+ w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_STRING);
} else {
int type = _find_key_word(s->data);
break;
if ('\n' == c2->c)
- c->c = ' ';
+ c2->flag = 0;
}
}
c = _lex_pop_char(lex);
- while ('\n' == c->c || '\r' == c->c || '\t' == c->c || ' ' == c->c) {
+ while ('\n' == c->c
+ || '\r' == c->c || '\t' == c->c
+ || ' ' == c->c || '\\' == c->c) {
if ('\n' == c->c) {
lex->nb_lines++;
return -ENOMEM;
}
- for (w = h->next; w; w = w->next) {
+ while ( h->next) {
+ w = h->next;
if (SCF_LEX_WORD_CONST_STRING != w->type)
s = w->text;
int ret = scf_string_cat(h->data.s, s);
if (ret < 0)
return ret;
+
+ ret = scf_string_cat(h->text, w->text);
+ if (ret < 0)
+ return ret;
+
+ h->next = w->next;
+
+ scf_lex_word_free(w);
+ w = NULL;
}
- scf_logw("h: %s, file: %s, line: %d\n", h->data.s->data, h->file->data, h->line);
+ scf_logw("h: '%s', file: %s, line: %d\n", h->data.s->data, h->file->data, h->line);
return 0;
}
continue;
}
- scf_logd("p: %s, line: %d, hash: %d\n", p->text->data, p->line, hash);
+ scf_logd("p: '%s', line: %d, hash: %d\n", p->text->data, p->line, hash);
if (m->argv) {
assert(argv);
}
if (i < m->argv->size) {
- w = argv->data[i];
+ scf_lex_word_t** tmp = pp;
- if (1 == hash) {
- ret = __convert_str(w);
- if (ret < 0)
+ for (w = argv->data[i]; w; w = w->next) {
+
+ *pp = scf_lex_word_clone(w);
+ if (!*pp) {
+ ret = -ENOMEM;
goto error;
+ }
- scf_slist_clear(w->next, scf_lex_word_t, next, scf_lex_word_free);
- w->next = NULL;
- }
+ if (!strcmp((*pp)->text->data, "__LINE__"))
+ (*pp)->data.u64 = use->line;
- *pp = w;
- while (w) {
- pp = &w->next;
- w = w->next;
+ pp = &(*pp)->next;
}
- argv->data[i] = NULL;
+ if (1 == hash) {
+ ret = __convert_str(*tmp);
+ if (ret < 0)
+ goto error;
+
+ pp = &(*tmp)->next;
+ }
hash = 0;
continue;
goto error;
}
+ if (!strcmp((*pp)->text->data, "__LINE__"))
+ (*pp)->data.u64 = use->line;
+
pp = &(*pp)->next;
hash = 0;
int printf(const char* fmt, ...);
+int rand();
+void srand(uint32_t seed);
+int atoi(const char* s);
+
void* malloc (uintptr_t size);
void* calloc (uintptr_t n, uintptr_t size);
void* realloc(void* p, uintptr_t size);
void scf__auto_freep_array(void** pp, int nb_pointers, scf__release_pt* release);
void scf__auto_free_array (void** pp, int size, int nb_pointers, scf__release_pt* release);
+uintptr_t time(uintptr_t* t);
+
uintptr_t strlen (const char *s);
int strcmp (const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, uintptr_t n);
}
var = SCF_VAR_ALLOC_BY_TYPE(id->identity, pt, 1, 1, f);
- if (!var) {
- scf_loge("var '%s' alloc failed\n", w->text->data);
- return SCF_DFA_ERROR;
- }
+ if (!var)
+ return -ENOMEM;
+
var->const_literal_flag = 1;
}
- scf_loge("var: %s, member_flag: %d, line: %d\n", var->w->text->data, var->member_flag, var->w->line);
+ scf_logd("var: %s, member_flag: %d, line: %d\n", var->w->text->data, var->member_flag, var->w->line);
node = scf_node_alloc(w, var->type, var);
- if (!node) {
- scf_loge("var node '%s' alloc failed\n", w->text->data);
- return SCF_DFA_ERROR;
- }
+ if (!node)
+ return -ENOMEM;
if (!d->expr) {
d->expr = scf_expr_alloc();
- if (!d->expr) {
- scf_loge("expr alloc failed\n");
- return SCF_DFA_ERROR;
- }
+ if (!d->expr)
+ return -ENOMEM;
}
scf_logd("d->expr: %p, node: %p\n", d->expr, node);
assert(nodes);
scf_variable_t* fret = f->rets->data[i];
- scf_expr_t* e = nodes[i];
scf_variable_t* r = NULL;
+ scf_expr_t* e = nodes[i];
if (SCF_VAR_VOID == fret->type && 0 == fret->nb_pointers) {
- scf_loge("void function needs no return value\n");
+ scf_loge("void function needs no return value, file: %s, line: %d\n", e->parent->w->file->data, e->parent->w->line);
return -1;
}
}
assert(scf_list_empty(&h));
-// scf_basic_block_print_list(&f->basic_block_list_head);
+ scf_basic_block_print_list(&f->basic_block_list_head);
}
int ret = scf_optimize(parse->ast, functions);