equal
deleted
inserted
replaced
467 */ |
467 */ |
468 spc = __qSpace(nObj); |
468 spc = __qSpace(nObj); |
469 srcP = __arrayVal(self); |
469 srcP = __arrayVal(self); |
470 dstP = __arrayVal(nObj); |
470 dstP = __arrayVal(nObj); |
471 |
471 |
472 #ifdef UNROLL_LOOPS |
472 #ifdef __UNROLL_LOOPS__ |
473 while (nIndex >= 4) { |
473 while (nIndex >= 4) { |
474 OBJ element; |
474 OBJ element; |
475 |
475 |
476 element = srcP[0]; |
476 element = srcP[0]; |
477 dstP[0] = element; |
477 dstP[0] = element; |
580 * what an unrolling optimizing compiler produces from the loop below ... |
580 * what an unrolling optimizing compiler produces from the loop below ... |
581 * notice, that those gotos expand to forward branches (which are predicted |
581 * notice, that those gotos expand to forward branches (which are predicted |
582 * as NOT taken by most machines ... which is exactly what we want) |
582 * as NOT taken by most machines ... which is exactly what we want) |
583 */ |
583 */ |
584 REGISTER OBJ el; |
584 REGISTER OBJ el; |
585 #if defined(UNROLL_LOOPS) |
585 #ifdef __UNROLL_LOOPS__ |
586 |
586 |
587 { |
587 { |
588 int i8; |
588 int i8; |
589 |
589 |
590 while ((i8 = index+8) < nIndex) { |
590 while ((i8 = index+8) < nIndex) { |
621 continue7: |
621 continue7: |
622 (*codeVal)(BLOCK_ARG, el); |
622 (*codeVal)(BLOCK_ARG, el); |
623 index = i8; |
623 index = i8; |
624 } |
624 } |
625 } |
625 } |
626 #endif /* UNROLL_LOOPS */ |
626 #endif /* __UNROLL_LOOPS__ */ |
627 |
627 |
628 for (; index < nIndex; index++) { |
628 for (; index < nIndex; index++) { |
629 el = __InstPtr(self)->i_instvars[index]; |
629 el = __InstPtr(self)->i_instvars[index]; |
630 if (InterruptPending != nil) goto interruptX; |
630 if (InterruptPending != nil) goto interruptX; |
631 continueX: |
631 continueX: |
632 (*codeVal)(BLOCK_ARG, el); |
632 (*codeVal)(BLOCK_ARG, el); |
633 } |
633 } |
634 RETURN (self); |
634 RETURN (self); |
635 |
635 |
636 #if defined(UNROLL_LOOPS) |
636 #ifdef __UNROLL_LOOPS__ |
637 interrupt0: |
637 interrupt0: |
638 __interruptL(@line); |
638 __interruptL(@line); |
639 el = __InstPtr(self)->i_instvars[index]; |
639 el = __InstPtr(self)->i_instvars[index]; |
640 goto continue0; |
640 goto continue0; |
641 interrupt1: |
641 interrupt1: |
664 goto continue6; |
664 goto continue6; |
665 interrupt7: |
665 interrupt7: |
666 __interruptL(@line); |
666 __interruptL(@line); |
667 el = __InstPtr(self)->i_instvars[index+7]; |
667 el = __InstPtr(self)->i_instvars[index+7]; |
668 goto continue7; |
668 goto continue7; |
669 #endif /* UNROLL_LOOPS */ |
669 #endif /* __UNROLL_LOOPS__ */ |
670 interruptX: |
670 interruptX: |
671 __interruptL(@line); |
671 __interruptL(@line); |
672 el = __InstPtr(self)->i_instvars[index]; |
672 el = __InstPtr(self)->i_instvars[index]; |
673 goto continueX; |
673 goto continueX; |
674 } |
674 } |
799 if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE)) |
799 if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE)) |
800 #endif |
800 #endif |
801 { |
801 { |
802 REGISTER OBJ el; |
802 REGISTER OBJ el; |
803 |
803 |
804 #if defined(UNROLL_LOOPS) |
804 #ifdef __UNROLL_LOOPS__ |
805 /* |
805 /* |
806 * boy; what an ugly looking piece of code ... |
806 * boy; what an ugly looking piece of code ... |
807 * however, this software pipelined thing has no taken conditional |
807 * however, this software pipelined thing has no taken conditional |
808 * branches in the normal case and is almost twice as fast to even |
808 * branches in the normal case and is almost twice as fast to even |
809 * what an unrolling optimizing compiler produces from the loop below ... |
809 * what an unrolling optimizing compiler produces from the loop below ... |
845 continue7: |
845 continue7: |
846 (*codeVal)(BLOCK_ARG, el); |
846 (*codeVal)(BLOCK_ARG, el); |
847 n -= 8; |
847 n -= 8; |
848 index += 8; |
848 index += 8; |
849 } |
849 } |
850 # ifdef UNROLL_LOOPS2 /* this makes small loops slower */ |
850 # ifdef __UNROLL_LOOPS2__ /* this makes small loops slower */ |
851 if (n >= 4) { |
851 if (n >= 4) { |
852 el = __InstPtr(self)->i_instvars[index]; |
852 el = __InstPtr(self)->i_instvars[index]; |
853 if (InterruptPending != nil) goto interrupt0b; |
853 if (InterruptPending != nil) goto interrupt0b; |
854 continue0b: |
854 continue0b: |
855 (*codeVal)(BLOCK_ARG, el); |
855 (*codeVal)(BLOCK_ARG, el); |
878 continue1c: |
878 continue1c: |
879 (*codeVal)(BLOCK_ARG, el); |
879 (*codeVal)(BLOCK_ARG, el); |
880 n -= 2; |
880 n -= 2; |
881 index += 2; |
881 index += 2; |
882 } |
882 } |
883 # endif /* UNROLL_LOOPS2 */ |
883 # endif /* __UNROLL_LOOPS2__ */ |
884 } |
884 } |
885 #endif /* UNROLL_LOOPS */ |
885 #endif /* __UNROLL_LOOPS__ */ |
886 while (n > 0) { |
886 while (n > 0) { |
887 el = __InstPtr(self)->i_instvars[index]; |
887 el = __InstPtr(self)->i_instvars[index]; |
888 if (InterruptPending != nil) goto interruptX; |
888 if (InterruptPending != nil) goto interruptX; |
889 continueX: |
889 continueX: |
890 (*codeVal)(BLOCK_ARG, el); |
890 (*codeVal)(BLOCK_ARG, el); |
891 n--; |
891 n--; |
892 index++; |
892 index++; |
893 } |
893 } |
894 RETURN (self); |
894 RETURN (self); |
895 |
895 |
896 #if defined(UNROLL_LOOPS) |
896 #ifdef __UNROLL_LOOPS__ |
897 interrupt0: |
897 interrupt0: |
898 __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; |
898 __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; |
899 goto continue0; |
899 goto continue0; |
900 interrupt1: |
900 interrupt1: |
901 __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1]; |
901 __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1]; |
917 goto continue6; |
917 goto continue6; |
918 interrupt7: |
918 interrupt7: |
919 __interruptL(@line); el = __InstPtr(self)->i_instvars[index+7]; |
919 __interruptL(@line); el = __InstPtr(self)->i_instvars[index+7]; |
920 goto continue7; |
920 goto continue7; |
921 |
921 |
922 # ifdef UNROLL_LOOPS2 |
922 # ifdef __UNROLL_LOOPS2__ |
923 interrupt0b: |
923 interrupt0b: |
924 __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; |
924 __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; |
925 goto continue0b; |
925 goto continue0b; |
926 interrupt1b: |
926 interrupt1b: |
927 __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1]; |
927 __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1]; |
937 __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; |
937 __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; |
938 goto continue0c; |
938 goto continue0c; |
939 interrupt1c: |
939 interrupt1c: |
940 __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1]; |
940 __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1]; |
941 goto continue1c; |
941 goto continue1c; |
942 # endif /* UNROLL_LOOPS2 */ |
942 # endif /* __UNROLL_LOOPS2__ */ |
943 #endif /* UNROLL_LOOPS */ |
943 #endif /* __UNROLL_LOOPS__ */ |
944 interruptX: |
944 interruptX: |
945 __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; |
945 __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; |
946 goto continueX; |
946 goto continueX; |
947 } |
947 } |
948 } |
948 } |
1400 if ((INT)anObject == 0) { |
1400 if ((INT)anObject == 0) { |
1401 memset(dst, 0, __OBJS2BYTES__(endIndex-index+1)); |
1401 memset(dst, 0, __OBJS2BYTES__(endIndex-index+1)); |
1402 } else |
1402 } else |
1403 # endif |
1403 # endif |
1404 { |
1404 { |
1405 # if defined(UNROLL_LOOPS) |
1405 # ifdef __UNROLL_LOOPS__ |
1406 { |
1406 { |
1407 int i8; |
1407 int i8; |
1408 |
1408 |
1409 while ((i8 = index + 8) <= endIndex) { |
1409 while ((i8 = index + 8) <= endIndex) { |
1410 dst[3] = dst[2] = dst[1] = dst[0] = anObject; |
1410 dst[3] = dst[2] = dst[1] = dst[0] = anObject; |
1481 */ |
1481 */ |
1482 if (src < dst) { |
1482 if (src < dst) { |
1483 /* must do a reverse copy */ |
1483 /* must do a reverse copy */ |
1484 src += count; |
1484 src += count; |
1485 dst += count; |
1485 dst += count; |
1486 #if defined(UNROLL_LOOPS) |
1486 #ifdef __UNROLL_LOOPS__ |
1487 while (count > 8) { |
1487 while (count > 8) { |
1488 dst[-1] = src[-1]; |
1488 dst[-1] = src[-1]; |
1489 dst[-2] = src[-2]; |
1489 dst[-2] = src[-2]; |
1490 dst[-3] = src[-3]; |
1490 dst[-3] = src[-3]; |
1491 dst[-4] = src[-4]; |
1491 dst[-4] = src[-4]; |
1530 bcopy4(src, dst, count); |
1530 bcopy4(src, dst, count); |
1531 # else |
1531 # else |
1532 # ifdef FAST_MEMCPY |
1532 # ifdef FAST_MEMCPY |
1533 bcopy(src, dst, __OBJS2BYTES__(count)); |
1533 bcopy(src, dst, __OBJS2BYTES__(count)); |
1534 # else |
1534 # else |
1535 # if defined(UNROLL_LOOPS) |
1535 # ifdef __UNROLL_LOOPS__ |
1536 while (count >= 8) { |
1536 while (count >= 8) { |
1537 dst[0] = src[0]; |
1537 dst[0] = src[0]; |
1538 dst[1] = src[1]; |
1538 dst[1] = src[1]; |
1539 dst[2] = src[2]; |
1539 dst[2] = src[2]; |
1540 dst[3] = src[3]; |
1540 dst[3] = src[3]; |
1554 #endif |
1554 #endif |
1555 } else { |
1555 } else { |
1556 REGISTER int spc; |
1556 REGISTER int spc; |
1557 |
1557 |
1558 spc = __qSpace(self); |
1558 spc = __qSpace(self); |
1559 #if defined(UNROLL_LOOPS) |
1559 #ifdef __UNROLL_LOOPS__ |
1560 while (count >= 8) { |
1560 while (count >= 8) { |
1561 t = src[0]; dst[0] = t; __STORE_SPC(self, t, spc); |
1561 t = src[0]; dst[0] = t; __STORE_SPC(self, t, spc); |
1562 t = src[1]; dst[1] = t; __STORE_SPC(self, t, spc); |
1562 t = src[1]; dst[1] = t; __STORE_SPC(self, t, spc); |
1563 t = src[2]; dst[2] = t; __STORE_SPC(self, t, spc); |
1563 t = src[2]; dst[2] = t; __STORE_SPC(self, t, spc); |
1564 t = src[3]; dst[3] = t; __STORE_SPC(self, t, spc); |
1564 t = src[3]; dst[3] = t; __STORE_SPC(self, t, spc); |
1859 RETURN ( __mkSmallInteger(index) ); |
1859 RETURN ( __mkSmallInteger(index) ); |
1860 } |
1860 } |
1861 } |
1861 } |
1862 #else |
1862 #else |
1863 |
1863 |
1864 # if defined(UNROLL_LOOPS) |
1864 # ifdef __UNROLL_LOOPS__ |
1865 { |
1865 { |
1866 /* |
1866 /* |
1867 * dont argue about those gotos below - they speed up that thing by 30%; |
1867 * dont argue about those gotos below - they speed up that thing by 30%; |
1868 * its better to exit the loops below with a goto, |
1868 * its better to exit the loops below with a goto, |
1869 * since the generated code will then be: |
1869 * since the generated code will then be: |
1913 RETURN ( __mkSmallInteger(index + 7 - nInsts) ); |
1913 RETURN ( __mkSmallInteger(index + 7 - nInsts) ); |
1914 found8: |
1914 found8: |
1915 RETURN ( __mkSmallInteger(index + 8 - nInsts) ); |
1915 RETURN ( __mkSmallInteger(index + 8 - nInsts) ); |
1916 } |
1916 } |
1917 } |
1917 } |
1918 # endif /* UNROLLED_LOOPS */ |
1918 # endif /* __UNROLLED_LOOPS__ */ |
1919 |
1919 |
1920 while (index++ < nIndex) { |
1920 while (index++ < nIndex) { |
1921 if (*op++ == el) goto found0; |
1921 if (*op++ == el) goto found0; |
1922 } |
1922 } |
1923 |
1923 |
1970 RETURN ( __mkSmallInteger(index) ); |
1970 RETURN ( __mkSmallInteger(index) ); |
1971 } |
1971 } |
1972 } |
1972 } |
1973 #else |
1973 #else |
1974 |
1974 |
1975 # if defined(UNROLL_LOOPS) |
1975 # ifdef __UNROLL_LOOPS__ |
1976 { |
1976 { |
1977 unsigned int i8; |
1977 unsigned int i8; |
1978 |
1978 |
1979 while ((i8 = index + 8) < lastIndex) { |
1979 while ((i8 = index + 8) < lastIndex) { |
1980 if (op[0] == el) goto found1; |
1980 if (op[0] == el) goto found1; |
2006 RETURN ( __mkSmallInteger(index + 7 - nInsts) ); |
2006 RETURN ( __mkSmallInteger(index + 7 - nInsts) ); |
2007 found8: |
2007 found8: |
2008 RETURN ( __mkSmallInteger(index + 8 - nInsts) ); |
2008 RETURN ( __mkSmallInteger(index + 8 - nInsts) ); |
2009 } |
2009 } |
2010 } |
2010 } |
2011 # endif /* UNROLL_LOOPS */ |
2011 # endif /* __UNROLL_LOOPS__ */ |
2012 |
2012 |
2013 while (index++ < lastIndex) { |
2013 while (index++ < lastIndex) { |
2014 if (*op++ == el) goto found0; |
2014 if (*op++ == el) goto found0; |
2015 } |
2015 } |
2016 |
2016 |
2121 OBJ slf = self; |
2121 OBJ slf = self; |
2122 |
2122 |
2123 /* |
2123 /* |
2124 * search for nil - do an identity-search |
2124 * search for nil - do an identity-search |
2125 */ |
2125 */ |
2126 #if defined(UNROLL_LOOPS) |
2126 #ifdef __UNROLL_LOOPS__ |
2127 { |
2127 { |
2128 unsigned int i8; |
2128 unsigned int i8; |
2129 |
2129 |
2130 while ((i8 = index + 8) < nIndex) { |
2130 while ((i8 = index + 8) < nIndex) { |
2131 if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); } |
2131 if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); } |
2253 OBJ slf = self; |
2253 OBJ slf = self; |
2254 |
2254 |
2255 /* |
2255 /* |
2256 * search for nil - do an identity-search |
2256 * search for nil - do an identity-search |
2257 */ |
2257 */ |
2258 #if defined(UNROLL_LOOPS) |
2258 #ifdef __UNROLL_LOOPS__ |
2259 { |
2259 { |
2260 unsigned int i8; |
2260 unsigned int i8; |
2261 |
2261 |
2262 while ((i8 = index + 8) < lastIndex) { |
2262 while ((i8 = index + 8) < lastIndex) { |
2263 if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); } |
2263 if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); } |
2348 * when found; without the goto, we branch always. |
2348 * when found; without the goto, we branch always. |
2349 * Pipelined CPUs do usually not like taken branches. |
2349 * Pipelined CPUs do usually not like taken branches. |
2350 * also, all branches are forward, which are usually predicted |
2350 * also, all branches are forward, which are usually predicted |
2351 * as not taken. |
2351 * as not taken. |
2352 */ |
2352 */ |
2353 # if defined(UNROLL_LOOPS) |
2353 # ifdef __UNROLL_LOOPS__ |
2354 { |
2354 { |
2355 unsigned int i8; |
2355 unsigned int i8; |
2356 REGISTER OBJ slf = self; |
2356 REGISTER OBJ slf = self; |
2357 |
2357 |
2358 while ((i8 = index + 8) < nIndex) { |
2358 while ((i8 = index + 8) < nIndex) { |
2365 if (__InstPtr(slf)->i_instvars[index+6] == o) goto found; |
2365 if (__InstPtr(slf)->i_instvars[index+6] == o) goto found; |
2366 if (__InstPtr(slf)->i_instvars[index+7] == o) goto found; |
2366 if (__InstPtr(slf)->i_instvars[index+7] == o) goto found; |
2367 index = i8; |
2367 index = i8; |
2368 } |
2368 } |
2369 } |
2369 } |
2370 # endif /* UNROLL_LOOPS */ |
2370 # endif /* __UNROLL_LOOPS__ */ |
2371 |
2371 |
2372 while (index < nIndex) { |
2372 while (index < nIndex) { |
2373 if (__InstPtr(self)->i_instvars[index++] == o) goto found; |
2373 if (__InstPtr(self)->i_instvars[index++] == o) goto found; |
2374 } |
2374 } |
2375 if (0) { |
2375 if (0) { |
2498 ! ! |
2498 ! ! |
2499 |
2499 |
2500 !Array class methodsFor:'documentation'! |
2500 !Array class methodsFor:'documentation'! |
2501 |
2501 |
2502 version |
2502 version |
2503 ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.138 2005-07-08 17:15:00 cg Exp $' |
2503 ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.139 2005-07-08 21:13:38 cg Exp $' |
2504 ! ! |
2504 ! ! |