private Stmt makeBlock(Stmt stmt) { return new BlockStmt(Arrays.asList(stmt), true); }
private BlockStmt emptyBlock() { return new BlockStmt(new ArrayList<>(), true); }
@Override public BlockStmt clone() { return new BlockStmt(stmts.stream().map(x -> x.clone()).collect(Collectors.toList()), introducesNewScope); }
private List<Stmt> regionStackToStmts(List<List<Stmt>> regionStack) { if (regionStack.size() == 1) { return regionStack.get(0); } final List<Stmt> result = new ArrayList<>(); result.addAll(regionStack.get(0)); // Check that the remainder actually contains some statements if (regionStack.subList(1, regionStack.size()).stream().anyMatch(item -> !item.isEmpty())) { result.add(new IfStmt( new UnaryExpr(makeHasReturned(), UnOp.LNOT), new BlockStmt(regionStackToStmts( regionStack.subList(1, regionStack.size())), true), null)); } return result; }
@Override public void inject(Stmt stmt) { assert !(loopStmt.getBody() instanceof BlockStmt); List<Stmt> stmts = new ArrayList<>(); stmts.add(stmt); stmts.add(loopStmt.getBody()); loopStmt.setBody(new BlockStmt(stmts, false)); }
@Override public void inject(Stmt stmt) { if (chooseThen) { assert !(ifStmt.getThenStmt() instanceof BlockStmt); List<Stmt> stmts = new ArrayList<>(); stmts.add(stmt); stmts.add(ifStmt.getThenStmt()); ifStmt.setThenStmt(new BlockStmt(stmts, false)); } else { assert ifStmt.hasElseStmt(); assert !(ifStmt.getElseStmt() instanceof BlockStmt); List<Stmt> stmts = new ArrayList<>(); stmts.add(stmt); stmts.add(ifStmt.getElseStmt()); ifStmt.setElseStmt(new BlockStmt(stmts, false)); } }
@Override public BlockStmt visitSwitch_body(Switch_bodyContext ctx) { if (ctx.case_statement_list() == null) { return new BlockStmt(new ArrayList<>(), true); } Deque<Case_statementContext> cases = new LinkedList<>(); { Case_statement_listContext temp = ctx.case_statement_list(); while (true) { cases.addFirst(temp.case_statement()); if (temp.case_statement_list() == null) { break; } temp = temp.case_statement_list(); } } final List<Stmt> stmts = new ArrayList<>(); for (Case_statementContext caseCtx : cases) { stmts.addAll(visitCase_statement(caseCtx)); } return new BlockStmt(stmts, true); }
private BlockStmt fuzzBlockStmt(boolean introducesNewScope) { if (introducesNewScope) { fuzzingContext.enterScope(); } List<Stmt> stmts = new ArrayList<>(); // Populate with null statements for now final int numStmts = generator.nextInt(MAX_BLOCK_STMTS); for (int i = 0; i < numStmts; i++) { stmts.add(fuzzStmt()); } if (introducesNewScope) { fuzzingContext.leaveScope(); } return new BlockStmt(stmts, introducesNewScope); }
@Override public boolean apply(TranslationUnit tu, TransformationProbabilities probabilities, ShadingLanguageVersion shadingLanguageVersion, IRandom generator, GenerationParams generationParams) { List<IInjectionPoint> injectionPoints = new InjectionPoints(tu, generator, AddWrappingConditionalStmts::suitableForWrapping).getInjectionPoints( probabilities::wrapStmtInConditional); for (IInjectionPoint injectionPoint : injectionPoints) { assert suitableForWrapping(injectionPoint); Stmt wrapped = wrapStatement(injectionPoint, generator, shadingLanguageVersion, generationParams); if (injectionPoint instanceof IfInjectionPoint) { // Avoid replacing the body of an if with an if, due to dangling else problem wrapped = new BlockStmt(Arrays.asList(wrapped), false); } injectionPoint.replaceNext(wrapped); } return !injectionPoints.isEmpty(); }
@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); }
@Override public void applyReductionImpl() { BlockStmt replacement = new BlockStmt(new ArrayList<>(), true); boolean reachedOriginalCode = false; for (Stmt stmt : switchStmt.getBody().getStmts()) { if (!reachedOriginalCode) { if (!(stmt instanceof ExprCaseLabel && isZeroLabel((ExprCaseLabel) stmt))) { continue; } reachedOriginalCode = true; } if (stmt instanceof BreakStmt) { break; } if (stmt instanceof CaseLabel) { continue; } replacement.addStmt(stmt); } parent.replaceChild(switchStmt, replacement); }
@Override public void applyReductionImpl() { try { Stmt parent = (Stmt) parentMap.getParent(wrapper); if (parent instanceof BlockStmt) { final BlockStmt parentBlock = (BlockStmt) parent; if (!parentBlock.getStmts().contains(wrapper)) { throw new ChildDoesNotExistException(wrapper, parentBlock); } for (Stmt stmt : wrapees) { parentBlock.insertBefore(wrapper, stmt); } parentBlock.removeStmt(wrapper); } else { parent.replaceChild(wrapper, wrapees.size() == 1 ? wrapees.get(0) : new BlockStmt(wrapees, true)); } } catch (ChildDoesNotExistException exception) { // TODO: it would be cleaner to capture this in the precondition. // The wrapper has already been eliminated // by some other reduction opportunity } }
private IfStmt prepareReturnStmt(IInjectionPoint injectionPoint, IRandom generator, ShadingLanguageVersion shadingLanguageVersion, GenerationParams generationParams) { Type returnType = injectionPoint.getEnclosingFunction().getPrototype().getReturnType(); Stmt stmtToInject; if (returnType.hasCanonicalConstant()) { stmtToInject = new ReturnStmt(returnType.getCanonicalConstant()); } else if (returnType.getWithoutQualifiers() == VoidType.VOID) { stmtToInject = new ReturnStmt(); } else { stmtToInject = new BlockStmt(new ArrayList<>(), true); } return makeDeadConditional(injectionPoint, stmtToInject, generator, shadingLanguageVersion, generationParams); }
private Stmt splitForLoop(IInjectionPoint injectionPoint, IRandom generator) { assert injectionPoint.getNextStmt() instanceof ForStmt; ForStmt original = (ForStmt) injectionPoint.getNextStmt(); LoopSplitInfo loopSplitInfo = maybeGetLoopSplitInfo(original).get(); final int renamedCounterId = loopVariableRenameCounter++; String newLoopCounter = Constants.SPLIT_LOOP_COUNTER_PREFIX + renamedCounterId + loopSplitInfo.getLoopCounter(); ForStmt firstLoop = cloneWithReplacedLoopCounter(original, loopSplitInfo.getLoopCounter(), newLoopCounter); ForStmt secondLoop = cloneWithReplacedLoopCounter(original, loopSplitInfo.getLoopCounter(), newLoopCounter); int numIterationsToSplitAfter = generator.nextInt( Math.abs(loopSplitInfo.getStartValue() - loopSplitInfo.getEndValue()) + 1); adjustBound(firstLoop, numIterationsToSplitAfter, loopSplitInfo, newLoopCounter); adjustInitializer(secondLoop, numIterationsToSplitAfter, loopSplitInfo); return new BlockStmt( Arrays.asList(firstLoop, secondLoop), true); }
@Override public void visitForStmt(ForStmt forStmt) { super.visitForStmt(forStmt); if (isUnwrappable(forStmt)) { Stmt wrappee = forStmt.getBody(); if (wrappee instanceof BlockStmt) { // A ForStmt's block does not introduce a new scope, but we need it to when unwrapped. assert !((BlockStmt) wrappee).introducesNewScope(); wrappee = new BlockStmt(((BlockStmt) wrappee).getStmts(), true); } addOpportunity(new UnwrapReductionOpportunity(forStmt, wrappee, parentMap, getVistitationDepth())); } }
@Override public void visitReturnStmt(ReturnStmt returnStmt) { if (returnStmt.hasExpr()) { parentMap.getParent(returnStmt).replaceChild(returnStmt, new BlockStmt(Arrays.asList( new ExprStmt(new BinaryExpr(makeReturnValue(), returnStmt.getExpr(), BinOp.ASSIGN)), setHasReturned()), true)); } else { parentMap.getParent(returnStmt).replaceChild(returnStmt, setHasReturned()); } }
private IfStmt prepareFragColorWrite(IInjectionPoint injectionPoint, IRandom generator, ShadingLanguageVersion shadingLanguageVersion, GenerationParams generationParams) { final Pair<String, Type> outputVariableInfo = chooseOutputVariable(injectionPoint, generator, shadingLanguageVersion, generationParams); final String outputVariableName = outputVariableInfo.getLeft(); final Type outputVariableType = outputVariableInfo.getRight(); return AddJumpStmts.makeDeadConditional(injectionPoint, new BlockStmt(Arrays.asList( new ExprStmt(new BinaryExpr( new VariableIdentifierExpr(outputVariableName), new Fuzzer(new FuzzingContext(), shadingLanguageVersion, generator, generationParams) .fuzzExpr(outputVariableType, false, false, 0), BinOp.ASSIGN) )), true), generator, shadingLanguageVersion, generationParams); }