--- a/Array.st Tue Jan 21 11:20:33 1997 +0100
+++ b/Array.st Tue Jan 21 13:54:25 1997 +0100
@@ -560,12 +560,78 @@
if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE))
#endif
{
+
+# if defined(UNROLL_LOOPS2)
+ {
+ int i8;
+
+ while ((i8 = index+8) < nIndex) {
+ if (InterruptPending != nil) goto interrupt0;
+ continue0:
+ (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index]);
+ if (InterruptPending != nil) goto interrupt1;
+ continue1:
+ (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index+1]);
+ if (InterruptPending != nil) goto interrupt2;
+ continue2:
+ (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index+2]);
+ if (InterruptPending != nil) goto interrupt3;
+ continue3:
+ (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index+3]);
+ if (InterruptPending != nil) goto interrupt4;
+ continue4:
+ (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index+4]);
+ if (InterruptPending != nil) goto interrupt5;
+ continue5:
+ (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index+5]);
+ if (InterruptPending != nil) goto interrupt6;
+ continue6:
+ (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index+6]);
+ if (InterruptPending != nil) goto interrupt7;
+ continue7:
+ (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index+7]);
+ index = i8;
+ }
+ }
+# endif /* UNROLL_LOOPS2 */
+
for (; index < nIndex; index++) {
+# ifdef i386
if (InterruptPending != nil) __interruptL(@line);
+ (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index]);
+# else
+ OBJ el;
- (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index]);
+ el = __InstPtr(self)->i_instvars[index]; */
+ if (InterruptPending == nil) {
+ (*codeVal)(BLOCK_ARG, el);
+ } else {
+ __interruptL(@line);
+ (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index]);
+ }
+# endif
}
RETURN (self);
+
+# if defined(UNROLL_LOOPS2)
+ interrupt0:
+ __interruptL(@line); goto continue0;
+ interrupt1:
+ __interruptL(@line); goto continue1;
+ interrupt2:
+ __interruptL(@line); goto continue2;
+ interrupt3:
+ __interruptL(@line); goto continue3;
+ interrupt4:
+ __interruptL(@line); goto continue4;
+ interrupt5:
+ __interruptL(@line); goto continue5;
+ interrupt6:
+ __interruptL(@line); goto continue6;
+ interrupt7:
+ __interruptL(@line); goto continue7;
+
+# endif /* UNROLL_LOOPS2 */
}
}
}
@@ -642,7 +708,6 @@
up to (and including) stop in the collection.
- reimplemented for speed"
- |home|
%{
REGISTER OBJFUNC codeVal;
REGISTER int index;
@@ -690,12 +755,92 @@
if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE))
#endif
{
- for (index=indexLow; index <= indexHigh; index++) {
+ index = indexLow;
+
+#if defined(UNROLL_LOOPS2)
+ OBJ el;
+ /*
+ * boy; what an ugly looking piece of code ...
+ * however, this software pipelined thing has no taken conditional
+ * branches in the normal case and is almost twice as fast to even
+ * what an unrolling optimizing compiler produces from the loop below ...
+ */
+ {
+ int i8;
+
+ while ((i8 = index+8) <= indexHigh) {
+ el = __InstPtr(self)->i_instvars[index];
+ if (InterruptPending != nil) goto interrupt0;
+ continue0:
+ (*codeVal)(BLOCK_ARG, el);
+ el = __InstPtr(self)->i_instvars[index+1];
+ if (InterruptPending != nil) goto interrupt1;
+ continue1:
+ (*codeVal)(BLOCK_ARG, el);
+ el = __InstPtr(self)->i_instvars[index+2];
+ if (InterruptPending != nil) goto interrupt2;
+ continue2:
+ (*codeVal)(BLOCK_ARG, el);
+ el = __InstPtr(self)->i_instvars[index+3];
+ if (InterruptPending != nil) goto interrupt3;
+ continue3:
+ (*codeVal)(BLOCK_ARG, el);
+ el = __InstPtr(self)->i_instvars[index+4];
+ if (InterruptPending != nil) goto interrupt4;
+ continue4:
+ (*codeVal)(BLOCK_ARG, el);
+ el = __InstPtr(self)->i_instvars[index+5];
+ if (InterruptPending != nil) goto interrupt5;
+ continue5:
+ (*codeVal)(BLOCK_ARG, el);
+ el = __InstPtr(self)->i_instvars[index+6];
+ if (InterruptPending != nil) goto interrupt6;
+ continue6:
+ (*codeVal)(BLOCK_ARG, el);
+ el = __InstPtr(self)->i_instvars[index+7];
+ if (InterruptPending != nil) goto interrupt7;
+ continue7:
+ (*codeVal)(BLOCK_ARG, el);
+ index = i8;
+ }
+ }
+#endif /* UNROLL_LOOP2 */
+ for (; index <= indexHigh; index++) {
+#ifdef i386
if (InterruptPending != nil) __interruptL(@line);
+ (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index]);
+#else
+ OBJ el;
- (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index]);
+ el = __InstPtr(self)->i_instvars[index]; */
+ if (InterruptPending == nil) {
+ (*codeVal)(BLOCK_ARG, el);
+ } else {
+ __interruptL(@line);
+ (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index]);
+ }
+#endif
}
RETURN (self);
+
+#if defined(UNROLL_LOOP2)
+ interrupt0:
+ __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; goto continue0;
+ interrupt1:
+ __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1]; goto continue1;
+ interrupt2:
+ __interruptL(@line); el = __InstPtr(self)->i_instvars[index+2]; goto continue2;
+ interrupt3:
+ __interruptL(@line); el = __InstPtr(self)->i_instvars[index+3]; goto continue3;
+ interrupt4:
+ __interruptL(@line); el = __InstPtr(self)->i_instvars[index+4]; goto continue4;
+ interrupt5:
+ __interruptL(@line); el = __InstPtr(self)->i_instvars[index+5]; goto continue5;
+ interrupt6:
+ __interruptL(@line); el = __InstPtr(self)->i_instvars[index+6]; goto continue6;
+ interrupt7:
+ __interruptL(@line); el = __InstPtr(self)->i_instvars[index+7]; goto continue7;
+#endif /* UNROLL_LOOP2 */
}
}
}
@@ -769,7 +914,6 @@
up to (and including) stop in the collection. Step in reverse order.
- reimplemented for speed"
- |home|
%{
REGISTER OBJFUNC codeVal;
REGISTER int index;
@@ -789,37 +933,6 @@
if (__isBlockLike(aBlock)
&& (__BlockInstPtr(aBlock)->b_nargs == __MKSMALLINT(1))) {
- {
- /*
- * the most common case: a static compiled block, with home on the stack ...
- */
- REGISTER OBJFUNC codeVal;
-
- if ((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
-#ifdef NEW_BLOCK_CALL
-# define BLOCK_ARG aBlock
-#else
-# define BLOCK_ARG rHome
- REGISTER OBJ rHome;
-
- rHome = __BlockInstPtr(aBlock)->b_home;
- if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE))
-#endif
- {
- for (index=indexHigh; index >= indexLow; index--) {
- if (InterruptPending != nil) __interruptL(@line);
-
- (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index]);
- }
- RETURN (self);
- }
- }
- }
-
- /*
- * sorry, must check code-pointer in the loop
- * it could be recompiled or flushed
- */
# undef BLOCK_ARG
#ifdef NEW_BLOCK_CALL
# define BLOCK_ARG aBlock
@@ -885,7 +998,7 @@
Pass both index and element to the block.
- reimplemented for speed"
- |home sz "{ Class: SmallInteger }" |
+ |sz "{ Class: SmallInteger }" |
sz := self size.
%{
@@ -1035,37 +1148,6 @@
if (nIndex <= actualSize) {
if (__isBlockLike(aBlock)
&& (__BlockInstPtr(aBlock)->b_nargs == __MKSMALLINT(1))) {
- {
- /*
- * the most common case: a static compiled block, with home on the stack ...
- */
- REGISTER OBJFUNC codeVal;
-
- if ((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
-#ifdef NEW_BLOCK_CALL
-# define BLOCK_ARG aBlock
-#else
-# define BLOCK_ARG rHome
- REGISTER OBJ rHome;
-
- rHome = __BlockInstPtr(aBlock)->b_home;
- if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE))
-#endif
- {
- for (index=nIndex-1; index >= endIndex; index--) {
- if (InterruptPending != nil) __interruptL(@line);
-
- (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index]);
- }
- RETURN (self);
- }
- }
- }
-
- /*
- * sorry, must check code-pointer in the loop
- * it could be recompiled or flushed
- */
# undef BLOCK_ARG
#ifdef NEW_BLOCK_CALL
# define BLOCK_ARG aBlock
@@ -1560,40 +1642,63 @@
el = anElement;
op = & (__InstPtr(self)->i_instvars[index]);
- /*
- * dont argue about those gotos below - they speed up that thing by 30%;
- * its better to exit the loops below with a goto,
- * since the generated code will then be:
- * compare
- * branch-on-equal found
- *
- * otherwise, we get:
- * compare
- * branch-on-not-equal skipLabel
- * move-to-return-register true
- * goto return-label
- * skipLabel
- *
- * therefore, WITH the so-much-blamed goto, we only branch
- * when found; without the goto, we branch always.
- * Pipelined CPUs do usually not like taken branches.
- */
-
#if defined(memsrch4)
if (index < nIndex) {
OBJ *p;
- p = memsrch4(op, (int)el, (nIndex - index));
- if (p) {
+ p = memsrch4(op, (int)el, (nIndex - index));
+ if (p) {
index = p - op + 1;
RETURN ( __MKSMALLINT(index) );
- }
+ }
}
#else
+ if (0) {
+ found0:
+ RETURN ( __MKSMALLINT(index - nInsts) );
+# if defined(UNROLL_LOOPS)
+ found1:
+ RETURN ( __MKSMALLINT(index + 1 - nInsts) );
+ found2:
+ RETURN ( __MKSMALLINT(index + 2 - nInsts) );
+ found3:
+ RETURN ( __MKSMALLINT(index + 3 - nInsts) );
+ found4:
+ RETURN ( __MKSMALLINT(index + 4 - nInsts) );
+ found5:
+ RETURN ( __MKSMALLINT(index + 5 - nInsts) );
+ found6:
+ RETURN ( __MKSMALLINT(index + 6 - nInsts) );
+ found7:
+ RETURN ( __MKSMALLINT(index + 7 - nInsts) );
+ found8:
+ RETURN ( __MKSMALLINT(index + 8 - nInsts) );
+# endif /* UNROLL_LOOPS */
+ }
+
# if defined(UNROLL_LOOPS)
{
+ /*
+ * dont argue about those gotos below - they speed up that thing by 30%;
+ * its better to exit the loops below with a goto,
+ * since the generated code will then be:
+ * compare
+ * branch-on-equal found
+ *
+ * otherwise (with return as if-statement), we get:
+ * compare
+ * branch-on-not-equal skipLabel
+ * move-to-return-register true
+ * goto return-label
+ * skipLabel
+ *
+ * therefore, WITH the so-much-blamed goto, we only branch
+ * when found; without the goto, we branch always.
+ * Pipelined CPUs do usually not like taken branches.
+ */
+
unsigned int i8;
-
+
while ((i8 = index + 8) < nIndex) {
if (op[0] == el) goto found1;
if (op[1] == el) goto found2;
@@ -1614,31 +1719,9 @@
#endif
}
RETURN ( __MKSMALLINT(0) );
-
- found0:
- RETURN ( __MKSMALLINT(index - nInsts) );
- found1:
- RETURN ( __MKSMALLINT(index + 1 - nInsts) );
- found2:
- RETURN ( __MKSMALLINT(index + 2 - nInsts) );
- found3:
- RETURN ( __MKSMALLINT(index + 3 - nInsts) );
- found4:
- RETURN ( __MKSMALLINT(index + 4 - nInsts) );
- found5:
- RETURN ( __MKSMALLINT(index + 5 - nInsts) );
- found6:
- RETURN ( __MKSMALLINT(index + 6 - nInsts) );
- found7:
- RETURN ( __MKSMALLINT(index + 7 - nInsts) );
- found8:
- RETURN ( __MKSMALLINT(index + 8 - nInsts) );
-
}
%}.
^ self indexNotInteger
-
-
!
identityIndexOf:anElement startingAt:start endingAt:stop
@@ -1669,16 +1752,39 @@
op = & (__InstPtr(self)->i_instvars[index]);
#if defined(memsrch4)
- if (index < lastIndex) {
- OBJ *p;
+ if (index < lastIndex) {
+ OBJ *p;
+
+ p = memsrch4(op, (int)el, (lastIndex - index));
+ if (p) {
+ index = p - op + 1;
+ RETURN ( __MKSMALLINT(index) );
+ }
+ }
+#else
- p = memsrch4(op, (int)el, (lastIndex - index));
- if (p) {
- index = p - op + 1;
- RETURN ( __MKSMALLINT(index) );
- }
- }
-#else
+ if (0) {
+ found0:
+ RETURN ( __MKSMALLINT(index - nInsts) );
+# if defined(UNROLL_LOOPS)
+ found1:
+ RETURN ( __MKSMALLINT(index + 1 - nInsts) );
+ found2:
+ RETURN ( __MKSMALLINT(index + 2 - nInsts) );
+ found3:
+ RETURN ( __MKSMALLINT(index + 3 - nInsts) );
+ found4:
+ RETURN ( __MKSMALLINT(index + 4 - nInsts) );
+ found5:
+ RETURN ( __MKSMALLINT(index + 5 - nInsts) );
+ found6:
+ RETURN ( __MKSMALLINT(index + 6 - nInsts) );
+ found7:
+ RETURN ( __MKSMALLINT(index + 7 - nInsts) );
+ found8:
+ RETURN ( __MKSMALLINT(index + 8 - nInsts) );
+# endif /* UNROLL_LOOPS */
+ }
# if defined(UNROLL_LOOPS)
{
@@ -1704,26 +1810,6 @@
#endif
}
RETURN ( __MKSMALLINT(0) );
-
- found0:
- RETURN ( __MKSMALLINT(index - nInsts) );
- found1:
- RETURN ( __MKSMALLINT(index + 1 - nInsts) );
- found2:
- RETURN ( __MKSMALLINT(index + 2 - nInsts) );
- found3:
- RETURN ( __MKSMALLINT(index + 3 - nInsts) );
- found4:
- RETURN ( __MKSMALLINT(index + 4 - nInsts) );
- found5:
- RETURN ( __MKSMALLINT(index + 5 - nInsts) );
- found6:
- RETURN ( __MKSMALLINT(index + 6 - nInsts) );
- found7:
- RETURN ( __MKSMALLINT(index + 7 - nInsts) );
- found8:
- RETURN ( __MKSMALLINT(index + 8 - nInsts) );
-
}
%}.
^ self indexNotInteger
@@ -1787,14 +1873,13 @@
}
# ifdef memsrch4
-
if (index < nIndex) {
- OBJ *p;
+ OBJ *p;
- p = memsrch4(&(__InstPtr(self)->i_instvars[index]), (int)o, (nIndex - index));
- if (p) {
- RETURN ( true );
- }
+ p = memsrch4(&(__InstPtr(self)->i_instvars[index]), (int)o, (nIndex - index));
+ if (p) {
+ RETURN ( true );
+ }
}
# else
@@ -2072,5 +2157,5 @@
!Array class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.83 1997-01-20 21:35:59 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.84 1997-01-21 12:53:40 cg Exp $'
! !