commit c497784654927b8bdc2c893ccef54332f6600a4f
parent ff1a009f88d2eff66c17da40a34ad8773f4e507d
Author: erai <erai@omiltem.net>
Date: Sun, 2 Feb 2025 17:45:24 +0000
basic identities in folding
Diffstat:
M | cc0.c | | | 482 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
M | ir.om | | | 326 | +++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------- |
2 files changed, 599 insertions(+), 209 deletions(-)
diff --git a/cc0.c b/cc0.c
@@ -773,12 +773,16 @@ void( my_irblock_dead_expr)(struct my_irfunc* my_ic,struct my_irblock* my_b);
void( my_irblock_fold)(struct my_irfunc* my_ic,struct my_irblock* my_b);
void( my_irbranch)(struct my_irfunc* my_ic,struct my_irop* my_cond,struct my_irblock* my_alt,struct my_irblock* my_next);
struct my_irop*( my_ircall)(struct my_irfunc* my_ic,struct my_node* my_n);
-struct my_irop*( my_irexpr_fold)(struct my_irfunc* my_ic,struct my_irblock* my_b,struct my_irop* my_o);
+struct my_irop*( my_irexpr_fold)(struct my_irfunc* my_ic,struct my_irop* my_o);
struct my_irblock*( my_irfind_block)(struct my_irfunc* my_ic,unsigned char* my_name,unsigned long my_make);
struct my_irvar**( my_irfind_var)(struct my_irfunc* my_ic,unsigned char* my_name);
void( my_irjump)(struct my_irfunc* my_ic,struct my_irblock* my_to,struct my_irblock* my_next);
void( my_irreset)(struct my_irblock* my_b);
void( my_irreturn)(struct my_irfunc* my_ic,struct my_irop* my_value);
+void( my_irshow)(struct my_file* my_out,struct my_irblock* my_b);
+void( my_irshow2)(struct my_file* my_out,struct my_irblock* my_b,unsigned long* my_id);
+void( my_irshow3)(struct my_file* my_out,struct my_irblock* my_b);
+void( my_irshow4)(struct my_file* my_out,struct my_irop* my_o);
void( my_labels_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n);
void( my_layout_struct)(struct my_compiler* my_c,struct my_decl* my_d);
void( my_layout_union)(struct my_compiler* my_c,struct my_decl* my_d);
@@ -794,6 +798,7 @@ void( my_memcpy)(unsigned char* my_dest,unsigned char* my_src,unsigned long my_s
void( my_memset)(unsigned char* my_dest,unsigned long my_c,unsigned long my_size);
struct my_irblock*( my_mkirblock)(struct my_irfunc* my_ic);
struct my_irop*( my_mkirconst)(struct my_irfunc* my_ic,unsigned long my_n);
+struct my_irop*( my_mkirfold)(struct my_irfunc* my_ic,struct my_irop* my_s,unsigned long my_n);
struct my_irop*( my_mkirfunc)(struct my_irfunc* my_ic,unsigned char* my_name);
struct my_irop*( my_mkirop)(struct my_irfunc* my_ic,unsigned long my_kind,struct my_irop* my_a,struct my_irop* my_b);
struct my_irop*( my_mkirstr)(struct my_irfunc* my_ic,unsigned char* my_s,unsigned long my_slen);
@@ -3866,8 +3871,7 @@ struct my_irop*( my_expr_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_ASSIGN)))) {
(my_a)=((my_expr_to_ir)((my_ic),((my_n)->my_a)));
(my_b)=((my_expr_to_ir)((my_ic),((my_n)->my_b)));
- (my_d)=((my_mkirop)((my_ic),(my_IOP_REF),(my_a),((void *)0)));
- (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_d),(my_b)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b)));
((my_o)->my_t)=((my_n)->my_t);
return my_o;
} else if ((unsigned long)(((long)(my_kind))==((long)(my_N_POS)))) {
@@ -3891,15 +3895,13 @@ struct my_irop*( my_expr_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){
(my_e)=((my_mkirtmp)((my_ic),((my_n)->my_t)));
(my_a)=((my_expr_to_ir)((my_ic),((my_n)->my_a)));
(my_irbranch)((my_ic),(my_a),(my_bool_next),(my_bool_body));
- (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0)));
(my_b)=((my_mkirconst)((my_ic),(0UL)));
- (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b)));
((my_o)->my_t)=((my_n)->my_t);
(my_iraddop)((my_ic),(my_o));
(my_irjump)((my_ic),(my_bool_out),(my_bool_next));
- (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0)));
(my_b)=((my_mkirconst)((my_ic),(1UL)));
- (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b)));
((my_o)->my_t)=((my_n)->my_t);
(my_iraddop)((my_ic),(my_o));
(my_irjump)((my_ic),(my_bool_out),(my_bool_out));
@@ -3912,24 +3914,21 @@ struct my_irop*( my_expr_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){
(my_e)=((my_mkirtmp)((my_ic),((my_n)->my_t)));
(my_a)=((my_expr_to_ir)((my_ic),((my_n)->my_a)));
(my_irbranch)((my_ic),(my_a),(my_bool_next),(my_bool_body));
- (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0)));
(my_b)=((my_mkirconst)((my_ic),(1UL)));
- (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b)));
((my_o)->my_t)=((my_n)->my_t);
(my_iraddop)((my_ic),(my_o));
(my_irjump)((my_ic),(my_bool_out),(my_bool_next));
(my_bool_next)=((my_mkirblock)((my_ic)));
(my_a)=((my_expr_to_ir)((my_ic),((my_n)->my_b)));
(my_irbranch)((my_ic),(my_a),(my_bool_next),(my_bool_final));
- (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0)));
(my_b)=((my_mkirconst)((my_ic),(1UL)));
- (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b)));
((my_o)->my_t)=((my_n)->my_t);
(my_iraddop)((my_ic),(my_o));
(my_irjump)((my_ic),(my_bool_out),(my_bool_next));
- (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0)));
(my_b)=((my_mkirconst)((my_ic),(0UL)));
- (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b)));
((my_o)->my_t)=((my_n)->my_t);
(my_iraddop)((my_ic),(my_o));
(my_irjump)((my_ic),(my_bool_out),(my_bool_out));
@@ -3944,15 +3943,13 @@ struct my_irop*( my_expr_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){
(my_irbranch)((my_ic),(my_a),(my_bool_next),(my_bool_body));
(my_a)=((my_expr_to_ir)((my_ic),((my_n)->my_b)));
(my_irbranch)((my_ic),(my_a),(my_bool_next),(my_bool_final));
- (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0)));
(my_b)=((my_mkirconst)((my_ic),(1UL)));
- (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b)));
((my_o)->my_t)=((my_n)->my_t);
(my_iraddop)((my_ic),(my_o));
(my_irjump)((my_ic),(my_bool_out),(my_bool_next));
- (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0)));
(my_b)=((my_mkirconst)((my_ic),(0UL)));
- (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b)));
((my_o)->my_t)=((my_n)->my_t);
(my_iraddop)((my_ic),(my_o));
(my_irjump)((my_ic),(my_bool_out),(my_bool_out));
@@ -4524,6 +4521,9 @@ void( my_ir_optimize)(struct my_irfunc* my_ic){
(my_irblock_fold)((my_ic),(((my_ic)->my_blocks)[my_i]));
(my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL))));
}
+ if ((unsigned long)(((long)((my_strcmp)(((my_ic)->my_name),((unsigned char *)"reconstruct_dec"))))==((long)(0UL)))) {
+ (my_irshow)(((void *)0),(((my_ic)->my_blocks)[0UL]));
+ }
}
void( my_iraddarg)(struct my_irfunc* my_ic,unsigned char* my_name,struct my_type* my_t){
struct my_irvar** my_iv = 0;
@@ -4595,6 +4595,7 @@ void( my_irblock_dead_expr)(struct my_irfunc* my_ic,struct my_irblock* my_b){
void( my_irblock_fold)(struct my_irfunc* my_ic,struct my_irblock* my_b){
unsigned long my_i = 0;
struct my_irop* my_o = 0;
+ struct my_irop* my_ret = 0;
if ((unsigned long)(!((my_b)->my_done))) {
return;
}
@@ -4603,10 +4604,23 @@ void( my_irblock_fold)(struct my_irfunc* my_ic,struct my_irblock* my_b){
if ((unsigned long)(((long)(my_i))==((long)((my_b)->my_ops_len)))) {
break;
}
- (my_o)=((my_irexpr_fold)((my_ic),(my_b),(((my_b)->my_ops)[my_i])));
+ (my_o)=((my_irexpr_fold)((my_ic),(((my_b)->my_ops)[my_i])));
(((my_b)->my_ops)[my_i])=(my_o);
(my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL))));
}
+ (my_i)=((unsigned long)(((unsigned long)(my_i))-((unsigned long)(1UL))));
+ (my_o)=(((my_b)->my_ops)[my_i]);
+ if ((unsigned long)(((unsigned long)(((long)((my_o)->my_kind))==((long)(my_IOP_BRANCH))))&&((unsigned long)(((long)(((my_o)->my_a)->my_kind))==((long)(my_IOP_CONST)))))) {
+ (my_ret)=((my_mkirop)((my_ic),(my_IOP_JUMP),((void *)0),((void *)0)));
+ ((my_ret)->my_filename)=((my_o)->my_filename);
+ ((my_ret)->my_lineno)=((my_o)->my_lineno);
+ ((my_ret)->my_colno)=((my_o)->my_colno);
+ (((my_b)->my_ops)[my_i])=(my_ret);
+ if ((unsigned long)(!((my_o)->my_n))) {
+ ((my_b)->my_out)=((my_b)->my_alt);
+ }
+ ((my_b)->my_alt)=((void *)0);
+ }
}
void( my_irbranch)(struct my_irfunc* my_ic,struct my_irop* my_cond,struct my_irblock* my_alt,struct my_irblock* my_next){
struct my_irblock* my_cur = 0;
@@ -4653,8 +4667,7 @@ struct my_irop*( my_ircall)(struct my_irfunc* my_ic,struct my_node* my_n){
}
(my_fp)=((my_mkirtmp)((my_ic),(((my_n)->my_a)->my_t)));
(my_b)=((my_expr_to_ir)((my_ic),((my_n)->my_a)));
- (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_fp),((void *)0)));
- (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_fp),(my_b)));
((my_o)->my_t)=(((my_n)->my_a)->my_t);
(my_iraddop)((my_ic),(my_o));
(my_arg)=((my_n)->my_b);
@@ -4675,8 +4688,7 @@ struct my_irop*( my_ircall)(struct my_irfunc* my_ic,struct my_node* my_n){
}
((my_tmp)[my_i])=((my_mkirtmp)((my_ic),(((my_arg)->my_a)->my_t)));
(my_b)=((my_expr_to_ir)((my_ic),((my_arg)->my_a)));
- (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),((my_tmp)[my_i]),((void *)0)));
- (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),((my_tmp)[my_i]),(my_b)));
((my_o)->my_t)=(((my_arg)->my_a)->my_t);
(my_iraddop)((my_ic),(my_o));
(my_arg)=((my_arg)->my_b);
@@ -4697,8 +4709,7 @@ struct my_irop*( my_ircall)(struct my_irfunc* my_ic,struct my_node* my_n){
}
(my_free)(((my_ic)->my_a),((unsigned char*)my_tmp));
(my_ret)=((my_mkirtmp)((my_ic),((my_n)->my_t)));
- (my_b)=((my_mkirop)((my_ic),(my_IOP_REF),(my_ret),((void *)0)));
- (my_o)=((my_mkirop)((my_ic),(my_IOP_RETVAL),(my_b),((void *)0)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_RETVAL),(my_ret),((void *)0)));
((my_o)->my_t)=((my_n)->my_t);
(my_iraddop)((my_ic),(my_o));
(my_o)=((my_mkirop)((my_ic),(my_IOP_CALL),(my_fp),((void *)0)));
@@ -4716,107 +4727,159 @@ struct my_irop*( my_ircall)(struct my_irfunc* my_ic,struct my_node* my_n){
((my_ic)->my_cur)=(my_next);
return my_ret;
}
-struct my_irop*( my_irexpr_fold)(struct my_irfunc* my_ic,struct my_irblock* my_b,struct my_irop* my_o){
+struct my_irop*( my_irexpr_fold)(struct my_irfunc* my_ic,struct my_irop* my_o){
+ struct my_irop* my_a = 0;
+ struct my_irop* my_b = 0;
+ struct my_irop* my_c = 0;
+ unsigned long my_n = 0;
unsigned long my_kind = 0;
- (my_kind)=((my_o)->my_kind);
+ struct my_irop* my_ret = 0;
if ((my_o)->my_a) {
- ((my_o)->my_a)=((my_irexpr_fold)((my_ic),(my_b),((my_o)->my_a)));
+ (my_a)=((my_irexpr_fold)((my_ic),((my_o)->my_a)));
} else {
return my_o;
}
if ((my_o)->my_b) {
- ((my_o)->my_b)=((my_irexpr_fold)((my_ic),(my_b),((my_o)->my_b)));
+ (my_b)=((my_irexpr_fold)((my_ic),((my_o)->my_b)));
}
- if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_REF))))&&((unsigned long)(((long)(((my_o)->my_a)->my_kind))==((long)(my_IOP_LOAD)))))) {
- ((((my_o)->my_a)->my_a)->my_t)=((my_o)->my_t);
- return ((my_o)->my_a)->my_a;
+ (my_kind)=((my_o)->my_kind);
+ if ((unsigned long)(((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_REF))))&&((unsigned long)(((long)((my_a)->my_kind))==((long)(my_IOP_LOAD))))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_LOAD))))&&((unsigned long)(((long)((my_a)->my_kind))==((long)(my_IOP_REF)))))))) {
+ (my_ret)=((my_mkirop)((my_ic),(((my_a)->my_a)->my_kind),(((my_a)->my_a)->my_a),(((my_a)->my_a)->my_b)));
+ ((my_ret)->my_filename)=((my_o)->my_filename);
+ ((my_ret)->my_lineno)=((my_o)->my_lineno);
+ ((my_ret)->my_colno)=((my_o)->my_colno);
+ ((my_ret)->my_t)=((my_o)->my_t);
+ ((my_ret)->my_n)=(((my_a)->my_a)->my_n);
+ return my_ret;
}
- if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_LOAD))))&&((unsigned long)(((long)(((my_o)->my_a)->my_kind))==((long)(my_IOP_REF)))))) {
- ((((my_o)->my_a)->my_a)->my_t)=((my_o)->my_t);
- return ((my_o)->my_a)->my_a;
- }
- if ((unsigned long)(((long)(((my_o)->my_a)->my_kind))!=((long)(my_IOP_CONST)))) {
- return my_o;
+ if ((unsigned long)(((long)((my_a)->my_kind))!=((long)(my_IOP_CONST)))) {
+ goto my_out;
}
if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NEG)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(-(unsigned long)(((my_o)->my_a)->my_n)));
- return (my_o)->my_a;
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(-(unsigned long)((my_a)->my_n))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NOT)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(~(unsigned long)((my_a)->my_n))));
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NOT)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(~(unsigned long)(((my_o)->my_a)->my_n)));
- return (my_o)->my_a;
+ if ((unsigned long)(((unsigned long)(!(my_b)))||((unsigned long)(((long)((my_b)->my_kind))!=((long)(my_IOP_CONST)))))) {
+ goto my_out;
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_BRANCH)))) {
- if ((unsigned long)(!(((my_o)->my_a)->my_n))) {
- ((my_b)->my_out)=((my_b)->my_alt);
+ if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_ADD)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((unsigned long)((my_a)->my_n))+((unsigned long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_OR)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((unsigned long)((my_a)->my_n))|((unsigned long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_XOR)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((unsigned long)((my_a)->my_n))^((unsigned long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_DIV)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))/((long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MOD)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))%((long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LSH)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((unsigned long)((my_a)->my_n))<<((unsigned long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_RSH)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((unsigned long)((my_a)->my_n))>>((unsigned long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))*((long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_SUB)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((unsigned long)((my_a)->my_n))-((unsigned long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_EQ)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))==((long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NE)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))!=((long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_GT)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))>((long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_GE)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))>=((long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LT)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))<((long)((my_b)->my_n)))));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LE)))) {
+ return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))<=((long)((my_b)->my_n)))));
+ } else {
+ goto my_out;
}
- ((my_o)->my_kind)=(my_IOP_JUMP);
- return my_o;
+my_out:
+ if ((unsigned long)((my_a)&&((unsigned long)(((long)((my_a)->my_kind))==((long)(my_IOP_CONST)))))) {
+ (my_n)=((my_a)->my_n);
+ if ((unsigned long)(((long)(my_n))==((long)(0UL)))) {
+ if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_ADD))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_OR))))||((unsigned long)(((long)(my_kind))==((long)(my_IOP_XOR)))))))) {
+ return my_b;
}
- if ((unsigned long)(((unsigned long)(!((my_o)->my_b)))||((unsigned long)(((long)(((my_o)->my_b)->my_kind))!=((long)(my_IOP_CONST)))))) {
- return my_o;
+ if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_SUB)))) {
+ (my_ret)=((my_mkirop)((my_ic),(my_IOP_NEG),(my_b),((void *)0)));
+ ((my_ret)->my_filename)=((my_o)->my_filename);
+ ((my_ret)->my_lineno)=((my_o)->my_lineno);
+ ((my_ret)->my_colno)=((my_o)->my_colno);
+ return my_ret;
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_ADD)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((unsigned long)(((my_o)->my_a)->my_n))+((unsigned long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
+ if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_AND))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_LSH))))||((unsigned long)(((long)(my_kind))==((long)(my_IOP_RSH)))))))))) {
+ return (my_mkirfold)((my_ic),(my_o),(0UL));
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_OR)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((unsigned long)(((my_o)->my_a)->my_n))|((unsigned long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
+ } else if ((unsigned long)(((long)(my_n))==((long)(1UL)))) {
+ if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))) {
+ return my_b;
+ }
+ } else if ((unsigned long)(((long)(my_n))==((long)((unsigned long)(-(unsigned long)(1UL)))))) {
+ if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))) {
+ (my_ret)=((my_mkirop)((my_ic),(my_IOP_NEG),(my_b),((void *)0)));
+ ((my_ret)->my_filename)=((my_o)->my_filename);
+ ((my_ret)->my_lineno)=((my_o)->my_lineno);
+ ((my_ret)->my_colno)=((my_o)->my_colno);
+ return my_ret;
}
if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_XOR)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((unsigned long)(((my_o)->my_a)->my_n))^((unsigned long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
+ (my_ret)=((my_mkirop)((my_ic),(my_IOP_NOT),(my_b),((void *)0)));
+ ((my_ret)->my_filename)=((my_o)->my_filename);
+ ((my_ret)->my_lineno)=((my_o)->my_lineno);
+ ((my_ret)->my_colno)=((my_o)->my_colno);
+ return my_ret;
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_DIV)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))/((long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
+ if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_AND)))) {
+ return my_b;
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MOD)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))%((long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LSH)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((unsigned long)(((my_o)->my_a)->my_n))<<((unsigned long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_RSH)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((unsigned long)(((my_o)->my_a)->my_n))>>((unsigned long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
+ if ((unsigned long)((my_b)&&((unsigned long)(((long)((my_b)->my_kind))==((long)(my_IOP_CONST)))))) {
+ (my_n)=((my_b)->my_n);
+ if ((unsigned long)(((long)(my_n))==((long)(0UL)))) {
+ if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_ADD))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_OR))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_XOR))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_SUB))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_LSH))))||((unsigned long)(((long)(my_kind))==((long)(my_IOP_RSH)))))))))))))) {
+ return my_a;
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))*((long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
+ if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_AND))))||((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))))) {
+ return (my_mkirfold)((my_ic),(my_o),(0UL));
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_SUB)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((unsigned long)(((my_o)->my_a)->my_n))-((unsigned long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
- }
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_EQ)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))==((long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
+ } else if ((unsigned long)(((long)(my_n))==((long)(1UL)))) {
+ if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_DIV))))||((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))))) {
+ return my_a;
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NE)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))!=((long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
+ } else if ((unsigned long)(((long)(my_n))==((long)((unsigned long)(-(unsigned long)(1UL)))))) {
+ if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))) {
+ (my_ret)=((my_mkirop)((my_ic),(my_IOP_NEG),(my_a),((void *)0)));
+ ((my_ret)->my_filename)=((my_o)->my_filename);
+ ((my_ret)->my_lineno)=((my_o)->my_lineno);
+ ((my_ret)->my_colno)=((my_o)->my_colno);
+ return my_ret;
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_GT)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))>((long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
+ if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_XOR)))) {
+ (my_ret)=((my_mkirop)((my_ic),(my_IOP_NOT),(my_a),((void *)0)));
+ ((my_ret)->my_filename)=((my_o)->my_filename);
+ ((my_ret)->my_lineno)=((my_o)->my_lineno);
+ ((my_ret)->my_colno)=((my_o)->my_colno);
+ return my_ret;
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_GE)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))>=((long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
+ if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_AND)))) {
+ return my_a;
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LT)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))<((long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
}
- if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LE)))) {
- (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))<=((long)(((my_o)->my_b)->my_n))));
- return (my_o)->my_a;
}
+ if ((unsigned long)(((unsigned long)(((long)((my_o)->my_a))==((long)(my_a))))&&((unsigned long)(((long)((my_o)->my_b))==((long)(my_b)))))) {
return my_o;
+ }
+ (my_ret)=((my_mkirop)((my_ic),(my_kind),(my_a),(my_b)));
+ ((my_ret)->my_filename)=((my_o)->my_filename);
+ ((my_ret)->my_lineno)=((my_o)->my_lineno);
+ ((my_ret)->my_colno)=((my_o)->my_colno);
+ ((my_ret)->my_t)=((my_o)->my_t);
+ ((my_ret)->my_n)=((my_o)->my_n);
+ return my_ret;
}
struct my_irblock*( my_irfind_block)(struct my_irfunc* my_ic,unsigned char* my_name,unsigned long my_make){
struct my_irlabel** my_link = 0;
@@ -4911,6 +4974,212 @@ void( my_irreturn)(struct my_irfunc* my_ic,struct my_irop* my_value){
}
((my_ic)->my_cur)=((void *)0);
}
+void( my_irshow)(struct my_file* my_out,struct my_irblock* my_b){
+ unsigned long my_id = 0;
+ (my_id)=(1UL);
+ (my_irshow2)((my_out),(my_b),(&(my_id)));
+ (my_irreset)((my_b));
+}
+void( my_irshow2)(struct my_file* my_out,struct my_irblock* my_b,unsigned long* my_id){
+ if ((unsigned long)(!(my_b))) {
+ return;
+ }
+ if ((my_b)->my_mark) {
+ return;
+ }
+ ((my_b)->my_mark)=(*(my_id));
+ (*(my_id))=((unsigned long)(((unsigned long)(*(my_id)))+((unsigned long)(1UL))));
+ (my_irshow3)((my_out),(my_b));
+ if ((my_b)->my_out) {
+ (my_irshow2)((my_out),((my_b)->my_out),(my_id));
+ }
+ if ((my_b)->my_alt) {
+ (my_irshow2)((my_out),((my_b)->my_alt),(my_id));
+ }
+}
+void( my_irshow3)(struct my_file* my_out,struct my_irblock* my_b){
+ unsigned long my_i = 0;
+ (my_fputd)((my_out),((my_b)->my_mark));
+ (my_fputs)((my_out),((unsigned char *)"{\012"));
+ (my_i)=(0UL);
+ while (1) {
+ if ((unsigned long)(((long)(my_i))==((long)((my_b)->my_ops_len)))) {
+ break;
+ }
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),(((my_b)->my_ops)[my_i]));
+ (my_fputs)((my_out),((unsigned char *)"\012"));
+ (my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL))));
+ }
+ (my_fputs)((my_out),((unsigned char *)"}\012"));
+}
+void( my_irshow4)(struct my_file* my_out,struct my_irop* my_o){
+ unsigned long my_kind = 0;
+ if ((unsigned long)(!(my_o))) {
+ (my_fputs)((my_out),((unsigned char *)"(nil)"));
+ return;
+ }
+ (my_kind)=((my_o)->my_kind);
+ if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_VAR)))) {
+ (my_fputs)((my_out),((unsigned char *)"(var "));
+ (my_fputd)((my_out),((my_o)->my_n));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_FUNC)))) {
+ (my_fputs)((my_out),((unsigned char *)"(func "));
+ (my_fputs)((my_out),((my_o)->my_s));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_CONST)))) {
+ (my_fputs)((my_out),((unsigned char *)"(const "));
+ (my_fputd)((my_out),((my_o)->my_n));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_STR)))) {
+ (my_fputs)((my_out),((unsigned char *)"(str)"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LOAD)))) {
+ (my_fputs)((my_out),((unsigned char *)"(load "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_STORE)))) {
+ (my_fputs)((my_out),((unsigned char *)"(store "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_REF)))) {
+ (my_fputs)((my_out),((unsigned char *)"(ref "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_RETVAL)))) {
+ (my_fputs)((my_out),((unsigned char *)"(retval "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_ARG)))) {
+ (my_fputs)((my_out),((unsigned char *)"(arg "));
+ (my_fputd)((my_out),((my_o)->my_n));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NEG)))) {
+ (my_fputs)((my_out),((unsigned char *)"(neg "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NOT)))) {
+ (my_fputs)((my_out),((unsigned char *)"(not "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_ADD)))) {
+ (my_fputs)((my_out),((unsigned char *)"(add "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_AND)))) {
+ (my_fputs)((my_out),((unsigned char *)"(and "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_OR)))) {
+ (my_fputs)((my_out),((unsigned char *)"(or "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_XOR)))) {
+ (my_fputs)((my_out),((unsigned char *)"(xor "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_DIV)))) {
+ (my_fputs)((my_out),((unsigned char *)"(div "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MOD)))) {
+ (my_fputs)((my_out),((unsigned char *)"(mod "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LSH)))) {
+ (my_fputs)((my_out),((unsigned char *)"(lsh "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_RSH)))) {
+ (my_fputs)((my_out),((unsigned char *)"(rsh "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))) {
+ (my_fputs)((my_out),((unsigned char *)"(mul "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_SUB)))) {
+ (my_fputs)((my_out),((unsigned char *)"(sub "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_EQ)))) {
+ (my_fputs)((my_out),((unsigned char *)"(eq "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NE)))) {
+ (my_fputs)((my_out),((unsigned char *)"(ne "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_GT)))) {
+ (my_fputs)((my_out),((unsigned char *)"(gt "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_GE)))) {
+ (my_fputs)((my_out),((unsigned char *)"(ge "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LT)))) {
+ (my_fputs)((my_out),((unsigned char *)"(lt "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LE)))) {
+ (my_fputs)((my_out),((unsigned char *)"(le "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)" "));
+ (my_irshow4)((my_out),((my_o)->my_b));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_CALL)))) {
+ (my_fputs)((my_out),((unsigned char *)"(call "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_JUMP)))) {
+ (my_fputs)((my_out),((unsigned char *)"(jump)"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_BRANCH)))) {
+ (my_fputs)((my_out),((unsigned char *)"(branch "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_RETURN)))) {
+ (my_fputs)((my_out),((unsigned char *)"(return "));
+ (my_irshow4)((my_out),((my_o)->my_a));
+ (my_fputs)((my_out),((unsigned char *)")"));
+ } else {
+ (my_die)(((unsigned char *)"invalid iop"));
+ }
+}
void( my_labels_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){
unsigned long my_kind = 0;
unsigned char* my_name = 0;
@@ -5428,6 +5697,15 @@ struct my_irop*( my_mkirconst)(struct my_irfunc* my_ic,unsigned long my_n){
((my_o)->my_n)=(my_n);
return my_o;
}
+struct my_irop*( my_mkirfold)(struct my_irfunc* my_ic,struct my_irop* my_s,unsigned long my_n){
+ struct my_irop* my_o = 0;
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_CONST),((void *)0),((void *)0)));
+ ((my_o)->my_filename)=((my_s)->my_filename);
+ ((my_o)->my_lineno)=((my_s)->my_lineno);
+ ((my_o)->my_colno)=((my_s)->my_colno);
+ ((my_o)->my_n)=(my_n);
+ return my_o;
+}
struct my_irop*( my_mkirfunc)(struct my_irfunc* my_ic,unsigned char* my_name){
struct my_irop* my_o = 0;
(my_o)=((my_mkirop)((my_ic),(my_IOP_FUNC),((void *)0),((void *)0)));
@@ -6065,7 +6343,13 @@ void( my_output_irretval)(struct my_irfunc* my_ic,struct my_irblock* my_b,struct
return;
}
(my_as_modrr)(((my_ic)->my_s),(my_OP_MOVE),(my_R_RDI),(my_R_RAX));
- (my_output_irexpr)((my_ic),(my_b),((my_op)->my_a));
+ if ((unsigned long)(((long)(((my_op)->my_a)->my_kind))==((long)(my_IOP_LOAD)))) {
+ (my_output_irexpr)((my_ic),(my_b),(((my_op)->my_a)->my_a));
+ } else if ((unsigned long)(((long)(((my_op)->my_a)->my_kind))==((long)(my_IOP_VAR)))) {
+ (my_as_modrm)(((my_ic)->my_s),(my_OP_LEA),(my_R_RAX),(my_R_RBP),(0UL),(0UL),((((my_ic)->my_vars)[((my_op)->my_a)->my_n])->my_offset));
+ } else {
+ (my_die)(((unsigned char *)"invalid store"));
+ }
if ((unsigned long)(((long)(((my_op)->my_t)->my_kind))==((long)(my_TY_BYTE)))) {
(my_as_modrm)(((my_ic)->my_s),(my_OP_STOREB),(my_R_RDI),(my_R_RAX),(0UL),(0UL),(0UL));
} else if ((my_type_isprim)(((my_op)->my_t))) {
@@ -6083,7 +6367,13 @@ void( my_output_irstmt)(struct my_irfunc* my_ic,struct my_irblock* my_b,struct m
(((my_ic)->my_s)->my_lineno)=((my_o)->my_lineno);
(my_kind)=((my_o)->my_kind);
if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_STORE)))) {
- (my_output_irexpr)((my_ic),(my_b),((my_o)->my_a));
+ if ((unsigned long)(((long)(((my_o)->my_a)->my_kind))==((long)(my_IOP_LOAD)))) {
+ (my_output_irexpr)((my_ic),(my_b),(((my_o)->my_a)->my_a));
+ } else if ((unsigned long)(((long)(((my_o)->my_a)->my_kind))==((long)(my_IOP_VAR)))) {
+ (my_as_modrm)(((my_ic)->my_s),(my_OP_LEA),(my_R_RAX),(my_R_RBP),(0UL),(0UL),((((my_ic)->my_vars)[((my_o)->my_a)->my_n])->my_offset));
+ } else {
+ (my_die)(((unsigned char *)"invalid store"));
+ }
(my_as_opr)(((my_ic)->my_s),(my_OP_PUSHR),(my_R_RAX));
(my_output_irexpr)((my_ic),(my_b),((my_o)->my_b));
(my_as_opr)(((my_ic)->my_s),(my_OP_POPR),(my_R_RDI));
diff --git a/ir.om b/ir.om
@@ -335,8 +335,7 @@ func ircall(ic: *irfunc, n: *node): *irop {
// Evaluate the expression left to right starting with the function
fp = mkirtmp(ic, n.a.t);
b = expr_to_ir(ic, n.a);
- a = mkirop(ic, IOP_REF, fp, nil);
- o = mkirop(ic, IOP_STORE, a, b);
+ o = mkirop(ic, IOP_STORE, fp, b);
o.t = n.a.t;
iraddop(ic, o);
@@ -370,8 +369,7 @@ func ircall(ic: *irfunc, n: *node): *irop {
b = expr_to_ir(ic, arg.a);
// Save the value
- a = mkirop(ic, IOP_REF, tmp[i], nil);
- o = mkirop(ic, IOP_STORE, a, b);
+ o = mkirop(ic, IOP_STORE, tmp[i], b);
o.t = arg.a.t;
iraddop(ic, o);
@@ -400,8 +398,7 @@ func ircall(ic: *irfunc, n: *node): *irop {
// Add a temporary for the return value
ret = mkirtmp(ic, n.t);
- b = mkirop(ic, IOP_REF, ret, nil);
- o = mkirop(ic, IOP_RETVAL, b, nil);
+ o = mkirop(ic, IOP_RETVAL, ret, nil);
o.t = n.t;
iraddop(ic, o);
@@ -541,8 +538,7 @@ func expr_to_ir(ic: *irfunc, n: *node): *irop {
} else if kind == N_ASSIGN {
a = expr_to_ir(ic, n.a);
b = expr_to_ir(ic, n.b);
- d = mkirop(ic, IOP_REF, a, nil);
- o = mkirop(ic, IOP_STORE, d, b);
+ o = mkirop(ic, IOP_STORE, a, b);
o.t = n.t;
return o;
} else if kind == N_POS {
@@ -568,16 +564,14 @@ func expr_to_ir(ic: *irfunc, n: *node): *irop {
a = expr_to_ir(ic, n.a);
irbranch(ic, a, bool_next, bool_body);
- a = mkirop(ic, IOP_REF, e, nil);
b = mkirconst(ic, 0);
- o = mkirop(ic, IOP_STORE, a, b);
+ o = mkirop(ic, IOP_STORE, e, b);
o.t = n.t;
iraddop(ic, o);
irjump(ic, bool_out, bool_next);
- a = mkirop(ic, IOP_REF, e, nil);
b = mkirconst(ic, 1);
- o = mkirop(ic, IOP_STORE, a, b);
+ o = mkirop(ic, IOP_STORE, e, b);
o.t = n.t;
iraddop(ic, o);
irjump(ic, bool_out, bool_out);
@@ -593,9 +587,8 @@ func expr_to_ir(ic: *irfunc, n: *node): *irop {
a = expr_to_ir(ic, n.a);
irbranch(ic, a, bool_next, bool_body);
- a = mkirop(ic, IOP_REF, e, nil);
b = mkirconst(ic, 1);
- o = mkirop(ic, IOP_STORE, a, b);
+ o = mkirop(ic, IOP_STORE, e, b);
o.t = n.t;
iraddop(ic, o);
irjump(ic, bool_out, bool_next);
@@ -605,16 +598,14 @@ func expr_to_ir(ic: *irfunc, n: *node): *irop {
a = expr_to_ir(ic, n.b);
irbranch(ic, a, bool_next, bool_final);
- a = mkirop(ic, IOP_REF, e, nil);
b = mkirconst(ic, 1);
- o = mkirop(ic, IOP_STORE, a, b);
+ o = mkirop(ic, IOP_STORE, e, b);
o.t = n.t;
iraddop(ic, o);
irjump(ic, bool_out, bool_next);
- a = mkirop(ic, IOP_REF, e, nil);
b = mkirconst(ic, 0);
- o = mkirop(ic, IOP_STORE, a, b);
+ o = mkirop(ic, IOP_STORE, e, b);
o.t = n.t;
iraddop(ic, o);
irjump(ic, bool_out, bool_out);
@@ -633,16 +624,14 @@ func expr_to_ir(ic: *irfunc, n: *node): *irop {
a = expr_to_ir(ic, n.b);
irbranch(ic, a, bool_next, bool_final);
- a = mkirop(ic, IOP_REF, e, nil);
b = mkirconst(ic, 1);
- o = mkirop(ic, IOP_STORE, a, b);
+ o = mkirop(ic, IOP_STORE, e, b);
o.t = n.t;
iraddop(ic, o);
irjump(ic, bool_out, bool_next);
- a = mkirop(ic, IOP_REF, e, nil);
b = mkirconst(ic, 0);
- o = mkirop(ic, IOP_STORE, a, b);
+ o = mkirop(ic, IOP_STORE, e, b);
o.t = n.t;
iraddop(ic, o);
irjump(ic, bool_out, bool_out);
@@ -1719,7 +1708,14 @@ func output_irstmt(ic: *irfunc, b: *irblock, o: *irop) {
kind = o.kind;
if kind == IOP_STORE {
// Evaluate the address
- output_irexpr(ic, b, o.a);
+ if o.a.kind == IOP_LOAD {
+ output_irexpr(ic, b, o.a.a);
+ } else if o.a.kind == IOP_VAR {
+ as_modrm(ic.s, OP_LEA, R_RAX, R_RBP, 0, 0, ic.vars[o.a.n].offset);
+ } else {
+ die("invalid store");
+ }
+
as_opr(ic.s, OP_PUSHR, R_RAX);
// Evaluate the value
@@ -1875,7 +1871,13 @@ func output_irretval(ic: *irfunc, b: *irblock, o: *irop) {
as_modrr(ic.s, OP_MOVE, R_RDI, R_RAX);
// Compute the address
- output_irexpr(ic, b, op.a);
+ if op.a.kind == IOP_LOAD {
+ output_irexpr(ic, b, op.a.a);
+ } else if op.a.kind == IOP_VAR {
+ as_modrm(ic.s, OP_LEA, R_RAX, R_RBP, 0, 0, ic.vars[op.a.n].offset);
+ } else {
+ die("invalid store");
+ }
// Execute the store
if op.t.kind == TY_BYTE {
@@ -2123,139 +2125,217 @@ func irblock_dead_expr(ic: *irfunc, b: *irblock) {
b.ops_len = j;
}
-func irexpr_fold(ic: *irfunc, b: *irblock, o: *irop): *irop {
- var kind: int;
+func mkirfold(ic: *irfunc, s: *irop, n: int): *irop {
+ var o: *irop;
- kind = o.kind;
+ o = mkirop(ic, IOP_CONST, nil, nil);
+
+ o.filename = s.filename;
+ o.lineno = s.lineno;
+ o.colno = s.colno;
+ o.n = n;
+
+ return o;
+}
+
+func irexpr_fold(ic: *irfunc, o: *irop): *irop {
+ var a: *irop;
+ var b: *irop;
+ var c: *irop;
+ var n: int;
+ var kind: int;
+ var ret: *irop;
+ // Recursive fold the first operand
if o.a {
- o.a = irexpr_fold(ic, b, o.a);
+ a = irexpr_fold(ic, o.a);
} else {
+ // If the op has zero operands, there's nothing to do.
return o;
}
+ // Recursive fold the second operand
if o.b {
- o.b = irexpr_fold(ic, b, o.b);
+ b = irexpr_fold(ic, o.b);
}
- if kind == IOP_REF && o.a.kind == IOP_LOAD {
- o.a.a.t = o.t;
- return o.a.a;
- }
+ kind = o.kind;
- if kind == IOP_LOAD && o.a.kind == IOP_REF {
- o.a.a.t = o.t;
- return o.a.a;
+ // Eliminate *& and &* redundant operations
+ if (kind == IOP_REF && a.kind == IOP_LOAD) || (kind == IOP_LOAD && a.kind == IOP_REF) {
+ // This could be a type pun, so make a new op with a new type
+ ret = mkirop(ic, a.a.kind, a.a.a, a.a.b);
+ ret.filename = o.filename;
+ ret.lineno = o.lineno;
+ ret.colno = o.colno;
+ ret.t = o.t;
+ ret.n = a.a.n;
+ return ret;
}
- if o.a.kind != IOP_CONST {
- return o;
+ // Check if a is a constant
+ if a.kind != IOP_CONST {
+ goto out;
}
+ // Simplify unary operations
if kind == IOP_NEG {
- o.a.n = -o.a.n;
- return o.a;
- }
-
- if kind == IOP_NOT {
- o.a.n = ~o.a.n;
- return o.a;
- }
-
- if kind == IOP_BRANCH {
- if !o.a.n {
- b.out = b.alt;
- }
- o.kind = IOP_JUMP;
- return o;
+ return mkirfold(ic, o, -a.n);
+ } else if kind == IOP_NOT {
+ return mkirfold(ic, o, ~a.n);
}
- if !o.b || o.b.kind != IOP_CONST {
- return o;
+ // Check if b is a constant
+ if !b || b.kind != IOP_CONST {
+ goto out;
}
+ // Simplify binary operations
if kind == IOP_ADD {
- o.a.n = o.a.n + o.b.n;
- return o.a;
- }
-
- if kind == IOP_OR {
- o.a.n = o.a.n | o.b.n;
- return o.a;
+ return mkirfold(ic, o, a.n + b.n);
+ } else if kind == IOP_OR {
+ return mkirfold(ic, o, a.n | b.n);
+ } else if kind == IOP_XOR {
+ return mkirfold(ic, o, a.n ^ b.n);
+ } else if kind == IOP_DIV {
+ return mkirfold(ic, o, a.n / b.n);
+ } else if kind == IOP_MOD {
+ return mkirfold(ic, o, a.n % b.n);
+ } else if kind == IOP_LSH {
+ return mkirfold(ic, o, a.n << b.n);
+ } else if kind == IOP_RSH {
+ return mkirfold(ic, o, a.n >> b.n);
+ } else if kind == IOP_MUL {
+ return mkirfold(ic, o, a.n * b.n);
+ } else if kind == IOP_SUB {
+ return mkirfold(ic, o, a.n - b.n);
+ } else if kind == IOP_EQ {
+ return mkirfold(ic, o, a.n == b.n);
+ } else if kind == IOP_NE {
+ return mkirfold(ic, o, a.n != b.n);
+ } else if kind == IOP_GT {
+ return mkirfold(ic, o, a.n > b.n);
+ } else if kind == IOP_GE {
+ return mkirfold(ic, o, a.n >= b.n);
+ } else if kind == IOP_LT {
+ return mkirfold(ic, o, a.n < b.n);
+ } else if kind == IOP_LE {
+ return mkirfold(ic, o, a.n <= b.n);
+ } else {
+ goto out;
}
- if kind == IOP_XOR {
- o.a.n = o.a.n ^ o.b.n;
- return o.a;
- }
+out:
- if kind == IOP_DIV {
- o.a.n = o.a.n / o.b.n;
- return o.a;
- }
+ // Do some simple algebraic identities on a
+ if a && a.kind == IOP_CONST {
+ n = a.n;
- if kind == IOP_MOD {
- o.a.n = o.a.n % o.b.n;
- return o.a;
- }
+ if n == 0 {
+ if kind == IOP_ADD || kind == IOP_OR || kind == IOP_XOR {
+ return b;
+ }
- if kind == IOP_LSH {
- o.a.n = o.a.n << o.b.n;
- return o.a;
- }
+ if kind == IOP_SUB {
+ ret = mkirop(ic, IOP_NEG, b, nil);
+ ret.filename = o.filename;
+ ret.lineno = o.lineno;
+ ret.colno = o.colno;
+ return ret;
+ }
- if kind == IOP_RSH {
- o.a.n = o.a.n >> o.b.n;
- return o.a;
- }
+ if kind == IOP_AND || kind == IOP_MUL || kind == IOP_LSH || kind == IOP_RSH {
+ return mkirfold(ic, o, 0);
+ }
+ } else if n == 1 {
+ if kind == IOP_MUL {
+ return b;
+ }
+ } else if n == -1 {
+ if kind == IOP_MUL {
+ ret = mkirop(ic, IOP_NEG, b, nil);
+ ret.filename = o.filename;
+ ret.lineno = o.lineno;
+ ret.colno = o.colno;
+ return ret;
+ }
- if kind == IOP_MUL {
- o.a.n = o.a.n * o.b.n;
- return o.a;
- }
+ if kind == IOP_XOR {
+ ret = mkirop(ic, IOP_NOT, b, nil);
+ ret.filename = o.filename;
+ ret.lineno = o.lineno;
+ ret.colno = o.colno;
+ return ret;
+ }
- if kind == IOP_SUB {
- o.a.n = o.a.n - o.b.n;
- return o.a;
+ if kind == IOP_AND {
+ return b;
+ }
+ }
}
- if kind == IOP_EQ {
- o.a.n = o.a.n == o.b.n;
- return o.a;
- }
+ // Do some simple algebraic identities on b
+ if b && b.kind == IOP_CONST {
+ n = b.n;
- if kind == IOP_NE {
- o.a.n = o.a.n != o.b.n;
- return o.a;
- }
+ if n == 0 {
+ if (
+ kind == IOP_ADD || kind == IOP_OR || kind == IOP_XOR
+ || kind == IOP_SUB || kind == IOP_LSH || kind == IOP_RSH
+ ) {
+ return a;
+ }
- if kind == IOP_GT {
- o.a.n = o.a.n > o.b.n;
- return o.a;
- }
+ if kind == IOP_AND || kind == IOP_MUL {
+ return mkirfold(ic, o, 0);
+ }
+ } else if n == 1 {
+ if kind == IOP_DIV || kind == IOP_MUL {
+ return a;
+ }
+ } else if n == -1 {
+ if kind == IOP_MUL {
+ ret = mkirop(ic, IOP_NEG, a, nil);
+ ret.filename = o.filename;
+ ret.lineno = o.lineno;
+ ret.colno = o.colno;
+ return ret;
+ }
- if kind == IOP_GE {
- o.a.n = o.a.n >= o.b.n;
- return o.a;
- }
+ if kind == IOP_XOR {
+ ret = mkirop(ic, IOP_NOT, a, nil);
+ ret.filename = o.filename;
+ ret.lineno = o.lineno;
+ ret.colno = o.colno;
+ return ret;
+ }
- if kind == IOP_LT {
- o.a.n = o.a.n < o.b.n;
- return o.a;
+ if kind == IOP_AND {
+ return a;
+ }
+ }
}
- if kind == IOP_LE {
- o.a.n = o.a.n <= o.b.n;
- return o.a;
+ // If neither side folded, then just return the op unmodified
+ if o.a == a && o.b == b {
+ return o;
}
- return o;
+ // Otherwise, make a new one with the folded operands
+ ret = mkirop(ic, kind, a, b);
+ ret.filename = o.filename;
+ ret.lineno = o.lineno;
+ ret.colno = o.colno;
+ ret.t = o.t;
+ ret.n = o.n;
+ return ret;
}
// Fold constant expressions
func irblock_fold(ic: *irfunc, b: *irblock) {
var i: int;
var o: *irop;
+ var ret: *irop;
if !b.done {
return;
@@ -2267,11 +2347,31 @@ func irblock_fold(ic: *irfunc, b: *irblock) {
break;
}
- o = irexpr_fold(ic, b, b.ops[i]);
+ o = irexpr_fold(ic, b.ops[i]);
b.ops[i] = o;
i = i + 1;
}
+
+ i = i - 1;
+
+ o = b.ops[i];
+
+ // Fold constant branches into jumps
+ if o.kind == IOP_BRANCH && o.a.kind == IOP_CONST {
+ ret = mkirop(ic, IOP_JUMP, nil, nil);
+ ret.filename = o.filename;
+ ret.lineno = o.lineno;
+ ret.colno = o.colno;
+
+ b.ops[i] = ret;
+
+ if !o.n {
+ b.out = b.alt;
+ }
+
+ b.alt = nil;
+ }
}
func ir_optimize(ic: *irfunc) {