new write barrier class
authorbdemsky <bdemsky>
Sun, 5 Apr 2009 04:52:04 +0000 (04:52 +0000)
committerbdemsky <bdemsky>
Sun, 5 Apr 2009 04:52:04 +0000 (04:52 +0000)
fixed many bugs

Robust/src/Analysis/Loops/CSE.java
Robust/src/Analysis/Loops/DeadCode.java
Robust/src/Analysis/Loops/GlobalFieldType.java
Robust/src/Analysis/Loops/WriteBarrier.java [new file with mode: 0644]
Robust/src/Analysis/Loops/localCSE.java

index 76adcd851a4c7dd278bc1b566c1330356bda4b3c..b98b4f090ffa020706a45d7051625be193f8db96 100644 (file)
@@ -22,7 +22,6 @@ public class CSE {
 
   public void doAnalysis(FlatMethod fm) {
     Hashtable<FlatNode,Hashtable<Expression, TempDescriptor>> availexpr=new Hashtable<FlatNode,Hashtable<Expression, TempDescriptor>>();
-
     HashSet toprocess=new HashSet();
     HashSet discovered=new HashSet();
     toprocess.add(fm);
@@ -47,19 +46,23 @@ public class CSE {
       }
       
       switch(fn.kind()) {
+      case FKind.FlatAtomicEnterNode:
+       {
+         killexpressions(tab, null, null, true);
+       }
       case FKind.FlatCall:
        {
          FlatCall fc=(FlatCall) fn;
          MethodDescriptor md=fc.getMethod();
          Set<FieldDescriptor> fields=gft.getFields(md);
          Set<TypeDescriptor> arrays=gft.getArrays(md);
-         killexpressions(tab, fields, arrays);
+         killexpressions(tab, fields, arrays, gft.containsAtomic(md));
          break;
        }
       case FKind.FlatOpNode:
        {
          FlatOpNode fon=(FlatOpNode) fn;
-         Expression e=new Expression(fon.getLeft(), fon.getRight(),fon.getOp());
+         Expression e=new Expression(fon.getLeft(), fon.getRight(), fon.getOp());
          tab.put(e, fon.getDest());
          break;
        }
@@ -68,7 +71,7 @@ public class CSE {
          FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
          Set<FieldDescriptor> fields=new HashSet<FieldDescriptor>();
          fields.add(fsfn.getField());
-         killexpressions(tab, fields, null);
+         killexpressions(tab, fields, null, false);
          Expression e=new Expression(fsfn.getDst(), fsfn.getField());
          tab.put(e, fsfn.getSrc());
          break;
@@ -114,52 +117,59 @@ public class CSE {
        }
       }
     }
+
     doOptimize(fm, availexpr);
   }
     
   public void doOptimize(FlatMethod fm, Hashtable<FlatNode,Hashtable<Expression, TempDescriptor>> availexpr) {
-      for(Iterator<FlatNode> it=fm.getNodeSet().iterator();it.hasNext();) {
-         FlatNode fn=it.next();
-         Hashtable<Expression, TempDescriptor> tab=computeIntersection(fn, availexpr);
-         switch(fn.kind()) {
-         case FKind.FlatOpNode:
-             {
-                 FlatOpNode fon=(FlatOpNode) fn;
-                 Expression e=new Expression(fon.getLeft(), fon.getRight(),fon.getOp());
-                 if (tab.containsKey(e)) {
-                     TempDescriptor t=tab.get(e);
-                     FlatOpNode newfon=new FlatOpNode(fon.getDest(),t,null,new Operation(Operation.ASSIGN));
-                     fon.replace(newfon);
-                 }
-                 break;
-             }
-         case FKind.FlatFieldNode:
-             {
-                 FlatFieldNode ffn=(FlatFieldNode)fn;
-                 Expression e=new Expression(ffn.getSrc(), ffn.getField());
-                 if (tab.containsKey(e)) {
-                     TempDescriptor t=tab.get(e);
-                     FlatOpNode newfon=new FlatOpNode(ffn.getDst(),t,null,new Operation(Operation.ASSIGN));
-                     ffn.replace(newfon);
-                 }
-                 break;
-             }
-         case FKind.FlatElementNode:
-             {
-                 FlatElementNode fen=(FlatElementNode)fn;
-                 Expression e=new Expression(fen.getSrc(),fen.getIndex());
-                 if (tab.containsKey(e)) {
-                     TempDescriptor t=tab.get(e);
-                     FlatOpNode newfon=new FlatOpNode(fen.getDst(),t,null,new Operation(Operation.ASSIGN));
-                     fen.replace(newfon);
-                 }
-                 break;
-             }
-         default: 
+    Hashtable<FlatNode, FlatNode> replacetable=new Hashtable<FlatNode, FlatNode>();
+    for(Iterator<FlatNode> it=fm.getNodeSet().iterator();it.hasNext();) {
+      FlatNode fn=it.next();
+      Hashtable<Expression, TempDescriptor> tab=computeIntersection(fn, availexpr);
+      switch(fn.kind()) {
+      case FKind.FlatOpNode:
+       {
+         FlatOpNode fon=(FlatOpNode) fn;
+         Expression e=new Expression(fon.getLeft(), fon.getRight(),fon.getOp());
+         if (tab.containsKey(e)) {
+           TempDescriptor t=tab.get(e);
+           FlatNode newfon=new FlatOpNode(fon.getDest(),t,null,new Operation(Operation.ASSIGN));
+           replacetable.put(fon,newfon);
          }
+         break;
+       }
+      case FKind.FlatFieldNode:
+       {
+         FlatFieldNode ffn=(FlatFieldNode)fn;
+         Expression e=new Expression(ffn.getSrc(), ffn.getField());
+         if (tab.containsKey(e)) {
+           TempDescriptor t=tab.get(e);
+           FlatNode newfon=new FlatOpNode(ffn.getDst(),t,null,new Operation(Operation.ASSIGN));
+           replacetable.put(ffn,newfon);
+         }
+         break;
+       }
+      case FKind.FlatElementNode:
+       {
+         FlatElementNode fen=(FlatElementNode)fn;
+         Expression e=new Expression(fen.getSrc(),fen.getIndex());
+         if (tab.containsKey(e)) {
+           TempDescriptor t=tab.get(e);
+           FlatNode newfon=new FlatOpNode(fen.getDst(),t,null,new Operation(Operation.ASSIGN));
+           replacetable.put(fen,newfon);
+         }
+         break;
+       }
+      default: 
       }
+    }
+    for(Iterator<FlatNode> it=replacetable.keySet().iterator();it.hasNext();) {
+      FlatNode fn=it.next();
+      FlatNode newfn=replacetable.get(fn);
+      fn.replace(newfn);
+    }
   }
-
+  
   public Hashtable<Expression, TempDescriptor> computeIntersection(FlatNode fn, Hashtable<FlatNode,Hashtable<Expression, TempDescriptor>> availexpr) {
     Hashtable<Expression, TempDescriptor> tab=new Hashtable<Expression, TempDescriptor>();
     boolean first=true;
@@ -168,9 +178,10 @@ public class CSE {
     for(int i=0;i<fn.numPrev();i++) {
       FlatNode prev=fn.getPrev(i);
       if (first) {
-       if (availexpr.containsKey(prev))
+       if (availexpr.containsKey(prev)) {
          tab.putAll(availexpr.get(prev));
-       first=false;
+         first=false;
+       }
       } else {
        if (availexpr.containsKey(prev)) {
          Hashtable<Expression, TempDescriptor> table=availexpr.get(prev);
@@ -185,11 +196,13 @@ public class CSE {
     return tab;
   }
 
-  public void killexpressions(Hashtable<Expression, TempDescriptor> tab, Set<FieldDescriptor> fields, Set<TypeDescriptor> arrays) {
+  public void killexpressions(Hashtable<Expression, TempDescriptor> tab, Set<FieldDescriptor> fields, Set<TypeDescriptor> arrays, boolean killall) {
     for(Iterator it=tab.entrySet().iterator();it.hasNext();) {
       Map.Entry m=(Map.Entry)it.next();
       Expression e=(Expression)m.getKey();
-      if (e.f!=null&&fields!=null&&fields.contains(e.f)) 
+      if (killall&&(e.f!=null||e.a!=null))
+       it.remove();
+      else if (e.f!=null&&fields!=null&&fields.contains(e.f)) 
        it.remove();
       else if ((e.a!=null)&&(arrays!=null)) {
        for(Iterator<TypeDescriptor> arit=arrays.iterator();arit.hasNext();) {
index 4df9eb4841f54fc3febfe0b52b1706ea71719771..d624fdd44862b87ecc6c09e90c8ed21d2b1aa4c3 100644 (file)
@@ -72,10 +72,9 @@ public class DeadCode {
     //get rid of useless nodes
     for(Iterator<FlatNode> it=fm.getNodeSet().iterator();it.hasNext();) {
       FlatNode fn=it.next();
-      if (!useful.contains(fn)) {
+      if (!useful.contains(fn)||isuseless(fn)) {
        //We have a useless node
        FlatNode fnnext=fn.getNext(0);
-
        for(int i=0;i<fn.numPrev();i++) {
          FlatNode nprev=fn.getPrev(i);
              
@@ -91,4 +90,13 @@ public class DeadCode {
       }
     }
   }
+  public boolean isuseless(FlatNode fn) {
+    if (fn.kind()==FKind.FlatOpNode) {
+      FlatOpNode fon=(FlatOpNode)fn;
+      if (fon.getOp().getOp()==Operation.ASSIGN&&fon.getLeft()==fon.getDest())
+       return true;
+    }
+    return false;
+  }
+
 }
\ No newline at end of file
index cbef45407074b0d2e3f66f5919cf5741f6d473a7..4802b1d95e620c7b5f566d35d29aa09178e1ae2a 100644 (file)
@@ -17,6 +17,7 @@ public class GlobalFieldType {
   MethodDescriptor root;
   Hashtable<MethodDescriptor, Set<FieldDescriptor>> fields;
   Hashtable<MethodDescriptor, Set<TypeDescriptor>> arrays;
+  HashSet<MethodDescriptor> containsAtomic;
   
   public GlobalFieldType(CallGraph cg, State st, MethodDescriptor root) {
     this.cg=cg;
@@ -24,6 +25,7 @@ public class GlobalFieldType {
     this.root=root;
     this.fields=new Hashtable<MethodDescriptor, Set<FieldDescriptor>>();
     this.arrays=new Hashtable<MethodDescriptor, Set<TypeDescriptor>>();
+    this.containsAtomic=new HashSet<MethodDescriptor>();
     doAnalysis();
   }
   private void doAnalysis() {
@@ -56,11 +58,19 @@ public class GlobalFieldType {
            changed=true;
          if (arrays.get(md).addAll(arrays.get(md2)))
            changed=true;
+         if (containsAtomic.contains(md2)) {
+           if (containsAtomic.add(md))
+             changed=true;
+         }
        }
       }
     }
   }
 
+  public boolean containsAtomic(MethodDescriptor md) {
+    return containsAtomic.contains(md);
+  }
+
   public Set<FieldDescriptor> getFields(MethodDescriptor md) {
     return fields.get(md);
   }
@@ -82,6 +92,8 @@ public class GlobalFieldType {
       } else if (fn.kind()==FKind.FlatSetFieldNode) {
        FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
        fields.get(md).add(fsfn.getField());
+      } else if (fn.kind()==FKind.FlatAtomicEnterNode) {
+       containsAtomic.add(md);
       }
     }
   }
diff --git a/Robust/src/Analysis/Loops/WriteBarrier.java b/Robust/src/Analysis/Loops/WriteBarrier.java
new file mode 100644 (file)
index 0000000..fd69784
--- /dev/null
@@ -0,0 +1,134 @@
+package Analysis.Loops;
+import IR.Flat.*;
+import Analysis.Locality.*;
+import IR.Operation;
+import IR.State;
+import IR.MethodDescriptor;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+
+public class WriteBarrier {
+  /* This computes whether we actually need a write barrier. */
+  LocalityAnalysis la;
+  State state;
+  public WriteBarrier(LocalityAnalysis la, State state) {
+    this.la=la;
+    this.state=state;
+  }
+  
+  public boolean needBarrier(FlatNode fn) {
+    HashSet<TempDescriptor> nb=computeIntersection(fn);
+    switch(fn.kind()) {
+    case FKind.FlatSetElementNode:
+      {
+       FlatSetElementNode fsen=(FlatSetElementNode)fn;
+       return !nb.contains(fsen.getDst());
+      }
+    case FKind.FlatSetFieldNode:
+      {
+       FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
+       return !nb.contains(fsfn.getDst());
+      }
+    default:
+      return true;
+    }
+  }
+  
+  Hashtable<FlatNode,HashSet<TempDescriptor>> needbarrier;
+
+  public void analyze(LocalityBinding lb) {
+    MethodDescriptor md=lb.getMethod();
+    FlatMethod fm=state.getMethodFlat(md);
+    HashSet useful=new HashSet();
+    HashSet toprocess=new HashSet();
+    HashSet discovered=new HashSet();
+    needbarrier=new Hashtable<FlatNode,HashSet<TempDescriptor>>();
+    toprocess.add(fm);
+    discovered.add(fm);
+    Hashtable<FlatNode, Integer> atomic=la.getAtomic(lb);
+    
+    while(!toprocess.isEmpty()) {
+      FlatNode fn=(FlatNode)toprocess.iterator().next();
+      toprocess.remove(fn);
+      for(int i=0;i<fn.numNext();i++) {
+        FlatNode nnext=fn.getNext(i);
+        if (!discovered.contains(nnext)) {
+          toprocess.add(nnext);
+          discovered.add(nnext);
+        }
+      }
+      HashSet<TempDescriptor> nb=computeIntersection(fn);
+      TempDescriptor[] writes=fn.writesTemps();
+      for(int i=0;i<writes.length;i++) {
+       nb.remove(writes[i]);
+      }
+      switch(fn.kind()) {
+      case FKind.FlatSetElementNode:
+       {
+         FlatSetElementNode fsen=(FlatSetElementNode)fn;
+         nb.add(fsen.getDst());
+         break;
+       }
+      case FKind.FlatSetFieldNode:
+       {
+         FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
+         nb.add(fsfn.getDst());
+         break;
+       }
+      case FKind.FlatOpNode: 
+       {
+         FlatOpNode fon=(FlatOpNode)fn;
+         if (fon.getOp().getOp()==Operation.ASSIGN) {
+           if (nb.contains(fon.getLeft())) {
+             nb.add(fon.getDest());
+           }
+         }
+         break;
+       }
+      case FKind.FlatNew:
+       {
+         FlatNew fnew=(FlatNew)fn;
+         nb.add(fnew.getDst());
+         break;
+       }
+      default:
+       //If we enter a transaction toss everything
+       if (atomic.get(fn).intValue()>0&&
+           atomic.get(fn.getPrev(0)).intValue()==0) {
+         nb=new HashSet<TempDescriptor>();
+       }
+      }
+      if (!needbarrier.containsKey(fn)||
+         !needbarrier.get(fn).equals(nb)) {
+       for(int i=0;i<fn.numNext();i++) {
+         FlatNode nnext=fn.getNext(i);
+         toprocess.add(nnext);
+       }
+       needbarrier.put(fn,nb);
+      }
+    }
+  }
+  HashSet<TempDescriptor> computeIntersection(FlatNode fn) {
+    HashSet<TempDescriptor> tab=new HashSet<TempDescriptor>();
+    boolean first=true;
+    for(int i=0;i<fn.numPrev();i++) {
+      FlatNode fprev=fn.getPrev(i);
+      HashSet<TempDescriptor> hs=needbarrier.get(fprev);
+      if (hs!=null) {
+       if (first) {
+         tab.addAll(hs);
+         first=false;
+       } else {
+         //Intersect sets
+         for(Iterator<TempDescriptor> it=tab.iterator();it.hasNext();) {
+           TempDescriptor t=it.next();
+           if (!hs.contains(t))
+             it.remove();
+         }
+       }
+      }
+    }
+    return tab;
+  }
+}
\ No newline at end of file
index 0d1b4e0df4dc0db85ee5899d75f7bdb2065c34fb..155b83082972ae0320b032e12897ec5e8d964e15 100644 (file)
@@ -71,7 +71,7 @@ public class localCSE {
            Group g=getGroup(table,e);
            TempDescriptor td=getTemp(g);
            if (td!=null) {
-             FlatOpNode nfon=new FlatOpNode(fon.getDest(),td,null,new Operation(Operation.ASSIGN));
+             FlatNode nfon=new FlatOpNode(fon.getDest(),td,null,new Operation(Operation.ASSIGN));
              fn.replace(nfon);
            }
            g.set.add(dst);
@@ -132,7 +132,7 @@ public class localCSE {
          dstf.set.add(src);
          HashSet<FieldDescriptor> fields=new HashSet<FieldDescriptor>();
          fields.add(fsfn.getField());
-         kill(table, fields, null);
+         kill(table, fields, null, false);
          table.put(src, dstf);
          break;
        }
@@ -146,7 +146,7 @@ public class localCSE {
          dstf.set.add(src);
          HashSet<TypeDescriptor> arrays=new HashSet<TypeDescriptor>();
          arrays.add(fsen.getDst().getType());
-         kill(table, null, arrays);
+         kill(table, null, arrays, false);
          table.put(src, dstf);
          break;
        }
@@ -156,7 +156,7 @@ public class localCSE {
          MethodDescriptor md=fc.getMethod();
          Set<FieldDescriptor> fields=gft.getFields(md);
          Set<TypeDescriptor> arrays=gft.getArrays(md);
-         kill(table, fields, arrays);
+         kill(table, fields, arrays, gft.containsAtomic(md));
        }
        default: {
          TempDescriptor[] writes=fn.writesTemps();
@@ -168,11 +168,15 @@ public class localCSE {
       } while(fn.numPrev()==1);
     }
   }
-  public void kill(Hashtable<LocalExpression, Group> tab, Set<FieldDescriptor> fields, Set<TypeDescriptor> arrays) {
+  public void kill(Hashtable<LocalExpression, Group> tab, Set<FieldDescriptor> fields, Set<TypeDescriptor> arrays, boolean isAtomic) {
     Set<LocalExpression> eset=tab.keySet();
     for(Iterator<LocalExpression> it=eset.iterator();it.hasNext();) {
       LocalExpression e=it.next();
-      if (e.td!=null) {
+      if (isAtomic&&(e.td!=null||e.f!=null)) {
+       Group g=tab.get(e);
+       g.set.remove(e);
+       it.remove();
+      } else if (e.td!=null) {
        //have array
        TypeDescriptor artd=e.td;
        for(Iterator<TypeDescriptor> arit=arrays.iterator();arit.hasNext();) {