blob: d1544ac34fb5207a5be23d701e6d8cbfa27677ef [file] [log] [blame]
/*
* 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 "src/sksl/ir/SkSLVariableReference.h"
#include "src/sksl/SkSLIRGenerator.h"
#include "src/sksl/ir/SkSLConstructor.h"
#include "src/sksl/ir/SkSLFloatLiteral.h"
#include "src/sksl/ir/SkSLSetting.h"
namespace SkSL {
VariableReference::VariableReference(int offset, const Variable& variable, RefKind refKind)
: INHERITED(offset, kExpressionKind, &variable.type())
, 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) {
SkASSERT(expr->isCompileTimeConstant());
switch (expr->kind()) {
case Expression::Kind::kIntLiteral:
return std::unique_ptr<Expression>(new IntLiteral(irGenerator.fContext,
-1,
((IntLiteral*) expr)->fValue));
case Expression::Kind::kFloatLiteral:
return std::unique_ptr<Expression>(new FloatLiteral(
irGenerator.fContext,
-1,
((FloatLiteral*) expr)->fValue));
case Expression::Kind::kBoolLiteral:
return std::unique_ptr<Expression>(new BoolLiteral(irGenerator.fContext,
-1,
((BoolLiteral*) expr)->fValue));
case Expression::Kind::kConstructor: {
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->type(),
std::move(args)));
}
case Expression::Kind::kSetting: {
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->isCompileTimeConstant() &&
this->type().typeKind() != Type::TypeKind::kArray) {
return copy_constant(irGenerator, fVariable.fInitialValue);
}
auto exprIter = definitions.find(&fVariable);
if (exprIter != definitions.end() && exprIter->second &&
(*exprIter->second)->isCompileTimeConstant()) {
return copy_constant(irGenerator, exprIter->second->get());
}
return nullptr;
}
} // namespace SkSL