void addTemp(Parameter p, Expression actual, List<Expression> newParams, VarReplacer vr) { String name = varGen.nextVar(p.getName()); addStatement(new StmtVarDecl(actual, (Type) p.getType().accept(vr), name, actual)); Expression ev = new ExprVar(actual, name); newParams.add(ev); after.add(new StmtAssign(actual, ev)); }
public Object visitExprFunCall(ExprFunCall efc) { Function fun = nres.getFun(efc.getName()); List<Expression> newParams = new ArrayList<Expression>(fun.getParams().size()); Map<Expression, Integer> pset = new HashMap<Expression, Integer>(); Iterator<Expression> eit = efc.getParams().iterator(); for (Parameter p : fun.getParams()) { Expression actual = eit.next(); { ExprVar ev = getBaseVar(actual); if (ev != null && pset.containsKey(ev)) { pset.put(ev, pset.get(ev) + 1); } else { pset.put(ev, 1); } } } boolean hasChanged = false; eit = efc.getParams().iterator(); Map<String, Expression> repl = new HashMap<String, Expression>(); VarReplacer vr = new VarReplacer(repl); for (Parameter p : fun.getParams()) { Expression actual = eit.next(); repl.put(p.getName(), actual); if (p.isParameterOutput()) { ExprVar ev = getBaseVar(actual); if (ev == null) { newParams.add(actual); continue; } if (ev == FromHeap) { addTemp(p, actual, newParams, vr); hasChanged = true; continue; } int cnt = pset.get(ev); if (cnt > 1) { addTemp(p, actual, newParams, vr); hasChanged = true; } else { newParams.add(actual); } } else { newParams.add(actual); } } if (!hasChanged) addStatement(new StmtExpr(efc)); else addStatement(new StmtExpr(new ExprFunCall(efc, efc.getName(), newParams))); addStatements(after); after.clear(); return null; }
@Override public Object visitExprFunCall(ExprFunCall exp) { exp = (ExprFunCall) super.visitExprFunCall(exp); Function callee = nres.getFun(exp.getName()); Map<String, Expression> repl = new HashMap<String, Expression>(); VarReplacer vr = new VarReplacer(repl); for (ZipIdxEnt<Expression> arg : zipwithindex(exp.getParams())) { Expression actual = arg.entry; Parameter p = callee.getParams().get(arg.idx); Type t = p.getType(); repl.put(p.getName(), actual); upgradeStarToInt(actual, (Type) t.accept(vr)); } return exp; }
@Override public Object visitFunction(Function fcn) { if (fcn.isSketchHarness() || fcn.getSpecification() != null || specFcns.contains(fcn.getName()) || !fcn.isStatic()) { return fcn; } else { this.parametersToInout = new TypedHashSet<String>(); this.inputParameters = new Vector<String>(); for (Parameter param : fcn.getParams()) { if (!param.isParameterOutput()) { this.inputParameters.add(param.getName()); } } super.visitFunction(fcn); if (parametersToInout.isEmpty()) { return fcn; } else { Vector<Parameter> newParams = new Vector<Parameter>(); for (Parameter param : fcn.getParams()) { if (parametersToInout.contains(param.getName())) { newParams.add(new Parameter(param, param.getType(), param.getName(), Parameter.REF)); } else { newParams.add(param); } } return fcn.creator().params(newParams).create(); } } }
private Function addAssumes(Function f) { Map<Expression, Expression> lenVars = new HashMap<Expression, Expression>(); List<Statement> stmts = new ArrayList<Statement>(); for (Parameter p : f.getParams()) { Type t = p.getType(); if (t.isArray()) { TypeArray ta = (TypeArray) t; Type tb = ta.getBase(); if (!tb.isArray()) { Expression len = ta.getLength(); if (!len.isConstant()) { Expression v = lenVars.get(len); if (v == null) { String vname = varGen.nextVar("valen_" + p.getName()); v = new ExprVar(p, vname); lenVars.put(len, v); stmts.add(new StmtVarDecl(p, TypePrimitive.inttype, vname, len)); } Expression zero = tb.defaultValue(); Expression arr = new ExprVar(p, p.getName()); for (int j = 0; j < arrSize; ++j) { Expression jexp = constInts.get(j); Expression cond1 = new ExprBinary(p, ExprBinary.BINOP_GT, v, jexp); Expression cond2 = new ExprBinary(p, ExprBinary.BINOP_EQ, zero, new ExprArrayRange(arr, jexp)); stmts.add( new StmtAssume( p, new ExprBinary(p, ExprBinary.BINOP_OR, cond1, cond2), "trunc " + p.getName() + " " + j)); } } } } } if (stmts.isEmpty()) { return f; } else { stmts.addAll(((StmtBlock) f.getBody()).getStmts()); return f.creator().body(new StmtBlock(stmts)).create(); } }