@Test public void prepareStatementToDonateContinueInLoopKept() throws Exception { final DonateDeadCodeTransformation dlc = getDummyTransformationObject(); final TranslationUnit donor = ParseHelper.parse("#version 100\n" + "void main() {\n" + " for (int i = 0; i < 10; i ++)\n" + " if (i > 5) continue;\n" + "\n" + "}\n"); final TranslationUnit reference = ParseHelper.parse("#version 100\n" + "void main() {\n" + " ;\n" + " for(int i = 0; i < 100; i++) {\n" + " }\n" + "}\n"); for (IInjectionPoint injectionPoint : new InjectionPoints(reference, new RandomWrapper(0), item -> true).getAllInjectionPoints()) { final Stmt toDonate = donor.getMainFunction().getBody().getStmt(0).clone(); assert toDonate instanceof ForStmt; final DonationContext dc = new DonationContext(toDonate, new HashMap<>(), new ArrayList<>(), donor.getMainFunction()); final Stmt donated = dlc.prepareStatementToDonate(injectionPoint, dc, TransformationProbabilities.DEFAULT_PROBABILITIES, new RandomWrapper(0), ShadingLanguageVersion.ESSL_100); assertTrue(new CheckPredicateVisitor() { @Override public void visitContinueStmt(ContinueStmt continueStmt) { predicateHolds(); } }.test(donated)); } }
@Override Stmt prepareStatementToDonate(IInjectionPoint injectionPoint, DonationContext donationContext, TransformationProbabilities probabilities, IRandom generator, ShadingLanguageVersion shadingLanguageVersion) { Map<String, String> substitution = new HashMap<>(); List<Stmt> donatedStmts = new ArrayList<>(); for (String name : asSortedList(donationContext.getFreeVariables().keySet())) { boolean dealtWithFreeVariable = false; Type type = donationContext.getFreeVariables().get(name); if (probabilities.substituteFreeVariable(generator)) { List<String> options = injectionPoint.scopeAtInjectionPoint().namesOfAllVariablesInScope() .stream() .filter(x -> injectionPoint.scopeAtInjectionPoint().lookupType(x).equals(type)) .collect(Collectors.toList()); options = options.stream().filter(x -> !donationContext.getDeclaredVariableNames().contains(x)).collect(Collectors.toList()); if (options.size() > 0) { substitution.put(name, options.get(generator.nextInt(options.size()))); dealtWithFreeVariable = true; } } if (!dealtWithFreeVariable) { String newName = "donor_replacement" + name; substitution.put(name, newName); final Type typeWithRestrictedQualifiers = dropQualifiersThatCannotBeUsedForLocalVariable(type); final Initializer initializer = getInitializer( injectionPoint, donationContext, typeWithRestrictedQualifiers, type.hasQualifier(TypeQualifier.CONST), generator, shadingLanguageVersion); final ImmutablePair<Type, ArrayInfo> baseTypeAndArrayInfo = Typer.getBaseTypeArrayInfo(typeWithRestrictedQualifiers); donatedStmts.add(new DeclarationStmt( new VariablesDeclaration(baseTypeAndArrayInfo.left, new VariableDeclInfo(newName, baseTypeAndArrayInfo.right, initializer)))); } } Stmt substitutedDonorFragment = donationContext.getDonorFragment(); new ApplySubstitution(substitution, substitutedDonorFragment); donatedStmts.add(substitutedDonorFragment); IfStmt donatedStmt = new IfStmt( new OpaqueExpressionGenerator(generator, generationParams, shadingLanguageVersion) .makeDeadCondition( new Fuzzer(new FuzzingContext(injectionPoint.scopeAtInjectionPoint()), shadingLanguageVersion, generator, generationParams)), new BlockStmt(donatedStmts, true), null); new RemoveImmediateCaseLabels(donatedStmt); if (!injectionPoint.inLoop()) { new RemoveImmediateContinueStatements(donatedStmt); } if (!(injectionPoint.inLoop() || injectionPoint.inSwitch())) { new RemoveImmediateBreakStatements(donatedStmt); } if (generationParams.getShaderKind() != ShaderKind.FRAGMENT) { new RemoveDiscardStatements(donatedStmt); } if (incompatibleReturnTypes(injectionPoint.getEnclosingFunction(), donationContext.getEnclosingFunction())) { new RemoveReturnStatements(donatedStmt); } return donatedStmt; }
DonateDeadCodeTransformation extends DonateCodeTransformation { @Override Stmt prepareStatementToDonate(IInjectionPoint injectionPoint, DonationContext donationContext, TransformationProbabilities probabilities, IRandom generator, ShadingLanguageVersion shadingLanguageVersion) { Map<String, String> substitution = new HashMap<>(); List<Stmt> donatedStmts = new ArrayList<>(); for (String name : asSortedList(donationContext.getFreeVariables().keySet())) { boolean dealtWithFreeVariable = false; Type type = donationContext.getFreeVariables().get(name); if (probabilities.substituteFreeVariable(generator)) { List<String> options = injectionPoint.scopeAtInjectionPoint().namesOfAllVariablesInScope() .stream() .filter(x -> injectionPoint.scopeAtInjectionPoint().lookupType(x).equals(type)) .collect(Collectors.toList()); options = options.stream().filter(x -> !donationContext.getDeclaredVariableNames().contains(x)).collect(Collectors.toList()); if (options.size() > 0) { substitution.put(name, options.get(generator.nextInt(options.size()))); dealtWithFreeVariable = true; } } if (!dealtWithFreeVariable) { String newName = "donor_replacement" + name; substitution.put(name, newName); final Type typeWithRestrictedQualifiers = dropQualifiersThatCannotBeUsedForLocalVariable(type); final Initializer initializer = getInitializer( injectionPoint, donationContext, typeWithRestrictedQualifiers, type.hasQualifier(TypeQualifier.CONST), generator, shadingLanguageVersion); final ImmutablePair<Type, ArrayInfo> baseTypeAndArrayInfo = Typer.getBaseTypeArrayInfo(typeWithRestrictedQualifiers); donatedStmts.add(new DeclarationStmt( new VariablesDeclaration(baseTypeAndArrayInfo.left, new VariableDeclInfo(newName, baseTypeAndArrayInfo.right, initializer)))); } } Stmt substitutedDonorFragment = donationContext.getDonorFragment(); new ApplySubstitution(substitution, substitutedDonorFragment); donatedStmts.add(substitutedDonorFragment); IfStmt donatedStmt = new IfStmt( new OpaqueExpressionGenerator(generator, generationParams, shadingLanguageVersion) .makeDeadCondition( new Fuzzer(new FuzzingContext(injectionPoint.scopeAtInjectionPoint()), shadingLanguageVersion, generator, generationParams)), new BlockStmt(donatedStmts, true), null); new RemoveImmediateCaseLabels(donatedStmt); if (!injectionPoint.inLoop()) { new RemoveImmediateContinueStatements(donatedStmt); } if (!(injectionPoint.inLoop() || injectionPoint.inSwitch())) { new RemoveImmediateBreakStatements(donatedStmt); } if (generationParams.getShaderKind() != ShaderKind.FRAGMENT) { new RemoveDiscardStatements(donatedStmt); } if (incompatibleReturnTypes(injectionPoint.getEnclosingFunction(), donationContext.getEnclosingFunction())) { new RemoveReturnStatements(donatedStmt); } return donatedStmt; } }
DonateDeadCodeTransformation extends DonateCodeTransformation { @Override Stmt prepareStatementToDonate(IInjectionPoint injectionPoint, DonationContext donationContext, TransformationProbabilities probabilities, IRandom generator, ShadingLanguageVersion shadingLanguageVersion) { Map<String, String> substitution = new HashMap<>(); List<Stmt> donatedStmts = new ArrayList<>(); for (String name : asSortedList(donationContext.getFreeVariables().keySet())) { boolean dealtWithFreeVariable = false; Type type = donationContext.getFreeVariables().get(name); if (probabilities.substituteFreeVariable(generator)) { List<String> options = injectionPoint.scopeAtInjectionPoint().namesOfAllVariablesInScope() .stream() .filter(x -> injectionPoint.scopeAtInjectionPoint().lookupType(x).equals(type)) .collect(Collectors.toList()); options = options.stream().filter(x -> !donationContext.getDeclaredVariableNames().contains(x)).collect(Collectors.toList()); if (options.size() > 0) { substitution.put(name, options.get(generator.nextInt(options.size()))); dealtWithFreeVariable = true; } } if (!dealtWithFreeVariable) { String newName = "donor_replacement" + name; substitution.put(name, newName); final Type typeWithRestrictedQualifiers = dropQualifiersThatCannotBeUsedForLocalVariable(type); final Initializer initializer = getInitializer( injectionPoint, donationContext, typeWithRestrictedQualifiers, type.hasQualifier(TypeQualifier.CONST), generator, shadingLanguageVersion); final ImmutablePair<Type, ArrayInfo> baseTypeAndArrayInfo = Typer.getBaseTypeArrayInfo(typeWithRestrictedQualifiers); donatedStmts.add(new DeclarationStmt( new VariablesDeclaration(baseTypeAndArrayInfo.left, new VariableDeclInfo(newName, baseTypeAndArrayInfo.right, initializer)))); } } Stmt substitutedDonorFragment = donationContext.getDonorFragment(); new ApplySubstitution(substitution, substitutedDonorFragment); donatedStmts.add(substitutedDonorFragment); IfStmt donatedStmt = new IfStmt( new OpaqueExpressionGenerator(generator, generationParams, shadingLanguageVersion) .makeDeadCondition( new Fuzzer(new FuzzingContext(injectionPoint.scopeAtInjectionPoint()), shadingLanguageVersion, generator, generationParams)), new BlockStmt(donatedStmts, true), null); new RemoveImmediateCaseLabels(donatedStmt); if (!injectionPoint.inLoop()) { new RemoveImmediateContinueStatements(donatedStmt); } if (!(injectionPoint.inLoop() || injectionPoint.inSwitch())) { new RemoveImmediateBreakStatements(donatedStmt); } if (generationParams.getShaderKind() != ShaderKind.FRAGMENT) { new RemoveDiscardStatements(donatedStmt); } if (incompatibleReturnTypes(injectionPoint.getEnclosingFunction(), donationContext.getEnclosingFunction())) { new RemoveReturnStatements(donatedStmt); } return donatedStmt; } DonateDeadCodeTransformation(Function<IRandom, Boolean> probabilityOfDonation,
                                      File donorsDirectory,
                                      GenerationParams generationParams); }
