changeset 463:50a59dfb4606

inline continue...
author kono
date Sat, 04 Dec 2004 12:21:47 +0900
parents f7c87020e6fe
children d88f08d81bba
files Changes mc-code-arm.c mc-code-mips.c mc-code-powerpc.c mc-codegen.c mc-codegen.h mc-inline.c mc-inline.h mc-parse.c
diffstat 9 files changed, 183 insertions(+), 99 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Fri Dec 03 01:05:17 2004 +0900
+++ b/Changes	Sat Dec 04 12:21:47 2004 +0900
@@ -6999,3 +6999,62 @@
 
 partial evaluator って思ったより量が多いなぁ。
 
+Fri Dec  3 12:47:50 JST 2004
+
+inline の引数を計算して、vartable に割り振る。pexpr で定数な
+ら、そのまま定数に。変数だったら alias を避けないといけない
+ので、new_lvar & copy 。変数でも、const (read only)なら、そ
+のまま使って良い。このあたりは、const って宣言しなくてもコン
+パイラの方で検出できるけどね。このコンパイラはさぼる方針なの
+で。
+
+複雑な式なら変数を確保(new_lvar)して代入する(式をparseに付け
+加える)必要がある。なんだけど、一回しか使われてないなら、そ
+のまま使っても良い。後で使われない可能性も高いので。この「一
+回」の意味は結構複雑。attr で評価されたどうかを覚えておく方
+が良い? ただし、副作用がある場合は、使われてなくても、一回は
+評価する必要がある。f(k,i++) {ret k;} みたいな場合。しかも、
+f の前に評価する必要があるのか。i がその後使われないなら実行
+する必要ないし.... 副作用のあるなしや、evalられない場合を判
+定するのは難しいから、無条件生成でしょうね。でも、すぐにasm
+に食わせる場合とかあるけど。
+
+     vartable     argument (-4)
+        -> ptr    local    (0)
+                  local    (4)
+
+ってな感じ? argment size は、どうやって計算するんだっけ?
+
+あと、return value の返し方だけど... ない場合は簡単だけど、
+ある場合は、
+    if()に使われる場合
+    代入される場合
+    使われない場合
+とあるよね。ST_COMPにすることは簡単なんだけど、余計な
+変数が必要になる。COMMA でいいのか。
+     if() { retrun ...} else { return ... }
+のような場合はどうする? COND に変換する?
+     while() { return hoge; }
+は?
+     ({ while() { ret = hoge }; } ret;)
+かな。全体的に、
+    ({hoge....  ret=hoge.... ; ret;})
+にする? hoge が構造体の場合は....
+
+goto するっていう技もありか。
+         { return exp; ... } =>   {  exp; goto exit; ... exit: }
+にする。こうすれば変数は不要。nest した時にだめか。いや、goto
+しないとだめなのか。pexit_label ってのがあるわけね。
+
+単純な場合を単純にするには? 単一で最後の時だけ特別扱いする?
+
+local 変数も使うものだけ生成した方が良いんだが... それには
+2 pass 必要。rechability は2passでないとだめか。あ、めんどう。
+一旦展開した後、不要なコードを取り除くっていう感じですかね。
+そうでないと switch の不要コードを取り除けない?
+
+pcontrol みたいなので除去できない? pcontain みたいな感じで、
+直前のSTが実行される(かもしれない)コードを含んでいるかどうか
+を判断する。pcontain = pcontrol のorみたいな感じ?
+
+
--- a/mc-code-arm.c	Fri Dec 03 01:05:17 2004 +0900
+++ b/mc-code-arm.c	Sat Dec 04 12:21:47 2004 +0900
@@ -2498,6 +2498,7 @@
     int half_register = 0;
 
     special_lvar = -1;
+#if 0
     ret_type = cadr(cadddr(e1));
     if (ret_type==CHAR) ret_type=INT;  // ???
 
@@ -2510,6 +2511,10 @@
 	    if (car(t)==DOTS) dots = 1;
 	}
     }
