}
}
-void scf_bb_group_print(scf_bb_group_t* bbg)
+static void __bb_group_print(scf_bb_group_t* bbg)
{
scf_basic_block_t* bb;
int i;
- printf("\033[33mbbg: %p\033[0m\n", bbg);
-
printf("\033[34mentries:\033[0m\n");
if (bbg->entries) {
for (i = 0; i < bbg->entries->size; i++) {
printf("%p, %d\n", bb, bb->index);
}
}
+}
+
+void scf_bb_group_print(scf_bb_group_t* bbg)
+{
+ printf("\033[33mbbg: %p, loop_layers: %d\033[0m\n", bbg, bbg->loop_layers);
+
+ __bb_group_print(bbg);
+
+ printf("\n");
+}
+
+void scf_bb_loop_print(scf_bb_group_t* loop)
+{
+ scf_basic_block_t* bb;
+ scf_bb_group_t* bbg;
+
+ int k;
+
+ if (loop->loop_childs) {
+ for (k = 0; k < loop->loop_childs->size; k++) {
+ bbg = loop->loop_childs->data[k];
+
+ scf_bb_loop_print(bbg);
+ }
+ }
+
+ printf("\033[33mloop: %p, loop_layers: %d\033[0m\n", loop, loop->loop_layers);
+
+ __bb_group_print(loop);
+
+ if (loop->loop_childs) {
+ printf("childs: %d\n", loop->loop_childs->size);
+
+ for (k = 0; k < loop->loop_childs->size; k++)
+ printf("%p ", loop->loop_childs->data[k]);
+ printf("\n");
+ }
+
+ if (loop->loop_parent)
+ printf("parent: %p\n", loop->loop_parent);
+
printf("\n");
}
scf_bb_group_t* scf_bb_group_alloc();
void scf_bb_group_free (scf_bb_group_t* bbg);
void scf_bb_group_print(scf_bb_group_t* bbg);
+void scf_bb_loop_print (scf_bb_group_t* loop);
void scf_basic_block_print(scf_basic_block_t* bb, scf_list_t* sentinel);
void scf_basic_block_print_list(scf_list_t* h);
SCF_OP_BREAK, // break statement
SCF_OP_CONTINUE, // continue statement
SCF_OP_ASYNC, // async statement
- SCF_OP_INCLUDE, // include statement
+
+ SCF_N_OPS, // total operators
// 58
SCF_OP_3AC_TEQ, // test if = 0
SCF_OP_3AC_END,
SCF_OP_GOTO, // goto statement
+ SCF_N_3AC_OPS, // totaol 3ac operators
SCF_VAR_CHAR, // char variable
&scf_optimizer_generate_loads_saves,
};
-static void __scf_loops_print(scf_bb_group_t* loop)
-{
- scf_basic_block_t* bb;
-
- int j;
- int k;
-
- if (loop->loop_childs) {
-
- for (k = 0; k < loop->loop_childs->size; k++)
- __scf_loops_print(loop->loop_childs->data[k]);
- }
-
- printf("\033[33mloop: %p\033[0m\n", loop);
-
- printf("\033[34mentry:\033[0m\n");
- for (j = 0; j < loop->entries->size; j++) {
- bb = loop->entries->data[j];
-
- printf("%p, %d\n", bb, bb->index);
- }
-
- printf("\033[35mexit:\033[0m\n");
- for (j = 0; j < loop->exits->size; j++) {
- bb = loop->exits->data[j];
-
- printf("%p, %d\n", bb, bb->index);
- }
-
- printf("\033[36mbody:\033[0m\n");
- for (j = 0; j < loop->body->size; j++) {
- bb = loop->body->data[j];
-
- printf("%p, %d\n", bb, bb->index);
- }
-
- if (loop->loop_childs) {
- printf("childs: %d\n", loop->loop_childs->size);
-
- for (k = 0; k < loop->loop_childs->size; k++)
- printf("%p ", loop->loop_childs->data[k]);
- printf("\n");
- }
-
- if (loop->loop_parent)
- printf("parent: %p\n", loop->loop_parent);
-
- printf("loop_layers: %d\n\n", loop->loop_layers);
-}
-
-void scf_loops_print(scf_vector_t* loops)
-{
- int i;
- for (i = 0; i < loops->size; i++)
- __scf_loops_print(loops->data[i]);
-}
-
-void scf_groups_print(scf_vector_t* groups)
-{
- int i;
- for (i = 0; i < groups->size; i++)
- scf_bb_group_print(groups->data[i]);
-}
-
-
int scf_optimize(scf_ast_t* ast, scf_vector_t* functions)
{
scf_optimizer_t* opt;
scf_function_t* f;
+ scf_bb_group_t* bbg;
int n = sizeof(scf_optimizers) / sizeof(scf_optimizers[0]);
int i;
scf_basic_block_print_list(&f->basic_block_list_head);
- scf_loops_print (f->bb_loops);
- scf_groups_print(f->bb_groups);
+ for (j = 0; j < f->bb_groups->size; j++) {
+ bbg = f->bb_groups->data[j];
+
+ switch (bbg->loop_layers) {
+ case 0:
+ scf_bb_group_print(bbg);
+ break;
+ default:
+ scf_bb_loop_print(bbg);
+ break;
+ };
+ }
}
#endif
return 0;
int main()
{
- assert(0);
+ assert(1);
+
+ printf("main ok\n");
return 0;
}
--- /dev/null
+#include"../lib/scf_capi.c"
+
+#define assert(x)\
+ do {\
+ if (!(x))\
+ printf("assert '%s' fail, %s, %d\n", #x, __func__, __LINE__);\
+ } while (0)
+
+struct buf_t
+{
+ int refs;
+ int n;
+ int data[0];
+};
+
+struct mat_t
+{
+ int i;
+ int j;
+ int n;
+ buf_t* b;
+};
+
+int g_buf_size = 0;
+int g_buf_size_max = 0;
+
+buf_t* buf_alloc(int n)
+{
+ buf_t* b = malloc(sizeof(buf_t) + sizeof(int) * n * n);
+
+ g_buf_size += n * n;
+ if (g_buf_size_max < g_buf_size)
+ g_buf_size_max = g_buf_size;
+
+ b->refs = 1;
+ b->n = n;
+ return b;
+}
+
+void buf_free(buf_t* b)
+{
+ if (b && 0 == --b->refs) {
+
+ g_buf_size -= b->n * b->n;
+
+ free(b);
+ }
+}
+
+mat_t* mat_alloc(int i, int j, int n, buf_t* b)
+{
+ mat_t* m = malloc(sizeof(mat_t));
+ assert(m);
+
+ m->i = i;
+ m->j = j;
+ m->n = n;
+
+ if (!b) {
+ b = buf_alloc(n);
+ assert(b);
+ } else {
+ b->refs++;
+ }
+ m->b = b;
+ return m;
+}
+
+void mat_free(mat_t* m)
+{
+ if (m) {
+ buf_free(m->b);
+ free(m);
+ }
+}
+
+void mat_add(mat_t* m, mat_t* m0, mat_t* m1)
+{
+ assert(m0->n == m1->n);
+ assert(m->n == m0->n);
+
+ int i;
+ int j;
+ int n = m->n;
+
+ for (i = 0; i < n; i++) {
+
+ int* d0 = m0->b->data + (i + m0->i) * m0->b->n + m0->j;
+ int* d1 = m1->b->data + (i + m1->i) * m1->b->n + m1->j;
+ int* d = m ->b->data + (i + m->i) * m->b->n + m->j;
+
+ for (j = 0; j < n; j++)
+ d[j] = d0[j] + d1[j];
+ }
+}
+
+void mat_sub(mat_t* m, mat_t* m0, mat_t* m1)
+{
+ int i;
+ int j;
+ int n = m->n;
+
+ for (i = 0; i < n; i++) {
+
+ int* d0 = m0->b->data + (i + m0->i) * m0->b->n + m0->j;
+ int* d1 = m1->b->data + (i + m1->i) * m1->b->n + m1->j;
+ int* d = m ->b->data + (i + m->i) * m->b->n + m->j;
+
+ for (j = 0; j < n; j++)
+ d[j] = d0[j] - d1[j];
+ }
+}
+
+void mat_trans(mat_t* t, mat_t* m)
+{
+ assert(m->n == t->n);
+
+ int i;
+ int j;
+ int n = m->n;
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < n; j++) {
+
+ int ij = (i + m->i) * m->b->n + (j + m->j);
+ int ji = (j + t->i) * t->b->n + (i + t->j);
+
+ t->b->data[ji] = m->b->data[ij];
+ }
+ }
+}
+
+void mat_mul(mat_t* m, mat_t* m0, mat_t* m1)
+{
+ assert(m0->n == m1->n);
+ assert(m->n == m0->n);
+
+ int i;
+ int j;
+ int k;
+ int n = m->n;
+
+ mat_t* t1 = mat_alloc(0, 0, n, NULL);
+
+ mat_trans(t1, m1);
+
+ for (i = 0; i < n; i++) {
+ int* d0 = m0->b->data + (i + m0->i) * m0->b->n + m0->j;
+ int* d = m ->b->data + (i + m->i) * m->b->n + m->j;
+
+ for (j = 0; j < n; j++) {
+ int* d1 = t1->b->data + (j + t1->i) * t1->b->n + t1->j;
+
+ int sum = 0;
+ for (k = 0; k < n; k++) {
+ sum += d0[k] * d1[k];
+ }
+
+ d[j] = sum;
+ }
+ }
+
+ mat_free(t1);
+}
+
+void mat_mul_strassen(mat_t* m, mat_t* m0, mat_t* m1, int n_min)
+{
+ assert(m0->n == m1->n);
+ assert(m->n == m0->n);
+
+ if (m->n <= n_min) {
+ mat_mul(m, m0, m1);
+ return;
+ }
+
+ if (n_min < 16)
+ printf("%s(), m->n: %d, n_min: %d\n", __func__, m->n, n_min);
+
+ int n = m->n / 2;
+
+ mat_t* a = mat_alloc(m0->i, m0->j, n, m0->b);
+ mat_t* b = mat_alloc(m0->i, m0->j + n, n, m0->b);
+ mat_t* c = mat_alloc(m0->i + n, m0->j, n, m0->b);
+ mat_t* d = mat_alloc(m0->i + n, m0->j + n, n, m0->b);
+
+ mat_t* e = mat_alloc(m1->i, m1->j, n, m1->b);
+ mat_t* f = mat_alloc(m1->i, m1->j + n, n, m1->b);
+ mat_t* g = mat_alloc(m1->i + n, m1->j, n, m1->b);
+ mat_t* h = mat_alloc(m1->i + n, m1->j + n, n, m1->b);
+
+ mat_t* r = mat_alloc(m->i, m->j, n, m->b);
+ mat_t* s = mat_alloc(m->i, m->j + n, n, m->b);
+ mat_t* t = mat_alloc(m->i + n, m->j, n, m->b);
+ mat_t* u = mat_alloc(m->i + n, m->j + n, n, m->b);
+
+ mat_t* p1 = mat_alloc(0, 0, n, NULL);
+ mat_t* p2 = mat_alloc(0, 0, n, NULL);
+ mat_t* p3 = mat_alloc(0, 0, n, NULL);
+
+ // tmp mat t0
+ mat_t* t0 = mat_alloc(0, 0, n, NULL);
+
+ // p1 = a * (f - h)
+ mat_sub(t0, f, h);
+ mat_mul_strassen(p1, a, t0, n_min);
+ // p2 = (a + b) * h
+ mat_add(t0, a, b);
+ mat_mul_strassen(p2, t0, h, n_min);
+ // s = p1 + p2
+ mat_add(s, p1, p2);
+
+ // p3 = (c + d) * e
+ mat_add(t0, c, d);
+ mat_mul_strassen(p3, t0, e, n_min);
+
+ mat_sub(u, p1, p3);
+
+ // p4 = d * (g - e)
+ mat_t* p4 = p1;
+ p1 = NULL;
+
+ mat_sub(t0, g, e);
+ mat_mul_strassen(p4, d, t0, n_min);
+ // t = p3 + p4
+ mat_add(t, p3, p4);
+ mat_sub(r, p4, p2);
+// mat_free(p2);
+// mat_free(p3);
+// mat_free(p4);
+
+ // tmp mat t1
+ mat_t* t1 = p2;
+ mat_t* p5 = p3;
+ mat_t* p6 = p4;
+ p2 = NULL;
+ p3 = NULL;
+ p4 = NULL;
+
+ //p5 = (a + d) * (e + h)
+ mat_add(t0, a, d);
+ mat_add(t1, e, h);
+ mat_mul_strassen(p5, t0, t1, n_min);
+
+ //p6 = (b - d) * (g + h)
+ mat_sub(t0, b, d);
+ mat_add(t1, g, h);
+ mat_mul_strassen(p6, t0, t1, n_min);
+
+ // r = p5 + p4 - p2 + p6
+ mat_add(r, r, p5);
+ mat_add(r, r, p6);
+
+ //p7 = (a - c) * (e + f)
+ mat_t* p7 = p6;
+ p6 = NULL;
+
+ mat_sub(t0, a, c);
+ mat_add(t1, e, f);
+ mat_mul_strassen(p7, t0, t1, n_min);
+
+ // u = p5 + p1 -p3 -p7
+ mat_add(u, u, p5);
+ mat_sub(u, u, p7);
+
+ // free unused mats
+ mat_free(t0);
+ mat_free(t1);
+
+ mat_free(p5);
+ mat_free(p7);
+
+ mat_free(a);
+ mat_free(b);
+ mat_free(c);
+ mat_free(d);
+
+ mat_free(e);
+ mat_free(f);
+ mat_free(g);
+ mat_free(h);
+
+ mat_free(r);
+ mat_free(s);
+ mat_free(t);
+ mat_free(u);
+}
+
+void mat_fill(mat_t* m)
+{
+ assert(m && m->b);
+
+ int i;
+ int j;
+
+ for (i = 0; i < m->n; i++) {
+ for (j = 0; j < m->n; j++) {
+
+ int ij = (i + m->i) * m->b->n + (j + m->j);
+
+ m->b->data[ij] = rand() % 10;
+ }
+ }
+}
+
+void mat_print(mat_t* m)
+{
+ assert(m && m->b);
+
+ int i;
+ int j;
+
+ printf("m: %p, i: %d, j: %d, n: %d, m->b->n: %d, m->b: %p\n",
+ m, m->i, m->j, m->n, m->b->n, m->b);
+
+ for (i = 0; i < m->n; i++) {
+ for (j = 0; j < m->n; j++) {
+
+ int ij = (i + m->i) * m->b->n + (j + m->j);
+
+ printf("%8d ", m->b->data[ij]);
+ }
+ printf("\n");
+ }
+ printf("\n");
+}
+
+int main(int argc, char* argv[])
+{
+ if (argc < 3) {
+ printf("./mat_mul n flag:\n");
+ printf("n: nxn mat, n = 2^N, N > 0\n");
+ printf("flag: 0 (normal), 1 (strassen), 2 (all & print)\n");
+ return -1;
+ }
+
+ int n = atoi(argv[1]);
+ int flag = atoi(argv[2]);
+
+ if (n < 2) {
+ printf("n must >= 2, n: %d\n", n);
+ return -1;
+ }
+
+ if (n & (n - 1)) {
+ printf("n: %d, not 2^N\n", n);
+ return -1;
+ }
+
+ srand(time(NULL));
+
+ mat_t* m0 = mat_alloc(0, 0, n, NULL);
+ mat_t* m1 = mat_alloc(0, 0, n, NULL);
+ mat_t* m2 = mat_alloc(0, 0, n, NULL);
+ mat_t* m3 = mat_alloc(0, 0, n, NULL);
+
+ mat_fill(m0);
+ mat_fill(m1);
+
+ printf("%s(), g_buf_size_max: %d\n", __func__, g_buf_size_max);
+
+ switch (flag) {
+ case 0:
+ mat_mul(m2, m0, m1);
+ break;
+ case 1:
+ mat_mul_strassen(m3, m0, m1, 64);
+ break;
+ case 2:
+ mat_mul(m2, m0, m1);
+ mat_mul_strassen(m3, m0, m1, 2);
+
+ mat_print(m0);
+ mat_print(m1);
+ mat_print(m2);
+ mat_print(m3);
+ break;
+ default:
+ printf("trans: \n");
+ mat_trans(m1, m0);
+ mat_print(m0);
+ mat_print(m1);
+ break;
+ };
+
+ printf("%s(), g_buf_size_max: %d\n", __func__, g_buf_size_max);
+ return 0;
+}
x64_init_bb_colors(bb);
- if (0 == bb->index) {
- ret = _x64_argv_save(bb, f);
- if (ret < 0)
- return ret;
- }
-
ret = _x64_make_insts_for_list(ctx, &bb->code_list_head, 0);
if (ret < 0)
return ret;
x64_init_bb_colors(bbg->pre);
- if (0 == bbg->pre->index) {
- ret = _x64_argv_save(bbg->pre, f);
- if (ret < 0)
- return ret;
- }
-
int j;
for (j = 0; j < bbg->body->size; j++) {
bb = bbg->body->data[j];
x64_init_bb_colors(bbg->pre);
- if (0 == bbg->pre->index) {
- ret = _x64_argv_save(bbg->pre, f);
- if (ret < 0)
- return ret;
- }
-
ret = _x64_make_insts_for_list(ctx, &bbg->pre->code_list_head, 0);
if (ret < 0)
return ret;
int x64_bb_load_dn2(intptr_t color, scf_dag_node_t* dn, scf_basic_block_t* bb, scf_function_t* f);
int x64_bb_save_dn2(intptr_t color, scf_dag_node_t* dn, scf_basic_block_t* bb, scf_function_t* f);
-int x64_fix_bb_colors (scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f);
-int x64_load_bb_colors (scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f);
-int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f);
-void x64_init_bb_colors (scf_basic_block_t* bb);
+int x64_fix_bb_colors (scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f);
+int x64_load_bb_colors (scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f);
+int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f);
+int x64_init_bb_colors (scf_basic_block_t* bb);
scf_instruction_t* x64_make_inst (scf_x64_OpCode_t* OpCode, int size);
int x64_inst_cmp_set(scf_native_t* ctx, scf_3ac_code_t* c, int setcc_type);
#endif
-
#include"scf_basic_block.h"
#include"scf_3ac.h"
-void x64_init_bb_colors(scf_basic_block_t* bb)
+int x64_init_bb_colors(scf_basic_block_t* bb)
{
scf_dag_node_t* dn;
scf_dn_status_t* ds;
+ scf_register_t* r;
int i;
dn->color = ds->color;
dn->loaded = 0;
- if (0 == bb->index && dn->rabi)
+ if (0 == bb->index && dn->rabi) {
dn->loaded = 1;
+ r = dn->rabi;
+
+ int ret = scf_vector_add_unique(r->dag_nodes, dn);
+ if (ret < 0)
+ return ret;
+
+ dn->color = r->color;
+ }
+
if (scf_vector_find(bb->dn_loads, dn)) {
scf_variable_t* v = dn->var;
if (v->w)
// printf("\n");
}
}
+
+ return 0;
}
int x64_save_bb_colors(scf_vector_t* dn_colors, scf_bb_group_t* bbg, scf_basic_block_t* bb)
}
return 0;
}
-
}
}
+void x64_registers_print()
+{
+ scf_register_t* r;
+ scf_dag_node_t* dn;
+ scf_variable_t* v;
+ int i;
+ int j;
+
+ for (i = 0; i < sizeof(x64_registers) / sizeof(x64_registers[0]); i++) {
+
+ r = &(x64_registers[i]);
+
+ if (SCF_X64_REG_RSP == r->id || SCF_X64_REG_RBP == r->id)
+ continue;
+
+ if (!r->dag_nodes)
+ continue;
+
+ for (j = 0; j < r->dag_nodes->size; j++) {
+ dn = r->dag_nodes->data[j];
+
+ v = dn->var;
+ printf("%s, dn: %#lx, v_%#lx", r->name, 0xffff & (uintptr_t)dn, 0xffff & (uintptr_t)v);
+
+ if (v->w)
+ printf(", %s_%d_%d\n", v->w->text->data, v->w->line, v->w->pos);
+ else
+ printf("\n");
+ }
+ }
+}
+
int x64_caller_save_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs)
{
int i;
return ret;
}
- dn->loaded = 0;
- dn->color = 0;
+ dn->loaded = 0;
+ dn->color = 0;
}
}
static int _x64_overflow_reg3(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f)
{
- scf_register_t* r2;
- scf_dn_status_t* ds2;
- scf_dag_node_t* dn2;
+ scf_register_t* r2;
+ scf_dn_status_t* ds2;
+ scf_dag_node_t* dn2;
int i;
int j;
- int ret;
for (i = 0; i < sizeof(x64_registers) / sizeof(x64_registers[0]); i++) {
continue;
for (j = 0; j < r2->dag_nodes->size; ) {
- dn2 = r2->dag_nodes->data[j];
+ dn2 = r2->dag_nodes->data[j];
if (dn2 == dn) {
j++;
int x64_registers_init();
int x64_registers_reset();
void x64_registers_clear();
+void x64_registers_print();
scf_vector_t* x64_register_colors();
scf_register_t* x64_find_register(const char* name);
}
#endif
-
if (!add)
return -ENOMEM;
- r = SCF_VAR_ALLOC_BY_TYPE(parent->w, t, v->const_flag, scf_variable_nb_pointers(v), v->func_ptr);
+ int nb_pointers = scf_variable_nb_pointers(v);
+
+ r = SCF_VAR_ALLOC_BY_TYPE(parent->w, t, v->const_flag, nb_pointers - 1, v->func_ptr);
if (!r) {
scf_node_free(add);
return -ENOMEM;
#define scf_list_clear(h, type, member, type_free) \
do {\
scf_list_t* l;\
+ type* t;\
for (l = scf_list_head(h); l != scf_list_sentinel(h);) {\
- type* t = scf_list_data(l, type, member);\
- l = scf_list_next(l);\
+ t = scf_list_data(l, type, member);\
+ l = scf_list_next(l);\
scf_list_del(&t->member);\
type_free(t);\
t = NULL;\