private Optional<String> extractLoopCounter(ForStmt loop) { if (!(loop.getInit() instanceof DeclarationStmt)) { return Optional.empty(); } final DeclarationStmt init = (DeclarationStmt) loop.getInit(); if (init.getVariablesDeclaration().getNumDecls() != 1) { return Optional.empty(); } return Optional.of(init.getVariablesDeclaration().getDeclInfo(0).getName()); }
@Override public void applyReductionImpl() { firstLoop.setCondition(secondLoop.getCondition()); enclosingBlock.removeStmt(secondLoop); final String splitLoopCounter = ((DeclarationStmt) firstLoop.getInit()) .getVariablesDeclaration().getDeclInfo(0).getName(); int originalNameBeginIndex = Constants.SPLIT_LOOP_COUNTER_PREFIX.length(); assert Character.isDigit(splitLoopCounter.charAt(originalNameBeginIndex)); while (Character.isDigit(splitLoopCounter.charAt(originalNameBeginIndex))) { originalNameBeginIndex++; } final String mergedLoopCounter = splitLoopCounter.substring(originalNameBeginIndex); ReplaceLoopCounter.replaceLoopCounter(firstLoop, splitLoopCounter, mergedLoopCounter); }
private boolean maybeLongRunning(ForStmt forStmt) { final Optional<ImmutablePair<String, Integer>> initValueAndLoopCounterName = getLoopCounterNameAndInitValue(forStmt.getInit()); if (!initValueAndLoopCounterName.isPresent()) { return false; } final String loopCounterName = initValueAndLoopCounterName.get().left; final int initValue = initValueAndLoopCounterName.get().right; final Optional<ImmutablePair<BinOp, Integer>> condTestTypeAndLimitValue = getCondTestTypeAndLimitValue(forStmt.getCondition(), loopCounterName); if (!condTestTypeAndLimitValue.isPresent()) { return false; } final BinOp condTestType = condTestTypeAndLimitValue.get().left; final int condLimitValue = condTestTypeAndLimitValue.get().right; if (condTestType.isSideEffecting()) { return false; } final Optional<Integer> incrementValue = getIncrementValue(forStmt.getIncrement(), loopCounterName); if (!incrementValue.isPresent()) { return false; } return (((condTestType == BinOp.LT || condTestType == BinOp.LE) && incrementValue.get() <= 0) || ((condTestType == BinOp.GT || condTestType == BinOp.GE) && incrementValue.get() >= 0) || ((condLimitValue - initValue) / incrementValue.get() >= limit)); }
@Override public void applyReductionImpl() { Stmt replacement; if (compoundStmt instanceof ForStmt) { final ForStmt forStmt = (ForStmt) compoundStmt; assert childStmt == forStmt.getBody(); List<Stmt> stmts = new ArrayList<>(); stmts.add(forStmt.getInit()); if (forStmt.getBody() instanceof BlockStmt) { stmts.addAll(((BlockStmt) forStmt.getBody()).getStmts()); } else { stmts.add(forStmt.getBody()); } replacement = new BlockStmt(stmts, true); } else { replacement = childStmt; } parent.replaceChild(compoundStmt, replacement); }
public static ForStmt replaceLoopCounter(ForStmt loop, String oldLoopCounter, String newLoopCounter) { final Map<String, String> substitution = new HashMap<>(); substitution.put(oldLoopCounter, newLoopCounter); new ApplySubstitution(substitution, loop.getBody()); replaceLoopCounterInInitializer(loop.getInit(), newLoopCounter); replaceLoopCounterInCondition(loop.getCondition(), newLoopCounter); replaceLoopCounterInIncrement(loop.getIncrement(), newLoopCounter); return loop; }
private void adjustInitializer(ForStmt loop, int numIterationsToSplitAfter, LoopSplitInfo loopSplitInfo) { final Integer newStart = new Integer(loopSplitInfo.getStartValue() + (loopSplitInfo.getIncreasing() ? 1 : -1) * numIterationsToSplitAfter); VariablesDeclaration varDecl = ((DeclarationStmt) loop.getInit()).getVariablesDeclaration(); varDecl.getDeclInfo(0).setInitializer(new ScalarInitializer(new IntConstantExpr( newStart.toString()))); }
@Override public void visitForStmt(ForStmt forStmt) { out.append(indent() + "for(" + newLine()); out.append(" "); visit(forStmt.getInit()); out.append(" " + indent()); visit(forStmt.getCondition()); out.append(";" + newLine()); out.append(" " + indent()); visit(forStmt.getIncrement()); out.append(newLine()); out.append(indent() + ")" + newLine()); increaseIndent(); visit(forStmt.getBody()); decreaseIndent(); }
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 visitForStmt(ForStmt forStmt) { visitChildFromParent(forStmt.getInit(), forStmt); visitChildFromParent(forStmt.getCondition(), forStmt); visitChildFromParent(forStmt.getIncrement(), forStmt); visitChildFromParent(forStmt.getBody(), forStmt); }