+#else
+    ret_type = function_type(cadddr(e1),&dots);
+    if (caddr(cadddr(e1))==0) dots=1;
+#endif
 
     arg_assign = 0;
     e2 = cadr(e1);
--- a/mc-code-mips.c	Fri Dec 03 01:05:17 2004 +0900
+++ b/mc-code-mips.c	Sat Dec 04 12:21:47 2004 +0900
@@ -2068,6 +2068,7 @@
     int stargs;
 
     special_lvar = -1;
+#if 0
     ret_type = cadr(cadddr(e1));
     if (ret_type==CHAR) ret_type=INT;  // ???
 
@@ -2080,6 +2081,10 @@
 	    if (car(t)==DOTS) dots = 1;
 	}
     }
+#else
+    ret_type = function_type(cadddr(e1),&dots);
+    if (caddr(cadddr(e1))==0) dots=1;
+#endif
 
     arg_assign = 0;
     e2 = cadr(e1);
--- a/mc-code-powerpc.c	Fri Dec 03 01:05:17 2004 +0900
+++ b/mc-code-powerpc.c	Sat Dec 04 12:21:47 2004 +0900
@@ -1939,38 +1939,14 @@
     int stargs;
 
     special_lvar = -1;
-#if 0
-    ret_type = cadr(cadddr(e1));
-    if (ret_type==CHAR) ret_type=INT;
-
-    /* check argments type is DOTS? */
-    t = caddr(cadddr(e1));
-    if (t==0 || t==DOTS) dots = 1;
-    else {
-	dots = 0;
-	for(t = caddr(cadddr(e1));t;t = cadr(t)) {
-	    if (car(t)==DOTS) dots = 1;
-	}
-    }
-#else
     ret_type = function_type(cadddr(e1),&dots);
     if (caddr(cadddr(e1))==0) dots=1;
-#endif
 
     arg_assign = 0;
     e2 = cadr(e1);
     if (car(e2) == FNAME) {	
 	fn=(NMTBL *)cadr(e2);
     } else {	
-#if 0
-	jmp = get_register_var(0);
-	if (car(jmp)!=REGISTER) error(-1);
-	reg_arg_list = list2(jmp,reg_arg_list);
-	g_expr(e2);
-	if (!is_int_reg(creg)) error(-1);
-	code_register(creg,cadr(jmp));
-        /* g_expr(assign_expr0(jmp,e2,INT,INT)); functions are lvalue */
-#else
         if (car(e2)==INDIRECT) e2=cadr(e2); // (*func)(i) case
 	jmp = get_register_var(0);
 	if (car(jmp)!=REGISTER) error(-1);
@@ -1979,7 +1955,6 @@
             g_expr_u(assign_expr0(jmp,e2,INT,INT));
         } else
 	    arg_assign = list2(assign_expr0(jmp,e2,INT,INT),arg_assign);
-#endif
     }
     /* first we execute complex argument to avoid interaction with
        input variables */
--- a/mc-codegen.c	Fri Dec 03 01:05:17 2004 +0900
+++ b/mc-codegen.c	Sat Dec 04 12:21:47 2004 +0900
@@ -1180,7 +1180,7 @@
     return 0;
 }
 
