stable introduction of mlp analysis, infrastructure for variable analysis in place
authorjjenista <jjenista>
Thu, 9 Apr 2009 16:30:59 +0000 (16:30 +0000)
committerjjenista <jjenista>
Thu, 9 Apr 2009 16:30:59 +0000 (16:30 +0000)
Robust/src/Analysis/MLP/MLPAnalysis.java
Robust/src/Analysis/MLP/VariableSourceToken.java [new file with mode: 0644]
Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java
Robust/src/IR/Flat/FlatSESEEnterNode.java
Robust/src/IR/Flat/FlatSESEExitNode.java

index 2970bd924663c9effc92664f0d2ff624d228a1e3..27c3921e4c5eef20af9a10a2565b43a85aea7c24 100644 (file)
@@ -16,11 +16,16 @@ public class MLPAnalysis {
   private CallGraph callGraph;
   private OwnershipAnalysis ownAnalysis;
 
-  public MLPAnalysis(State state,
-                    TypeUtil tu,
-                    CallGraph callGraph,
-                    OwnershipAnalysis ownAnalysis
-                    ) {
+
+  private Stack<FlatSESEEnterNode> seseStack;
+  private Set<FlatSESEEnterNode>   seseRoots;
+
+
+  public MLPAnalysis( State state,
+                     TypeUtil tu,
+                     CallGraph callGraph,
+                     OwnershipAnalysis ownAnalysis
+                     ) {
 
     double timeStartAnalysis = (double) System.nanoTime();
 
@@ -29,6 +34,39 @@ public class MLPAnalysis {
     this.callGraph   = callGraph;
     this.ownAnalysis = ownAnalysis;
 
+    // initialize analysis data structures
+    seseStack = new Stack  <FlatSESEEnterNode>();
+    seseRoots = new HashSet<FlatSESEEnterNode>();
+
+    // run analysis on each method that is actually called
+    // reachability analysis already computed this so reuse
+    Iterator<Descriptor> methItr = ownAnalysis.descriptorsToAnalyze.iterator();
+    while( methItr.hasNext() ) {
+      Descriptor d = methItr.next();
+      
+      FlatMethod fm;
+      if( d instanceof MethodDescriptor ) {
+       fm = state.getMethodFlat( (MethodDescriptor) d);
+      } else {
+       assert d instanceof TaskDescriptor;
+       fm = state.getMethodFlat( (TaskDescriptor) d);
+      }
+
+      // find every SESE from methods that may be called
+      // and organize them into roots and children
+      buildForestForward( fm );
+    }
+
+    Iterator<FlatSESEEnterNode> seseItr = seseRoots.iterator();
+    while( seseItr.hasNext() ) {
+      FlatSESEEnterNode fsen = seseItr.next();
+
+      // do a post-order traversal of the forest so that
+      // a child is analyzed before a parent.  Start from
+      // SESE's exit and do a backward data-flow analysis
+      // for the source of variables
+      computeReadAndWriteSetBackward( fsen );
+    }
 
     double timeEndAnalysis = (double) System.nanoTime();
     double dt = (timeEndAnalysis - timeStartAnalysis)/(Math.pow( 10.0, 9.0 ) );
@@ -37,43 +75,192 @@ public class MLPAnalysis {
   }
 
 
-  Stack<FlatSESEEnterNode> seseStack;
+  private void buildForestForward( FlatMethod fm ) {
 
-  protected void analyze() {
-    seseStack = new Stack<FlatSESEEnterNode>();
+    Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
+    flatNodesToVisit.add( fm );
 
-    /*
-      if( !seseStack.empty() ) {
-      seseStack.peek().addInVar( tmp );
-      seseStack.peek().addOutVar( out_temp );
+    Set<FlatNode> visited = new HashSet<FlatNode>();
+
+    while( !flatNodesToVisit.isEmpty() ) {
+      FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
+      flatNodesToVisit.remove( fn );
+      visited.add( fn );
+
+      //System.out.println( "  "+fn );
+
+      analyzeFlatNode( fn, true );
+
+      for( int i = 0; i < fn.numNext(); i++ ) {
+       FlatNode nn = fn.getNext( i );
+
+       if( !visited.contains( nn ) ) {
+         flatNodesToVisit.add( nn );
+       }
       }
-    */
+    }      
+  }
 
-    /*
-      if( !seseStack.empty() ) {
-      throw new Error("Error: return statement enclosed within SESE "+seseStack.peek());
+
+  private void computeReadAndWriteSetBackward( FlatSESEEnterNode fsen ) {
+    
+  }
+
+
+  private void analyzeFlatNode( FlatNode fn, boolean buildForest ) {
+
+    TempDescriptor lhs;
+    TempDescriptor rhs;
+    FieldDescriptor fld;
+
+    // use node type to decide what alterations to make
+    // to the ownership graph
+    switch( fn.kind() ) {
+
+    case FKind.FlatSESEEnterNode: {
+      FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
+
+      if( buildForest ) {
+       if( seseStack.empty() ) {
+         seseRoots.add( fsen );
+       } else {
+         seseStack.peek().addChild( fsen );
+       }
+       seseStack.push( fsen );
       }
-    */
-
-    /*
-    if( sn.isStart() ) {
-      FlatSESEEnterNode fsen=new FlatSESEEnterNode(sn);
-      sn.setFlatEnter(fsen);
-      seseStack.push(fsen);
-      return new NodePair(fsen, fsen);
-    }
+    } break;
 
-    FlatSESEExitNode fsexn=new FlatSESEExitNode(sn);
-    sn.setFlatExit(fsexn);
-    FlatSESEEnterNode fsen=sn.getStart().getFlatEnter();
-    fsexn.setFlatEnter(fsen);    
-    sn.getStart().getFlatEnter().setFlatExit( fsexn );
-    assert !seseStack.empty();
-    assert fsen == seseStack.pop();
-    if( !seseStack.empty() ) {
-      seseStack.peek().addInVarSet ( fsen.getInVarSet()  );
-      seseStack.peek().addOutVarSet( fsen.getOutVarSet() );
-    }
-    */
+    case FKind.FlatSESEExitNode: {
+      FlatSESEExitNode  fsexn = (FlatSESEExitNode) fn;
+
+      if( buildForest ) {
+       assert !seseStack.empty();
+       seseStack.pop();
+      }
+       
+      //FlatSESEEnterNode fsen  = fsexn.getFlatEnter();
+      //assert fsen == seseStack.pop();
+      //seseStack.peek().addInVarSet ( fsen.getInVarSet()  );
+      //seseStack.peek().addOutVarSet( fsen.getOutVarSet() );
+    } break;
+
+      /*
+    case FKind.FlatMethod: {
+      FlatMethod fm = (FlatMethod) fn;
+    } break;
+
+    case FKind.FlatOpNode: {
+      FlatOpNode fon = (FlatOpNode) fn;
+      if( fon.getOp().getOp() == Operation.ASSIGN ) {
+       lhs = fon.getDest();
+       rhs = fon.getLeft();
+
+      }
+    } break;
+
+    case FKind.FlatCastNode: {
+      FlatCastNode fcn = (FlatCastNode) fn;
+      lhs = fcn.getDst();
+      rhs = fcn.getSrc();
+
+      TypeDescriptor td = fcn.getType();
+      assert td != null;
+      
+    } break;
+
+    case FKind.FlatFieldNode: {
+      FlatFieldNode ffn = (FlatFieldNode) fn;
+      lhs = ffn.getDst();
+      rhs = ffn.getSrc();
+      fld = ffn.getField();
+      if( !fld.getType().isImmutable() || fld.getType().isArray() ) {
+
+      }
+    } break;
+
+    case FKind.FlatSetFieldNode: {
+      FlatSetFieldNode fsfn = (FlatSetFieldNode) fn;
+      lhs = fsfn.getDst();
+      fld = fsfn.getField();
+      rhs = fsfn.getSrc();
+      if( !fld.getType().isImmutable() || fld.getType().isArray() ) {
+
+      }
+    } break;
+
+    case FKind.FlatElementNode: {
+      FlatElementNode fen = (FlatElementNode) fn;
+      lhs = fen.getDst();
+      rhs = fen.getSrc();
+      if( !lhs.getType().isImmutable() || lhs.getType().isArray() ) {
+
+       assert rhs.getType() != null;
+       assert rhs.getType().isArray();
+       
+       TypeDescriptor  tdElement = rhs.getType().dereference();
+       //FieldDescriptor fdElement = getArrayField( tdElement );
+  
+      }
+    } break;
+
+    case FKind.FlatSetElementNode: {
+      FlatSetElementNode fsen = (FlatSetElementNode) fn;
+      lhs = fsen.getDst();
+      rhs = fsen.getSrc();
+      if( !rhs.getType().isImmutable() || rhs.getType().isArray() ) {
+
+       assert lhs.getType() != null;
+       assert lhs.getType().isArray();
+       
+       TypeDescriptor  tdElement = lhs.getType().dereference();
+       //FieldDescriptor fdElement = getArrayField( tdElement );
+      }
+    } break;
+
+    case FKind.FlatNew: {
+      FlatNew fnn = (FlatNew) fn;
+      lhs = fnn.getDst();
+      if( !lhs.getType().isImmutable() || lhs.getType().isArray() ) {
+       //AllocationSite as = getAllocationSiteFromFlatNewPRIVATE( fnn );
+      }
+    } break;
+
+    case FKind.FlatCall: {
+      FlatCall fc = (FlatCall) fn;
+      MethodDescriptor md = fc.getMethod();
+      FlatMethod flatm = state.getMethodFlat( md );
+
+
+      if( md.isStatic() ) {
+
+      } else {
+       // if the method descriptor is virtual, then there could be a
+       // set of possible methods that will actually be invoked, so
+       // find all of them and merge all of their results together
+       TypeDescriptor typeDesc = fc.getThis().getType();
+       Set possibleCallees = callGraph.getMethods( md, typeDesc );
+
+       Iterator i = possibleCallees.iterator();
+       while( i.hasNext() ) {
+         MethodDescriptor possibleMd = (MethodDescriptor) i.next();
+         FlatMethod pflatm = state.getMethodFlat( possibleMd );
+
+       }
+      }
+
+    } break;
+
+    case FKind.FlatReturnNode: {
+      FlatReturnNode frn = (FlatReturnNode) fn;
+      rhs = frn.getReturnTemp();
+      if( rhs != null && !rhs.getType().isImmutable() ) {
+
+      }
+      if( !seseStack.empty() ) {
+       throw new Error( "Error: return statement enclosed within SESE "+seseStack.peek() );
+      }
+    } break;
+      */
+    } // end switch
   }
 }
diff --git a/Robust/src/Analysis/MLP/VariableSourceToken.java b/Robust/src/Analysis/MLP/VariableSourceToken.java
new file mode 100644 (file)
index 0000000..fe43742
--- /dev/null
@@ -0,0 +1,58 @@
+package Analysis.MLP;
+
+import IR.*;
+import IR.Flat.*;
+import java.util.*;
+import java.io.*;
+
+public class VariableSourceToken {
+
+  private FlatSESEEnterNode sese;
+  private TempDescriptor    var;
+  private Integer           age;
+
+  public VariableSourceToken( FlatSESEEnterNode sese,
+                             TempDescriptor    var, 
+                             Integer           age ) {
+    this.sese = sese;
+    this.var  = var;
+    this.age  = age;
+  }
+
+  public FlatSESEEnterNode getSESE() {
+    return sese;
+  }
+
+  public TempDescriptor getVar() {
+    return var;
+  }
+
+  public Integer getAge() {
+    return age;
+  }
+
+
+  public boolean equals( Object o ) {
+    if( o == null ) {
+      return false;
+    }
+
+    if( !(o instanceof VariableSourceToken) ) {
+      return false;
+    }
+
+    VariableSourceToken vst = (VariableSourceToken) o;
+
+    return var.equals( vst.var ) &&
+           age.equals( vst.age );
+  }
+
+  public int hashCode() {
+    return (var.hashCode() << 2) ^ age.intValue();
+  }
+
+
+  public String toString() {
+    return "["+var+", "+age+"]";
+  }
+}
index 14a099bf6a6cf08fa29e1f24fea978908fb04666..df464d43438083aa2b4038dd54529f6d9e66cb04 100644 (file)
@@ -294,7 +294,7 @@ public class OwnershipAnalysis {
   // descriptorsToAnalyze identifies the set of tasks and methods
   // that are reachable from the program tasks, this set is initialized
   // and then remains static
-  private HashSet<Descriptor> descriptorsToAnalyze;
+  public HashSet<Descriptor> descriptorsToAnalyze;
 
   // descriptorsToVisit is initialized to descriptorsToAnalyze and is
   // reduced by visiting a descriptor during analysis.  When dependents
index 46cb62c8f42380f48b4fb79ba7fbd7bf7b65dfe6..1373659c1410351317e214e52939460134034914 100644 (file)
@@ -1,21 +1,24 @@
 package IR.Flat;
+import Analysis.MLP.VariableSourceToken;
 import IR.Tree.SESENode;
-import java.util.HashSet;
+import java.util.*;
 
 public class FlatSESEEnterNode extends FlatNode {
   private static int identifier=0;
   private int id;
   protected FlatSESEExitNode exit;
   protected SESENode treeNode;
-  protected HashSet<TempDescriptor> inVars;
-  protected HashSet<TempDescriptor> outVars;
+  protected Set<FlatSESEEnterNode> children;
+  protected Set<VariableSourceToken> inVars;
+  protected Set<VariableSourceToken> outVars;
   protected FlatMethod enclosing;
 
   public FlatSESEEnterNode( SESENode sn ) {
     this.id  = identifier++;
     treeNode = sn;
-    inVars   = new HashSet<TempDescriptor>();
-    outVars  = new HashSet<TempDescriptor>();
+    children = new HashSet<FlatSESEEnterNode>();
+    inVars   = new HashSet<VariableSourceToken>();
+    outVars  = new HashSet<VariableSourceToken>();
   }
 
   public void rewriteUse() {
@@ -24,27 +27,35 @@ public class FlatSESEEnterNode extends FlatNode {
   public void rewriteDef() {
   }
 
-  public void addInVar( TempDescriptor td ) {
-    inVars.add( td );
+  public void addChild( FlatSESEEnterNode child ) {
+    children.add( child );
   }
 
-  public void addOutVar( TempDescriptor td ) {
-    outVars.add( td );
+  public Set<FlatSESEEnterNode> getChildren() {
+    return children;
   }
 
-  public void addInVarSet( HashSet<TempDescriptor> s ) {
+  public void addInVar( VariableSourceToken vst ) {
+    inVars.add( vst );
+  }
+
+  public void addOutVar( VariableSourceToken vst ) {
+    outVars.add( vst );
+  }
+
+  public void addInVarSet( Set<VariableSourceToken> s ) {
     inVars.addAll( s );
   }
 
-  public void addOutVarSet( HashSet<TempDescriptor> s ) {
+  public void addOutVarSet( Set<VariableSourceToken> s ) {
     outVars.addAll( s );
   }
 
-  public HashSet<TempDescriptor> getInVarSet() {
+  public Set<VariableSourceToken> getInVarSet() {
     return inVars;
   }
 
-  public HashSet<TempDescriptor> getOutVarSet() {
+  public Set<VariableSourceToken> getOutVarSet() {
     return outVars;
   }
 
index eb77cbcebbc6962640d87daba42987c9477e68ec..61b968db066e499a94484b558b9b3772778e82cd 100644 (file)
@@ -21,7 +21,7 @@ public class FlatSESEExitNode extends FlatNode {
     enter = fsen;
   }
 
-  public FlatSESEEnterNode getSESEEnter() {
+  public FlatSESEEnterNode getFlatEnter() {
     return enter;
   }