DonateDeadCodeTransformation extends DonateCodeTransformation { @Override Stmt prepareStatementToDonate(IInjectionPoint injectionPoint, DonationContext donationContext, TransformationProbabilities probabilities, IRandom generator, ShadingLanguageVersion shadingLanguageVersion) { Map<String, String> substitution = new HashMap<>(); List<Stmt> donatedStmts = new ArrayList<>(); for (String name : asSortedList(donationContext.getFreeVariables().keySet())) { boolean dealtWithFreeVariable = false; Type type = donationContext.getFreeVariables().get(name); if (probabilities.substituteFreeVariable(generator)) { List<String> options = injectionPoint.scopeAtInjectionPoint().namesOfAllVariablesInScope() .stream() .filter(x -> injectionPoint.scopeAtInjectionPoint().lookupType(x).equals(type)) .collect(Collectors.toList()); options = options.stream().filter(x -> !donationContext.getDeclaredVariableNames().contains(x)).collect(Collectors.toList()); if (options.size() > 0) { substitution.put(name, options.get(generator.nextInt(options.size()))); dealtWithFreeVariable = true; } } if (!dealtWithFreeVariable) { String newName = "donor_replacement" + name; substitution.put(name, newName); final Type typeWithRestrictedQualifiers = dropQualifiersThatCannotBeUsedForLocalVariable(type); final Initializer initializer = getInitializer( injectionPoint, donationContext, typeWithRestrictedQualifiers, type.hasQualifier(TypeQualifier.CONST), generator, shadingLanguageVersion); final ImmutablePair<Type, ArrayInfo> baseTypeAndArrayInfo = Typer.getBaseTypeArrayInfo(typeWithRestrictedQualifiers); donatedStmts.add(new DeclarationStmt( new VariablesDeclaration(baseTypeAndArrayInfo.left, new VariableDeclInfo(newName, baseTypeAndArrayInfo.right, initializer)))); } } Stmt substitutedDonorFragment = donationContext.getDonorFragment(); new ApplySubstitution(substitution, substitutedDonorFragment); donatedStmts.add(substitutedDonorFragment); IfStmt donatedStmt = new IfStmt( new OpaqueExpressionGenerator(generator, generationParams, shadingLanguageVersion) .makeDeadCondition( new Fuzzer(new FuzzingContext(injectionPoint.scopeAtInjectionPoint()), shadingLanguageVersion, generator, generationParams)), new BlockStmt(donatedStmts, true), null); new RemoveImmediateCaseLabels(donatedStmt); if (!injectionPoint.inLoop()) { new RemoveImmediateContinueStatements(donatedStmt); } if (!(injectionPoint.inLoop() || injectionPoint.inSwitch())) { new RemoveImmediateBreakStatements(donatedStmt); } if (generationParams.getShaderKind() != ShaderKind.FRAGMENT) { new RemoveDiscardStatements(donatedStmt); } if (incompatibleReturnTypes(injectionPoint.getEnclosingFunction(), donationContext.getEnclosingFunction())) { new RemoveReturnStatements(donatedStmt); } return donatedStmt; } DonateDeadCodeTransformation(Function<IRandom, Boolean> probabilityOfDonation,
                                      File donorsDirectory,
                                      GenerationParams generationParams); @Override String getName(); }