-static int
+extern int
 is_memory(int e1)
 {
     switch(car(e1)) {
--- a/mc-codegen.h	Fri Dec 03 01:05:17 2004 +0900
+++ b/mc-codegen.h	Sat Dec 04 12:21:47 2004 +0900
@@ -89,6 +89,7 @@
 extern int g_expr0(int e1);
 extern int g_expr_u(int e1);
 extern int is_const(int e);
+extern int is_memory(int e);
 extern int is_code(NMTBL *fnptr);
 extern int is_function(NMTBL *fnptr);
 extern int is_inline(NMTBL *fnptr);
--- a/mc-inline.c	Fri Dec 03 01:05:17 2004 +0900
+++ b/mc-inline.c	Sat Dec 04 12:21:47 2004 +0900
@@ -7,6 +7,8 @@
 #include "mc-codegen.h"
 #include "mc-switch.h"
 
+static int pvartable;
+static int pdisp;
 
 /*
     Basic code generator from parse tree
@@ -387,18 +389,26 @@
    partial evaluator
  */
 
-static int convlvar;
-
 static int
-pconv_var(int e)
+p_vartable(int e,int adisp,int ldisp)
 {
+    int i,e1,e3;
+    pvartable = getfree(adisp+ldisp);
+    pdisp = pvartable+adisp;
+    for(i=adisp+ldisp;i>=0;i--) {
+	pvartable = 0;
+    }
     return 0;
 }
 
 static int
 p_lvar(int e1)
 {
-    return e1;
+    int sz = is_memory(e1);
+    int d = cadr(e1);
+    int d1;
+    if ((d1=(heap[pdisp+e1]))) return d1;
+    return (heap[pdisp+narg]=new_lvar(sz));
 }
 
 static int
@@ -425,11 +435,6 @@
 
 }
 
-code_lpreinc(int e)
-{
-
-}
-
 static int
 pbinop(int e)
 {
@@ -437,18 +442,6 @@
 }
 
 static int
-pdbinop(int e)
-{
-
-}
-
-static int
-plbinop(int e)
-{
-
-}
-
-static int
 psassign(int e)
 {
 
@@ -523,7 +516,34 @@
 static int
 p_decl(int e)
 {
-
+    // list4(ST_DECL,parse,(int)n,stmode);
+    int stmode=cadddr(e);
+    NMTBL *n=(NMTBL*)caddr(e);
+    int dsp = n->dsp;
+    int v;
+    switch(stmode) {
+    case REGISTER:
+	switch(n->ty) {
+	case ULONGLONG: case LONGLONG:
+	    v = get_lregister_var(n); break;
+	case FLOAT: 
+	    v = get_dregister_var(n,0); break;
+	case DOUBLE: 
+	    v = get_dregister_var(n,1); break;
+	default:
+	    if (scalar(n->ty)) 
+		v = get_dregister_var(n,1);
+	    else
+		error(TYERR);
+	}
+    case EXTRN: case EXTRN1: case STATIC:
+	    return pexpr(cadr(e));
+    default:
+	v = new_lvar(size(n->dsp));
+    }
+    if (heap[pdisp+dsp]) error(-1);
+    heap[pdisp+dsp]=v;
+    return pexpr(cadr(e));
 }
 
 static int
@@ -616,13 +636,13 @@
 
 }
 
-static int
-pexpr0(int e1)
+extern int
+pexpr(int e1)
 {
     int e2,e3;
     NMTBL *n;
 
-    if (inmode) error(-1);
+    // if (inmode) error(-1);
     e2 = cadr(e1);
     switch (car(e1)){
     case GVAR: case RGVAR: case CRGVAR: case CURGVAR: case SRGVAR:
@@ -656,9 +676,9 @@
     case FUNCTION:
 	return pfunction(e1);
     case CODE:
-	return list2(car(e1),pexpr0(e2));
+	return list2(car(e1),pexpr(e2));
     case INLINE:
-	return pexpr(e1);
+	return gen_inline(e1);
     case INDIRECT:
 	return prindirect(e1);
     case RINDIRECT:  case URINDIRECT:  
@@ -672,82 +692,80 @@
 #endif
 	return prindirect(e1);
     case ADDRESS:
-	return paddress(pexpr0(e2));
+	return paddress(pexpr(e2));
     case MINUS:
-	if ((e3 = pexpr0(e2))==e2) return e1;
+	if ((e3 = pexpr(e2))==e2) return e1;
 	if (car(e3)==CONST) return list2(CONST,-cadr(e3));
 	return list2(car(e1),e3);
 #if LONGLONG_CODE
     case LMINUS: 
-	if ((e3 = pexpr0(e2))==e2) return e1;
+	if ((e3 = pexpr(e2))==e2) return e1;
 	if (car(e3)==LCONST) return llist2(LCONST,-lcadr(e3));
 	return list2(car(e1),e3);
 #endif
 #if FLOAT_CODE
     case DMINUS: 
-	if ((e3 = pexpr0(e2))==e2) return e1;
+	if ((e3 = pexpr(e2))==e2) return e1;
 	if (car(e3)==DCONST) return dlist2(DCONST,-dcadr(e3));
 	if (car(e3)==FCONST) return dlist2(FCONST,-dcadr(e3));
 	return list2(car(e1),e3);
     case FMINUS: 
-	if ((e3 = pexpr0(e2))==e2) return e1;
+	if ((e3 = pexpr(e2))==e2) return e1;
 	if (car(e3)==DCONST) return dlist2(DCONST,-dcadr(e3));
 	if (car(e3)==FCONST) return dlist2(FCONST,-dcadr(e3));
 	return list2(car(e1),e3);
 #endif
     case CONV: 
-	return p_conv(caddr(e1),pexpr0(e2));
+	return p_conv(caddr(e1),pexpr(e2));
     case BNOT:   /* ~ */
-	if ((e3 = pexpr0(e2))==e2) return e1;
+	if ((e3 = pexpr(e2))==e2) return e1;
 	if (car(e3)==CONST) return list2(CONST,~cadr(e3));
 	return list2(BNOT,e3);
     case LNOT:   /* !  */
-	if ((e3 = pexpr0(e2))==e2) return e1;
+	if ((e3 = pexpr(e2))==e2) return e1;
 	if (car(e3)==CONST) return list2(CONST,!cadr(e3));
 	return list2(LNOT,e3);
     case PREINC:
     case UPREINC:
-	if ((e3 = pexpr0(e2))==e2) return e1;
+	if ((e3 = pexpr(e2))==e2) return e1;
 	if (car(e3)==CONST) return list2(CONST,cadr(e3)+1);
 	return list2(car(e1),e3);
     case POSTINC:
     case UPOSTINC:
-	if ((e3 = pexpr0(e2))==e2) return e1;
+	if ((e3 = pexpr(e2))==e2) return e1;
 	if (car(e3)==CONST) return e3;
 	return list2(car(e1),e3);
 #if FLOAT_CODE
     case DPREINC:   /* ++d */
-	if ((e3 = pexpr0(e2))==e2) return e1;
-	if (car(e3)==FCONST) return dlist2(FCONST,dcadr(e3)+1.0);
-	if (car(e3)==DCONST) return dlist2(DCONST,dcadr(e3)+1.0);
+	if ((e3 = pexpr(e2))==e2) return e1;
+	if (car(e3)==FCONST) return dlist2(FCONST,dcadr(e3)+cadr(e2));
+	if (car(e3)==DCONST) return dlist2(DCONST,dcadr(e3)+cadr(e2));
 	return list2(car(e1),e3);
     case DPOSTINC:  /* d++ */
-	if ((e3 = pexpr0(e2))==e2) return e1;
+	if ((e3 = pexpr(e2))==e2) return e1;
 	if (car(e3)==FCONST||car(e3)==DCONST) return e3;
 	return list2(car(e1),e3);
     case FPREINC:   /* ++f */
-	if ((e3 = pexpr0(e2))==e2) return e1;
-	if (car(e3)==FCONST) return dlist2(FCONST,dcadr(e3)+1.0);
-	if (car(e3)==DCONST) return dlist2(DCONST,dcadr(e3)+1.0);
+	if ((e3 = pexpr(e2))==e2) return e1;
+	if (car(e3)==FCONST) return dlist2(FCONST,dcadr(e3)+cadr(e2));
+	if (car(e3)==DCONST) return dlist2(DCONST,dcadr(e3)+cadr(e2));
 	return list2(car(e1),e3);
     case FPOSTINC:  /* f++ */
-	if ((e3 = pexpr0(e2))==e2) return e1;
+	if ((e3 = pexpr(e2))==e2) return e1;
 	if (car(e3)==FCONST||car(e3)==DCONST) return e3;
 	return list2(car(e1),e3);
 #endif
 #if LONGLONG_CODE
     case LPREINC:   /* ++d */
     case LUPREINC:   /* ++d */
-	if ((e3 = pexpr0(e2))==e2) return e1;
-	if (car(e3)==LCONST) return llist2(LCONST,lcadr(e3)+1);
+	if ((e3 = pexpr(e2))==e2) return e1;
+	if (car(e3)==LCONST) return llist2(LCONST,lcadr(e3)+cadr(e2));
 	return list2(car(e1),e3);
     case LPOSTINC:  /* d++ */
     case LUPOSTINC:  /* d++ */
-	if ((e3 = pexpr0(e2))==e2) return e1;
+	if ((e3 = pexpr(e2))==e2) return e1;
 	if (car(e3)==LCONST) return e3;
 	return list2(car(e1),e3);
-	code_lpreinc(e1,e2,USE_CREG);
-	return ULONGLONG;
 #endif
     case MUL: case UMUL:
     case DIV: case UDIV:	   
@@ -755,17 +773,13 @@
     case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT:
     case ADD: case SUB: case BAND: case EOR: case BOR: case CMP: case CMPGE:
     case UCMP: case CMPEQ: case CMPNEQ: case UCMPGE:
-	pbinop(car(e1),pexpr0(cadr(e1)),pexpr0(caddr(e1)));
-	return INT;
 #if FLOAT_CODE
     case DMUL: case DDIV:
     case DADD: case DSUB:
     case DCMP: case DCMPGE: case DCMPEQ: case DCMPNEQ:
-	return pdbinop(car(e1),pexpr0(cadr(e1)),pexpr0(caddr(e1)),1);
     case FMUL: case FDIV:
     case FADD: case FSUB:
     case FCMP: case FCMPGE: case FCMPEQ: case FCMPNEQ:
-	return pdbinop(car(e1),pexpr0(cadr(e1)),pexpr0(caddr(e1)),0);
 #endif
 #if LONGLONG_CODE
     case LMUL: case LUMUL:
@@ -773,12 +787,14 @@
     case LMOD: case LUMOD:
     case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT:
     case LADD: case LSUB: case LBAND: case LEOR: case LBOR: case LCMP:
-	return plbinop(car(e1),pexpr0(cadr(e1)),pexpr0(caddr(e1)));
 #endif
+	e3 = pexpr(e2); e2 = pexpr(caddr(e1));
+	if (e3==cadr(e1)&&e2==caddr(e1)) return e1;
+	return pbinop(car(e1),e3,e2);
     case LCOND: case DCOND: case FCOND: case COND:
-	e3 = pexpr0(e2);
-	if (car(e3)==CONST) return pexpr0(cadr(e3)?caddr(e1):cadddr(e1));
-	return list4(car(e1),e3,pexpr0(cadr(e1)),pexpr0(cadr(e2)));
+	e3 = pexpr(e2);
+	if (car(e3)==CONST) return pexpr(cadr(e3)?caddr(e1):cadddr(e1));
+	return list4(car(e1),e3,pexpr(cadr(e1)),pexpr(cadr(e2)));
     case STASS: 
 	return psassign(e1);
     case ASS: case CASS: case SASS:
@@ -799,11 +815,11 @@
 	return plassop(e1);
 #endif
     case ALLOCA:
-	return palloc(pexpr0(e2));
+	return palloc(pexpr(e2));
     case BUILTINP:
-	return list2(CONST,is_const(pexpr0(e2)));
+	return list2(CONST,is_const(pexpr(e2)));
     case COMMA:
-	return pcomma(pexpr0(e2),pexpr0(caddr(e1)));
+	return pcomma(pexpr(e2),pexpr(caddr(e1)));
     case RETURN:
     case ENVIRONMENT:
     case LCALL:
@@ -821,8 +837,8 @@
 #if ASM_CODE
     case ASM:
 	return list3(ASM,list4(
-	    pexpr0(car(e2)),pexpr0(cadr(e2)),pexpr0(caddr(e2)),pexpr0(cadddr(e2))),
-		pexpr0(caddr(e1)));
+	    pexpr(car(e2)),pexpr(cadr(e2)),pexpr(caddr(e2)),pexpr(cadddr(e2))),
+		pexpr(caddr(e1)));
 #endif
     case ST_DECL:         return p_decl(e1);
     case ST_IF:           return p_if(e1);
@@ -846,14 +862,35 @@
   return VOID;
 }
 
