Expr right;
Opcode opcode;
- public void findmatch(Descriptor d, Set s) {
- left.findmatch(d,s);
- if (right!=null)
- right.findmatch(d,s);
+ public Expr getUpper() {
+ Expr lupper=left.getUpper();
+ if (lupper==null)
+ return null;
+ if (right!=null) {
+ Expr rupper=right.getUpper();
+ if (rupper==null)
+ return null;
+ OpExpr oe=new OpExpr(this.opcode,lupper,rupper);
+ oe.td = ReservedTypeDescriptor.INT;
+ return oe;
+ } else return lupper;
+ }
+
+ public Expr getLower() {
+ Expr llower=left.getLower();
+ if (llower==null)
+ return null;
+ if (right!=null) {
+ Expr rlower=right.getLower();
+ if (rlower==null)
+ return null;
+ OpExpr oe=new OpExpr(this.opcode,llower,rlower);
+ oe.td = ReservedTypeDescriptor.INT;
+ return oe;
+ } else return llower;
+ }
+
+
+ public boolean isSafe() {
+ if (right==null)
+ return left.isSafe();
+ return left.isSafe()&&right.isSafe();
+ }
+
+ public boolean isInvariant(Set vars) {
+ return left.isInvariant(vars)&&((right==null)||right.isInvariant(vars));
+ }
+
+ public Set findInvariants(Set vars) {
+ if (isInt(this)) {
+ /* Don't hoist ints */
+ return new HashSet();
+ } else if (isInvariant(vars)) {
+ Set s=new HashSet();
+ s.add(this);
+ return s;
+ } else {
+ Set ls=left.findInvariants(vars);
+ if (right!=null)
+ ls.addAll(right.findInvariants(vars));
+ return ls;
+ }
+ }
+
+ public Set getfunctions() {
+ Set leftfunctions=left.getfunctions();
+ Set rightfunctions=null;
+ if (right!=null) rightfunctions=right.getfunctions();
+ if (leftfunctions!=null&&rightfunctions!=null) {
+ HashSet functions=new HashSet();
+ functions.addAll(leftfunctions);
+ functions.addAll(rightfunctions);
+ return functions;
+ }
+ if (leftfunctions!=null)
+ return leftfunctions;
+ return rightfunctions;
}
public static boolean isInt(Expr e) {
+ if (e==null)
+ return false;
if ((e instanceof IntegerLiteralExpr)||
- ((e instanceof OpExpr)&&(((OpExpr)e).getLeftExpr() instanceof IntegerLiteralExpr)))
+ ((e instanceof OpExpr)&&(((OpExpr)e).opcode==Opcode.NOP)&&(((OpExpr)e).getLeftExpr() instanceof IntegerLiteralExpr)))
return true;
return false;
}
(isInt(left)&&(opcode==Opcode.RND))) {
this.opcode=Opcode.NOP;
this.right=null;
- int lint=getInt(left);
- int rint=getInt(right);
+ int lint=isInt(left)?getInt(left):0;
+ int rint=isInt(right)?getInt(right):0;
int value=0;
if (opcode==Opcode.ADD) {
value=lint+rint;
value+=8;
} else throw new Error("Unrecognized Opcode");
this.left=new IntegerLiteralExpr(value);
- } else {
+ } else if ((opcode==Opcode.MULT)&&
+ ((isInt(left)&&(getInt(left)==0))
+ ||(isInt(right)&&(getInt(right)==0)))) {
+ this.opcode=Opcode.NOP;
+ this.right=null;
+ this.left=new IntegerLiteralExpr(0);
+ } else {
this.opcode = opcode;
this.left = left;
this.right = right;
if (opcode==Opcode.RND)
return "Round("+left.name()+")";
String name=left.name()+opcode.toString();
- if (right!=null)
+ if (right!=null) {
name+=right.name();
+ name="("+name+")";
+ }
return name;
}
return opcode;
}
-
-
-
public boolean equals(Map remap, Expr e) {
if (e==null||!(e instanceof OpExpr))
return false;
}
public boolean usesDescriptor(Descriptor d) {
- if (opcode==Opcode.GT||opcode==Opcode.GE||opcode==Opcode.LT||
- opcode==Opcode.LE||opcode==Opcode.EQ||opcode==Opcode.NE)
- return left.usesDescriptor(d)||(right!=null&&right.usesDescriptor(d));
- // return right.usesDescriptor(d);
- else
- return left.usesDescriptor(d)||(right!=null&&right.usesDescriptor(d));
+ return left.usesDescriptor(d)||(right!=null&&right.usesDescriptor(d));
+ }
+
+ public void findmatch(Descriptor d, Set s) {
+ left.findmatch(d,s);
+ if (right!=null)
+ right.findmatch(d,s);
}
-
- public int[] getRepairs(boolean negated) {
+ public Set useDescriptor(Descriptor d) {
+ HashSet newset=new HashSet();
+ newset.addAll(left.useDescriptor(d));
+ if (right!=null)
+ newset.addAll(right.useDescriptor(d));
+ return newset;
+ }
+
+ public int[] getRepairs(boolean negated, Termination t) {
if (left instanceof RelationExpr)
return new int[] {AbstractRepair.MODIFYRELATION};
if (left instanceof SizeofExpr) {
op=Opcode.GT;
}
+ int maxsize=t.maxsize.getsize(getDescriptor());
+ int size=getInt(right);
boolean isRelation=((SizeofExpr)left).setexpr instanceof ImageSetExpr;
if (isRelation) {
if (op==Opcode.EQ) {
- if (((IntegerLiteralExpr)right).getValue()==0)
+ if (size==0)
return new int[] {AbstractRepair.REMOVEFROMRELATION};
- else
+ else {
+ if ((maxsize!=-1)&&maxsize<=size)
+ return new int[] {AbstractRepair.ADDTORELATION};
return new int[] {AbstractRepair.ADDTORELATION,
AbstractRepair.REMOVEFROMRELATION};
+ }
} else if (op==Opcode.GE||op==Opcode.GT) {
- return new int[]{AbstractRepair.ADDTORELATION};
+ return new int[]{AbstractRepair.ADDTORELATION};
} else if (op==Opcode.LE||op==Opcode.LT) {
+ if ((op==Opcode.LT&&maxsize!=-1&&maxsize<size)||(op==Opcode.LE&&maxsize!=-1&&maxsize<=size))
+ return new int[0];
return new int[]{AbstractRepair.REMOVEFROMRELATION};
} else if (op==Opcode.NE) {
+ if (maxsize<size&&maxsize!=-1)
+ return new int[0];
return new int[]{AbstractRepair.ADDTORELATION};
} else throw new Error();
} else {
if (op==Opcode.EQ) {
- if (((IntegerLiteralExpr)right).getValue()==0)
- return new int[] {AbstractRepair.REMOVEFROMSET};
- else
+ if (size==0)
+ return new int[] {AbstractRepair.REMOVEFROMSET};
+ else {
+ if (maxsize<=size&&maxsize!=-1)
+ return new int[] {AbstractRepair.ADDTOSET};
return new int[] {AbstractRepair.ADDTOSET,
AbstractRepair.REMOVEFROMSET};
+ }
} else if (op==Opcode.GE||op==Opcode.GT) {
- return new int[] {AbstractRepair.ADDTOSET};
+ return new int[] {AbstractRepair.ADDTOSET};
} else if (op==Opcode.LE||op==Opcode.LT) {
+ if ((op==Opcode.LT&&maxsize<size&&maxsize!=-1)||(op==Opcode.LE&&maxsize<=size&&maxsize!=-1))
+ return new int[0];
return new int[] {AbstractRepair.REMOVEFROMSET};
} else if (op==Opcode.NE) {
+ if (maxsize<size&&maxsize!=-1)
+ return new int[0];
return new int[] {AbstractRepair.ADDTOSET};
} else throw new Error();
}
}
throw new Error("BAD");
}
-
+
public Descriptor getDescriptor() {
return left.getDescriptor();
}
public Set getRequiredDescriptors() {
Set v = left.getRequiredDescriptors();
-
+
if (right != null) {
v.addAll(right.getRequiredDescriptors());
}
return v;
- }
+ }
public void generate(CodeWriter writer, VarDescriptor dest) {
VarDescriptor ld = VarDescriptor.makeNew("leftop");
- left.generate(writer, ld);
+ /* Check for loop invariant hoisting. */
+ if (writer.getInvariantValue()!=null&&
+ writer.getInvariantValue().isInvariant(this)) {
+ writer.addDeclaration("int",dest.getSafeSymbol());
+ writer.outputline(dest.getSafeSymbol()+"="+writer.getInvariantValue().getValue(this).getSafeSymbol()+";");
+ writer.outputline("maybe="+writer.getInvariantValue().getMaybe(this).getSafeSymbol()+";");
+ return;
+ }
+
+ left.generate(writer, ld);
VarDescriptor rd = null;
VarDescriptor lm=VarDescriptor.makeNew("lm");
VarDescriptor rm=VarDescriptor.makeNew("rm");
if (right != null) {
if ((opcode==Opcode.OR)||
(opcode==Opcode.AND)) {
- writer.outputline("int "+lm.getSafeSymbol()+"=maybe;");
- writer.outputline("int maybe=0;");
+ writer.addDeclaration("int",lm.getSafeSymbol());
+ writer.outputline(lm.getSafeSymbol()+"=maybe;");
+ writer.outputline("maybe=0;");
}
rd = VarDescriptor.makeNew("rightop");
String code;
if (opcode == Opcode.RND) {
- writer.outputline("int " +dest.getSafeSymbol() + " = (" +
+ writer.addDeclaration("int",dest.getSafeSymbol());
+ writer.outputline(dest.getSafeSymbol() + " = (" +
ld.getSafeSymbol() + ">>3)<<3; ");
writer.outputline("if ("+ld.getSafeSymbol()+" % 8) "+dest.getSafeSymbol()+"+=8;");
} else if (opcode == Opcode.NOP) {
- writer.outputline("int " +dest.getSafeSymbol() + " = " +
+ writer.addDeclaration("int", dest.getSafeSymbol());
+ writer.outputline(dest.getSafeSymbol() + " = " +
ld.getSafeSymbol() +"; ");
- } else if (opcode != Opcode.NOT) { /* two operands */
- assert rd != null;
- writer.outputline("int " + dest.getSafeSymbol() + " = " +
- ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
} else if (opcode == Opcode.AND) {
- writer.outputline("int "+rm.getSafeSymbol()+"=maybe;");
+ writer.addDeclaration("int",rm.getSafeSymbol());
+ writer.outputline(rm.getSafeSymbol()+"=maybe;");
writer.outputline("maybe = (" + ld.getSafeSymbol() + " && " + rm.getSafeSymbol() + ") || (" + rd.getSafeSymbol() + " && " + lm.getSafeSymbol() + ") || (" + lm.getSafeSymbol() + " && " + rm.getSafeSymbol() + ");");
+ writer.addDeclaration("int",dest.getSafeSymbol());
writer.outputline(dest.getSafeSymbol() + " = " + ld.getSafeSymbol() + " && " + rd.getSafeSymbol() + ";");
} else if (opcode == Opcode.OR) {
- writer.outputline("int "+rm.getSafeSymbol()+"=maybe;");
+ writer.addDeclaration("int",rm.getSafeSymbol());
+ writer.outputline(rm.getSafeSymbol()+"=maybe;");
writer.outputline("maybe = (!" + ld.getSafeSymbol() + " && " + rm.getSafeSymbol() + ") || (!" + rd.getSafeSymbol() +
" && " + lm.getSafeSymbol() + ") || (" + lm.getSafeSymbol() + " && " + rm.getSafeSymbol() + ");");
- writer.outputline(dest.getSafeSymbol() + " = " + ld.getSafeSymbol() + " || " + rd.getSafeSymbol() +
- ";");
- } else {
- writer.outputline("int " + dest.getSafeSymbol() + " = !" + ld.getSafeSymbol() + ";");
+ writer.addDeclaration("int",dest.getSafeSymbol());
+ writer.outputline(dest.getSafeSymbol() + " = " + ld.getSafeSymbol() + " || " + rd.getSafeSymbol() + ";");
+ } else if (opcode != Opcode.NOT) { /* two operands */
+ assert rd != null;
+ writer.addDeclaration("int", dest.getSafeSymbol());
+ writer.outputline(dest.getSafeSymbol() + " = " +
+ ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
+ } else if (opcode == Opcode.NOT) {
+ writer.addDeclaration("int", dest.getSafeSymbol());
+ writer.outputline(dest.getSafeSymbol() + " = !" + ld.getSafeSymbol() + ";");
}
}
public void prettyPrint(PrettyPrinter pp) {
pp.output("(");
if (opcode == Opcode.NOT) {
- pp.output("!");
+ pp.output("!(");
left.prettyPrint(pp);
+ pp.output(")");
} else if (opcode == Opcode.NOP) {
left.prettyPrint(pp);
} else if (opcode == Opcode.RND) {
pp.output("RND ");
left.prettyPrint(pp);
- } else {
+ } else {
left.prettyPrint(pp);
pp.output(" " + opcode.toString() + " ");
assert right != null;
boolean ok = true;
- // #ATTN#: if we want node.next != literal(0) to represent a null check than we need to allow ptr arithmetic
- // either that or we use a isvalid clause to check for null
-
- /*
- if (lt != ReservedTypeDescriptor.INT) {
- sa.getErrorReporter().report(null, "Left hand side of expression is of type '" + lt.getSymbol() + "' but must be type 'int'");
- ok = false;
- }
-
- if (right != null) {
- if (rt != ReservedTypeDescriptor.INT) {
- sa.getErrorReporter().report(null, "Right hand side of expression is of type '" + rt.getSymbol() + "' but must be type 'int'");
- ok = false;
- }
- }
- */
-
if (!ok) {
return null;
}
}
}
-
-
-
-
-