missing files
[IRC.git] / Robust / src / Analysis / Locality / LocalityAnalysis.java
index 7ceab573346b2d5d729f49348157b5c86b77a8aa..7227cbc2634d42708d634613cb638e79995549c3 100644 (file)
@@ -1,5 +1,6 @@
 package Analysis.Locality;
 
+import Analysis.Liveness;
 import java.util.*;
 import Analysis.CallGraph.CallGraph;
 import IR.SymbolTable;
@@ -23,6 +24,7 @@ public class LocalityAnalysis {
   Hashtable<MethodDescriptor, Set<LocalityBinding>> methodtolb;
   private LocalityBinding lbmain;
   private LocalityBinding lbrun;
+  private LocalityBinding lbexecute;
 
   CallGraph callgraph;
   TypeUtil typeutil;
@@ -191,8 +193,14 @@ public class LocalityAnalysis {
     Stack<LocalityBinding> lbstack=new Stack<LocalityBinding>();
     lbstack.add(lbmain);
     lbstack.add(lbrun);
+
     lbset.add(lbmain);
     lbset.add(lbrun);
+
+    if(state.DSMTASK) {       // when Task.java is used
+      lbstack.add(lbexecute);
+      lbset.add(lbexecute);
+    }
     while(!lbstack.isEmpty()) {
       LocalityBinding lb=lbstack.pop();
       if (calldep.containsKey(lb)) {
@@ -297,6 +305,7 @@ public class LocalityAnalysis {
     FlatMethod fm=state.getMethodFlat(md);
     HashSet<FlatNode> tovisit=new HashSet<FlatNode>();
     tovisit.add(fm.getNext(0));
+
     {
       // Build table for initial node
       Hashtable<TempDescriptor,Integer> table=new Hashtable<TempDescriptor,Integer>();
@@ -314,9 +323,12 @@ public class LocalityAnalysis {
       }
     }
 
+    Hashtable<FlatNode, Set<TempDescriptor>> livemap=Liveness.computeLiveTemps(fm);
+    
     while(!tovisit.isEmpty()) {
       FlatNode fn=tovisit.iterator().next();
       tovisit.remove(fn);
+      Set<TempDescriptor> liveset=livemap.get(fn);
       Hashtable<TempDescriptor, Integer> currtable=new Hashtable<TempDescriptor, Integer>();
       int atomicstate=0;
       for(int i=0; i<fn.numPrev(); i++) {
@@ -329,6 +341,8 @@ public class LocalityAnalysis {
        Hashtable<TempDescriptor, Integer> prevtable=temptable.get(prevnode);
        for(Iterator<TempDescriptor> tempit=prevtable.keySet().iterator(); tempit.hasNext();) {
          TempDescriptor temp=tempit.next();
+         if (!liveset.contains(temp))
+           continue;
          Integer tmpint=prevtable.get(temp);
          Integer oldint=currtable.containsKey(temp) ? currtable.get(temp) : STMEITHER;
          Integer newint=mergestm(tmpint, oldint);
@@ -497,8 +511,8 @@ public class LocalityAnalysis {
        }
       } else {
        Integer thistype=currtable.get(fc.getThis());
-       if (!thistype.equals(NORMAL)) {
-         throw new Error("Called start on possible scratch object");
+       if (!thistype.equals(NORMAL)&&!thistype.equals(STMEITHER)) {
+         throw new Error("Called start on possible scratch object"+thistype);
        }
        lb.setGlobal(0,currtable.get(fc.getThis()));
       }
@@ -512,6 +526,7 @@ public class LocalityAnalysis {
 
        lb.setParent(currlb);
        lbtovisit.add(lb);
+       System.out.println("New lb:"+lb);
        discovered.put(lb, lb);
        if (!classtolb.containsKey(lb.getMethod().getClassDesc()))
          classtolb.put(lb.getMethod().getClassDesc(), new HashSet<LocalityBinding>());
@@ -531,7 +546,7 @@ public class LocalityAnalysis {
        calldep.put(currlb, new HashSet<LocalityBinding>());
       calldep.get(currlb).add(lb);
     }
-    if (fc.getReturnTemp()!=null) {
+    if (fc.getReturnTemp()!=null&&fc.getReturnTemp().getType().isPtr()) {
       currtable.put(fc.getReturnTemp(), currreturnval);
     }
   }
@@ -539,18 +554,15 @@ public class LocalityAnalysis {
   void processFieldNodeSTM(LocalityBinding lb, FlatFieldNode ffn, Hashtable<TempDescriptor, Integer> currtable) {
     Integer type=currtable.get(ffn.getSrc());
     TempDescriptor dst=ffn.getDst();
+    if (!ffn.getDst().getType().isPtr())
+      return;
+
     if (type.equals(SCRATCH)) {
       currtable.put(dst,SCRATCH);
     } else if (type.equals(NORMAL)) {
-      if (ffn.getField().getType().isPrimitive()&&!ffn.getField().getType().isArray())
-       currtable.put(dst, SCRATCH);         // primitives are local
-      else
-       currtable.put(dst, NORMAL);
+      currtable.put(dst, NORMAL);
     } else if (type.equals(STMEITHER)) {
-      if (ffn.getField().getType().isPrimitive()&&!ffn.getField().getType().isArray())
-       currtable.put(dst, SCRATCH);         // primitives are local
-      else
-       currtable.put(dst, STMEITHER);
+      currtable.put(dst, STMEITHER);
     } else if (type.equals(STMCONFLICT)) {
       throw new Error("Access to object that could be either normal or scratch in context:\n"+ffn+"  "+lb.getExplanation());
     }
@@ -688,9 +700,26 @@ public class LocalityAnalysis {
       methodtolb.put(lbrun.getMethod(), new HashSet<LocalityBinding>());
     methodtolb.get(lbrun.getMethod()).add(lbrun);
 
+    if(state.DSMTASK) {
+      lbexecute = new LocalityBinding(typeutil.getExecute(), false);
+      lbexecute.setGlobalReturn(EITHER);
+      lbexecute.setGlobalThis(GLOBAL);
+      lbtovisit.add(lbexecute);
+      discovered.put(lbexecute, lbexecute);
+      if (!classtolb.containsKey(lbexecute.getMethod().getClassDesc()))
+        classtolb.put(lbexecute.getMethod().getClassDesc(), new HashSet<LocalityBinding>());
+      classtolb.get(lbexecute.getMethod().getClassDesc()).add(lbexecute);
+
+      if (!methodtolb.containsKey(lbexecute.getMethod()))
+        methodtolb.put(lbexecute.getMethod(), new HashSet<LocalityBinding>());
+      methodtolb.get(lbexecute.getMethod()).add(lbexecute);
+    }
+
     while(!lbtovisit.isEmpty()) {
       LocalityBinding lb=(LocalityBinding) lbtovisit.iterator().next();
       lbtovisit.remove(lb);
+
+      System.out.println("Analyzing "+lb);
       Integer returnglobal=lb.getGlobalReturn();
       MethodDescriptor md=lb.getMethod();
       Hashtable<FlatNode,Hashtable<TempDescriptor, Integer>> temptable=new Hashtable<FlatNode,Hashtable<TempDescriptor, Integer>>();
@@ -759,6 +788,7 @@ public class LocalityAnalysis {
        }
       }
       atomictable.put(fn, atomicstate);
+
       // Process this node
       switch(fn.kind()) {
       case FKind.FlatAtomicEnterNode:
@@ -772,7 +802,7 @@ public class LocalityAnalysis {
        break;
 
       case FKind.FlatCall:
-       processCallNode(lb, (FlatCall)fn, currtable, isAtomic(atomictable, fn));
+         processCallNode(lb, (FlatCall)fn, currtable, isAtomic(atomictable, fn), temptable.get(fn));
        break;
 
       case FKind.FlatFieldNode:
@@ -860,10 +890,11 @@ public class LocalityAnalysis {
     return CONFLICT;
   }
 
-  void processCallNode(LocalityBinding currlb, FlatCall fc, Hashtable<TempDescriptor, Integer> currtable, boolean isatomic) {
+    void processCallNode(LocalityBinding currlb, FlatCall fc, Hashtable<TempDescriptor, Integer> currtable, boolean isatomic, Hashtable<TempDescriptor,Integer> oldtable) {
     MethodDescriptor nodemd=fc.getMethod();
     Set methodset=null;
     Set runmethodset=null;
+    Set executemethodset=null;
 
     if (nodemd.isStatic()||nodemd.getReturnType()==null) {
       methodset=new HashSet();
@@ -874,24 +905,56 @@ public class LocalityAnalysis {
       if (nodemd.getClassDesc().getSymbol().equals(TypeUtil.ThreadClass)&&
           nodemd.getSymbol().equals("start")&&!nodemd.getModifiers().isStatic()&&
           nodemd.numParameters()==1&&nodemd.getParamType(0).isInt()) {
-       assert(nodemd.getModifiers().isNative());
+       assert(nodemd.getModifiers().isNative());
 
-       MethodDescriptor runmd=null;
-       for(Iterator methodit=nodemd.getClassDesc().getMethodTable().getSet("run").iterator(); methodit.hasNext();) {
-         MethodDescriptor md=(MethodDescriptor) methodit.next();
-         if (md.numParameters()!=0||md.getModifiers().isStatic())
-           continue;
-         runmd=md;
-         break;
-       }
-       if (runmd!=null) {
-         runmethodset=callgraph.getMethods(runmd,fc.getThis().getType());
-         methodset.addAll(runmethodset);
-       } else throw new Error("Can't find run method");
+       MethodDescriptor runmd=null;
+
+        for(Iterator methodit=nodemd.getClassDesc().getMethodTable().getSet("run").iterator(); methodit.hasNext();) {
+         MethodDescriptor md=(MethodDescriptor) methodit.next();
+      
+          if (md.numParameters()!=0||md.getModifiers().isStatic())
+           continue;
+         runmd=md;
+         break;
+             }
+       if (runmd!=null) {
+         runmethodset=callgraph.getMethods(runmd,fc.getThis().getType());
+         methodset.addAll(runmethodset);
+       } else throw new Error("Can't find run method");
+      }
+
+      if(state.DSMTASK) {
+        if (nodemd.getClassDesc().getSymbol().equals(TypeUtil.TaskClass) &&
+          nodemd.getSymbol().equals("execution") && !nodemd.getModifiers().isStatic() &&
+          nodemd.numParameters() == 0) {
+      
+          assert(nodemd.getModifiers().isNative());
+          MethodDescriptor exemd = null;
+
+          for(Iterator methodit=nodemd.getClassDesc().getMethodTable().getSet("execute").iterator(); methodit.hasNext();) {
+            MethodDescriptor md = (MethodDescriptor) methodit.next();
+
+            if (md.numParameters() != 0 || md.getModifiers().isStatic())
+              continue;
+            exemd = md;
+            break;
+          }
+
+          if (exemd != null) {
+            executemethodset = callgraph.getMethods(exemd, fc.getThis().getType());
+            methodset.addAll(executemethodset);
+          } else throw new Error("Can't find execute method");
+        }
       }
     }
 
     Integer currreturnval=EITHER;     //Start off with the either value
+    if (oldtable!=null&&fc.getReturnTemp()!=null&&
+        oldtable.get(fc.getReturnTemp())!=null) {
+       //ensure termination
+       currreturnval=merge(currreturnval, oldtable.get(fc.getReturnTemp()));
+    }
+
     for(Iterator methodit=methodset.iterator(); methodit.hasNext();) {
       MethodDescriptor md=(MethodDescriptor) methodit.next();
 
@@ -904,8 +967,9 @@ public class LocalityAnalysis {
       if (isnative&&isatomic) {
        System.out.println("Don't call native methods in atomic blocks!"+currlb.getMethod());
       }
-      if (runmethodset==null||!runmethodset.contains(md)) {
-       //Skip this part if it is a run method
+
+  if ((runmethodset==null||!runmethodset.contains(md)) &&( executemethodset == null || !executemethodset.contains(md))) {
+       //Skip this part if it is a run method or execute method
        for(int i=0; i<fc.numArgs(); i++) {
          TempDescriptor arg=fc.getArg(i);
          if(isnative&&(currtable.get(arg).equals(GLOBAL)||
@@ -921,15 +985,16 @@ public class LocalityAnalysis {
        if (thistype==null)
          thistype=EITHER;
 
-       if(runmethodset!=null&&runmethodset.contains(md)&&thistype.equals(LOCAL))
+       if(runmethodset!=null&&runmethodset.contains(md)&&thistype.equals(LOCAL) && executemethodset != null && executemethodset.contains(md))
          throw new Error("Starting thread on local object not allowed in context:\n"+currlb.getExplanation());
        if(isjoin&&thistype.equals(LOCAL))
          throw new Error("Joining thread on local object not allowed in context:\n"+currlb.getExplanation());
        if(thistype.equals(CONFLICT))
          throw new Error("Using type that can be either local or global in context:\n"+currlb.getExplanation());
-       if(runmethodset==null&&thistype.equals(GLOBAL)&&!isatomic && !isjoin)
+       if(runmethodset==null&&thistype.equals(GLOBAL)&&!isatomic && !isjoin && executemethodset == null) {
          throw new Error("Using global object outside of transaction in context:\n"+currlb.getExplanation());
-       if (runmethodset==null&&isnative&&thistype.equals(GLOBAL) && !isjoin && !isObjectgetType && !isObjecthashCode)
+    }
+       if (runmethodset==null&&isnative&&thistype.equals(GLOBAL) && !isjoin && executemethodset == null && !isObjectgetType && !isObjecthashCode)
          throw new Error("Potential call to native method "+md+" on global objects:\n"+currlb.getExplanation());
        lb.setGlobalThis(thistype);
       }
@@ -1002,8 +1067,9 @@ public class LocalityAnalysis {
        if (!(srctype.equals(GLOBAL)||srctype.equals(EITHER)))
          throw new Error("Writing possible local reference to global field in context: \n"+lb.getExplanation());
       } else {
-       if (!(srctype.equals(LOCAL)||srctype.equals(EITHER)))
+       if (!(srctype.equals(LOCAL)||srctype.equals(EITHER))) {
          throw new Error("Writing possible global reference to local object in context: \n"+lb.getExplanation());
+    }
       }
     } else if (dsttype.equals(GLOBAL)) {
       if (!transaction)
@@ -1072,8 +1138,9 @@ public class LocalityAnalysis {
     Integer dsttype=currtable.get(fsen.getDst());
 
     if (dsttype.equals(LOCAL)) {
-      if (!(srctype.equals(LOCAL)||srctype.equals(EITHER)))
+      if (!(srctype.equals(LOCAL)||srctype.equals(EITHER))) {
        throw new Error("Writing possible global reference to local object in context:\n"+lb.getExplanation()+fsen);
+      }
     } else if (dsttype.equals(GLOBAL)) {
       if (srctype.equals(LOCAL) && fsen.getDst().getType().dereference().isPrimitive() && !fsen.getDst().getType().dereference().isArray())
        return;
@@ -1123,10 +1190,6 @@ public class LocalityAnalysis {
     atomictable.put(fen, new Integer(atomic-1));
   }
     
-  Hashtable<FlatNode, Set<TempDescriptor>> computeLiveTemps(FlatMethod fm) {
-    return Liveness.computeLiveTemps(fm);
-  }
-
   private void computeTempstoSave() {
     for(Iterator<LocalityBinding> lbit=getLocalityBindings().iterator(); lbit.hasNext();) {
       LocalityBinding lb=lbit.next();
@@ -1150,7 +1213,7 @@ public class LocalityAnalysis {
     Hashtable<FlatNode, Hashtable<TempDescriptor, Integer>> temptab=getNodeTempInfo(lb);
     MethodDescriptor md=lb.getMethod();
     FlatMethod fm=state.getMethodFlat(md);
-    Hashtable<FlatNode, Set<TempDescriptor>> nodetotemps=computeLiveTemps(fm);
+    Hashtable<FlatNode, Set<TempDescriptor>> nodetotemps=Liveness.computeLiveTemps(fm);
     Hashtable<FlatAtomicEnterNode, Set<TempDescriptor>> nodetosavetemps=new Hashtable<FlatAtomicEnterNode, Set<TempDescriptor>>();
     tempstosave.put(lb, nodetosavetemps);
     Hashtable<FlatNode, FlatAtomicEnterNode> nodemap=new Hashtable<FlatNode, FlatAtomicEnterNode>();
@@ -1164,14 +1227,14 @@ public class LocalityAnalysis {
       boolean isatomic=atomictab.get(fn).intValue()>0;
       if (isatomic&&
           atomictab.get(fn.getPrev(0)).intValue()==0) {
-       assert(fn.getPrev(0).kind()==FKind.FlatAtomicEnterNode);
+       assert(fn.kind()==FKind.FlatAtomicEnterNode);
        nodemap.put(fn, (FlatAtomicEnterNode)fn);
        nodetosavetemps.put((FlatAtomicEnterNode)fn, new HashSet<TempDescriptor>());
       } else if (isatomic) {
        FlatAtomicEnterNode atomicnode=nodemap.get(fn);
-       Set<TempDescriptor> livetemps=nodetotemps.get(fn);
+       Set<TempDescriptor> livetemps=nodetotemps.get(atomicnode);
        List<TempDescriptor> reads=Arrays.asList(fn.readsTemps());
-       List<TempDescriptor> writes=Arrays.asList(fn.readsTemps());
+       List<TempDescriptor> writes=Arrays.asList(fn.writesTemps());
 
        for(Iterator<TempDescriptor> tempit=livetemps.iterator(); tempit.hasNext();) {
          TempDescriptor tmp=tempit.next();