-int
-pexpr(int e)
+#define round4(i)   ((i+(SIZE_OF_INT-1))&~(SIZE_OF_INT-1))
+
+extern int
+gen_inline(int e)
 {
-    int sconvlvar = convlvar;
-    // compute new disp, and local variable table
-    convlvar = pconv_var(e);
-    e = pexpr0(e1);
+    int svartable = pvartable;
+    int sdisp = pdisp;
+    int narg,arg;
+    NMTBL *n = (NMTBL*)cadr(cadr(e));
+    int e1 = attr_value(n,INLINE);
+    int parse = car(e1);
+    int arg_disp = cadr(e1);
+
+    pvartable = p_vartable(e,pdisp=arg_disp,caddr(e1));
+    /* inline function arguments */
+    narg = 0;
+    for (e3 = e1 = reverse0(caddr(e)); e3; e3 = cadr(e3)) {
+        t=caddr(e3);
+	if (is_const(e3)||(is_memory(e3)&&is_readonly(e3))) {
+	    heap[pdisp+narg]=e3;
+	} else {
+	    arg = heap[pdisp+narg]=new_lvar(size(t));
+	    g_expr_u(assign_expr0(arg,e3,t,t));
+	}
+	narg += (size(t)+3)/4;
+    }
+    e = pexpr(parse);
     convlvar = sconvlvar;
+    pdisp = sdisp;
     return e;
 }
 
