add more steps to OoO analysis
authoryeom <yeom>
Mon, 28 Jun 2010 17:52:17 +0000 (17:52 +0000)
committeryeom <yeom>
Mon, 28 Jun 2010 17:52:17 +0000 (17:52 +0000)
Robust/src/Analysis/Disjoint/DisjointAnalysis.java
Robust/src/Analysis/Disjoint/ReachGraph.java
Robust/src/Analysis/OoOJava/ConflictGraph.java
Robust/src/Analysis/OoOJava/OoOJavaAnalysis.java
Robust/src/Analysis/RBlockStatusAnalysis.java [new file with mode: 0644]

index 9cde75ff458b2803782c5ea90c0b9b40fcc7e1d9..86dc5366d85c498035ab9665799b91b646abe261 100644 (file)
@@ -4,6 +4,7 @@ import Analysis.CallGraph.*;
 import Analysis.Liveness;
 import Analysis.ArrayReferencees;
 import Analysis.RBlockRelationAnalysis;
+import Analysis.RBlockStatusAnalysis;
 import IR.*;
 import IR.Flat.*;
 import IR.Tree.Modifiers;
@@ -334,6 +335,7 @@ public class DisjointAnalysis {
   public Liveness         liveness;
   public ArrayReferencees arrayReferencees;
   public RBlockRelationAnalysis rblockRel;
+  public RBlockStatusAnalysis rblockStatus;
   public TypeUtil         typeUtil;
   public int              allocationDepth;
 
@@ -557,9 +559,10 @@ public class DisjointAnalysis {
                           CallGraph        cg,
                           Liveness         l,
                           ArrayReferencees ar,
-                           RBlockRelationAnalysis rra
+                           RBlockRelationAnalysis rra,
+                           RBlockStatusAnalysis rsa
                            ) {
-    init( s, tu, cg, l, ar, rra );
+    init( s, tu, cg, l, ar, rra, rsa );
   }
   
   protected void init( State            state,
@@ -567,7 +570,8 @@ public class DisjointAnalysis {
                        CallGraph        callGraph,
                        Liveness         liveness,
                        ArrayReferencees arrayReferencees,
-                       RBlockRelationAnalysis rra
+                       RBlockRelationAnalysis rra,
+                       RBlockStatusAnalysis rsa
                        ) {
          
     analysisComplete = false;
@@ -578,6 +582,7 @@ public class DisjointAnalysis {
     this.liveness                = liveness;
     this.arrayReferencees        = arrayReferencees;
     this.rblockRel               = rra;
+    this.rblockStatus         = rsa;
 
     if( rblockRel != null ) {
       doEffectsAnalysis = true;
@@ -1064,6 +1069,16 @@ public class DisjointAnalysis {
        lhs = fon.getDest();
        rhs = fon.getLeft();
        rg.assignTempXEqualToTempY( lhs, rhs );
+       
+  if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+    if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+      // x gets status of y
+      if(rg.getAccessibleVar().contains(rhs)){
+        rg.addAccessibleVar(lhs);
+      }
+    }    
+  }
+       
       }
       break;
 
@@ -1087,7 +1102,16 @@ public class DisjointAnalysis {
        rg.assignTempXEqualToTempYFieldF( lhs, rhs, fld );
 
         if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
-          effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fld );          
+          effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fld );
+          
+          if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+            // x=y.f, stall y if not accessible
+            // contributes read effects on stall site of y
+            // after this, x and y are accessbile. 
+            
+            rg.addAccessibleVar(lhs);
+            rg.addAccessibleVar(rhs);            
+          }
         }
       }          
       break;
@@ -1103,6 +1127,16 @@ public class DisjointAnalysis {
 
         if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
           effectsAnalysis.analyzeFlatSetFieldNode( rg, lhs, fld, strongUpdate );
+          
+          if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+            // x.y=f , stall x and y if they are not accessible
+            // also contribute write effects on stall site of x
+            
+            // accessible status update
+            rg.addAccessibleVar(lhs);
+            rg.addAccessibleVar(rhs);            
+          }
+          
         }
       }           
       break;
@@ -1122,7 +1156,17 @@ public class DisjointAnalysis {
        rg.assignTempXEqualToTempYFieldF( lhs, rhs, fdElement );
         
         if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
-          effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fdElement );          
+          effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fdElement );       
+          
+          if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+            // x=y.f, stall y if not accessible
+            // contributes read effects on stall site of y
+            // after this, x and y are accessbile. 
+            
+            rg.addAccessibleVar(lhs);
+            rg.addAccessibleVar(rhs);            
+          }
+          
         }
       }
       break;
