コード例 #1
0
int
OPTstrengthReductionImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	int i, j = 0, k, se= FALSE;
	InstrPtr p;
	int bk, ik, blk, blkbegin, blkexit, actions = 0;
	InstrPtr *before, *within, *old = mb->stmt;
	Lifespan span;

	(void) cntxt;
	(void) pci;
	(void) stk;		/* to fool compilers */

	before = (InstrPtr *) GDKmalloc((mb->ssize + 1) * sizeof(InstrPtr));
	within = (InstrPtr *) GDKmalloc((mb->ssize + 1) * sizeof(InstrPtr));
	if (before== NULL || within == NULL){
		if(before) GDKfree(before);
		if(within) GDKfree(within);
		return 0;
	}
	bk = 0;
	ik = 0;
	blk = 0;
	blkexit= blkbegin = 0;
	for (i = 0; i < mb->stop; i++)
		before[i] = within[i] = 0;
	before[bk++] = getInstrPtr(mb, 0);

	span =setLifespan(mb);
	if( span == NULL)
		return 0;

	for (i = 1; i < mb->stop - 1; i++) {
		p = getInstrPtr(mb, i);
		if (blockStart(p)) {
			if (blkbegin == 0){
				if( isLoopBarrier(mb,i) ){
					blkbegin = i;
					blkexit = getBlockExit(mb,i);
				}
				OPTDEBUGstrengthReduction
					mnstr_printf(cntxt->fdout, "#check block %d-%d\n", blkbegin, blkexit);
			}
			within[ik++] = p;
			blk++;
			continue;
		}
		if (blockExit(p)) {
			blk--;
			if (blk == 0)
				blkexit= blkbegin = 0;
			/* move the saved instruction into place */
			OPTDEBUGstrengthReduction
				mnstr_printf(cntxt->fdout, "#combine both %d %d\n", bk, ik);
			for (k = 0; k < ik; k++)
				before[bk++] = within[k];
			ik = 0;
			before[bk++] = p;
			continue;
		}
		/*
		 * @-
		 * Strength reduction is only relevant inside a block;
		 */
		if( blkexit == 0) {
			within[ik++] = p;
			continue;
		}
		/*
		 * @-
		 * Flow control statements may not be moved around
		 */
		if ( p->barrier != 0){
			within[ik++] = p;
			continue;
		}
		/*
		 * @-
		 * Limit strength reduction to the type modules and the batcalc, batstr, batcolor
		 * and sql.bind.
		 */
		if(getModuleId(p) && !isNewSource(p) ) {
			within[ik++] = p;
			continue;
		}
		/*
		 * @-
		 * Search the prospective new block and make sure that
		 * none of the arguments is assigned a value.
		 */
		for (j = ik-1; j > 0; j--) {
			InstrPtr q = within[j];
			for (k = 0; k < q->retc; k++)
				if (SRoverwritten(p, getArg(q, k))) {
					se = TRUE;
					OPTDEBUGstrengthReduction
						mnstr_printf(cntxt->fdout, "variable is set in loop %d\n", getArg(p, k));
					goto noreduction;
				}
		}
		/*
		 * @-
		 * Make sure the variables are not declared before the loop and used
		 * after the loop, because then you may not simple move an expression.
		 */
		for (k = 0; k < p->retc; k++)
			if ( getBeginLifespan(span, getArg(p, k))<= blkbegin ||
				 getEndLifespan(span, getArg(p, k))> blkexit) {
				se = TRUE;
				OPTDEBUGstrengthReduction
					mnstr_printf(cntxt->fdout, "variable %d may not be moved %d-%d\n",
					getArg(p, k),getBeginLifespan(span, getArg(p, k)), getEndLifespan(span, getArg(p, k)));
				goto noreduction;
			}

  noreduction:
		OPTDEBUGstrengthReduction{
			mnstr_printf(cntxt->fdout,"move %d to stack %s\n", i, (se ?"within":"before"));
			printInstruction(cntxt->fdout, mb, 0, p, LIST_MAL_ALL);
		}
		if (blkexit && se == FALSE && !hasSideEffects(p, TRUE) && !isUpdateInstruction(p) )
			before[bk++] = p;
		else
			within[ik++] = p;
	}
	actions += ik;
	for (k = 0; k < ik; k++)
		before[bk++] = within[k];
	before[bk++] = getInstrPtr(mb, i);
	GDKfree(mb->stmt);
	mb->stmt = (InstrPtr *) GDKzalloc((mb->ssize) * sizeof(InstrPtr));
	if ( mb->stmt == NULL){
		GDKfree(span);
		GDKfree(before);
		GDKfree(within);
		mb->stmt = old;
		return 0;
	}
	mb->stop = 0;

	OPTDEBUGstrengthReduction
		mnstr_printf(cntxt->fdout,"stop= %d bk=%d\n",mb->stop,bk);

	for (i = 0; i < bk; i++)
	if( before[i])
		pushInstruction(mb, before[i]);
	GDKfree(span);
	GDKfree(before);
	GDKfree(within);
	return actions;
}
コード例 #2
0
/*
 * Keeping variables around beyond their end-of-life-span
 * can be marked with the proper 'keep'.
 */
