Changeset: bbab2d7ad02d for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=bbab2d7ad02d
Modified Files:
        monetdb5/modules/mal/language.c
        monetdb5/modules/mal/language.h
        monetdb5/modules/mal/language.mal
        monetdb5/optimizer/opt_dataflow.c
        monetdb5/optimizer/opt_prelude.c
        monetdb5/optimizer/opt_prelude.h
Branch: Feb2013
Log Message:

Improve release of temporaries
The sink() operation ensures we handle proper execution of variables used
repeatedly at the cost of retaining the temporaries too long.
Using the pass() operation turns it into a cheap dataflow dependency.
Cheap instruction to disgard storage while retaining the dataflow dependency.


diffs (282 lines):

diff --git a/monetdb5/modules/mal/language.c b/monetdb5/modules/mal/language.c
--- a/monetdb5/modules/mal/language.c
+++ b/monetdb5/modules/mal/language.c
@@ -152,6 +152,16 @@ MALgarbagesink( Client cntxt, MalBlkPtr 
        return MAL_SUCCEED;
 }
 
+str
+MALpass( Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
+{
+       (void) cntxt;
+       (void) mb;
+       (void) stk;
+       (void) pci;
+       return MAL_SUCCEED;
+}
+
 str 
 CMDregisterFunction(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
diff --git a/monetdb5/modules/mal/language.h b/monetdb5/modules/mal/language.h
--- a/monetdb5/modules/mal/language.h
+++ b/monetdb5/modules/mal/language.h
@@ -47,6 +47,7 @@ language_export str MALassertSht(int *re
 language_export str MALassertInt(int *ret, int *val, str *msg);
 language_export str MALassertLng(int *ret, lng *val, str *msg);
 language_export str MALstartDataflow( Client cntxt, MalBlkPtr mb, MalStkPtr 
stk, InstrPtr pci);
+language_export str MALpass( Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 language_export str MALgarbagesink( Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 language_export str CMDregisterFunction(Client cntxt, MalBlkPtr mb, MalStkPtr 
stk, InstrPtr pci);
 language_export str CMDsetMemoryTrace(Client cntxt, MalBlkPtr mb, MalStkPtr 
stk, InstrPtr pci);
diff --git a/monetdb5/modules/mal/language.mal 
b/monetdb5/modules/mal/language.mal
--- a/monetdb5/modules/mal/language.mal
+++ b/monetdb5/modules/mal/language.mal
@@ -39,6 +39,10 @@ address MALgarbagesink
 comment "Variables to be considered together when triggering garbage 
collection.
 Used in the dataflow blocks to avoid early release of values.";
 
+pattern pass(v:any_1):any_1
+address MALpass
+comment "Cheap instruction to disgard storage while retaining the dataflow 
dependency";
+
 pattern register(m:str,f:str,code:str,help:str):void
 address CMDregisterFunction
 comment"Compile the code string to MAL and register it as a function.";
diff --git a/monetdb5/optimizer/opt_dataflow.c 
b/monetdb5/optimizer/opt_dataflow.c
--- a/monetdb5/optimizer/opt_dataflow.c
+++ b/monetdb5/optimizer/opt_dataflow.c
@@ -132,34 +132,44 @@ dflowInstruction(InstrPtr p) {
        return FALSE;
 }
 
-static InstrPtr
-dflowGarbagesink(MalBlkPtr mb, InstrPtr *old, int start, int last, int var, 
int *usage){
-       InstrPtr p, sink;
+static int
+dflowGarbagesink(MalBlkPtr mb, InstrPtr *old, int start, int last, int var, 
InstrPtr *sink, int top){
+       InstrPtr p, q, r;
        int j,k;
-       if ( usage[var] == 0  || isVarConstant(mb, var) )
-               return NULL;
-       sink= newInstruction(mb,ASSIGNsymbol); 
-       getModuleId(sink) = languageRef;
-       getFunctionId(sink) = sinkRef;
-       getArg(sink,0)= newTmpVariable(mb,TYPE_void);
-       sink= pushArgument(mb, sink, var);
+       
+       q= newInstruction(NULL,ASSIGNsymbol); 
+       getModuleId(q) = languageRef;
+       getFunctionId(q) = sinkRef;
+       getArg(q,0)= newTmpVariable(mb,TYPE_void);
+       q= pushArgument(mb, q, var);
        for ( j= start; j< last; j++){
+               assert(top <mb->vsize);
                p = old[j];
                if ( p )
                for (k = p->retc; k< p->argc; k++)
-                       if ( getArg(p,k)== var)
-                               sink= pushArgument(mb,sink, getArg(p,0));
+                       if ( getArg(p,k)== var) {
+                               r = newInstruction(NULL,ASSIGNsymbol);
+                               getModuleId(r) = languageRef;
+                               getFunctionId(r) = passRef;
+                               getArg(r,0) = 
newTmpVariable(mb,getArgType(mb,p,0));
+                               r= pushArgument(mb,r, getArg(p,0));
+                               sink[top++] = r;
+                               q= pushArgument(mb,q, getArg(r,0));
+                               break;
+               }
        }
-       return sink;
+       assert(top <mb->vsize);
+       sink[top++] = q;
+       return top;
 }
 
 int
 OPTdataflowImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
p)
 {
-       int i,j,k, cnt, start=1,entries=0, actions=0;
+       int i,j,k, var, cnt, start=1,entries=0, actions=0;
        int flowblock= 0, dumbcopy=0;
        InstrPtr *sink, *old, q;
-       int limit, slimit, top = 0;
+       int limit, slimit, size, top = 0;
        Lifespan span;
        char *init;
        int *usage;
@@ -187,18 +197,18 @@ OPTdataflowImplementation(Client cntxt, 
                GDKfree(init);
                return 0;
        }
-       sink= (InstrPtr*) GDKzalloc(mb->stop * sizeof(InstrPtr));
-       if ( usage == NULL){
+       sink= (InstrPtr*) GDKzalloc(size = mb->vsize * sizeof(InstrPtr));
+       if ( sink == NULL){
                GDKfree(span);
                GDKfree(init);
-               GDKfree(sink);
+               GDKfree(usage);
                return 0;
        }
 
        limit= mb->stop;
        slimit= mb->ssize;
        old = mb->stmt;
-       if ( newMalBlkStmt(mb, mb->ssize+20) <0 ){
+       if ( newMalBlkStmt(mb, mb->ssize+mb->vtop) <0 ){
                GDKfree(span);
                GDKfree(init);
                GDKfree(usage);
@@ -222,6 +232,7 @@ OPTdataflowImplementation(Client cntxt, 
                        /* close old flow block */
                        if (flowblock){
                                int sf = simpleFlow(old,start,i);
+                               top = 0;
                                if (!sf && entries > 1){
                                        for( j=start ; j<i; j++)
                                        if (old[j]) {
@@ -234,13 +245,12 @@ OPTdataflowImplementation(Client cntxt, 
                                                }
                                                /* collect variables garbage 
collected within the block */
                                                for( k=old[j]->retc; 
k<old[j]->argc; k++)
-                                               if( 
getEndLifespan(span,getArg(old[j],k)) == j) {
-                                                       sink[top] = 
dflowGarbagesink(mb,old, start, i, getArg(old[j],k), usage);
-                                                       top += sink[top] != 
NULL;
-                                               }
-                                               else
-                                               if( 
getEndLifespan(span,getArg(old[j],k)) < i)
-                                                       
usage[getArg(old[j],k)]++;
+                                                       if( 
getEndLifespan(span, var = getArg(old[j],k)) == j && usage[var]==1 && 
!isVarConstant(mb, var) )
+                                                               top = 
dflowGarbagesink(mb,old, start, i, getArg(old[j],k), sink,top);
+                                                       else
+                                                       if( 
getEndLifespan(span,getArg(old[j],k)) < i && !isVarConstant(mb, var) )
+                                                               
usage[getArg(old[j],k)]++;
+                                               assert(top <mb->vsize);
                                        }
                                        q= 
newFcnCall(mb,languageRef,dataflowRef);
                                        q->barrier= BARRIERsymbol;
@@ -254,10 +264,6 @@ OPTdataflowImplementation(Client cntxt, 
                                                pushInstruction(mb,old[j]);
                                for( j=0; j<top; j++)
                                                pushInstruction(mb,sink[j]);
-                               if ( top ) {
-                                       top = 0;
-                                       memset( (char*) sink, 0, limit * 
sizeof(InstrPtr));
-                               }
                                if (!sf && entries>1){
                                        q= newAssignment(mb);
                                        q->barrier= EXITsymbol;
@@ -278,6 +284,7 @@ OPTdataflowImplementation(Client cntxt, 
                                /* close old flow block */
                                if (flowblock){
                                        int sf = simpleFlow(old,start,i);
+                                       top = 0;
                                        if (!sf && entries > 1){
                                                for( j=start ; j<i; j++)
                                                if (old[j]) {
@@ -290,13 +297,11 @@ OPTdataflowImplementation(Client cntxt, 
                                                        }
                                                        /* collect variables 
garbagecollected in the block */
                                                        for( k=old[j]->retc; 
k<old[j]->argc; k++)
-                                                               if( 
getEndLifespan(span,getArg(old[j],k)) == i) {
-                                                                       
sink[top] = dflowGarbagesink(mb, old, start, i, getArg(old[j],k), usage);
-                                                                       top += 
sink[top] != NULL;
-                                                               }
-                                                               else
-                                                               if( 
getEndLifespan(span,getArg(old[j],k)) < i) 
-                                                                       
usage[getArg(old[j],k)]++;
+                                                       if( 
getEndLifespan(span, var = getArg(old[j],k)) == j && usage[var]==1 && 
!isVarConstant(mb, var) )
+                                                               top = 
dflowGarbagesink(mb,old, start, i, getArg(old[j],k), sink,top);
+                                                       else
+                                                       if( 
getEndLifespan(span,getArg(old[j],k)) < i && !isVarConstant(mb, var) )
+                                                               
usage[getArg(old[j],k)]++;
                                                }
                                                q= 
newFcnCall(mb,languageRef,dataflowRef);
                                                q->barrier= BARRIERsymbol;
@@ -308,13 +313,10 @@ OPTdataflowImplementation(Client cntxt, 
                                        for( j=start ; j<i; j++)
                                                if (old[j])
                                                        
pushInstruction(mb,old[j]);
-                                               /* inject the optional garbage 
sink statement */
-                                               for( j=0; j<top; j++)
-                                                               
pushInstruction(mb,sink[j]);
-                                               if ( top) {
-                                                       top = 0;
-                                                       memset( (char*) sink, 
0, mb->stop * sizeof(InstrPtr));
-                                               }
+                                       assert(top <mb->vsize);
+                                       /* inject the optional garbage sink 
statement */
+                                       for( j=0; j<top; j++)
+                                                       
pushInstruction(mb,sink[j]);
                                        if (!sf && entries>1){
                                                q= newAssignment(mb);
                                                q->barrier= EXITsymbol;
@@ -357,9 +359,10 @@ OPTdataflowImplementation(Client cntxt, 
        /* close old flow block */
        if (flowblock){
                int sf = simpleFlow(old,start,i);
+               top = 0;
                if (!sf && entries > 1){
                        for( j=start ; j<i; j++)
-                       if (old[j]) 
+                       if (old[j]) {
                                for( k=0; k<old[j]->retc; k++)
                                if( getBeginLifespan(span,getArg(old[j],k)) > 
start && getEndLifespan(span,getArg(old[j],k)) >= i && 
init[getArg(old[j],k)]==0){
                                        InstrPtr r= newAssignment(mb);
@@ -367,6 +370,13 @@ OPTdataflowImplementation(Client cntxt, 
                                        pushNil(mb,r,getArgType(mb,old[j],k));
                                        init[getArg(old[j],k)]=1;
                                }
+                               for( k=old[j]->retc; k<old[j]->argc; k++)
+                               if( getEndLifespan(span, var = 
getArg(old[j],k)) == j && usage[var]==1 && !isVarConstant(mb, var) )
+                                       top = dflowGarbagesink(mb,old, start, 
i, getArg(old[j],k), sink,top);
+                               else
+                               if( getEndLifespan(span,getArg(old[j],k)) < i 
&& !isVarConstant(mb, var) )
+                                       usage[getArg(old[j],k)]++;
+                       }
                        q= newFcnCall(mb,languageRef,dataflowRef);
                        q->barrier= BARRIERsymbol;
                        getArg(q,0)= flowblock;
@@ -377,6 +387,10 @@ OPTdataflowImplementation(Client cntxt, 
                for( j=start ; j<i; j++)
                        if (old[j])
                                pushInstruction(mb,old[j]);
+               assert(top <mb->vsize);
+               /* inject the optional garbage sink statement */
+               for( j=0; j<top; j++)
+                               pushInstruction(mb,sink[j]);
                if (!sf && entries>1){
                        q= newAssignment(mb);
                        q->barrier= EXITsymbol;
diff --git a/monetdb5/optimizer/opt_prelude.c b/monetdb5/optimizer/opt_prelude.c
--- a/monetdb5/optimizer/opt_prelude.c
+++ b/monetdb5/optimizer/opt_prelude.c
@@ -167,6 +167,7 @@ str openRef;
 str optimizerRef;
 str packRef;
 str pack2Ref;
+str passRef;
 str partitionRef;
 str pcreRef;
 str pinRef;
@@ -423,6 +424,7 @@ void optimizerInit(void){
                openRef = putName("open",4);
                packRef = putName("pack",4);
                pack2Ref = putName("pack2",5);
+               passRef = putName("pass",4);
                partitionRef = putName("partition",9);
                pcreRef = putName("pcre",4);
                pinRef = putName("pin",3);
diff --git a/monetdb5/optimizer/opt_prelude.h b/monetdb5/optimizer/opt_prelude.h
--- a/monetdb5/optimizer/opt_prelude.h
+++ b/monetdb5/optimizer/opt_prelude.h
@@ -166,6 +166,7 @@ opt_export  str openRef;
 opt_export  str optimizerRef;
 opt_export  str packRef;
 opt_export  str pack2Ref;
+opt_export  str passRef;
 opt_export  str partitionRef;
 opt_export  str pcreRef;
 opt_export  str pinRef;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to