@@ -1150,6 +1194,16 @@ public class DisjointAnalysis {
         if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
           effectsAnalysis.analyzeFlatSetFieldNode( rg, lhs, fdElement,
                                                    false );
+          
+          if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+            // x.y=f , stall x and y if they are not accessible
+            // also contribute write effects on stall site of x
+            
+            // accessible status update
+            rg.addAccessibleVar(lhs);
+            rg.addAccessibleVar(rhs);            
+          }
+          
         }
       }
       break;
@@ -1160,6 +1214,14 @@ public class DisjointAnalysis {
       if( shouldAnalysisTrack( lhs.getType() ) ) {
        AllocSite as = getAllocSiteFromFlatNewPRIVATE( fnn );   
        rg.assignTempEqualToNewAlloc( lhs, as );
+       
+        if (doEffectsAnalysis && fmContaining != fmAnalysisEntry) {
+          if (rblockStatus.isInCriticalRegion(fmContaining, fn)) {
+            // after creating new object, lhs is accessible
+            rg.addAccessibleVar(lhs);
+          }
+        } 
+        
       }
       break;
 
@@ -1174,6 +1236,9 @@ public class DisjointAnalysis {
       if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
         FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
         rg.removeInContextTaints( fsexn.getFlatEnter() );
+        // sese exit clears all mappings of accessible vars and stall sites
+        // need to wipe out stall site taints
+        rg.clearAccessibleVarSet();        
       }
       break;
 
index 71a6f98393ef339275d72dfdb779fcfde9bb9efb..5e0e217ec84fc6b63a6bc0fb7a676dbc089d3132 100644 (file)
@@ -378,12 +378,7 @@ public class ReachGraph {
   public void assignTempXEqualToTempY( TempDescriptor x,
                                       TempDescriptor y ) {
     assignTempXEqualToCastedTempY( x, y, null );
-    
-    // x gets status of y
-    // if it is in region, 
-    //if(accessibleVars.contains(y)){
-    //  accessibleVars.add(x);
-    //}
+
   }
 
   public void assignTempXEqualToCastedTempY( TempDescriptor x,
@@ -510,11 +505,7 @@ public class ReachGraph {
        globalSweep();
       }
     }
-    
-    // accessible status update
-    // if it is in region,
-    //accessibleVars.add(x);
-    //accessibleVars.add(y);
+
   }
 
 
@@ -682,14 +673,6 @@ public class ReachGraph {
         globalSweep();
       }
     }    
-    
-
-    // after x.y=f , stall x and y if they are not accessible
-    // also contribute write effects on stall site of x
-    // accessible status update
-    // if it is in region
-    //accessibleVars.add(x);
-    //accessibleVars.add(y);
 
     return edgeRemovedByStrongUpdate;
   }
