Update of /cvsroot/monetdb/MonetDB5/src/optimizer
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv21239
Modified Files:
opt_commonTerms.mx opt_deadcode.mx opt_emptySet.mx
opt_macro.mx opt_partitions.mx opt_remap.mx opt_support.mx
Log Message:
Synchronization point. The major part of the multiplex inline
remapping has been done. For side-effect-free functions an
attempt is made to cast scalar operators to their bat variant
and replace the corresponding instruction with the newly derived
block. The target is to speedup simple PSM routines.
Normalization of the RETURN/YIELD
has increased the errors to be handled in SQL
by one. There is a joinPath issue to be solved.
Index: opt_deadcode.mx
===================================================================
RCS file: /cvsroot/monetdb/MonetDB5/src/optimizer/opt_deadcode.mx,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- opt_deadcode.mx 9 Dec 2007 16:21:10 -0000 1.28
+++ opt_deadcode.mx 26 Dec 2007 14:31:11 -0000 1.29
@@ -129,7 +129,7 @@
freeInstruction(p);
actions++;
} else
- if (se || hasSideEffects(p, FALSE) || isProcedure(mb,p) )
+ if (se || hasSideEffects(p, FALSE) || !isLinearFlow(p) ||
isProcedure(mb,p) )
pushInstruction(mb,p);
else {
freeInstruction(p);
Index: opt_emptySet.mx
===================================================================
RCS file: /cvsroot/monetdb/MonetDB5/src/optimizer/opt_emptySet.mx,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- opt_emptySet.mx 9 Dec 2007 16:21:10 -0000 1.42
+++ opt_emptySet.mx 26 Dec 2007 14:31:11 -0000 1.43
@@ -250,6 +250,7 @@
of the empty set. The dead-code optimizer will take care
of removal of superflous constructions.
if( p->retc==1 && !hasSideEffects(p, FALSE) &&
+ !isLinearFlow(p) &&
!isUnsafeFunction(p) &&
isaBatType(getArgType(mb,p,0))){
int tpe=getArgType(mb,p,0);
Index: opt_remap.mx
===================================================================
RCS file: /cvsroot/monetdb/MonetDB5/src/optimizer/opt_remap.mx,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- opt_remap.mx 14 Nov 2007 12:24:29 -0000 1.15
+++ opt_remap.mx 26 Dec 2007 14:31:12 -0000 1.16
@@ -75,6 +75,7 @@
@c
#include "mal_config.h"
#include "opt_remap.h"
+#include "opt_macro.h"
static int
OPTremapDirect(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, Module scope){
@@ -119,6 +120,143 @@
}
@-
+Multiplex inline functions should be done with care.
+The approach taken is to make a temporary copy of the function to be inlined.
+To change all the statements to reflect the new situation
+and, if no error occurs, replaces the target instruction
+with this new block.
+
+By the time we get here, we know that function is
+side-effect free.
+
+The multiplex upgrade is targeted at all function
+arguments whose actual is a BAT and its formal
+is a scalar.
+This seems sufficient for the SQL generated PSM code,
+but does in general not hold.
+Forexample,
+
+function foo(b:int,c:bat[:oid,:int])
+ ... d:= batcalc.+(b,c)
+and
+multiplex("user","foo",ba:bat[:oid,:int],ca:bat[:oid,:int])
+upgrades the first argument. The naive upgrade of
+the statement that would fail. The code below catches
+most of them by simple prepending "bat" to the MAL function
+name and leave it to the type resolver to generate the
+error.
+
+The process terminates as soon as we
+find an instruction that does not have a multiplex
+counterpart.
[EMAIL PROTECTED]
+#define DEBUG_OPT_REMAP
+static int OPTmultiplexInline( MalBlkPtr mb, InstrPtr p, int pc ){
+ MalBlkPtr mq;
+ InstrPtr q,sig;
+ char buf[1024];
+ int i,j,k, *upgrade;
+ Symbol s;
+ s= findSymbol( VALget(&getVar(mb, getArg(p, 1))->value),
+ VALget(&getVar(mb, getArg(p,
2))->value));
+
+ if( s== NULL || !isSideEffectFree(s->def)){
+#ifdef DEBUG_OPT_REMAP
+ if( s== NULL)
+ stream_printf(GDKout,"#not found \n");
+ else
+ stream_printf(GDKout,"#side-effects\n");
+#endif
+ return 0;
+ }
[EMAIL PROTECTED]
+Determine the variables to be upgraded and adjust their type
[EMAIL PROTECTED]
+ mq= copyMalBlk(s->def);
+ sig= getInstrPtr(mq,0);
+#ifdef DEBUG_OPT_REMAP
+ stream_printf(GDKout,"#Modify the code\n");
+ printInstruction(GDKout,mq,sig,LIST_MAL_ALL);
+ printInstruction(GDKout,mb,p,LIST_MAL_ALL);
+#endif
+ upgrade= (int*) GDKzalloc(sizeof(int)*mq->vtop);
+ for(i=3; i<p->argc; i++){
+ if( !isaBatType( getArgType(mq,sig,i-2)) &&
+ isaBatType( getArgType(mb,p,i)) ){
+
+ if( getTailType(getArgType(mb,p,i)) !=
getArgType(mq,sig,i-2)){
+#ifdef DEBUG_OPT_REMAP
+ stream_printf(GDKout,"#Type mismatch %d\n",i);
+#endif
+ goto terminateMX;
+ }
+#ifdef DEBUG_OPT_REMAP
+ stream_printf(GDKout,"#Upgrade type %d\n",i);
+#endif
+ setVarType(mq, i-2,newBatType(TYPE_oid,
getArgType(mb,p,i)));
+ upgrade[getArg(sig,i-2)]= TRUE;
+ }
+ }
[EMAIL PROTECTED]
+The next step is to check each instruction of the
+to-be-inlined function for arguments that require
+an upgrade and resolve it afterwards.
[EMAIL PROTECTED]
+ for(i=1; i<mq->stop; i++){
+ q= getInstrPtr(mq,i);
+ k=0;
+ for(j=q->retc; j<q->argc; j++)
+ if( upgrade[getArg(q,j)] )
+ k++;
+ if(k){
+#ifdef DEBUG_OPT_REMAP
+ stream_printf(GDKout,"#Patch the instruction\n");
+ printInstruction(GDKout,mq,q,LIST_MAL_ALL);
+#endif
+ for(j=0;j<q->retc; j++)
+ setVarType(mq,getArg(q,j),TYPE_any);
+ if( getModuleId(q)){
+ snprintf(buf,1024,"bat%s",getModuleId(q));
+ setModuleId(q,putName(buf,strlen(buf)));
+#ifdef DEBUG_OPT_REMAP
+ printInstruction(GDKout,mq,q,LIST_MAL_ALL);
+#endif
+ }
+ /* now see if we can resolve the instruction */
+ typeChecker(MCgetClient()->nspace,mq,q,TRUE);
+ if( q->typechk== TYPE_UNKNOWN)
+ goto terminateMX;
+ for(j=0;j<q->retc; j++)
+ upgrade[getArg(q,j)]= TRUE;
+ }
+ }
+
+ if(mq->errors){
+terminateMX:
+ freeMalBlk(mq);
+ GDKfree(upgrade);
+ return 0;
+ }
[EMAIL PROTECTED]
+We have successfully constructed a variant
+of the to-be-inlined function. Put it in place
+of the original multiplex.
+But first, shift the arguments of the multiplex.
[EMAIL PROTECTED]
+ delArgument(p,2);
+ delArgument(p,1);
+ inlineMALblock(mb,pc,mq);
+#ifdef DEBUG_OPT_REMAP
+ printInstruction(GDKout,mb,p,LIST_MAL_ALL);
+ stream_printf(GDKout,"New block\n");
+ printFunction(GDKout,mq,LIST_MAL_ALL);
+ stream_printf(GDKout,"Inlined result\n");
+ printFunction(GDKout,mb,LIST_MAL_ALL);
+#endif
+ GDKfree(upgrade);
+ return 0;
+}
[EMAIL PROTECTED]
The comparison multiplex operations with a constant head may be supported
by reverse of the operation.
@c
@@ -187,6 +325,21 @@
p = old[i];
if ( getModuleId(p) == malRef &&
getFunctionId(p) == multiplexRef) {
[EMAIL PROTECTED]
+The next step considered is to handle inlined functions.
+It means we have already skipped the most obvious ones,
+such as the calculator functions. It is particularly
+geared at handling the PSM code.
[EMAIL PROTECTED]
+ if ( varGetProp(mb,getArg(p,0),inlineProp)!= NULL) {
+#ifdef DEBUG_OPT_REMAP
+ stream_printf(GDKout,"Multiplex inline\n");
+ printInstruction(GDKout,mb,p,LIST_MAL_ALL);
+#endif
+ pushInstruction(mb, p);
+ if( OPTmultiplexInline(mb,p,mb->stop-1) )
+ doit++;
+ } else
if( OPTremapDirect(mb, stk, p, scope) ||
OPTremapSwitched(mb, stk, p, scope)){
freeInstruction(p);
@@ -231,7 +384,8 @@
avg = pushArgument(mb, avg, getDestVar(cnt));
freeInstruction(p);
pushInstruction(mb, avg);
- } else {
+ } else
+ {
pushInstruction(mb, p);
}
}
Index: opt_partitions.mx
===================================================================
RCS file: /cvsroot/monetdb/MonetDB5/src/optimizer/opt_partitions.mx,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- opt_partitions.mx 17 Aug 2007 13:56:55 -0000 1.35
+++ opt_partitions.mx 26 Dec 2007 14:31:12 -0000 1.36
@@ -286,6 +286,7 @@
}
if( !hasSideEffects(p,TRUE) && p->retc == 1 &&
+ isLinearFlow(p) &&
!isBlocking(p) &&
getModuleId(p) != batcalcRef &&
OPTbarrierListCnt(mb, p, alias) > 0
Index: opt_macro.mx
===================================================================
RCS file: /cvsroot/monetdb/MonetDB5/src/optimizer/opt_macro.mx,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- opt_macro.mx 24 Dec 2007 12:28:25 -0000 1.23
+++ opt_macro.mx 26 Dec 2007 14:31:12 -0000 1.24
@@ -278,13 +278,14 @@
for (i = 0; i < pc; i++)
ns[k++] = mb->stmt[i];
- /* make result variable(s) known, ie assign a nil value */
+ /* make result variable(s) known, ie assign a nil value
for (n = 0; n < p->retc; n++) {
q = ns[k++] = newInstruction(NULL, ASSIGNsymbol);
q->argc = q->retc = 0;
q= pushArgument(mb, q, getArg(p, n)); q->retc++;
q= pushNil(mb, q, getArgType(mb, p, n));
}
+ */
/* copying stops at the first return statement */
for (i = 1; i < mc->stop - 1; i++) {
@@ -298,6 +299,8 @@
getArg(ns[k], n) = nv[getArg(q, n)];
if (q->barrier == RETURNsymbol || q->barrier == YIELDsymbol) {
+ setModuleId(ns[k],NULL);
+ setFunctionId(ns[k],NULL);
ns[k]->barrier = 0;
ns[k]->token = ASSIGNsymbol;
}
Index: opt_support.mx
===================================================================
RCS file: /cvsroot/monetdb/MonetDB5/src/optimizer/opt_support.mx,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -d -r1.52 -r1.53
--- opt_support.mx 17 Dec 2007 21:26:56 -0000 1.52
+++ opt_support.mx 26 Dec 2007 14:31:12 -0000 1.53
@@ -528,6 +528,7 @@
opt_export int hasCommonResults(InstrPtr p, InstrPtr q);
opt_export int isProcedure(MalBlkPtr mb, InstrPtr p);
opt_export int hasSideEffects(InstrPtr p, int strict);
+opt_export int isSideEffectFree(MalBlkPtr mb);
opt_export int isBlocking(InstrPtr p);
opt_export int isFragmentGroup(InstrPtr q);
opt_export int allArgumentsVisible(MalBlkPtr mb, int pc,int qc);
@@ -1067,6 +1068,11 @@
because it will trim most programs to an empty list.
The side effect tests should become part of the signature
definitions.
+
+A side effect is either an action to leave data around
+in a variable/resource outside the MALblock.
+A variant encoded here as well is that the linear flow
+of control can be broken.
@c
int
@@ -1080,8 +1086,6 @@
int
hasSideEffects(InstrPtr p, int strict)
{
- if (blockStart(p) || blockExit(p) || blockCntrl(p))
- return TRUE;
if( getFunctionId(p) == NULL) return FALSE;
if (getFunctionId(p) == depositRef ||
@@ -1136,6 +1140,18 @@
return FALSE;
}
@-
+Side-effect free functions are crucial for several operators.
[EMAIL PROTECTED]
+int
+isSideEffectFree(MalBlkPtr mb){
+ int i;
+ for(i=1; i< mb->stop; i++){
+ if( hasSideEffects(getInstrPtr(mb,i), TRUE))
+ return FALSE;
+ }
+ return TRUE;
+}
[EMAIL PROTECTED]
Breaking up a MAL program into pieces for distributed requires
identification of (partial) blocking instructions. A conservative
definition can be used.
Index: opt_commonTerms.mx
===================================================================
RCS file: /cvsroot/monetdb/MonetDB5/src/optimizer/opt_commonTerms.mx,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- opt_commonTerms.mx 23 Dec 2007 11:48:26 -0000 1.22
+++ opt_commonTerms.mx 26 Dec 2007 14:31:11 -0000 1.23
@@ -180,11 +180,13 @@
printf("%d, %d %d %d ", i, j,
hasSameSignature(p, q),
hasSameArguments(mb, p, q));
- printf(" :%d %d %d %d\n",
+ printf(" :%d %d %d %d %d %d\n",
!isUpdated(mb, i),
!hasCommonResults(p, q),
!hasSideEffects(p, TRUE),
- !hasSideEffects(q, TRUE));
+ !hasSideEffects(q, TRUE),
+ isLinearFlow(q),
+ isLinearFlow(p));
#endif
@-
@@ -197,6 +199,7 @@
!isUpdated(mb, i) &&
!hasCommonResults(p, q) &&
!hasSideEffects(p, TRUE) &&
+ isLinearFlow(p) &&
allTargetsVisible(mb,j,n-1)
) {
#ifdef DEBUG_OPT_COMMONTERMS
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Monetdb-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-checkins