missing files
[IRC.git] / Robust / src / Analysis / Locality / DiscoverConflicts.java
index 9f35c7cc027d86af7a29d613449631f50b81c76e..7baa47e9522857e97e6aefb6ed5a90dba1c6927c 100644 (file)
@@ -11,6 +11,8 @@ import IR.Operation;
 import IR.TypeDescriptor;
 import IR.MethodDescriptor;
 import IR.FieldDescriptor;
+import Analysis.Liveness;
+import Analysis.Loops.GlobalFieldType;
 
 public class DiscoverConflicts {
   Set<FieldDescriptor> fields;
@@ -19,22 +21,75 @@ public class DiscoverConflicts {
   State state;
   Hashtable<LocalityBinding, Set<FlatNode>> treadmap;
   Hashtable<LocalityBinding, Set<TempFlatPair>> transreadmap;
+  Hashtable<LocalityBinding, Set<FlatNode>> twritemap;
+  Hashtable<LocalityBinding, Set<TempFlatPair>> writemap;
+  Hashtable<LocalityBinding, Set<FlatNode>> getmap;
+
   Hashtable<LocalityBinding, Set<FlatNode>> srcmap;
+  Hashtable<LocalityBinding, Set<FlatNode>> leftsrcmap;
+  Hashtable<LocalityBinding, Set<FlatNode>> rightsrcmap;
   TypeAnalysis typeanalysis;
-  
-  public DiscoverConflicts(LocalityAnalysis locality, State state, TypeAnalysis typeanalysis) {
+  Hashtable<LocalityBinding, HashSet<FlatNode>>cannotdelaymap;
+  Hashtable<LocalityBinding, Hashtable<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>>> lbtofnmap;
+  boolean inclusive=false;
+  boolean normalassign=false;
+  GlobalFieldType gft;
+
+  public DiscoverConflicts(LocalityAnalysis locality, State state, TypeAnalysis typeanalysis, GlobalFieldType gft) {
+    this.locality=locality;
+    this.fields=new HashSet<FieldDescriptor>();
+    this.arrays=new HashSet<TypeDescriptor>();
+    this.state=state;
+    this.typeanalysis=typeanalysis;
+    transreadmap=new Hashtable<LocalityBinding, Set<TempFlatPair>>();
+    treadmap=new Hashtable<LocalityBinding, Set<FlatNode>>();
+    srcmap=new Hashtable<LocalityBinding, Set<FlatNode>>();
+    leftsrcmap=new Hashtable<LocalityBinding, Set<FlatNode>>();
+    rightsrcmap=new Hashtable<LocalityBinding, Set<FlatNode>>();
+    lbtofnmap=new Hashtable<LocalityBinding, Hashtable<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>>>();
+    if (gft!=null) {
+      twritemap=new Hashtable<LocalityBinding, Set<FlatNode>>();
+      writemap=new Hashtable<LocalityBinding, Set<TempFlatPair>>();
+    }
+    getmap=new Hashtable<LocalityBinding, Set<FlatNode>>();
+    this.gft=gft;
+  }
+
+  public DiscoverConflicts(LocalityAnalysis locality, State state, TypeAnalysis typeanalysis, Hashtable<LocalityBinding, HashSet<FlatNode>> cannotdelaymap, boolean inclusive, boolean normalassign, GlobalFieldType gft) {
     this.locality=locality;
     this.fields=new HashSet<FieldDescriptor>();
     this.arrays=new HashSet<TypeDescriptor>();
     this.state=state;
     this.typeanalysis=typeanalysis;
+    this.cannotdelaymap=cannotdelaymap;
     transreadmap=new Hashtable<LocalityBinding, Set<TempFlatPair>>();
     treadmap=new Hashtable<LocalityBinding, Set<FlatNode>>();
     srcmap=new Hashtable<LocalityBinding, Set<FlatNode>>();
+    leftsrcmap=new Hashtable<LocalityBinding, Set<FlatNode>>();
+    rightsrcmap=new Hashtable<LocalityBinding, Set<FlatNode>>();
+    lbtofnmap=new Hashtable<LocalityBinding, Hashtable<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>>>();
+    this.inclusive=inclusive;
+    this.normalassign=normalassign;
+    if (gft!=null) {
+      twritemap=new Hashtable<LocalityBinding, Set<FlatNode>>();
+      writemap=new Hashtable<LocalityBinding, Set<TempFlatPair>>();
+    }
+    getmap=new Hashtable<LocalityBinding, Set<FlatNode>>();
+    this.gft=gft;
+  }
+
+  public Set<FieldDescriptor> getFields() {
+    return fields;
+  }
+
+  public Set<TypeDescriptor> getArrays() {
+    return arrays;
   }
   
   public void doAnalysis() {
-    //Compute fields and arrays for all transactions
+    //Compute fields and arrays for all transactions.  Note that we
+    //only look at changes to old objects
+
     Set<LocalityBinding> localityset=locality.getLocalityBindings();
     for(Iterator<LocalityBinding> lb=localityset.iterator();lb.hasNext();) {
       computeModified(lb.next());
@@ -44,19 +99,63 @@ public class DiscoverConflicts {
     for(Iterator<LocalityBinding> lb=localityset.iterator();lb.hasNext();) {
       LocalityBinding l=lb.next();
       analyzeLocality(l);
-      setNeedReadTrans(l);
     }
   }
 
-  public void setNeedReadTrans(LocalityBinding lb) {
+  //Change flatnode/temp pairs to just flatnodes that need transactional reads
+
+  private void setNeedReadTrans(LocalityBinding lb) {
     HashSet<FlatNode> set=new HashSet<FlatNode>();
     for(Iterator<TempFlatPair> it=transreadmap.get(lb).iterator();it.hasNext();) {
       TempFlatPair tfp=it.next();
       set.add(tfp.f);
     }
     treadmap.put(lb, set);
+    if (gft!=null) {
+      //need to translate write map set
+      set=new HashSet<FlatNode>();
+      for(Iterator<TempFlatPair> it=writemap.get(lb).iterator();it.hasNext();) {
+       TempFlatPair tfp=it.next();
+       set.add(tfp.f);
+      }
+      twritemap.put(lb, set);
+    }
   }
+  
+  private void computeneedsarrayget(LocalityBinding lb, Hashtable<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>> fnmap) {
+    //    Set<FlatNode> gwriteset=(state.READSET&&gft!=null)?twritemap.get(lb):treadmap.get(lb);
+    if (state.READSET&&gft!=null) {
+      if (twritemap.get(lb).size()==0) {
+       getmap.put(lb, new HashSet<FlatNode>());
+        return;
+      }
+    }
 
+    Set<FlatNode> gwriteset=treadmap.get(lb);
+    FlatMethod fm=state.getMethodFlat(lb.getMethod());
+    HashSet<FlatNode> needsget=new HashSet<FlatNode>();
+    for(Iterator<FlatNode> fnit=fm.getNodeSet().iterator();fnit.hasNext();) {
+      FlatNode fn=fnit.next();
+      Hashtable<FlatNode, Integer> atomictable=locality.getAtomic(lb);
+      if (atomictable.get(fn).intValue()>0&&fn.kind()==FKind.FlatElementNode) {
+       FlatElementNode fen=(FlatElementNode)fn;
+       Set<TempFlatPair> tfpset=fnmap.get(fen).get(fen.getSrc());
+       if (tfpset!=null) {
+         for(Iterator<TempFlatPair> tfpit=tfpset.iterator();tfpit.hasNext();) {
+           TempFlatPair tfp=tfpit.next();
+           if (gwriteset.contains(tfp.f)) {
+             needsget.add(fen);
+             break;
+           }
+         }
+       }
+      }
+    }
+    getmap.put(lb, needsget);
+  }
+
+  //We have a set of things we write to, figure out what things this
+  //could effect.
   public void expandTypes() {
     Set<TypeDescriptor> expandedarrays=new HashSet<TypeDescriptor>();
     for(Iterator<TypeDescriptor> it=arrays.iterator();it.hasNext();) {
@@ -92,27 +191,130 @@ public class DiscoverConflicts {
     return srcmap.get(lb).contains(fn);
   }
 
+  public boolean getNeedLeftSrcTrans(LocalityBinding lb, FlatNode fn) {
+    return leftsrcmap.get(lb).contains(fn);
+  }
+
+  public boolean getNeedRightSrcTrans(LocalityBinding lb, FlatNode fn) {
+    return rightsrcmap.get(lb).contains(fn);
+  }
+
   public boolean getNeedTrans(LocalityBinding lb, FlatNode fn) {
     return treadmap.get(lb).contains(fn);
   }
 
+  public boolean getNeedGet(LocalityBinding lb, FlatNode fn) {
+    if (gft!=null)
+      return getmap.get(lb).contains(fn);
+    else throw new Error();
+  }
+
+  public boolean getNeedWriteTrans(LocalityBinding lb, FlatNode fn) {
+    if (gft!=null)
+      return twritemap.get(lb).contains(fn);
+    else throw new Error();
+  }
+
+  public Hashtable<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>> getMap(LocalityBinding lb) {
+    return lbtofnmap.get(lb);
+  }
+
   private void analyzeLocality(LocalityBinding lb) {
     MethodDescriptor md=lb.getMethod();
     FlatMethod fm=state.getMethodFlat(md);
+
+    //Compute map from flatnode -> (temps -> source of value)
     Hashtable<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>> fnmap=computeTempSets(lb);
-    HashSet<TempFlatPair> tfset=computeTranslationSet(lb, fm, fnmap);
+    lbtofnmap.put(lb,fnmap);
+    HashSet<TempFlatPair> writeset=null;
+    if (gft!=null) {
+      writeset=new HashSet<TempFlatPair>();
+    }
+    HashSet<TempFlatPair> tfset=computeTranslationSet(lb, fm, fnmap, writeset);
+    if (gft!=null) {
+      writemap.put(lb, writeset);
+    }
+
     HashSet<FlatNode> srctrans=new HashSet<FlatNode>();
+    HashSet<FlatNode> leftsrctrans=new HashSet<FlatNode>();
+    HashSet<FlatNode> rightsrctrans=new HashSet<FlatNode>();
     transreadmap.put(lb, tfset);
     srcmap.put(lb,srctrans);
-    
+    leftsrcmap.put(lb,leftsrctrans);
+    rightsrcmap.put(lb,rightsrctrans);
+
+    //compute writes that need translation on source
     for(Iterator<FlatNode> fnit=fm.getNodeSet().iterator();fnit.hasNext();) {
       FlatNode fn=fnit.next();
       Hashtable<FlatNode, Integer> atomictable=locality.getAtomic(lb);
       if (atomictable.get(fn).intValue()>0) {
        Hashtable<TempDescriptor, Set<TempFlatPair>> tmap=fnmap.get(fn);
        switch(fn.kind()) {
+         //We might need to translate arguments to pointer comparison
+         
+       case FKind.FlatOpNode: { 
+         FlatOpNode fon=(FlatOpNode)fn;
+         if (fon.getOp().getOp()==Operation.EQUAL||
+             fon.getOp().getOp()==Operation.NOTEQUAL) {
+           if (!fon.getLeft().getType().isPtr())
+             break;
+           Set<TempFlatPair> lefttfpset=tmap.get(fon.getLeft());
+           Set<TempFlatPair> righttfpset=tmap.get(fon.getRight());
+           //handle left operand
+           if (lefttfpset!=null) {
+             for(Iterator<TempFlatPair> tfpit=lefttfpset.iterator();tfpit.hasNext();) {
+               TempFlatPair tfp=tfpit.next();
+               if (tfset.contains(tfp)||outofscope(tfp)) {
+                 leftsrctrans.add(fon);
+                 break;
+               }
+             }
+           }
+           //handle right operand
+           if (righttfpset!=null) {
+             for(Iterator<TempFlatPair> tfpit=righttfpset.iterator();tfpit.hasNext();) {
+               TempFlatPair tfp=tfpit.next();
+               if (tfset.contains(tfp)||outofscope(tfp)) {
+                 rightsrctrans.add(fon);
+                 break;
+               }
+             }
+           }
+         }
+         break;
+       }
+
+       case FKind.FlatGlobalConvNode: { 
+         //need to translate these if the value we read from may be a
+         //shadow...  check this by seeing if any of the values we
+         //may read are in the transread set or came from our caller
+         //or a method we called
+
+         FlatGlobalConvNode fgcn=(FlatGlobalConvNode)fn;
+         if (fgcn.getLocality()!=lb||
+             fgcn.getMakePtr())
+           break;
+
+         Set<TempFlatPair> tfpset=tmap.get(fgcn.getSrc());
+
+         if (tfpset!=null) {
+           for(Iterator<TempFlatPair> tfpit=tfpset.iterator();tfpit.hasNext();) {
+             TempFlatPair tfp=tfpit.next();
+             if (tfset.contains(tfp)||outofscope(tfp)) {
+               srctrans.add(fgcn);
+               break;
+             }
+           }
+         }
+         break;
+       }
+
        case FKind.FlatSetFieldNode: { 
-         //definitely need to translate these
+         //need to translate these if the value we read from may be a
+         //shadow...  check this by seeing if any of the values we
+         //may read are in the transread set or came from our caller
+         //or a method we called
+
          FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
          if (!fsfn.getField().getType().isPtr())
            break;
@@ -120,7 +322,7 @@ public class DiscoverConflicts {
          if (tfpset!=null) {
            for(Iterator<TempFlatPair> tfpit=tfpset.iterator();tfpit.hasNext();) {
              TempFlatPair tfp=tfpit.next();
-             if (tfset.contains(tfp)||ok(tfp)) {
+             if (tfset.contains(tfp)||outofscope(tfp)) {
                srctrans.add(fsfn);
                break;
              }
@@ -129,7 +331,11 @@ public class DiscoverConflicts {
          break;
        }
        case FKind.FlatSetElementNode: { 
-         //definitely need to translate these
+         //need to translate these if the value we read from may be a
+         //shadow...  check this by seeing if any of the values we
+         //may read are in the transread set or came from our caller
+         //or a method we called
+
          FlatSetElementNode fsen=(FlatSetElementNode)fn;
          if (!fsen.getSrc().getType().isPtr())
            break;
@@ -137,7 +343,7 @@ public class DiscoverConflicts {
          if (tfpset!=null) {
            for(Iterator<TempFlatPair> tfpit=tfpset.iterator();tfpit.hasNext();) {
              TempFlatPair tfp=tfpit.next();
-             if (tfset.contains(tfp)||ok(tfp)) {
+             if (tfset.contains(tfp)||outofscope(tfp)) {
                srctrans.add(fsen);
                break;
              }
@@ -149,18 +355,113 @@ public class DiscoverConflicts {
        }
       }
     }
+    //Update results
+    setNeedReadTrans(lb);
+    computeneedsarrayget(lb, fnmap);
   }
 
-  public boolean ok(TempFlatPair tfp) {
+  public boolean outofscope(TempFlatPair tfp) {
     FlatNode fn=tfp.f;
-    return fn.kind()==FKind.FlatCall;
+    return fn.kind()==FKind.FlatCall||fn.kind()==FKind.FlatMethod;
   }
 
-  HashSet<TempFlatPair> computeTranslationSet(LocalityBinding lb, FlatMethod fm, Hashtable<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>> fnmap) {
-    HashSet<TempFlatPair> tfset=new HashSet<TempFlatPair>();
+  private void computeReadOnly(LocalityBinding lb, Hashtable<FlatNode, Set<TypeDescriptor>> updatedtypemap, Hashtable<FlatNode, Set<FieldDescriptor>> updatedfieldmap) {
+    //inside of transaction, try to convert rw access to ro access
+    MethodDescriptor md=lb.getMethod();
+    FlatMethod fm=state.getMethodFlat(md);
+    Hashtable<FlatNode, Integer> atomictable=locality.getAtomic(lb);
+
+    HashSet<FlatNode> toanalyze=new HashSet<FlatNode>();
+    toanalyze.addAll(fm.getNodeSet());
     
+    while(!toanalyze.isEmpty()) {
+      FlatNode fn=toanalyze.iterator().next();
+      toanalyze.remove(fn);
+      HashSet<TypeDescriptor> updatetypeset=new HashSet<TypeDescriptor>();
+      HashSet<FieldDescriptor> updatefieldset=new HashSet<FieldDescriptor>();
+      
+      //Stop if we aren't in a transaction
+      if (atomictable.get(fn).intValue()==0)
+       continue;
+      
+      //Do merge of all exits
+      for(int i=0;i<fn.numNext();i++) {
+       FlatNode fnnext=fn.getNext(i);
+       if (updatedtypemap.containsKey(fnnext)) {
+         updatetypeset.addAll(updatedtypemap.get(fnnext));
+       }
+       if (updatedfieldmap.containsKey(fnnext)) {
+         updatefieldset.addAll(updatedfieldmap.get(fnnext));
+       }
+      }
+      
+      //process this node
+      if (cannotdelaymap!=null&&cannotdelaymap.containsKey(lb)&&cannotdelaymap.get(lb).contains(fn)!=inclusive) {
+       switch(fn.kind()) {
+       case FKind.FlatSetFieldNode: {
+         FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
+         updatefieldset.add(fsfn.getField());
+         break;
+       }
+       case FKind.FlatSetElementNode: {
+         FlatSetElementNode fsen=(FlatSetElementNode)fn;
+         updatetypeset.addAll(typeanalysis.expand(fsen.getDst().getType()));
+         break;
+       }
+       case FKind.FlatCall: {
+         FlatCall fcall=(FlatCall)fn;
+         MethodDescriptor mdfc=fcall.getMethod();
+         
+         //get modified fields
+         Set<FieldDescriptor> fields=gft.getFieldsAll(mdfc);
+         updatefieldset.addAll(fields);
+         
+         //get modified arrays
+         Set<TypeDescriptor> arrays=gft.getArraysAll(mdfc);
+         updatetypeset.addAll(typeanalysis.expandSet(arrays));
+         break;
+       }
+       }
+      }
+      
+      if (!updatedtypemap.containsKey(fn)||!updatedfieldmap.containsKey(fn)||
+         !updatedtypemap.get(fn).equals(updatetypeset)||!updatedfieldmap.get(fn).equals(updatefieldset)) {
+       updatedtypemap.put(fn, updatetypeset);
+       updatedfieldmap.put(fn, updatefieldset);
+       for(int i=0;i<fn.numPrev();i++) {
+         toanalyze.add(fn.getPrev(i));
+       }
+      }
+    }
+  }
+
+
+  /** Need to figure out which nodes need a transread to make local
+  copies.  Transread conceptually tracks conflicts.  This depends on
+  what fields/elements are accessed We iterate over all flatnodes that
+  access fields...If these accesses could conflict, we mark the source
+  tempflat pair as needing a transread */
+
+  
+  HashSet<TempFlatPair> computeTranslationSet(LocalityBinding lb, FlatMethod fm, Hashtable<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>> fnmap, Set<TempFlatPair> writeset) {
+    HashSet<TempFlatPair> tfset=new HashSet<TempFlatPair>();
+
+    //Compute maps from flatnodes -> sets of things that may be updated after this node
+    Hashtable<FlatNode, Set<TypeDescriptor>> updatedtypemap=null;
+    Hashtable<FlatNode, Set<FieldDescriptor>> updatedfieldmap=null;
+
+    if (writeset!=null&&!lb.isAtomic()) {
+      updatedtypemap=new Hashtable<FlatNode, Set<TypeDescriptor>>();
+      updatedfieldmap=new Hashtable<FlatNode, Set<FieldDescriptor>>();
+      computeReadOnly(lb, updatedtypemap, updatedfieldmap);
+    }
+
     for(Iterator<FlatNode> fnit=fm.getNodeSet().iterator();fnit.hasNext();) {
       FlatNode fn=fnit.next();
+      //Check whether this node matters for cannot delayed computation
+      if (cannotdelaymap!=null&&cannotdelaymap.containsKey(lb)&&cannotdelaymap.get(lb).contains(fn)==inclusive)
+       continue;
+
       Hashtable<FlatNode, Integer> atomictable=locality.getAtomic(lb);
       if (atomictable.get(fn).intValue()>0) {
        Hashtable<TempDescriptor, Set<TempFlatPair>> tmap=fnmap.get(fn);
@@ -173,6 +474,12 @@ public class DiscoverConflicts {
            if (tfpset!=null)
              tfset.addAll(tfpset);
          }
+         if (updatedtypemap!=null&&updatedtypemap.get(fen).contains(fen.getSrc().getType())) {
+           //this could cause conflict...figure out conflict set
+           Set<TempFlatPair> tfpset=tmap.get(fen.getSrc());
+           if (tfpset!=null)
+             tfset.addAll(tfpset);
+         }
          break;
        }
        case FKind.FlatFieldNode: { 
@@ -183,6 +490,12 @@ public class DiscoverConflicts {
            if (tfpset!=null)
              tfset.addAll(tfpset);
          }
+         if (updatedfieldmap!=null&&updatedfieldmap.get(ffn).contains(ffn.getField())) {
+           //this could cause conflict...figure out conflict set
+           Set<TempFlatPair> tfpset=tmap.get(ffn.getSrc());
+           if (tfpset!=null)
+             tfset.addAll(tfpset);
+         }
          break;
        }
        case FKind.FlatSetFieldNode: { 
@@ -191,6 +504,10 @@ public class DiscoverConflicts {
          Set<TempFlatPair> tfpset=tmap.get(fsfn.getDst());
          if (tfpset!=null)
            tfset.addAll(tfpset);
+         if (writeset!=null) {
+           if (tfpset!=null)
+             writeset.addAll(tfpset);
+         }
          break;
        }
        case FKind.FlatSetElementNode: { 
@@ -199,6 +516,10 @@ public class DiscoverConflicts {
          Set<TempFlatPair> tfpset=tmap.get(fsen.getDst());
          if (tfpset!=null)
            tfset.addAll(tfpset);
+         if (writeset!=null) {
+           if (tfpset!=null)
+             writeset.addAll(tfpset);
+         }
          break;
        }
        case FKind.FlatCall: //assume pessimistically that calls do bad things
@@ -209,6 +530,10 @@ public class DiscoverConflicts {
            Set<TempFlatPair> tfpset=tmap.get(rtmp);
            if (tfpset!=null)
              tfset.addAll(tfpset);
+           if (writeset!=null) {
+             if (tfpset!=null)
+               writeset.addAll(tfpset);
+           }
          }
          break;
        }
@@ -220,6 +545,13 @@ public class DiscoverConflicts {
     return tfset;
   }
 
+
+  //This method generates as output for each node
+  //A map from from temps to a set of temp/flat pairs that the
+  //original temp points to
+  //A temp/flat pair gives the flatnode that the value was created at
+  //and the original temp
+
   Hashtable<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>> computeTempSets(LocalityBinding lb) {
     Hashtable<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>> tmptofnset=new Hashtable<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>>();
     HashSet<FlatNode> discovered=new HashSet<FlatNode>();
@@ -227,7 +559,7 @@ public class DiscoverConflicts {
     MethodDescriptor md=lb.getMethod();
     FlatMethod fm=state.getMethodFlat(md);
     Hashtable<FlatNode, Integer> atomictable=locality.getAtomic(lb);
-    Hashtable<FlatNode, Set<TempDescriptor>> livetemps=locality.computeLiveTemps(fm);
+    Hashtable<FlatNode, Set<TempDescriptor>> livetemps=Liveness.computeLiveTemps(fm);
     tovisit.add(fm);
     discovered.add(fm);
     
@@ -244,20 +576,25 @@ public class DiscoverConflicts {
       Hashtable<TempDescriptor, Set<TempFlatPair>> ttofn=null;
       if (atomictable.get(fn).intValue()!=0) {
        if ((fn.numPrev()>0)&&atomictable.get(fn.getPrev(0)).intValue()==0) {
-         //flatatomic enter node...  see what we really need to transread
-         Set<TempDescriptor> liveset=livetemps.get(fn);
+         //atomic node, start with new set
          ttofn=new Hashtable<TempDescriptor, Set<TempFlatPair>>();
-         for(Iterator<TempDescriptor> tmpit=liveset.iterator();tmpit.hasNext();) {
-           TempDescriptor tmp=tmpit.next();
-           if (tmp.getType().isPtr()) {
-             HashSet<TempFlatPair> fnset=new HashSet<TempFlatPair>();
-             fnset.add(new TempFlatPair(tmp, fn));
-             ttofn.put(tmp, fnset);
-           }
-         }
        } else {
          ttofn=doMerge(fn, tmptofnset);
          switch(fn.kind()) {
+         case FKind.FlatGlobalConvNode: {
+           FlatGlobalConvNode fgcn=(FlatGlobalConvNode)fn;
+           if (lb==fgcn.getLocality()&&
+               fgcn.getMakePtr()) {
+             TempDescriptor[] writes=fn.writesTemps();
+             for(int i=0;i<writes.length;i++) {
+               TempDescriptor wtmp=writes[i];
+               HashSet<TempFlatPair> set=new HashSet<TempFlatPair>();
+               set.add(new TempFlatPair(wtmp, fn));
+               ttofn.put(wtmp, set);
+             }
+           }
+           break;
+         }
          case FKind.FlatFieldNode:
          case FKind.FlatElementNode: {
            TempDescriptor[] writes=fn.writesTemps();
@@ -280,14 +617,31 @@ public class DiscoverConflicts {
            }
            break;
          }
-         case FKind.FlatOpNode: {
-           FlatOpNode fon=(FlatOpNode)fn;
-           if (fon.getOp().getOp()==Operation.ASSIGN&&fon.getDest().getType().isPtr()&&
-               ttofn.containsKey(fon.getLeft())) {
-             ttofn.put(fon.getDest(), new HashSet<TempFlatPair>(ttofn.get(fon.getLeft())));
-             break;
+         case FKind.FlatCastNode:
+         case FKind.FlatOpNode: 
+           if (fn.kind()==FKind.FlatCastNode) {
+             FlatCastNode fcn=(FlatCastNode)fn;
+             if (fcn.getDst().getType().isPtr()) {
+               HashSet<TempFlatPair> set=new HashSet<TempFlatPair>();
+               if (ttofn.containsKey(fcn.getSrc()))
+                 set.addAll(ttofn.get(fcn.getSrc()));
+               if (normalassign)
+                 set.add(new TempFlatPair(fcn.getDst(), fn));
+               ttofn.put(fcn.getDst(), set);
+               break;
+             }
+           } else if (fn.kind()==FKind.FlatOpNode) {
+             FlatOpNode fon=(FlatOpNode)fn;
+             if (fon.getOp().getOp()==Operation.ASSIGN&&fon.getDest().getType().isPtr()) {
+               HashSet<TempFlatPair> set=new HashSet<TempFlatPair>();
+               if (ttofn.containsKey(fon.getLeft()))
+                 set.addAll(ttofn.get(fon.getLeft()));
+               if (normalassign)
+                 set.add(new TempFlatPair(fon.getDest(), fn));
+               ttofn.put(fon.getDest(), set);
+               break;
+             }
            }
-         }
          default:
            //Do kill computation
            TempDescriptor[] writes=fn.writesTemps();
@@ -313,6 +667,12 @@ public class DiscoverConflicts {
     return tmptofnset;
   }
   
+  /* See what fields and arrays transactions might modify.  We only
+   * look at changes to old objects. */
+
+  //Bug fix: original version forget to check if object is new and
+  //could be optimized
+
   public void computeModified(LocalityBinding lb) {
     MethodDescriptor md=lb.getMethod();
     FlatMethod fm=state.getMethodFlat(md);
@@ -321,14 +681,17 @@ public class DiscoverConflicts {
       FlatNode fn=fnit.next();
       Hashtable<FlatNode, Integer> atomictable=locality.getAtomic(lb);
       if (atomictable.get(fn).intValue()>0) {
+       Set<TempDescriptor> oldtemp=oldtemps.get(fn);
        switch (fn.kind()) {
        case FKind.FlatSetFieldNode:
          FlatSetFieldNode fsfn=(FlatSetFieldNode) fn;
-         fields.add(fsfn.getField());
+         if (oldtemp.contains(fsfn.getDst()))
+           fields.add(fsfn.getField());
          break;
        case FKind.FlatSetElementNode:
          FlatSetElementNode fsen=(FlatSetElementNode) fn;
-         arrays.add(fsen.getDst().getType());
+         if (oldtemp.contains(fsen.getDst()))
+           arrays.add(fsen.getDst().getType());
          break;
        default:
        }
@@ -336,6 +699,11 @@ public class DiscoverConflicts {
     }
   }
     
+
+  //Returns a table that maps a flatnode to a set of temporaries
+  //This set of temporaries is old (meaning they may point to object
+  //allocated before the beginning of the current transaction
+
   Hashtable<FlatNode, Set<TempDescriptor>> computeOldTemps(LocalityBinding lb) {
     Hashtable<FlatNode, Set<TempDescriptor>> fntooldtmp=new Hashtable<FlatNode, Set<TempDescriptor>>();
     HashSet<FlatNode> discovered=new HashSet<FlatNode>();
@@ -343,7 +711,7 @@ public class DiscoverConflicts {
     MethodDescriptor md=lb.getMethod();
     FlatMethod fm=state.getMethodFlat(md);
     Hashtable<FlatNode, Integer> atomictable=locality.getAtomic(lb);
-    Hashtable<FlatNode, Set<TempDescriptor>> livetemps=locality.computeLiveTemps(fm);
+    Hashtable<FlatNode, Set<TempDescriptor>> livetemps=Liveness.computeLiveTemps(fm);
     tovisit.add(fm);
     discovered.add(fm);
     
@@ -383,16 +751,27 @@ public class DiscoverConflicts {
          case FKind.FlatNew:
            oldtemps.removeAll(Arrays.asList(fn.readsTemps()));
            break;
-         case FKind.FlatOpNode: {
-           FlatOpNode fon=(FlatOpNode)fn;
-           if (fon.getOp().getOp()==Operation.ASSIGN&&fon.getDest().getType().isPtr()) {
-             if (oldtemps.contains(fon.getLeft()))
-               oldtemps.add(fon.getDest());
-             else
-               oldtemps.remove(fon.getDest());
-             break;
+         case FKind.FlatOpNode:
+         case FKind.FlatCastNode: 
+           if (fn.kind()==FKind.FlatCastNode) {
+             FlatCastNode fcn=(FlatCastNode)fn;
+             if (fcn.getDst().getType().isPtr()) {
+               if (oldtemps.contains(fcn.getSrc()))
+                 oldtemps.add(fcn.getDst());
+               else
+                 oldtemps.remove(fcn.getDst());
+               break;
+             }
+           } else if (fn.kind()==FKind.FlatOpNode) {
+             FlatOpNode fon=(FlatOpNode)fn;
+             if (fon.getOp().getOp()==Operation.ASSIGN&&fon.getDest().getType().isPtr()) {
+               if (oldtemps.contains(fon.getLeft()))
+                 oldtemps.add(fon.getDest());
+               else
+                 oldtemps.remove(fon.getDest());
+               break;
+             }
            }
-         }
          default: {
            TempDescriptor[] writes=fn.writesTemps();
            for(int i=0;i<writes.length;i++) {
@@ -421,18 +800,21 @@ public class DiscoverConflicts {
 }
 
 class TempFlatPair {
-    FlatNode f;
-    TempDescriptor t;
-    TempFlatPair(TempDescriptor t, FlatNode f) {
-       this.t=t;
-       this.f=f;
-    }
-
-    public int hashCode() {
-       return f.hashCode()^t.hashCode();
-    }
-    public boolean equals(Object o) {
-       TempFlatPair tf=(TempFlatPair)o;
-       return t.equals(tf.t)&&f.equals(tf.f);
-    }
+  FlatNode f;
+  TempDescriptor t;
+  TempFlatPair(TempDescriptor t, FlatNode f) {
+    this.t=t;
+    this.f=f;
+  }
+  
+  public int hashCode() {
+    return f.hashCode()^t.hashCode();
+  }
+  public boolean equals(Object o) {
+    TempFlatPair tf=(TempFlatPair)o;
+    return t.equals(tf.t)&&f.equals(tf.f);
+  }
+  public String toString() {
+    return f.toString()+" "+t.toString();
+  }
 }