index 224790a030c5b26211d75809755024e79d1286ee..35017612f536eb0b7c85de155730b7b8504a2736 100644 (file)
@@ -144,12 +144,12 @@ public class ConflictGraph {
 
     int conflictType = ConflictGraph.NON_WRITE_CONFLICT;
 
-    // if node A has write effects on reading/writing regions of node B
     Hashtable<AllocSite, Set<Effect>> alloc2readEffectsA = nodeA.getReadEffectSet();
     Hashtable<AllocSite, Set<Effect>> alloc2writeEffectsA = nodeA.getWriteEffectSet();
     Hashtable<AllocSite, Set<Effect>> alloc2readEffectsB = nodeB.getReadEffectSet();
     Hashtable<AllocSite, Set<Effect>> alloc2writeEffectsB = nodeB.getWriteEffectSet();
 
+    // if node A has write effects on reading/writing regions of node B
     conflictType = updateConflictType(conflictType, determineConflictType(alloc2writeEffectsA,
         alloc2readEffectsB));
     conflictType = updateConflictType(conflictType, determineConflictType(alloc2writeEffectsA,
@@ -184,7 +184,7 @@ public class ConflictGraph {
             Effect effectB = (Effect) iterator2.next();
 
             if (effectA.getAffectedAllocSite().equals(effectB.getAffectedAllocSite())
-                && effectA.getField().equals(effectB.getField())) {
+                && effectA.getField().equals(effectB.getField())) {             
               // possible conflict
               /*
                * if(og.isReachable(asA, asB, effectA.getAffectedAllocSite())){
index 81021b1ad11b52f5f3806c6f6f8c38e85aab7e60..d052f23ffdd2f11a224017004276377e5bd1d21e 100644 (file)
@@ -12,6 +12,7 @@ import java.util.Map.Entry;
 import Analysis.ArrayReferencees;
 import Analysis.Liveness;
 import Analysis.RBlockRelationAnalysis;
+import Analysis.RBlockStatusAnalysis;
 import Analysis.CallGraph.CallGraph;
 import Analysis.Disjoint.DisjointAnalysis;
 import Analysis.Disjoint.Effect;
@@ -39,6 +40,7 @@ public class OoOJavaAnalysis {
   private TypeUtil typeUtil;
   private CallGraph callGraph;
   private RBlockRelationAnalysis rblockRel;
+  private RBlockStatusAnalysis rblockStatus;
   private DisjointAnalysis disjointAnalysisTaints;
   private DisjointAnalysis disjointAnalysisReach;
 
@@ -121,6 +123,9 @@ public class OoOJavaAnalysis {
 
     // 1st pass, find basic rblock relations
     rblockRel = new RBlockRelationAnalysis(state, typeUtil, callGraph);
+    
+    rblockStatus = new RBlockStatusAnalysis(state, typeUtil, callGraph, rblockRel);
+
 
     // 2nd pass, liveness, in-set out-set (no virtual reads yet!)
     Iterator<FlatSESEEnterNode> rootItr = rblockRel.getRootSESEs().iterator();
@@ -151,7 +156,7 @@ public class OoOJavaAnalysis {
     // 5th pass, use disjointness with NO FLAGGED REGIONS
     // to compute taints and effects
     disjointAnalysisTaints = new DisjointAnalysis(state, typeUtil, callGraph, liveness,
-        arrayReferencees, rblockRel);
+        arrayReferencees, rblockRel, rblockStatus);
 
     // 6th pass, not available analysis FOR VARIABLES!
     methItr = descriptorsToAnalyze.iterator();
diff --git a/Robust/src/Analysis/RBlockStatusAnalysis.java b/Robust/src/Analysis/RBlockStatusAnalysis.java
new file mode 100644 (file)
index 0000000..0185860
--- /dev/null
@@ -0,0 +1,222 @@
+package Analysis;
+
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.Stack;
+import java.util.Map.Entry;
+
+import Analysis.CallGraph.CallGraph;
+import IR.MethodDescriptor;
+import IR.State;
+import IR.TypeUtil;
+import IR.Flat.FKind;
+import IR.Flat.FlatMethod;
+import IR.Flat.FlatNode;
+import IR.Flat.FlatSESEEnterNode;
+import IR.Flat.FlatSESEExitNode;
+
+public class RBlockStatusAnalysis {
+
+  // compiler data
+  State state;
+  TypeUtil typeUtil;
+  CallGraph callGraph;
+  RBlockRelationAnalysis rra;
+
+  // per method-per node-rblock stacks
+  protected Hashtable<FlatMethod, Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>>> fm2statusmap;
+
+  public RBlockStatusAnalysis(State state, TypeUtil typeUtil, CallGraph callGraph,
+      RBlockRelationAnalysis rra) {
+    this.state = state;
+    this.typeUtil = typeUtil;
+    this.callGraph = callGraph;
+    this.rra = rra;
+
+    fm2statusmap =
+        new Hashtable<FlatMethod, Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>>>();
+
+    MethodDescriptor mdSourceEntry = typeUtil.getMain();
+    FlatMethod fmMain = state.getMethodFlat(mdSourceEntry);
+
+    // add all methods transitively reachable from the
+    // source's main to set for analysis
+    Set<MethodDescriptor> descriptorsToAnalyze = callGraph.getAllMethods(mdSourceEntry);
+
+    descriptorsToAnalyze.add(mdSourceEntry);
+
+    analyzeMethods(descriptorsToAnalyze);
+
+    // analyzeMethodsDebug(descriptorsToAnalyze);
+  }
+
+  protected void analyzeMethods(Set<MethodDescriptor> descriptorsToAnalyze) {
+
+    Iterator<MethodDescriptor> mdItr = descriptorsToAnalyze.iterator();
+    while (mdItr.hasNext()) {
+      FlatMethod fm = state.getMethodFlat(mdItr.next());
+
+      Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>> fn2seseStatus =
+          computeRBlockStatus(fm);
+
+      fm2statusmap.put(fm, fn2seseStatus);
+    }
+  }
+
+  public Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>> computeRBlockStatus(
+      FlatMethod fm) {
+
+    Hashtable<FlatNode, Stack<FlatSESEEnterNode>> seseStacks =
+        new Hashtable<FlatNode, Stack<FlatSESEEnterNode>>();
+
+    Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>> fn2seseStatus =
+        new Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>>();
+
+    LinkedList<FlatNode> flatNodesToVisit = new LinkedList<FlatNode>();
+    flatNodesToVisit.add(fm);
+
+    Stack<FlatSESEEnterNode> seseStackFirst = new Stack<FlatSESEEnterNode>();
+    seseStacks.put(fm, seseStackFirst);
+
+    while (!flatNodesToVisit.isEmpty()) {
+      Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
+      FlatNode fn = fnItr.next();
+
+      Hashtable<FlatSESEEnterNode, Boolean> prevResult = fn2seseStatus.get(fn);
+
+      Hashtable<FlatSESEEnterNode, Boolean> currentResult =
+          new Hashtable<FlatSESEEnterNode, Boolean>();
+
+      for (int i = 0; i < fn.numPrev(); i++) {
+        FlatNode prevFlatNode = fn.getPrev(i);
+        Hashtable<FlatSESEEnterNode, Boolean> incoming = fn2seseStatus.get(prevFlatNode);
+        if (incoming != null) {
+          merge(currentResult, incoming);
+        }
+      }
+
+      flatNodesToVisit.remove(fn);
+
+      nodeActions(fn, fm, currentResult);
+
+      // if we have a new result, schedule forward nodes for
+      // analysis
+      if (prevResult == null || !currentResult.equals(prevResult)) {
+        fn2seseStatus.put(fn, currentResult);
+        for (int i = 0; i < fn.numNext(); i++) {
+          FlatNode nn = fn.getNext(i);
+          flatNodesToVisit.addFirst(nn);
+        }
+      }
+    }
+
+    return fn2seseStatus;
+  }
+
+  private void merge(Hashtable<FlatSESEEnterNode, Boolean> current,
+      Hashtable<FlatSESEEnterNode, Boolean> incoming) {
+
+    Iterator inIter = incoming.entrySet().iterator();
+    while (inIter.hasNext()) {
+      Entry inEntry = (Entry) inIter.next();
+      FlatSESEEnterNode seseContaining = (FlatSESEEnterNode) inEntry.getKey();
+      Boolean isAfter = (Boolean) inEntry.getValue();
+
+      Boolean currentIsAfter = current.get(seseContaining);
+      if (currentIsAfter == null || currentIsAfter == Boolean.FALSE) {
+        current.put(seseContaining, isAfter);
+      }
+    }
+
+  }
+  
+  public boolean isInCriticalRegion(FlatMethod fmContaining, FlatNode fn) {
+    FlatSESEEnterNode seseContaining = rra.getRBlockStacks(fmContaining, fn).peek();
+    Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>> statusMap =
+        fm2statusmap.get(fmContaining);
+    Hashtable<FlatSESEEnterNode, Boolean> status = statusMap.get(fn);
+    
+    if(status.get(seseContaining).booleanValue()==true){
+      System.out.println(fn+" is in the critical region in according to "+seseContaining);
+    }
+    
+    return status.get(seseContaining).booleanValue();
+  }
+
+  protected void nodeActions(FlatNode fn, FlatMethod fm,
+      Hashtable<FlatSESEEnterNode, Boolean> status) {
+    switch (fn.kind()) {
+
+    case FKind.FlatSESEExitNode: {
+      FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
+      FlatSESEEnterNode fsen = fsexn.getFlatEnter();
+      if (fsen.getParent() != null) {
+        status.put(fsen.getParent(), Boolean.TRUE);
+      }
+    }
+      break;
+
+    default: {
+      if (!(fn instanceof FlatMethod)) {
+        Stack<FlatSESEEnterNode> seseStack = rra.getRBlockStacks(fm, fn);
+        if (!seseStack.isEmpty()) {
+          FlatSESEEnterNode currentParent = seseStack.peek();
+          if (!status.containsKey(currentParent)) {
+            status.put(currentParent, Boolean.FALSE);
+          }
+        }
+      }
+
+    }
+      break;
+    }
+
+  }
+
+  /*
+   * DEBUG
+   */
+  protected void analyzeMethodsDebug(Set<MethodDescriptor> descriptorsToAnalyze) {
+
+    Iterator<MethodDescriptor> mdItr = descriptorsToAnalyze.iterator();
+    while (mdItr.hasNext()) {
+      FlatMethod fm = state.getMethodFlat(mdItr.next());
+      printStatusMap(fm);
+
+    }
+  }
+
+  protected void printStatusMap(FlatMethod fm) {
+
+    Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
+    flatNodesToVisit.add(fm);
+
+    Set<FlatNode> visited = new HashSet<FlatNode>();
+
+    while (!flatNodesToVisit.isEmpty()) {
+      Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
+      FlatNode fn = fnItr.next();
+
+      flatNodesToVisit.remove(fn);
+      visited.add(fn);
+
+      System.out.println("------------------");
+      System.out.println("fn=" + fn);
+      System.out.println(fm2statusmap.get(fm).get(fn));
+
+      for (int i = 0; i < fn.numNext(); i++) {
+        FlatNode nn = fn.getNext(i);
+
+        if (!visited.contains(nn)) {
+          flatNodesToVisit.add(nn);
+
+        }
+      }
+    }
+
+  }
+
+}