aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sksl/ir/SkSLVariableReference.h
diff options
context:
space:
mode:
authorGravatar Ethan Nicholas <ethannicholas@google.com>2017-01-19 10:44:45 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-19 16:17:36 +0000
commitf54b07121f81a56145fb118a2e18841fc135717d (patch)
tree088966a79e4f01641af5f198f985b07b9144b267 /src/sksl/ir/SkSLVariableReference.h
parent189098e70967c05c8810299b4afa325736a6565e (diff)
Added constant propagation and better variable liveness tracking to
skslc. This allows skslc to track the values of variables with constant values across multiple statements and replace variable references with constant values where appropriate. The improved liveness tracking allows skslc to realize that a variable is no longer alive if all references to it have been replaced. It is not yet doing much with this information; better dead code elimination is coming in a followup change. BUG=skia: Change-Id: I6bf267d478b769caf0063ac3597dc16bbe618cb4 Reviewed-on: https://skia-review.googlesource.com/7033 Commit-Queue: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
Diffstat (limited to 'src/sksl/ir/SkSLVariableReference.h')
-rw-r--r--src/sksl/ir/SkSLVariableReference.h71
1 files changed, 69 insertions, 2 deletions
diff --git a/src/sksl/ir/SkSLVariableReference.h b/src/sksl/ir/SkSLVariableReference.h
index c6a2ea0511..fecb04e2e5 100644
--- a/src/sksl/ir/SkSLVariableReference.h
+++ b/src/sksl/ir/SkSLVariableReference.h
@@ -20,16 +20,83 @@ namespace SkSL {
* there is only one Variable 'x', but two VariableReferences to it.
*/
struct VariableReference : public Expression {
- VariableReference(Position position, const Variable& variable)
+ enum RefKind {
+ kRead_RefKind,
+ kWrite_RefKind,
+ kReadWrite_RefKind
+ };
+
+ VariableReference(Position position, const Variable& variable, RefKind refKind = kRead_RefKind)
: INHERITED(position, kVariableReference_Kind, variable.fType)
- , fVariable(variable) {}
+ , fVariable(variable)
+ , fRefKind(refKind) {
+ if (refKind != kRead_RefKind) {
+ fVariable.fWriteCount++;
+ }
+ if (refKind != kWrite_RefKind) {
+ fVariable.fReadCount++;
+ }
+ }
+
+ virtual ~VariableReference() override {
+ if (fRefKind != kWrite_RefKind) {
+ fVariable.fReadCount--;
+ }
+ }
+
+ RefKind refKind() {
+ return fRefKind;
+ }
+
+ void setRefKind(RefKind refKind) {
+ if (fRefKind != kRead_RefKind) {
+ fVariable.fWriteCount--;
+ }
+ if (fRefKind != kWrite_RefKind) {
+ fVariable.fReadCount--;
+ }
+ if (refKind != kRead_RefKind) {
+ fVariable.fWriteCount++;
+ }
+ if (refKind != kWrite_RefKind) {
+ fVariable.fReadCount++;
+ }
+ fRefKind = refKind;
+ }
SkString description() const override {
return fVariable.fName;
}
+ virtual std::unique_ptr<Expression> constantPropagate(
+ const IRGenerator& irGenerator,
+ const DefinitionMap& definitions) override {
+ auto exprIter = definitions.find(&fVariable);
+ if (exprIter != definitions.end() && exprIter->second) {
+ const Expression* expr = exprIter->second->get();
+ switch (expr->fKind) {
+ case Expression::kIntLiteral_Kind:
+ return std::unique_ptr<Expression>(new IntLiteral(
+ irGenerator.fContext,
+ Position(),
+ ((IntLiteral*) expr)->fValue));
+ case Expression::kFloatLiteral_Kind:
+ return std::unique_ptr<Expression>(new FloatLiteral(
+ irGenerator.fContext,
+ Position(),
+ ((FloatLiteral*) expr)->fValue));
+ default:
+ break;
+ }
+ }
+ return nullptr;
+ }
+
const Variable& fVariable;
+private:
+ RefKind fRefKind;
+
typedef Expression INHERITED;
};