RemoveStructFieldReductionOpportunities extends ScopeTrackingVisitor { static List<RemoveStructFieldReductionOpportunity> findOpportunities( ShaderJob shaderJob, ReducerContext context) { return shaderJob.getShaders() .stream() .map(item -> findOpportunitiesForShader(item)) .reduce(Arrays.asList(), ListConcat::concatenate); } private  RemoveStructFieldReductionOpportunities(TranslationUnit translationUnit); @Override void visitDeclarationStmt(DeclarationStmt declarationStmt);  }
@Test public void nestedStruct() throws Exception { final String program = "struct _GLF_struct_15 {\n" + " int _f0;\n" + " float x1;\n" + " int _f1;\n" + "};\n" + "struct _GLF_struct_16 {\n" + " _GLF_struct_15 _f0;\n" + "};\n" + "void f(float x)\n" + "{\n" + " _GLF_struct_16 _GLF_struct_replacement_17 = _GLF_struct_16(_GLF_struct_15(1, " + "x + 1.0, mat3(1.0)));\n" + "}\n"; TranslationUnit tu = ParseHelper.parse(program); assertEquals(2, RemoveStructFieldReductionOpportunities .findOpportunities(MakeShaderJobFromFragmentShader.make(tu), new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())).size()); }
@Test public void singleField() throws Exception { final String program = "struct _GLF_struct_15 {\n" + " int _f0;\n" + "};\n" + "struct _GLF_struct_16 {\n" + " _GLF_struct_15 _f0;\n" + "};\n" + "void f(float x)\n" + "{\n" + " _GLF_struct_16 _GLF_struct_replacement_17 = _GLF_struct_16(_GLF_struct_15(1));\n" + "}\n"; TranslationUnit tu = ParseHelper.parse(program); assertEquals(0, RemoveStructFieldReductionOpportunities .findOpportunities(MakeShaderJobFromFragmentShader.make(tu), new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())).size()); }
@Test public void testNonLocalInitialization() throws Exception { final String shader = "struct _GLF_struct_28 {\n" + " mat4 _f0;\n" + " vec4 a;\n" + "};\n" + "vec4 f(_GLF_struct_28 _GLF_struct_replacement_29)\n" + "{\n" + " return _GLF_struct_28(mat4(1.0), vec4(1.0)).a;\n" + "}\n" + "void main()\n" + "{\n" + " _GLF_struct_28 _GLF_struct_replacement_29;\n" + "}\n"; final String expected = "struct _GLF_struct_28 {\n" + " vec4 a;\n" + "};\n" + "vec4 f(_GLF_struct_28 _GLF_struct_replacement_29)\n" + "{\n" + " return _GLF_struct_28(vec4(1.0)).a;\n" + "}\n" + "void main()\n" + "{\n" + " _GLF_struct_28 _GLF_struct_replacement_29;\n" + "}\n"; TranslationUnit tu = ParseHelper.parse(shader); List<RemoveStructFieldReductionOpportunity> ops = RemoveStructFieldReductionOpportunities .findOpportunities(MakeShaderJobFromFragmentShader.make(tu), new ReducerContext(true, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals(1, ops.size()); ops.get(0).applyReduction(); assertEquals(PrettyPrinterVisitor.prettyPrintAsString(tu), PrettyPrinterVisitor.prettyPrintAsString(ParseHelper.parse(expected))); }
@Test public void twoFields() throws Exception { final String program = "struct _GLF_struct_15 {\n" + " int _f0;\n" + " int _f1;\n" + "};\n" + "struct _GLF_struct_16 {\n" + " _GLF_struct_15 _f0;\n" + "};\n" + "void f(float x)\n" + "{\n" + " _GLF_struct_16 _GLF_struct_replacement_17 = " + "_GLF_struct_16(_GLF_struct_15(1, 2));\n" + "}\n"; final String expected = "struct _GLF_struct_15 {\n" + " int _f1;\n" + "};\n" + "struct _GLF_struct_16 {\n" + " _GLF_struct_15 _f0;\n" + "};\n" + "void f(float x)\n" + "{\n" + " _GLF_struct_16 _GLF_struct_replacement_17 = _GLF_struct_16(_GLF_struct_15(2));\n" + "}\n"; TranslationUnit tu = ParseHelper.parse(program); final List<RemoveStructFieldReductionOpportunity> ops = RemoveStructFieldReductionOpportunities .findOpportunities(MakeShaderJobFromFragmentShader.make(tu), new ReducerContext(false, ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator())); assertEquals(2, ops .size()); ops.stream().filter(item -> item.getFieldToRemove().equals("_f0")) .findAny().get().applyReduction(); assertEquals(PrettyPrinterVisitor.prettyPrintAsString(ParseHelper.parse(expected)), PrettyPrinterVisitor.prettyPrintAsString(tu)); final RemoveStructFieldReductionOpportunity op = ops.stream() .filter(item -> item.getFieldToRemove().equals("_f1")) .findAny().get(); assertFalse(op.preconditionHolds()); op.applyReduction(); assertEquals(PrettyPrinterVisitor.prettyPrintAsString(ParseHelper.parse(expected)), PrettyPrinterVisitor.prettyPrintAsString(tu)); }