Disable optimizations for shaders with conditional discard in D3D9, and
only use expanded short-circuiting conditionals for expressions with
potential side-effects.
Conservatively assume aggreate and selection operators have side effects for now.
BUG=
ANGLEBUG=486
R=geofflang@chromium.org, kbr@chromium.org, nicolas@transgaming.com, shannonwoods@chromium.org
Review URL: https://codereview.appspot.com/14441075
Conflicts:
src/common/version.h
src/compiler/translator.vcxproj
src/compiler/translator.vcxproj.filters
src/compiler/translator/OutputHLSL.cpp
src/libGLESv2/ProgramBinary.cpp
src/libGLESv2/Shader.cpp
src/libGLESv2/Shader.h
Change-Id: Iaf9f10b5de7b33c927ef032f3c4fe9d5095f64dd
diff --git a/src/compiler/translator/intermediate.h b/src/compiler/translator/intermediate.h
index c286149..f252298 100644
--- a/src/compiler/translator/intermediate.h
+++ b/src/compiler/translator/intermediate.h
@@ -258,6 +258,8 @@
TIntermTyped(const TType& t) : type(t) { }
virtual TIntermTyped* getAsTyped() { return this; }
+ virtual bool hasSideEffects() const = 0;
+
void setType(const TType& t) { type = t; }
const TType& getType() const { return type; }
TType* getTypePointer() { return &type; }
@@ -359,6 +361,8 @@
TIntermSymbol(int i, const TString& sym, const TType& t) :
TIntermTyped(t), id(i) { symbol = sym; originalSymbol = sym; }
+ virtual bool hasSideEffects() const { return false; }
+
int getId() const { return id; }
const TString& getSymbol() const { return symbol; }
@@ -380,6 +384,8 @@
public:
TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
+ virtual bool hasSideEffects() const { return false; }
+
ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
int getIConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
@@ -404,7 +410,7 @@
TOperator getOp() const { return op; }
void setOp(TOperator o) { op = o; }
- bool modifiesState() const;
+ virtual bool hasSideEffects() const;
bool isConstructor() const;
protected:
@@ -423,6 +429,8 @@
virtual TIntermBinary* getAsBinaryNode() { return this; }
virtual void traverse(TIntermTraverser*);
+ virtual bool hasSideEffects() const { return (TIntermOperator::hasSideEffects() || left->hasSideEffects() || right->hasSideEffects()); }
+
void setLeft(TIntermTyped* n) { left = n; }
void setRight(TIntermTyped* n) { right = n; }
TIntermTyped* getLeft() const { return left; }
@@ -451,6 +459,8 @@
virtual void traverse(TIntermTraverser*);
virtual TIntermUnary* getAsUnaryNode() { return this; }
+ virtual bool hasSideEffects() const { return (TIntermOperator::hasSideEffects() || operand->hasSideEffects()); }
+
void setOperand(TIntermTyped* o) { operand = o; }
TIntermTyped* getOperand() { return operand; }
bool promote(TInfoSink&);
@@ -481,6 +491,9 @@
virtual TIntermAggregate* getAsAggregate() { return this; }
virtual void traverse(TIntermTraverser*);
+ // Conservatively assume function calls and other aggregate operators have side-effects
+ virtual bool hasSideEffects() const { return true; }
+
TIntermSequence& getSequence() { return sequence; }
void setName(const TString& n) { name = n; }
@@ -524,6 +537,9 @@
virtual void traverse(TIntermTraverser*);
+ // Conservatively assume selections have side-effects
+ virtual bool hasSideEffects() const { return true; }
+
bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
TIntermNode* getCondition() const { return condition; }
TIntermNode* getTrueBlock() const { return trueBlock; }