for source code as 'if (obj)', 'if (!obj)', or 'if (Boolean(0))', etc.
<script>
-var s0 = "123";
-var s1 = "124";
-
-document.write(s0 == s1);
-document.write("<br>");
-
-if (s0 == s1)
+if (Boolean(0))
document.write(true);
else
document.write(false);
CFILES += ../js/core/scf_optimizer_inline.c
CFILES += ../js/core/scf_optimizer_js_array.c
+CFILES += ../js/core/scf_optimizer_js_teq.c
CFILES += ../js/core/scf_optimizer_js_call.c
CFILES += ../js/core/scf_optimizer_split_call.c
if (!dn->childs) {
if (SCF_OP_CALL == node->type /*&& 1 == node->nb_nodes*/) {
int ret = __dn_same_call(dn, node, split);
+ scf_logd("ret: %d\n", ret);
return ret;
}
}
}
- if (dn->childs->size != node->nb_nodes)
+ if (dn->childs->size != node->nb_nodes) {
+ if (SCF_OP_CALL == node->type /*&& 1 == node->nb_nodes*/) {
+ int ret = __dn_same_call(dn, node, split);
+ scf_logd("ret: %d\n", ret);
+ return ret;
+ }
+
return 0;
+ }
cmp_childs:
for (i = 0; i < node->nb_nodes; i++) {
if (SCF_OP_CALL == dn->type) {
int ret = __dn_same_call(dn, node, split);
+ scf_logd("ret: %d\n", ret);
return ret;
}
node2 = node;
v = _scf_operand_get((scf_node_t*)node2);
-
dn = scf_dag_find_node(h, node2);
if (!dn) {
}
SCF_OP_CMP(eq, ==, SCF_OP_EQ)
+SCF_OP_CMP(ne, ==, SCF_OP_NE)
SCF_OP_CMP(gt, >, SCF_OP_GT)
SCF_OP_CMP(lt, <, SCF_OP_LT)
{SCF_OP_BIT_OR, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_or},
{SCF_OP_EQ, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_eq},
+ {SCF_OP_NE, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_ne},
{SCF_OP_GT, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_gt},
{SCF_OP_LT, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_lt},
extern scf_optimizer_t scf_optimizer_inline;
extern scf_optimizer_t scf_optimizer_js_array;
+extern scf_optimizer_t scf_optimizer_js_teq;
extern scf_optimizer_t scf_optimizer_js_call;
extern scf_optimizer_t scf_optimizer_split_call;
{
&scf_optimizer_inline, // global optimizer
&scf_optimizer_js_array,
+ &scf_optimizer_js_teq,
&scf_optimizer_js_call,
&scf_optimizer_split_call,
dn = ds->dag_node;
v = dn->var;
- scf_logw("%s(), last free: v_%d_%d/%s, ds->ret_flag: %u\n",
- f->node.w->text->data, v->w->line, v->w->pos, v->w->text->data, ds->ret_flag);
- scf_dn_status_print(ds);
+// scf_logw("%s(), last free: v_%d_%d/%s, ds->ret_flag: %u\n",
+// f->node.w->text->data, v->w->line, v->w->pos, v->w->text->data, ds->ret_flag);
+// scf_dn_status_print(ds);
if (ds->ret_flag)
continue;
int count = 0;
int ret;
- scf_logw("--- %s() ---\n", f->node.w->text->data);
+ scf_logd("--- %s() ---\n", f->node.w->text->data);
do {
for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); ) {
if (!ds->ret_flag)
continue;
-#if 1
+#if 0
scf_logi("ds: %#lx, ds->ret_flag: %u, ds->ret_index: %d, ds->dag_node->var->arg_flag: %u\n",
0xffff & (uintptr_t)ds, ds->ret_flag, ds->ret_index, ds->dag_node->var->arg_flag);
scf_dn_status_print(ds);
_bb_find_ds_alias_leak(ds, c, bb, bb_list_head);
}
}
- scf_logi("--- %s() ---\n\n", f->node.w->text->data);
+ scf_logd("--- %s() ---\n\n", f->node.w->text->data);
return total;
}
total1 += ret;
}
- scf_logi("total0: %d, total1: %d\n", total0, total1);
+ scf_logd("total0: %d, total1: %d\n", total0, total1);
} while (total0 != total1);
int i;
for (i = 0; i < functions->size; i++) {
+ f = functions->data[i];
- int ret = _optimize_inline2(ast, functions->data[i]);
+ if (f->js_flag)
+ continue;
+
+ int ret = _optimize_inline2(ast, f);
if (ret < 0) {
scf_loge("\n");
return ret;
--- /dev/null
+#include"scf_optimizer.h"
+#include"scf_pointer_alias.h"
+
+static int __js_teq(scf_ast_t* ast, scf_3ac_code_t** pc, scf_node_t* node)
+{
+ scf_3ac_code_t* c;
+ scf_variable_t* v;
+ scf_function_t* f = NULL;
+ scf_type_t* t = NULL;
+ scf_node_t* pf;
+ scf_node_t* fret;
+
+ int ret = scf_ast_find_global_function(&f, ast, "Object_teq");
+ if (ret < 0)
+ return ret;
+
+ ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR);
+ if (ret < 0)
+ return ret;
+
+ v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f);
+ if (!v)
+ return -ENOMEM;
+ v->const_literal_flag = 1;
+
+ pf = scf_node_alloc(NULL, v->type, v);
+ scf_variable_free(v);
+ v = NULL;
+ if (!pf)
+ return -ENOMEM;
+
+ ret = scf_ast_find_type_type(&t, ast, SCF_VAR_BOOL);
+ if (ret < 0)
+ return ret;
+
+ v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 0, 0, NULL);
+ if (!v)
+ return -ENOMEM;
+ v->tmp_flag = 1;
+
+ fret = scf_node_alloc(f->node.w, SCF_OP_CALL, NULL);
+ if (!fret) {
+ scf_variable_free(v);
+ scf_node_free(pf);
+ return -ENOMEM;
+ }
+ fret->op = scf_find_base_operator_by_type(SCF_OP_CALL);
+ fret->result = v;
+ v = NULL;
+
+ scf_node_t* srcs[] = {pf, node};
+
+ c = scf_3ac_code_NN(SCF_OP_CALL, &fret, 1, srcs, 2);
+ if (!c) {
+ scf_node_free(pf);
+ scf_node_free(fret);
+ return -ENOMEM;
+ }
+
+ *pc = c;
+ return 0;
+}
+
+static int _optimize_js_teq_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t* bb, scf_list_t* bb_list_head)
+{
+ scf_3ac_operand_t* src;
+ scf_3ac_operand_t* dst;
+ scf_3ac_code_t* c;
+ scf_3ac_code_t* c2;
+ scf_variable_t* v;
+ scf_node_t* node;
+ scf_type_t* Object = NULL;
+ scf_list_t* l;
+
+ int ret = scf_ast_find_global_type(&Object, ast, "Object");
+ if (ret < 0)
+ return ret;
+
+ for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); ) {
+
+ c = scf_list_data(l, scf_3ac_code_t, list);
+ l = scf_list_next(l);
+
+ if (SCF_OP_3AC_TEQ == c->op->type) {
+ src = c->srcs->data[0];
+ node = src->node;
+
+ while (SCF_OP_EXPR == node->type)
+ node = node->nodes[0];
+
+ v = _scf_operand_get(node);
+
+ if (v->type != Object->type)
+ continue;
+
+ if (SCF_OP_CALL == node->type) {
+ assert(node->nb_nodes > 0);
+
+ scf_variable_t* v2 = _scf_operand_get(node->nodes[0]);
+ scf_function_t* f2 = v2->func_ptr;
+
+ if (!strcmp(f2->node.w->text->data, "scf__auto_malloc"))
+ continue;
+ scf_logd("f2: %s()\n", f2->node.w->text->data);
+ }
+
+ c2 = NULL;
+ ret = __js_teq(ast, &c2, node);
+ if (ret < 0)
+ return ret;
+
+ c2->basic_block = c->basic_block;
+ c2->basic_block->call_flag = 1;
+
+ scf_list_add_tail(&c->list, &c2->list);
+
+ assert(1 == c2->dsts->size);
+ dst = c2->dsts->data[0];
+
+ src->node = scf_node_clone(dst->node);
+ if (!src->node)
+ return -ENOMEM;
+ src->node->result = dst->node->result;
+ src->node->op = dst->node->op;
+ }
+ }
+
+ return 0;
+}
+
+static int _optimize_js_teq(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions)
+{
+ if (!f)
+ return -EINVAL;
+
+ if (strcmp(f->node.w->text->data, "__js_main")) {
+ scf_string_t* s = f->node.w->file;
+
+ if (!strncmp(s->data + s->len - 8, "js/doc.c", 8))
+ return 0;
+ }
+
+ printf("\n");
+ scf_logi("------- %s() ------ file: %s\n", f->node.w->text->data, f->node.w->file->data);
+
+ scf_list_t* bb_list_head = &f->basic_block_list_head;
+ scf_list_t* l;
+ scf_basic_block_t* bb;
+
+ if (scf_list_empty(bb_list_head))
+ return 0;
+
+ 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) {
+
+ int ret = _optimize_js_teq_bb(ast, f, bb, bb_list_head);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+scf_optimizer_t scf_optimizer_js_teq =
+{
+ .name = "js_teq",
+
+ .optimize = _optimize_js_teq,
+
+ .flags = SCF_OPTIMIZER_LOCAL,
+};
bb = scf_list_data(l, scf_basic_block_t, list);
l = scf_list_next(l);
- if (bb->jmp_flag || bb->end_flag || bb->cmp_flag)
+ if (bb->jmp_flag || bb->end_flag)
continue;
if (!bb->call_flag)
case SCF_LEX_WORD_CONST_CHAR:
v->data.u32 = w->data.u32;
break;
+ case SCF_LEX_WORD_CONST_BOOL:
+ v->data.u32 = w->data.u32;
+ break;
case SCF_LEX_WORD_CONST_STRING:
v->data.s = scf_string_clone(w->data.s);
uint32_t global_flag :1;
uint32_t member_flag :1;
+ uint32_t js_flag :1;
uint32_t vla_flag :1;
uint32_t arg_flag :1;
uint32_t auto_gc_flag:1;
}
}
+bool Object_teq(Object* this)
+{
+ if (!this)
+ return 0;
+
+ switch (this->type) {
+ case JS_Number:
+ return 0.0 != this->d;
+ break;
+
+ case JS_Boolean:
+ return 0 != this->i64;
+ break;
+
+ case JS_String:
+ return '\0' != this->str[0];
+ break;
+ default:
+ break;
+ };
+
+ return 0;
+}
+
int Object_array_realloc(Object* this, int i)
{
if (JS_Object != this->type)
uint32_t global_flag;
uint32_t local_flag;
uint32_t member_flag;
+ uint32_t js_flag = 0;
if (!b) {
local_flag = 0;
if (scf_ast_find_type(&id0->type, parse->ast, "Object") < 0)
return SCF_DFA_ERROR;
+
+ js_flag = 1;
}
v = SCF_VAR_ALLOC_BY_TYPE(id->identity, id0->type, id0->const_flag, id0->nb_pointers, id0->func_ptr);
v->local_flag = local_flag;
v->global_flag = global_flag;
v->member_flag = member_flag;
+ v->js_flag = js_flag;
v->static_flag = id0->static_flag;
v->extern_flag = id0->extern_flag;
for (i = 0; i < functions->size; i++) {
f = functions->data[i];
- printf("%d, %p\n", i, f->node.w->text);
- printf("argv: %p, define_flag: %d, inline_flag: %d\n",
- f->argv, f->node.define_flag, f->inline_flag);
-
printf("%d, %s(), argv->size: %d, define_flag: %d, inline_flag: %d\n",
i, f->node.w->text->data, f->argv->size, f->node.define_flag, f->inline_flag);
CFILES += ../js/core/scf_optimizer_dag.c
CFILES += ../js/core/scf_optimizer_inline.c
CFILES += ../js/core/scf_optimizer_js_array.c
+CFILES += ../js/core/scf_optimizer_js_teq.c
CFILES += ../js/core/scf_optimizer_js_call.c
CFILES += ../js/core/scf_optimizer_split_call.c
CFILES += ../js/core/scf_optimizer_call.c