private OwnershipAnalysis ownAnalysis;
-
// an implicit SESE is automatically spliced into
// the IR graph around the C main before this analysis--it
// is nothing special except that we can make assumptions
// will fit into the runtime tree of SESEs
private Set<FlatSESEEnterNode> rootSESEs;
- // simply a set of every reachable SESE in the program
+ // simply a set of every reachable SESE in the program, not
+ // including caller placeholder SESEs
private Set<FlatSESEEnterNode> allSESEs;
wdvNodesToSpliceIn = new Hashtable< FlatEdge, FlatWriteDynamicVarNode >();
- FlatMethod fmMain = state.getMethodFlat( tu.getMain() );
+ FlatMethod fmMain = state.getMethodFlat( typeUtil.getMain() );
mainSESE = (FlatSESEEnterNode) fmMain.getNext(0);
mainSESE.setfmEnclosing( fmMain );
mainSESE.setcdEnclosing( fmMain.getMethod().getClassDesc() );
- if( state.MLPDEBUG ) {
- System.out.println( "" );
- }
-
// 1st pass
// run analysis on each method that is actually called
// reachability analysis already computed this so reuse
// and organize them into roots and children
buildForestForward( fm );
}
- if( state.MLPDEBUG ) {
- System.out.println( "\nSESE Hierarchy\n--------------\n" ); printSESEHierarchy();
- }
// 2nd pass, results are saved in FlatSESEEnterNode, so
FlatSESEEnterNode root = rootItr.next();
livenessAnalysisBackward( root,
true,
- null,
- root.getfmEnclosing().getFlatExit() );
+ null );
}
FlatSESEEnterNode root = rootItr.next();
livenessAnalysisBackward( root,
true,
- null,
- root.getfmEnclosing().getFlatExit() );
- }
- if( state.MLPDEBUG ) {
- //System.out.println( "\nLive-In, SESE View\n-------------\n" ); printSESELiveness();
- //System.out.println( "\nLive-In, Root View\n------------------\n"+fmMain.printMethod( livenessRootView ) );
+ null );
}
// by removing reference variables that are not live
pruneVariableResultsWithLiveness( fm );
}
- if( state.MLPDEBUG ) {
- System.out.println( "\nVariable Results-Out\n----------------\n"+fmMain.printMethod( variableResults ) );
- }
// 6th pass
// point, in a forward fixed-point pass
notAvailableForward( fm );
}
- if( state.MLPDEBUG ) {
- //System.out.println( "\nNot Available Results-Out\n---------------------\n"+fmMain.printMethod( notAvailableResults ) );
- }
// 7th pass
// compute a plan for code injections
codePlansForward( fm );
}
- if( state.MLPDEBUG ) {
- System.out.println( "\nCode Plans\n----------\n"+fmMain.printMethod( codePlans ) );
- }
+
// splice new IR nodes into graph after all
// analysis passes are complete
fwdvn.spliceIntoIR();
}
- // detailed per-SESE information
- if( state.MLPDEBUG ) {
- System.out.println( "\nSESE info\n-------------\n" ); printSESEInfo();
- }
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 );
System.out.println( treport );
+
+ if( state.MLPDEBUG ) {
+ try {
+ writeReports( treport );
+ } catch( IOException e ) {}
+ }
}
case FKind.FlatSESEEnterNode: {
FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
- allSESEs.add( fsen );
+ if( !fsen.getIsCallerSESEplaceholder() ) {
+ allSESEs.add( fsen );
+ }
+
fsen.setfmEnclosing( fm );
fsen.setmdEnclosing( fm.getMethod() );
fsen.setcdEnclosing( fm.getMethod().getClassDesc() );
case FKind.FlatReturnNode: {
FlatReturnNode frn = (FlatReturnNode) fn;
- if( !seseStack.empty() ) {
+ if( !seseStack.empty() &&
+ !seseStack.peek().getIsCallerSESEplaceholder()
+ ) {
throw new Error( "Error: return statement enclosed within SESE "+
seseStack.peek().getPrettyIdentifier() );
}
}
}
- private void printSESEHierarchy() {
- Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
- while( rootItr.hasNext() ) {
- FlatSESEEnterNode root = rootItr.next();
- printSESEHierarchyTree( root, 0 );
- }
- System.out.println( "" );
- }
-
- private void printSESEHierarchyTree( FlatSESEEnterNode fsen, int depth ) {
- for( int i = 0; i < depth; ++i ) {
- System.out.print( " " );
- }
- System.out.println( "- "+fsen.getPrettyIdentifier() );
-
- Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
- while( childItr.hasNext() ) {
- FlatSESEEnterNode fsenChild = childItr.next();
- printSESEHierarchyTree( fsenChild, depth + 1 );
- }
- }
-
private void livenessAnalysisBackward( FlatSESEEnterNode fsen,
boolean toplevel,
- Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout,
- FlatExit fexit ) {
+ Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout ) {
// start from an SESE exit, visit nodes in reverse up to
// SESE enter in a fixed-point scheme, where children SESEs
// because child SESE enter node has all necessary info
Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
- FlatSESEExitNode fsexn = fsen.getFlatExit();
- if (toplevel) {
- //handle root SESE
- flatNodesToVisit.add( fexit );
- } else
- flatNodesToVisit.add( fsexn );
- Hashtable<FlatNode, Set<TempDescriptor>> livenessResults=new Hashtable<FlatNode, Set<TempDescriptor>>();
+ if( toplevel ) {
+ flatNodesToVisit.add( fsen.getfmEnclosing().getFlatExit() );
+ } else {
+ flatNodesToVisit.add( fsen.getFlatExit() );
+ }
+
+ Hashtable<FlatNode, Set<TempDescriptor>> livenessResults =
+ new Hashtable< FlatNode, Set<TempDescriptor> >();
+
+ if( toplevel ) {
+ liveout = new Hashtable< FlatSESEExitNode, Set<TempDescriptor> >();
+ }
- if (toplevel==true)
- liveout=new Hashtable<FlatSESEExitNode, Set<TempDescriptor>>();
-
while( !flatNodesToVisit.isEmpty() ) {
FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
flatNodesToVisit.remove( fn );
// remember liveness per node from the root view as the
// global liveness of variables for later passes to use
- if( toplevel == true ) {
+ if( toplevel ) {
livenessRootView.putAll( livenessResults );
}
Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
while( childItr.hasNext() ) {
FlatSESEEnterNode fsenChild = childItr.next();
- livenessAnalysisBackward( fsenChild, false, liveout, null );
+ livenessAnalysisBackward( fsenChild, false, liveout );
}
}
Set<TempDescriptor> liveIn,
FlatSESEEnterNode currentSESE,
boolean toplevel,
- Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout ) {
-
+ Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout
+ ) {
switch( fn.kind() ) {
-
+
case FKind.FlatSESEExitNode:
- if (toplevel==true) {
- FlatSESEExitNode exitn=(FlatSESEExitNode) fn;
- //update liveout set for FlatSESEExitNode
- if (!liveout.containsKey(exitn))
- liveout.put(exitn, new HashSet<TempDescriptor>());
- liveout.get(exitn).addAll(liveIn);
+ if( toplevel ) {
+ FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
+ if( !liveout.containsKey( fsexn ) ) {
+ liveout.put( fsexn, new HashSet<TempDescriptor>() );
+ }
+ liveout.get( fsexn ).addAll( liveIn );
}
// no break, sese exits should also execute default actions
TempDescriptor [] writeTemps = fn.writesTemps();
for( int i = 0; i < writeTemps.length; ++i ) {
liveIn.remove( writeTemps[i] );
-
- if (!toplevel) {
- FlatSESEExitNode exitnode=currentSESE.getFlatExit();
- Set<TempDescriptor> livetemps=liveout.get(exitnode);
- if (livetemps.contains(writeTemps[i])) {
- //write to a live out temp...
- //need to put in SESE liveout set
- currentSESE.addOutVar(writeTemps[i]);
- }
+
+ if( !toplevel ) {
+ FlatSESEExitNode fsexn = currentSESE.getFlatExit();
+ Set<TempDescriptor> livetemps = liveout.get( fsexn );
+ if( livetemps != null &&
+ livetemps.contains( writeTemps[i] ) ) {
+ // write to a live out temp...
+ // need to put in SESE liveout set
+ currentSESE.addOutVar( writeTemps[i] );
+ }
}
}
for( int i = 0; i < readTemps.length; ++i ) {
liveIn.add( readTemps[i] );
}
-
+
Set<TempDescriptor> virtualReadTemps = livenessVirtualReads.get( fn );
if( virtualReadTemps != null ) {
- Iterator<TempDescriptor> vrItr = virtualReadTemps.iterator();
- while( vrItr.hasNext() ) {
- TempDescriptor vrt = vrItr.next();
- liveIn.add( vrt );
- }
- }
+ liveIn.addAll( virtualReadTemps );
+ }
+
} break;
} // end switch
return liveIn;
}
- private void printSESELiveness() {
- Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
- while( rootItr.hasNext() ) {
- FlatSESEEnterNode root = rootItr.next();
- printSESELivenessTree( root );
- }
- 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 printSESEInfo() {
- Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
- while( rootItr.hasNext() ) {
- FlatSESEEnterNode root = rootItr.next();
- printSESEInfoTree( root );
- }
- System.out.println( "" );
- }
-
- private void printSESEInfoTree( FlatSESEEnterNode fsen ) {
-
- System.out.println( "SESE "+fsen.getPrettyIdentifier()+" {" );
-
- System.out.println( " in-set: "+fsen.getInVarSet() );
- Iterator<TempDescriptor> tItr = fsen.getInVarSet().iterator();
- while( tItr.hasNext() ) {
- TempDescriptor inVar = tItr.next();
- if( fsen.getReadyInVarSet().contains( inVar ) ) {
- System.out.println( " (ready) "+inVar );
- }
- if( fsen.getStaticInVarSet().contains( inVar ) ) {
- System.out.println( " (static) "+inVar );
- }
- if( fsen.getDynamicInVarSet().contains( inVar ) ) {
- System.out.println( " (dynamic)"+inVar );
- }
- }
-
- System.out.println( " out-set: "+fsen.getOutVarSet() );
-
- /*
- System.out.println( " static names to track:" );
- 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();
- printSESEInfoTree( fsenChild );
- }
- }
-
private void variableAnalysisForward( FlatMethod fm ) {
-
+
Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
flatNodesToVisit.add( fm );
vstTable.age( currentSESE );
vstTable.assertConsistency();
-
- //vstTable.ownInSet( currentSESE );
- //vstTable.assertConsistency();
} break;
case FKind.FlatSESEExitNode: {
vstTable.remapChildTokens( fsen );
- // liveness virtual reads are things written by an SESE
- // that, if not already, should be added to the in-set
- Set<TempDescriptor> liveIn = currentSESE.getInVarSet();
- Set<TempDescriptor> virLiveIn = vstTable.removeParentAndSiblingTokens( fsen, liveIn );
- virLiveIn.addAll( fsen.getOutVarSet() );
- Set<TempDescriptor> virLiveInOld = livenessVirtualReads.get( fn );
- if( virLiveInOld != null ) {
- virLiveIn.addAll( virLiveInOld );
+ // liveness virtual reads are things that might be
+ // written by an SESE and should be added to the in-set
+ // anything virtually read by this SESE should be pruned
+ // of parent or sibling sources
+ Set<TempDescriptor> liveVars = livenessRootView.get( fn );
+ Set<TempDescriptor> fsenVirtReads = vstTable.calcVirtReadsAndPruneParentAndSiblingTokens( fsen, liveVars );
+ Set<TempDescriptor> fsenVirtReadsOld = livenessVirtualReads.get( fn );
+ if( fsenVirtReadsOld != null ) {
+ fsenVirtReads.addAll( fsenVirtReadsOld );
}
- livenessVirtualReads.put( fn, virLiveIn );
-
- vstTable.assertConsistency();
+ livenessVirtualReads.put( fn, fsenVirtReads );
// then all child out-set tokens are guaranteed
HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
ts.add( lhs );
- forAddition.add( new VariableSourceToken( ts,
- vst.getSESE(),
- vst.getAge(),
- vst.getAddrVar()
- )
- );
+ if( currentSESE.getChildren().contains( vst.getSESE() ) ) {
+ // if the source comes from a child, copy it over
+ forAddition.add( new VariableSourceToken( ts,
+ vst.getSESE(),
+ vst.getAge(),
+ vst.getAddrVar()
+ )
+ );
+ } else {
+ // otherwise, stamp it as us as the source
+ forAddition.add( new VariableSourceToken( ts,
+ currentSESE,
+ new Integer( 0 ),
+ lhs
+ )
+ );
+ }
}
vstTable.addAll( forAddition );
break;
}
-
vstTable.remove( writeTemps[0] );
HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
FlatSESEEnterNode fsen = fsexn.getFlatEnter();
assert currentSESE.getChildren().contains( fsen );
-
- Set<TempDescriptor> liveTemps = livenessRootView.get( fn );
- assert liveTemps != null;
-
- notAvailSet.addAll( liveTemps );
+ notAvailSet.addAll( fsen.getOutVarSet() );
} break;
case FKind.FlatMethod: {
notAvailSet.clear();
}
- /*
- case FKind.FlatCall: {
- FlatCall fc = (FlatCall) fn;
- MethodDescriptor md = fc.getMethod();
- FlatMethod fm = state.getMethodFlat( md );
- for( int i = 0; i < fm.numParameters(); ++i ) {
- TempDescriptor param = fm.getParameter( i );
- notAvailSet.remove( param );
- }
- } break;
- */
-
case FKind.FlatOpNode: {
FlatOpNode fon = (FlatOpNode) fn;
// check the source type of this variable
Integer srcType
= vstTableIn.getRefVarSrcType( readtmp,
- currentSESE,
- currentSESE.getParent() );
+ currentSESE,
+ currentSESE.getParent() );
if( srcType.equals( VarSrcTokTable.SrcType_DYNAMIC ) ) {
// 1) It is not clear statically where this variable will
Iterator<VariableSourceToken> vstItr = staticSet.iterator();
while( vstItr.hasNext() ) {
VariableSourceToken vst = vstItr.next();
-
+
+ // placeholder source tokens are useful results, but
+ // the placeholder static name is never needed
+ if( vst.getSESE().getIsCallerSESEplaceholder() ) {
+ continue;
+ }
+
FlatSESEEnterNode sese = currentSESE;
while( sese != null ) {
sese.addNeededStaticName(
new SESEandAgePair( vst.getSESE(), vst.getAge() )
);
sese.mustTrackAtLeastAge( vst.getAge() );
-
+
sese = sese.getParent();
}
}
if( nextVstTable != null && nextLiveIn != null ) {
Hashtable<TempDescriptor, VariableSourceToken> static2dynamicSet =
- thisVstTable.getStatic2DynamicSet( nextVstTable, nextLiveIn );
+ thisVstTable.getStatic2DynamicSet( nextVstTable,
+ nextLiveIn,
+ currentSESE,
+ currentSESE.getParent()
+ );
if( !static2dynamicSet.isEmpty() ) {
}
}
}
+
+
+ public void writeReports( String timeReport ) throws java.io.IOException {
+
+ BufferedWriter bw = new BufferedWriter( new FileWriter( "mlpReport_summary.txt" ) );
+ bw.write( "MLP Analysis Results\n\n" );
+ bw.write( timeReport+"\n\n" );
+ printSESEHierarchy( bw );
+ bw.write( "\n" );
+ printSESEInfo( bw );
+ bw.close();
+
+ Iterator<Descriptor> methItr = ownAnalysis.descriptorsToAnalyze.iterator();
+ while( methItr.hasNext() ) {
+ MethodDescriptor md = (MethodDescriptor) methItr.next();
+ FlatMethod fm = state.getMethodFlat( md );
+ bw = new BufferedWriter( new FileWriter( "mlpReport_"+
+ md.getClassMethodName()+
+ md.getSafeMethodDescriptor()+
+ ".txt" ) );
+ bw.write( "MLP Results for "+md+"\n-------------------\n");
+ bw.write( "\n\nLive-In, Root View\n------------------\n" +fm.printMethod( livenessRootView ) );
+ bw.write( "\n\nVariable Results-Out\n----------------\n" +fm.printMethod( variableResults ) );
+ bw.write( "\n\nNot Available Results-Out\n---------------------\n"+fm.printMethod( notAvailableResults ) );
+ bw.write( "\n\nCode Plans\n----------\n" +fm.printMethod( codePlans ) );
+ bw.close();
+ }
+ }
+
+ private void printSESEHierarchy( BufferedWriter bw ) throws java.io.IOException {
+ bw.write( "SESE Hierarchy\n--------------\n" );
+ Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
+ while( rootItr.hasNext() ) {
+ FlatSESEEnterNode root = rootItr.next();
+ if( root.getIsCallerSESEplaceholder() ) {
+ if( !root.getChildren().isEmpty() ) {
+ printSESEHierarchyTree( bw, root, 0 );
+ }
+ } else {
+ printSESEHierarchyTree( bw, root, 0 );
+ }
+ }
+ }
+
+ private void printSESEHierarchyTree( BufferedWriter bw,
+ FlatSESEEnterNode fsen,
+ int depth
+ ) throws java.io.IOException {
+ for( int i = 0; i < depth; ++i ) {
+ bw.write( " " );
+ }
+ bw.write( "- "+fsen.getPrettyIdentifier()+"\n" );
+
+ Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
+ while( childItr.hasNext() ) {
+ FlatSESEEnterNode fsenChild = childItr.next();
+ printSESEHierarchyTree( bw, fsenChild, depth + 1 );
+ }
+ }
+
+
+ private void printSESEInfo( BufferedWriter bw ) throws java.io.IOException {
+ bw.write("\nSESE info\n-------------\n" );
+ Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
+ while( rootItr.hasNext() ) {
+ FlatSESEEnterNode root = rootItr.next();
+ if( root.getIsCallerSESEplaceholder() ) {
+ if( !root.getChildren().isEmpty() ) {
+ printSESEInfoTree( bw, root );
+ }
+ } else {
+ printSESEInfoTree( bw, root );
+ }
+ }
+ }
+
+ private void printSESEInfoTree( BufferedWriter bw,
+ FlatSESEEnterNode fsen
+ ) throws java.io.IOException {
+
+ if( !fsen.getIsCallerSESEplaceholder() ) {
+ bw.write( "SESE "+fsen.getPrettyIdentifier()+" {\n" );
+
+ bw.write( " in-set: "+fsen.getInVarSet()+"\n" );
+ Iterator<TempDescriptor> tItr = fsen.getInVarSet().iterator();
+ while( tItr.hasNext() ) {
+ TempDescriptor inVar = tItr.next();
+ if( fsen.getReadyInVarSet().contains( inVar ) ) {
+ bw.write( " (ready) "+inVar+"\n" );
+ }
+ if( fsen.getStaticInVarSet().contains( inVar ) ) {
+ bw.write( " (static) "+inVar+"\n" );
+ }
+ if( fsen.getDynamicInVarSet().contains( inVar ) ) {
+ bw.write( " (dynamic)"+inVar+"\n" );
+ }
+ }
+
+ bw.write( " out-set: "+fsen.getOutVarSet()+"\n" );
+ bw.write( "}\n" );
+ }
+
+ Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
+ while( childItr.hasNext() ) {
+ FlatSESEEnterNode fsenChild = childItr.next();
+ printSESEInfoTree( bw, fsenChild );
+ }
+ }
}
}
- // if we can get a value from the current SESE and the parent
- // or a sibling, just getting from the current SESE suffices now
- // return a set of temps that are virtually read
- public Set<TempDescriptor> removeParentAndSiblingTokens( FlatSESEEnterNode curr,
- Set<TempDescriptor> liveIn ) {
-
- HashSet<TempDescriptor> virtualLiveIn = new HashSet<TempDescriptor>();
-
- FlatSESEEnterNode parent = curr.getParent();
+ // this method is called at the SESE exit of SESE 'curr'
+ // if the sources for a variable written by curr can also
+ // come from curr's parent or curr's siblings then we're not
+ // sure that curr will actually modify the variable. There are
+ // many ways to handle this, but for now, mark the variable as
+ // virtually read so curr insists on having ownership of it
+ // whether it ends up writing to it or not. It will always, then,
+ // appear in curr's out-set.
+ public Set<TempDescriptor>
+ calcVirtReadsAndPruneParentAndSiblingTokens( FlatSESEEnterNode exiter,
+ Set<TempDescriptor> liveVars ) {
+
+ Set<TempDescriptor> virtReadSet = new HashSet<TempDescriptor>();
+
+ FlatSESEEnterNode parent = exiter.getParent();
if( parent == null ) {
- // have no parent or siblings
- return virtualLiveIn;
- }
-
- remove_A_if_B( parent, curr, liveIn, virtualLiveIn );
+ // having no parent means no siblings, too
+ return virtReadSet;
+ }
+ Set<FlatSESEEnterNode> alternateSESEs = new HashSet<FlatSESEEnterNode>();
+ alternateSESEs.add( parent );
Iterator<FlatSESEEnterNode> childItr = parent.getChildren().iterator();
- if( childItr.hasNext() ) {
- FlatSESEEnterNode child = childItr.next();
-
- if( !child.equals( curr ) ) {
- remove_A_if_B( child, curr, liveIn, virtualLiveIn );
+ while( childItr.hasNext() ) {
+ FlatSESEEnterNode sibling = childItr.next();
+ if( !sibling.equals( exiter ) ) {
+ alternateSESEs.add( sibling );
}
}
- assertConsistency();
- return virtualLiveIn;
- }
-
- // if B is also a source for some variable, remove all entries
- // of A as a source for that variable: s is virtual reads
- protected void remove_A_if_B( FlatSESEEnterNode a,
- FlatSESEEnterNode b,
- Set<TempDescriptor> liveInCurrentSESE,
- Set<TempDescriptor> virtualLiveIn ) {
-
+ // VSTs to remove if they are alternate sources for exiter VSTs
+ // whose variables will become virtual reads
Set<VariableSourceToken> forRemoval = new HashSet<VariableSourceToken>();
- Iterator<VariableSourceToken> vstItr = get( a ).iterator();
+ // look at all of this SESE's VSTs at exit...
+ Iterator<VariableSourceToken> vstItr = get( exiter ).iterator();
while( vstItr.hasNext() ) {
- VariableSourceToken vst = vstItr.next();
- Iterator<TempDescriptor> refVarItr = vst.getRefVars().iterator();
+ VariableSourceToken vstExiterSrc = vstItr.next();
+
+ // only interested in tokens that come from our current instance
+ if( vstExiterSrc.getAge() != 0 ) {
+ continue;
+ }
+
+ // for each variable that might come from those sources...
+ Iterator<TempDescriptor> refVarItr = vstExiterSrc.getRefVars().iterator();
while( refVarItr.hasNext() ) {
- TempDescriptor refVar = refVarItr.next();
- Set<VariableSourceToken> bSet = get( b, refVar );
-
- if( !bSet.isEmpty() ) {
- forRemoval.add( vst );
+ TempDescriptor refVar = refVarItr.next();
+
+ // only matters for live variables at SESE exit program point
+ if( !liveVars.contains( refVar ) ) {
+ continue;
+ }
- // mark this variable as a virtual read as well
- virtualLiveIn.add( refVar );
+ // examine other sources for a variable...
+ Iterator<VariableSourceToken> srcItr = get( refVar ).iterator();
+ while( srcItr.hasNext() ) {
+ VariableSourceToken vstPossibleOtherSrc = srcItr.next();
+
+ if( vstPossibleOtherSrc.getSESE().equals( exiter ) &&
+ vstPossibleOtherSrc.getAge() > 0
+ ) {
+ // this is an alternate source if its
+ // an older instance of this SESE
+ virtReadSet.add( refVar );
+ forRemoval.add( vstPossibleOtherSrc );
+
+ } else if( alternateSESEs.contains( vstPossibleOtherSrc.getSESE() ) ) {
+ // this is an alternate source from parent or sibling
+ virtReadSet.add( refVar );
+ forRemoval.add( vstPossibleOtherSrc );
+
+ } else {
+ assert vstPossibleOtherSrc.getSESE().equals( exiter );
+ assert vstPossibleOtherSrc.getAge().equals( 0 );
+ }
}
}
}
VariableSourceToken vst = vstItr.next();
remove( vst );
}
-
assertConsistency();
+
+ return virtReadSet;
}
-
+
// get the set of VST's that come from a child
public Set<VariableSourceToken> getChildrenVSTs( FlatSESEEnterNode curr ) {
}
- // get the set of variables that have exactly one source
- // from the static perspective
- public Set<VariableSourceToken> getStaticSet() {
+ // get a sufficient set of VariableSourceTokens to cover all static sources
+ public Set<VariableSourceToken> getStaticSet( FlatSESEEnterNode current,
+ FlatSESEEnterNode parent
+ ) {
Set<VariableSourceToken> out = new HashSet<VariableSourceToken>();
TempDescriptor var = (TempDescriptor) me.getKey();
HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
- if( s1.size() == 1 ) {
- out.addAll( s1 );
+ if( getRefVarSrcType( var, current, parent ) == SrcType_STATIC ) {
+ out.add( s1.iterator().next() );
}
}
// dynamic source and return them
public Hashtable<TempDescriptor, VariableSourceToken>
getStatic2DynamicSet( VarSrcTokTable nextTable,
- Set<TempDescriptor> nextLiveIn ) {
+ Set<TempDescriptor> nextLiveIn,
+ FlatSESEEnterNode current,
+ FlatSESEEnterNode parent
+ ) {
Hashtable<TempDescriptor, VariableSourceToken> out =
new Hashtable<TempDescriptor, VariableSourceToken>();
// only worth tracking if live
if( nextLiveIn.contains( var ) ) {
- // this is a variable with a static source if it
- // currently has one vst
- if( s1.size() == 1 ) {
- Set<VariableSourceToken> s2 = nextTable.get( var );
-
- // and if in the next table, it is dynamic, then
- // this is a transition point, so
- if( s2.size() > 1 ) {
-
- // remember the variable and the only source
- // it had before crossing the transition
- out.put( var, s1.iterator().next() );
- }
+ if( this.getRefVarSrcType( var, current, parent ) == SrcType_STATIC &&
+ nextTable.getRefVarSrcType( var, current, parent ) == SrcType_DYNAMIC
+ ) {
+ // remember the variable and a static source
+ // it had before crossing the transition
+ out.put( var, s1.iterator().next() );
}
}
}
return SrcType_READY;
}
- // if the variable may have more than one source, or that
- // source is at the summary age, it must be tracked dynamically
- if( srcs.size() > 1 ||
- srcs.iterator().next().getAge() == MLPAnalysis.maxSESEage ) {
+ // if the variable may have more than one source it might be
+ // dynamic, unless all sources are from a placeholder
+ if( srcs.size() > 1 ) {
+ Iterator<VariableSourceToken> itrSrcs = srcs.iterator();
+ VariableSourceToken oneSrc = itrSrcs.next();
+ while( itrSrcs.hasNext() ) {
+ VariableSourceToken anotherSrc = itrSrcs.next();
+ if( !oneSrc.getSESE().equals( anotherSrc.getSESE() ) ||
+ !oneSrc.getAge( ).equals( anotherSrc.getAge( ) )
+ ) {
+ return SrcType_DYNAMIC;
+ }
+ }
+
+ // all sources were same SESE and age, BUT, make sure it's
+ // not a placeholder SESE, who's vars are always ready
+ if( oneSrc.getSESE().getIsCallerSESEplaceholder() ) {
+ return SrcType_READY;
+ }
+
+ return SrcType_DYNAMIC;
+ }
+
+ VariableSourceToken singleSrc = srcs.iterator().next();
+ // if the one source is max age, track it dynamically
+ if( singleSrc.getAge() == MLPAnalysis.maxSESEage ) {
return SrcType_DYNAMIC;
}
// if it has one source that comes from the parent, it's ready
- if( srcs.iterator().next().getSESE() == parent ) {
+ if( singleSrc.getSESE() == parent ) {
return SrcType_READY;
}
+ // if the one source is a placeholder SESE then it's ready
+ if( singleSrc.getSESE().getIsCallerSESEplaceholder() ) {
+ return SrcType_READY;
+ }
+
// otherwise it comes from one source not the parent (sibling)
// and we know exactly which static SESE/age it will come from
return SrcType_STATIC;
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...*/
protected void initializeSESE( FlatSESEEnterNode fsen ) {
-
+
FlatMethod fm = fsen.getfmEnclosing();
MethodDescriptor md = fm.getMethod();
ClassDescriptor cn = md.getClassDesc();
}
}
- HashSet<FlatNode> exitset=new HashSet<FlatNode>();
- exitset.add(seseExit);
+ // 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("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;
generateFlatNode(fm, lb, current_node, output);
nextnode=fsen.getFlatExit().getNext(0);
Iterator<TempDescriptor> tdItr = cp.getCopySet( vst ).iterator();
while( tdItr.hasNext() ) {
TempDescriptor td = tdItr.next();
- output.println(" "+generateTemp( currentSESE.getfmBogus(), td, null )+
+ FlatMethod fmContext;
+ if( currentSESE.getIsCallerSESEplaceholder() ) {
+ fmContext = currentSESE.getfmEnclosing();
+ } else {
+ fmContext = currentSESE.getfmBogus();
+ }
+ output.println(" "+generateTemp( fmContext, td, null )+
" = child->"+vst.getAddrVar().getSafeSymbol()+";");
}
output.println(" if( "+dynVar+"_srcSESE != NULL ) {");
output.println(" SESEcommon* common = (SESEcommon*) "+dynVar+"_srcSESE;");
output.println(" psem_take( &(common->stallSem) );");
- output.println(" "+generateTemp( currentSESE.getfmBogus(), dynVar, null )+
- " = *(("+dynVar.getType()+"*) ("+
- dynVar+"_srcSESE + "+dynVar+"_srcOffset));");
+
+ 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(" }");
}
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 ) {
- output.println(" SESEcommon* parentCommon = &("+paramsprefix+"->common);");
} else {
- //output.println(" SESEcommon* parentCommon = (SESEcommon*) peekItem( seseCallStack );");
- output.println(" SESEcommon* parentCommon = seseCaller;");
+ 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
Iterator<TempDescriptor> tempItr = fsen.getReadyInVarSet().iterator();
while( tempItr.hasNext() ) {
TempDescriptor temp = tempItr.next();
- if( fsen != mlpa.getMainSESE() &&
- fsen.getParent() != null ) {
+
+ // 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 )+";");
+ generateTemp( fsen.getParent().getfmBogus(), temp, null )+";");
} else {
output.println(" seseToIssue->"+temp+" = "+
generateTemp( fsen.getfmEnclosing(), temp, null )+";");
output.println(" pthread_mutex_unlock( &(src->lock) );");
output.println(" seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;");
output.println(" } else {");
- if( fsen.getParent() != null ) {
+
+ 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(" }");
// maintain pointers for for finding dynamic SESE
// instances from static names
SESEandAgePair p = new SESEandAgePair( fsen, 0 );
- if( fsen.getParent() != null &&
- fsen.getParent().getNeededStaticNames().contains( p ) ) {
+ 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 );
return;
}
+ // also, if we have encountered a placeholder, just jump it
+ if( fsexn.getFlatEnter().getIsCallerSESEplaceholder() ) {
+ return;
+ }
+
output.println(" /* SESE exiting */");
String com = paramsprefix+"->common";
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 generateFlatWriteDynamicVarNode( FlatMethod fm,
private void generateFlatCall(FlatMethod fm, LocalityBinding lb, FlatCall fc, PrintWriter output) {
- if( state.MLP ) {
+ if( state.MLP && !nonSESEpass ) {
output.println(" seseCaller = (SESEcommon*)"+paramsprefix+";");
}
Iterator methodit=cn.getMethods();
while(methodit.hasNext()) {
currmd=(MethodDescriptor)methodit.next();
-
- FlatSESEEnterNode mainSESE = null;
- FlatSESEExitNode mainExit = null;
- if (state.MLP && currmd.equals(typeutil.getMain())) {
- SESENode mainTree = new SESENode( "main" );
- mainSESE = new FlatSESEEnterNode( mainTree );
- mainExit = new FlatSESEExitNode ( mainTree );
- mainSESE.setFlatExit ( mainExit );
- mainExit.setFlatEnter( mainSESE );
+
+ // if MLP is on, splice a special SESE in to
+ // enclose the main method, and a special SESE
+ // in around every other method that statically
+ // represents the SESE instance that will call
+ // that method at runtime
+ FlatSESEEnterNode spliceSESE = null;
+ FlatSESEExitNode spliceExit = null;
+ if( state.MLP ) {
+ if( currmd.equals( typeutil.getMain() ) ) {
+ SESENode mainTree = new SESENode( "main" );
+ spliceSESE = new FlatSESEEnterNode( mainTree );
+ spliceExit = new FlatSESEExitNode ( mainTree );
+ spliceSESE.setFlatExit ( spliceExit );
+ spliceExit.setFlatEnter( spliceSESE );
+ } else {
+ SESENode callerSESETree = new SESENode( "caller SESE placeholder" );
+ spliceSESE = new FlatSESEEnterNode( callerSESETree );
+ spliceSESE.setCallerSESEplaceholder();
+ spliceExit = new FlatSESEExitNode ( callerSESETree );
+ spliceSESE.setFlatExit ( spliceExit );
+ spliceExit.setFlatEnter( spliceSESE );
+ }
}
fe=new FlatExit();
aen.addNext(rnflat);
rnflat.addNext(fe);
}
-
- } else if (state.MLP && mainSESE != null) {
- mainSESE.addNext(fn);
- fn=mainSESE;
- FlatReturnNode rnflat=new FlatReturnNode(null);
- np.getEnd().addNext(mainExit);
- mainExit.addNext(rnflat);
- rnflat.addNext(fe);
} else if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) {
FlatReturnNode rnflat=new FlatReturnNode(null);
- np.getEnd().addNext(rnflat);
+ // splice implicit SESE exit after method body
+ if( state.MLP ) {
+ np.getEnd().addNext(spliceExit);
+ spliceExit.addNext(rnflat);
+ } else {
+ np.getEnd().addNext(rnflat);
+ }
rnflat.addNext(fe);
+
+ } else if (np.getEnd()!=null) {
+ // splice implicit SESE exit after method body
+ if( state.MLP ) {
+ FlatReturnNode rnflat=(FlatReturnNode)np.getEnd();
+ np.getEnd().addNext(spliceExit);
+ spliceExit.addNext(fe);
+ }
+ }
+
+ // splice an implicit SESE enter before method body
+ if( state.MLP ) {
+ spliceSESE.addNext(fn);
+ fn=spliceSESE;
}
FlatMethod fm=new FlatMethod(currmd, fe);
protected SESENode treeNode;
protected FlatSESEEnterNode parent;
protected Integer oldestAgeToTrack;
+ protected boolean isCallerSESEplaceholder;
protected Set<FlatSESEEnterNode> children;
fmEnclosing = null;
mdEnclosing = null;
cdEnclosing = null;
+
+ isCallerSESEplaceholder = false;
}
public void rewriteUse() {
mdBogus.getSafeMethodDescriptor()+
"_SESErec";
}
+
+ public void setCallerSESEplaceholder() {
+ isCallerSESEplaceholder = true;
+ }
+
+ public boolean getIsCallerSESEplaceholder() {
+ return isCallerSESEplaceholder;
+ }
+
+
+ public boolean equals( Object o ) {
+ if( o == null ) {
+ return false;
+ }
+
+ if( !(o instanceof FlatSESEEnterNode) ) {
+ return false;
+ }
+
+ FlatSESEEnterNode fsen = (FlatSESEEnterNode) o;
+ return id == fsen.id;
+ }
+
+ public int hashCode() {
+ return 31*id;
+ }
}
}
}
}
+
+ if (state.FLATIRGRAPH) {
+ FlatIRGraph firg = new FlatIRGraph(state,
+ state.FLATIRGRAPHTASKS,
+ state.FLATIRGRAPHUSERMETHODS,
+ state.FLATIRGRAPHLIBMETHODS);
+ }
if (state.OWNERSHIP && !state.MLP) {
CallGraph callGraph = new CallGraph(state);
oa);
}
- if (state.FLATIRGRAPH) {
- FlatIRGraph firg = new FlatIRGraph(state,
- state.FLATIRGRAPHTASKS,
- state.FLATIRGRAPHUSERMETHODS,
- state.FLATIRGRAPHLIBMETHODS);
- }
-
if (state.TAGSTATE) {
CallGraph callgraph=new CallGraph(state);
TagAnalysis taganalysis=new TagAnalysis(state, callgraph);
rm -f *.dot
rm -f *.png
rm -f aliases.txt
+ rm -f mlpReport*txt
+ rm -f results*txt
-echo 'Each single/multi output line pairs should be identical'
+echo 'Each single/multi output line pair should be identical'
+
+echo '' > resultsSingle.txt
+echo '' > resultsMulti.txt
for i in $(seq 5)
do
-
-echo ''
-./testSingle.bin 25
-./testMulti.bin 25
-echo ''
-./testSingle.bin 125
-./testMulti.bin 125
-echo ''
-./testSingle.bin 1255
-./testMulti.bin 1255
-
+echo 'running...'
+./testSingle.bin 10 >> resultsSingle.txt
+./testMulti.bin 10 >> resultsMulti.txt
+./testSingle.bin 25 >> resultsSingle.txt
+./testMulti.bin 25 >> resultsMulti.txt
+./testSingle.bin 125 >> resultsSingle.txt
+./testMulti.bin 125 >> resultsMulti.txt
+./testSingle.bin 1255 >> resultsSingle.txt
+./testMulti.bin 1255 >> resultsMulti.txt
done
+
+echo 'Diffing results'
+diff resultsSingle.txt resultsMulti.txt
public class Test {
- public static void main( String args[] ) {
-
+ public static void main( String args[] ) {
int x = Integer.parseInt( args[0] );
-
doSomeWork( x );
+ nullMethodBodyFinalNode();
}
-
public static void doSomeWork( int x ) {
for( int i = 0; i < x; ++i ) {
sese calc {
sum = calculateStuff( sum, 1, 0 );
}
}
+ sese forceVirtualReal {
+ if( i % 3 == 0 ) {
+ sum = sum + (i % 20);
+ }
+ }
if( i % 2 == 0 ) {
sese change {
for( int k = 0; k < i*2; ++k ) {
}
public static int calculateStuff( int sum, int num, int mode ) {
- int answer;
+ int answer = sum;
if( mode == 0 ) {
sese mode1 {
answer = sum + num;
sese mode3 {
answer = sum / num;
}
- }
+ }
return answer;
}
+ public static void nullMethodBodyFinalNode() {
+ int y = 1;
+ sese nothing {
+ int x = 0;
+ }
+ y = x;
+ if( x > y ) {
+ return;
+ } else {
+ return;
+ }
+ }
+
public static void mightPrint( int x, int i, int sum ) {
if( i == x - 1 ) {
- System.out.println( "sum of integers 0-"+i+" is "+sum );
+ System.out.println( "sum of integers 0-"+i+"("+x+") is "+sum );
}
}
}
-break methods.c:6605
-break methods.c:6606
-break methods.c:6644
-break methods.c:6657
-break methods.c:6755
-break methods.c:6782
-break methods.c:6789
-break methods.c:6793
-break methods.c:6805
-break methods.c:6808
+break methods.c:5763
run 2
BUILDSCRIPT=~/research/Robust/src/buildscript
USEMLP= -mlp 8 2 -mlpdebug # use to turn mlp on and off and make sure rest of build not broken
-BSFLAGS= -nooptimize -debug -garbagestats -mainclass Test -ownership -ownallocdepth 1 -ownwritedots final -enable-assertions -flatirusermethods -ownaliasfile aliases.txt
+BSFLAGS= -nooptimize -debug -garbagestats -mainclass Test -ownership -ownallocdepth 1 -enable-assertions -flatirusermethods #-ownwritedots final -ownaliasfile aliases.txt
all: $(PROGRAM).bin
rm -f *.dot
rm -f *.png
rm -f aliases.txt
+ rm -f mlpReport*
-public class Foo {
- int f;
- public Foo() {}
-}
-
public class Test {
- public static void main( String args[] ) {
-
+ public static void main( String args[] ) {
int x = Integer.parseInt( args[0] );
- //int y = Integer.parseInt( args[1] );
-
- doTheTest( x );
-
- // just for testing root's ability to
- // realize a single exit after all returns
- // DOESN'T WORK!
- //if( false ) {
- // return;
- //}
-
-
- //Foo foo = new Foo();
- //foo.f = x;
- //setTo3( foo );
+ doSomeWork( x );
+ nullMethodBodyFinalNode();
}
- public static void doTheTest( int x ) {
-
- sese wrapper {
-
- for( int i = 0; i < x; ++i ) {
- sese calc {
- int sum = 0;
- for( int j = 0; j <= i; ++j ) {
- sum = sum + j;
- }
+ public static void doSomeWork( int x ) {
+ for( int i = 0; i < x; ++i ) {
+ sese calc {
+ int sum = 0;
+ for( int j = 0; j <= i; ++j ) {
+ sum = calculateStuff( sum, 1, 0 );
+ }
+ }
+ sese forceVirtualReal {
+ if( i % 3 == 0 ) {
+ sum = sum + (i % 20);
}
+ }
+ if( i % 2 == 0 ) {
+ sese change {
+ for( int k = 0; k < i*2; ++k ) {
+ sum = calculateStuff( sum, k, 1 );
+ }
+ sum = sum + 1;
+ }
- sese prnt {
- mightPrint( x, i, sum );
+ for( int l = 0; l < 3; ++l ) {
+ sum = calculateStuff( sum, 2, 2 );
}
}
-
+ sese prnt {
+ mightPrint( x, i, sum );
+ }
}
-
}
- public static void mightPrint( int x, int i, int sum ) {
- if( i == x - 1 ) {
- sese output {
- System.out.println( "sum of integers 0-"+i+" is "+sum );
+ public static int calculateStuff( int sum, int num, int mode ) {
+ int answer = sum;
+ if( mode == 0 ) {
+ sese mode1 {
+ answer = sum + num;
+ }
+ } else if( mode == 1 ) {
+ sese mode2 {
+ answer = sum + (num/2);
+ }
+ } else {
+ sese mode3 {
+ answer = sum / num;
}
+ }
+ return answer;
+ }
+
+ public static void nullMethodBodyFinalNode() {
+ int y = 1;
+ sese nothing {
+ int x = 0;
+ }
+ y = x;
+ if( x > y ) {
+ return;
+ } else {
+ return;
}
}
- /*
- public static void setTo3( Foo foo ) {
- sese func {
- foo.f = 3;
- }
+ public static void mightPrint( int x, int i, int sum ) {
+ if( i == x - 1 ) {
+ System.out.println( "sum of integers 0-"+i+"("+x+") is "+sum );
+ }
}
- */
}