Added improvements to ImplicitSchema analysis, bug fixes to ImplicitSchema
[repair.git] / Repair / RepairCompiler / MCC / IR / UpdateNode.java
index 8eee4a87df2375fe27a02939d3cfac165117393d..7c0e5a464ab3129dc016f70f3cb52627b6471fd2 100755 (executable)
@@ -1,5 +1,6 @@
 package MCC.IR;
 import java.util.*;
+import MCC.State;
 
 class UpdateNode {
     Vector updates;
@@ -176,6 +177,14 @@ class UpdateNode {
        binding.put(b.getVar(),b);
     }
 
+    public int numBindings() {
+       return bindings.size();
+    }
+
+    public Binding getBinding(int i) {
+       return (Binding)bindings.get(i);
+    }
+    
     public Binding getBinding(VarDescriptor vd) {
        if (binding.containsKey(vd))
            return (Binding)binding.get(vd);
@@ -193,33 +202,166 @@ class UpdateNode {
     public Updates getUpdate(int i) {
        return (Updates)updates.get(i);
     }
-    public void generate(CodeWriter cr, boolean removal, String slot0, String slot1) {
-       if (!removal)
+
+    private MultUpdateNode getMultUpdateNode(boolean negate, Descriptor d, RepairGenerator rg) {
+       Termination termination=rg.termination;
+       MultUpdateNode mun=null;
+       GraphNode gn;
+       if (negate)
+           gn=(GraphNode)termination.abstractremove.get(d);
+       else
+           gn=(GraphNode)termination.abstractadd.get(d);
+       TermNode tn=(TermNode)gn.getOwner();
+       for(Iterator edgeit=gn.edges();edgeit.hasNext();) {
+           GraphNode gn2=((GraphNode.Edge) edgeit.next()).getTarget();
+           if (!rg.removed.contains(gn2)) {
+               TermNode tn2=(TermNode)gn2.getOwner();
+               if (tn2.getType()==TermNode.UPDATE) {
+                   mun=tn2.getUpdate();
+                   break;
+               }
+           }
+       }
+       if (mun==null)
+           throw new Error("Can't find update node!");
+       return mun;
+    }
+
+    public void generate_abstract(CodeWriter cr, Updates u, RepairGenerator rg) {
+       State state=rg.state;
+       Expr abstractexpr=u.getLeftExpr();
+       boolean negated=u.negate;
+       Descriptor d=null;
+       Expr left=null;
+       Expr right=null;
+       boolean istuple=false;
+       if (abstractexpr instanceof TupleOfExpr) {
+           TupleOfExpr toe=(TupleOfExpr) abstractexpr;
+           d=toe.relation;
+           left=toe.left;
+           right=toe.right;
+           istuple=true;
+       } else if (abstractexpr instanceof ElementOfExpr) {
+           ElementOfExpr eoe=(ElementOfExpr) abstractexpr;
+           d=eoe.set;
+           left=eoe.element;
+           istuple=false;
+       } else {
+           throw new Error("Unsupported Expr");
+       }
+       MultUpdateNode mun=getMultUpdateNode(negated,d,rg);
+       VarDescriptor leftvar=VarDescriptor.makeNew("leftvar");
+       VarDescriptor rightvar=VarDescriptor.makeNew("rightvar");
+       left.generate(cr, leftvar);
+       if (istuple)
+           right.generate(cr,rightvar);
+
+       if (negated) {
+           if (istuple) {
+               RelationDescriptor rd=(RelationDescriptor)d;
+               boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
+               boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
+               if (usageimage)
+                   cr.outputline(rg.stmodel+"->"+rd.getJustSafeSymbol() + "_hash->remove((int)" + leftvar.getSafeSymbol() + ", (int)" + rightvar.getSafeSymbol() + ");");
+               if (usageinvimage)
+                   cr.outputline(rg.stmodel+"->"+rd.getJustSafeSymbol() + "_hashinv->remove((int)" + rightvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
+               
+               for(int i=0;i<state.vRules.size();i++) {
+                   Rule r=(Rule)state.vRules.get(i);
+                   if (r.getInclusion().getTargetDescriptors().contains(rd)) {
+                       for(int j=0;j<mun.numUpdates();j++) {
+                           UpdateNode un=mun.getUpdate(i);
+                           if (un.getRule()==r) {
+                               /* Update for rule rule r */
+                               String name=(String)rg.updatenames.get(un);
+                               cr.outputline(rg.strepairtable+"->addrelation("+rd.getNum()+","+r.getNum()+","+leftvar.getSafeSymbol()+","+rightvar.getSafeSymbol()+",(int) &"+name+");");
+                           }
+                       }
+                   }
+               }
+           } else {
+               SetDescriptor sd=(SetDescriptor) d;
+               cr.outputline(rg.stmodel+"->"+sd.getJustSafeSymbol() + "_hash->remove((int)" + leftvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
+
+               for(int i=0;i<state.vRules.size();i++) {
+                   Rule r=(Rule)state.vRules.get(i);
+                   if (r.getInclusion().getTargetDescriptors().contains(sd)) {
+                       for(int j=0;j<mun.numUpdates();j++) {
+                           UpdateNode un=mun.getUpdate(j);
+                           if (un.getRule()==r) {
+                               /* Update for rule rule r */
+                               String name=(String)rg.updatenames.get(un);
+                               cr.outputline(rg.strepairtable+"->addset("+sd.getNum()+","+r.getNum()+","+leftvar.getSafeSymbol()+",(int) &"+name+");");
+                           }
+                       }
+                   }
+               }
+           }
+       } else {
+           /* Generate update */
+           if (istuple) {
+               RelationDescriptor rd=(RelationDescriptor) d;
+               boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
+               boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
+               if (usageimage)
+                   cr.outputline(rg.stmodel+"->"+rd.getJustSafeSymbol() + "_hash->add((int)" + leftvar.getSafeSymbol() + ", (int)" + rightvar.getSafeSymbol() + ");");
+               if (usageinvimage)
+                   cr.outputline(rg.stmodel+"->"+rd.getJustSafeSymbol() + "_hashinv->add((int)" + rightvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
+
+               UpdateNode un=mun.getUpdate(0);
+               String name=(String)rg.updatenames.get(un);
+               cr.outputline(name+"(this,"+rg.stmodel+","+rg.strepairtable+","+leftvar.getSafeSymbol()+","+rightvar.getSafeSymbol()+");");
+           } else {
+               SetDescriptor sd=(SetDescriptor)d;
+               cr.outputline(rg.stmodel+"->"+sd.getJustSafeSymbol() + "_hash->add((int)" + leftvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
+
+               UpdateNode un=mun.getUpdate(0);
+               /* Update for rule rule r */
+               String name=(String)rg.updatenames.get(un);
+               cr.outputline(name+"(this,"+rg.stmodel+","+rg.strepairtable+","+leftvar.getSafeSymbol()+");");
+           }
+       }
+       
+    }
+
+    public void generate(CodeWriter cr, boolean removal, boolean modify, String slot0, String slot1, String slot2, RepairGenerator rg) {
+       if (!removal&&!modify)
            generate_bindings(cr, slot0,slot1);
        for(int i=0;i<updates.size();i++) {
            Updates u=(Updates)updates.get(i);
            VarDescriptor right=VarDescriptor.makeNew("right");
-           if (u.getType()==Updates.ABSTRACT)
-               throw new Error("Abstract update not implemented");
+           if (u.getType()==Updates.ABSTRACT) {
+               generate_abstract(cr, u, rg);
+               return;
+           }
 
            switch(u.getType()) {
            case Updates.EXPR:
                u.getRightExpr().generate(cr,right);
                break;
            case Updates.POSITION:
+           case Updates.ACCESSPATH:
                if (u.getRightPos()==0)
                    cr.outputline("int "+right.getSafeSymbol()+"="+slot0+";");
                else if (u.getRightPos()==1)
                    cr.outputline("int "+right.getSafeSymbol()+"="+slot1+";");
+               else if (u.getRightPos()==2)
+                   cr.outputline("int "+right.getSafeSymbol()+"="+slot2+";");
                else throw new Error("Error w/ Position");
                break;
            default:
                throw new Error();
            }
+
+           if (u.getType()==Updates.ACCESSPATH) {
+               VarDescriptor newright=VarDescriptor.makeNew("right");
+               /* Need to do the modulo computation here...FIXME */
+               right=newright;
+           }
            VarDescriptor left=VarDescriptor.makeNew("left");
            u.getLeftExpr().generate(cr,left);
            Opcode op=u.getOpcode();
-           cr.outputline("if ("+left.getSafeSymbol()+op+right.getSafeSymbol()+")");
+           cr.outputline("if (!("+left.getSafeSymbol()+op+right.getSafeSymbol()+"))");
            cr.startblock();
 
            if (op==Opcode.GT)
@@ -240,26 +382,78 @@ class UpdateNode {
                cr.outputline(vd.getSafeSymbol()+"="+right.getSafeSymbol()+";");
            } else if (u.isField()) {
                /* NEED TO FIX */
+               Expr subexpr=((DotExpr)u.getLeftExpr()).getExpr();
+               Expr intindex=((DotExpr)u.getLeftExpr()).getIndex();
+               VarDescriptor subvd=VarDescriptor.makeNew("subexpr");
+               VarDescriptor indexvd=VarDescriptor.makeNew("index");
+               subexpr.generate(cr,subvd);
+               if (intindex!=null)
+                   intindex.generate(cr,indexvd);
+               FieldDescriptor fd=(FieldDescriptor)u.getDescriptor();
+               StructureTypeDescriptor std=(StructureTypeDescriptor)subexpr.getType();
+               if (fd instanceof ArrayDescriptor) {
+                   fd = ((ArrayDescriptor) fd).getField();
+               }
+
+               Expr offsetbits = std.getOffsetExpr(fd);
+               if (intindex != null) {
+                   Expr basesize = fd.getBaseSizeExpr();
+                   offsetbits = new OpExpr(Opcode.ADD, offsetbits, new OpExpr(Opcode.MULT, basesize, intindex));
+               }
+               Expr offsetbytes = new OpExpr(Opcode.SHR, offsetbits,new IntegerLiteralExpr(3));
+               Expr byteaddress=new OpExpr(Opcode.ADD, offsetbytes, subexpr);
+               VarDescriptor addr=VarDescriptor.makeNew("byteaddress");
+               byteaddress.generate(cr,addr);
+
+               if (fd.getType() instanceof ReservedTypeDescriptor && !fd.getPtr()) {
+                   ReservedTypeDescriptor rtd=(ReservedTypeDescriptor)fd.getType();
+                   if (rtd==ReservedTypeDescriptor.INT) {
+                       cr.outputline("*((int *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
+                   } else if (rtd==ReservedTypeDescriptor.SHORT) {
+                       cr.outputline("*((short *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
+                   } else if (rtd==ReservedTypeDescriptor.BYTE) {
+                       cr.outputline("*((char *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
+                   } else if (rtd==ReservedTypeDescriptor.BIT) {
+                       Expr tmp = new OpExpr(Opcode.SHL, offsetbytes, new IntegerLiteralExpr(3));
+                       Expr offset=new OpExpr(Opcode.SUB, offsetbits, tmp);
+                       Expr mask=new OpExpr(Opcode.SHR, new IntegerLiteralExpr(1), offset);
+                       VarDescriptor maskvar=VarDescriptor.makeNew("mask");
+                       mask.generate(cr,maskvar);
+                       cr.outputline("*((char *) "+addr.getSafeSymbol()+")|="+maskvar.getSafeSymbol()+";");
+                       cr.outputline("if (!"+right.getSafeSymbol()+")");
+                       cr.outputline("*((char *) "+addr.getSafeSymbol()+")^="+maskvar.getSafeSymbol()+";");
+                   } else throw new Error();
+               } else {
+                   /* Pointer */
+                   cr.outputline("*((int *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
+               }
            }
            cr.endblock();
-           
        }
     }
+
     private void generate_bindings(CodeWriter cr, String slot0, String slot1) {
        for(int i=0;i<bindings.size();i++) {
            Binding b=(Binding)bindings.get(i);
-           if (b.search)
-               throw new Error("Search not implemented for bindings");
-           VarDescriptor vd=b.getVar();
-           switch(b.getPosition()) {
-           case 0:
-               cr.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+"="+slot0+";");
-               break;
-           case 1:
-               cr.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+"="+slot1+";");
-               break;
-           default:
-               throw new Error("Slot >1 doesn't exist.");
+
+           if (b.getType()==Binding.SEARCH) {
+               VarDescriptor vd=b.getVar();
+               cr.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+"="+b.getSet().getSafeSymbol()+"->firstkey();");
+           } else if (b.getType()==Binding.CREATE) {
+               throw new Error("Creation not supported");
+               //              source.generateSourceAlloc(cr,vd,b.getSet());
+           } else {
+               VarDescriptor vd=b.getVar();
+               switch(b.getPosition()) {
+               case 0:
+                   cr.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+"="+slot0+";");
+                   break;
+               case 1:
+                   cr.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+"="+slot1+";");
+                   break;
+               default:
+                   throw new Error("Slot >1 doesn't exist.");
+               }
            }
        }
     }