From: jjenista Date: Mon, 11 Feb 2008 21:51:21 +0000 (+0000) Subject: Added generation of method dependency map X-Git-Tag: preEdgeChange~286 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3f39bdff42d4624bca74e8c46041adb03d1207ad;p=IRC.git Added generation of method dependency map --- diff --git a/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java b/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java index 314b9d0c..511c48ea 100644 --- a/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java +++ b/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java @@ -8,28 +8,133 @@ import java.io.*; public class OwnershipAnalysis { - + // from the compiler private State state; - private HashSet visited; - private HashSet toVisit; - - private int labelindex; - private Hashtable flatnodetolabel; - - private Hashtable flatNodeToOwnershipGraph; + private int allocationDepthK; + + // Use these data structures to track progress of + // processing all methods in the program + private HashSet flatMethodsToVisit; + private Hashtable mapFlatMethodToCompleteOwnershipGraph; + private Hashtable > mapMethodToDependentMethods; + + // Use these data structures to track progress of one pass of + // processing the FlatNodes in a FlatMethod + private HashSet flatNodesToVisit; + private Hashtable mapFlatNodeToOwnershipGraph; + private HashSet returnNodesToCombineForComplete; + + // for generating unique ownership node ID's throughout the + // ownership analysis + static private int uniqueIDcount = 0; + + static public Integer generateUniqueID() { + ++uniqueIDcount; + return new Integer( uniqueIDcount ); + } - private int newDepthK; // this analysis generates an ownership graph for every task // in the program public OwnershipAnalysis( State state ) throws java.io.IOException { - this.state=state; - this.newDepthK = 3; - analyzeTasks(); + this.state = state; + this.allocationDepthK = 3; + + // the analyzeMethods() function will keep analyzing the contents + // of flatMethodsToVisit until it is empty. The following function + // will generate the method dependencies and put every task (subclass + // of method) in flatMethodsToVisit so the ownership analysis will + // cover at least every task, but might not analyze every method of + // the program if there is no dependency chain back to a task + prepareForAndEnqueueTasks(); + + // as mentioned above, analyze methods one-by-one, possibly revisiting + // a method if the methods that it calls are updated + analyzeMethods(); + } + + // run once per program analysis + private void prepareForAndEnqueueTasks() { + flatMethodsToVisit = new HashSet(); + + mapFlatMethodToCompleteOwnershipGraph = + new Hashtable(); + + mapMethodToDependentMethods = + new Hashtable >(); + + // once the dependency map is generated here it + // doesn't need to be modified anymore. It is + // used when a method is updated to enqueue the + // methods that are dependent on the result. They + // may or may not have a different analysis outcome + + // first put all the tasks into the dependency map + Iterator itrTasks = state.getTaskSymbolTable().getDescriptorsIterator(); + while( itrTasks.hasNext() ) { + TaskDescriptor td = itrTasks.next(); + FlatMethod fm = state.getMethodFlat( td ); + + searchFlatMethodForCallNodes( td, fm ); + } + + // then put all the methods of classes into the map + } + + // called on each task and class method before ownership + // analysis is started so the method dependency map can + // be generated + private void searchFlatMethodForCallNodes( Descriptor caller, FlatMethod fm ) { + // borrow this data structure before the ownership + // analysis proper begins in order to search the IR + flatNodesToVisit = new HashSet(); + + flatNodesToVisit.add( fm ); + + while( !flatNodesToVisit.isEmpty() ) { + FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next(); + flatNodesToVisit.remove( fn ); + + if( fn.kind() == FKind.FlatClass ) { + FlatCall fc = (FlatCall) fn; + addMethodDependency( caller, fc.getMethod() ); + } + } + } + + // supports creation of the method dependency map + private void addMethodDependency( Descriptor caller, Descriptor callee ) { + + // the caller is calling the callee so the caller's + // analysis depends on the callee's analysis, + // therefore build a map that looks like this: + // callee: + // + // and only add the dependency if it doesn't already exist + + if( !mapMethodToDependentMethods.containsKey( callee ) ) { + // there is no map entry for this callee, so add it with + // just the caller as the only dependent method and return + mapMethodToDependentMethods.put( callee, caller ); + return; + } + + // if there is already an entry for the callee, check to see + // if the caller is already in the value for that map entry + HashSet dependentMethods = (HashSet) mapMethodToDependentMethods.get( callee ); + + if( !dependentMethods.contains( caller ) ) { + // the caller is not in the set of dependent methods for + // this callee, so add it and return + dependentMethods.add( caller ); + return; + } + + // the dependency was already there, do nothing } - public void analyzeTasks() throws java.io.IOException { + private void analyzeMethods() throws java.io.IOException { for( Iterator it_tasks=state.getTaskSymbolTable().getDescriptorsIterator(); it_tasks.hasNext(); ) { @@ -49,23 +154,12 @@ public class OwnershipAnalysis { labelindex = 0; labelFlatNodes( fm ); - String taskname = td.getSymbol(); - analyzeFlatIRGraph( fm, taskname ); + String methodname = td.getSymbol(); + analyzeFlatIRGraph( fm, methodname ); } } - private void labelFlatNodes( FlatNode fn ) { - visited.add( fn ); - flatnodetolabel.put( fn, new Integer( labelindex++ ) ); - for( int i = 0; i < fn.numNext(); i++ ) { - FlatNode nn = fn.getNext( i ); - if( !visited.contains( nn ) ) { - labelFlatNodes( nn ); - } - } - } - - private OwnershipGraph getGraphFromFlat( FlatNode fn ) { + private OwnershipGraph getGraphFromFlatNode( FlatNode fn ) { if( !flatNodeToOwnershipGraph.containsKey( fn ) ) { flatNodeToOwnershipGraph.put( fn, new OwnershipGraph( newDepthK ) ); } @@ -73,32 +167,52 @@ public class OwnershipAnalysis { return flatNodeToOwnershipGraph.get( fn ); } - private void setGraphForFlat( FlatNode fn, OwnershipGraph og ) { + private void setGraphForFlatNode( FlatNode fn, OwnershipGraph og ) { flatNodeToOwnershipGraph.put( fn, og ); } - private void analyzeFlatIRGraph( FlatMethod flatm, String taskname ) throws java.io.IOException { - visited=new HashSet(); + private void analyzeFlatMethod( FlatMethod flatm, String methodname ) throws java.io.IOException { toVisit=new HashSet(); toVisit.add( flatm ); while( !toVisit.isEmpty() ) { - FlatNode fn = (FlatNode)toVisit.iterator().next(); + FlatNode fn = (FlatNode) toVisit.iterator().next(); toVisit.remove( fn ); - visited.add( fn ); // perform this node's contributions to the ownership // graph on a new copy, then compare it to the old graph // at this node to see if anything was updated. OwnershipGraph og = new OwnershipGraph( newDepthK ); - // start by merging all incoming node's graphs + // start by merging all node's parents' graphs for( int i = 0; i < fn.numPrev(); ++i ) { FlatNode pn = fn.getPrev( i ); - OwnershipGraph ogParent = getGraphFromFlat( pn ); + OwnershipGraph ogParent = getGraphFromFlatNode( pn ); og.merge( ogParent ); } + analyzeFlatNode( fn ); + + // if the results of the new graph are different from + // the current graph at this node, replace the graph + // with the update and enqueue the children for + // processing + OwnershipGraph ogOld = getGraphFromFlatNode( fn ); + + if( !og.equals( ogOld ) ) { + setGraphForFlatNode( fn, og ); + + for( int i = 0; i < fn.numNext(); i++ ) { + FlatNode nn = fn.getNext( i ); + visited.remove( nn ); + toVisit.add( nn ); + } + } + } + } + + + private void analyzeFlatNode( FlatNode fn, String methodname ) { TempDescriptor src; TempDescriptor dst; FieldDescriptor fld; @@ -173,40 +287,24 @@ public class OwnershipAnalysis { case FKind.FlatReturnNode: nodeDescription = "Return"; writeGraph = true; - og.writeCondensedAnalysis( makeCondensedAnalysisName( taskname, flatnodetolabel.get(fn) ) ); + og.writeCondensedAnalysis( makeCondensedAnalysisName( methodname, flatnodetolabel.get(fn) ) ); break; } if( writeGraph ) { - og.writeGraph( makeNodeName( taskname, + og.writeGraph( makeNodeName( methodname, flatnodetolabel.get( fn ), nodeDescription ) ); } - - // if the results of the new graph are different from - // the current graph at this node, replace the graph - // with the update and enqueue the children for - // processing - OwnershipGraph ogOld = getGraphFromFlat( fn ); - - if( !og.equals( ogOld ) ) { - setGraphForFlat( fn, og ); - - for( int i = 0; i < fn.numNext(); i++ ) { - FlatNode nn = fn.getNext( i ); - visited.remove( nn ); - toVisit.add( nn ); - } - } - } } - private String makeNodeName( String taskname, Integer id, String type ) { + + private String makeNodeName( String methodname, Integer id, String type ) { String s = String.format( "%05d", id ); - return "task"+taskname+"_FN"+s+"_"+type; + return "method_"+methodname+"_FN"+s+"_"+type; } - private String makeCondensedAnalysisName( String taskname, Integer id ) { - return "task"+taskname+"_Ownership_from"+id; + private String makeCondensedAnalysisName( String methodname, Integer id ) { + return "method_"+methodname+"_Ownership_from"+id; } }