/* ************************************************************************* */
VerticalBlockMatrix SymmetricBlockMatrix::choleskyPartial(
    DenseIndex nFrontals) {
  // Do dense elimination
  if (blockStart() != 0)
    throw std::invalid_argument(
        "Can only do Cholesky when the SymmetricBlockMatrix is not a restricted view, i.e. when blockStart == 0.");
  if (!gtsam::choleskyPartial(matrix_, offset(nFrontals)))
    throw CholeskyFailed();

  // Split conditional

  // Create one big conditionals with many frontal variables.
  gttic(Construct_conditional);
  const size_t varDim = offset(nFrontals);
  VerticalBlockMatrix Ab = VerticalBlockMatrix::LikeActiveViewOf(*this, varDim);
  Ab.full() = matrix_.topRows(varDim);
  Ab.full().triangularView<Eigen::StrictlyLower>().setZero();
  gttoc(Construct_conditional);

  gttic(Remaining_factor);
  // Take lower-right block of Ab_ to get the remaining factor
  blockStart() = nFrontals;
  gttoc(Remaining_factor);

  return Ab;
}
Пример #2
0
/* barrier blocks can only be dropped when they are fully excluded.  */
static str
OPTremoveUnusedBlocks(Client cntxt, MalBlkPtr mb)
{
	/* catch and remove constant bounded blocks */
	int i, j = 0, action = 0, block = -1, skip = 0, multipass = 1;
	InstrPtr p;
	str msg = MAL_SUCCEED;

	while(multipass--){
		block = -1;
		skip = 0;
		j = 0;
		for (i = 0; i < mb->stop; i++) {
			p = mb->stmt[i];
			if (blockExit(p) && block == getArg(p,0) ){
					block = -1;
					skip = 0;
					freeInstruction(p);
					mb->stmt[i]= 0;
					continue;
			}
			if (p->argc == 2 && blockStart(p) && block < 0 && isVarConstant(mb, getArg(p, 1)) && getArgType(mb, p, 1) == TYPE_bit ){
				if( getVarConstant(mb, getArg(p, 1)).val.btval == 0)
				{
					block = getArg(p,0);
					skip ++;
					action++;
				}
				// Try to remove the barrier statement itself (when true).
				if ( getVarConstant(mb, getArg(p, 1)).val.btval == 1  && OPTsimpleflow(mb,i))
				{
					block = getArg(p,0);
					skip = 0;
					action++;
					freeInstruction(p);
					mb->stmt[i]= 0;
					continue;
				}
			} else 
			if( p->argc == 2 &&  blockStart(p) && block >= 0 && skip == 0 && isVarConstant(mb, getArg(p, 1)) && getArgType(mb, p, 1) == TYPE_bit && multipass == 0)
				multipass++;
			if (skip){
				freeInstruction(p);
				mb->stmt[i]= 0;
			} else
				mb->stmt[j++] = p;
		}
		mb->stop = j;
		for (; j < i; j++)
			mb->stmt[j] = NULL;
	}
	if (action)
		chkTypes(cntxt->usermodule, mb, TRUE);
	return msg;
}
Пример #3
0
/* barrier blocks can only be dropped when they are fully excluded.  */
static int
OPTremoveUnusedBlocks(Client cntxt, MalBlkPtr mb)
{
	/* catch and remove constant bounded blocks */
	int i, j = 0, action = 0, block = 0, skip = 0, top =0, skiplist[10];
	InstrPtr p;

	for (i = 0; i < mb->stop; i++) {
		p = mb->stmt[i];
		if (blockStart(p)) {
			block++;
			if (p->argc == 2 && isVarConstant(mb, getArg(p, 1)) &&
					getArgType(mb, p, 1) == TYPE_bit &&
					getVarConstant(mb, getArg(p, 1)).val.btval == 0)
			{
				if (skip == 0)
					skip = block;
				action++;
			}
			// Try to remove the barrier statement itself (when true).
			if (p->argc == 2 && isVarConstant(mb, getArg(p, 1)) &&
					getArgType(mb, p, 1) == TYPE_bit &&
					getVarConstant(mb, getArg(p, 1)).val.btval == 1 && 
					top <10 && OPTsimpleflow(mb,i))
			{
				skiplist[top++]= getArg(p,0);
				freeInstruction(p);
				continue;
			}
		}
		if (blockExit(p)) {
			if (top > 0 && skiplist[top-1] == getArg(p,0) ){
				top--;
				freeInstruction(p);
				continue;
			} 
			if (skip )
				freeInstruction(p);
			else
				mb->stmt[j++] = p;
			if (skip == block)
				skip = 0;
			block--;
			if (block == 0)
				skip = 0;
		} else if (skip)
			freeInstruction(p);
		else
			mb->stmt[j++] = p;
	}
	mb->stop = j;
	for (; j < i; j++)
		mb->stmt[j] = NULL;
	if (action) {
		chkTypes(cntxt->fdout, cntxt->nspace, mb, TRUE);
		return mb->errors ? 0 : action;
	}
	return action;
}
Пример #4
0
// http://www.w3.org/TR/css3-syntax/#consume-an-ident-like-token
MediaQueryToken MediaQueryTokenizer::consumeIdentLikeToken()
{
    String name = consumeName();
    if (consumeIfNext('(')) {
        return blockStart(LeftParenthesisToken, FunctionToken, name);
    }
    return MediaQueryToken(IdentToken, name);
}
// http://dev.w3.org/csswg/css-syntax/#consume-ident-like-token
CSSParserToken CSSTokenizer::consumeIdentLikeToken()
{
    CSSParserString name = consumeName();
    if (consumeIfNext('(')) {
        if (name.equalIgnoringASCIICase("url")) {
            // The spec is slightly different so as to avoid dropping whitespace
            // tokens, but they wouldn't be used and this is easier.
            consumeUntilNonWhitespace();
            UChar next = m_input.nextInputChar();
            if (next != '"' && next != '\'')
                return consumeUrlToken();
        }
        return blockStart(LeftParenthesisToken, FunctionToken, name);
    }
    return CSSParserToken(IdentToken, name);
}
Пример #6
0
static int OPTsimpleflow(MalBlkPtr mb, int pc)
{
	int i, block =0, simple= TRUE;
	InstrPtr p;

	for ( i= pc; i< mb->stop; i++){
		p =getInstrPtr(mb,i);
		if (blockStart(p))
			block++;
		if ( blockExit(p))
			block--;
		if ( blockCntrl(p))
			simple= FALSE;
		if ( block == 0){
			return simple;
		}
	}
	return FALSE;
}
CSSParserToken CSSTokenizer::leftBrace(UChar cc)
{
    return blockStart(LeftBraceToken);
}
CSSParserToken CSSTokenizer::leftParenthesis(UChar cc)
{
    return blockStart(LeftParenthesisToken);
}
Пример #9
0
MediaQueryToken MediaQueryTokenizer::leftParenthesis(UChar cc)
{
    return blockStart(LeftParenthesisToken);
}
Пример #10
0
MediaQueryToken MediaQueryTokenizer::leftBrace(UChar cc)
{
    return blockStart(LeftBraceToken);
}
Пример #11
0
int
OPTevaluateImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	InstrPtr p;
	int i, k, limit, *alias, barrier;
	MalStkPtr env = NULL;
	int profiler;
	str msg;
	int debugstate = cntxt->itrace, actions = 0, constantblock = 0;
	int *assigned, setonce; 

	cntxt->itrace = 0;
	(void)stk;
	(void)pci;

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

	(void)cntxt;
	OPTDEBUGevaluate mnstr_printf(cntxt->fdout, "Constant expression optimizer started\n");

	assigned = (int*) GDKzalloc(sizeof(int) * mb->vtop);
	if (assigned == NULL)
		return 0;

	alias = (int*)GDKzalloc(mb->vsize * sizeof(int) * 2); /* we introduce more */
	if (alias == NULL){
		GDKfree(assigned);
		return 0;
	}

	// arguments are implicitly assigned by context
	p = getInstrPtr(mb, 0);
	for ( k =p->retc;  k < p->argc; k++)
		assigned[getArg(p,k)]++;
	limit = mb->stop;
	for (i = 1; i < limit; i++) {
		p = getInstrPtr(mb, i);
		// The double count emerging from a barrier exit is ignored.
		if (! blockExit(p) || (blockExit(p) && p->retc != p->argc))
		for ( k =0;  k < p->retc; k++)
			assigned[getArg(p,k)]++;
	}

	for (i = 1; i < limit; i++) {
		p = getInstrPtr(mb, i);
		for (k = p->retc; k < p->argc; k++)
			if (alias[getArg(p, k)])
				getArg(p, k) = alias[getArg(p, k)];
		// to avoid management of duplicate assignments over multiple blocks
		// we limit ourselfs to evaluation of the first assignment only.
		setonce = assigned[getArg(p,0)] == 1;
		OPTDEBUGevaluate printInstruction(cntxt->fdout, mb, 0, p, LIST_MAL_ALL);
		constantblock +=  blockStart(p) && OPTallConstant(cntxt,mb,p);

		/* be aware that you only assign once to a variable */
		if (setonce && p->retc == 1 && OPTallConstant(cntxt, mb, p) && !isUnsafeFunction(p)) {
			barrier = p->barrier;
			p->barrier = 0;
			profiler = malProfileMode;	/* we don't trace it */
			malProfileMode = 0;
			if ( env == NULL) {
				env = prepareMALstack(mb,  2 * mb->vsize );
				env->keepAlive = TRUE;
			}
			msg = reenterMAL(cntxt, mb, i, i + 1, env);
			malProfileMode= profiler;
			p->barrier = barrier;
			OPTDEBUGevaluate {
				mnstr_printf(cntxt->fdout, "#retc var %s\n", getVarName(mb, getArg(p, 0)));
				mnstr_printf(cntxt->fdout, "#result:%s\n", msg == MAL_SUCCEED ? "ok" : msg);
			}
			if (msg == MAL_SUCCEED) {
				int nvar;
				ValRecord cst;

				actions++;
				cst.vtype = 0;
				VALcopy(&cst, &env->stk[getArg(p, 0)]);
				/* You may not overwrite constants.  They may be used by
				 * other instructions */
				nvar = getArg(p, 1) = defConstant(mb, getArgType(mb, p, 0), &cst);
				if (nvar >= env->stktop) {
					VALcopy(&env->stk[getArg(p, 1)], &getVarConstant(mb, getArg(p, 1)));
					env->stktop = getArg(p, 1) + 1;
				}
				alias[getArg(p, 0)] = getArg(p, 1);
				p->argc = 2;
				p->token = ASSIGNsymbol;
				clrFunction(p);
				p->barrier = barrier;
				/* freeze the type */
				setVarFixed(mb,getArg(p,1));
				setVarUDFtype(mb,getArg(p,1));
				OPTDEBUGevaluate {
					mnstr_printf(cntxt->fdout, "Evaluated new constant=%d -> %d:%s\n",
						getArg(p, 0), getArg(p, 1), getTypeName(getArgType(mb, p, 1)));
				}
			} else {
Пример #12
0
str
OPTevaluateImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	InstrPtr p;
	int i, k, limit, *alias = 0, barrier;
	MalStkPtr env = NULL;
	int profiler;
	int debugstate = cntxt->itrace, actions = 0, constantblock = 0;
	int *assigned = 0, use; 
	char buf[256];
	lng usec = GDKusec();
	str msg = MAL_SUCCEED;

	(void)stk;
	(void)pci;

	if ( mb->inlineProp )
		return MAL_SUCCEED;

	cntxt->itrace = 0;

#ifdef DEBUG_OPT_EVALUATE
	fprintf(stderr, "Constant expression optimizer started\n");
#endif

	assigned = (int*) GDKzalloc(sizeof(int) * mb->vtop);
	if (assigned == NULL)
		throw(MAL,"optimzier.evaluate", SQLSTATE(HY001) MAL_MALLOC_FAIL);

	alias = (int*)GDKzalloc(mb->vsize * sizeof(int) * 2); /* we introduce more */
	if (alias == NULL){
		GDKfree(assigned);
		throw(MAL,"optimzier.evaluate", SQLSTATE(HY001) MAL_MALLOC_FAIL);
	}

	// arguments are implicitly assigned by context
	p = getInstrPtr(mb, 0);
	for ( k =p->retc;  k < p->argc; k++)
		assigned[getArg(p,k)]++;
	limit = mb->stop;
	for (i = 1; i < limit; i++) {
		p = getInstrPtr(mb, i);
		// The double count emerging from a barrier exit is ignored.
		if (! blockExit(p) || (blockExit(p) && p->retc != p->argc))
		for ( k =0;  k < p->retc; k++)
		if ( p->retc != p->argc || p->token != ASSIGNsymbol )
			assigned[getArg(p,k)]++;
	}

	for (i = 1; i < limit && cntxt->mode != FINISHCLIENT; i++) {
		p = getInstrPtr(mb, i);
		// to avoid management of duplicate assignments over multiple blocks
		// we limit ourselves to evaluation of the first assignment only.
		use = assigned[getArg(p,0)] == 1 && !(p->argc == p->retc && blockExit(p));
		for (k = p->retc; k < p->argc; k++)
			if (alias[getArg(p, k)])
				getArg(p, k) = alias[getArg(p, k)];
#ifdef DEBUG_OPT_EVALUATE
		fprintInstruction(stderr , mb, 0, p, LIST_MAL_ALL);
#endif
		/* be aware that you only assign once to a variable */
		if (use && p->retc == 1 && OPTallConstant(cntxt, mb, p) && !isUnsafeFunction(p)) {
			barrier = p->barrier;
			p->barrier = 0;
			profiler = malProfileMode;	/* we don't trace it */
			malProfileMode = 0;
			if ( env == NULL) {
				env = prepareMALstack(mb,  2 * mb->vsize);
				if (!env) {
					msg = createException(MAL,"optimizer.evaluate", SQLSTATE(HY001) MAL_MALLOC_FAIL);
					goto wrapup;
				}
				env->keepAlive = TRUE;
			}
			msg = reenterMAL(cntxt, mb, i, i + 1, env);
			malProfileMode= profiler;
			p->barrier = barrier;
#ifdef DEBUG_OPT_EVALUATE
			fprintf(stderr, "#retc var %s\n", getVarName(mb, getArg(p, 0)));
			fprintf(stderr, "#result:%s\n", msg == MAL_SUCCEED ? "ok" : msg);
#endif
			if (msg == MAL_SUCCEED) {
				int nvar;
				ValRecord cst;

				actions++;
				cst.vtype = 0;
				VALcopy(&cst, &env->stk[getArg(p, 0)]);
				/* You may not overwrite constants.  They may be used by
				 * other instructions */
				nvar = getArg(p, 1) = defConstant(mb, getArgType(mb, p, 0), &cst);
				if (nvar >= env->stktop) {
					VALcopy(&env->stk[getArg(p, 1)], &getVarConstant(mb, getArg(p, 1)));
					env->stktop = getArg(p, 1) + 1;
				}
				alias[getArg(p, 0)] = getArg(p, 1);
				p->argc = 2;
				p->token = ASSIGNsymbol;
				clrFunction(p);
				p->barrier = barrier;
				/* freeze the type */
				setVarFixed(mb,getArg(p,1));
				setVarUDFtype(mb,getArg(p,1));
#ifdef DEBUG_OPT_EVALUATE
				{str tpename;
				fprintf(stderr, "Evaluated new constant=%d -> %d:%s\n",
					getArg(p, 0), getArg(p, 1), tpename = getTypeName(getArgType(mb, p, 1)));
				GDKfree(tpename);
				}
#endif
			} else {
				/* if there is an error, we should postpone message handling,
					as the actual error (eg. division by zero ) may not happen) */
#ifdef DEBUG_OPT_EVALUATE
				fprintf(stderr, "Evaluated %s\n", msg);
#endif
				freeException(msg);
				msg= MAL_SUCCEED;
				mb->errors = 0;
			}
		}
		constantblock +=  blockStart(p) && OPTallConstant(cntxt, mb, p);	/* default */
	}
	// produces errors in SQL when enabled
	if ( constantblock)
		msg = OPTremoveUnusedBlocks(cntxt, mb);
	cntxt->itrace = debugstate;

    /* Defense line against incorrect plans */
	/* Plan is unaffected */
	chkTypes(cntxt->usermodule, mb, FALSE);
	chkFlow(mb);
	chkDeclarations(mb);
    
    /* keep all actions taken as a post block comment */
	usec = GDKusec()- usec;
    snprintf(buf,256,"%-20s actions=%2d time=" LLFMT " usec","evaluate",actions,usec);
    newComment(mb,buf);
	if( actions >= 0)
		addtoMalBlkHistory(mb);

wrapup:
	if ( env) freeStack(env);
	if(assigned) GDKfree(assigned);
	if(alias)	GDKfree(alias);
	return msg;
}
Пример #13
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;
}
Пример #14
0
 void blockStart() { FOREACH blockStart(); }
Пример #15
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;
}
Пример #16
0
int
OPTrecyclerImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	int i, j, cnt, cand, actions = 1, marks = 0;
	InstrPtr *old, q,p;
	int limit;
	char *recycled;

	(void) cntxt;
	(void) stk;
	(void) pci;

	limit = mb->stop;
	old = mb->stmt;

	/* watch out, newly created instructions may introduce new variables */
	recycled = GDKzalloc(sizeof(char) * mb->vtop * 2);
	if (recycled == NULL)
		return 0;
	if (newMalBlkStmt(mb, mb->ssize) < 0) {
		GDKfree(recycled);
		return 0;
	}
	pushInstruction(mb, old[0]);
	for (i = 1; i < limit; i++) {
		p = old[i];
		if (p->token == ENDsymbol )
			break;
		/* the first non-dataflow barrier breaks the recycler code*/
		if (blockStart(p) && !(getFunctionId(p) && getFunctionId(p) == dataflowRef) )
			break;

		if ( isUpdateInstruction(p) || hasSideEffects(p,TRUE)){
			/*  update instructions are not recycled but monitored*/
			pushInstruction(mb, p);
			if (isUpdateInstruction(p)) {
				if (getModuleId(p) == batRef && isaBatType(getArgType(mb, p, 1))) {
					q = newFcnCall(mb, "recycle", "reset");
					pushArgument(mb, q, getArg(p, 1));
					actions++;
				}
				if (getModuleId(p) == sqlRef) {
					q= copyInstruction(p);
					getModuleId(q) = recycleRef;
					actions++;
				}
			}
			continue;
		}
		// Not all instruction may be recycled. In particular, we should avoid
		// MAL function with implicit/recursive side effects. 
		// This can not always be detected easily. Likewise, we ignore cheap operations
		// Therefore, we use a safe subset to start with
		if ( ! (getModuleId(p) == sqlRef || getModuleId(p)== batRef || 
				getModuleId(p) == algebraRef || getModuleId(p)==batcalcRef ||
				getModuleId(p)== aggrRef || getModuleId(p)== groupRef ||
				getModuleId(p)== batstrRef || getModuleId(p)== batmmathRef ||
				getModuleId(p)== arrayRef || getModuleId(p)== batmtimeRef ||
				getModuleId(p)== batcalcRef || getModuleId(p)== pcreRef ||
				getModuleId(p)== mtimeRef || getModuleId(p) == calcRef  ||
				getModuleId(p)== dateRef || getModuleId(p) == timestampRef  ||
				getModuleId(p)== matRef )
			){
			pushInstruction(mb,p);
			continue;
		}

		/* general rule: all arguments should be constants or recycled*/
		cnt = 0;
		for (j = p->retc; j < p->argc; j++)
			if (recycled[getArg(p, j)] || isVarConstant(mb, getArg(p, j)) || isFunctionArgument(mb,getArg(p,j)) )
				cnt++;
		cand = 0;
		for (j =0; j< p->retc; j++)
			if (recycled[getArg(p, j)] ==0)
				cand++;
		if (cnt == p->argc - p->retc && cand == p->retc) {
			marks++;
			p->recycle = RECYCLING; /* this instruction is to be monitored */
			for (j = 0; j < p->retc; j++)
				recycled[getArg(p, j)] = 1;
		}
		pushInstruction(mb, p);
	}
	for (; i < limit; i++) 
		pushInstruction(mb, old[i]);
	GDKfree(old);
	GDKfree(recycled);
	mb->recycle = marks > 0;
	OPTDEBUGrecycle {
		mnstr_printf(cntxt->fdout, "#recycle optimizer: ");
		printFunction(cntxt->fdout,mb, 0, LIST_MAL_ALL);
	}
	return actions + marks;
}