>
> fm2relmap;
+ // to support calculation of leaf SESEs (no children even
+ // through method calls) for optimization during code gen
+ protected Set<MethodDescriptor> methodsContainingSESEs;
+
public RBlockRelationAnalysis( State state,
TypeUtil typeUtil,
rootSESEs = new HashSet<FlatSESEEnterNode>();
allSESEs = new HashSet<FlatSESEEnterNode>();
+ methodsContainingSESEs = new HashSet<MethodDescriptor>();
+
fm2relmap =
new Hashtable< FlatMethod, Hashtable< FlatNode, Stack<FlatSESEEnterNode> > >();
descriptorsToAnalyze.add( mdSourceEntry );
analyzeMethods( descriptorsToAnalyze );
+
+ computeLeafSESEs();
}
if( !fsen.getIsCallerSESEplaceholder() ) {
allSESEs.add( fsen );
+ methodsContainingSESEs.add( fm.getMethod() );
}
fsen.setfmEnclosing( fm );
}
}
+
+
+ protected void computeLeafSESEs() {
+ for( Iterator<FlatSESEEnterNode> itr = allSESEs.iterator();
+ itr.hasNext();
+ ) {
+ FlatSESEEnterNode fsen = itr.next();
+
+ boolean hasNoNestedChildren = !fsen.getChildren().isEmpty();
+ boolean hasNoChildrenByCall = !hasChildrenByCall( fsen );
+
+ fsen.setIsLeafSESE( hasNoNestedChildren &&
+ hasNoChildrenByCall );
+ }
+ }
+
+
+ protected boolean hasChildrenByCall( FlatSESEEnterNode fsen ) {
+
+ // visit every flat node in SESE body, find method calls that
+ // may transitively call methods with SESEs enclosed
+ Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
+ flatNodesToVisit.add( fsen );
+
+ Set<FlatNode> visited = new HashSet<FlatNode>();
+
+ while( !flatNodesToVisit.isEmpty() ) {
+ Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
+ FlatNode fn = fnItr.next();
+
+ flatNodesToVisit.remove( fn );
+ visited.add( fn );
+
+ if( fn.kind() == FKind.FlatCall ) {
+ FlatCall fc = (FlatCall) fn;
+ MethodDescriptor mdCallee = fc.getMethod();
+ Set reachable = new HashSet();
+
+ reachable.addAll( callGraph.getAllMethods( mdCallee ) );
+ reachable.retainAll( methodsContainingSESEs );
+
+ if( !reachable.isEmpty() ) {
+ return true;
+ }
+ }
+
+ if( fn == fsen.getFlatExit() ) {
+ // don't enqueue any futher nodes
+ continue;
+ }
+
+ for( int i = 0; i < fn.numNext(); i++ ) {
+ FlatNode nn = fn.getNext( i );
+
+ if( !visited.contains( nn ) ) {
+ flatNodesToVisit.add( nn );
+ }
+ }
+ }
+
+ return false;
+ }
+
}
protected Integer oldestAgeToTrack;
protected boolean isCallerSESEplaceholder;
+ protected static final int ISLEAF_UNINIT = 1;
+ protected static final int ISLEAF_FALSE = 2;
+ protected static final int ISLEAF_TRUE = 3;
+ protected int isLeafSESE;
+
protected Set<FlatSESEEnterNode> children;
protected Set<TempDescriptor> inVars;
isCallerSESEplaceholder = false;
+ isLeafSESE = ISLEAF_UNINIT;
+
firstDepRecField = null;
numDepRecs = 0;
}
public void addInVarForDynamicCoarseConflictResolution(TempDescriptor inVar) {
inVarsForDynamicCoarseConflictResolution.add(inVar);
}
+
+
+ public void setIsLeafSESE( boolean isLeaf ) {
+ //protected static final int ISLEAF_UNINIT = 1;
+ if( isLeaf ) {
+ isLeafSESE = ISLEAF_TRUE;
+ } else {
+ isLeafSESE = ISLEAF_FALSE;
+ }
+ }
+
+ public boolean getIsLeafSESE() {
+ if( isLeafSESE == ISLEAF_UNINIT ) {
+ throw new Error( "isLeafSESE uninitialized" );
+ }
+
+ return isLeafSESE == ISLEAF_TRUE;
+ }
}