// for injecting code before and/or after a flat node
public class CodePlan {
- private String before;
- private String after;
+ private FlatSESEEnterNode seseToIssue;
- public CodePlan( String before,
- String after ) {
- this.before = before;
- this.after = after;
+
+ public CodePlan() {
+ seseToIssue = null;
}
- public String getBefore() {
- return before;
+
+ public void setSESEtoIssue( FlatSESEEnterNode sese ) {
+ seseToIssue = sese;
}
- public String getAfter() {
- return after;
+ public FlatSESEEnterNode getSESEtoIssue() {
+ return seseToIssue;
}
+
public boolean equals( Object o ) {
if( o == null ) {
return false;
CodePlan cp = (CodePlan) o;
- boolean beforeEq;
- if( before == null ) {
- beforeEq = (cp.before == null);
- } else {
- beforeEq = (before.equals( cp.before ));
- }
-
- boolean afterEq;
- if( after == null ) {
- afterEq = (cp.after == null);
+ boolean issueEq;
+ if( seseToIssue == null ) {
+ issueEq = (cp.seseToIssue == null);
} else {
- afterEq = (after.equals( cp.after ));
+ issueEq = (seseToIssue.equals( cp.seseToIssue ));
}
- return beforeEq && afterEq;
+ return issueEq;
}
public int hashCode() {
- int beforeHC = 1;
- if( before != null ) {
- beforeHC = before.hashCode();
+ int issueHC = 1;
+ if( seseToIssue != null ) {
+ issueHC = seseToIssue.hashCode();
}
- int afterHC = 7;
- if( after != null ) {
- afterHC = after.hashCode();
- }
-
- return beforeHC ^ afterHC;
+ return issueHC;
}
public String toString() {
- return "plan { b="+before+" a="+after+" }";
+ String s = "";
+
+ if( seseToIssue != null ) {
+ s += "[ISSUE "+seseToIssue.getPrettyIdentifier()+"]";
+ }
+
+ return s;
}
}
}
+ if( state.MLPDEBUG ) {
+ System.out.println( "" );
+ //printSESEHierarchy();
+ //printSESELiveness();
+ //System.out.println( fmMain.printMethod( livenessRootView ) );
+ //System.out.println( fmMain.printMethod( variableResults ) );
+ //System.out.println( fmMain.printMethod( notAvailableResults ) );
+ System.out.println( "CODE PLANS\n"+fmMain.printMethod( codePlans ) );
+ }
+
+
double timeEndAnalysis = (double) System.nanoTime();
double dt = (timeEndAnalysis - timeStartAnalysis)/(Math.pow( 10.0, 9.0 ) );
String treport = String.format( "The mlp analysis took %.3f sec.", dt );
}
}
}
-
- if( state.MLPDEBUG ) {
- printSESEForest();
- }
}
private void buildForest_nodeActions( FlatNode fn,
}
}
- private void printSESEForest() {
+ private void printSESEHierarchy() {
// our forest is actually a tree now that
// there is an implicit root SESE
- printSESETree( rootSESE, 0 );
+ printSESEHierarchyTree( rootSESE, 0 );
System.out.println( "" );
}
- private void printSESETree( FlatSESEEnterNode fsen, int depth ) {
+ private void printSESEHierarchyTree( FlatSESEEnterNode fsen, int depth ) {
for( int i = 0; i < depth; ++i ) {
System.out.print( " " );
}
Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
while( childItr.hasNext() ) {
FlatSESEEnterNode fsenChild = childItr.next();
- printSESETree( fsenChild, depth + 1 );
+ printSESEHierarchyTree( fsenChild, depth + 1 );
}
}
- private void livenessAnalysisBackward( FlatSESEEnterNode fsen,
- boolean toplevel,
- Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout,
- FlatExit fexit ) {
+ private void livenessAnalysisBackward( FlatSESEEnterNode fsen,
+ boolean toplevel,
+ Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout,
+ FlatExit fexit ) {
// start from an SESE exit, visit nodes in reverse up to
// SESE enter in a fixed-point scheme, where children SESEs
fsen.addInVarSet( s );
}
- if( state.MLPDEBUG ) {
- System.out.println( "SESE "+fsen.getPrettyIdentifier()+" has in-set:" );
- Iterator<TempDescriptor> tItr = fsen.getInVarSet().iterator();
- while( tItr.hasNext() ) {
- System.out.println( " "+tItr.next() );
- }
- System.out.println( "and out-set:" );
- tItr = fsen.getOutVarSet().iterator();
- while( tItr.hasNext() ) {
- System.out.println( " "+tItr.next() );
- }
- System.out.println( "" );
- }
-
// remember liveness per node from the root view as the
// global liveness of variables for later passes to use
if( toplevel == true ) {
return liveIn;
}
+ private void printSESELiveness() {
+ // our forest is actually a tree now that
+ // there is an implicit root SESE
+ printSESELivenessTree( rootSESE );
+ System.out.println( "" );
+ }
+
+ private void printSESELivenessTree( FlatSESEEnterNode fsen ) {
+
+ System.out.println( "SESE "+fsen.getPrettyIdentifier()+" has in-set:" );
+ Iterator<TempDescriptor> tItr = fsen.getInVarSet().iterator();
+ while( tItr.hasNext() ) {
+ System.out.println( " "+tItr.next() );
+ }
+ System.out.println( "and out-set:" );
+ tItr = fsen.getOutVarSet().iterator();
+ while( tItr.hasNext() ) {
+ System.out.println( " "+tItr.next() );
+ }
+ System.out.println( "" );
+
+
+ Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
+ while( childItr.hasNext() ) {
+ FlatSESEEnterNode fsenChild = childItr.next();
+ printSESELivenessTree( fsenChild );
+ }
+ }
+
private void variableAnalysisForward( FlatMethod fm ) {
default: {
TempDescriptor [] writeTemps = fn.writesTemps();
if( writeTemps.length > 0 ) {
- assert writeTemps.length == 1;
+
+
+ // for now, when writeTemps > 1, make sure
+ // its a call node, programmer enforce only
+ // doing stuff like calling a print routine
+ //assert writeTemps.length == 1;
+ if( writeTemps.length > 1 ) {
+ assert fn.kind() == FKind.FlatCall ||
+ fn.kind() == FKind.FlatMethod;
+ break;
+ }
+
vstTable.remove( writeTemps[0] );
}
}
}
-
- if( state.MLPDEBUG ) {
- //System.out.println( fm.printMethod( livenessRootView ) );
- //System.out.println( fm.printMethod( variableResults ) );
- //System.out.println( fm.printMethod( notAvailableResults ) );
- //System.out.println( fm.printMethod( codePlans ) );
- }
}
private void computeStalls_nodeActions( FlatNode fn,
VarSrcTokTable vstTable,
Set<TempDescriptor> notAvailSet,
FlatSESEEnterNode currentSESE ) {
- String before = null;
- String after = null;
+ CodePlan plan = new CodePlan();
+
switch( fn.kind() ) {
case FKind.FlatSESEEnterNode: {
- FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
+ FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
+ plan.setSESEtoIssue( fsen );
} break;
case FKind.FlatSESEExitNode: {
// assert notAvailSet.containsAll( writeSet );
-
+ /*
for( Iterator<VariableSourceToken> readit = readSet.iterator();
readit.hasNext(); ) {
VariableSourceToken vst = readit.next();
before += "("+vst+" "+readtmp+")";
}
}
+ */
}
} break;
assert nextVstTable != null;
static2dynamicSet.addAll( vstTable.getStatic2DynamicSet( nextVstTable ) );
}
+ /*
Iterator<VariableSourceToken> vstItr = static2dynamicSet.iterator();
while( vstItr.hasNext() ) {
VariableSourceToken vst = vstItr.next();
}
after += "("+vst+")";
}
-
-
- if( before == null ) {
- before = "";
- }
-
- if( after == null ) {
- after = "";
- }
+ */
- codePlans.put( fn, new CodePlan( before, after ) );
+ codePlans.put( fn, plan );
}
}
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 \"mlp_runtime.h\"");
+ }
/* Output Structures */
outputStructs(outstructs);
// Output function prototypes and structures for SESE's and code
if( state.MLP ) {
nonSESEpass = false;
+
+ // 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);
}
+
+ // then write the invokeSESE switch to decouple scheduler
+ // from having to do unique details of sese invocation
+ generateSESEinvocationMethod(outmethodheader, outmethod);
}
if (state.TASK) {
output.println("}\n\n");
}
+ private void generateSESEinvocationMethod(PrintWriter outmethodheader,
+ PrintWriter outmethod
+ ) {
+
+ outmethodheader.println("void invokeSESEmethod( int classID, struct SESErecord* record );");
+ outmethod.println( "void invokeSESEmethod( int classID, struct SESErecord* record ) {");
+ outmethod.println( " switch( classID ) {");
+ outmethod.println( " ");
+ for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
+ FlatSESEEnterNode fsen = seseit.next();
+ outmethod.println( " /* "+fsen.getPrettyIdentifier()+" */");
+ outmethod.println( " case "+fsen.getIdentifier()+":");
+ generateSESEinvocation(fsen, outmethod);
+ outmethod.println( " break;");
+ outmethod.println( "");
+ }
+ 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( "}\n\n");
+ }
+
+ private void generateSESEinvocation(FlatSESEEnterNode fsen,
+ PrintWriter output
+ ) {
+
+ FlatMethod fm = fsen.getEnclosingFlatMeth();
+ MethodDescriptor md = fm.getMethod();
+ ClassDescriptor cn = md.getClassDesc();
+
+ FlatMethod bogusfm = sese2bogusFlatMeth.get(fsen);
+ MethodDescriptor bogusmd = bogusfm.getMethod();
+ ParamsObject objectparams = (ParamsObject)paramstable.get(bogusmd);
+
+ // first copy SESE record into param structure
+
+
+ // then invoke the sese's method
+ output.print(" "+cn.getSafeSymbol()+bogusmd.getSafeSymbol()+"_"+bogusmd.getSafeMethodDescriptor());
+ output.print("(");
+
+ // why doesn't this work?
+ //output.print("("+cn.getSafeSymbol()+bogusmd.getSafeSymbol()+"_"+bogusmd.getSafeMethodDescriptor()+paramsprefix+")");
+ output.print("(struct "+cn.getSafeSymbol()+bogusmd.getSafeSymbol()+"__params*)");
+
+ output.print("&(record->paramStruct)");
+
+ for(int i=0; i<objectparams.numPrimitives(); i++) {
+ TempDescriptor td=objectparams.getPrimitive(i);
+ TypeDescriptor type=td.getType();
+ assert type.isPrimitive();
+ output.print(", record->vars["+i+"].sesetype_"+type.toString());
+ }
+
+ output.println(");");
+ }
+
private void generateFlatMethodSESE(FlatMethod fm,
ClassDescriptor cn,
FlatSESEEnterNode seseEnter,
FlatSESEExitNode stop,
PrintWriter output) {
- //System.out.println( "generating code, stop="+stop );
-
/* Assign labels to FlatNode's if necessary.*/
Hashtable<FlatNode, Integer> nodetolabel=assignLabels(first, stop);
}
visited.add(current_node);
if (nodetolabel.containsKey(current_node)) {
-
- //System.out.println( " *"+current_node+" preceeded with label "+nodetolabel.get(current_node) );
-
output.println("L"+nodetolabel.get(current_node)+":");
}
if (state.INSTRUCTIONFAILURE) {
//2) Join point
nodetolabel.put(nn,new Integer(labelindex++));
}
-
-
- /*
- if( nodetolabel.get(nn) != null ) {
- System.out.println( " "+nn+" has label "+nodetolabel.get(nn) );
- }
- */
-
}
}
return nodetolabel;
#include <stdlib.h>
#include <stdio.h>
#include "mlp_runtime.h"
+#include "Queue.h"
-struct SESE* root;
+struct Queue* issued;
-void mlpIssue();
-
-
-struct SESE* mlpInit() {
- return root;
+void mlpInit() {
+ issued = createQueue();
}
-void mlpEnqueue( struct SESE* sese ) {
- printf( "mlp enqueue\n" );
+void mlpIssue( struct SESErecord* sese ) {
+ addNewItem( issued, (void*) sese );
}
-void mlpBlock( struct SESE* sese ) {
-
+void mlpStall( struct SESErecord* sese ) {
+
}
-void mlpNotifyExit( struct SESE* sese ) {
- printf( "mlp notify exit\n" );
+void mlpNotifyExit( struct SESErecord* sese ) {
+
}
-void mlpIssue() {
-
-}
+/*
+isEmpty(queue)
+void* getItem(queue)
+*/
#ifndef __MLP_RUNTIME__
#define __MLP_RUNTIME__
-struct SESE {
+
+// value mode means the variable's value
+// is present in the SESEvar struct
+#define SESEvar_MODE_VALUE 3001
+
+// static move means the variable's value
+// will come from a statically known SESE
+#define SESEvar_MODE_STATIC 3002
+
+// dynamic mode means the variable's value
+// will come from an SESE, and the exact
+// SESE will be determined at runtime
+#define SESEvar_MODE_DYNAMIC 3003
+
+
+// a forward delcaration for SESEvar
+struct SESErecord;
+
+
+struct SESEvar {
+ unsigned char mode;
+
+ // the value when it is known will be placed
+ // in this location, which can be accessed
+ // as a variety of types
+ union {
+ char sesetype_byte;
+ char sesetype_boolean;
+ short sesetype_short;
+ int sesetype_int;
+ long sesetype_long;
+ char sesetype_char;
+ float sesetype_float;
+ double sesetype_double;
+ };
+ // a statically or dynamically known SESE
+ // to gather the variable's value from
+ struct SESErecord* source;
+ unsigned int index;
};
-struct SESE* mlpInit();
-void mlpEnqueue ( struct SESE* sese );
-void mlpBlock ( struct SESE* sese );
-void mlpNotifyExit( struct SESE* sese );
+struct SESErecord {
+ // the identifier for the class of sese's that
+ // are instances of one particular static code block
+ int classID;
+
+ // not globally unqiue, but each parent ensures that
+ // its children have unique identifiers, including to
+ // the parent itself
+ int instanceID;
+
+ // for state of vars after issue
+ struct SESEvar* vars;
+
+ // when this sese is ready to be invoked,
+ // allocate and fill in this structure, and
+ // the primitives will be passed out of the
+ // above var array at the call site
+ void* paramStruct;
+};
+
+
+void mlpInit();
+
+void mlpIssue ( struct SESErecord* sese );
+void mlpStall ( struct SESErecord* sese );
+void mlpNotifyExit( struct SESErecord* sese );
+
#endif /* __MLP_RUNTIME__ */
int z = n + j;
*/
+
+
+
+
+
+
+
+
+
int x = 1;
int y = 1;
if( true ) {
x = y + 2;
y = 3;
- }
-
+ }
}
+ /*
// shouldn't cause a stall
int z = x;
y = y + 1;
x = x + 1;
z = z + 1;
+ */
+
+ // expecting x=3, y=3
+ System.out.println( "x="+x+", y="+y );
+
+
+
+
//Integer i;
//afunc( i );