fix: DAG of call() error when function has no arg.
fix: change pointer add / sub to address of array.
fix: optimize 'const teq'
}
}
- printf("\n");
return 0;
}
SCF_OP_3AC_DEC_POST_ARRAY_INDEX,
SCF_OP_3AC_ADDRESS_OF_ARRAY_INDEX,
+ // 97
SCF_OP_3AC_ASSIGN_POINTER, // left value, p->a = expr
SCF_OP_3AC_ADD_ASSIGN_POINTER,
SCF_OP_3AC_SUB_ASSIGN_POINTER,
}
}
+static int __dn_same_call(scf_dag_node_t* dn, const scf_node_t* node, const scf_node_t* split)
+{
+ scf_variable_t* v0 = _scf_operand_get(node);
+ scf_variable_t* v1 = dn->var;
+
+ if (split)
+ v0 = _scf_operand_get(split);
+
+ if (v0 && v0->w && v1 && v1->w) {
+ if (v0->type != v1->type) {
+ scf_logd("v0: %d/%s_%#lx, split_flag: %d\n", v0->w->line, v0->w->text->data, 0xffff & (uintptr_t)v0, node->split_flag);
+ scf_logd("v1: %d/%s_%#lx\n", v1->w->line, v1->w->text->data, 0xffff & (uintptr_t)v1);
+ }
+ }
+
+ return v0 == v1;
+}
+
int scf_dag_node_same(scf_dag_node_t* dn, const scf_node_t* node)
{
int i;
const scf_node_t* split = NULL;
if (node->split_flag) {
-
if (dn->var != _scf_operand_get(node))
return 0;
return 0;
}
- if (!dn->childs)
+ if (!dn->childs) {
+ if (SCF_OP_CALL == node->type && 1 == node->nb_nodes)
+ return __dn_same_call(dn, node, split);
return 0;
+ }
if (SCF_OP_TYPE_CAST == node->type) {
scf_dag_node_t* dn0 = dn->childs->data[0];
}
}
- if (SCF_OP_CALL == dn->type) {
-
- scf_variable_t* v0 = _scf_operand_get(node);
- scf_variable_t* v1 = dn->var;
-
- if (split)
- v0 = _scf_operand_get(split);
-
- if (v0 && v0->w && v1 && v1->w) {
- if (v0->type != v1->type) {
- scf_logd("v0: %d/%s_%#lx, split_flag: %d\n", v0->w->line, v0->w->text->data, 0xffff & (uintptr_t)v0, node->split_flag);
- scf_logd("v1: %d/%s_%#lx\n", v1->w->line, v1->w->text->data, 0xffff & (uintptr_t)v1);
- }
- }
+ if (SCF_OP_CALL == dn->type)
+ return __dn_same_call(dn, node, split);
- if (v0 != v1)
- return 0;
- }
return 1;
}
{SCF_OP_3AC_SUB_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_sub_assign_pointer},
{SCF_OP_3AC_AND_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_and_assign_pointer},
{SCF_OP_3AC_OR_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_or_assign_pointer},
+ {SCF_OP_3AC_INC_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_inc_pointer},
+ {SCF_OP_3AC_DEC_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_dec_pointer},
{SCF_OP_3AC_ASSIGN_DEREFERENCE, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_assign_dereference},
{SCF_OP_3AC_ADD_ASSIGN_DEREFERENCE, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_add_assign_dereference},
#endif
scf_dag_operator_t* op = scf_dag_operator_find(node->type);
if (!op) {
- scf_loge("node->type: %d, %d\n", node->type, SCF_OP_3AC_ADD_ASSIGN_DEREFERENCE);
+ scf_loge("node->type: %d, %d\n", node->type, SCF_OP_3AC_DEC_POINTER);
if (node->var && node->var->w)
scf_loge("node->var: %s\n", node->var->w->text->data);
return -1;
for (i = 0; i < bb->ds_malloced->size; i++) {
ds = bb->ds_malloced->data[i];
#if 1
- scf_loge("ds->ret: %u, ds->dag_node->var->arg_flag: %u\n", ds->ret, ds->dag_node->var->arg_flag);
+ scf_logi("ds->ret: %u, ds->dag_node->var->arg_flag: %u\n", ds->ret, ds->dag_node->var->arg_flag);
scf_dn_status_print(ds);
printf("\n");
#endif
_bb_find_ds_alias_leak(ds, c, bb, bb_list_head);
}
}
- scf_loge("f: %s *****\n\n", f->node.w->text->data);
+ scf_logi("f: %s *****\n\n", f->node.w->text->data);
return total;
}
.flags = SCF_OPTIMIZER_GLOBAL,
};
-
if (scf_list_empty(bb_list_head))
return 0;
-// scf_logi("------- %s() ------\n", f->node.w->text->data);
+ scf_logd("------- %s() ------\n", f->node.w->text->data);
for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); l = scf_list_next(l)) {
l2 = scf_list_head(&bb2->code_list_head);
c = scf_list_data(l2, scf_3ac_code_t, list);
- if (SCF_OP_3AC_JZ == c->op->type) {
+ if (!jmp_flag) {
+ if (SCF_OP_3AC_JZ == c->op->type) {
- if (0 == flag) {
- c->op = scf_3ac_find_operator(SCF_OP_GOTO);
- jmp_flag = 1;
- continue;
- }
+ if (0 == flag) {
+ c->op = scf_3ac_find_operator(SCF_OP_GOTO);
+ jmp_flag = 1;
+ continue;
+ }
- } else if (SCF_OP_3AC_JNZ == c->op->type) {
+ } else if (SCF_OP_3AC_JNZ == c->op->type) {
- if (1 == flag) {
- c->op = scf_3ac_find_operator(SCF_OP_GOTO);
+ if (1 == flag) {
+ c->op = scf_3ac_find_operator(SCF_OP_GOTO);
+ jmp_flag = 1;
+ continue;
+ }
+
+ } else if (SCF_OP_GOTO == c->op->type) {
jmp_flag = 1;
continue;
+ } else {
+ scf_loge("\n");
+ return -EINVAL;
}
-
- } else if (SCF_OP_GOTO == c->op->type) {
- jmp_flag = 1;
- continue;
- } else {
- scf_loge("\n");
- return -EINVAL;
}
assert(c->dsts && 1 == c->dsts->size);
if (jmp_flag && bb2 && !bb2->jmp_flag) {
- assert(0 == scf_vector_del(bb2->prevs, bb));
+ scf_vector_del(bb2->prevs, bb);
}
int ret;
if (scf_list_empty(bb_list_head))
return 0;
+ scf_logd("------- %s() ------\n", f->node.w->text->data);
+
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 (ds->dn_indexes)
return 0;
- scf_loge("pointer '%s' is not inited, file: %s, line: %d\n", v->w->text->data, v->w->file->data, v->w->line);
+ if (v->tmp_flag)
+ return 0;
+
+ scf_loge("pointer '%s' is not inited, tmp_flag: %d, local_flag: %d, file: %s, line: %d\n",
+ v->w->text->data, v->tmp_flag, v->local_flag, v->w->file->data, v->w->line);
return SCF_POINTER_NOT_INIT;
}
ds->alias = dn_alias;
ds->alias_type = SCF_DN_ALIAS_VAR;
- scf_dn_status_print(ds);
-
ret = scf_vector_add(aliases, ds);
if (ret < 0) {
scf_dn_status_free(ds);
scf_ModRM_setReg(&ModRM, reg);
scf_ModRM_setRM(&ModRM, SCF_X64_RM_SIB);
- if (SCF_X64_RM_EBP != r_base->id && SCF_X64_RM_ESP != r_base->id && 0 == disp)
+ if (SCF_X64_RM_EBP != r_base->id
+ && SCF_X64_RM_ESP != r_base->id
+ && SCF_X64_RM_R12 != r_base->id
+ && SCF_X64_RM_R13 != r_base->id
+ && 0 == disp)
scf_ModRM_setMod(&ModRM, SCF_X64_MOD_BASE);
else {
if (disp <= 127 && disp >= -128)
};
inst->code[inst->len++] = SIB;
- if (SCF_X64_RM_EBP == r_base->id || SCF_X64_RM_ESP == r_base->id || 0 != disp) {
+ if (SCF_X64_RM_EBP == r_base->id
+ || SCF_X64_RM_ESP == r_base->id
+ || SCF_X64_RM_R12 == r_base->id
+ || SCF_X64_RM_R13 == r_base->id
+ || 0 != disp) {
if (disp <= 127 && disp >= -128)
inst->code[inst->len++] = (int8_t)disp;
return 0;
}
+static int _semantic_pointer_add(scf_ast_t* ast, scf_node_t* parent, scf_node_t* pointer, scf_node_t* index)
+{
+ scf_variable_t* r;
+ scf_variable_t* v = _scf_operand_get(pointer);
+ scf_type_t* t = NULL;
+ scf_node_t* add;
+
+ int ret = scf_ast_find_type_type(&t, ast, v->type);
+ if (ret < 0)
+ return ret;
+
+ add = scf_node_alloc(parent->w, SCF_OP_ARRAY_INDEX, NULL);
+ if (!add)
+ return -ENOMEM;
+
+ r = SCF_VAR_ALLOC_BY_TYPE(parent->w, t, v->const_flag, scf_variable_nb_pointers(v), v->func_ptr);
+ if (!r) {
+ scf_node_free(add);
+ return -ENOMEM;
+ }
+ r->local_flag = 1;
+ r->tmp_flag = 1;
+
+ add->result = r;
+ r = NULL;
+
+ ret = scf_node_add_child(add, pointer);
+ if (ret < 0) {
+ scf_node_free(add);
+ return ret;
+ }
+
+ ret = scf_node_add_child(add, index);
+ if (ret < 0) {
+ pointer->parent = parent;
+
+ add->nb_nodes = 0;
+ scf_node_free(add);
+ return ret;
+ }
+
+ add->parent = parent;
+
+ parent->nodes[0] = add;
+ parent->nodes[1] = NULL;
+ parent->nb_nodes = 1;
+
+ parent->op = scf_find_base_operator_by_type(SCF_OP_ADDRESS_OF);
+ parent->type = SCF_OP_ADDRESS_OF;
+ return 0;
+}
+
static int _scf_op_semantic_binary(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(2 == nb_nodes);
scf_variable_t* v2 = NULL;
scf_type_t* t = NULL;
- int const_flag = 0;
- int nb_pointers = 0;
- int nb_pointers0 = scf_variable_nb_pointers(v0);
- int nb_pointers1 = scf_variable_nb_pointers(v1);
+ int const_flag = 0;
+ int nb_pointers = 0;
+ int nb_pointers0 = scf_variable_nb_pointers(v0);
+ int nb_pointers1 = scf_variable_nb_pointers(v1);
+ int add_flag = 0;
if (nb_pointers0 > 0) {
scf_loge("add type cast failed\n");
return ret;
}
+
+ if (SCF_OP_ADD == parent->type || SCF_OP_SUB == parent->type) {
+
+ ret = _semantic_pointer_add(ast, parent, nodes[0], nodes[1]);
+ if (ret < 0)
+ return ret;
+ add_flag = 1;
+ }
}
t = NULL;
if (!scf_variable_integer(v0)) {
scf_loge("var calculated with a pointer should be a interger\n");
return -EINVAL;
+
} else {
+ if (SCF_OP_SUB == parent->type) {
+ scf_loge("only a pointer sub an integer, NOT reverse, file: %s, line: %d\n", parent->w->file->data, parent->w->line);
+ return -1;
+ }
+
t = scf_block_find_type_type(ast->current_block, SCF_VAR_UINTPTR);
v2 = SCF_VAR_ALLOC_BY_TYPE(v0->w, t, v0->const_flag, 0, NULL);
scf_loge("add type cast failed\n");
return ret;
}
+
+ if (SCF_OP_ADD == parent->type) {
+ ret = _semantic_pointer_add(ast, parent, nodes[1], nodes[0]);
+ if (ret < 0)
+ return ret;
+
+ add_flag = 1;
+ }
}
t = NULL;
func_ptr = NULL;
}
- scf_lex_word_t* w = nodes[0]->parent->w;
+ scf_lex_word_t* w = parent->w;
scf_variable_t* r = SCF_VAR_ALLOC_BY_TYPE(w, t, const_flag, nb_pointers, func_ptr);
- if (!r) {
- scf_loge("var alloc failed\n");
+ if (!r)
return -ENOMEM;
- }
+
+ r->tmp_flag = add_flag;
*d->pret = r;
return 0;