Added call optimization for functions that return array

This commit is contained in:
WPMGPRoSToTeMa 2017-06-25 12:01:22 +03:00
parent 5ad72374cd
commit 44570deb82

View File

@ -729,6 +729,8 @@ static cell array_levelsize(symbol *sym,int level)
* Global references: sc_intest (reffered to only) * Global references: sc_intest (reffered to only)
* sc_allowproccall (modified) * sc_allowproccall (modified)
*/ */
static int g_isLValueArray = FALSE;
static int g_isRValueArrayRetFunc = FALSE;
static int hier14(value *lval1) static int hier14(value *lval1)
{ {
int lvalue; int lvalue;
@ -740,6 +742,7 @@ static int hier14(value *lval1)
int bwcount,leftarray; int bwcount,leftarray;
cell arrayidx1[sDIMEN_MAX],arrayidx2[sDIMEN_MAX]; /* last used array indices */ cell arrayidx1[sDIMEN_MAX],arrayidx2[sDIMEN_MAX]; /* last used array indices */
cell *org_arrayidx; cell *org_arrayidx;
int isRValueArrayRetFunc = FALSE;
bwcount=bitwise_opercount; bwcount=bitwise_opercount;
bitwise_opercount=0; bitwise_opercount=0;
@ -840,7 +843,11 @@ static int hier14(value *lval1)
rvalue(lval1); rvalue(lval1);
} /* if */ } /* if */
lval2.arrayidx=arrayidx2; lval2.arrayidx=arrayidx2;
g_isLValueArray = TRUE;
plnge2(oper,hier14,lval1,&lval2); plnge2(oper,hier14,lval1,&lval2);
isRValueArrayRetFunc = g_isRValueArrayRetFunc;
g_isRValueArrayRetFunc = FALSE;
g_isLValueArray = FALSE;
if (lval2.ident!=iARRAYCELL && lval2.ident!=iARRAYCHAR) if (lval2.ident!=iARRAYCELL && lval2.ident!=iARRAYCHAR)
lval2.arrayidx=NULL; lval2.arrayidx=NULL;
if (oper) if (oper)
@ -967,7 +974,9 @@ static int hier14(value *lval1)
error(6); /* must be assigned to an array */ error(6); /* must be assigned to an array */
} /* if */ } /* if */
if (leftarray) { if (leftarray) {
if (!isRValueArrayRetFunc) {
memcopy(val*sizeof(cell)); memcopy(val*sizeof(cell));
}
} else { } else {
check_userop(NULL,lval2.tag,lval3.tag,2,&lval3,&lval2.tag); check_userop(NULL,lval2.tag,lval3.tag,2,&lval3,&lval2.tag);
store(&lval3); /* now, store the expression result */ store(&lval3); /* now, store the expression result */
@ -1859,7 +1868,9 @@ static int nesting=0;
symbol *symret; symbol *symret;
cell lexval; cell lexval;
char *lexstr; char *lexstr;
int isLValueArray = g_isLValueArray;
g_isLValueArray = FALSE;
assert(sym!=NULL); assert(sym!=NULL);
lval_result->ident=iEXPRESSION; /* preset, may be changed later */ lval_result->ident=iEXPRESSION; /* preset, may be changed later */
lval_result->constval=0; lval_result->constval=0;
@ -1872,11 +1883,15 @@ static int nesting=0;
/* allocate space on the heap for the array, and pass the pointer to the /* allocate space on the heap for the array, and pass the pointer to the
* reserved memory block as a hidden parameter * reserved memory block as a hidden parameter
*/ */
if (isLValueArray) {
g_isRValueArrayRetFunc = TRUE;
} else {
retsize = (int)array_totalsize(symret); retsize = (int)array_totalsize(symret);
assert(retsize > 0); assert(retsize > 0);
modheap(retsize * sizeof(cell));/* address is in ALT */ modheap(retsize * sizeof(cell));/* address is in ALT */
pushreg(sALT); /* pass ALT as the last (hidden) parameter */ pushreg(sALT); /* pass ALT as the last (hidden) parameter */
decl_heap += retsize; decl_heap += retsize;
}
/* also mark the ident of the result as "array" */ /* also mark the ident of the result as "array" */
lval_result->ident=iREFARRAY; lval_result->ident=iREFARRAY;
lval_result->sym=symret; lval_result->sym=symret;
@ -2255,7 +2270,7 @@ static int nesting=0;
if ((sym->usage & uNATIVE)!=0 &&sym->x.lib!=NULL) if ((sym->usage & uNATIVE)!=0 &&sym->x.lib!=NULL)
sym->x.lib->value += 1; /* increment "usage count" of the library */ sym->x.lib->value += 1; /* increment "usage count" of the library */
modheap(-heapalloc*sizeof(cell)); modheap(-heapalloc*sizeof(cell));
if (symret!=NULL) if (symret!=NULL && !isLValueArray)
popreg(sPRI); /* pop hidden parameter as function result */ popreg(sPRI); /* pop hidden parameter as function result */
sideeffect=TRUE; /* assume functions carry out a side-effect */ sideeffect=TRUE; /* assume functions carry out a side-effect */
sc_allowproccall=FALSE; sc_allowproccall=FALSE;
@ -2267,7 +2282,7 @@ static int nesting=0;
long totalsize; long totalsize;
totalsize=declared+decl_heap+1; /* local variables & return value size, totalsize=declared+decl_heap+1; /* local variables & return value size,
* +1 for PROC opcode */ * +1 for PROC opcode */
if (lval_result->ident==iREFARRAY) if (lval_result->ident==iREFARRAY && !isLValueArray)
totalsize++; /* add hidden parameter (on the stack) */ totalsize++; /* add hidden parameter (on the stack) */
if ((sym->usage & uNATIVE)==0) if ((sym->usage & uNATIVE)==0)
totalsize++; /* add "call" opcode */ totalsize++; /* add "call" opcode */