DonateDeadCodeTransformation extends DonateCodeTransformation { @Override Stmt prepareStatementToDonate(IInjectionPoint injectionPoint, DonationContext donationContext, TransformationProbabilities probabilities, IRandom generator, ShadingLanguageVersion shadingLanguageVersion) { Map<String, String> substitution = new HashMap<>(); List<Stmt> donatedStmts = new ArrayList<>(); for (String name : asSortedList(donationContext.getFreeVariables().keySet())) { boolean dealtWithFreeVariable = false; Type type = donationContext.getFreeVariables().get(name); if (probabilities.substituteFreeVariable(generator)) { List<String> options = injectionPoint.scopeAtInjectionPoint().namesOfAllVariablesInScope() .stream() .filter(x -> injectionPoint.scopeAtInjectionPoint().lookupType(x).equals(type)) .collect(Collectors.toList()); options = options.stream().filter(x -> !donationContext.getDeclaredVariableNames().contains(x)).collect(Collectors.toList()); if (options.size() > 0) { substitution.put(name, options.get(generator.nextInt(options.size()))); dealtWithFreeVariable = true; } } if (!dealtWithFreeVariable) { String newName = "donor_replacement" + name; substitution.put(name, newName); final Type typeWithRestrictedQualifiers = dropQualifiersThatCannotBeUsedForLocalVariable(type); final Initializer initializer = getInitializer( injectionPoint, donationContext, typeWithRestrictedQualifiers, type.hasQualifier(TypeQualifier.CONST), generator, shadingLanguageVersion); final ImmutablePair<Type, ArrayInfo> baseTypeAndArrayInfo = Typer.getBaseTypeArrayInfo(typeWithRestrictedQualifiers); donatedStmts.add(new DeclarationStmt( new VariablesDeclaration(baseTypeAndArrayInfo.left, new VariableDeclInfo(newName, baseTypeAndArrayInfo.right, initializer)))); } } Stmt substitutedDonorFragment = donationContext.getDonorFragment(); new ApplySubstitution(substitution, substitutedDonorFragment); donatedStmts.add(substitutedDonorFragment); IfStmt donatedStmt = new IfStmt( new OpaqueExpressionGenerator(generator, generationParams, shadingLanguageVersion) .makeDeadCondition( new Fuzzer(new FuzzingContext(injectionPoint.scopeAtInjectionPoint()), shadingLanguageVersion, generator, generationParams)), new BlockStmt(donatedStmts, true), null); new RemoveImmediateCaseLabels(donatedStmt); if (!injectionPoint.inLoop()) { new RemoveImmediateContinueStatements(donatedStmt); } if (!(injectionPoint.inLoop() || injectionPoint.inSwitch())) { new RemoveImmediateBreakStatements(donatedStmt); } if (generationParams.getShaderKind() != ShaderKind.FRAGMENT) { new RemoveDiscardStatements(donatedStmt); } if (incompatibleReturnTypes(injectionPoint.getEnclosingFunction(), donationContext.getEnclosingFunction())) { new RemoveReturnStatements(donatedStmt); } return donatedStmt; } DonateDeadCodeTransformation(Function<IRandom, Boolean> probabilityOfDonation,
                                      File donorsDirectory,
                                      GenerationParams generationParams); @Override String getName(); static final String NAME; }