switch to spaces only..
[IRC.git] / Robust / src / Analysis / Locality / LocalityAnalysis.java
index f86ada2c551e95ea68ead14402f4154decdcaea2..0441898444eb8bd9e2d8edb60f66c3da788e8517 100644 (file)
@@ -1,5 +1,6 @@
 package Analysis.Locality;
 
+import Analysis.Liveness;
 import java.util.*;
 import Analysis.CallGraph.CallGraph;
 import IR.SymbolTable;
@@ -7,11 +8,12 @@ import IR.State;
 import IR.TypeUtil;
 import IR.MethodDescriptor;
 import IR.Flat.*;
+import Analysis.Liveness;
 import IR.ClassDescriptor;
 
 public class LocalityAnalysis {
   State state;
-  Stack lbtovisit;
+  Set lbtovisit;
   Hashtable<LocalityBinding,LocalityBinding> discovered;
   Hashtable<LocalityBinding, Set<LocalityBinding>> dependence;
   Hashtable<LocalityBinding, Set<LocalityBinding>> calldep;
@@ -22,6 +24,7 @@ public class LocalityAnalysis {
   Hashtable<MethodDescriptor, Set<LocalityBinding>> methodtolb;
   private LocalityBinding lbmain;
   private LocalityBinding lbrun;
+  private LocalityBinding lbexecute;
 
   CallGraph callgraph;
   TypeUtil typeutil;
@@ -43,7 +46,7 @@ public class LocalityAnalysis {
     this.calldep=new Hashtable<LocalityBinding, Set<LocalityBinding>>();
     this.temptab=new Hashtable<LocalityBinding, Hashtable<FlatNode,Hashtable<TempDescriptor, Integer>>>();
     this.atomictab=new Hashtable<LocalityBinding, Hashtable<FlatNode, Integer>>();
-    this.lbtovisit=new Stack();
+    this.lbtovisit=new HashSet();
     this.callgraph=callgraph;
     this.tempstosave=new Hashtable<LocalityBinding, Hashtable<FlatAtomicEnterNode, Set<TempDescriptor>>>();
     this.classtolb=new Hashtable<ClassDescriptor, Set<LocalityBinding>>();
@@ -75,16 +78,16 @@ public class LocalityAnalysis {
     if (state.DSM&&fc.getThis()!=null) {
       Integer thistype=currtable.get(fc.getThis());
       if (thistype==null)
-       thistype=EITHER;
+        thistype=EITHER;
       lb.setGlobalThis(thistype);
     } else if (state.SINGLETM&&fc.getThis()!=null) {
       Integer thistype=currtable.get(fc.getThis());
       if (thistype==null)
-       thistype=STMEITHER;
+        thistype=STMEITHER;
       lb.setGlobalThis(thistype);
     }
     // else
-         // lb.setGlobalThis(EITHER);//default value
+    // lb.setGlobalThis(EITHER);//default value
     if (discovered.containsKey(lb))
       lb=discovered.get(lb);
     else throw new Error();
@@ -135,12 +138,12 @@ public class LocalityAnalysis {
     for(int i=0; i<fn.numPrev(); i++) {
       FlatNode prevnode=fn.getPrev(i);
       Hashtable<TempDescriptor, Integer> prevtable=temptable.get(prevnode);
-      for(Iterator<TempDescriptor> tempit=prevtable.keySet().iterator(); tempit.hasNext();) {
-       TempDescriptor temp=tempit.next();
-       Integer tmpint=prevtable.get(temp);
-       Integer oldint=currtable.containsKey(temp) ? currtable.get(temp) : (state.DSM?EITHER:STMEITHER);
-       Integer newint=state.DSM?merge(tmpint, oldint):mergestm(tmpint, oldint);
-       currtable.put(temp, newint);
+      for(Iterator<TempDescriptor> tempit=prevtable.keySet().iterator(); tempit.hasNext(); ) {
+        TempDescriptor temp=tempit.next();
+        Integer tmpint=prevtable.get(temp);
+        Integer oldint=currtable.containsKey(temp)?currtable.get(temp):(state.DSM?EITHER:STMEITHER);
+        Integer newint=state.DSM?merge(tmpint, oldint):mergestm(tmpint, oldint);
+        currtable.put(temp, newint);
       }
     }
     return currtable;
@@ -169,9 +172,9 @@ public class LocalityAnalysis {
     HashSet<TempDescriptor> set=new HashSet<TempDescriptor>();
     Hashtable<FlatAtomicEnterNode, Set<TempDescriptor>> table=getTemps(lb);
     if (table!=null)
-      for(Iterator<FlatAtomicEnterNode> faenit=table.keySet().iterator(); faenit.hasNext();) {
-       FlatAtomicEnterNode faen=faenit.next();
-       set.addAll(table.get(faen));
+      for(Iterator<FlatAtomicEnterNode> faenit=table.keySet().iterator(); faenit.hasNext(); ) {
+        FlatAtomicEnterNode faen=faenit.next();
+        set.addAll(table.get(faen));
       }
     return set;
   }
@@ -190,24 +193,30 @@ 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)) {
-       Set<LocalityBinding> set=new HashSet<LocalityBinding>();
-       set.addAll(calldep.get(lb));
-       set.removeAll(lbset);
-       lbstack.addAll(set);
-       lbset.addAll(set);
+        Set<LocalityBinding> set=new HashSet<LocalityBinding>();
+        set.addAll(calldep.get(lb));
+        set.removeAll(lbset);
+        lbstack.addAll(set);
+        lbset.addAll(set);
       }
     }
-    for(Iterator<LocalityBinding> lbit=discovered.keySet().iterator(); lbit.hasNext();) {
+    for(Iterator<LocalityBinding> lbit=discovered.keySet().iterator(); lbit.hasNext(); ) {
       LocalityBinding lb=lbit.next();
       if (!lbset.contains(lb)) {
-       lbit.remove();
-       classtolb.get(lb.getMethod().getClassDesc()).remove(lb);
-       methodtolb.get(lb.getMethod()).remove(lb);
+        lbit.remove();
+        classtolb.get(lb.getMethod().getClassDesc()).remove(lb);
+        methodtolb.get(lb.getMethod()).remove(lb);
       }
     }
   }
@@ -215,7 +224,7 @@ public class LocalityAnalysis {
   public MethodDescriptor getStart() {
     ClassDescriptor cd=typeutil.getClass(TypeUtil.ThreadClass);
     for(Iterator methodit=cd.getMethodTable().getSet("staticStart").iterator(); methodit
-.hasNext();) {
+        .hasNext(); ) {
       MethodDescriptor md=(MethodDescriptor) methodit.next();
       if (md.numParameters()!=1||!md.getModifiers().isStatic()||!md.getParamType(0).getSymbol().equals(TypeUtil.ThreadClass))
         continue;
@@ -223,8 +232,8 @@ public class LocalityAnalysis {
     }
     throw new Error("Can't find Thread.run");
   }
-  
-  
+
+
   private void computeLocalityBindingsSTM() {
     lbmain=new LocalityBinding(typeutil.getMain(), false);
     lbmain.setGlobalReturn(STMEITHER);
@@ -253,27 +262,31 @@ public class LocalityAnalysis {
       methodtolb.put(lbrun.getMethod(), new HashSet<LocalityBinding>());
     methodtolb.get(lbrun.getMethod()).add(lbrun);
 
-    while(!lbtovisit.empty()) {
-      LocalityBinding lb=(LocalityBinding) lbtovisit.pop();
+    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>>();
       Hashtable<FlatNode, Integer> atomictable=new Hashtable<FlatNode, Integer>();
       calldep.remove(lb);
       try {
-       computeCallsFlagsSTM(md, lb, temptable, atomictable);
+        computeCallsFlagsSTM(md, lb, temptable, atomictable);
       } catch (Error e) {
-       System.out.println("Error in "+md+" context "+lb);
-       e.printStackTrace();
-       System.exit(-1);
+        System.out.println("Error in "+md+" context "+lb);
+        e.printStackTrace();
+        System.exit(-1);
       }
       temptab.put(lb, temptable);
       atomictab.put(lb, atomictable);
 
-      if (md.getReturnType()!=null&&!returnglobal.equals(lb.getGlobalReturn())) {
-       //return type is more precise now
-       //rerun everything that call us
-       lbtovisit.addAll(dependence.get(lb));
+      if (md.getReturnType()!=null&&md.getReturnType().isPtr()&&!returnglobal.equals(lb.getGlobalReturn())) {
+        //return type is more precise now
+        //rerun everything that call us
+        lbtovisit.addAll(dependence.get(lb));
       }
     }
   }
@@ -292,96 +305,103 @@ 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>();
       temptable.put(fm, table);
-      atomictable.put(fm, lb.isAtomic() ? 1 : 0);
-      int offset=md.isStatic() ? 0 : 1;
+      atomictable.put(fm, lb.isAtomic()?1:0);
+      int offset=md.isStatic()?0:1;
       if (!md.isStatic()) {
-       table.put(fm.getParameter(0), lb.getGlobalThis());
+        table.put(fm.getParameter(0), lb.getGlobalThis());
       }
       for(int i=offset; i<fm.numParameters(); i++) {
-       TempDescriptor temp=fm.getParameter(i);
-       Integer b=lb.isGlobal(i-offset);
-       table.put(temp,b);
+        TempDescriptor temp=fm.getParameter(i);
+        Integer b=lb.isGlobal(i-offset);
+        if (b!=null)
+          table.put(temp,b);
       }
     }
 
+    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++) {
-       FlatNode prevnode=fn.getPrev(i);
-       if (atomictable.containsKey(prevnode)) {
-         atomicstate=atomictable.get(prevnode).intValue();
-       }
-       if (!temptable.containsKey(prevnode))
-         continue;
-       Hashtable<TempDescriptor, Integer> prevtable=temptable.get(prevnode);
-       for(Iterator<TempDescriptor> tempit=prevtable.keySet().iterator(); tempit.hasNext();) {
-         TempDescriptor temp=tempit.next();
-         Integer tmpint=prevtable.get(temp);
-         Integer oldint=currtable.containsKey(temp) ? currtable.get(temp) : STMEITHER;
-         Integer newint=mergestm(tmpint, oldint);
-         currtable.put(temp, newint);
-       }
+        FlatNode prevnode=fn.getPrev(i);
+        if (atomictable.containsKey(prevnode)) {
+          atomicstate=atomictable.get(prevnode).intValue();
+        }
+        if (!temptable.containsKey(prevnode))
+          continue;
+        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);
+          currtable.put(temp, newint);
+        }
       }
       atomictable.put(fn, atomicstate);
 
       // Process this node
       switch(fn.kind()) {
       case FKind.FlatAtomicEnterNode:
-       processAtomicEnterNode((FlatAtomicEnterNode)fn, atomictable);
-       if (!lb.isAtomic())
-         lb.setHasAtomic();
-       break;
+        processAtomicEnterNode((FlatAtomicEnterNode)fn, atomictable);
+        if (!lb.isAtomic())
+          lb.setHasAtomic();
+        break;
 
       case FKind.FlatAtomicExitNode:
-       processAtomicExitNode((FlatAtomicExitNode)fn, atomictable);
-       break;
+        processAtomicExitNode((FlatAtomicExitNode)fn, atomictable);
+        break;
 
       case FKind.FlatCall:
-       processCallNodeSTM(lb, (FlatCall)fn, isAtomic(atomictable, fn), currtable, temptable.get(fn));
-       break;
+        processCallNodeSTM(lb, (FlatCall)fn, isAtomic(atomictable, fn), currtable, temptable.get(fn));
+        break;
 
       case FKind.FlatNew:
-       processNewSTM(lb, (FlatNew) fn, currtable);
-       break;
+        processNewSTM(lb, (FlatNew) fn, currtable);
+        break;
 
       case FKind.FlatFieldNode:
-       processFieldNodeSTM(lb, (FlatFieldNode) fn, currtable);
-       break;
+        processFieldNodeSTM(lb, (FlatFieldNode) fn, currtable);
+        break;
 
       case FKind.FlatSetFieldNode:
-       processSetFieldNodeSTM(lb, (FlatSetFieldNode) fn, currtable);
-       break;
+        processSetFieldNodeSTM(lb, (FlatSetFieldNode) fn, currtable);
+        break;
 
       case FKind.FlatSetElementNode:
-       processSetElementNodeSTM(lb, (FlatSetElementNode) fn, currtable);
-       break;
+        processSetElementNodeSTM(lb, (FlatSetElementNode) fn, currtable);
+        break;
 
       case FKind.FlatElementNode:
-       processElementNodeSTM(lb, (FlatElementNode) fn, currtable);
-       break;
+        processElementNodeSTM(lb, (FlatElementNode) fn, currtable);
+        break;
 
       case FKind.FlatOpNode:
-       processOpNodeSTM((FlatOpNode)fn, currtable);
-       break;
+        processOpNodeSTM(lb, (FlatOpNode)fn, currtable);
+        break;
 
       case FKind.FlatCastNode:
-       processCastNodeSTM((FlatCastNode)fn, currtable);
-       break;
+        processCastNodeSTM((FlatCastNode)fn, currtable);
+        break;
 
       case FKind.FlatReturnNode:
-       processReturnNodeSTM(lb, (FlatReturnNode)fn, currtable);
-       break;
+        processReturnNodeSTM(lb, (FlatReturnNode)fn, currtable);
+        break;
 
       case FKind.FlatLiteralNode:
-       processLiteralNodeSTM((FlatLiteralNode)fn, currtable);
-       break;
+        processLiteralNodeSTM((FlatLiteralNode)fn, currtable);
+        break;
 
       case FKind.FlatMethod:
       case FKind.FlatOffsetNode:
@@ -391,27 +411,27 @@ public class LocalityAnalysis {
       case FKind.FlatNop:
       case FKind.FlatPrefetchNode:
       case FKind.FlatExit:
-       //No action needed for these
-       break;
+        //No action needed for these
+        break;
 
       case FKind.FlatFlagActionNode:
       case FKind.FlatCheckNode:
       case FKind.FlatTagDeclaration:
-       throw new Error("Incompatible with tasks!");
+        throw new Error("Incompatible with tasks!");
 
       default:
-       throw new Error("In finding fn.kind()= " + fn.kind());
+        throw new Error("In finding fn.kind()= " + fn.kind());
       }
 
 
-      
+
       Hashtable<TempDescriptor,Integer> oldtable=temptable.get(fn);
       if (oldtable==null||!oldtable.equals(currtable)) {
-       // Update table for this node
-       temptable.put(fn, currtable);
-       for(int i=0; i<fn.numNext(); i++) {
-         tovisit.add(fn.getNext(i));
-       }
+        // Update table for this node
+        temptable.put(fn, currtable);
+        for(int i=0; i<fn.numNext(); i++) {
+          tovisit.add(fn.getNext(i));
+        }
       }
     }
   }
@@ -437,31 +457,31 @@ public class LocalityAnalysis {
       if (nodemd.getClassDesc().getSymbol().equals(TypeUtil.ThreadClass)&&
           nodemd.getSymbol().equals("start")&&!nodemd.getModifiers().isStatic()&&
           nodemd.numParameters()==0) {
-       assert(nodemd.getModifiers().isNative());
-
-       MethodDescriptor runmd=null;
-       for(Iterator methodit=nodemd.getClassDesc().getMethodTable().getSet("staticStart").iterator(); methodit.hasNext();) {
-         MethodDescriptor md=(MethodDescriptor) methodit.next();
-         if (md.numParameters()!=1||!md.getModifiers().isStatic()||!md.getParamType(0).getSymbol().equals(TypeUtil.ThreadClass))
-           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");
+        assert(nodemd.getModifiers().isNative());
+
+        MethodDescriptor runmd=null;
+        for(Iterator methodit=nodemd.getClassDesc().getMethodTable().getSet("staticStart").iterator(); methodit.hasNext(); ) {
+          MethodDescriptor md=(MethodDescriptor) methodit.next();
+          if (md.numParameters()!=1||!md.getModifiers().isStatic()||!md.getParamType(0).getSymbol().equals(TypeUtil.ThreadClass))
+            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");
       }
     }
 
     Integer currreturnval=STMEITHER;     //Start off with the either value
     if (oldtable!=null&&fc.getReturnTemp()!=null&&
-       oldtable.get(fc.getReturnTemp())!=null) {
+        oldtable.get(fc.getReturnTemp())!=null) {
       //ensure termination
       currreturnval=mergestm(currreturnval, oldtable.get(fc.getReturnTemp()));
     }
 
-    for(Iterator methodit=methodset.iterator(); methodit.hasNext();) {
+    for(Iterator methodit=methodset.iterator(); methodit.hasNext(); ) {
       MethodDescriptor md=(MethodDescriptor) methodit.next();
 
       boolean isnative=md.getModifiers().isNative();
@@ -471,62 +491,62 @@ public class LocalityAnalysis {
 
       LocalityBinding lb=new LocalityBinding(md, isatomic);
       if (isnative&&isatomic) {
-       System.out.println("Don't call native methods in atomic blocks!"+currlb.getMethod());
+        System.out.println("Don't call native methods in atomic blocks!"+currlb.getMethod());
       }
 
       if (runmethodset==null||!runmethodset.contains(md)) {
-       for(int i=0; i<fc.numArgs(); i++) {
-         TempDescriptor arg=fc.getArg(i);
-         lb.setGlobal(i,currtable.get(arg));
-       }
-       if (fc.getThis()!=null) {
-         Integer thistype=currtable.get(fc.getThis());
-         if (thistype==null)
-           thistype=STMEITHER;
-         
-         if(thistype.equals(STMCONFLICT))
-           throw new Error("Using type that can be either normal or scratch in context:\n"+currlb.getExplanation());
-         lb.setGlobalThis(thistype);
-       }
+        for(int i=0; i<fc.numArgs(); i++) {
+          TempDescriptor arg=fc.getArg(i);
+          if (currtable.containsKey(arg))
+            lb.setGlobal(i,currtable.get(arg));
+        }
+        if (fc.getThis()!=null) {
+          Integer thistype=currtable.get(fc.getThis());
+          if (thistype==null)
+            thistype=STMEITHER;
+
+          if(thistype.equals(STMCONFLICT))
+            throw new Error("Using type that can be either normal or scratch in context:\n"+currlb.getExplanation());
+          lb.setGlobalThis(thistype);
+        }
       } else {
-       Integer thistype=currtable.get(fc.getThis());
-       if (!thistype.equals(NORMAL)) {
-         throw new Error("Called start on possible scratch object");
-       }
-       lb.setGlobal(0,currtable.get(fc.getThis()));
+        Integer thistype=currtable.get(fc.getThis());
+        if (!thistype.equals(NORMAL)&&!thistype.equals(STMEITHER)) {
+          throw new Error("Called start on possible scratch object"+thistype);
+        }
+        lb.setGlobal(0,currtable.get(fc.getThis()));
       }
       //lb is built
       if (!discovered.containsKey(lb)) {
-       if (isnative) {
-         if (nodemd.getReturnType()==null||!nodemd.getReturnType().isPtr())
-           lb.setGlobalReturn(SCRATCH);
-         else
-           lb.setGlobalReturn(NORMAL);
-       } else
-         lb.setGlobalReturn(STMEITHER);
-
-       lb.setParent(currlb);
-       lbtovisit.add(lb);
-       discovered.put(lb, lb);
-       if (!classtolb.containsKey(lb.getMethod().getClassDesc()))
-         classtolb.put(lb.getMethod().getClassDesc(), new HashSet<LocalityBinding>());
-       classtolb.get(lb.getMethod().getClassDesc()).add(lb);
-       if (!methodtolb.containsKey(lb.getMethod()))
-         methodtolb.put(lb.getMethod(), new HashSet<LocalityBinding>());
-       methodtolb.get(lb.getMethod()).add(lb);
+        if (isnative) {
+          if (nodemd.getReturnType()!=null&&nodemd.getReturnType().isPtr())
+            lb.setGlobalReturn(NORMAL);
+        } else
+          lb.setGlobalReturn(STMEITHER);
+
+        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>());
+        classtolb.get(lb.getMethod().getClassDesc()).add(lb);
+        if (!methodtolb.containsKey(lb.getMethod()))
+          methodtolb.put(lb.getMethod(), new HashSet<LocalityBinding>());
+        methodtolb.get(lb.getMethod()).add(lb);
       } else
-       lb=discovered.get(lb);
+        lb=discovered.get(lb);
       Integer returnval=lb.getGlobalReturn();
       currreturnval=mergestm(returnval, currreturnval);
       if (!dependence.containsKey(lb))
-       dependence.put(lb, new HashSet<LocalityBinding>());
+        dependence.put(lb, new HashSet<LocalityBinding>());
       dependence.get(lb).add(currlb);
 
       if (!calldep.containsKey(currlb))
-       calldep.put(currlb, new HashSet<LocalityBinding>());
+        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);
     }
   }
@@ -534,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());
     }
@@ -555,22 +572,21 @@ public class LocalityAnalysis {
   void processSetFieldNodeSTM(LocalityBinding lb, FlatSetFieldNode fsfn, Hashtable<TempDescriptor, Integer> currtable) {
     Integer srctype=currtable.get(fsfn.getSrc());
     Integer dsttype=currtable.get(fsfn.getDst());
+    if (!fsfn.getSrc().getType().isPtr())
+      return;
+
     if (dsttype==null)
       System.out.println(fsfn);
     if (dsttype.equals(SCRATCH)) {
-      if (srctype.equals(SCRATCH) && fsfn.getField().getType().isPrimitive() && !fsfn.getField().getType().isArray())
-       return;
       if (!(srctype.equals(SCRATCH)||srctype.equals(STMEITHER)))
-       throw new Error("Writing possible normal reference to scratch object in context: \n"+lb.getExplanation());
+        throw new Error("Writing possible normal reference to scratch object in context: \n"+lb.getExplanation());
     } else if (dsttype.equals(NORMAL)) {
       //okay to store primitives in global object
-      if (srctype.equals(SCRATCH) && fsfn.getField().getType().isPrimitive() && !fsfn.getField().getType().isArray())
-       return;
       if (!(srctype.equals(NORMAL)||srctype.equals(STMEITHER)))
-       throw new Error("Writing possible scratch reference to normal object in context:\n"+lb.getExplanation()+" for FlatFieldNode "+fsfn);
+        throw new Error("Writing possible scratch reference to normal object in context:\n"+lb.getExplanation()+" for FlatFieldNode "+fsfn);
     } else if (dsttype.equals(STMEITHER)) {
       if (srctype.equals(STMCONFLICT))
-       throw new Error("Using reference that could be scratch or normal in context:\n"+lb.getExplanation());
+        throw new Error("Using reference that could be scratch or normal in context:\n"+lb.getExplanation());
     } else if (dsttype.equals(STMCONFLICT)) {
       throw new Error("Access to object that could be either scratch or normal in context:\n"+lb.getExplanation());
     }
@@ -579,78 +595,78 @@ public class LocalityAnalysis {
   void processSetElementNodeSTM(LocalityBinding lb, FlatSetElementNode fsen, Hashtable<TempDescriptor, Integer> currtable) {
     Integer srctype=currtable.get(fsen.getSrc());
     Integer dsttype=currtable.get(fsen.getDst());
+    if (!fsen.getSrc().getType().isPtr())
+      return;
 
     if (dsttype.equals(SCRATCH)) {
       if (!(srctype.equals(SCRATCH)||srctype.equals(STMEITHER)))
-       throw new Error("Writing possible normal reference to scratch object in context:\n"+lb.getExplanation()+fsen);
+        throw new Error("Writing possible normal reference to scratch object in context:\n"+lb.getExplanation()+fsen);
     } else if (dsttype.equals(NORMAL)) {
-      if (srctype.equals(SCRATCH) && fsen.getDst().getType().dereference().isPrimitive() && !fsen.getDst().getType().dereference().isArray())
-       return;
       if (!(srctype.equals(NORMAL)||srctype.equals(STMEITHER)))
-       throw new Error("Writing possible scratch reference to normal object in context:\n"+lb.getExplanation());
+        throw new Error("Writing possible scratch reference to normal object in context:\n"+lb.getExplanation());
     } else if (dsttype.equals(STMEITHER)) {
       if (srctype.equals(STMCONFLICT))
-       throw new Error("Using reference that could be scratch or normal in context:\n"+lb.getExplanation());
+        throw new Error("Using reference that could be scratch or normal in context:\n"+lb.getExplanation());
     } else if (dsttype.equals(STMCONFLICT)) {
       throw new Error("Access to object that could be either normal or scratch in context:\n"+lb.getExplanation());
     }
   }
 
-  void processOpNodeSTM(FlatOpNode fon, Hashtable<TempDescriptor, Integer> currtable) {
+  void processOpNodeSTM(LocalityBinding lb, FlatOpNode fon, Hashtable<TempDescriptor, Integer> currtable) {
     /* Just propagate value */
+    if (!fon.getLeft().getType().isPtr())
+      return;
+
     Integer srcvalue=currtable.get(fon.getLeft());
-    
+
     if (srcvalue==null) {
-      if (!fon.getLeft().getType().isPtr()) {
-       srcvalue=SCRATCH;
-      } else
-       throw new Error(fon.getLeft()+" is undefined!");
+      System.out.println(fon);
+      MethodDescriptor md=lb.getMethod();
+      FlatMethod fm=state.getMethodFlat(md);
+      System.out.println(fm.printMethod());
+      throw new Error(fon.getLeft()+" is undefined!");
     }
     currtable.put(fon.getDest(), srcvalue);
   }
-  
-   void processCastNodeSTM(FlatCastNode fcn, Hashtable<TempDescriptor, Integer> currtable) {
-    currtable.put(fcn.getDst(), currtable.get(fcn.getSrc()));
+
+  void processCastNodeSTM(FlatCastNode fcn, Hashtable<TempDescriptor, Integer> currtable) {
+    if (currtable.containsKey(fcn.getSrc()))
+      currtable.put(fcn.getDst(), currtable.get(fcn.getSrc()));
   }
 
   void processReturnNodeSTM(LocalityBinding lb, FlatReturnNode frn, Hashtable<TempDescriptor, Integer> currtable) {
-    if(frn.getReturnTemp()!=null) {
+    if(frn.getReturnTemp()!=null&&frn.getReturnTemp().getType().isPtr()) {
       Integer returntype=currtable.get(frn.getReturnTemp());
       lb.setGlobalReturn(mergestm(returntype, lb.getGlobalReturn()));
     }
   }
-  
-   void processLiteralNodeSTM(FlatLiteralNode fln, Hashtable<TempDescriptor, Integer> currtable) {
+
+  void processLiteralNodeSTM(FlatLiteralNode fln, Hashtable<TempDescriptor, Integer> currtable) {
     //null is either
-     if (fln.getType().isNull())
-       currtable.put(fln.getDst(), STMEITHER);
-     else if (fln.getType().isPtr())
-       currtable.put(fln.getDst(), NORMAL);
-     else
-       currtable.put(fln.getDst(), SCRATCH);
+    if (fln.getType().isNull())
+      currtable.put(fln.getDst(), STMEITHER);
+    else if (fln.getType().isPtr())
+      currtable.put(fln.getDst(), NORMAL);
   }
 
   void processElementNodeSTM(LocalityBinding lb, FlatElementNode fen, Hashtable<TempDescriptor, Integer> currtable) {
     Integer type=currtable.get(fen.getSrc());
     TempDescriptor dst=fen.getDst();
+    if (!fen.getDst().getType().isPtr())
+      return;
 
     if (type==null) {
       System.out.println(fen +" in "+lb+" may access undefined variable");
+      MethodDescriptor md=lb.getMethod();
+      FlatMethod fm=state.getMethodFlat(md);
+      System.out.println(fm.printMethod());
       System.exit(-1);
     } else if (type.equals(SCRATCH)) {
       currtable.put(dst,SCRATCH);
     } else if (type.equals(NORMAL)) {
-      if(fen.getSrc().getType().dereference().isPrimitive()&&
-         !fen.getSrc().getType().dereference().isArray())
-       currtable.put(dst, SCRATCH);
-      else
-       currtable.put(dst, NORMAL);
+      currtable.put(dst, NORMAL);
     } else if (type.equals(STMEITHER)) {
-      if(fen.getSrc().getType().dereference().isPrimitive()&&
-         !fen.getSrc().getType().dereference().isArray())
-       currtable.put(dst, SCRATCH);
-      else
-       currtable.put(dst, STMEITHER);
+      currtable.put(dst, STMEITHER);
     } else if (type.equals(STMCONFLICT)) {
       throw new Error("Access to object that could be either global or local in context:\n"+lb.getExplanation());
     }
@@ -684,27 +700,45 @@ public class LocalityAnalysis {
       methodtolb.put(lbrun.getMethod(), new HashSet<LocalityBinding>());
     methodtolb.get(lbrun.getMethod()).add(lbrun);
 
-    while(!lbtovisit.empty()) {
-      LocalityBinding lb=(LocalityBinding) lbtovisit.pop();
+    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>>();
       Hashtable<FlatNode, Integer> atomictable=new Hashtable<FlatNode, Integer>();
       calldep.remove(lb);
       try {
-       computeCallsFlags(md, lb, temptable, atomictable);
+        computeCallsFlags(md, lb, temptable, atomictable);
       } catch (Error e) {
-       System.out.println("Error in "+md+" context "+lb);
-       e.printStackTrace();
-       System.exit(-1);
+        System.out.println("Error in "+md+" context "+lb);
+        e.printStackTrace();
+        System.exit(-1);
       }
       temptab.put(lb, temptable);
       atomictab.put(lb, atomictable);
 
       if (md.getReturnType()!=null&&!returnglobal.equals(lb.getGlobalReturn())) {
-       //return type is more precise now
-       //rerun everything that call us
-       lbtovisit.addAll(dependence.get(lb));
+        //return type is more precise now
+        //rerun everything that call us
+        lbtovisit.addAll(dependence.get(lb));
       }
     }
   }
@@ -720,15 +754,15 @@ public class LocalityAnalysis {
       // Build table for initial node
       Hashtable<TempDescriptor,Integer> table=new Hashtable<TempDescriptor,Integer>();
       temptable.put(fm, table);
-      atomictable.put(fm, lb.isAtomic() ? 1 : 0);
-      int offset=md.isStatic() ? 0 : 1;
+      atomictable.put(fm, lb.isAtomic()?1:0);
+      int offset=md.isStatic()?0:1;
       if (!md.isStatic()) {
-       table.put(fm.getParameter(0), lb.getGlobalThis());
+        table.put(fm.getParameter(0), lb.getGlobalThis());
       }
       for(int i=offset; i<fm.numParameters(); i++) {
-       TempDescriptor temp=fm.getParameter(i);
-       Integer b=lb.isGlobal(i-offset);
-       table.put(temp,b);
+        TempDescriptor temp=fm.getParameter(i);
+        Integer b=lb.isGlobal(i-offset);
+        table.put(temp,b);
       }
     }
 
@@ -738,73 +772,74 @@ public class LocalityAnalysis {
       Hashtable<TempDescriptor, Integer> currtable=new Hashtable<TempDescriptor, Integer>();
       int atomicstate=0;
       for(int i=0; i<fn.numPrev(); i++) {
-       FlatNode prevnode=fn.getPrev(i);
-       if (atomictable.containsKey(prevnode)) {
-         atomicstate=atomictable.get(prevnode).intValue();
-       }
-       if (!temptable.containsKey(prevnode))
-         continue;
-       Hashtable<TempDescriptor, Integer> prevtable=temptable.get(prevnode);
-       for(Iterator<TempDescriptor> tempit=prevtable.keySet().iterator(); tempit.hasNext();) {
-         TempDescriptor temp=tempit.next();
-         Integer tmpint=prevtable.get(temp);
-         Integer oldint=currtable.containsKey(temp) ? currtable.get(temp) : EITHER;
-         Integer newint=merge(tmpint, oldint);
-         currtable.put(temp, newint);
-       }
+        FlatNode prevnode=fn.getPrev(i);
+        if (atomictable.containsKey(prevnode)) {
+          atomicstate=atomictable.get(prevnode).intValue();
+        }
+        if (!temptable.containsKey(prevnode))
+          continue;
+        Hashtable<TempDescriptor, Integer> prevtable=temptable.get(prevnode);
+        for(Iterator<TempDescriptor> tempit=prevtable.keySet().iterator(); tempit.hasNext(); ) {
+          TempDescriptor temp=tempit.next();
+          Integer tmpint=prevtable.get(temp);
+          Integer oldint=currtable.containsKey(temp)?currtable.get(temp):EITHER;
+          Integer newint=merge(tmpint, oldint);
+          currtable.put(temp, newint);
+        }
       }
       atomictable.put(fn, atomicstate);
+
       // Process this node
       switch(fn.kind()) {
       case FKind.FlatAtomicEnterNode:
-       processAtomicEnterNode((FlatAtomicEnterNode)fn, atomictable);
-       if (!lb.isAtomic())
-         lb.setHasAtomic();
-       break;
+        processAtomicEnterNode((FlatAtomicEnterNode)fn, atomictable);
+        if (!lb.isAtomic())
+          lb.setHasAtomic();
+        break;
 
       case FKind.FlatAtomicExitNode:
-       processAtomicExitNode((FlatAtomicExitNode)fn, atomictable);
-       break;
+        processAtomicExitNode((FlatAtomicExitNode)fn, atomictable);
+        break;
 
       case FKind.FlatCall:
-       processCallNode(lb, (FlatCall)fn, currtable, isAtomic(atomictable, fn));
-       break;
+        processCallNode(lb, (FlatCall)fn, currtable, isAtomic(atomictable, fn), temptable.get(fn));
+        break;
 
       case FKind.FlatFieldNode:
-       processFieldNode(lb, (FlatFieldNode)fn, isAtomic(atomictable, fn), currtable);
-       break;
+        processFieldNode(lb, (FlatFieldNode)fn, isAtomic(atomictable, fn), currtable);
+        break;
 
       case FKind.FlatSetFieldNode:
-       processSetFieldNode(lb, (FlatSetFieldNode)fn, isAtomic(atomictable,fn), currtable);
-       break;
+        processSetFieldNode(lb, (FlatSetFieldNode)fn, isAtomic(atomictable,fn), currtable);
+        break;
 
       case FKind.FlatNew:
-       processNew(lb, (FlatNew)fn, isAtomic(atomictable, fn), currtable);
-       break;
+        processNew(lb, (FlatNew)fn, isAtomic(atomictable, fn), currtable);
+        break;
 
       case FKind.FlatOpNode:
-       processOpNode((FlatOpNode)fn, currtable);
-       break;
+        processOpNode((FlatOpNode)fn, currtable);
+        break;
 
       case FKind.FlatCastNode:
-       processCastNode((FlatCastNode)fn, currtable);
-       break;
+        processCastNode((FlatCastNode)fn, currtable);
+        break;
 
       case FKind.FlatLiteralNode:
-       processLiteralNode((FlatLiteralNode)fn, currtable);
-       break;
+        processLiteralNode((FlatLiteralNode)fn, currtable);
+        break;
 
       case FKind.FlatReturnNode:
-       processReturnNode(lb, (FlatReturnNode)fn, currtable);
-       break;
+        processReturnNode(lb, (FlatReturnNode)fn, currtable);
+        break;
 
       case FKind.FlatSetElementNode:
-       processSetElementNode(lb, (FlatSetElementNode)fn, currtable, isAtomic(atomictable, fn));
-       break;
+        processSetElementNode(lb, (FlatSetElementNode)fn, currtable, isAtomic(atomictable, fn));
+        break;
 
       case FKind.FlatElementNode:
-       processElementNode(lb, (FlatElementNode)fn, currtable, isAtomic(atomictable, fn));
-       break;
+        processElementNode(lb, (FlatElementNode)fn, currtable, isAtomic(atomictable, fn));
+        break;
 
       case FKind.FlatInstanceOfNode:
       case FKind.FlatCondBranch:
@@ -812,31 +847,31 @@ public class LocalityAnalysis {
       case FKind.FlatNop:
       case FKind.FlatExit:
       case FKind.FlatPrefetchNode:
-       //No action needed for these
-       break;
+        //No action needed for these
+        break;
 
       case FKind.FlatFlagActionNode:
       case FKind.FlatCheckNode:
       case FKind.FlatTagDeclaration:
-       throw new Error("Incompatible with tasks!");
+        throw new Error("Incompatible with tasks!");
 
       case FKind.FlatMethod:
-       break;
+        break;
 
       case FKind.FlatOffsetNode:
-       processOffsetNode((FlatOffsetNode)fn, currtable);
-       break;
+        processOffsetNode((FlatOffsetNode)fn, currtable);
+        break;
 
       default:
-       throw new Error("In finding fn.kind()= " + fn.kind());
+        throw new Error("In finding fn.kind()= " + fn.kind());
       }
       Hashtable<TempDescriptor,Integer> oldtable=temptable.get(fn);
       if (oldtable==null||!oldtable.equals(currtable)) {
-       // Update table for this node
-       temptable.put(fn, currtable);
-       for(int i=0; i<fn.numNext(); i++) {
-         tovisit.add(fn.getNext(i));
-       }
+        // Update table for this node
+        temptable.put(fn, currtable);
+        for(int i=0; i<fn.numNext(); i++) {
+          tovisit.add(fn.getNext(i));
+        }
       }
     }
   }
@@ -855,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();
@@ -869,25 +905,57 @@ 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());
-
-       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");
+        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");
+      }
+
+      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
-    for(Iterator methodit=methodset.iterator(); methodit.hasNext();) {
+    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();
 
       boolean isnative=md.getModifiers().isNative();
@@ -897,62 +965,64 @@ public class LocalityAnalysis {
 
       LocalityBinding lb=new LocalityBinding(md, isatomic);
       if (isnative&&isatomic) {
-       System.out.println("Don't call native methods in atomic blocks!"+currlb.getMethod());
+        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
-       for(int i=0; i<fc.numArgs(); i++) {
-         TempDescriptor arg=fc.getArg(i);
-         if(isnative&&(currtable.get(arg).equals(GLOBAL)||
-                       currtable.get(arg).equals(CONFLICT))&& !(nodemd.getSymbol().equals("rangePrefetch"))) {
-           throw new Error("Potential call to native method "+md+" with global parameter:\n"+currlb.getExplanation());
-         }
-         lb.setGlobal(i,currtable.get(arg));
-       }
+
+      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)||
+                        currtable.get(arg).equals(CONFLICT))&& !(nodemd.getSymbol().equals("rangePrefetch"))) {
+            throw new Error("Potential call to native method "+md+" with global parameter:\n"+currlb.getExplanation());
+          }
+          lb.setGlobal(i,currtable.get(arg));
+        }
       }
 
       if (fc.getThis()!=null) {
-       Integer thistype=currtable.get(fc.getThis());
-       if (thistype==null)
-         thistype=EITHER;
-
-       if(runmethodset!=null&&runmethodset.contains(md)&&thistype.equals(LOCAL))
-         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)
-         throw new Error("Using global object outside of transaction in context:\n"+currlb.getExplanation());
-       if (runmethodset==null&&isnative&&thistype.equals(GLOBAL) && !isjoin && !isObjectgetType && !isObjecthashCode)
-         throw new Error("Potential call to native method "+md+" on global objects:\n"+currlb.getExplanation());
-       lb.setGlobalThis(thistype);
+        Integer thistype=currtable.get(fc.getThis());
+        if (thistype==null)
+          thistype=EITHER;
+
+        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 && executemethodset == null) {
+          throw new Error("Using global object outside of transaction in context:\n"+currlb.getExplanation());
+        }
+        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);
       }
       //lb is built
       if (!discovered.containsKey(lb)) {
-       if (isnative)
-         lb.setGlobalReturn(LOCAL);
-       else
-         lb.setGlobalReturn(EITHER);
-       lb.setParent(currlb);
-       lbtovisit.add(lb);
-       discovered.put(lb, lb);
-       if (!classtolb.containsKey(lb.getMethod().getClassDesc()))
-         classtolb.put(lb.getMethod().getClassDesc(), new HashSet<LocalityBinding>());
-       classtolb.get(lb.getMethod().getClassDesc()).add(lb);
-       if (!methodtolb.containsKey(lb.getMethod()))
-         methodtolb.put(lb.getMethod(), new HashSet<LocalityBinding>());
-       methodtolb.get(lb.getMethod()).add(lb);
+        if (isnative)
+          lb.setGlobalReturn(LOCAL);
+        else
+          lb.setGlobalReturn(EITHER);
+        lb.setParent(currlb);
+        lbtovisit.add(lb);
+        discovered.put(lb, lb);
+        if (!classtolb.containsKey(lb.getMethod().getClassDesc()))
+          classtolb.put(lb.getMethod().getClassDesc(), new HashSet<LocalityBinding>());
+        classtolb.get(lb.getMethod().getClassDesc()).add(lb);
+        if (!methodtolb.containsKey(lb.getMethod()))
+          methodtolb.put(lb.getMethod(), new HashSet<LocalityBinding>());
+        methodtolb.get(lb.getMethod()).add(lb);
       } else
-       lb=discovered.get(lb);
+        lb=discovered.get(lb);
       Integer returnval=lb.getGlobalReturn();
       currreturnval=merge(returnval, currreturnval);
       if (!dependence.containsKey(lb))
-       dependence.put(lb, new HashSet<LocalityBinding>());
+        dependence.put(lb, new HashSet<LocalityBinding>());
       dependence.get(lb).add(currlb);
 
       if (!calldep.containsKey(currlb))
-       calldep.put(currlb, new HashSet<LocalityBinding>());
+        calldep.put(currlb, new HashSet<LocalityBinding>());
       calldep.get(currlb).add(lb);
     }
     if (fc.getReturnTemp()!=null) {
@@ -965,23 +1035,23 @@ public class LocalityAnalysis {
     TempDescriptor dst=ffn.getDst();
     if (type.equals(LOCAL)) {
       if (ffn.getField().isGlobal())
-       currtable.put(dst,GLOBAL);
+        currtable.put(dst,GLOBAL);
       else
-       currtable.put(dst,LOCAL);
+        currtable.put(dst,LOCAL);
     } else if (type.equals(GLOBAL)) {
       if (!transaction)
-       throw new Error("Global access outside of a transaction in context:\n"+lb.getExplanation());
+        throw new Error("Global access outside of a transaction in context:\n"+lb.getExplanation());
       if (ffn.getField().getType().isPrimitive()&&!ffn.getField().getType().isArray())
-       currtable.put(dst, LOCAL);         // primitives are local
+        currtable.put(dst, LOCAL);         // primitives are local
       else
-       currtable.put(dst, GLOBAL);
+        currtable.put(dst, GLOBAL);
     } else if (type.equals(EITHER)) {
       if (ffn.getField().getType().isPrimitive()&&!ffn.getField().getType().isArray())
-       currtable.put(dst, LOCAL);         // primitives are local
+        currtable.put(dst, LOCAL);         // primitives are local
       else if (ffn.getField().isGlobal())
-       currtable.put(dst, GLOBAL);
+        currtable.put(dst, GLOBAL);
       else
-       currtable.put(dst, EITHER);
+        currtable.put(dst, EITHER);
     } else if (type.equals(CONFLICT)) {
       throw new Error("Access to object that could be either global or local in context:\n"+lb.getExplanation());
     }
@@ -994,23 +1064,24 @@ public class LocalityAnalysis {
 
     if (dsttype.equals(LOCAL)) {
       if (fsfn.getField().isGlobal()) {
-       if (!(srctype.equals(GLOBAL)||srctype.equals(EITHER)))
-         throw new Error("Writing possible local reference to global field in context: \n"+lb.getExplanation());
+        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)))
-         throw new Error("Writing possible global reference to local object in context: \n"+lb.getExplanation());
+        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)
-       throw new Error("Global access outside of a transaction in context:\n"+lb.getExplanation());
+        throw new Error("Global access outside of a transaction in context:\n"+lb.getExplanation());
       //okay to store primitives in global object
       if (srctype.equals(LOCAL) && fsfn.getField().getType().isPrimitive() && !fsfn.getField().getType().isArray())
-       return;
+        return;
       if (!(srctype.equals(GLOBAL)||srctype.equals(EITHER)))
-       throw new Error("Writing possible local reference to global object in context:\n"+lb.getExplanation()+" for FlatFieldNode "+fsfn);
+        throw new Error("Writing possible local reference to global object in context:\n"+lb.getExplanation()+" for FlatFieldNode "+fsfn);
     } else if (dsttype.equals(EITHER)) {
       if (srctype.equals(CONFLICT))
-       throw new Error("Using reference that could be local or global in context:\n"+lb.getExplanation());
+        throw new Error("Using reference that could be local or global in context:\n"+lb.getExplanation());
     } else if (dsttype.equals(CONFLICT)) {
       throw new Error("Access to object that could be either global or local in context:\n"+lb.getExplanation());
     }
@@ -1032,9 +1103,9 @@ public class LocalityAnalysis {
 
     if (srcvalue==null) {
       if (!fon.getLeft().getType().isPtr()) {
-       srcvalue=LOCAL;
+        srcvalue=LOCAL;
       } else
-       throw new Error(fon.getLeft()+" is undefined!");
+        throw new Error(fon.getLeft()+" is undefined!");
     }
     currtable.put(fon.getDest(), srcvalue);
   }
@@ -1067,18 +1138,19 @@ public class LocalityAnalysis {
     Integer dsttype=currtable.get(fsen.getDst());
 
     if (dsttype.equals(LOCAL)) {
-      if (!(srctype.equals(LOCAL)||srctype.equals(EITHER)))
-       throw new Error("Writing possible global reference to local object in context:\n"+lb.getExplanation()+fsen);
+      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;
+        return;
       if (!(srctype.equals(GLOBAL)||srctype.equals(EITHER)))
-       throw new Error("Writing possible local reference to global object in context:\n"+lb.getExplanation());
+        throw new Error("Writing possible local reference to global object in context:\n"+lb.getExplanation());
       if (!isatomic)
-       throw new Error("Global access outside of a transaction in context:\n"+lb.getExplanation());
+        throw new Error("Global access outside of a transaction in context:\n"+lb.getExplanation());
     } else if (dsttype.equals(EITHER)) {
       if (srctype.equals(CONFLICT))
-       throw new Error("Using reference that could be local or global in context:\n"+lb.getExplanation());
+        throw new Error("Using reference that could be local or global in context:\n"+lb.getExplanation());
     } else if (dsttype.equals(CONFLICT)) {
       throw new Error("Access to object that could be either global or local in context:\n"+lb.getExplanation());
     }
@@ -1091,18 +1163,18 @@ public class LocalityAnalysis {
       currtable.put(dst,LOCAL);
     } else if (type.equals(GLOBAL)) {
       if (!isatomic)
-       throw new Error("Global access outside of a transaction in context:\n"+lb.getExplanation());
+        throw new Error("Global access outside of a transaction in context:\n"+lb.getExplanation());
       if(fen.getSrc().getType().dereference().isPrimitive()&&
          !fen.getSrc().getType().dereference().isArray())
-       currtable.put(dst, LOCAL);
+        currtable.put(dst, LOCAL);
       else
-       currtable.put(dst, GLOBAL);
+        currtable.put(dst, GLOBAL);
     } else if (type.equals(EITHER)) {
       if(fen.getSrc().getType().dereference().isPrimitive()&&
          !fen.getSrc().getType().dereference().isArray())
-       currtable.put(dst, LOCAL);
+        currtable.put(dst, LOCAL);
       else
-       currtable.put(dst, EITHER);
+        currtable.put(dst, EITHER);
     } else if (type.equals(CONFLICT)) {
       throw new Error("Access to object that could be either global or local in context:\n"+lb.getExplanation());
     }
@@ -1117,39 +1189,9 @@ public class LocalityAnalysis {
     int atomic=atomictable.get(fen).intValue();
     atomictable.put(fen, new Integer(atomic-1));
   }
-    
-  Hashtable<FlatNode, Set<TempDescriptor>> computeLiveTemps(FlatMethod fm) {
-    Hashtable<FlatNode, Set<TempDescriptor>> nodetotemps=new Hashtable<FlatNode, Set<TempDescriptor>>();
-
-    Set<FlatNode> toprocess=fm.getNodeSet();
-
-    while(!toprocess.isEmpty()) {
-      FlatNode fn=toprocess.iterator().next();
-      toprocess.remove(fn);
-
-      List<TempDescriptor> reads=Arrays.asList(fn.readsTemps());
-      List<TempDescriptor> writes=Arrays.asList(fn.writesTemps());
-
-      HashSet<TempDescriptor> tempset=new HashSet<TempDescriptor>();
-      for(int i=0; i<fn.numNext(); i++) {
-       FlatNode fnnext=fn.getNext(i);
-       if (nodetotemps.containsKey(fnnext))
-         tempset.addAll(nodetotemps.get(fnnext));
-      }
-      tempset.removeAll(writes);
-      tempset.addAll(reads);
-      if (!nodetotemps.containsKey(fn)||
-          !nodetotemps.get(fn).equals(tempset)) {
-       nodetotemps.put(fn, tempset);
-       for(int i=0; i<fn.numPrev(); i++)
-         toprocess.add(fn.getPrev(i));
-      }
-    }
-    return nodetotemps;
-  }
 
   private void computeTempstoSave() {
-    for(Iterator<LocalityBinding> lbit=getLocalityBindings().iterator(); lbit.hasNext();) {
+    for(Iterator<LocalityBinding> lbit=getLocalityBindings().iterator(); lbit.hasNext(); ) {
       LocalityBinding lb=lbit.next();
       computeTempstoSave(lb);
     }
@@ -1171,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>();
@@ -1185,39 +1227,39 @@ 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);
-       nodemap.put(fn, (FlatAtomicEnterNode)fn);
-       nodetosavetemps.put((FlatAtomicEnterNode)fn, new HashSet<TempDescriptor>());
+        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);
-       List<TempDescriptor> reads=Arrays.asList(fn.readsTemps());
-       List<TempDescriptor> writes=Arrays.asList(fn.readsTemps());
-
-       for(Iterator<TempDescriptor> tempit=livetemps.iterator(); tempit.hasNext();) {
-         TempDescriptor tmp=tempit.next();
-         if (writes.contains(tmp)) {
-           nodetosavetemps.get(atomicnode).add(tmp);
-         } else if (state.DSM) {
-           if (reads.contains(tmp)&&temptab.get(fn).get(tmp)==GLOBAL) {
-             nodetosavetemps.get(atomicnode).add(tmp);
-           } 
-         } else if (state.SINGLETM) {
-           if (reads.contains(tmp)&&tmp.getType().isPtr()&&temptab.get(fn).get(tmp)==NORMAL) {
-             nodetosavetemps.get(atomicnode).add(tmp);
-           } 
-         }
-       }
+        FlatAtomicEnterNode atomicnode=nodemap.get(fn);
+        Set<TempDescriptor> livetemps=nodetotemps.get(atomicnode);
+        List<TempDescriptor> reads=Arrays.asList(fn.readsTemps());
+        List<TempDescriptor> writes=Arrays.asList(fn.writesTemps());
+
+        for(Iterator<TempDescriptor> tempit=livetemps.iterator(); tempit.hasNext(); ) {
+          TempDescriptor tmp=tempit.next();
+          if (writes.contains(tmp)) {
+            nodetosavetemps.get(atomicnode).add(tmp);
+          } else if (state.DSM) {
+            if (reads.contains(tmp)&&temptab.get(fn).get(tmp)==GLOBAL) {
+              nodetosavetemps.get(atomicnode).add(tmp);
+            }
+          } else if (state.SINGLETM) {
+            if (reads.contains(tmp)&&tmp.getType().isPtr()&&temptab.get(fn).get(tmp)==NORMAL) {
+              nodetosavetemps.get(atomicnode).add(tmp);
+            }
+          }
+        }
       }
       for(int i=0; i<fn.numNext(); i++) {
-       FlatNode fnnext=fn.getNext(i);
-       if (!discovered.contains(fnnext)) {
-         discovered.add(fnnext);
-         toprocess.add(fnnext);
-         if(isatomic) {
-           nodemap.put(fnnext, nodemap.get(fn));
-         }
-       }
+        FlatNode fnnext=fn.getNext(i);
+        if (!discovered.contains(fnnext)) {
+          discovered.add(fnnext);
+          toprocess.add(fnnext);
+          if(isatomic) {
+            nodemap.put(fnnext, nodemap.get(fn));
+          }
+        }
       }
     }
   }