Mercurial > hg > CbC > old > device
comparison mc-codegen.c @ 296:284aa4eaab0d
case merge for cascade, table.
author | kono |
---|---|
date | Sun, 06 Jun 2004 02:40:32 +0900 |
parents | 2437a94a1538 |
children | 0f79c95df73a |
comparison
equal
deleted
inserted
replaced
295:2437a94a1538 | 296:284aa4eaab0d |
---|---|
1788 // cslist is already sorted | 1788 // cslist is already sorted |
1789 delta = 0; | 1789 delta = 0; |
1790 list = list4(cslist,0,1,list3(0,car(cslist) /* min */,0)); | 1790 list = list4(cslist,0,1,list3(0,car(cslist) /* min */,0)); |
1791 count=1; | 1791 count=1; |
1792 for(p=0;cadr(cslist);cslist = cadr(cslist),count++) { | 1792 for(p=0;cadr(cslist);cslist = cadr(cslist),count++) { |
1793 // compute new delta | |
1793 delta1 = car(cadr(cslist))-car(cslist); | 1794 delta1 = car(cadr(cslist))-car(cslist); |
1795 // empty case | |
1794 if (!caddr(cslist)) count--; | 1796 if (!caddr(cslist)) count--; |
1795 if (delta==0) { | 1797 if (delta==0) { |
1798 // 2nd element | |
1796 caddr(list) = delta = delta1; | 1799 caddr(list) = delta = delta1; |
1797 if (p) cadr(p)=0; // terminate previous chunk | 1800 if (p) cadr(p)=0; // terminate previous chunk |
1798 } else if (delta1!=delta) { | 1801 } else if (delta1!=delta) { |
1799 // not contiguous, start new list | 1802 // not contiguous, start new list |
1800 caddr(cadddr(list)) = car(cslist); // max | 1803 caddr(cadddr(list)) = car(cslist); // max |
1801 car(cadddr(list)) = count; count=0; | 1804 car(cadddr(list)) = count; count=0; |
1802 delta = 0; | 1805 delta = 0; |
1803 list = list4(cadr(cslist),list,1,list3(0,0,0)); | 1806 list = list4(cadr(cslist),list,1,list3(0,0,0)); |
1804 cadr(cadddr(list)) = car(cadr(cslist)); // min | 1807 cadr(cadddr(list)) = car(cadr(cslist)); // min |
1808 // prepare terminate point for next turn | |
1805 p=cslist; | 1809 p=cslist; |
1806 } | 1810 } |
1807 } | 1811 } |
1808 if (p) cadr(p)=0; // terminate previous chunk | 1812 if (p) cadr(p)=0; // terminate previous chunk |
1809 car(cadddr(list)) = count; | 1813 car(cadddr(list)) = count; |
1810 caddr(cadddr(list)) = car(cslist); // max | 1814 caddr(cadddr(list)) = car(cslist); // max |
1811 return list; | 1815 return list; |
1812 } | 1816 } |
1813 | 1817 |
1814 #define CASE_MERGE_RATE 80 | 1818 #define CASE_MERGE_RATE 70 |
1815 /* | |
1816 rate = (sum count(c_i))/(max-min) | |
1817 list3(count,min,max) | |
1818 */ | |
1819 | 1819 |
1820 static int gcd(int i,int j) | 1820 static int gcd(int i,int j) |
1821 { | 1821 { |
1822 int k; | 1822 int k; |
1823 if (i<j) { k=i; i=j; j=k;} | 1823 if (i<j) { k=i; i=j; j=k;} |
1834 int | 1834 int |
1835 merge_chunk_p(int *delta,int max,int min,int *count,int delta1,int count1) | 1835 merge_chunk_p(int *delta,int max,int min,int *count,int delta1,int count1) |
1836 { | 1836 { |
1837 int range = max-min; | 1837 int range = max-min; |
1838 int g; | 1838 int g; |
1839 // compute possible merge delta | |
1839 g = gcd(*delta,delta1); | 1840 g = gcd(*delta,delta1); |
1840 g = gcd(g,range); | 1841 g = gcd(g,range); |
1841 range /= g; | 1842 range /= g; |
1842 *count = count1 = count1+*count; | 1843 *count = count1 = count1+*count; |
1843 *delta = g; | 1844 *delta = g; |
1844 #if 1 | 1845 #if 1 |
1845 printf("# min %d, max %d, count %d, delta %d, rate %g t=%d\n", | 1846 if (count1*128>(range*128*CASE_MERGE_RATE/100)) { |
1846 min,max,count1,g, | 1847 printf("# min %d, max %d, count %d, delta %d, rate %g t=%d\n", |
1847 ((double)count1)*100.0/range, | 1848 min,max,count1,g, |
1848 count1*128>(range*128*CASE_MERGE_RATE/100) | 1849 ((double)count1)*100.0/range, |
1849 ); | 1850 count1*128>(range*128*CASE_MERGE_RATE/100) |
1850 #endif | 1851 ); |
1852 } | |
1853 #endif | |
1854 // count/((max-min)/delta) > 0.8 | |
1851 return count1*128>(range*128*CASE_MERGE_RATE/100); | 1855 return count1*128>(range*128*CASE_MERGE_RATE/100); |
1852 } | 1856 } |
1853 | 1857 |
1854 /* | 1858 /* |
1855 merge possible chunk | 1859 merge possible chunk |
1856 input: list4(cslist,next,delta,list3(count,min,max)) | 1860 input: list4(cslist,next,delta,list3(count,min,max)) |
1857 output: list3(continuous number of chunk,next,delta); | 1861 output: list3(continuous number of chunk,next,delta,case_count); |
1858 */ | 1862 */ |
1859 | 1863 |
1860 static int | 1864 static int |
1861 merge_chunk(int cslist) | 1865 merge_chunk(int cslist) |
1862 { | 1866 { |
1863 int list = cslist; | 1867 int list = cslist; |
1864 int tail,last,max,min,i; | 1868 int tail,last,max,min,i; |
1865 int count,p,widest,delta=1; | 1869 int count,c_count,p,widest,delta=1; |
1866 int chunks = 0; | 1870 int chunks = 0; |
1867 while(cadr(list)) { | 1871 while(cadr(list)) { |
1868 p = cadddr(list); | 1872 p = cadddr(list); |
1869 count = car(p); max=caddr(p); | 1873 c_count = count = car(p); max=caddr(p); |
1870 widest = 1; last = list; | 1874 widest = 1; last = list; |
1871 delta = caddr(list); | 1875 delta = caddr(list); |
1876 // check possible merge against the end of the chunks | |
1872 for(i=1,tail=cadr(list);cadr(tail); tail=cadr(tail),i++) { | 1877 for(i=1,tail=cadr(list);cadr(tail); tail=cadr(tail),i++) { |
1873 p = cadddr(tail); | 1878 p = cadddr(tail); |
1874 min = cadr(p); | 1879 min = cadr(p); |
1875 if (merge_chunk_p(&delta,max,min,&count,caddr(tail),car(p))) { | 1880 if (merge_chunk_p(&delta,max,min,&count,caddr(tail),car(p))) { |
1876 widest = i+1; last = tail; | 1881 // It is mergeable. |
1882 widest = i+1; last = tail; c_count=count; | |
1877 } | 1883 } |
1878 } | 1884 } |
1879 chunks = list3(widest,chunks,delta); | 1885 chunks = list4(widest,chunks,delta,c_count); |
1886 // skip merged chunks | |
1880 list = cadr(last); | 1887 list = cadr(last); |
1881 } | 1888 } |
1882 if (list) chunks = list3(1,chunks,delta); | 1889 // last one can remain. |
1883 return reverse0(chunks); | 1890 if (list) chunks = list4(1,chunks,caddr(list),car(cadddr(list))); |
1884 } | 1891 return chunks; |
1885 | 1892 } |
1886 static void | 1893 |
1887 table_jump(int cslist) | 1894 static int |
1888 { | 1895 table_jump(int count,int delta,int cslist) |
1889 for(;cslist; cslist=cadr(cslist)) { | 1896 { |
1890 if (caddr(cslist)) | 1897 int list; |
1891 cmpdimm(car(cslist),csvalue1,caddr(cslist),0); | 1898 for(;count-->0;cslist=cadr(cslist)) { |
1892 } | 1899 list = car(cslist); |
1893 } | 1900 printf("# table cases delta=%d count=%d min=%d max=%d\n", |
1894 | 1901 caddr(cslist),car(cadddr(cslist)), |
1895 static void | 1902 cadr(cadddr(cslist)),caddr(cadddr(cslist)) |
1896 cascade_compare(int cslist) | 1903 ); |
1897 { | 1904 for(;list; list=cadr(list)) { |
1898 for(;cslist; cslist=cadr(cslist)) { | 1905 if (caddr(list)) |
1899 if (caddr(cslist)) | 1906 cmpdimm(car(list),csvalue1,caddr(list),0); |
1900 cmpdimm(car(cslist),csvalue1,caddr(cslist),0); | 1907 } |
1901 } | 1908 } |
1909 return cslist; | |
1910 } | |
1911 | |
1912 static int | |
1913 cascade_compare(int count,int cslist) | |
1914 { | |
1915 int list; | |
1916 for(;count-->0;cslist=cadr(cslist)) { | |
1917 list = car(cslist); | |
1918 printf("# cascade cases delta=%d count=%d min=%d max=%d\n", | |
1919 caddr(cslist),car(cadddr(cslist)), | |
1920 cadr(cadddr(cslist)),caddr(cadddr(cslist)) | |
1921 ); | |
1922 for(;list; list=cadr(list)) { | |
1923 if (caddr(list)) | |
1924 cmpdimm(car(list),csvalue1,caddr(list),0); | |
1925 } | |
1926 } | |
1927 return cslist; | |
1902 } | 1928 } |
1903 | 1929 |
1904 #define CASE_TABLE_COUNT 10 | 1930 #define CASE_TABLE_COUNT 10 |
1905 | 1931 |
1906 void | 1932 void |
1920 chunks++; | 1946 chunks++; |
1921 } | 1947 } |
1922 j = chunks; | 1948 j = chunks; |
1923 #endif | 1949 #endif |
1924 chunks = merge_chunk(cslist); | 1950 chunks = merge_chunk(cslist); |
1925 #if 1 | 1951 #if 0 |
1926 // chunks: list3(widest,next,delta); | 1952 // chunks: list3(widest,next,delta); |
1927 printf("# chunks %d = sum ",j); | 1953 printf("# chunks %d = sum ",j); |
1928 j = 0; | 1954 j = 0; |
1929 for(i=chunks;i;i=cadr(i)) { | 1955 for(i=chunks;i;i=cadr(i)) { |
1930 printf(" %d/%d",car(i),caddr(i)); | 1956 printf(" %d/%d",car(i),caddr(i)); |
1931 j+=car(i); | 1957 j+=car(i); |
1932 } | 1958 } |
1933 printf(" sum = %d\n",j); | 1959 printf(" sum = %d\n",j); |
1934 #endif | 1960 #endif |
1935 fwddef(cslabel); | 1961 fwddef(cslabel); |
1936 for(;cslist;cslist=cadr(cslist)) { | 1962 cslist = reverse0(cslist); |
1937 printf("# case chunk delta=%d count=%d min=%d max=%d\n", | 1963 for(;chunks;chunks=cadr(chunks)) { |
1938 caddr(cslist),car(cadddr(cslist)), | 1964 printf("# chunk count %d delta %d c_count %d\n", |
1939 cadr(cadddr(cslist)),caddr(cadddr(cslist)) | 1965 car(chunks),caddr(chunks),cadddr(chunks)); |
1940 ); | 1966 if (cadddr(chunks)>CASE_TABLE_COUNT) |
1941 if (cadddr(cslist)>CASE_TABLE_COUNT) | 1967 cslist = table_jump(car(chunks),caddr(chunks),cslist); |
1942 table_jump(car(cslist)); | |
1943 else | 1968 else |
1944 cascade_compare(car(cslist)); | 1969 cslist = cascade_compare(car(chunks),cslist); |
1945 } | 1970 } |
1946 if (dlabel) jmp(dlabel); | 1971 if (dlabel) jmp(dlabel); |
1947 } | 1972 } |
1948 | 1973 |
1949 #endif | 1974 #endif |