Skip to content

Commit

Permalink
Various improvements to the reducer (#37)
Browse files Browse the repository at this point in the history
* Added facility for the reducer to inline uniform values into a shader.

* Adjusted tests according to changes in how uniform pruning works.

* Fixed bug in constant folding of cos.

* Folding of -0 and +0 to 0 in reducer.

* Constant folder now removes redundant parentheses.

* Added reduction of vector constructor lookups, e.g. vec4(1.0, 2.0, 3.0, 4.0).y -> 3.0.
  • Loading branch information
afd authored and hevrard committed Oct 10, 2018
1 parent f0fcbb5 commit 37e756c
Show file tree
Hide file tree
Showing 15 changed files with 588 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,17 @@ public List<TranslationUnit> getShaders() {
}
return result;
}

@Override
public GlslShaderJob clone() {
return new GlslShaderJob(
hasVertexShader()
? Optional.of(getVertexShader().cloneAndPatchUp())
: Optional.empty(),
hasFragmentShader()
? Optional.of(getFragmentShader().cloneAndPatchUp())
: Optional.empty(),
new UniformsInfo(getUniformsInfo().toString()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.graphicsfuzz.common.ast.TranslationUnit;
import com.graphicsfuzz.common.util.UniformsInfo;
import java.util.List;
import java.util.Optional;

public interface ShaderJob {

Expand All @@ -24,4 +25,6 @@ public interface ShaderJob {

List<TranslationUnit> getShaders();

ShaderJob clone();

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,12 @@
import com.graphicsfuzz.common.ast.expr.FloatConstantExpr;
import com.graphicsfuzz.common.ast.expr.IntConstantExpr;
import com.graphicsfuzz.common.ast.expr.TypeConstructorExpr;
import com.graphicsfuzz.common.ast.expr.UIntConstantExpr;
import com.graphicsfuzz.common.ast.type.ArrayType;
import com.graphicsfuzz.common.ast.type.BasicType;
import com.graphicsfuzz.common.ast.type.QualifiedType;
import com.graphicsfuzz.common.ast.type.TypeQualifier;
import com.graphicsfuzz.common.transformreduce.ShaderJob;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -130,26 +129,32 @@ private static Initializer makeInitializer(BasicType baseType,
assert arrayInfo.getSize() * baseType.getNumElements() == args.size();
List<Expr> argExprs = new ArrayList<>();
for (int index = 0; index < arrayInfo.getSize(); index++) {
argExprs.add(getTypeConstructorExpr(baseType,
argExprs.add(getBasicTypeLiteralExpr(baseType,
args.subList(index * baseType.getNumElements(),
(index + 1) * baseType.getNumElements())));
}
return new ScalarInitializer(new ArrayConstructorExpr(
new ArrayType(baseType.getWithoutQualifiers(), arrayInfo.clone()),
argExprs));
}
return new ScalarInitializer(getTypeConstructorExpr(baseType, args));
return new ScalarInitializer(getBasicTypeLiteralExpr(baseType, args));
}

private static TypeConstructorExpr getTypeConstructorExpr(BasicType baseType, List<Number> args) {
public static Expr getBasicTypeLiteralExpr(BasicType baseType, List<Number> args) {
List<Expr> argExprs;
if (baseType.getElementType() == BasicType.FLOAT) {
argExprs = args.stream().map(item -> new FloatConstantExpr(item.toString()))
.collect(Collectors.toList());
} else if (baseType.getElementType() == BasicType.UINT) {
argExprs = args.stream().map(item -> new UIntConstantExpr(item.toString() + "u"))
.collect(Collectors.toList());
} else {
argExprs = args.stream().map(item -> new IntConstantExpr(item.toString()))
.collect(Collectors.toList());
}
if (argExprs.size() == 1) {
return argExprs.get(0);
}
return new TypeConstructorExpr(baseType.toString(),
argExprs);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void testPruneOne() throws Exception {
+ "}\n";

final String expectedProgram = "uniform float a;"
+ "float prune_b = float(23.0);"
+ "float prune_b = 23.0;"
+ "uniform int c;"
+ "void main() {"
+ "}";
Expand Down Expand Up @@ -151,12 +151,12 @@ public void testPruneAll() throws Exception {
+ " }\n"
+ "}\n";

final String expectedProgram = "int liveI[10] = int[10](int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8), int(9), int(10));"
final String expectedProgram = "int liveI[10] = int[10](1, 2, 3, 4, 5, 6, 7, 8, 9, 10);"
+ "vec3 deadF[3] = vec3[3](vec3(1.0, 2.0, 3.0), vec3(4.0, 5.0, 6.0), vec3(7.0, 8.0, 9.0));"
+ "vec2 deadH = vec2(258.0, 259.0);"
+ "vec2 liveG = vec2(256.0, 257.0);"
+ "uint liveA = uint(25);"
+ "uint liveB = uint(26);"
+ "uint liveA = 25u;"
+ "uint liveB = 26u;"
+ "bvec3 liveC[3] = bvec3[3](bvec3(0, 1, 0), bvec3(1, 0, 1), bvec3(0, 1, 0));"
+ "void main() {"
+ "}";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,16 @@ public static void assertEqualAsts(TranslationUnit first, TranslationUnit second
PrettyPrinterVisitor.prettyPrintAsString(second));
}

public static boolean isEqualAsts(String first, String second) throws IOException,
ParseTimeoutException {
return PrettyPrinterVisitor.prettyPrintAsString(ParseHelper.parse(first, false))
.equals(
PrettyPrinterVisitor.prettyPrintAsString(ParseHelper.parse(second, false)));
}

public static boolean isEqualAsts(String first, TranslationUnit second) throws IOException,
ParseTimeoutException {
return isEqualAsts(first, PrettyPrinterVisitor.prettyPrintAsString(second));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ private void resetPlans() {
IReductionOpportunityFinder.declarationFinder(),
IReductionOpportunityFinder.unusedParamFinder(),
IReductionOpportunityFinder.foldConstantFinder(),
IReductionOpportunityFinder.inlineUniformFinder(),
}) {
plans.add(new SimplePlan(reductionOpportunityContext,
verbose,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public void update(boolean interesting) {
@Override
public ShaderJob applyReduction(ShaderJob shaderJob)
throws NoMoreToReduceException {
final ShaderJob workingShaderJob = getWorkingShaderJob(shaderJob);
final ShaderJob workingShaderJob = shaderJob.clone();
int localPercentageToReduce = percentageToReduce;
while (true) {
if (attemptToTransform(workingShaderJob, localPercentageToReduce)) {
Expand Down Expand Up @@ -215,15 +215,4 @@ public void replenish() {
percentageToReduce = Math.max(percentageToReduce, 1);
}

private ShaderJob getWorkingShaderJob(ShaderJob shaderJob) {
return new GlslShaderJob(
shaderJob.hasVertexShader()
? Optional.of(shaderJob.getVertexShader().cloneAndPatchUp())
: Optional.empty(),
shaderJob.hasFragmentShader()
? Optional.of(shaderJob.getFragmentShader().cloneAndPatchUp())
: Optional.empty(),
new UniformsInfo(shaderJob.getUniformsInfo().toString()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,7 @@ public CheckValidReductionOpportunityDecorator(IReductionOpportunity delegate,

@Override
public void applyReduction() {
final ShaderJob before = new GlslShaderJob(
shaderJob.hasVertexShader()
? Optional.of(shaderJob.getVertexShader().cloneAndPatchUp())
: Optional.empty(),
shaderJob.hasFragmentShader()
? Optional.of(shaderJob.getFragmentShader().cloneAndPatchUp())
: Optional.empty(),
new UniformsInfo(shaderJob.getUniformsInfo().toString()));
final ShaderJob before = shaderJob.clone();
delegate.applyReduction();
final String prefix = "temp_to_validate";
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,26 @@
import com.graphicsfuzz.common.ast.IAstNode;
import com.graphicsfuzz.common.ast.TranslationUnit;
import com.graphicsfuzz.common.ast.expr.BinaryExpr;
import com.graphicsfuzz.common.ast.expr.ConstantExpr;
import com.graphicsfuzz.common.ast.expr.Expr;
import com.graphicsfuzz.common.ast.expr.FloatConstantExpr;
import com.graphicsfuzz.common.ast.expr.FunctionCallExpr;
import com.graphicsfuzz.common.ast.expr.IntConstantExpr;
import com.graphicsfuzz.common.ast.expr.MemberLookupExpr;
import com.graphicsfuzz.common.ast.expr.ParenExpr;
import com.graphicsfuzz.common.ast.expr.TypeConstructorExpr;
import com.graphicsfuzz.common.ast.expr.UnOp;
import com.graphicsfuzz.common.ast.expr.UnaryExpr;
import com.graphicsfuzz.common.ast.expr.VariableIdentifierExpr;
import com.graphicsfuzz.common.ast.type.BasicType;
import com.graphicsfuzz.common.ast.type.Type;
import com.graphicsfuzz.common.transformreduce.ShaderJob;
import com.graphicsfuzz.common.util.ListConcat;
import com.graphicsfuzz.common.util.SideEffectChecker;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import jdk.nashorn.internal.ir.FunctionCall;

public final class FoldConstantReductionOpportunities extends SimplifyExprReductionOpportunities {

Expand All @@ -39,8 +45,8 @@ void identifyReductionOpportunitiesForChild(IAstNode parent, Expr child) {
return;
case "cos":
assert maybeFce.get().getNumArgs() == 1;
if (isOneFloat(maybeFce.get().getArg(0))) {
addReplaceWithZero(parent, child);
if (isZeroFloat(maybeFce.get().getArg(0))) {
addReplaceWithOne(parent, child);
}
return;
default:
Expand Down Expand Up @@ -84,6 +90,109 @@ void identifyReductionOpportunitiesForChild(IAstNode parent, Expr child) {
return;
}
}

Optional<UnaryExpr> maybeUe = asUnaryExpr(child);
if (maybeUe.isPresent()) {
final Expr arg = maybeUe.get().getExpr();
switch (maybeUe.get().getOp()) {
case PLUS:
findFoldPlusMinusZeroOpportunities(parent, child, arg);
return;
case MINUS:
findFoldPlusMinusZeroOpportunities(parent, child, arg);
return;
default:
return;
}
}

Optional<ParenExpr> maybeParen = asParenExpr(child);
if (maybeParen.isPresent()) {
findRemoveParenOpportunities(parent, child, maybeParen.get().getExpr());
}

Optional<MemberLookupExpr> maybeMemberLookup = asMemberLookupExpr(child);
if (maybeMemberLookup.isPresent()) {
findReplaceTypeConstructorWithElementOpportunities(parent, child,
maybeMemberLookup.get());
}

}

private void findReplaceTypeConstructorWithElementOpportunities(
IAstNode parent,
Expr child,
MemberLookupExpr memberLookupExpr) {
if (!(memberLookupExpr.getStructure() instanceof TypeConstructorExpr)) {
return;
}
final TypeConstructorExpr tce = (TypeConstructorExpr) memberLookupExpr.getStructure();
if (!Arrays.asList("x", "y", "z", "w", "r", "g", "b", "a", "s", "t", "p", "q")
.contains(memberLookupExpr.getMember())) {
return; // We could handle swizzles, but for now we do not.
}
final Type structureType = typer.lookupType(memberLookupExpr.getStructure());
if (structureType == null || !(structureType instanceof BasicType)) {
return;
}
final BasicType basicType = (BasicType) structureType;
if (!BasicType.allVectorTypes().contains(basicType)) {
return;
}
if (basicType.getNumElements() != tce.getNumArgs()) {
// We could handle cases such as vec2(0.0).x resolving to 0.0; but for now we do not.
return;
}
if (!SideEffectChecker.isSideEffectFree(tce, context.getShadingLanguageVersion())) {
// We mustn't eliminate side-effects from elements of the vector that we are not popping out.
return;
}
int index;
switch (memberLookupExpr.getMember()) {
case "x":
case "r":
case "s":
index = 0;
break;
case "y":
case "g":
case "t":
index = 1;
break;
case "z":
case "b":
case "p":
index = 2;
break;
case "w":
case "a":
case "q":
index = 3;
break;
default:
throw new RuntimeException("Should be unreachable.");
}
addReplaceWithExpr(parent, child, new ParenExpr(tce.getArg(index)));
}

private void findRemoveParenOpportunities(IAstNode parent, Expr child, Expr expr) {
if (expr instanceof ConstantExpr
|| expr instanceof VariableIdentifierExpr
|| expr instanceof ParenExpr
|| expr instanceof FunctionCallExpr
|| expr instanceof MemberLookupExpr
|| expr instanceof TypeConstructorExpr) {
addReplaceWithExpr(parent, child, expr);
}
}

private void findFoldPlusMinusZeroOpportunities(IAstNode parent, Expr child, Expr arg) {
if (isZeroFloat(arg)) {
addReplaceWithExpr(parent, child, makeZeroFloat());
}
if (isZeroInt(arg)) {
addReplaceWithExpr(parent, child, makeZeroInt());
}
}

private void findFoldAddZeroOpportunities(IAstNode parent,
Expand Down Expand Up @@ -218,6 +327,24 @@ private Optional<BinaryExpr> asBinaryExpr(Expr expr) {
: Optional.empty();
}

private Optional<UnaryExpr> asUnaryExpr(Expr expr) {
return expr instanceof UnaryExpr
? Optional.of((UnaryExpr) expr)
: Optional.empty();
}

private Optional<ParenExpr> asParenExpr(Expr expr) {
return expr instanceof ParenExpr
? Optional.of((ParenExpr) expr)
: Optional.empty();
}

private Optional<MemberLookupExpr> asMemberLookupExpr(Expr expr) {
return expr instanceof MemberLookupExpr
? Optional.of((MemberLookupExpr) expr)
: Optional.empty();
}

private boolean isZeroFloat(Expr expr) {
return isFloatValue(expr, Arrays.asList("0.0", "0."));
}
Expand Down Expand Up @@ -291,14 +418,37 @@ private boolean isIdentityMatrix(Expr expr) {
return true;
}

private boolean isZeroInt(Expr expr) {
return isIntValue(expr, Arrays.asList("0"));
}

private boolean isIntValue(Expr expr, List<String> values) {
if (!(expr instanceof IntConstantExpr)) {
return false;
}
return values.contains(((IntConstantExpr) expr).getValue());
}

private Expr makeZeroFloat() {
return new FloatConstantExpr("0.0");
}

private Expr makeOneFloat() {
return new FloatConstantExpr("1.0");
}

private Expr makeZeroInt() {
return new IntConstantExpr("0");
}

private void addReplaceWithZero(IAstNode parent, Expr child) {
addReplaceWithExpr(parent, child, makeZeroFloat());
}

private void addReplaceWithOne(IAstNode parent, Expr child) {
addReplaceWithExpr(parent, child, makeOneFloat());
}

private void addReplaceWithExpr(IAstNode parent, Expr child, Expr newChild) {
addOpportunity(new SimplifyExprReductionOpportunity(
parent,
Expand Down
Loading

0 comments on commit 37e756c

Please sign in to comment.