private boolean isEmptyBlockStmt(Stmt stmt) { return stmt instanceof BlockStmt && ((BlockStmt) stmt).getNumStmts() == 0; }
private boolean isNonEmptyBlockStmtWithoutTopLevelDeclaration(Stmt stmt) { if (!(stmt instanceof BlockStmt)) { return false; } final BlockStmt blockStmt = (BlockStmt) stmt; return blockStmt.getNumStmts() > 0 && blockStmt.getStmts().stream() .noneMatch(item -> item instanceof DeclarationStmt); }
private Optional<Integer> indexOfAssignment(String lhsName, String rhsName) { for (int i = 0; i < block.getNumStmts(); i++) { if (isAssignment(block.getStmt(i), lhsName, rhsName)) { return Optional.of(i); } } return Optional.empty(); }
@Override public void inject(Stmt stmt) { if (nextStmt == null) { blockStmt.insertStmt(blockStmt.getNumStmts(), stmt); } else { blockStmt.insertBefore(nextStmt, stmt); } }
private List<Stmt> generateReachableSwitchCases(BlockStmt block, int numCases, List<Integer> usedLabels, IRandom generator) { // Index i of this list stores the case labels to appear before statement i List<List<Integer>> stmtIndexToCaseLabels = new ArrayList<>(); // Initially make the label sets empty for (int i = 0; i < block.getNumStmts(); i++) { stmtIndexToCaseLabels.add(new ArrayList<>()); } // Label 0, which is what we should actually jump to, is the first label. stmtIndexToCaseLabels.get(0).add(0); for (int i = 0; i < numCases; i++) { stmtIndexToCaseLabels.get(generator.nextInt(block.getNumStmts())) .add(getCaseLabel(usedLabels, generator)); } List<Stmt> result = new ArrayList<>(); for (int i = 0; i < block.getNumStmts(); i++) { result.addAll(stmtIndexToCaseLabels.get(i) .stream().map(item -> new ExprCaseLabel(new IntConstantExpr(item.toString()))) .collect(Collectors.toList())); result.add(block.getStmt(i)); } result.add(BreakStmt.INSTANCE); return result; }
@Override public void visitBlockStmt(BlockStmt block) { final BlockStmt prevBlock = currentBlockStmt; final int prevIndex = currentIndex; currentBlockStmt = block; for (currentIndex = 0; currentIndex < block.getNumStmts(); currentIndex++) { visit(block.getStmt(currentIndex)); } currentBlockStmt = prevBlock; currentIndex = prevIndex; }
private Optional<Integer> indexOfBackupDeclaration() { for (int i = 0; i < block.getNumStmts(); i++) { if (!(block.getStmt(i) instanceof DeclarationStmt)) { continue; } if (isOutVariableBackup( (DeclarationStmt) block.getStmt(i))) { return Optional.of(i); } } return Optional.empty(); }
@Override void applyReductionImpl() { List<Stmt> newStmts = new ArrayList<>(); for (int i = 0; i < block.getNumStmts(); i++) { if (i == indexOfBackupDeclaration().get()) { continue; } if (i >= indexOfAssignmentToBackup().get() && i <= indexOfRestorationFromBackup().get()) { continue; } newStmts.add(block.getStmt(i)); } block.setStmts(newStmts); }
@Override public void applyReductionImpl() { for (int i = 0; i < blockStmt.getNumStmts(); i++) { if (child == blockStmt.getStmt(i)) { blockStmt.removeStmt(i); return; } } throw new FailedReductionException("Should be unreachable."); }
@Override public void replaceNext(Stmt stmt) { assert hasNextStmt(); for (int i = 0; i < blockStmt.getNumStmts(); i++) { if (blockStmt.getStmt(i) == nextStmt) { blockStmt.setStmt(i, stmt); } } }
for (int i = restoreIndex.get() + 1; i < block.getNumStmts(); i++) { if (referencesBackup(block.getStmt(i))) { return false;
public OutlinedStatementReductionOpportunity(ExprStmt stmt, FunctionDefinition outlined, VisitationDepth depth) { super(depth); assert stmt.getExpr() instanceof BinaryExpr; assert outlined.getBody().getNumStmts() == 1; assert outlined.getBody().getStmt(0) instanceof ReturnStmt; this.stmt = stmt; this.outlined = outlined; }
if (relevantFunction.getBody().getNumStmts() != 1) { return;
private Optional<Integer> indexOfRestorationFromBackup() { final Optional<Integer> maybeAssignmentIndex = indexOfAssignment(getOriginalVariableName(), backupName); if (maybeAssignmentIndex.isPresent()) { return maybeAssignmentIndex; } for (int i = 0; i < block.getNumStmts(); i++) { final Stmt stmt = block.getStmt(i); if (!(stmt instanceof IfStmt)) { continue; } final IfStmt ifStmt = (IfStmt) stmt; if (!MacroNames.isIfWrapperTrue(ifStmt.getCondition())) { continue; } if (isAssignment(ifStmt.getThenStmt(), getOriginalVariableName(), backupName)) { return Optional.of(i); } if (ifStmt.getThenStmt() instanceof BlockStmt && ((BlockStmt) ifStmt.getThenStmt()).getNumStmts() == 1 && isAssignment(((BlockStmt) ifStmt.getThenStmt()).getStmt(0), getOriginalVariableName(), backupName)) { return Optional.of(i); } } return Optional.empty(); }
private boolean isLoopLimiterBlock(Stmt stmt) { // Identifies when a block starts with a loop-limiter declaration, in which case the whole // block can go. We are really careful about otherwise removing loop-limiters, so this is // the chance to do it! if (!(stmt instanceof BlockStmt)) { return false; } final BlockStmt blockStmt = (BlockStmt) stmt; if (blockStmt.getNumStmts() == 0) { return false; } final Stmt firstStmt = blockStmt.getStmt(0); if (!(firstStmt instanceof DeclarationStmt)) { return false; } final DeclarationStmt declarationStmt = (DeclarationStmt) firstStmt; if (declarationStmt.getVariablesDeclaration().getNumDecls() == 0) { return false; } return isLooplimiter(declarationStmt.getVariablesDeclaration().getDeclInfo(0).getName()); }
assert stmt instanceof BlockStmt; BlockStmt block = (BlockStmt) stmt; if (block.getNumStmts() == 0) { return;
@Override public void visitBlockStmt(BlockStmt stmt) { enterBlockStmt(stmt); // This setup ensures that variables declared inside the block are in scope by the time we // consider each statement as an injection point. // It is a bit ugly because it has to mimic the "enter ... leave" structure of ScopeTreeBuilder for (int i = 0; i < stmt.getNumStmts(); i++) { Stmt innerStmt = stmt.getStmt(i); if (i == 0 && innerStmt instanceof CaseLabel) { // Don't allow injection before first label of case. continue; } maybeAddInjectionPoint(new BlockInjectionPoint(stmt, innerStmt, currentFunction, inLoop(), currentScope)); visit(innerStmt); } maybeAddInjectionPoint(new BlockInjectionPoint(stmt, null, currentFunction, inLoop(), currentScope)); leaveBlockStmt(stmt); }
private void doRemoveReturns() throws CannotRemoveReturnsException { if (!containsReturn(fd.getBody())) { // No return to remove return; } if (numReturnStmts(fd.getBody()) == 1 && fd.getBody() .getStmt(fd.getBody().getNumStmts() - 1) instanceof ReturnStmt) { // Only one return at end -- removing it doesn't simplify things return; } if (containsSwitch(fd)) { throw new CannotRemoveReturnsException("Switch statements not yet supported."); } addReturnInstrumentation(); replaceReturnStatements(); addSpecialDeclarations(); }