Commit d6cbbdcf authored by Camil Staps's avatar Camil Staps 🐧

Merge branch 'optimized-instance-calls' into 'master'

Add support for .ai, jsr_i and jmp_i for optimized instance calls

See merge request !106
parents 162968cb ccd334c7
Pipeline #24432 canceled with stages
in 10 minutes and 47 seconds
...@@ -56,6 +56,7 @@ benchmark-x86: ...@@ -56,6 +56,7 @@ benchmark-x86:
script: script:
- cd test - cd test
- ./run_tests.sh -3bf - ./run_tests.sh -3bf
allow_failure: true
benchmark-wasm: benchmark-wasm:
extends: .base extends: .base
......
...@@ -277,6 +277,11 @@ const char *instruction_type (BC_WORD i) { ...@@ -277,6 +277,11 @@ const char *instruction_type (BC_WORD i) {
case Cjmp_eval: return ""; case Cjmp_eval: return "";
case Cjmp_eval_upd: return ""; case Cjmp_eval_upd: return "";
case Cjmp_false: return "l"; case Cjmp_false: return "l";
case Cjmp_i: return "n";
case Cjmp_i0: return "";
case Cjmp_i1: return "";
case Cjmp_i2: return "";
case Cjmp_i3: return "";
case Cjmp_true: return "l"; case Cjmp_true: return "l";
case Cjsr: return "l"; case Cjsr: return "l";
case Cjsr_eval: return "n"; case Cjsr_eval: return "n";
...@@ -284,6 +289,11 @@ const char *instruction_type (BC_WORD i) { ...@@ -284,6 +289,11 @@ const char *instruction_type (BC_WORD i) {
case Cjsr_eval1: return ""; case Cjsr_eval1: return "";
case Cjsr_eval2: return ""; case Cjsr_eval2: return "";
case Cjsr_eval3: return ""; case Cjsr_eval3: return "";
case Cjsr_i: return "n";
case Cjsr_i0: return "";
case Cjsr_i1: return "";
case Cjsr_i2: return "";
case Cjsr_i3: return "";
case ClnR: return ""; case ClnR: return "";
case Cload_i: return "i"; case Cload_i: return "i";
case Cload_module_name: return ""; case Cload_module_name: return "";
...@@ -774,6 +784,7 @@ const char *instruction_type (BC_WORD i) { ...@@ -774,6 +784,7 @@ const char *instruction_type (BC_WORD i) {
case CA_data_IIl: return "IIl"; case CA_data_IIl: return "IIl";
case CA_data_IlI: return "IlI"; case CA_data_IlI: return "IlI";
case CA_data_IlIla: return "IlIla"; case CA_data_IlIla: return "IlIla";
case CA_data_lIlI: return "lIlI";
case CA_data_la: return "la"; case CA_data_la: return "la";
case CA_data_a: return "a"; case CA_data_a: return "a";
......
...@@ -263,6 +263,11 @@ enum { ...@@ -263,6 +263,11 @@ enum {
INSTRUCTION(jmp_eval) INSTRUCTION(jmp_eval)
INSTRUCTION(jmp_eval_upd) INSTRUCTION(jmp_eval_upd)
INSTRUCTION(jmp_false) INSTRUCTION(jmp_false)
INSTRUCTION(jmp_i)
INSTRUCTION(jmp_i0)
INSTRUCTION(jmp_i1)
INSTRUCTION(jmp_i2)
INSTRUCTION(jmp_i3)
INSTRUCTION(jmp_true) INSTRUCTION(jmp_true)
INSTRUCTION(jsr) INSTRUCTION(jsr)
INSTRUCTION(jsr_eval) INSTRUCTION(jsr_eval)
...@@ -270,6 +275,11 @@ enum { ...@@ -270,6 +275,11 @@ enum {
INSTRUCTION(jsr_eval1) INSTRUCTION(jsr_eval1)
INSTRUCTION(jsr_eval2) INSTRUCTION(jsr_eval2)
INSTRUCTION(jsr_eval3) INSTRUCTION(jsr_eval3)
INSTRUCTION(jsr_i)
INSTRUCTION(jsr_i0)
INSTRUCTION(jsr_i1)
INSTRUCTION(jsr_i2)
INSTRUCTION(jsr_i3)
INSTRUCTION(lnR) INSTRUCTION(lnR)
INSTRUCTION(load_i) INSTRUCTION(load_i)
INSTRUCTION(load_module_name) INSTRUCTION(load_module_name)
...@@ -764,6 +774,7 @@ enum { ...@@ -764,6 +774,7 @@ enum {
INSTRUCTION(A_data_IIl) INSTRUCTION(A_data_IIl)
INSTRUCTION(A_data_IlI) INSTRUCTION(A_data_IlI)
INSTRUCTION(A_data_IlIla) INSTRUCTION(A_data_IlIla)
INSTRUCTION(A_data_lIlI)
INSTRUCTION(A_data_la) INSTRUCTION(A_data_la)
INSTRUCTION(A_data_a) INSTRUCTION(A_data_a)
......
...@@ -148,10 +148,12 @@ void load_instruction_table(void) { ...@@ -148,10 +148,12 @@ void load_instruction_table(void) {
put_instruction_name("jmp_eval", parse_instruction, code_jmp_eval ); put_instruction_name("jmp_eval", parse_instruction, code_jmp_eval );
put_instruction_name("jmp_eval_upd", parse_instruction, code_jmp_eval_upd ); put_instruction_name("jmp_eval_upd", parse_instruction, code_jmp_eval_upd );
put_instruction_name("jmp_false", parse_instruction_a, code_jmp_false ); put_instruction_name("jmp_false", parse_instruction_a, code_jmp_false );
put_instruction_name("jmp_i", parse_instruction_n, code_jmp_i );
put_instruction_name("jmp_true", parse_instruction_a, code_jmp_true ); put_instruction_name("jmp_true", parse_instruction_a, code_jmp_true );
put_instruction_name("jsr", parse_instruction_a, code_jsr ); put_instruction_name("jsr", parse_instruction_a, code_jsr );
put_instruction_name("jsr_eval", parse_instruction_n, code_jsr_eval );
put_instruction_name("jsr_ap", parse_instruction_n, code_jsr_ap ); put_instruction_name("jsr_ap", parse_instruction_n, code_jsr_ap );
put_instruction_name("jsr_eval", parse_instruction_n, code_jsr_eval );
put_instruction_name("jsr_i", parse_instruction_n, code_jsr_i );
put_instruction_name("lnR", parse_instruction, code_lnR ); put_instruction_name("lnR", parse_instruction, code_lnR );
put_instruction_name("load_i", parse_instruction_i, code_load_i ); put_instruction_name("load_i", parse_instruction_i, code_load_i );
put_instruction_name("load_module_name", parse_instruction, code_load_module_name ); put_instruction_name("load_module_name", parse_instruction, code_load_module_name );
......
...@@ -2424,6 +2424,18 @@ void code_jmp_false(char label_name[]) { ...@@ -2424,6 +2424,18 @@ void code_jmp_false(char label_name[]) {
add_instruction_label(Cjmp_false,label_name); add_instruction_label(Cjmp_false,label_name);
} }
void code_jmp_i(int n_apply_args) {
last_d=0;
switch (n_apply_args) {
case 0: add_instruction(Cjmp_i0); break;
case 1: add_instruction(Cjmp_i1); break;
case 2: add_instruction(Cjmp_i2); break;
case 3: add_instruction(Cjmp_i3); break;
default: add_instruction_w(Cjmp_i,n_apply_args);
}
}
void code_jmp_true(char label_name[]) { void code_jmp_true(char label_name[]) {
add_instruction_label(Cjmp_true,label_name); add_instruction_label(Cjmp_true,label_name);
} }
...@@ -2514,6 +2526,21 @@ void code_jsr_eval(int a_offset) { ...@@ -2514,6 +2526,21 @@ void code_jsr_eval(int a_offset) {
} }
} }
void code_jsr_i(int n_apply_args) {
if (last_d) {
last_jsr_with_d=1;
last_d=0;
}
switch (n_apply_args) {
case 0: add_instruction(Cjsr_i0); break;
case 1: add_instruction(Cjsr_i1); break;
case 2: add_instruction(Cjsr_i2); break;
case 3: add_instruction(Cjsr_i3); break;
default: add_instruction_w(Cjsr_i,n_apply_args);
}
}
void code_lnR(void) { void code_lnR(void) {
add_instruction(ClnR); add_instruction(ClnR);
} }
...@@ -4149,7 +4176,20 @@ void code_a(int n_apply_args,char *ea_label_name) { ...@@ -4149,7 +4176,20 @@ void code_a(int n_apply_args,char *ea_label_name) {
} }
void code_ai(int n_apply_args,char *ea_label_name,char *instance_member_code_name) { void code_ai(int n_apply_args,char *ea_label_name,char *instance_member_code_name) {
code_a(n_apply_args,ea_label_name); if (n_apply_args==0) {
add_instruction_label(CA_data_lIlI,instance_member_code_name);
add_instruction_label(Cjmp,ea_label_name);
add_instruction(Chalt);
} else if (n_apply_args<=32) {
add_instruction_label(CA_data_lIlI,instance_member_code_name);
add_instruction_label(Cadd_empty_node3+(n_apply_args-3),ea_label_name);
add_instruction(Chalt);
} else {
if (ea_label_name!=NULL)
fprintf(stderr, "Error: .ai %d %s %s\n",n_apply_args,ea_label_name,instance_member_code_name);
else
fprintf(stderr, "Error: .ai %d %s\n",n_apply_args,instance_member_code_name);
}
} }
void code_algtype(int n_constructors) { void code_algtype(int n_constructors) {
...@@ -4537,19 +4577,27 @@ void code_nu(int a_size,int b_size,char *descriptor_name,char *ea_label_name) { ...@@ -4537,19 +4577,27 @@ void code_nu(int a_size,int b_size,char *descriptor_name,char *ea_label_name) {
} }
void code_o(int oa,int ob,uint32_t vector[]) { void code_o(int oa,int ob,uint32_t vector[]) {
if (last_jsr_with_d) { while (last_jsr_with_d) {
if (pgrm.code[pgrm.code_size-2].value!=Cjsr) { int i=pgrm.code[pgrm.code_size-2].value;
int i; if (i==Cjsr || i==Cjsr_i)
break;
i=pgrm.code[pgrm.code_size-1].value;
if ((Cjsr_ap1<=i && i<=Cjsr_ap32) ||
(Cjsr_i0<=i && i<=Cjsr_i3))
break;
i=pgrm.code[pgrm.code_size-3].value; i=pgrm.code[pgrm.code_size-3].value;
if (i!=Cpop_a_jsr && i!=Cpop_b_jsr && i!=Cpush_a_jsr && i!=Cpush_b_jsr if (i==Cpop_a_jsr || i==Cpop_b_jsr || i==Cpush_a_jsr || i==Cpush_b_jsr)
&& pgrm.code[pgrm.code_size-4].value!=Cbuildh0_put_a_jsr) break;
{
if (pgrm.code[pgrm.code_size-4].value==Cbuildh0_put_a_jsr)
break;
fprintf(stderr, "Error: .o directive used incorrectly near jsr\n"); fprintf(stderr, "Error: .o directive used incorrectly near jsr\n");
exit(1); exit(1);
} }
}
}
last_jsr_with_d=0; last_jsr_with_d=0;
} }
#endif #endif
......
...@@ -140,10 +140,12 @@ void code_jmp_ap(int n_apply_args); ...@@ -140,10 +140,12 @@ void code_jmp_ap(int n_apply_args);
void code_jmp_eval(void); void code_jmp_eval(void);
void code_jmp_eval_upd(void); void code_jmp_eval_upd(void);
void code_jmp_false(char label_name[]); void code_jmp_false(char label_name[]);
void code_jmp_i(int n_apply_args);
void code_jmp_true(char label_name[]); void code_jmp_true(char label_name[]);
void code_jsr(char label_name[]); void code_jsr(char label_name[]);
void code_jsr_ap(int n_apply_args); void code_jsr_ap(int n_apply_args);
void code_jsr_eval(int a_offset); void code_jsr_eval(int a_offset);
void code_jsr_i(int n_apply_args);
void code_lnR(void); void code_lnR(void);
void code_load_i(CleanInt value); void code_load_i(CleanInt value);
void code_load_module_name(void); void code_load_module_name(void);
......
...@@ -27,4 +27,4 @@ typedef int64_t CleanInt; ...@@ -27,4 +27,4 @@ typedef int64_t CleanInt;
#define BCGEN_INSTRUCTION_TABLE_SIZE 512 #define BCGEN_INSTRUCTION_TABLE_SIZE 512
#define ABC_MAGIC_NUMBER 0x2a434241 #define ABC_MAGIC_NUMBER 0x2a434241
#define ABC_VERSION 6 #define ABC_VERSION 7
False False
halt at 4 halt at 4
280002 244286 524288 280000 244288 524288
...@@ -1932,7 +1932,20 @@ all_instructions opts t = bootstrap $ collect_instructions opts $ map (\i -> i t ...@@ -1932,7 +1932,20 @@ all_instructions opts t = bootstrap $ collect_instructions opts $ map (\i -> i t
end_instruction end_instruction
) :. ) :.
Pc .= to_word_ptr (d - if_i64_or_i32_expr (lit_word 40) (lit_word 20)) Pc .= to_word_ptr (d - if_i64_or_i32_expr (lit_word 40) (lit_word 20))
, instr "jmp_false" Nothing $ , instr "jmp_i" Nothing $
new_local TWord (Pc @ 1) \i ->
let n = to_word_ptr (A @ 0) in
let d = to_word_ptr (n @ 0 - lit_word 2) in
let code_entry = to_word_ptr (d @ ((i <<. lit_word 1) - lit_word 1)) in
Pc .= to_word_ptr (code_entry @ -4)
] ++
[ instr ("jmp_i"+++toString i) Nothing $
let n = to_word_ptr (A @ 0) in
let d = to_word_ptr (n @ 0 - lit_word 2) in
let code_entry = to_word_ptr (d @ ((i<<1)-1)) in
Pc .= to_word_ptr (code_entry @ -4)
\\ i <- [0..3]] ++
[ instr "jmp_false" Nothing $
shrink_b 1 :. shrink_b 1 :.
if_then (B @ -1) ( if_then (B @ -1) (
advance_ptr Pc 2 :. advance_ptr Pc 2 :.
...@@ -1981,6 +1994,21 @@ all_instructions opts t = bootstrap $ collect_instructions opts $ map (\i -> i t ...@@ -1981,6 +1994,21 @@ all_instructions opts t = bootstrap $ collect_instructions opts $ map (\i -> i t
A @ 0 .= to_word n A @ 0 .= to_word n
\\ i <- [1..3] \\ i <- [1..3]
] ++ ] ++
[ instr "jsr_i" Nothing $
push_c (to_word (Pc @? 2)) :.
new_local TWord (Pc @ 1) \i ->
let n = to_word_ptr (A @ 0) in
let d = to_word_ptr (n @ 0 - lit_word 2) in
let code_entry = to_word_ptr (d @ ((i <<. lit_word 1) - lit_word 1)) in
Pc .= to_word_ptr (code_entry @ -4)
] ++
[ instr ("jsr_i"+++toString i) Nothing $
push_c (to_word (Pc @? 1)) :.
let n = to_word_ptr (A @ 0) in
let d = to_word_ptr (n @ 0 - lit_word 2) in
let code_entry = to_word_ptr (d @ ((i<<1)-1)) in
Pc .= to_word_ptr (code_entry @ -4)
\\ i <- [0..3]] ++
[ instr "lnR" (Just 0) $ [ instr "lnR" (Just 0) $
new_local TReal (lnR (to_real (B @ 0))) \r -> new_local TReal (lnR (to_real (B @ 0))) \r ->
B @ 0 .= to_word r B @ 0 .= to_word r
...@@ -3705,6 +3733,7 @@ all_instructions opts t = bootstrap $ collect_instructions opts $ map (\i -> i t ...@@ -3705,6 +3733,7 @@ all_instructions opts t = bootstrap $ collect_instructions opts $ map (\i -> i t
alias "A_data_IlI" $ alias "A_data_IlI" $
alias "A_data_IlIla" $ alias "A_data_IlIla" $
alias "A_data_a" $ alias "A_data_a" $
alias "A_data_lIlI" $
instr "A_data_la" Nothing $ instr "A_data_la" Nothing $
instr_unimplemented instr_unimplemented
] ]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment