Skip to content

Commit 045e96f

Browse files
authored
Place limit on size of functions inlined during reduction. (#95)
* Removed unused file. * Added a limit to the size of functions that will be inlined during reduction, to limit size explosion.
1 parent 486298e commit 045e96f

File tree

5 files changed

+104
-64
lines changed

5 files changed

+104
-64
lines changed

ast/src/main/java/com/graphicsfuzz/common/ast/inliner/Inliner.java

+10-6
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.graphicsfuzz.common.glslversion.ShadingLanguageVersion;
4040
import com.graphicsfuzz.common.typing.Typer;
4141
import com.graphicsfuzz.common.util.IdGenerator;
42+
import com.graphicsfuzz.common.util.StatsVisitor;
4243
import java.util.ArrayList;
4344
import java.util.List;
4445
import java.util.Optional;
@@ -58,9 +59,11 @@ public static void inline(FunctionCallExpr functionCallExpr, TranslationUnit tu,
5859
new Inliner(functionCallExpr, tu, shadingLanguageVersion).doInline(idGenerator);
5960
}
6061

61-
public static boolean canInline(FunctionCallExpr functionCallExpr, TranslationUnit tu,
62-
ShadingLanguageVersion shadingLanguageVersion) {
63-
return new Inliner(functionCallExpr, tu, shadingLanguageVersion).canInline();
62+
public static boolean canInline(FunctionCallExpr functionCallExpr,
63+
TranslationUnit tu,
64+
ShadingLanguageVersion shadingLanguageVersion,
65+
int nodeLimit) {
66+
return new Inliner(functionCallExpr, tu, shadingLanguageVersion).canInline(nodeLimit);
6467
}
6568

6669
private Inliner(FunctionCallExpr call, TranslationUnit tu,
@@ -72,10 +75,11 @@ private Inliner(FunctionCallExpr call, TranslationUnit tu,
7275
this.parentMap = IParentMap.createParentMap(tu);
7376
}
7477

75-
private boolean canInline() {
78+
private boolean canInline(int nodeLimit) {
7679
try {
77-
getCloneWithReturnsRemoved(findMatchingFunctionForCall());
78-
return true;
80+
final FunctionDefinition inlinable =
81+
getCloneWithReturnsRemoved(findMatchingFunctionForCall());
82+
return nodeLimit == 0 || new StatsVisitor(inlinable).getNumNodes() <= nodeLimit;
7983
} catch (CannotInlineCallException exception) {
8084
return false;
8185
}

generator/src/main/java/com/graphicsfuzz/generator/transformation/mutator/BreakIntLiterals.java

-56
This file was deleted.

reducer/src/main/java/com/graphicsfuzz/reducer/reductionopportunities/InlineFunctionReductionOpportunities.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
public class InlineFunctionReductionOpportunities extends StandardVisitor {
3131

32+
private static final int INLINE_NODE_LIMIT = 100; // Only inline relatively small functions
33+
3234
private final List<InlineFunctionReductionOpportunity> opportunities;
3335
private final TranslationUnit tu;
3436
private final ReducerContext context;
@@ -62,7 +64,8 @@ private InlineFunctionReductionOpportunities(TranslationUnit tu,
6264
public void visitFunctionCallExpr(FunctionCallExpr functionCallExpr) {
6365
super.visitFunctionCallExpr(functionCallExpr);
6466
if (allowedToInline(functionCallExpr)
65-
&& Inliner.canInline(functionCallExpr, tu, context.getShadingLanguageVersion())) {
67+
&& Inliner.canInline(
68+
functionCallExpr, tu, context.getShadingLanguageVersion(), INLINE_NODE_LIMIT)) {
6669
opportunities.add(new InlineFunctionReductionOpportunity(
6770
functionCallExpr,
6871
tu,

reducer/src/main/java/com/graphicsfuzz/reducer/reductionopportunities/InlineFunctionReductionOpportunity.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ void applyReductionImpl() {
5353

5454
@Override
5555
public boolean preconditionHolds() {
56-
return Inliner.canInline(functionCallExpr, tu, shadingLanguageVersion);
56+
// We use a node limit of 0 (to say "no limit") because we already checked the limit on
57+
// creation of this opportunity, and we're OK with the possibility that the limit might now
58+
// be exceeded due to other transformations.
59+
return Inliner.canInline(functionCallExpr, tu, shadingLanguageVersion, 0);
5760
}
5861

5962
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright 2018 The GraphicsFuzz Project Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.graphicsfuzz.reducer.reductionopportunities;
18+
19+
import com.graphicsfuzz.common.ast.TranslationUnit;
20+
import com.graphicsfuzz.common.glslversion.ShadingLanguageVersion;
21+
import com.graphicsfuzz.common.transformreduce.ShaderJob;
22+
import com.graphicsfuzz.common.util.CompareAsts;
23+
import com.graphicsfuzz.common.util.IdGenerator;
24+
import com.graphicsfuzz.common.util.ParseHelper;
25+
import com.graphicsfuzz.common.util.RandomWrapper;
26+
import java.util.List;
27+
import org.junit.Test;
28+
29+
import static org.junit.Assert.*;
30+
31+
public class InlineFunctionReductionOpportunitiesTest {
32+
33+
@Test
34+
public void testBasicInline() throws Exception {
35+
36+
final String program = "int inlineme(int x) { int y = 2; return y + x; }" +
37+
"void main() { int z = inlineme(5); }";
38+
39+
final String expected = "int inlineme(int x) { int y = 2; return y + x; }" +
40+
"void main() { " +
41+
" int inlineme_inline_return_value_0;" +
42+
" {" +
43+
" int x = 5;" +
44+
" int y = 2;" +
45+
" inlineme_inline_return_value_0 = y + x;" +
46+
" }" +
47+
" int z = inlineme_inline_return_value_0;" +
48+
"}";
49+
50+
final TranslationUnit tu = ParseHelper.parse(program);
51+
final ShaderJob shaderJob = MakeShaderJobFromFragmentShader.make(tu);
52+
53+
final List<InlineFunctionReductionOpportunity> ops =
54+
InlineFunctionReductionOpportunities.findOpportunities(shaderJob,
55+
new ReducerContext(true,
56+
ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator(), false));
57+
58+
assertEquals(1, ops.size());
59+
ops.get(0).applyReduction();
60+
CompareAsts.assertEqualAsts(expected, tu);
61+
}
62+
63+
@Test
64+
public void testTooLargeToInline() throws Exception {
65+
66+
final StringBuilder program = new StringBuilder();
67+
program.append("int donotinlineme(int x) { int y = 2;");
68+
for (int i = 0; i < 100; i++) {
69+
program.append(" y = y + x;");
70+
}
71+
program.append("}");
72+
program.append("void main() { int z = donotinlineme(5); }");
73+
74+
final TranslationUnit tu = ParseHelper.parse(program.toString());
75+
final ShaderJob shaderJob = MakeShaderJobFromFragmentShader.make(tu);
76+
77+
final List<InlineFunctionReductionOpportunity> ops =
78+
InlineFunctionReductionOpportunities.findOpportunities(shaderJob,
79+
new ReducerContext(true,
80+
ShadingLanguageVersion.ESSL_100, new RandomWrapper(0), new IdGenerator(), false));
81+
82+
assertEquals(0, ops.size());
83+
}
84+
85+
86+
}

0 commit comments

Comments
 (0)