Mercurial > hg > CbC > old > device
comparison mc-codegen.c @ 297:0f79c95df73a
switch index no compile error
author | kono |
---|---|
date | Sun, 06 Jun 2004 20:19:36 +0900 |
parents | 284aa4eaab0d |
children | 117baacd1ed0 |
comparison
equal
deleted
inserted
replaced
296:284aa4eaab0d | 297:0f79c95df73a |
---|---|
1768 } | 1768 } |
1769 } | 1769 } |
1770 return 0; | 1770 return 0; |
1771 } | 1771 } |
1772 | 1772 |
1773 #if CASE_CODE | |
1774 | |
1775 /* | |
1776 cslist = list3(value,next,label) label==0 means skip | |
1777 chunk = list4(cslist,next,delta,list3(count,min,max)) | |
1778 */ | |
1779 | |
1780 /* | |
1781 group continous case value | |
1782 */ | |
1783 | |
1784 static int | |
1785 make_chunk(int cslist) | |
1786 { | |
1787 int delta,delta1,list,p,count; | |
1788 // cslist is already sorted | |
1789 delta = 0; | |
1790 list = list4(cslist,0,1,list3(0,car(cslist) /* min */,0)); | |
1791 count=1; | |
1792 for(p=0;cadr(cslist);cslist = cadr(cslist),count++) { | |
1793 // compute new delta | |
1794 delta1 = car(cadr(cslist))-car(cslist); | |
1795 // empty case | |
1796 if (!caddr(cslist)) count--; | |
1797 if (delta==0) { | |
1798 // 2nd element | |
1799 caddr(list) = delta = delta1; | |
1800 if (p) cadr(p)=0; // terminate previous chunk | |
1801 } else if (delta1!=delta) { | |
1802 // not contiguous, start new list | |
1803 caddr(cadddr(list)) = car(cslist); // max | |
1804 car(cadddr(list)) = count; count=0; | |
1805 delta = 0; | |
1806 list = list4(cadr(cslist),list,1,list3(0,0,0)); | |
1807 cadr(cadddr(list)) = car(cadr(cslist)); // min | |
1808 // prepare terminate point for next turn | |
1809 p=cslist; | |
1810 } | |
1811 } | |
1812 if (p) cadr(p)=0; // terminate previous chunk | |
1813 car(cadddr(list)) = count; | |
1814 caddr(cadddr(list)) = car(cslist); // max | |
1815 return list; | |
1816 } | |
1817 | |
1818 #define CASE_MERGE_RATE 70 | |
1819 | |
1820 static int gcd(int i,int j) | |
1821 { | |
1822 int k; | |
1823 if (i<j) { k=i; i=j; j=k;} | |
1824 for(;;) { | |
1825 if ((k=i%j)==0) return j; | |
1826 i = j; j = k; | |
1827 } | |
1828 } | |
1829 | |
1830 /* | |
1831 check two chunks are mergeable or not. | |
1832 */ | |
1833 | |
1834 int | |
1835 merge_chunk_p(int *delta,int max,int min,int *count,int delta1,int count1) | |
1836 { | |
1837 int range = max-min; | |
1838 int g; | |
1839 // compute possible merge delta | |
1840 g = gcd(*delta,delta1); | |
1841 g = gcd(g,range); | |
1842 range /= g; | |
1843 *count = count1 = count1+*count; | |
1844 *delta = g; | |
1845 #if 1 | |
1846 if (count1*128>(range*128*CASE_MERGE_RATE/100)) { | |
1847 printf("# min %d, max %d, count %d, delta %d, rate %g t=%d\n", | |
1848 min,max,count1,g, | |
1849 ((double)count1)*100.0/range, | |
1850 count1*128>(range*128*CASE_MERGE_RATE/100) | |
1851 ); | |
1852 } | |
1853 #endif | |
1854 // count/((max-min)/delta) > 0.8 | |
1855 return count1*128>(range*128*CASE_MERGE_RATE/100); | |
1856 } | |
1857 | |
1858 /* | |
1859 merge possible chunk | |
1860 input: list4(cslist,next,delta,list3(count,min,max)) | |
1861 output: list3(continuous number of chunk,next,delta,case_count); | |
1862 */ | |
1863 | |
1864 static int | |
1865 merge_chunk(int cslist) | |
1866 { | |
1867 int list = cslist; | |
1868 int tail,last,max,min,i; | |
1869 int count,c_count,p,widest,delta=1; | |
1870 int chunks = 0; | |
1871 while(cadr(list)) { | |
1872 p = cadddr(list); | |
1873 c_count = count = car(p); max=caddr(p); | |
1874 widest = 1; last = list; | |
1875 delta = caddr(list); | |
1876 // check possible merge against the end of the chunks | |
1877 for(i=1,tail=cadr(list);cadr(tail); tail=cadr(tail),i++) { | |
1878 p = cadddr(tail); | |
1879 min = cadr(p); | |
1880 if (merge_chunk_p(&delta,max,min,&count,caddr(tail),car(p))) { | |
1881 // It is mergeable. | |
1882 widest = i+1; last = tail; c_count=count; | |
1883 } | |
1884 } | |
1885 chunks = list4(widest,chunks,delta,c_count); | |
1886 // skip merged chunks | |
1887 list = cadr(last); | |
1888 } | |
1889 // last one can remain. | |
1890 if (list) chunks = list4(1,chunks,caddr(list),car(cadddr(list))); | |
1891 return chunks; | |
1892 } | |
1893 | |
1894 static int | |
1895 table_jump(int count,int delta,int cslist) | |
1896 { | |
1897 int list; | |
1898 for(;count-->0;cslist=cadr(cslist)) { | |
1899 list = car(cslist); | |
1900 printf("# table cases delta=%d count=%d min=%d max=%d\n", | |
1901 caddr(cslist),car(cadddr(cslist)), | |
1902 cadr(cadddr(cslist)),caddr(cadddr(cslist)) | |
1903 ); | |
1904 for(;list; list=cadr(list)) { | |
1905 if (caddr(list)) | |
1906 cmpdimm(car(list),csvalue1,caddr(list),0); | |
1907 } | |
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; | |
1928 } | |
1929 | |
1930 #define CASE_TABLE_COUNT 10 | |
1931 | |
1932 void | |
1933 switch_table(int cslist,int cslabel,int dlabel) | |
1934 { | |
1935 int chunks; | |
1936 int i,j; | |
1937 #if 0 | |
1938 for(i=cslist;i;i=cadr(i)) { | |
1939 printf("# case %d L_%d\n",car(i),caddr(i)); | |
1940 } | |
1941 #endif | |
1942 cslist=make_chunk(cslist); | |
1943 #if 1 | |
1944 chunks = 0; | |
1945 for(i=cslist;i;i=cadr(i)) { | |
1946 chunks++; | |
1947 } | |
1948 j = chunks; | |
1949 #endif | |
1950 chunks = merge_chunk(cslist); | |
1951 #if 0 | |
1952 // chunks: list3(widest,next,delta); | |
1953 printf("# chunks %d = sum ",j); | |
1954 j = 0; | |
1955 for(i=chunks;i;i=cadr(i)) { | |
1956 printf(" %d/%d",car(i),caddr(i)); | |
1957 j+=car(i); | |
1958 } | |
1959 printf(" sum = %d\n",j); | |
1960 #endif | |
1961 fwddef(cslabel); | |
1962 cslist = reverse0(cslist); | |
1963 for(;chunks;chunks=cadr(chunks)) { | |
1964 printf("# chunk count %d delta %d c_count %d\n", | |
1965 car(chunks),caddr(chunks),cadddr(chunks)); | |
1966 if (cadddr(chunks)>CASE_TABLE_COUNT) | |
1967 cslist = table_jump(car(chunks),caddr(chunks),cslist); | |
1968 else | |
1969 cslist = cascade_compare(car(chunks),cslist); | |
1970 } | |
1971 if (dlabel) jmp(dlabel); | |
1972 } | |
1973 | |
1974 #endif | |
1975 | |
1976 | |
1977 | |
1978 /* end */ | 1773 /* end */ |