int
OPTgarbageCollectorImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	int i, j, k, n = 0, limit, vlimit, depth=0, slimit;
	InstrPtr p, q, *old;
	int actions = 0;
	Lifespan span;

	(void) pci;
	(void) cntxt;
	(void) stk;
	if (varGetProp(mb, getArg(mb->stmt[0], 0), inlineProp) != NULL)
		return 0;

	span = setLifespan(mb);
	if ( span == NULL)
		return 0;

	old= mb->stmt;
	limit = mb->stop;
	slimit = mb->ssize;
	vlimit = mb->vtop;
	if ( newMalBlkStmt(mb,mb->ssize) < 0) {
		GDKfree(span);
		return 0;
	}

	p = NULL;
	for (i = 0; i < limit; i++) {
		p = old[i];
		p->gc &=  ~GARBAGECONTROL;

		if ( p->barrier == RETURNsymbol){
			pushInstruction(mb, p);
			continue;
		}
		if (blockStart(p) )
			depth++;
		if ( p->token == ENDsymbol)
			break;
		
		pushInstruction(mb, p);
		n = mb->stop-1;
		for (j = 0; j < p->argc; j++) {
			if (getEndLifespan(span,getArg(p,j)) == i && isaBatType(getArgType(mb, p, j)) ){
				mb->var[getArg(p,j)]->eolife = n;
				p->gc |= GARBAGECONTROL;
			} 
		}
		if (blockExit(p) ){
			/* force garbage collection of all within upper block */
			depth--;
			for (k = 0; k < vlimit; k++) {
				if (getBeginLifespan(span,k) > 0  &&
					getEndLifespan(span,k) == i &&
					isaBatType(getVarType(mb,k)) &&
					varGetProp(mb, k, keepProp) == NULL){
						q= newAssignment(mb);
						getArg(q,0) = k;
						setVarUDFtype(mb,k);
						setVarFixed(mb,k);
						q= pushNil(mb,q, getVarType(mb,k));
						q->gc |= GARBAGECONTROL;
						mb->var[k]->eolife = mb->stop-1;
						actions++;
				}
			}
		}
	}
	assert(p);
	assert( p->token == ENDsymbol);
	pushInstruction(mb, p);
	for (i++; i < limit; i++) 
		pushInstruction(mb, old[i]);
	for (; i < slimit; i++) 
		if (old[i])
			freeInstruction(old[i]);
	getInstrPtr(mb,0)->gc |= GARBAGECONTROL;
	GDKfree(old);
	OPTDEBUGgarbageCollector{ 
		int k;
		mnstr_printf(cntxt->fdout, "#Garbage collected BAT variables \n");
		for ( k =0; k < vlimit; k++)
		mnstr_printf(cntxt->fdout,"%10s eolife %3d  begin %3d lastupd %3d end %3d\n",
			getVarName(mb,k), mb->var[k]->eolife,
			getBeginLifespan(span,k), getLastUpdate(span,k), getEndLifespan(span,k));
		mnstr_printf(cntxt->fdout, "End of GCoptimizer\n");
	}
	GDKfree(span);

	return actions+1;
}