--- a/mc-inline.h	Fri Dec 03 01:05:17 2004 +0900
+++ b/mc-inline.h	Sat Dec 04 12:21:47 2004 +0900
@@ -2,6 +2,7 @@
 /* $Id$ */
 
 extern int pexpr(int e);
+extern int gen_inline(int e);
 
 extern void st_decl(int e1);
 extern void st_if(int e1);
--- a/mc-parse.c	Fri Dec 03 01:05:17 2004 +0900
+++ b/mc-parse.c	Sat Dec 04 12:21:47 2004 +0900
@@ -1686,7 +1686,7 @@
 fdecl(NMTBL *n)
 {
     int sd = stypedecl;
-    int arglist;
+    int arglist,arg_disp;
     if (!inmode) {
 	if(!chk) gen_enter(n->nm);
 	extrn_use(n);
@@ -1720,6 +1720,7 @@
 	// arglist is set by adecl() and is reversed.
 	fnptr->dsp = arg_reorder(arglist,fnptr->dsp);
     }
+    arg_disp = args;
     fnptr->dsp=reverse0(fnptr->dsp);
     fdecl_struct(fnptr->ty); /* insert extra argument for struct passing */
     disp=0;
@@ -1741,7 +1742,7 @@
 
     conv->function_end_(); conv->rc_();
     if (inmode) {
-	set_attr(n,INLINE,reverse0(parse)); parse = 0;
+	set_attr(n,INLINE,list3(reverse0(parse),arg_disp,disp)); parse = 0;
 	inline_funcs = list2((int)n,inline_funcs);
     } else {
 	if(!chk) gen_leave(control,n->nm);
@@ -1778,7 +1779,7 @@
     control=1;
     cslabel = -1;
 
-    g_expr_u(pexpr(attr_value(n,INLINE)));
+    g_expr_u(pexpr(car(attr_value(n,INLINE))));
     conv->function_end_(); conv->rc_();
     if(!chk) gen_leave(control,n->nm);
 
@@ -3430,7 +3431,7 @@
 	    if (inmode)
 		return list4(INLINE,e1,arglist,ftype);
 	    else /* partial evaluation */
-		return pexpr(list4(INLINE,e1,arglist,ftype));
+		return gen_inline(list4(INLINE,e1,arglist,ftype));
 	}
     }
     return list4(FUNCTION,e1,arglist,ftype);