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 */