⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mal_function.mx

📁 一个内存数据库的源代码这是服务器端还有客户端
💻 MX
📖 第 1 页 / 共 2 页
字号:
			head = getHeadType(x);			tail = getTailType(x);			hx = getHeadIndex(x);			tx = getTailIndex(x);			if(v && hx == v && head == TYPE_any){			    hx =0;			    head =t;			}			if(v && tx == v && tail == TYPE_any){			    tx= 0;			    tail = t;			}			y= newBatType(head,tail);			setAnyHeadIndex(y,hx);			setAnyTailIndex(y,tx);			setArgType(mb,p,i,y);#ifdef DEBUG_MAL_FCN		stream_printf(GDKout," %d replaced %s->%s \n",i,getTypeName(x),getTypeName(y));#endif 		} else		if(v>0 &&  getTailIndex(x) == v){#ifdef DEBUG_MAL_FCN		stream_printf(GDKout," replace x= %s polymorphic\n",getTypeName(x));#endif 			setArgType(mb,p,i,t);		} #ifdef DEBUG_MAL_FCN		else 		stream_printf(GDKout," non x= %s %d\n",getTypeName(x),getTailIndex(x));#endif 	}#ifdef DEBUG_MAL_FCN		printInstruction(GDKout,mb,p,LIST_MAL_ALL);#endif 	}}@-Upon cloning a function we should remove all the polymorphic flags.Otherwise we may end up with a recursive clone.@cSymbol  cloneFunction(Module scope, Symbol proc, MalBlkPtr mb, InstrPtr p){	Symbol new;	int i,v;	InstrPtr pp;#ifdef DEBUG_CLONE	stream_printf(GDKout,"clone the function %s to scope %s\n",			proc->name,scope->name);	printInstruction(GDKout,mb, p,LIST_MAL_ALL);#endif	new= newFunction(putName(proc->name,strlen(proc->name)), 	            getSignature(proc)->token );	new->def = copyMalBlk(proc->def);	/* now change the definition of the original proc *//*printf("CLONED VERSION\n");printFunction(GDKout, new->def, LIST_MAL_ALL);*/	/* check for errors after fixation , TODO*/	pp = getSignature(new);	for(i=0;i<pp->argc;i++)	if( isPolymorphic(v= getArgType(new->def,pp,i)) ){		int t = getArgType(mb,p,i);		if( isaBatType(t) ){			if( getHeadIndex(v) )	            replaceTypeVar(new->def, pp, getHeadIndex(v), getHeadType(t));			if( getTailIndex(v) )	            replaceTypeVar(new->def, pp, getTailIndex(v), getTailType(t));		} else			replaceTypeVar(new->def, pp, getTailIndex(v), t);	} #ifdef DEBUG_MAL_FCN	else stream_printf(GDKout,"%d remains %s\n",i, getTypeName(v));#endif	/* include the function at the proper place in the scope */	insertSymbol(scope,new);	/* clear polymorphic and type to force analysis*/	for(i=0;i<new->def->stop;i++) {		pp= getInstrPtr(new->def,i);	    pp->typechk= TYPE_UNKNOWN;		pp->polymorphic= 0;	}	/* clear type fixations */	for(i=0;i< new->def->vtop; i++)		new->def->var[i]->fixtype=0;#ifdef DEBUG_MAL_FCN	printf("FUNCTION TO BE CHECKED\n");	printFunction(GDKout, new->def, LIST_MAL_ALL);#endif	/* check for errors after fixation , TODO*/	/* beware, we should now ignore any cloning */	if(proc->def->errors == 0) {		chkProgram(scope,new->def);		if( new->def->errors){			showScriptException(new->def,0,MAL,"Error in cloned function");#ifdef DEBUG_MAL_FCN			printFunction(GDKout,new->def, LIST_MAL_ALL);#endif		}	}#ifdef DEBUG_CLONE	stream_printf(GDKout,"newly cloned function added to %s %d \n",scope->name,i);	printFunction(GDKout,new->def, LIST_MAL_ALL);#endif	return new;}@-For commands we do not have to clone the routine. We merely have toassure that the type-constraints are obeyed. The resulting typeis returned.@cvoid printFunction(stream *fd, MalBlkPtr mb, int flg){	int i;	for(i=0;i<mb->stop;i++)	printInstruction(fd,mb, getInstrPtr(mb,i),flg);}@- Lifespan analysisOptimizers may be interested in the characteristic of thebarrier blocks for making a decision.The variables have a lifespan in the code blocks, denoted by propertiesbeginLifespan,endLifespan. The beginLifespan denotes the intruction whereit receives its first value, the endLifespan the last instruction in which it was used as operand or target.If, however, the last use lies within a BARRIER block, we can not be sureabout its end of life status, because a block redo may implictlyrevive it. For these situations we associate the endLifespan withthe block exit.In many cases, we have to determine if the lifespan interferes with a optimization decision being prepared.The lifespan is calculated once at the beginning of the optimizer sequence.It should either be maintained to reflect the most accurate situation whileoptimizing the code base. In particular it means that any move/remove/additionof an instruction calls for either a recalculation or delta propagation.Unclear what will be the best strategy. For the time being we just recalc.Also take care of the nested block structure. Because the span shouldfall within a single block. This is handled by the chkflow already.@cvoiddebugLifespan(MalBlkPtr mb){	int i;	for (i = 0; i < mb->vtop; i++) {		VarPtr v = getVar(mb, i);		if (isTmpVar(mb, i))			printf("%c%d ", TMPMARKER, v->tmpindex); 		else			printf("%8s ", v->name);		printf("%d - %d  update %d scope= %d,%d\n", 			v->beginLifespan, v->endLifespan, 			v->lastUpdate, v->scope, v->depth);	}}voidsetLifespan(MalBlkPtr mb){	int pc, j, k;	InstrPtr p;	for (k = 0; k < mb->vtop; k++) {		VarPtr v = getVar(mb, k);		v->lastUpdate = v->beginLifespan = v->endLifespan = 0;		v->isused= 0;	}	for (pc = 0; pc < mb->stop; pc++) {		p = getInstrPtr(mb, pc);		for (k = 0; k < p->argc; k++) {			VarPtr v = getVar(mb, p->argv[k]);			if (v->beginLifespan == 0)				v->beginLifespan = pc;			if (k < p->retc && p->retc<p->argc)				v->lastUpdate= pc;			if (pc > v->endLifespan) {				/* end only if the beginLifspan falls in the same blk */				/* otherwise it is the corresponding exit. */				v->endLifespan = pc;			}		}@-For all variables we keep track if it is used, cq modified.This simplifies subsequent optimization.@c		if( p->token != NOOPsymbol)			for(j= p->retc; j<p->argc; j++)				setVarUsed(mb,getArg(p,j),!isTypeVar(mb,getArg(p,j)) );		if( blockCntrl(p) || blockStart(p) )			setVarUsed(mb,getDestVar(p),TRUE);	}	/* debugLifespan(mb); */}@cintisLoopBarrier(MalBlkPtr mb, int pc){	InstrPtr p;	int varid;	p= getInstrPtr(mb,pc);	if( p->barrier != BARRIERsymbol)		return 0;	varid= getDestVar(p);	for(pc++; pc< mb->stop; pc++){		p= getInstrPtr(mb,pc);		if( p->barrier == REDOsymbol && getDestVar(p)== varid)			return 1;		if( p->barrier == EXITsymbol && getDestVar(p)== varid)			break;	}	return 0;}@-Searching the beginning or end of an instruction block.@cintgetBlockBegin(MalBlkPtr mb,int pc){	InstrPtr p;	int varid=0,i;	for(i= pc; i< mb->stop; i++){		p= getInstrPtr(mb,i);		if( p->barrier == EXITsymbol ){			varid= getDestVar(p);			break;		}	}	if( i==mb->stop) return 0;	for(; pc> 0; pc--){		p= getInstrPtr(mb,pc);		if( (p->barrier == BARRIERsymbol || p->barrier == CATCHsymbol) &&		    getDestVar(p)== varid)			return pc;	}	return 0;}intgetBlockExit(MalBlkPtr mb,int pc){	InstrPtr p;	int varid;	p= getInstrPtr(mb,pc);	if( p->barrier != BARRIERsymbol && p->barrier != CATCHsymbol)		return 0;	varid= getDestVar(p);	for(pc++; pc< mb->stop; pc++){		p= getInstrPtr(mb,pc);		if( p->barrier == EXITsymbol && getDestVar(p)== varid)			return pc;	}	return 0;}@- Variable declarationVariables are implicitly declared upon first use.This feature may become a source of runtime errors andcomplicates the analyse during optimization.Therefore, in line with the flow of control check,we make sure that all variables are properly initializedbefore being used. Since barrier blocks may be skipped atruntime, they actually introduce a separate scope.Variables declared within a block may not be used outside it.In many situation chkFlow and chkDeclarations should be calledtogether. Moreover, an erroneous chkFlow most likely implieserrors in the declarations as well.Since in interactive mode each statement is handled separately,we have to remember the scope assigned to a variable.@cvoid chkDeclarations(MalBlkPtr mb,int reset){	int pc,i, k,l;	InstrPtr p;	short s, blks[MAXDEPTH], top= 0, blkId=1;	blks[top] = 1;	blks[++top]= 0;	if( reset) 	for(i=0; i<mb->vtop; i++){		getVarDepth(mb,i)=0;		getVarScope(mb,i)=0;		if( mb->var[i]->name == 0 && !isTmpVar(mb,i)){			showScriptException(mb,0,TYPE,"Name missing in variable %d",i);			mb->errors++;		}	}	/* all signature variables are declared at outer level */	p= getInstrPtr(mb,0);	for(k=p->retc;k<p->argc; k++){		getVarScope(mb,p->argv[k])= 1;	    getVarDepth(mb,p->argv[k])= 0;	}	/* and the function name as well */	if( getFunctionId(p) == NULL){		showScriptException(mb,0, TYPE,			"Function name missing in signature");		return;	}			/* printFunction(GDKout,mb, LIST_MAL_ALL);*/	for(pc=1;pc<mb->stop; pc++){		p= getInstrPtr(mb,pc);		for(k=p->retc;k<p->argc; k++) {			l=getArg(p,k);			if( isConstant(mb, l) || isTypeVar(mb,l) ){				/* ok defined */			} else 			if( (s = getVarScope(mb,l) ) ==0 ) {					showScriptException(mb,pc,TYPE,						"'%s' may not be used before being initialized", 						getVarName(mb,l));						mb->errors++;			} else 			if( getVarDepth(mb,l) >= top){						showScriptException(mb,pc,TYPE,							"'%s' may not be used before being set in %s[%d]",							getVarName(mb,l));						mb->errors++;			}			assert( isTmpVar(mb,l) < mb->vtop);		}		for(k=0; k<p->retc; k++){			l= getArg(p,k);			assert( isTmpVar(mb,l) < mb->vtop);			if( getVarScope(mb, l) == 0){				if( (p->barrier== RETURNsymbol || p->barrier== YIELDsymbol) &&					getVarType(mb,l) != TYPE_void  && p->retc==p->argc){			            showScriptException(mb,pc,TYPE,							"'%s' returns before being initialized",							getVarName(mb,l));						mb->errors++;				}			    getVarScope(mb, l) = blks[top-1];			    getVarDepth(mb, l) = top-1;			} else {			    /* is the block still active ? */			    s = getVarScope(mb,l);			    for( i=0; i< top; i++)			    if( blks[i] == s ) break;			    if( i< top && blks[i]!= s && !isTmpVar(mb, l)){			            showScriptException(mb,pc,TYPE,							"'%s' used outside declaration",							getVarName(mb,l));			        mb->errors++;			    }			}		}		if( p->barrier){			if( blockStart(p)){				blkId++;				if( top <MAXDEPTH-2){					blks[top]= blkId;					blks[++top]= 0;				} else {					showScriptException(mb,pc,SYNTAX,						"too deeply nested  MAL program");					mb->errors++;					return;				}			}			if( blockExit(p) && top > 0) {			    top--;			    blks[top]= 0;			}		}	}}@-Data flow analysis.Flow graph display is handy for debugging and analysis.A better flow analysis is needed, which takes into accountloops and side-effect functions.@cstatic voidshowOutFlow(MalBlkPtr mb, int pc, int varid, stream *f){	InstrPtr p;	int i, k,found;	for (i = pc + 1; i < mb->stop - 1; i++) {		p = getInstrPtr(mb, i);		found=0;		for (k = p->retc; k < p->argc; k++) {			if (p->argv[k] == varid ) {				stream_printf(f, "n%d -> n%d\n", pc, i);				found++;			}		}		/* stop as soon you find a re-assignment */		for (k = 0; k < p->retc; k++) {			if (getArg(p,k) == varid)				i = mb->stop;		}		/* or a side-effect usage */		if( found &&			(p->retc== 0 || getArgType(mb,p,0)== TYPE_void) )				i = mb->stop;	}}static voidshowInFlow(MalBlkPtr mb, int pc, int varid, stream *f){	InstrPtr p;	int i, k;	/* find last use, needed for operations with side effects */	for (i = pc -1; i >= 0; i-- ){		p = getInstrPtr(mb, i);		for (k = 0; k < p->argc; k++)			if (p->argv[k] == varid  ){				stream_printf(f, "n%d -> n%d\n",i, pc);				return;			}	}}@-At a later stage we could extend the flow details with the statusof crucial properties, e.g. processing time, cost, size@cstatic voidshowFlowDetails(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int pc, stream *f){	str s, msg;	PropertySet ps;	int i;	(void) stk;		/* fool the compiler */	msg = instruction2str(mb, p, 0);	stream_printf(f, "n%d [fontsize=8, shape=box, label=\"", pc);	for (s = msg+1; *s; s++)		if (*s == '"')			stream_printf(f, "\\\"");		else			stream_printf(f, "%c", *s);	for(i=0;i<p->retc; i++){		stream_printf(f, "\\n%s",getArgName(mb,p,i));		stream_printf(f,":%s", s=getTypeName(getVarType(mb,getArg(p,i))));		GDKfree(s);		ps = getProps(mb,getArg(p,i));		if( ps == 0) continue;		s= propertySet2str(ps);		for (; s && *s; s++)			if (*s == '"')				stream_printf(f, "\\\"");			else				stream_printf(f, "%c", *s);	}	/* later: add BAT runtime properties */	stream_printf(f, "\"];\n");	GDKfree(msg);}voidshowFlowGraph(MalBlkPtr mb, MalStkPtr stk, str fname){	stream *f;	InstrPtr p;	int i, k;	(void) stk;		/* fool the compiler */	if (idcmp(fname, "stdout") == 0)		f = GDKout;	else		f = open_wastream(fname);	setLifespan(mb);	p = getInstrPtr(mb, 0);	stream_printf(f, "digraph %s{\n", getFunctionId(p));	p = getInstrPtr(mb, 0);	showFlowDetails(mb, stk, p, 0, f);	for (k = p->retc; k < p->argc; k++) {		showOutFlow(mb, 0, p->argv[k], f);	}	for (i = 1; i < mb->stop ; i++) {		p = getInstrPtr(mb, i);		showFlowDetails(mb, stk, p, i, f);		for (k = 0; k < p->retc; k++) 				showOutFlow(mb, i, p->argv[k], f);		if( p->retc== 0 || getArgType(mb,p,0)== TYPE_void) /* assume side effects */		for (k = p->retc; k < p->argc; k++) 			if (getArgType(mb,p,k) != TYPE_void && 				!isConstant(mb,getArg(p,k)))				showOutFlow(mb, i, p->argv[k], f);		if( getFunctionId(p)== 0)			for (k =0; k< p->retc; k++) 				if( getArgType(mb,p,k) != TYPE_void)					showInFlow(mb, i, p->argv[k], f);	}	stream_printf(f, "}\n");	if (f != GDKout)		stream_close(f);}@}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -