aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sksl/ir/SkSLVariableReference.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sksl/ir/SkSLVariableReference.cpp')
-rw-r--r--src/sksl/ir/SkSLVariableReference.cpp108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/sksl/ir/SkSLVariableReference.cpp b/src/sksl/ir/SkSLVariableReference.cpp
new file mode 100644
index 0000000000..37e0ca2e7d
--- /dev/null
+++ b/src/sksl/ir/SkSLVariableReference.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkSLVariableReference.h"
+
+#include "SkSLConstructor.h"
+#include "SkSLFloatLiteral.h"
+#include "SkSLIRGenerator.h"
+#include "SkSLSetting.h"
+
+namespace SkSL {
+
+VariableReference::VariableReference(int offset, const Variable& variable, RefKind refKind)
+: INHERITED(offset, kVariableReference_Kind, variable.fType)
+, fVariable(variable)
+, fRefKind(refKind) {
+ if (refKind != kRead_RefKind) {
+ fVariable.fWriteCount++;
+ }
+ if (refKind != kWrite_RefKind) {
+ fVariable.fReadCount++;
+ }
+}
+
+VariableReference::~VariableReference() {
+ if (fRefKind != kRead_RefKind) {
+ fVariable.fWriteCount--;
+ }
+ if (fRefKind != kWrite_RefKind) {
+ fVariable.fReadCount--;
+ }
+}
+
+void VariableReference::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;
+}
+
+std::unique_ptr<Expression> VariableReference::copy_constant(const IRGenerator& irGenerator,
+ const Expression* expr) {
+ ASSERT(expr->isConstant());
+ switch (expr->fKind) {
+ case Expression::kIntLiteral_Kind:
+ return std::unique_ptr<Expression>(new IntLiteral(irGenerator.fContext,
+ -1,
+ ((IntLiteral*) expr)->fValue));
+ case Expression::kFloatLiteral_Kind:
+ return std::unique_ptr<Expression>(new FloatLiteral(
+ irGenerator.fContext,
+ -1,
+ ((FloatLiteral*) expr)->fValue));
+ case Expression::kBoolLiteral_Kind:
+ return std::unique_ptr<Expression>(new BoolLiteral(irGenerator.fContext,
+ -1,
+ ((BoolLiteral*) expr)->fValue));
+ case Expression::kConstructor_Kind: {
+ const Constructor* c = (const Constructor*) expr;
+ std::vector<std::unique_ptr<Expression>> args;
+ for (const auto& arg : c->fArguments) {
+ args.push_back(copy_constant(irGenerator, arg.get()));
+ }
+ return std::unique_ptr<Expression>(new Constructor(-1, c->fType,
+ std::move(args)));
+ }
+ case Expression::kSetting_Kind: {
+ const Setting* s = (const Setting*) expr;
+ return std::unique_ptr<Expression>(new Setting(-1, s->fName,
+ copy_constant(irGenerator,
+ s->fValue.get())));
+ }
+ default:
+ ABORT("unsupported constant\n");
+ }
+}
+
+std::unique_ptr<Expression> VariableReference::constantPropagate(const IRGenerator& irGenerator,
+ const DefinitionMap& definitions) {
+ if (fRefKind != kRead_RefKind) {
+ return nullptr;
+ }
+ if ((fVariable.fModifiers.fFlags & Modifiers::kConst_Flag) && fVariable.fInitialValue &&
+ fVariable.fInitialValue->isConstant()) {
+ return copy_constant(irGenerator, fVariable.fInitialValue);
+ }
+ auto exprIter = definitions.find(&fVariable);
+ if (exprIter != definitions.end() && exprIter->second &&
+ (*exprIter->second)->isConstant()) {
+ return copy_constant(irGenerator, exprIter->second->get());
+ }
+ return nullptr;
+}
+
+} // namespace