private boolean hasRegularLoopGuard(ForStmt loop, String counterName) { if (!(loop.getCondition() instanceof BinaryExpr)) { return false; } final BinaryExpr guard = (BinaryExpr) loop.getCondition(); if (!(guard.getOp() == BinOp.LT || guard.getOp() == BinOp.GT)) { return false; } if (!(guard.getLhs() instanceof VariableIdentifierExpr)) { return false; } if (!(guard.getRhs() instanceof IntConstantExpr)) { return false; } return ((VariableIdentifierExpr) guard.getLhs()).getName().equals(counterName); }
private ExprStmt setHasReturned() { return new ExprStmt(new BinaryExpr(makeHasReturned(), BoolConstantExpr.TRUE, BinOp.ASSIGN)); } }.visit(fd);
@Override public void applyReductionImpl() { final BinaryExpr assignment = (BinaryExpr) stmt.getExpr(); final Expr expr = ((ReturnStmt) outlined.getBody().getStmt(0)).getExpr().clone(); Map<String, Expr> paramReplacement = new HashMap<>(); for (int i = 0; i < outlined.getPrototype().getNumParameters(); i++) { Expr actualParam = ((FunctionCallExpr) assignment.getRhs()).getArg(i); assert actualParam != null; paramReplacement.put(outlined.getPrototype().getParameter(i).getName(), actualParam); } assert assignment.getOp() == BinOp.ASSIGN; stmt.setExpr(new BinaryExpr(assignment.getLhs(), applySubstitutionDestructive(expr, paramReplacement), BinOp.ASSIGN)); }
static boolean isAssignment(Stmt stmt) { if (!(stmt instanceof ExprStmt)) { return false; } if (!(((ExprStmt)stmt).getExpr() instanceof BinaryExpr)) { return false; } return ((BinaryExpr)((ExprStmt)stmt).getExpr()).getOp() == BinOp.ASSIGN; }
public OutlineStatementOpportunity(ExprStmt toOutline, Scope scopeOfStmt, TranslationUnit tu, FunctionDefinition enclosingFunction) { this.scopeOfStmt = scopeOfStmt; this.toOutline = toOutline; this.tu = tu; this.enclosingFunction = enclosingFunction; if (!isAssignment(toOutline)) { throw new IllegalArgumentException("Can only outline an assignment statement"); } if (!assignsDirectlyToVariable((BinaryExpr) toOutline.getExpr())) { throw new IllegalArgumentException("At present, can only outline an assignment directly to " + "a variable"); } if (referencesArray(((BinaryExpr) toOutline.getExpr()).getRhs())) { throw new IllegalArgumentException("At present, we cannot handle arrays on the RHS of an " + "outlined expression"); } }
public void apply(IdGenerator idGenerator) { BinaryExpr be = (BinaryExpr) toOutline.getExpr(); assert be.getOp() == BinOp.ASSIGN; final List<String> referencedVariables = getReferencedVariables(be.getRhs()); final String newFunctionName = Constants.OUTLINED_FUNCTION_PREFIX + idGenerator.freshId(); toOutline.setExpr(new BinaryExpr( be.getLhs().clone(), new FunctionCallExpr(newFunctionName, referencedVariables.stream().map(item -> new VariableIdentifierExpr(item)) .collect(Collectors.toList())), BinOp.ASSIGN)); ((VariableIdentifierExpr) be.getLhs()).getName()); if (returnType == null) { switch (((VariableIdentifierExpr) be.getLhs()).getName()) { case OpenGlConstants.GL_FRAG_COLOR: case OpenGlConstants.GL_FRAG_COORD: default: assert returnType != null : "No type for " + ((VariableIdentifierExpr) be.getLhs()).getName(); params), new BlockStmt(Arrays.asList( new ReturnStmt(be.getRhs().clone())), false)), enclosingFunction);
@Override public void visitBinaryExpr(BinaryExpr binaryExpr) { super.visitBinaryExpr(binaryExpr); if (binaryExpr.getOp().isSideEffecting()) { if (binaryExpr.getLhs() instanceof VariableIdentifierExpr && ((VariableIdentifierExpr) binaryExpr.getLhs()).getName() .equals(loopCounterName)) { foundModification = true; } } }
private static void replaceLoopCounterInCondition(Expr condition, String newLoopCounter) { BinaryExpr binaryExpr = (BinaryExpr) condition; VariableIdentifierExpr toReplace; if (binaryExpr.getLhs() instanceof VariableIdentifierExpr) { toReplace = (VariableIdentifierExpr) binaryExpr.getLhs(); } else { toReplace = (VariableIdentifierExpr) binaryExpr.getRhs(); } toReplace.setName(newLoopCounter); }
private boolean canMergeLoops(Stmt first, Stmt second) { if (!(first instanceof ForStmt && second instanceof ForStmt)) { return false; } ForStmt firstLoop = (ForStmt) first; ForStmt secondLoop = (ForStmt) second; Optional<String> commonLoopCounter = checkForCommonLoopCounter(firstLoop, secondLoop); if (!commonLoopCounter.isPresent()) { return false; } if (!commonLoopCounter.get().startsWith(Constants.SPLIT_LOOP_COUNTER_PREFIX)) { return false; } if (!hasRegularLoopGuard(firstLoop, commonLoopCounter.get())) { return false; } if (!hasRegularLoopGuard(secondLoop, commonLoopCounter.get())) { return false; } final Integer firstLoopEnd = new Integer(((IntConstantExpr) ((BinaryExpr) firstLoop.getCondition()).getRhs()).getValue()); final BinOp firstLoopOp = ((BinaryExpr) firstLoop.getCondition()).getOp(); final Integer secondLoopStart = new Integer(((IntConstantExpr) ((ScalarInitializer) ((DeclarationStmt) secondLoop.getInit()).getVariablesDeclaration().getDeclInfo(0) .getInitializer()).getExpr()).getValue()); assert firstLoopOp == BinOp.LT || firstLoopOp == BinOp.GT : "Unexpected operator in split loops."; return firstLoopEnd.equals(secondLoopStart); }
@Override public void visitBinaryExpr(BinaryExpr binaryExpr) { if (binaryExpr.getOp().isSideEffecting()) { predicateHolds(); } super.visitBinaryExpr(binaryExpr); }
@Override public void visitExprStmt(ExprStmt exprStmt) { super.visitExprStmt(exprStmt); if (!OutlineStatementOpportunity.isAssignment(exprStmt)) { return; } BinaryExpr be = (BinaryExpr) exprStmt.getExpr(); if (!OutlineStatementOpportunity.assignsDirectlyToVariable(be)) { return; } if (referencesArray(be.getRhs(), currentScope)) { return; } opportunities.add(new OutlineStatementOpportunity(exprStmt, currentScope, tu, enclosingFunction)); }
/** * Determines whether the given statement came from a live code injection. * * @param stmt A statement to be analysed * @return Whether the statement is injected live code or not */ public static boolean isSimpleLiveCodeInjection(Stmt stmt) { if (!(stmt instanceof ExprStmt)) { return false; } final Expr expr = ((ExprStmt) stmt).getExpr(); if (expr instanceof BinaryExpr) { if (!((BinaryExpr) expr).getOp().isSideEffecting()) { return false; } return isLiveInjectionVariableReference(((BinaryExpr) expr).getLhs()); } if (expr instanceof UnaryExpr) { if (!((UnaryExpr) expr).getOp().isSideEffecting()) { return false; } return isLiveInjectionVariableReference(((UnaryExpr) expr).getExpr()); } if (expr instanceof FunctionCallExpr) { return ((FunctionCallExpr) expr).getCallee().startsWith(Constants.LIVE_PREFIX); } return false; }
private <T> Expr handleBinary(List<T> operands, List<Token> operators, Function<T, Expr> childVisitor) { assert operands.size() == operators.size() + 1; assert operands.size() >= 1; Expr result = childVisitor.apply(operands.get(0)); for (int i = 0; i < operators.size(); i++) { result = new BinaryExpr(result, childVisitor.apply(operands.get(i + 1)), getBinOp(operators.get(i))); } return result; }
private Optional<ImmutablePair<BinOp,Integer>> getCondTestTypeAndLimitValue(Expr cond, String loopCounterName) { if (!(cond instanceof BinaryExpr)) { return Optional.empty(); } final BinaryExpr binaryExprCond = (BinaryExpr) cond; Optional<Integer> condLimitValue = getAsConstant(binaryExprCond.getRhs()); if (condLimitValue.isPresent() && isSameVarIdentifier(binaryExprCond.getLhs(), loopCounterName)) { return Optional.of(new ImmutablePair<>(binaryExprCond.getOp(), condLimitValue.get())); } condLimitValue = getAsConstant(binaryExprCond.getLhs()); if (condLimitValue.isPresent() && isSameVarIdentifier(binaryExprCond.getRhs(), loopCounterName)) { return Optional.of(new ImmutablePair<>(switchCondTestType(binaryExprCond.getOp()), condLimitValue.get())); } return Optional.empty(); }
@Override public Expr generateExpr(IRandom generator, Expr... args) { assert args.length == getNumArguments(); return new ParenExpr(new BinaryExpr(args[0], args[1], op)); }