package IR.Flat;
+import IR.Tree.Modifiers;
import IR.Tree.FlagExpressionNode;
import IR.Tree.DNFFlag;
import IR.Tree.DNFFlagAtom;
import Analysis.Locality.LocalityAnalysis;
import Analysis.Locality.LocalityBinding;
import Analysis.Locality.DiscoverConflicts;
+import Analysis.Locality.DelayComputation;
import Analysis.CallGraph.CallGraph;
import Analysis.Prefetch.*;
import Analysis.Loops.WriteBarrier;
+import Analysis.Loops.GlobalFieldType;
import Analysis.Locality.TypeAnalysis;
+import Analysis.MLP.MLPAnalysis;
+import Analysis.MLP.VariableSourceToken;
+import Analysis.MLP.CodePlan;
+import Analysis.MLP.SESEandAgePair;
public class BuildCode {
State state;
Hashtable flagorder;
int tag=0;
String localsprefix="___locals___";
+ String localsprefixaddr="&"+localsprefix;
+ String localsprefixderef=localsprefix+".";
String fcrevert="___fcrevert___";
String paramsprefix="___params___";
String oidstr="___nextobject___";
Hashtable<LocalityBinding, Hashtable<TempDescriptor, TempDescriptor>> backuptable;
SafetyAnalysis sa;
PrefetchAnalysis pa;
- HashSet<FlatSESEEnterNode> setSESEtoGen;
+ MLPAnalysis mlpa;
+ String mlperrstr = "if(status != 0) { "+
+ "sprintf(errmsg, \"MLP error at %s:%d\", __FILE__, __LINE__); "+
+ "perror(errmsg); exit(-1); }";
boolean nonSESEpass=true;
WriteBarrier wb;
DiscoverConflicts dc;
+ DiscoverConflicts recorddc;
+ DelayComputation delaycomp;
CallGraph callgraph;
public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa) {
- this(st, temptovar, typeutil, null, sa, pa);
+ this(st, temptovar, typeutil, null, sa, pa, null);
}
- public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, PrefetchAnalysis pa) {
- this(st, temptovar, typeutil, locality, null, pa);
+ public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa, MLPAnalysis mlpa) {
+ this(st, temptovar, typeutil, null, sa, pa, mlpa);
}
- public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, SafetyAnalysis sa, PrefetchAnalysis pa) {
+ public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, PrefetchAnalysis pa, MLPAnalysis mlpa) {
+ this(st, temptovar, typeutil, locality, null, pa, mlpa);
+ }
+
+ public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, SafetyAnalysis sa, PrefetchAnalysis pa, MLPAnalysis mlpa) {
this.sa=sa;
this.pa=pa;
+ this.mlpa=mlpa;
state=st;
callgraph=new CallGraph(state);
if (state.SINGLETM)
}
if (state.SINGLETM&&state.DCOPTS) {
TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
- this.dc=new DiscoverConflicts(locality, st, typeanalysis);
+ this.dc=new DiscoverConflicts(locality, st, typeanalysis, null);
dc.doAnalysis();
}
-
- setSESEtoGen = new HashSet<FlatSESEEnterNode>();
+ if (state.DELAYCOMP) {
+ //TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
+ TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
+ GlobalFieldType gft=new GlobalFieldType(callgraph, st, typeutil.getMain());
+ delaycomp=new DelayComputation(locality, st, typeanalysis, gft);
+ delaycomp.doAnalysis();
+ dc=delaycomp.getConflicts();
+ recorddc=new DiscoverConflicts(locality, st, typeanalysis, delaycomp.getCannotDelayMap(), true, true, null);
+ recorddc.doAnalysis();
+ }
}
/** The buildCode method outputs C code for all the methods. The Flat
outmethodheader.println("#include \"structdefs.h\"");
if (state.DSM)
outmethodheader.println("#include \"dstm.h\"");
- if (state.SINGLETM)
+ if (state.SINGLETM) {
outmethodheader.println("#include \"tm.h\"");
+ outmethodheader.println("#include \"delaycomp.h\"");
+ }
if (state.ABORTREADERS) {
outmethodheader.println("#include \"abortreaders.h\"");
outmethodheader.println("#include <setjmp.h>");
}
+ if (state.MLP) {
+ outmethodheader.println("#include <stdlib.h>");
+ outmethodheader.println("#include <stdio.h>");
+ outmethodheader.println("#include <string.h>");
+ outmethodheader.println("#include \"mlp_runtime.h\"");
+ outmethodheader.println("#include \"psemaphore.h\"");
+ }
/* Output Structures */
outputStructs(outstructs);
outputTaskTypes(outtask);
}
+ if( state.MLP ) {
+ // have to initialize some SESE compiler data before
+ // analyzing normal methods, which must happen before
+ // generating SESE internal code
+ for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
+ FlatSESEEnterNode fsen = seseit.next();
+ initializeSESE( fsen );
+ }
+ }
+
/* Build the actual methods */
outputMethods(outmethod);
+ // Output function prototypes and structures for SESE's and code
if( state.MLP ) {
nonSESEpass = false;
- while( !setSESEtoGen.isEmpty() ) {
- FlatSESEEnterNode fsen = setSESEtoGen.iterator().next();
- setSESEtoGen.remove(fsen);
- generateMethodSESE(fsen, fsen.getEnclosingFlatMeth(), null, outmethod);
+
+ // first generate code for each sese's internals
+ for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
+ FlatSESEEnterNode fsen = seseit.next();
+ generateMethodSESE(fsen, null, outstructs, outmethodheader, outmethod);
}
- } else {
- assert setSESEtoGen.isEmpty();
+
+ // then write the invokeSESE switch to decouple scheduler
+ // from having to do unique details of sese invocation
+ generateSESEinvocationMethod(outmethodheader, outmethod);
}
if (state.TASK) {
private void outputMainMethod(PrintWriter outmethod) {
outmethod.println("int main(int argc, const char *argv[]) {");
outmethod.println(" int i;");
+
+ if (state.MLP) {
+ //outmethod.println(" pthread_once( &mlpOnceObj, mlpInitOncePerThread );");
+ outmethod.println(" workScheduleInit( "+state.MLP_NUMCORES+", invokeSESEmethod );");
+ }
+
if (state.DSM) {
outmethod.println("#ifdef TRANSSTATS \n");
outmethod.println("handle();\n");
}
if (state.THREAD||state.DSM||state.SINGLETM) {
outmethod.println("initializethreads();");
- outmethod.println("#ifdef STMSTATS\n");
- outmethod.println(" for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {");
- outmethod.println(" typesCausingAbort[i] = 0;");
- outmethod.println(" }");
- outmethod.println("#endif\n");
}
if (state.DSM) {
outmethod.println("if (dstmStartup(argv[1])) {");
- if (GENERATEPRECISEGC) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-2);");
} else {
outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-2);");
}
} else {
- if (GENERATEPRECISEGC) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
} else {
outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
} else
outmethod.println(" for(i=1;i<argc;i++) {");
outmethod.println(" int length=strlen(argv[i]);");
- if (GENERATEPRECISEGC) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
outmethod.println(" struct ___String___ *newstring=NewString(NULL, argv[i], length);");
} else {
outmethod.println(" struct ___String___ *newstring=NewString(argv[i], length);");
outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
outmethod.println(" }");
-
MethodDescriptor md=typeutil.getMain();
ClassDescriptor cd=typeutil.getMainClass();
outmethod.println(" {");
- if (GENERATEPRECISEGC) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
if (state.DSM||state.SINGLETM) {
outmethod.print(" struct "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
} else
if (state.DSM||state.SINGLETM) {
outmethod.println("#ifdef TRANSSTATS \n");
outmethod.println("printf(\"****** Transaction Stats ******\\n\");");
- outmethod.println("printf(\"numTransAbort= %d\\n\", numTransAbort);");
outmethod.println("printf(\"numTransCommit= %d\\n\", numTransCommit);");
+ outmethod.println("printf(\"numTransAbort= %d\\n\", numTransAbort);");
outmethod.println("printf(\"nSoftAbort= %d\\n\", nSoftAbort);");
if (state.DSM) {
outmethod.println("printf(\"nchashSearch= %d\\n\", nchashSearch);");
outmethod.println("printf(\"nSoftAbortCommit= %d\\n\", nSoftAbortCommit);");
outmethod.println("#ifdef STMSTATS\n");
outmethod.println("for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {\n");
- outmethod.println(" printf(\"typesCausingAbort[%d]= %d\\n\", i, typesCausingAbort[i]);\n");
+ outmethod.println(" printf(\"typesCausingAbort[%2d] numaccess= %5d numabort= %3d\\n\", i, typesCausingAbort[i].numaccess, typesCausingAbort[i].numabort);\n");
outmethod.println("}\n");
outmethod.println("#endif\n");
outmethod.println("fflush(stdout);");
if (state.THREAD||state.SINGLETM)
outmethod.println("pthread_exit(NULL);");
- outmethod.println("}");
+ if (state.MLP) {
+ outmethod.println(" workScheduleBegin();");
+ }
+ outmethod.println("}");
}
/* This method outputs code for each task. */
outmethod.println("#include \"checkers.h\"");
}
if (state.MLP) {
+ outmethod.println("#include <stdlib.h>");
+ outmethod.println("#include <stdio.h>");
outmethod.println("#include \"mlp_runtime.h\"");
+ outmethod.println("#include \"psemaphore.h\"");
}
+
//Store the sizes of classes & array elements
generateSizeArray(outmethod);
outstructs.println("#define INTPTR int");
outstructs.println("#endif");
outstructs.println("#endif");
+ if( state.MLP ) {
+ outstructs.println("#include \"mlp_runtime.h\"");
+ outstructs.println("#include \"psemaphore.h\"");
+ }
/* Output #defines that the runtime uses to determine type
* numbers for various objects it needs */
if(!state.MULTICORE) {
outclassdefs.println(" void * flagptr;");
} else {
- outclassdefs.println(" int isolate;"); // indicate if this object is shared or not
- outclassdefs.println(" int version;");
- outclassdefs.println(" struct ___Object___ * original;");
- //outclassdefs.println(" int numlocks;"); // array for locks
- outclassdefs.println(" int * lock;");
+ outclassdefs.println(" int version;");
+ outclassdefs.println(" int * lock;"); // lock entry for this obj
+ outclassdefs.println(" int mutex;");
+ outclassdefs.println(" int lockcount;");
+ if(state.MULTICOREGC) {
+ outclassdefs.println(" int marked;");
+ }
}
if(state.OPTIONAL) {
outclassdefs.println(" int numfses;");
}
printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
+ if (state.ARRAYPAD)
+ outclassdefs.println(" int paddingforarray;");
+
outclassdefs.println(" int ___length___;");
outclassdefs.println("};\n");
outclassdefs.println("extern int classsize[];");
outclassdefs.println("extern int nSoftAbortAbort;");
outclassdefs.println("extern int nSoftAbortCommit;");
outclassdefs.println("#ifdef STMSTATS\n");
- outclassdefs.println("extern int typesCausingAbort[];");
+ outclassdefs.println("extern objtypestat_t typesCausingAbort[];");
outclassdefs.println("#endif\n");
}
outclassdefs.print("#endif\n");
outclassdefs.print("int numprefetchsites = " + pa.prefetchsiteid + ";\n");
- outclassdefs.print("int classsize[]={");
Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
cdarray=new ClassDescriptor[state.numClasses()];
while(it.hasNext()) {
ClassDescriptor cd=(ClassDescriptor)it.next();
cdarray[cd.getId()]=cd;
}
- boolean needcomma=false;
- for(int i=0; i<state.numClasses(); i++) {
- if (needcomma)
- outclassdefs.print(", ");
- outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
- needcomma=true;
- }
-
arraytable=new TypeDescriptor[state.numArrays()];
arraytable[id]=td;
}
+
+
+ /* Print out types */
+ outclassdefs.println("/* ");
+ for(int i=0; i<state.numClasses(); i++) {
+ ClassDescriptor cd=cdarray[i];
+ outclassdefs.println(cd +" "+i);
+ }
+
+ for(int i=0; i<state.numArrays(); i++) {
+ TypeDescriptor arraytd=arraytable[i];
+ outclassdefs.println(arraytd.toPrettyString() +" "+(i+state.numClasses()));
+ }
+
+ outclassdefs.println("*/");
+
+
+ outclassdefs.print("int classsize[]={");
+
+ boolean needcomma=false;
+ for(int i=0; i<state.numClasses(); i++) {
+ if (needcomma)
+ outclassdefs.print(", ");
+ outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
+ needcomma=true;
+ }
+
+
for(int i=0; i<state.numArrays(); i++) {
if (needcomma)
outclassdefs.print(", ");
for(int i=0; i<fm.numParameters(); i++) {
TempDescriptor temp=fm.getParameter(i);
TypeDescriptor type=temp.getType();
- if (type.isPtr()&&GENERATEPRECISEGC)
+ if (type.isPtr()&&((GENERATEPRECISEGC) || (this.state.MULTICOREGC)))
objectparams.addPtr(temp);
else
objectparams.addPrim(temp);
for(int i=0; i<fm.numTags(); i++) {
TempDescriptor temp=fm.getTag(i);
- if (GENERATEPRECISEGC)
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
objectparams.addPtr(temp);
else
objectparams.addPrim(temp);
for(int i=0; i<writes.length; i++) {
TempDescriptor temp=writes[i];
TypeDescriptor type=temp.getType();
- if (type.isPtr()&&GENERATEPRECISEGC)
+ if (type.isPtr()&&((GENERATEPRECISEGC) || (this.state.MULTICOREGC)))
objecttemps.addPtr(temp);
else
objecttemps.addPrim(temp);
for(Iterator<TempDescriptor> tmpit=backuptable.get(lb).values().iterator(); tmpit.hasNext();) {
TempDescriptor tmp=tmpit.next();
TypeDescriptor type=tmp.getType();
- if (type.isPtr()&&GENERATEPRECISEGC)
+ if (type.isPtr()&&((GENERATEPRECISEGC) || (this.state.MULTICOREGC)))
objecttemps.addPtr(tmp);
else
objecttemps.addPrim(tmp);
/* Create temp to hold revert table */
if (state.DSM&&(lb.getHasAtomic()||lb.isAtomic())) {
TempDescriptor reverttmp=new TempDescriptor("revertlist", typeutil.getClass(TypeUtil.ObjectClass));
- if (GENERATEPRECISEGC)
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
objecttemps.addPtr(reverttmp);
else
objecttemps.addPrim(reverttmp);
if (!fieldorder.containsKey(cn)) {
Vector fields=new Vector();
fieldorder.put(cn,fields);
- if (sp==null&&!state.TASK) {
- fields.add(cn.getFieldTable().get("cachedCode"));
- }
- Iterator fieldit=cn.getFields();
- while(fieldit.hasNext()) {
- FieldDescriptor fd=(FieldDescriptor)fieldit.next();
- if ((sp==null||!sp.getFieldTable().contains(fd.getSymbol()))&&
- (!fd.getSymbol().equals("cachedCode")||state.TASK))
+ Vector fieldvec=cn.getFieldVec();
+ for(int i=0;i<fieldvec.size();i++) {
+ FieldDescriptor fd=(FieldDescriptor)fieldvec.get(i);
+ if ((sp==null||!sp.getFieldTable().contains(fd.getSymbol())))
fields.add(fd);
}
}
if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
classdefout.println(" void * flagptr;");
} else if (state.MULTICORE) {
- classdefout.println(" int isolate;"); // indicate if this object is shared or not
classdefout.println(" int version;");
- classdefout.println(" struct ___Object___ * original;");
- //classdefout.println(" int numlocks;"); // array for locks
- classdefout.println(" int * lock;");
+ classdefout.println(" int * lock;"); // lock entry for this obj
+ classdefout.println(" int mutex;");
+ classdefout.println(" int lockcount;");
+ if(state.MULTICOREGC) {
+ classdefout.println(" int marked;");
+ }
}
if (state.OPTIONAL) {
classdefout.println(" int numfses;");
private void generateMethodParam(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter output) {
/* Output parameter structure */
- if (GENERATEPRECISEGC) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null ? lb : md);
if ((state.DSM||state.SINGLETM)&&lb!=null)
output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
}
}
-
private void generateMethod(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter headersout, PrintWriter output) {
FlatMethod fm=state.getMethodFlat(md);
generateTempStructs(fm, lb);
generateMethodParam(cn, md, lb, output);
/* Output temp structure */
- if (GENERATEPRECISEGC) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
if (state.DSM||state.SINGLETM)
output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
else
headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
}
boolean printcomma=false;
- if (GENERATEPRECISEGC) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
if (state.DSM||state.SINGLETM) {
headersout.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
} else
TempObject objecttemps=(TempObject) tempstable.get(task);
/* Output parameter structure */
- if (GENERATEPRECISEGC) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
output.println("struct "+task.getSafeSymbol()+"_params {");
output.println(" INTPTR size;");
}
/* Output temp structure */
- if (GENERATEPRECISEGC) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
output.println("struct "+task.getSafeSymbol()+"_locals {");
output.println(" INTPTR size;");
output.println(" void * next;");
headersout.print("void " + task.getSafeSymbol()+"(");
boolean printcomma=false;
- if (GENERATEPRECISEGC) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
} else
headersout.print("void * parameterarray[]");
/***** Generate code for FlatMethod fm. *****/
+ Hashtable<FlatAtomicEnterNode, AtomicRecord> atomicmethodmap;
+ static int atomicmethodcount=0;
+
private void generateFlatMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
if (State.PRINTFLAT)
System.out.println(fm.printMethod());
MethodDescriptor md=fm.getMethod();
-
TaskDescriptor task=fm.getTask();
-
ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
-
ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : md!=null ? md : task);
+
+ HashSet<AtomicRecord> arset=null;
+
+ if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
+ //create map
+ if (atomicmethodmap==null)
+ atomicmethodmap=new Hashtable<FlatAtomicEnterNode, AtomicRecord>();
+
+ //fix these so we get right strings for local variables
+ localsprefixaddr=localsprefix;
+ localsprefixderef=localsprefix+"->";
+ arset=new HashSet<AtomicRecord>();
+
+ //Generate commit methods here
+ for(Iterator<FlatNode> fnit=fm.getNodeSet().iterator();fnit.hasNext();) {
+ FlatNode fn=fnit.next();
+ if (fn.kind()==FKind.FlatAtomicEnterNode&&
+ locality.getAtomic(lb).get(fn.getPrev(0)).intValue()==0) {
+ //We have an atomic enter
+ FlatAtomicEnterNode faen=(FlatAtomicEnterNode) fn;
+ Set<FlatNode> exitset=faen.getExits();
+ //generate header
+ String methodname=md.getSymbol()+(atomicmethodcount++);
+ AtomicRecord ar=new AtomicRecord();
+ ar.name=methodname;
+ arset.add(ar);
+
+ atomicmethodmap.put(faen, ar);
+
+ //build data structure declaration
+ output.println("struct atomicprimitives_"+methodname+" {");
+
+ Set<FlatNode> recordset=delaycomp.livecode(lb);
+ Set<TempDescriptor> liveinto=delaycomp.liveinto(lb, faen, recordset);
+ Set<TempDescriptor> liveout=delaycomp.liveout(lb, faen);
+ Set<TempDescriptor> liveoutvirtualread=delaycomp.liveoutvirtualread(lb, faen);
+ ar.livein=liveinto;
+ ar.reallivein=new HashSet(liveinto);
+ ar.liveout=liveout;
+ ar.liveoutvirtualread=liveoutvirtualread;
+
+ for(Iterator<TempDescriptor> it=liveinto.iterator(); it.hasNext();) {
+ TempDescriptor tmp=it.next();
+ //remove the pointers
+ if (tmp.getType().isPtr()) {
+ it.remove();
+ } else {
+ //let's print it here
+ output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+";");
+ }
+ }
+ for(Iterator<TempDescriptor> it=liveout.iterator(); it.hasNext();) {
+ TempDescriptor tmp=it.next();
+ //remove the pointers
+ if (tmp.getType().isPtr()) {
+ it.remove();
+ } else if (!liveinto.contains(tmp)) {
+ //let's print it here
+ output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+";");
+ }
+ }
+ output.println("};");
+
+ //print out method name
+ output.println("void "+methodname+"(struct "+ cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix+", struct "+ cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals *"+localsprefix+", struct atomicprimitives_"+methodname+" * primitives) {");
+ //build code for commit method
+
+ //first define local primitives
+ Set<TempDescriptor> alltemps=delaycomp.alltemps(lb, faen, recordset);
+ for(Iterator<TempDescriptor> tmpit=alltemps.iterator();tmpit.hasNext();) {
+ TempDescriptor tmp=tmpit.next();
+ if (!tmp.getType().isPtr()) {
+ if (liveinto.contains(tmp)||liveoutvirtualread.contains(tmp)) {
+ //read from live into set
+ output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+"=primitives->"+tmp.getSafeSymbol()+";");
+ } else {
+ //just define
+ output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+";");
+ }
+ }
+ }
+ //turn off write barrier generation
+ wb.turnoff();
+ state.SINGLETM=false;
+ generateCode(faen, fm, lb, exitset, output, false);
+ state.SINGLETM=true;
+ //turn on write barrier generation
+ wb.turnon();
+ output.println("}\n\n");
+ }
+ }
+ }
+ //redefine these back to normal
+
+ localsprefixaddr="&"+localsprefix;
+ localsprefixderef=localsprefix+".";
+
generateHeader(fm, lb, md!=null ? md : task,output);
TempObject objecttemp=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
- if (GENERATEPRECISEGC) {
+ if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
+ for(Iterator<AtomicRecord> arit=arset.iterator();arit.hasNext();) {
+ AtomicRecord ar=arit.next();
+ output.println("struct atomicprimitives_"+ar.name+" primitives_"+ar.name+";");
+ }
+ }
+
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
if (md!=null&&(state.DSM||state.SINGLETM))
output.print(" struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
else if (md!=null&&!(state.DSM||state.SINGLETM))
output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
}
+
+ if( state.MLP ) {
+ if( fm.getNext(0) instanceof FlatSESEEnterNode ) {
+ FlatSESEEnterNode callerSESEplaceholder = (FlatSESEEnterNode) fm.getNext( 0 );
+ if( callerSESEplaceholder != mlpa.getMainSESE() ) {
+ // declare variables for naming static SESE's
+ output.println(" /* static SESE names */");
+ Iterator<SESEandAgePair> pItr = callerSESEplaceholder.getNeededStaticNames().iterator();
+ while( pItr.hasNext() ) {
+ SESEandAgePair p = pItr.next();
+ output.println(" void* "+p+";");
+ }
+
+ // declare variables for tracking dynamic sources
+ output.println(" /* dynamic variable sources */");
+ Iterator<TempDescriptor> dynSrcItr = callerSESEplaceholder.getDynamicVarSet().iterator();
+ while( dynSrcItr.hasNext() ) {
+ TempDescriptor dynSrcVar = dynSrcItr.next();
+ output.println(" void* "+dynSrcVar+"_srcSESE;");
+ output.println(" int "+dynSrcVar+"_srcOffset;");
+ }
+ }
+ }
+ }
+
+
/* Check to see if we need to do a GC if this is a
* multi-threaded program...*/
- if ((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) {
+ if (((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC)
+ || this.state.MULTICOREGC) {
//Don't bother if we aren't in recursive methods...The loops case will catch it
if (callgraph.getAllMethods(md).contains(md)) {
if (state.DSM&&lb.isAtomic())
- output.println("if (needtocollect) checkcollect2(&"+localsprefix+");");
- else
- output.println("if (needtocollect) checkcollect(&"+localsprefix+");");
+ output.println("if (needtocollect) checkcollect2("+localsprefixaddr+");");
+ else if (this.state.MULTICOREGC) {
+ output.println("if(gcflag) gc("+localsprefixaddr+");");
+ } else
+ output.println("if (needtocollect) checkcollect("+localsprefixaddr+");");
}
}
- generateCode(fm.getNext(0), fm, lb, null, output);
+ generateCode(fm.getNext(0), fm, lb, null, output, true);
output.println("}\n\n");
}
+ protected void initializeSESE( FlatSESEEnterNode fsen ) {
+
+ FlatMethod fm = fsen.getfmEnclosing();
+ MethodDescriptor md = fm.getMethod();
+ ClassDescriptor cn = md.getClassDesc();
+
+
+ // Creates bogus method descriptor to index into tables
+ Modifiers modBogus = new Modifiers();
+ MethodDescriptor mdBogus =
+ new MethodDescriptor( modBogus,
+ new TypeDescriptor( TypeDescriptor.VOID ),
+ "sese_"+fsen.getPrettyIdentifier()+fsen.getIdentifier()
+ );
+
+ mdBogus.setClassDesc( fsen.getcdEnclosing() );
+ FlatMethod fmBogus = new FlatMethod( mdBogus, null );
+ fsen.setfmBogus( fmBogus );
+ fsen.setmdBogus( mdBogus );
+
+ Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
+ inSetAndOutSet.addAll( fsen.getInVarSet() );
+ inSetAndOutSet.addAll( fsen.getOutVarSet() );
+
+ // Build paramsobj for bogus method descriptor
+ ParamsObject objectparams = new ParamsObject( mdBogus, tag++ );
+ paramstable.put( mdBogus, objectparams );
+
+ Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
+ while( itr.hasNext() ) {
+ TempDescriptor temp = itr.next();
+ TypeDescriptor type = temp.getType();
+ if( type.isPtr() ) {
+ objectparams.addPtr( temp );
+ } else {
+ objectparams.addPrim( temp );
+ }
+ }
+
+ // Build normal temp object for bogus method descriptor
+ TempObject objecttemps = new TempObject( objectparams, mdBogus, tag++ );
+ tempstable.put( mdBogus, objecttemps );
+
+ for(Iterator nodeit=fsen.getNodeSet().iterator(); nodeit.hasNext();) {
+ FlatNode fn=(FlatNode)nodeit.next();
+ TempDescriptor[] writes=fn.writesTemps();
+ for(int i=0; i<writes.length; i++) {
+ TempDescriptor temp=writes[i];
+ TypeDescriptor type=temp.getType();
+ if (type.isPtr()&&GENERATEPRECISEGC) {
+ objecttemps.addPtr(temp);
+ } else {
+ objecttemps.addPrim(temp);
+ }
+ }
+ }
+ }
+
protected void generateMethodSESE(FlatSESEEnterNode fsen,
- FlatMethod fm,
LocalityBinding lb,
- PrintWriter output) {
+ PrintWriter outputStructs,
+ PrintWriter outputMethHead,
+ PrintWriter outputMethods
+ ) {
+
+ ParamsObject objectparams = (ParamsObject) paramstable.get( fsen.getmdBogus() );
+
+ TempObject objecttemps = (TempObject) tempstable.get( fsen.getmdBogus() );
+
+ // generate locals structure
+ outputStructs.println("struct "+fsen.getcdEnclosing().getSafeSymbol()+fsen.getmdBogus().getSafeSymbol()+"_"+fsen.getmdBogus().getSafeMethodDescriptor()+"_locals {");
+ outputStructs.println(" INTPTR size;");
+ outputStructs.println(" void * next;");
+ for(int i=0; i<objecttemps.numPointers(); i++) {
+ TempDescriptor temp=objecttemps.getPointer(i);
+ if (temp.getType().isNull())
+ outputStructs.println(" void * "+temp.getSafeSymbol()+";");
+ else
+ outputStructs.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
+ }
+ outputStructs.println("};\n");
+
+
+ // generate the SESE record structure
+ outputStructs.println(fsen.getSESErecordName()+" {");
+
+ // data common to any SESE, and it must be placed first so
+ // a module that doesn't know what kind of SESE record this
+ // is can cast the pointer to a common struct
+ outputStructs.println(" SESEcommon common;");
+
+ // then garbage list stuff
+ outputStructs.println(" INTPTR size;");
+ outputStructs.println(" void * next;");
+
+ // in-set source tracking
+ // in-vars that are READY come from parent, don't need anything
+ // stuff STATIC needs a custom SESE pointer for each age pair
+ Iterator<SESEandAgePair> itrStaticInVarSrcs = fsen.getStaticInVarSrcs().iterator();
+ while( itrStaticInVarSrcs.hasNext() ) {
+ SESEandAgePair srcPair = itrStaticInVarSrcs.next();
+ outputStructs.println(" "+srcPair.getSESE().getSESErecordName()+"* "+srcPair+";");
+ }
+
+ // DYNAMIC stuff needs a source SESE ptr and offset
+ Iterator<TempDescriptor> itrDynInVars = fsen.getDynamicInVarSet().iterator();
+ while( itrDynInVars.hasNext() ) {
+ TempDescriptor dynInVar = itrDynInVars.next();
+ outputStructs.println(" void* "+dynInVar+"_srcSESE;");
+ outputStructs.println(" int "+dynInVar+"_srcOffset;");
+ }
+
+ // space for all in and out set primitives
+ Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
+ inSetAndOutSet.addAll( fsen.getInVarSet() );
+ inSetAndOutSet.addAll( fsen.getOutVarSet() );
+
+ Set<TempDescriptor> inSetAndOutSetPrims = new HashSet<TempDescriptor>();
+
+ Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
+ while( itr.hasNext() ) {
+ TempDescriptor temp = itr.next();
+ TypeDescriptor type = temp.getType();
+ if( !type.isPtr() ) {
+ inSetAndOutSetPrims.add( temp );
+ }
+ }
+
+ Iterator<TempDescriptor> itrPrims = inSetAndOutSetPrims.iterator();
+ while( itrPrims.hasNext() ) {
+ TempDescriptor temp = itrPrims.next();
+ TypeDescriptor type = temp.getType();
+ outputStructs.println(" "+temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol()+";");
+ }
+
+ for(int i=0; i<objectparams.numPointers(); i++) {
+ TempDescriptor temp=objectparams.getPointer(i);
+ if (temp.getType().isNull())
+ outputStructs.println(" void * "+temp.getSafeSymbol()+";");
+ else
+ outputStructs.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
+ }
+
+ outputStructs.println("};\n");
+
+
+ // write method declaration to header file
+ outputMethHead.print("void ");
+ outputMethHead.print(fsen.getSESEmethodName()+"(");
+ outputMethHead.print(fsen.getSESErecordName()+"* "+paramsprefix);
+ outputMethHead.println(");\n");
+
+
+ generateFlatMethodSESE( fsen.getfmBogus(),
+ fsen.getcdEnclosing(),
+ fsen,
+ fsen.getFlatExit(),
+ outputMethods );
+ }
+
+ private void generateFlatMethodSESE(FlatMethod fm,
+ ClassDescriptor cn,
+ FlatSESEEnterNode fsen,
+ FlatSESEExitNode seseExit,
+ PrintWriter output
+ ) {
- //output.println( "void _SESE"+fsen.getPrettyIdentifier()+
- //" {\n" );
- //generateCode( fsen.getNext(0), fm, lb, fsen.getFlatExit(), output );
- //output.println( "}\n\n" );
+ MethodDescriptor md=fm.getMethod();
- /*
- output.println("struct sese"+faen.getPrettyIdentifier()+"in {");
- Iterator<TempDescriptor> itr = faen.getInVarSet().iterator();
- while( itr.hasNext() ) {
- TempDescriptor td = itr.next();
- output.println(" "+td+";");
- }
- output.println("}");
+ output.print("void ");
+ output.print(fsen.getSESEmethodName()+"(");
+ output.print(fsen.getSESErecordName()+"* "+paramsprefix);
+ output.println("){\n");
- output.println("struct sese"+faen.getPrettyIdentifier()+"out {");
- itr = faen.getOutVarSet().iterator();
- while( itr.hasNext() ) {
- TempDescriptor td = itr.next();
- output.println(" "+td+";");
- }
- output.println("}");
- */
+ TempObject objecttemp=(TempObject) tempstable.get(md);
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+ output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
+ output.print(objecttemp.numPointers()+",");
+ output.print("(void*) &("+paramsprefix+"->size)");
+ for(int j=0; j<objecttemp.numPointers(); j++)
+ output.print(", NULL");
+ output.println("};");
+ }
+
+ output.println(" /* regular local primitives */");
+ for(int i=0; i<objecttemp.numPrimitives(); i++) {
+ TempDescriptor td=objecttemp.getPrimitive(i);
+ TypeDescriptor type=td.getType();
+ if (type.isNull())
+ output.println(" void * "+td.getSafeSymbol()+";");
+ else if (type.isClass()||type.isArray())
+ output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
+ else
+ output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
+ }
+
+
+ // declare variables for naming static SESE's
+ output.println(" /* static SESE names */");
+ Iterator<SESEandAgePair> pItr = fsen.getNeededStaticNames().iterator();
+ while( pItr.hasNext() ) {
+ SESEandAgePair p = pItr.next();
+ output.println(" void* "+p+";");
+ }
+
+ // declare variables for tracking dynamic sources
+ output.println(" /* dynamic variable sources */");
+ Iterator<TempDescriptor> dynSrcItr = fsen.getDynamicVarSet().iterator();
+ while( dynSrcItr.hasNext() ) {
+ TempDescriptor dynSrcVar = dynSrcItr.next();
+ output.println(" void* "+dynSrcVar+"_srcSESE;");
+ output.println(" int "+dynSrcVar+"_srcOffset;");
+ }
+
+ // declare local temps for in-set primitives, and if it is
+ // a ready-source variable, get the value from the record
+ output.println(" /* local temps for in-set primitives */");
+ Iterator<TempDescriptor> itrInSet = fsen.getInVarSet().iterator();
+ while( itrInSet.hasNext() ) {
+ TempDescriptor temp = itrInSet.next();
+ TypeDescriptor type = temp.getType();
+ if( !type.isPtr() ) {
+ if( fsen.getReadyInVarSet().contains( temp ) ) {
+ output.println(" "+type+" "+temp+" = "+paramsprefix+"->"+temp+";");
+ } else {
+ output.println(" "+type+" "+temp+";");
+ }
+ }
+ }
+
+ // declare local temps for out-set primitives if its not already
+ // in the in-set, and it's value will get written so no problem
+ output.println(" /* local temp for out-set prim, not already in the in-set */");
+ Iterator<TempDescriptor> itrOutSet = fsen.getOutVarSet().iterator();
+ while( itrOutSet.hasNext() ) {
+ TempDescriptor temp = itrOutSet.next();
+ TypeDescriptor type = temp.getType();
+ if( !type.isPtr() && !fsen.getInVarSet().contains( temp ) ) {
+ output.println(" "+type+" "+temp+";");
+ }
+ }
+
+ // copy in-set into place, ready vars were already
+ // copied when the SESE was issued
+ Iterator<TempDescriptor> tempItr;
+
+ // static vars are from a known SESE
+ tempItr = fsen.getStaticInVarSet().iterator();
+ while( tempItr.hasNext() ) {
+ TempDescriptor temp = tempItr.next();
+ VariableSourceToken vst = fsen.getStaticInVarSrc( temp );
+ SESEandAgePair srcPair = new SESEandAgePair( vst.getSESE(), vst.getAge() );
+
+ // can't grab something from this source until it is done
+ output.println(" {");
+ output.println(" SESEcommon* com = (SESEcommon*)"+paramsprefix+"->"+srcPair+";" );
+ output.println(" pthread_mutex_lock( &(com->lock) );");
+ output.println(" while( com->doneExecuting == FALSE ) {");
+ output.println(" pthread_cond_wait( &(com->doneCond), &(com->lock) );");
+ output.println(" }");
+ output.println(" pthread_mutex_unlock( &(com->lock) );");
+
+ output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+
+ " = "+paramsprefix+"->"+srcPair+"->"+vst.getAddrVar()+";");
+
+ output.println(" }");
+ }
+
+ // dynamic vars come from an SESE and src
+ tempItr = fsen.getDynamicInVarSet().iterator();
+ while( tempItr.hasNext() ) {
+ TempDescriptor temp = tempItr.next();
+ TypeDescriptor type = temp.getType();
+
+ // go grab it from the SESE source
+ output.println(" if( "+paramsprefix+"->"+temp+"_srcSESE != NULL ) {");
+
+ // gotta wait until the source is done
+ output.println(" SESEcommon* com = (SESEcommon*)"+paramsprefix+"->"+temp+"_srcSESE;" );
+ output.println(" pthread_mutex_lock( &(com->lock) );");
+ output.println(" while( com->doneExecuting == FALSE ) {");
+ output.println(" pthread_cond_wait( &(com->doneCond), &(com->lock) );");
+ output.println(" }");
+ output.println(" pthread_mutex_unlock( &(com->lock) );");
+
+ String typeStr;
+ if( type.isNull() ) {
+ typeStr = "void*";
+ } else if( type.isClass() || type.isArray() ) {
+ typeStr = "struct "+type.getSafeSymbol()+"*";
+ } else {
+ typeStr = type.getSafeSymbol();
+ }
+
+ output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+
+ " = *(("+typeStr+"*) ("+
+ paramsprefix+"->"+temp+"_srcSESE + "+
+ paramsprefix+"->"+temp+"_srcOffset));");
+
+ // or if the source was our parent, its in the record to grab
+ output.println(" } else {");
+ output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+
+ " = "+paramsprefix+"->"+temp+";");
+ output.println(" }");
+ }
+
+ // Check to see if we need to do a GC if this is a
+ // multi-threaded program...
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+ //Don't bother if we aren't in recursive methods...The loops case will catch it
+ if (callgraph.getAllMethods(md).contains(md)) {
+ if(this.state.MULTICOREGC) {
+ output.println("if(gcflag) gc("+localsprefixaddr+");");
+ } else {
+ output.println("if (needtocollect) checkcollect("+localsprefixaddr+");");
+ }
+ }
+ }
+
+ // initialize thread-local var to a non-zero, invalid address
+ output.println(" seseCaller = (SESEcommon*) 0x2;");
+
+ HashSet<FlatNode> exitset=new HashSet<FlatNode>();
+ exitset.add(seseExit);
+
+ generateCode(fsen.getNext(0), fm, null, exitset, output, true);
+
+ output.println("}\n\n");
+ }
+
+
+ // when a new mlp thread is created for an issued SESE, it is started
+ // by running this method which blocks on a cond variable until
+ // it is allowed to transition to execute. Then a case statement
+ // allows it to invoke the method with the proper SESE body, and after
+ // exiting the SESE method, executes proper SESE exit code before the
+ // thread can be destroyed
+ private void generateSESEinvocationMethod(PrintWriter outmethodheader,
+ PrintWriter outmethod
+ ) {
+
+ outmethodheader.println("void* invokeSESEmethod( void* seseRecord );");
+ outmethod.println( "void* invokeSESEmethod( void* seseRecord ) {");
+ outmethod.println( " int status;");
+ outmethod.println( " char errmsg[128];");
+
+ // generate a case for each SESE class that can be invoked
+ outmethod.println( " switch( *((int*)seseRecord) ) {");
+ outmethod.println( " ");
+ for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
+ FlatSESEEnterNode fsen = seseit.next();
+
+ outmethod.println( " /* "+fsen.getPrettyIdentifier()+" */");
+ outmethod.println( " case "+fsen.getIdentifier()+":");
+ outmethod.println( " "+fsen.getSESEmethodName()+"( seseRecord );");
+
+ if( fsen.equals( mlpa.getMainSESE() ) ) {
+ outmethod.println( " /* work scheduler works forever, explicitly exit */");
+ outmethod.println( " exit( 0 );");
+ }
+
+ outmethod.println( " break;");
+ outmethod.println( "");
+ }
+
+ // default case should never be taken, error out
+ outmethod.println( " default:");
+ outmethod.println( " printf(\"Error: unknown SESE class ID in invoke method.\\n\");");
+ outmethod.println( " exit(-30);");
+ outmethod.println( " break;");
+ outmethod.println( " }");
+ outmethod.println( " return NULL;");
+ outmethod.println( "}\n\n");
}
protected void generateCode(FlatNode first,
FlatMethod fm,
LocalityBinding lb,
- FlatSESEExitNode stop,
- PrintWriter output) {
+ Set<FlatNode> stopset,
+ PrintWriter output, boolean firstpass) {
/* Assign labels to FlatNode's if necessary.*/
- Hashtable<FlatNode, Integer> nodetolabel=assignLabels(first);
-
+ Hashtable<FlatNode, Integer> nodetolabel=assignLabels(first, stopset);
+
+ Set<FlatNode> storeset=null;
+ HashSet<FlatNode> genset=null;
+ Set<FlatNode> unionset=null;
+
+ if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
+ storeset=delaycomp.livecode(lb);
+ genset=new HashSet<FlatNode>();
+ if (firstpass) {
+ genset.addAll(delaycomp.getCannotDelay(lb));
+ genset.addAll(delaycomp.getOther(lb));
+ } else {
+ genset.addAll(delaycomp.getNotReady(lb));
+ }
+ unionset=new HashSet<FlatNode>();
+ unionset.addAll(storeset);
+ unionset.addAll(genset);
+ }
+
/* Do the actual code generation */
FlatNode current_node=null;
HashSet tovisit=new HashSet();
HashSet visited=new HashSet();
- tovisit.add(first);
+ if (!firstpass)
+ tovisit.add(first.getNext(0));
+ else
+ tovisit.add(first);
while(current_node!=null||!tovisit.isEmpty()) {
if (current_node==null) {
current_node=(FlatNode)tovisit.iterator().next();
} else if (tovisit.contains(current_node)) {
tovisit.remove(current_node);
}
- if(current_node==stop) {
- return;
- }
visited.add(current_node);
- if (nodetolabel.containsKey(current_node))
+ if (nodetolabel.containsKey(current_node)) {
output.println("L"+nodetolabel.get(current_node)+":");
+ }
if (state.INSTRUCTIONFAILURE) {
if (state.THREAD||state.DSM||state.SINGLETM) {
output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
} else
output.println("if ((--instructioncount)==0) injectinstructionfailure();");
}
- if (current_node.numNext()==0) {
+ if (current_node.numNext()==0||stopset!=null&&stopset.contains(current_node)) {
output.print(" ");
- generateFlatNode(fm, lb, current_node, output);
+ if (!state.DELAYCOMP||firstpass) {
+ generateFlatNode(fm, lb, current_node, output);
+ } else {
+ //store primitive variables in out set
+ AtomicRecord ar=atomicmethodmap.get((FlatAtomicEnterNode)first);
+ Set<TempDescriptor> liveout=ar.liveout;
+ for(Iterator<TempDescriptor> tmpit=liveout.iterator();tmpit.hasNext();) {
+ TempDescriptor tmp=tmpit.next();
+ output.println("primitives->"+tmp.getSafeSymbol()+"="+tmp.getSafeSymbol()+";");
+ }
+ }
+ if (state.MLP && stopset!=null) {
+ assert first.getPrev( 0 ) instanceof FlatSESEEnterNode;
+ assert current_node instanceof FlatSESEExitNode;
+ FlatSESEEnterNode fsen = (FlatSESEEnterNode) first.getPrev( 0 );
+ FlatSESEExitNode fsxn = (FlatSESEExitNode) current_node;
+ assert fsen.getFlatExit().equals( fsxn );
+ assert fsxn.getFlatEnter().equals( fsen );
+ }
if (current_node.kind()!=FKind.FlatReturnNode) {
output.println(" return;");
}
current_node=null;
} else if(current_node.numNext()==1) {
FlatNode nextnode;
- if (state.MLP && current_node.kind()==FKind.FlatSESEEnterNode) {
+ if (state.MLP &&
+ current_node.kind()==FKind.FlatSESEEnterNode &&
+ !((FlatSESEEnterNode)current_node).getIsCallerSESEplaceholder()
+ ) {
FlatSESEEnterNode fsen = (FlatSESEEnterNode)current_node;
- if( nonSESEpass ) {
- setSESEtoGen.add(fsen);
- fsen.setEnclosingFlatMeth(fm);
- }
+ generateFlatNode(fm, lb, current_node, output);
nextnode=fsen.getFlatExit().getNext(0);
+ } else if (state.DELAYCOMP) {
+ boolean specialprimitive=false;
+ //skip literals...no need to add extra overhead
+ if (storeset!=null&&storeset.contains(current_node)&¤t_node.kind()==FKind.FlatLiteralNode) {
+ TypeDescriptor typedesc=((FlatLiteralNode)current_node).getType();
+ if (!typedesc.isClass()&&!typedesc.isArray()) {
+ specialprimitive=true;
+ }
+ }
+
+ if (genset==null||genset.contains(current_node)||specialprimitive)
+ generateFlatNode(fm, lb, current_node, output);
+ if (storeset!=null&&storeset.contains(current_node)&&!specialprimitive) {
+ TempDescriptor wrtmp=current_node.writesTemps()[0];
+ if (firstpass) {
+ //need to store value written by previous node
+ if (wrtmp.getType().isPtr()) {
+ //only lock the objects that may actually need locking
+ if (recorddc.getNeedTrans(lb, current_node)) {
+ output.println("STOREPTR("+generateTemp(fm, wrtmp,lb)+");");
+ } else {
+ output.println("STOREPTRNOLOCK("+generateTemp(fm, wrtmp,lb)+");");
+ }
+ } else {
+ output.println("STORE"+wrtmp.getType().getSafeDescriptor()+"("+generateTemp(fm, wrtmp, lb)+");");
+ }
+ } else {
+ //need to read value read by previous node
+ if (wrtmp.getType().isPtr()) {
+ output.println("RESTOREPTR("+generateTemp(fm, wrtmp,lb)+");");
+ } else {
+ output.println("RESTORE"+wrtmp.getType().getSafeDescriptor()+"("+generateTemp(fm, wrtmp, lb)+");");
+ }
+ }
+ }
+ nextnode=current_node.getNext(0);
} else {
output.print(" ");
generateFlatNode(fm, lb, current_node, output);
if (visited.contains(nextnode)) {
output.println("goto L"+nodetolabel.get(nextnode)+";");
current_node=null;
- } else
+ } else
current_node=nextnode;
} else if (current_node.numNext()==2) {
/* Branch */
- output.print(" ");
- generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
- if (!visited.contains(current_node.getNext(1)))
- tovisit.add(current_node.getNext(1));
- if (visited.contains(current_node.getNext(0))) {
- output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
- current_node=null;
- } else
- current_node=current_node.getNext(0);
+ if (state.DELAYCOMP) {
+ boolean computeside=false;
+ if (firstpass) {
+ //need to record which way it should go
+ if (genset==null||genset.contains(current_node)) {
+ if (storeset!=null&&storeset.contains(current_node)) {
+ //need to store which way branch goes
+ generateStoreFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+ } else
+ generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+ } else {
+ //which side to execute
+ computeside=true;
+ }
+ } else {
+ if (genset.contains(current_node)) {
+ generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+ } else if (storeset.contains(current_node)) {
+ //need to do branch
+ output.println("RESTOREANDBRANCH(L"+nodetolabel.get(current_node.getNext(1))+");");
+ } else {
+ //which side to execute
+ computeside=true;
+ }
+ }
+ if (computeside) {
+ Set<FlatNode> leftset=DelayComputation.getNext(current_node, 0, unionset, lb,locality, true);
+ int branch=0;
+ if (leftset.size()==0)
+ branch=1;
+ if (visited.contains(current_node.getNext(branch))) {
+ //already visited -- build jump
+ output.println("goto L"+nodetolabel.get(current_node.getNext(branch))+";");
+ current_node=null;
+ } else {
+ current_node=current_node.getNext(branch);
+ }
+ } else {
+ if (!visited.contains(current_node.getNext(1)))
+ tovisit.add(current_node.getNext(1));
+ if (visited.contains(current_node.getNext(0))) {
+ output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
+ current_node=null;
+ } else
+ current_node=current_node.getNext(0);
+ }
+ } else {
+ output.print(" ");
+ generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+ if (!visited.contains(current_node.getNext(1)))
+ tovisit.add(current_node.getNext(1));
+ if (visited.contains(current_node.getNext(0))) {
+ output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
+ current_node=null;
+ } else
+ current_node=current_node.getNext(0);
+ }
} else throw new Error();
}
}
-
/** This method assigns labels to FlatNodes */
-
protected Hashtable<FlatNode, Integer> assignLabels(FlatNode first) {
+ return assignLabels(first, null);
+ }
+
+ protected Hashtable<FlatNode, Integer> assignLabels(FlatNode first, Set<FlatNode> lastset) {
HashSet tovisit=new HashSet();
HashSet visited=new HashSet();
int labelindex=0;
FlatNode fn=(FlatNode)tovisit.iterator().next();
tovisit.remove(fn);
visited.add(fn);
+
+
+ if(lastset!=null&&lastset.contains(fn)) {
+ // if last is not null and matches, don't go
+ // any further for assigning labels
+ continue;
+ }
+
for(int i=0; i<fn.numNext(); i++) {
FlatNode nn=fn.getNext(i);
+
if(i>0) {
//1) Edge >1 of node
nodetolabel.put(nn,new Integer(labelindex++));
MethodDescriptor md=fm.getMethod();
TaskDescriptor task=fm.getTask();
TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
+
if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
//System.out.println("generateTemp returns " + td.getSafeSymbol());
return td.getSafeSymbol();
}
if (objecttemps.isLocalPtr(td)) {
- return localsprefix+"."+td.getSafeSymbol();
+ return localsprefixderef+td.getSafeSymbol();
}
if (objecttemps.isParamPtr(td)) {
return paramsprefix+"->"+td.getSafeSymbol();
}
+
throw new Error();
}
protected void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) {
+
+ // insert pre-node actions from the code plan
+ if( state.MLP ) {
+
+ CodePlan cp = mlpa.getCodePlan( fn );
+ if( cp != null ) {
+
+ FlatSESEEnterNode currentSESE = cp.getCurrentSESE();
+
+ // for each sese and age pair that this parent statement
+ // must stall on, take that child's stall semaphore, the
+ // copying of values comes after the statement
+ Iterator<VariableSourceToken> vstItr = cp.getStallTokens().iterator();
+ while( vstItr.hasNext() ) {
+ VariableSourceToken vst = vstItr.next();
+
+ SESEandAgePair p = new SESEandAgePair( vst.getSESE(), vst.getAge() );
+
+ output.println(" {");
+ output.println(" SESEcommon* common = (SESEcommon*) "+p+";");
+
+ output.println(" pthread_mutex_lock( &(common->lock) );");
+ output.println(" while( common->doneExecuting == FALSE ) {");
+ output.println(" pthread_cond_wait( &(common->doneCond), &(common->lock) );");
+ output.println(" }");
+ output.println(" pthread_mutex_unlock( &(common->lock) );");
+
+ //output.println(" psem_take( &(common->stallSem) );");
+
+ // copy things we might have stalled for
+ output.println(" "+p.getSESE().getSESErecordName()+"* child = ("+
+ p.getSESE().getSESErecordName()+"*) "+p+";");
+
+ Iterator<TempDescriptor> tdItr = cp.getCopySet( vst ).iterator();
+ while( tdItr.hasNext() ) {
+ TempDescriptor td = tdItr.next();
+ FlatMethod fmContext;
+ if( currentSESE.getIsCallerSESEplaceholder() ) {
+ fmContext = currentSESE.getfmEnclosing();
+ } else {
+ fmContext = currentSESE.getfmBogus();
+ }
+ output.println(" "+generateTemp( fmContext, td, null )+
+ " = child->"+vst.getAddrVar().getSafeSymbol()+";");
+ }
+
+ output.println(" }");
+ }
+
+ // for each variable with a dynamic source, stall just for that variable
+ Iterator<TempDescriptor> dynItr = cp.getDynamicStallSet().iterator();
+ while( dynItr.hasNext() ) {
+ TempDescriptor dynVar = dynItr.next();
+
+ // only stall if the dynamic source is not yourself, denoted by src==NULL
+ // otherwise the dynamic write nodes will have the local var up-to-date
+ output.println(" {");
+ output.println(" if( "+dynVar+"_srcSESE != NULL ) {");
+ output.println(" SESEcommon* common = (SESEcommon*) "+dynVar+"_srcSESE;");
+ output.println(" psem_take( &(common->stallSem) );");
+
+ FlatMethod fmContext;
+ if( currentSESE.getIsCallerSESEplaceholder() ) {
+ fmContext = currentSESE.getfmEnclosing();
+ } else {
+ fmContext = currentSESE.getfmBogus();
+ }
+ output.println(" "+generateTemp( fmContext, dynVar, null )+
+ " = *(("+dynVar.getType()+"*) ("+
+ dynVar+"_srcSESE + "+dynVar+"_srcOffset));");
+
+ output.println(" }");
+ output.println(" }");
+ }
+
+ // for each assignment of a variable to rhs that has a dynamic source,
+ // copy the dynamic sources
+ Iterator dynAssignItr = cp.getDynAssigns().entrySet().iterator();
+ while( dynAssignItr.hasNext() ) {
+ Map.Entry me = (Map.Entry) dynAssignItr.next();
+ TempDescriptor lhs = (TempDescriptor) me.getKey();
+ TempDescriptor rhs = (TempDescriptor) me.getValue();
+ output.println(" "+lhs+"_srcSESE = "+rhs+"_srcSESE;");
+ output.println(" "+lhs+"_srcOffset = "+rhs+"_srcOffset;");
+ }
+
+ // for each lhs that is dynamic from a non-dynamic source, set the
+ // dynamic source vars to the current SESE
+ dynItr = cp.getDynAssignCurr().iterator();
+ while( dynItr.hasNext() ) {
+ TempDescriptor dynVar = dynItr.next();
+ output.println(" "+dynVar+"_srcSESE = NULL;");
+ }
+ }
+ }
+
switch(fn.kind()) {
case FKind.FlatAtomicEnterNode:
generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
- return;
+ break;
case FKind.FlatAtomicExitNode:
generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output);
- return;
+ break;
case FKind.FlatInstanceOfNode:
generateFlatInstanceOfNode(fm, lb, (FlatInstanceOfNode)fn, output);
- return;
+ break;
case FKind.FlatSESEEnterNode:
- assert !state.MLP;
- return;
+ generateFlatSESEEnterNode(fm, lb, (FlatSESEEnterNode)fn, output);
+ break;
case FKind.FlatSESEExitNode:
- assert !state.MLP;
- return;
+ generateFlatSESEExitNode(fm, lb, (FlatSESEExitNode)fn, output);
+ break;
+
+ case FKind.FlatWriteDynamicVarNode:
+ generateFlatWriteDynamicVarNode(fm, lb, (FlatWriteDynamicVarNode)fn, output);
+ break;
case FKind.FlatGlobalConvNode:
generateFlatGlobalConvNode(fm, lb, (FlatGlobalConvNode) fn, output);
- return;
+ break;
case FKind.FlatTagDeclaration:
generateFlatTagDeclaration(fm, lb, (FlatTagDeclaration) fn,output);
- return;
+ break;
case FKind.FlatCall:
generateFlatCall(fm, lb, (FlatCall) fn,output);
- return;
+ break;
case FKind.FlatFieldNode:
generateFlatFieldNode(fm, lb, (FlatFieldNode) fn,output);
- return;
+ break;
case FKind.FlatElementNode:
generateFlatElementNode(fm, lb, (FlatElementNode) fn,output);
- return;
+ break;
case FKind.FlatSetElementNode:
generateFlatSetElementNode(fm, lb, (FlatSetElementNode) fn,output);
- return;
+ break;
case FKind.FlatSetFieldNode:
generateFlatSetFieldNode(fm, lb, (FlatSetFieldNode) fn,output);
- return;
+ break;
case FKind.FlatNew:
generateFlatNew(fm, lb, (FlatNew) fn,output);
- return;
+ break;
case FKind.FlatOpNode:
generateFlatOpNode(fm, lb, (FlatOpNode) fn,output);
- return;
+ break;
case FKind.FlatCastNode:
generateFlatCastNode(fm, lb, (FlatCastNode) fn,output);
- return;
+ break;
case FKind.FlatLiteralNode:
generateFlatLiteralNode(fm, lb, (FlatLiteralNode) fn,output);
- return;
+ break;
case FKind.FlatReturnNode:
generateFlatReturnNode(fm, lb, (FlatReturnNode) fn,output);
- return;
+ break;
case FKind.FlatNop:
output.println("/* nop */");
- return;
+ break;
case FKind.FlatExit:
output.println("/* exit */");
- return;
+ break;
case FKind.FlatBackEdge:
- if ((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) {
+ if (((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC)
+ || (this.state.MULTICOREGC)) {
if(state.DSM&&locality.getAtomic(lb).get(fn).intValue()>0) {
- output.println("if (needtocollect) checkcollect2(&"+localsprefix+");");
- } else
- output.println("if (needtocollect) checkcollect(&"+localsprefix+");");
+ output.println("if (needtocollect) checkcollect2("+localsprefixaddr+");");
+ } else if(this.state.MULTICOREGC) {
+ output.println("if (gcflag) gc("+localsprefixaddr+");");
+ } else
+ output.println("if (needtocollect) checkcollect("+localsprefixaddr+");");
} else
output.println("/* nop */");
- return;
+ break;
case FKind.FlatCheckNode:
generateFlatCheckNode(fm, lb, (FlatCheckNode) fn, output);
- return;
+ break;
case FKind.FlatFlagActionNode:
generateFlatFlagActionNode(fm, lb, (FlatFlagActionNode) fn, output);
- return;
+ break;
case FKind.FlatPrefetchNode:
generateFlatPrefetchNode(fm,lb, (FlatPrefetchNode) fn, output);
- return;
+ break;
case FKind.FlatOffsetNode:
generateFlatOffsetNode(fm, lb, (FlatOffsetNode)fn, output);
- return;
+ break;
+
+ default:
+ throw new Error();
}
- throw new Error();
+
+ // insert post-node actions from the code-plan
+ if( state.MLP ) {
+ CodePlan cp = mlpa.getCodePlan( fn );
+
+ if( cp != null ) {
+ }
+ }
}
public void generateFlatOffsetNode(FlatMethod fm, LocalityBinding lb, FlatOffsetNode fofn, PrintWriter output) {
if (state.DSM) {
output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");");
} else {
- output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+");");
+ if ((dc==null)||!state.READSET&&dc.getNeedTrans(lb, fgcn)||state.READSET&&dc.getNeedWriteTrans(lb, fgcn)) {
+ //need to do translation
+ output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+", (void *)("+localsprefixaddr+"));");
+ } else if (state.READSET&&dc.getNeedTrans(lb, fgcn)) {
+ output.println("TRANSREADRD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+");");
+ }
}
} else {
/* Need to convert to OID */
- if (fgcn.doConvert()) {
- output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
- } else {
- output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=NULL;");
+ if ((dc==null)||dc.getNeedSrcTrans(lb,fgcn)) {
+ if (fgcn.doConvert()||(delaycomp!=null&&atomicmethodmap.get(fgcn.getAtomicEnter()).reallivein.contains(fgcn.getSrc()))) {
+ output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
+ } else {
+ output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=NULL;");
+ }
}
}
}
public void generateFlatAtomicEnterNode(FlatMethod fm, LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) {
/* Check to see if we need to generate code for this atomic */
- if (locality==null||locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
+ if (locality==null) {
+ output.println("pthread_mutex_lock(&atomiclock);");
+ return;
+ }
+
+ if (locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
return;
+
+
+ if (state.DELAYCOMP) {
+ AtomicRecord ar=atomicmethodmap.get(faen);
+ //copy in
+ for(Iterator<TempDescriptor> tmpit=ar.livein.iterator();tmpit.hasNext();) {
+ TempDescriptor tmp=tmpit.next();
+ output.println("primitives_"+ar.name+"."+tmp.getSafeSymbol()+"="+tmp.getSafeSymbol()+";");
+ }
+
+ //copy outs that depend on path
+ for(Iterator<TempDescriptor> tmpit=ar.liveoutvirtualread.iterator();tmpit.hasNext();) {
+ TempDescriptor tmp=tmpit.next();
+ if (!ar.livein.contains(tmp))
+ output.println("primitives_"+ar.name+"."+tmp.getSafeSymbol()+"="+tmp.getSafeSymbol()+";");
+ }
+ }
+
/* Backup the temps. */
for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator(); tmpit.hasNext();) {
TempDescriptor tmp=tmpit.next();
public void generateFlatAtomicExitNode(FlatMethod fm, LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) {
/* Check to see if we need to generate code for this atomic */
- if (locality==null||locality.getAtomic(lb).get(faen).intValue()>0)
+ if (locality==null) {
+ output.println("pthread_mutex_unlock(&atomiclock);");
+ return;
+ }
+ if (locality.getAtomic(lb).get(faen).intValue()>0)
return;
//store the revert list before we lose the transaction object
String revertptr=null;
revertptr=generateTemp(fm, reverttable.get(lb),lb);
output.println(revertptr+"=revertlist;");
}
- output.println("if (transCommit()) {");
+ if (state.DELAYCOMP) {
+ AtomicRecord ar=atomicmethodmap.get(faen.getAtomicEnter());
+
+ //do call
+ output.println("if (transCommit((void (*)(void *, void *, void *))&"+ar.name+", &primitives_"+ar.name+", &"+localsprefix+", "+paramsprefix+")) {");
+ } else
+ output.println("if (transCommit()) {");
/* Transaction aborts if it returns true */
output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
if (state.DSM) {
output.println("}");
}
output.println("}");
+ if (state.DELAYCOMP) {
+ //copy out
+ AtomicRecord ar=atomicmethodmap.get(faen.getAtomicEnter());
+ output.println("else {");
+ for(Iterator<TempDescriptor> tmpit=ar.liveout.iterator();tmpit.hasNext();) {
+ TempDescriptor tmp=tmpit.next();
+ output.println(tmp.getSafeSymbol()+"=primitives_"+ar.name+"."+tmp.getSafeSymbol()+";");
+ }
+ output.println("}");
+ }
}
+ public void generateFlatSESEEnterNode( FlatMethod fm,
+ LocalityBinding lb,
+ FlatSESEEnterNode fsen,
+ PrintWriter output
+ ) {
- public void generateSESE(FlatMethod fm, LocalityBinding lb, FlatSESEEnterNode faen, PrintWriter output) {
+ // if MLP flag is off, okay that SESE nodes are in IR graph,
+ // just skip over them and code generates exactly the same
+ if( !state.MLP ) {
+ return;
+ }
+
+ // there may be an SESE in an unreachable method, skip over
+ if( !mlpa.getAllSESEs().contains( fsen ) ) {
+ return;
+ }
+
+ // also, if we have encountered a placeholder, just skip it
+ if( fsen.getIsCallerSESEplaceholder() ) {
+ return;
+ }
+
+ output.println(" {");
+
+ // set up the parent
+ if( fsen == mlpa.getMainSESE() ) {
+ output.println(" SESEcommon* parentCommon = NULL;");
+ } else {
+ if( fsen.getParent() == null ) {
+ System.out.println( "in "+fm+", "+fsen+" has null parent" );
+ }
+ assert fsen.getParent() != null;
+ if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
+ output.println(" SESEcommon* parentCommon = &("+paramsprefix+"->common);");
+ } else {
+ //output.println(" SESEcommon* parentCommon = (SESEcommon*) peekItem( seseCallStack );");
+ output.println(" SESEcommon* parentCommon = seseCaller;");
+ }
+ }
+
+ // before doing anything, lock your own record and increment the running children
+ if( fsen != mlpa.getMainSESE() ) {
+ output.println(" pthread_mutex_lock( &(parentCommon->lock) );");
+ output.println(" ++(parentCommon->numRunningChildren);");
+ output.println(" pthread_mutex_unlock( &(parentCommon->lock) );");
+ }
+
+ // just allocate the space for this record
+ output.println(" "+fsen.getSESErecordName()+"* seseToIssue = ("+
+ fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+
+ fsen.getSESErecordName()+" ) );");
+
+ // and keep the thread-local sese stack up to date
+ //output.println(" addNewItem( seseCallStack, (void*) seseToIssue);");
+
+ // fill in common data
+ output.println(" seseToIssue->common.classID = "+fsen.getIdentifier()+";");
+ output.println(" psem_init( &(seseToIssue->common.stallSem) );");
+
+ output.println(" seseToIssue->common.forwardList = createQueue();");
+ output.println(" seseToIssue->common.unresolvedDependencies = 0;");
+ output.println(" pthread_cond_init( &(seseToIssue->common.doneCond), NULL );");
+ output.println(" seseToIssue->common.doneExecuting = FALSE;");
+ output.println(" pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );");
+ output.println(" seseToIssue->common.numRunningChildren = 0;");
+ output.println(" seseToIssue->common.parent = parentCommon;");
+
+ // all READY in-vars should be copied now and be done with it
+ Iterator<TempDescriptor> tempItr = fsen.getReadyInVarSet().iterator();
+ while( tempItr.hasNext() ) {
+ TempDescriptor temp = tempItr.next();
+
+ // when we are issuing the main SESE or an SESE with placeholder
+ // caller SESE as parent, generate temp child child's eclosing method,
+ // otherwise use the parent's enclosing method as the context
+ boolean useParentContext = false;
+
+ if( fsen != mlpa.getMainSESE() ) {
+ assert fsen.getParent() != null;
+ if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
+ useParentContext = true;
+ }
+ }
+
+ if( useParentContext ) {
+ output.println(" seseToIssue->"+temp+" = "+
+ generateTemp( fsen.getParent().getfmBogus(), temp, null )+";");
+ } else {
+ output.println(" seseToIssue->"+temp+" = "+
+ generateTemp( fsen.getfmEnclosing(), temp, null )+";");
+ }
+ }
+
+ // before potentially adding this SESE to other forwarding lists,
+ // create it's lock and take it immediately
+ output.println(" pthread_mutex_init( &(seseToIssue->common.lock), NULL );");
+ output.println(" pthread_mutex_lock( &(seseToIssue->common.lock) );");
+
+ if( fsen != mlpa.getMainSESE() ) {
+ // count up outstanding dependencies, static first, then dynamic
+ Iterator<SESEandAgePair> staticSrcsItr = fsen.getStaticInVarSrcs().iterator();
+ while( staticSrcsItr.hasNext() ) {
+ SESEandAgePair srcPair = staticSrcsItr.next();
+ output.println(" {");
+ output.println(" SESEcommon* src = (SESEcommon*)"+srcPair+";");
+ output.println(" pthread_mutex_lock( &(src->lock) );");
+ output.println(" if( !isEmpty( src->forwardList ) &&");
+ output.println(" seseToIssue == peekItem( src->forwardList ) ) {");
+ output.println(" printf( \"This shouldnt already be here\\n\");");
+ output.println(" exit( -1 );");
+ output.println(" }");
+ output.println(" if( !src->doneExecuting ) {");
+ output.println(" addNewItem( src->forwardList, seseToIssue );");
+ output.println(" ++(seseToIssue->common.unresolvedDependencies);");
+ output.println(" }");
+ output.println(" pthread_mutex_unlock( &(src->lock) );");
+ output.println(" }");
+
+ // whether or not it is an outstanding dependency, make sure
+ // to pass the static name to the child's record
+ output.println(" seseToIssue->"+srcPair+" = "+srcPair+";");
+ }
+
+ // dynamic sources might already be accounted for in the static list,
+ // so only add them to forwarding lists if they're not already there
+ Iterator<TempDescriptor> dynVarsItr = fsen.getDynamicInVarSet().iterator();
+ while( dynVarsItr.hasNext() ) {
+ TempDescriptor dynInVar = dynVarsItr.next();
+ output.println(" {");
+ output.println(" SESEcommon* src = (SESEcommon*)"+dynInVar+"_srcSESE;");
+
+ // the dynamic source is NULL if it comes from your own space--you can't pass
+ // the address off to the new child, because you're not done executing and
+ // might change the variable, so copy it right now
+ output.println(" if( src != NULL ) {");
+ output.println(" pthread_mutex_lock( &(src->lock) );");
+ output.println(" if( isEmpty( src->forwardList ) ||");
+ output.println(" seseToIssue != peekItem( src->forwardList ) ) {");
+ output.println(" if( !src->doneExecuting ) {");
+ output.println(" addNewItem( src->forwardList, seseToIssue );");
+ output.println(" ++(seseToIssue->common.unresolvedDependencies);");
+ output.println(" }");
+ output.println(" }");
+ output.println(" pthread_mutex_unlock( &(src->lock) );");
+ output.println(" seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;");
+ output.println(" } else {");
+
+ boolean useParentContext = false;
+ if( fsen != mlpa.getMainSESE() ) {
+ assert fsen.getParent() != null;
+ if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
+ useParentContext = true;
+ }
+ }
+ if( useParentContext ) {
+ output.println(" seseToIssue->"+dynInVar+" = "+
+ generateTemp( fsen.getParent().getfmBogus(), dynInVar, null )+";");
+ } else {
+ output.println(" seseToIssue->"+dynInVar+" = "+
+ generateTemp( fsen.getfmEnclosing(), dynInVar, null )+";");
+ }
+
+ output.println(" }");
+ output.println(" }");
+
+ // even if the value is already copied, make sure your NULL source
+ // gets passed so child knows it already has the dynamic value
+ output.println(" seseToIssue->"+dynInVar+"_srcSESE = "+dynInVar+"_srcSESE;");
+ }
+
+ // maintain pointers for for finding dynamic SESE
+ // instances from static names
+ SESEandAgePair p = new SESEandAgePair( fsen, 0 );
+ if( fsen.getParent() != null &&
+ //!fsen.getParent().getIsCallerSESEplaceholder() &&
+ fsen.getParent().getNeededStaticNames().contains( p )
+ ) {
+
+ for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) {
+ SESEandAgePair p1 = new SESEandAgePair( fsen, i );
+ SESEandAgePair p2 = new SESEandAgePair( fsen, i-1 );
+ output.println(" "+p1+" = "+p2+";");
+ }
+ output.println(" "+p+" = seseToIssue;");
+ }
+ }
+
+ // if there were no outstanding dependencies, issue here
+ output.println(" if( seseToIssue->common.unresolvedDependencies == 0 ) {");
+ output.println(" workScheduleSubmit( (void*)seseToIssue );");
+ output.println(" }");
+
+ // release this SESE for siblings to update its dependencies or,
+ // eventually, for it to mark itself finished
+ output.println(" pthread_mutex_unlock( &(seseToIssue->common.lock) );");
+ output.println(" }");
}
+ public void generateFlatSESEExitNode( FlatMethod fm,
+ LocalityBinding lb,
+ FlatSESEExitNode fsexn,
+ PrintWriter output
+ ) {
- public void generateFlatSESEEnterNode(FlatMethod fm, LocalityBinding lb, FlatSESEEnterNode faen, PrintWriter output) {
+ // if MLP flag is off, okay that SESE nodes are in IR graph,
+ // just skip over them and code generates exactly the same
+ if( !state.MLP ) {
+ return;
+ }
+
+ // there may be an SESE in an unreachable method, skip over
+ if( !mlpa.getAllSESEs().contains( fsexn.getFlatEnter() ) ) {
+ return;
+ }
+
+ // also, if we have encountered a placeholder, just jump it
+ if( fsexn.getFlatEnter().getIsCallerSESEplaceholder() ) {
+ return;
+ }
+
+ output.println(" /* SESE exiting */");
+
+ String com = paramsprefix+"->common";
+
+ // this SESE cannot be done until all of its children are done
+ // so grab your own lock with the condition variable for watching
+ // that the number of your running children is greater than zero
+ output.println(" pthread_mutex_lock( &("+com+".lock) );");
+ output.println(" while( "+com+".numRunningChildren > 0 ) {");
+ output.println(" pthread_cond_wait( &("+com+".runningChildrenCond), &("+com+".lock) );");
+ output.println(" }");
+
+ // copy out-set from local temps into the sese record
+ Iterator<TempDescriptor> itr = fsexn.getFlatEnter().getOutVarSet().iterator();
+ while( itr.hasNext() ) {
+ TempDescriptor temp = itr.next();
+ output.println(" "+paramsprefix+
+ "->"+temp.getSafeSymbol()+
+ " = "+temp.getSafeSymbol()+";" );
+ }
+
+ // mark yourself done, your SESE data is now read-only
+ output.println(" "+com+".doneExecuting = TRUE;");
+ output.println(" pthread_cond_signal( &("+com+".doneCond) );");
+ output.println(" pthread_mutex_unlock( &("+com+".lock) );");
+
+ // decrement dependency count for all SESE's on your forwarding list
+ output.println(" while( !isEmpty( "+com+".forwardList ) ) {");
+ output.println(" SESEcommon* consumer = (SESEcommon*) getItem( "+com+".forwardList );");
+ output.println(" pthread_mutex_lock( &(consumer->lock) );");
+ output.println(" --(consumer->unresolvedDependencies);");
+ output.println(" if( consumer->unresolvedDependencies == 0 ) {");
+ output.println(" workScheduleSubmit( (void*)consumer );");
+ output.println(" }");
+ output.println(" pthread_mutex_unlock( &(consumer->lock) );");
+ output.println(" }");
+
+ // if parent is stalling on you, let them know you're done
+ if( fsexn.getFlatEnter() != mlpa.getMainSESE() ) {
+ output.println(" psem_give( &("+paramsprefix+"->common.stallSem) );");
+ }
+
+ // last of all, decrement your parent's number of running children
+ output.println(" if( "+paramsprefix+"->common.parent != NULL ) {");
+ output.println(" pthread_mutex_lock( &("+paramsprefix+"->common.parent->lock) );");
+ output.println(" --("+paramsprefix+"->common.parent->numRunningChildren);");
+ output.println(" pthread_cond_signal( &("+paramsprefix+"->common.parent->runningChildrenCond) );");
+ output.println(" pthread_mutex_unlock( &("+paramsprefix+"->common.parent->lock) );");
+ output.println(" }");
+
+ // this is a thread-only variable that can be handled when critical sese-to-sese
+ // data has been taken care of--set sese pointer to remember self over method
+ // calls to a non-zero, invalid address
+ output.println(" seseCaller = (SESEcommon*) 0x1;");
}
- public void generateFlatSESEExitNode(FlatMethod fm, LocalityBinding lb, FlatSESEExitNode faen, PrintWriter output) {
- //output.println("mlpNotifyExit( (struct SESE*)0 );");
+ public void generateFlatWriteDynamicVarNode( FlatMethod fm,
+ LocalityBinding lb,
+ FlatWriteDynamicVarNode fwdvn,
+ PrintWriter output
+ ) {
+ if( !state.MLP ) {
+ // should node should not be in an IR graph if the
+ // MLP flag is not set
+ throw new Error("Unexpected presence of FlatWriteDynamicVarNode");
+ }
+
+ Hashtable<TempDescriptor, VariableSourceToken> writeDynamic =
+ fwdvn.getVar2src();
+
+ assert writeDynamic != null;
+
+ Iterator wdItr = writeDynamic.entrySet().iterator();
+ while( wdItr.hasNext() ) {
+ Map.Entry me = (Map.Entry) wdItr.next();
+ TempDescriptor refVar = (TempDescriptor) me.getKey();
+ VariableSourceToken vst = (VariableSourceToken) me.getValue();
+
+ FlatSESEEnterNode current = fwdvn.getEnclosingSESE();
+
+ // only do this if the variable in question should be tracked,
+ // meaning that it was explicitly added to the dynamic var set
+ if( !current.getDynamicVarSet().contains( vst.getAddrVar() ) ) {
+ continue;
+ }
+
+ SESEandAgePair instance = new SESEandAgePair( vst.getSESE(), vst.getAge() );
+
+ output.println(" {");
+
+ if( current.equals( vst.getSESE() ) ) {
+ // if the src comes from this SESE, it's a method local variable,
+ // mark src pointer NULL to signify that the var is up-to-date
+ output.println(" "+vst.getAddrVar()+"_srcSESE = NULL;");
+
+ } else {
+ // otherwise we track where it will come from
+ output.println(" "+vst.getAddrVar()+"_srcSESE = "+instance+";");
+ output.println(" "+vst.getAddrVar()+"_srcOffset = (int) &((("+
+ vst.getSESE().getSESErecordName()+"*)0)->"+vst.getAddrVar()+");");
+ }
+
+ output.println(" }");
+ }
}
+
private void generateFlatCheckNode(FlatMethod fm, LocalityBinding lb, FlatCheckNode fcn, PrintWriter output) {
if (state.CONSCHECK) {
String specname=fcn.getSpec();
}
private void generateFlatCall(FlatMethod fm, LocalityBinding lb, FlatCall fc, PrintWriter output) {
+
+ if( state.MLP && !nonSESEpass ) {
+ output.println(" seseCaller = (SESEcommon*)"+paramsprefix+";");
+ }
+
MethodDescriptor md=fc.getMethod();
- ParamsObject objectparams=(ParamsObject)paramstable.get(state.DSM||state.SINGLETM ? locality.getBinding(lb, fc) : md);
+ ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? locality.getBinding(lb, fc) : md);
ClassDescriptor cn=md.getClassDesc();
output.println("{");
- if (GENERATEPRECISEGC) {
- if (state.DSM||state.SINGLETM) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+ if (lb!=null) {
LocalityBinding fclb=locality.getBinding(lb, fc);
output.print(" struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
} else
output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
output.print(objectparams.numPointers());
- output.print(", & "+localsprefix);
+ output.print(", "+localsprefixaddr);
if (md.getThis()!=null) {
output.print(", ");
output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis(),lb));
/* Do we need to do virtual dispatch? */
if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
//no
- if (state.DSM||state.SINGLETM) {
+ if (lb!=null) {
LocalityBinding fclb=locality.getBinding(lb, fc);
output.print(cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
} else {
output.print("(*)(");
boolean printcomma=false;
- if (GENERATEPRECISEGC) {
- if (state.DSM||state.SINGLETM) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+ if (lb!=null) {
LocalityBinding fclb=locality.getBinding(lb, fc);
output.print("struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
} else
}
- if (state.DSM||state.SINGLETM) {
+ if (lb!=null) {
LocalityBinding fclb=locality.getBinding(lb, fc);
output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getLocalityNumber(fclb)+"])");
} else
output.print("(");
boolean needcomma=false;
- if (GENERATEPRECISEGC) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
output.print("&__parameterlist__");
needcomma=true;
}
- if (!GENERATEPRECISEGC) {
+ if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
if (fc.getThis()!=null) {
TypeDescriptor ptd=md.getThis().getType();
if (needcomma)
output.println(dst+"="+ src +"->"+field+ ";");
if (ffn.getField().getType().isPtr()&&locality.getAtomic(lb).get(ffn).intValue()>0&&
- ((dc==null)||dc.getNeedTrans(lb, ffn))&&
locality.getNodePreTempInfo(lb, ffn).get(ffn.getSrc())!=LocalityAnalysis.SCRATCH) {
- output.println("TRANSREAD("+dst+", "+dst+");");
+ if ((dc==null)||(!state.READSET&&dc.getNeedTrans(lb, ffn))||
+ (state.READSET&&dc.getNeedWriteTrans(lb, ffn))) {
+ output.println("TRANSREAD("+dst+", "+dst+", (void *) (" + localsprefixaddr + "));");
+ } else if (state.READSET&&dc.getNeedTrans(lb, ffn)) {
+ output.println("TRANSREADRD("+dst+", "+dst+");");
+ }
}
} else if (state.DSM) {
Integer status=locality.getNodePreTempInfo(lb,ffn).get(ffn.getSrc());
boolean srcptr=fsfn.getSrc().getType().isPtr();
String src=generateTemp(fm,fsfn.getSrc(),lb);
String dst=generateTemp(fm,fsfn.getDst(),lb);
+ output.println("//"+srcptr+" "+fsfn.getSrc().getType().isNull());
if (srcptr&&!fsfn.getSrc().getType().isNull()) {
output.println("{");
if ((dc==null)||dc.getNeedSrcTrans(lb, fsfn)&&
/* Link object into list */
String revertptr=generateTemp(fm, reverttable.get(lb),lb);
output.println(revertptr+"=revertlist;");
- if (GENERATEPRECISEGC)
- output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
+ if (GENERATEPRECISEGC || this.state.MULTICOREGC)
+ output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
else
output.println("COPY_OBJ("+dst+");");
output.println(dst+"->"+nextobjstr+"="+revertptr+";");
String dst=generateTemp(fm, fsfn.getDst(),lb);
output.println("if(!"+dst+"->"+localcopystr+") {");
/* Link object into list */
- if (GENERATEPRECISEGC)
- output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
+ if (GENERATEPRECISEGC || this.state.MULTICOREGC)
+ output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
else
output.println("COPY_OBJ("+dst+");");
output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
if (elementtype.isPtr()&&locality.getAtomic(lb).get(fen).intValue()>0&&
- ((dc==null)||dc.getNeedTrans(lb, fen))&&
locality.getNodePreTempInfo(lb, fen).get(fen.getSrc())!=LocalityAnalysis.SCRATCH) {
- output.println("TRANSREAD("+dst+", "+dst+");");
+ if ((dc==null)||!state.READSET&&dc.getNeedTrans(lb, fen)||state.READSET&&dc.getNeedWriteTrans(lb, fen)) {
+ output.println("TRANSREAD("+dst+", "+dst+", (void *)(" + localsprefixaddr+"));");
+ } else if (state.READSET&&dc.getNeedTrans(lb, fen)) {
+ output.println("TRANSREADRD("+dst+", "+dst+");");
+ }
}
} else if (state.DSM) {
Integer status=locality.getNodePreTempInfo(lb,fen).get(fen.getSrc());
/* Link object into list */
String revertptr=generateTemp(fm, reverttable.get(lb),lb);
output.println(revertptr+"=revertlist;");
- if (GENERATEPRECISEGC)
- output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
+ if ((GENERATEPRECISEGC) || this.state.MULTICOREGC)
+ output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
else
output.println("COPY_OBJ("+dst+");");
output.println(dst+"->"+nextobjstr+"="+revertptr+";");
String dst=generateTemp(fm, fsen.getDst(),lb);
output.println("if(!"+dst+"->"+localcopystr+") {");
/* Link object into list */
- if (GENERATEPRECISEGC)
- output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
+ if (GENERATEPRECISEGC || this.state.MULTICOREGC)
+ output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
else
output.println("COPY_OBJ("+dst+");");
output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
if (locality.getAtomic(lb).get(fn).intValue()>0) {
//inside transaction
- output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarraytrans(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
+ output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarraytrans("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
} else {
//outside transaction
- output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
+ output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
}
} else {
if (locality.getAtomic(lb).get(fn).intValue()>0) {
//inside transaction
- output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newtrans(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
+ output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newtrans("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");
} else {
//outside transaction
- output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
+ output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");
}
}
} else if (fn.getType().isArray()) {
int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
if (fn.isGlobal()&&(state.DSM||state.SINGLETM)) {
output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarrayglobal("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
- } else if (GENERATEPRECISEGC) {
- output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
+ } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+ output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
} else {
output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
}
} else {
- if (fn.isGlobal()) {
+ if (fn.isGlobal()&&(state.DSM||state.SINGLETM)) {
output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newglobal("+fn.getType().getClassDesc().getId()+");");
- } else if (GENERATEPRECISEGC) {
- output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
+ } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+ output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");
} else {
output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
}
}
private void generateFlatTagDeclaration(FlatMethod fm, LocalityBinding lb, FlatTagDeclaration fn, PrintWriter output) {
- if (GENERATEPRECISEGC) {
- output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");");
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+ output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+localsprefixaddr+", "+state.getTagId(fn.getType())+");");
} else {
output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+state.getTagId(fn.getType())+");");
}
else
output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned int)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";");
+ } else if (dc!=null) {
+ output.print(generateTemp(fm, fon.getDest(),lb)+" = ");
+ if (dc.getNeedLeftSrcTrans(lb, fon))
+ output.print("("+generateTemp(fm, fon.getLeft(),lb)+"!=NULL?"+generateTemp(fm, fon.getLeft(),lb)+"->"+oidstr+":NULL)");
+ else
+ output.print(generateTemp(fm, fon.getLeft(),lb));
+ output.print(fon.getOp().toString());
+ if (dc.getNeedRightSrcTrans(lb, fon))
+ output.println("("+generateTemp(fm, fon.getRight(),lb)+"!=NULL?"+generateTemp(fm, fon.getRight(),lb)+"->"+oidstr+":NULL);");
+ else
+ output.println(generateTemp(fm,fon.getRight(),lb)+";");
} else
output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+fon.getOp().toString()+generateTemp(fm,fon.getRight(),lb)+";");
} else if (fon.getOp().getOp()==Operation.ASSIGN)
private void generateFlatCastNode(FlatMethod fm, LocalityBinding lb, FlatCastNode fcn, PrintWriter output) {
/* TODO: Do type check here */
if (fcn.getType().isArray()) {
- throw new Error();
+ output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct ArrayObject *)"+generateTemp(fm,fcn.getSrc(),lb)+";");
} else if (fcn.getType().isClass())
output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc(),lb)+";");
else
if (fln.getValue()==null)
output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
- if (GENERATEPRECISEGC) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
//Stash pointer in case of GC
String revertptr=generateTemp(fm, reverttable.get(lb),lb);
output.println(revertptr+"=revertlist;");
}
- output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
+ output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString("+localsprefixaddr+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
//Stash pointer in case of GC
String revertptr=generateTemp(fm, reverttable.get(lb),lb);
}
}
+ protected void generateStoreFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
+ output.println("STOREANDBRANCH(!"+generateTemp(fm, fcb.getTest(),lb)+", "+label+");");
+ }
+
protected void generateFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
output.println("if (!"+generateTemp(fm, fcb.getTest(),lb)+") goto "+label+";");
}
/** This method generates header information for the method or
* task referenced by the Descriptor des. */
-
private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
+ generateHeader(fm, lb, des, output, false);
+ }
+
+ private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output, boolean addSESErecord) {
/* Print header */
ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des);
MethodDescriptor md=null;
output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
} else
output.print(task.getSafeSymbol()+"(");
-
+
boolean printcomma=false;
- if (GENERATEPRECISEGC) {
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
if (md!=null) {
if (state.DSM||state.SINGLETM) {
output.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
}
output.println(") {");
- } else if (!GENERATEPRECISEGC) {
+ } else if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
/* Imprecise Task */
output.println("void * parameterarray[]) {");
/* Unpack variables */
Iterator tagit=tagtmps.iterator();
while(tagit.hasNext()) {
TempDescriptor tagtmp=(TempDescriptor)tagit.next();
- if (GENERATEPRECISEGC)
- output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
+ output.println("tagclear("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
else
output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
}
Iterator tagit=tagtmps.iterator();
while(tagit.hasNext()) {
TempDescriptor tagtmp=(TempDescriptor)tagit.next();
- if (GENERATEPRECISEGC)
- output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
+ output.println("tagset("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
else
output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp, lb)+", "+generateTemp(fm,tagtmp, lb)+");");
}