changeset 296:284aa4eaab0d

case merge for cascade, table.
author kono
date Sun, 06 Jun 2004 02:40:32 +0900
parents 2437a94a1538
children 0f79c95df73a
files Changes mc-codegen.c
diffstat 2 files changed, 65 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Sun Jun 06 01:46:58 2004 +0900
+++ b/Changes	Sun Jun 06 02:40:32 2004 +0900
@@ -4699,3 +4699,7 @@
 
 なんてのもあるし。
 
+merge が大きい方からやってくようにしちゃったけど、少し、
+結果が良くないみたい。人間は、case 1: case 2: ... というように
+書くからね。そんなに難しくないはずだが、直すのが面倒。
+
--- a/mc-codegen.c	Sun Jun 06 01:46:58 2004 +0900
+++ b/mc-codegen.c	Sun Jun 06 02:40:32 2004 +0900
@@ -1790,9 +1790,12 @@
     list = list4(cslist,0,1,list3(0,car(cslist) /* min */,0)); 
     count=1;
     for(p=0;cadr(cslist);cslist = cadr(cslist),count++) {
+        // compute new delta
 	delta1 = car(cadr(cslist))-car(cslist);
+        // empty case
 	if (!caddr(cslist)) count--;
 	if (delta==0) {
+            // 2nd element
 	    caddr(list) = delta = delta1;
 	    if (p) cadr(p)=0;  // terminate previous chunk
 	} else if (delta1!=delta) {
@@ -1802,6 +1805,7 @@
             delta = 0;
 	    list = list4(cadr(cslist),list,1,list3(0,0,0));
 	    cadr(cadddr(list)) = car(cadr(cslist)); // min
+            // prepare terminate point for next turn
 	    p=cslist;
 	}
     }
@@ -1811,11 +1815,7 @@
     return list;
 }
 
-#define CASE_MERGE_RATE 80
-/*
-    rate = (sum count(c_i))/(max-min)
-      list3(count,min,max)
- */
+#define CASE_MERGE_RATE 70
 
 static int gcd(int i,int j)
 {
@@ -1836,25 +1836,29 @@
 {
     int range = max-min;
     int g;
+    // compute possible merge delta
     g = gcd(*delta,delta1);
     g = gcd(g,range);
     range /= g;
     *count = count1 = count1+*count;
     *delta = g;
 #if 1
-    printf("# min %d, max %d, count %d, delta %d, rate %g t=%d\n",
-	min,max,count1,g,
-	     ((double)count1)*100.0/range,
-           count1*128>(range*128*CASE_MERGE_RATE/100)
-    );
+    if (count1*128>(range*128*CASE_MERGE_RATE/100)) {
+	printf("# min %d, max %d, count %d, delta %d, rate %g t=%d\n",
+	    min,max,count1,g,
+		 ((double)count1)*100.0/range,
+	       count1*128>(range*128*CASE_MERGE_RATE/100)
+	);
+    }
 #endif
+    //    count/((max-min)/delta) > 0.8
     return count1*128>(range*128*CASE_MERGE_RATE/100);
 }
 
 /*
      merge possible chunk
       input:  list4(cslist,next,delta,list3(count,min,max))
-      output: list3(continuous number of chunk,next,delta);
+      output: list3(continuous number of chunk,next,delta,case_count);
  */
 
 static int
@@ -1862,43 +1866,65 @@
 {
     int list = cslist;
     int tail,last,max,min,i;
-    int count,p,widest,delta=1;
+    int count,c_count,p,widest,delta=1;
     int chunks = 0;
     while(cadr(list)) {
 	p = cadddr(list);
-	count = car(p); max=caddr(p);
+	c_count = count = car(p); max=caddr(p);
 	widest = 1; last = list;
 	delta = caddr(list);
+        // check possible merge against the end of the chunks
 	for(i=1,tail=cadr(list);cadr(tail); tail=cadr(tail),i++) {
 	    p = cadddr(tail);
 	    min = cadr(p);
 	    if (merge_chunk_p(&delta,max,min,&count,caddr(tail),car(p))) {
-		widest = i+1; last = tail;
+                // It is mergeable.
+		widest = i+1; last = tail; c_count=count;
 	    }
 	}
-	chunks = list3(widest,chunks,delta);
+	chunks = list4(widest,chunks,delta,c_count);
+        // skip merged chunks
 	list = cadr(last);
     }
-    if (list) chunks = list3(1,chunks,delta);
-    return reverse0(chunks);
+    // last one can remain.
+    if (list) chunks = list4(1,chunks,caddr(list),car(cadddr(list)));
+    return chunks;
 }
 
-static void
-table_jump(int cslist)
+static int
+table_jump(int count,int delta,int cslist)
 {
-    for(;cslist; cslist=cadr(cslist)) {
-	if (caddr(cslist))
-	    cmpdimm(car(cslist),csvalue1,caddr(cslist),0);
+    int list;
+    for(;count-->0;cslist=cadr(cslist)) {
+	list = car(cslist);
+	printf("# table cases delta=%d count=%d min=%d max=%d\n",
+		caddr(cslist),car(cadddr(cslist)),
+				cadr(cadddr(cslist)),caddr(cadddr(cslist))
+		);
+	for(;list; list=cadr(list)) {
+	    if (caddr(list))
+		cmpdimm(car(list),csvalue1,caddr(list),0);
+	}
     }
+    return cslist;
 }
 
-static void
-cascade_compare(int cslist)
+static int
+cascade_compare(int count,int cslist)
 {
-    for(;cslist; cslist=cadr(cslist)) {
-	if (caddr(cslist))
-	    cmpdimm(car(cslist),csvalue1,caddr(cslist),0);
+    int list;
+    for(;count-->0;cslist=cadr(cslist)) {
+	list = car(cslist);
+	printf("# cascade cases delta=%d count=%d min=%d max=%d\n",
+		caddr(cslist),car(cadddr(cslist)),
+				cadr(cadddr(cslist)),caddr(cadddr(cslist))
+		);
+	for(;list; list=cadr(list)) {
+	    if (caddr(list))
+		cmpdimm(car(list),csvalue1,caddr(list),0);
+	}
     }
+    return cslist;
 }
 
 #define CASE_TABLE_COUNT 10
@@ -1922,7 +1948,7 @@
     j = chunks;
 #endif
     chunks = merge_chunk(cslist);
-#if 1
+#if 0
     //  chunks: list3(widest,next,delta);
     printf("# chunks %d = sum ",j);
     j = 0;
@@ -1933,15 +1959,14 @@
     printf(" sum = %d\n",j);
 #endif
     fwddef(cslabel);
-    for(;cslist;cslist=cadr(cslist)) {
-	printf("# case chunk delta=%d count=%d min=%d max=%d\n",
-		caddr(cslist),car(cadddr(cslist)),
-				cadr(cadddr(cslist)),caddr(cadddr(cslist))
-		);
-	if (cadddr(cslist)>CASE_TABLE_COUNT)
-	    table_jump(car(cslist));
+    cslist = reverse0(cslist);
+    for(;chunks;chunks=cadr(chunks)) {
+	printf("# chunk count %d delta %d c_count %d\n",
+		car(chunks),caddr(chunks),cadddr(chunks));
+	if (cadddr(chunks)>CASE_TABLE_COUNT)
+	    cslist = table_jump(car(chunks),caddr(chunks),cslist);
 	else
-	    cascade_compare(car(cslist));
+	    cslist = cascade_compare(car(chunks),cslist);
     }
     if (dlabel) jmp(dlabel);
 }