# HG changeset patch # User kono # Date 1045454778 -32400 # Node ID ddaa1aa5b49bc93af11c3b0b1436604312acde2f # Parent c2ef3a2fbe88fc367c4d0e020423f5d569d5e749 parallel assignment done (not circular dependency) diff -r c2ef3a2fbe88 -r ddaa1aa5b49b Idea --- a/Idea Sun Feb 16 22:21:23 2003 +0900 +++ b/Idea Mon Feb 17 13:06:18 2003 +0900 @@ -1571,3 +1571,13 @@ 代入しなくて良いからと言って、ソース のリストから除いては、上書きを防げない。 + +Sun Feb 16 22:55:58 JST 2003 + +vdisp ってなんだったんだ? + +Mon Feb 17 12:35:39 JST 2003 + +並列代入は出来たみたい。代入は小さいものを先にすべきなのか? +まぁ、できりゃいいんだけど、横に避けるものが大きいのはいや +だよね。 diff -r c2ef3a2fbe88 -r ddaa1aa5b49b mc-nop-386.c --- a/mc-nop-386.c Sun Feb 16 22:21:23 2003 +0900 +++ b/mc-nop-386.c Mon Feb 17 13:06:18 2003 +0900 @@ -117,7 +117,6 @@ static int creg; /* current register */ static int dreg; /* temporary register */ static int reg_sp; /* REGister Stack-Pointer */ -static int vdisp; #define REG_EAX 0 @@ -1029,26 +1028,28 @@ } /* goto arguments list */ -/* target list4(list2(tag,disp),cdr,source_expr,ty) */ +/* target list4(list2(tag,disp),cdr,ty,source_expr) */ /* source expr=listn(tag,...) */ /* source (after) list2(tag,disp) */ -/* source list list2(e,cdr) */ +/* source list list3(e,cdr,sz) */ int -overrap(int t,int source) +overrap(int t,int sz,int source) { - int s0,s1; - int t0=cadr(car(t)); - int t1=size(caddr(t)); + int s,s0,s1; + int t0=cadr(t); + int t1=t0+sz; for(;source;source=cadr(source)) { - s0=cadr(caddr(source)); - if(car(car(source))==REGISTER && car(car(t))==REGISTER) { + s=car(source); s0=cadr(s); + if(car(s)==REGISTER && car(t)==REGISTER) { if(s0==t0) return 1; - } else if (is_same_type(car(source),car(t))) { - s1=s0+size(caddr(source)); + } else if (is_same_type(s,t)) { + s1=s0+caddr(source); +#if 0 printf("# ovedrrap source %d t0 %d t1 %d\n",car(car(t)),t0,t1); printf("# ovedrrap target %d s0 %d s1 %d\n",car(car(source)),s0,s1); printf("# ovedrrap equal = %d\n",((t0<=s0&&s0<=t1)||(t0<=s1&&s1<=t1))); +#endif if((t0<=s0&&s0<=t1)||(t0<=s1&&s1<=t1)) return 1; } } @@ -1063,6 +1064,9 @@ if (ce1) { if(car(ce1)) g_expr(car(ce1)); +#if 1 +printf("# post process ty %d+%d\n",cadr(car(ce1)),caddr(car(ce1))); +#endif if(cadr(ce1)>=0) { free_register(cadr(ce1)); } @@ -1078,13 +1082,23 @@ while(*target) { t=car(*target); s=cadddr(*target); sz=size(ty=caddr(*target)); -printf("#0p type %d car(type) %d size %d\n",ty,car(ty),sz); + if(car(t)==car(s) && cadr(t)==cadr(s)) { +#if 1 +printf("# duplicate same target check (you shouldn't see this) \n# %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); +#endif + /*書き込み先が自分自身*/ + remove0(target,t); + /* 破壊されては困るので、source listからは除かない */ + continue; + } for(p=*processing;p;p=cadr(p)) { if(car(p)==t) { /*ターゲットが処理リスト中にある*/ /* どけてしまえば、もう関係ない。二度と処理する必要もない。*/ remove0(target,t); remove0(source,s); remove0(processing,p); - +#if 1 +printf("# circular dependcy %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); +#endif /*新しいレジスタ(or スタック)を取得する*/ if (sz==size_of_int && (e1=get_register())!=-1) { e1=list2(REGISTER,e1); @@ -1097,25 +1111,32 @@ } } } - if(car(t)==car(s) && cadr(t)==cadr(s)) { - /*書き込み先が自分自身*/ - remove0(target,t); - } else if (overrap(*target,*source)) { + if (overrap(t,sz,*source)) { remove0(target,t); *processing=list2(t,*processing); e1=0; - while (overrap(*target,*source)) { + do { /*書き込み先がソースと重なっているあいだ*/ - /*他のを先にする*/ + /*他のを先に処理する*/ +#if 1 +printf("# recursive%d %d ty %d+%d sz %d\n",e1,car(t),ty,cadr(t),sz); +#endif e1=list2(parallel_assign(target,source,processing),e1); - } - /* これで空いたはず*/ + } while (overrap(t,sz,*source)); + /* これで空いた */ +#if 1 +printf("# recursive%d done %d ty %d+%d sz %d\n",e1,car(t),ty,cadr(t),sz); +#endif + g_expr(assign_expr0(t,s,ty,ty)); remove0(source,s); remove0(processing,t); - g_expr(assign_expr0(t,car(s),ty,ty)); /* 横によけたものがあれば、後始末をする*/ parallel_assign_post(e1); } else { + /* 重なってないので安心して書き込める */ +#if 1 +printf("# normal assign %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); +#endif g_expr(assign_expr0(t,s,ty,ty)); remove0(target,t); remove0(source,s); } @@ -1171,6 +1192,17 @@ ); } +int +is_memory(int e1) +{ + int ce1=car(e1); + return ( + ce1==LVAR ||ce1==RLVAR||ce1==CRLVAR || + ce1==GVAR ||ce1==RGVAR||ce1==CRGVAR || + ce1==REGISTER + ); +} + void jump(int e1, int env) { @@ -1180,7 +1212,6 @@ int target = 0; int source = 0; int processing = 0; - int sdisp = disp; /* まず、サイズを計算しながら、決まった形に落す。 */ /* ここで、書込先アドレスを決める */ @@ -1188,7 +1219,6 @@ arg_size = 0; regs = 0; max_regs = MAX_REGISTER_VAR-1; for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { e2 = car(e3); sz = size(ty=caddr(e3)); -printf("#00 type %d car(type) %d size %d\n",ty,car(ty),sz); if (regs <= max_regs&&integral(ty)) { target=list4(list2(REGISTER,virtual((regs++)+REG_ESI)), target,ty,e2); @@ -1197,6 +1227,9 @@ target,ty,e2); arg_size += sz; } +#if 1 +printf("# target %d ty %d+%d sz %d\n",car(car(target)),ty,cadr(car(target)),sz); +#endif } /* disp を飛び先似合わせて修正 */ @@ -1212,24 +1245,25 @@ for (e2 = target; e2; e2 = cadr(e2)) { t0=car(e2); s0=cadddr(e2); + sz=size(ty=caddr(e2)); if (!is_simple(car(s0))) { - disp-=size(ty=caddr(e2)); + disp-=sz; g_expr(assign_expr0((e4=list2(LVAR,cvar(disp))),s0,ty,ty)); cadddr(e2)=e4; s0=e4; -#if 0 - } else if (is_same_type(t0,s0)) { - if(cadr(t0)==cadr(s0)) { - /* we should check size also (but currently useless */ - remove0(&target,t0); - /* still we have to avoid overwrite */ + } else if (is_same_type(t0,s0)) { + if(cadr(t0)==cadr(s0)) { + /* we should check size also (but currently useless */ + remove0(&target,t0); + /* still we have source to avoid overwrite */ } - } else { -printf("#01 diffrent type t0: car(t0)=%d s0: car(s0)=%d\n",car(t0),car(s0)); + } + if(is_memory(s0)) { + source=list3(s0,source,sz); +#if 1 +printf("# source %d ty %d+%d sz %d\n",car(car(source)),ty,cadr(car(source)),sz); #endif } - source=list2(e4,source); -printf("#01 type %d car(type) %d\n",ty,car(ty)); } /* compute jump address */ @@ -1278,8 +1312,6 @@ printf("\tjmp *%s\n",register_name(e2,0)); emit_pop_free(e2); } - if (vdisp