Eliminate vtable from DSLVar class hierarchy.

The only usage of `virtual` was the `storage()` method. This value is
now stored in a member variable. It is packed next to a bool so it
should be ~zero extra space, versus 8 bytes for a vtable pointer. We
also save cost of a virtual dtor call every time a DSLVar goes away.

Because VariableStorage is not a public type, this required shuffling
some constructors around to live in the cpp instead of the header.

Change-Id: I9fdefc3696d123848fb567029c051b478349cec7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/542139
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2022-05-19 14:47:34 -04:00 committed by SkCQ
parent f774e6c90b
commit 3dc829746a
3 changed files with 104 additions and 74 deletions

View File

@ -133,6 +133,7 @@ generated_cc_atom(
":DSLModifiers_hdr",
":DSLType_hdr",
":SkSLPosition_hdr",
"//include/private:SkSLStatement_hdr",
],
)

View File

@ -8,6 +8,7 @@
#ifndef SKSL_DSL_VAR
#define SKSL_DSL_VAR
#include "include/private/SkSLStatement.h"
#include "include/sksl/DSLExpression.h"
#include "include/sksl/DSLModifiers.h"
#include "include/sksl/DSLType.h"
@ -24,7 +25,6 @@ class Expression;
class ExpressionArray;
class IRGenerator;
class SPIRVCodeGenerator;
class Statement;
class Variable;
enum class VariableStorage : int8_t;
@ -32,23 +32,16 @@ namespace dsl {
class DSLVarBase {
public:
/**
* Creates an empty, unpopulated var. Can be replaced with a real var later via `swap`.
*/
DSLVarBase() : fType(kVoid_Type) {}
/**
* Constructs a new variable with the specified type and name.
*/
DSLVarBase(DSLType type, std::string_view name, DSLExpression initialValue, Position pos,
Position namePos);
DSLVarBase(const DSLModifiers& modifiers, DSLType type, std::string_view name,
DSLVarBase(VariableStorage storage, DSLType type, std::string_view name,
DSLExpression initialValue, Position pos, Position namePos);
DSLVarBase(DSLVarBase&&) = default;
DSLVarBase(VariableStorage storage, const DSLModifiers& modifiers, DSLType type,
std::string_view name, DSLExpression initialValue, Position pos, Position namePos);
virtual ~DSLVarBase();
DSLVarBase(DSLVarBase&&) = default;
std::string_view name() const {
return fName;
@ -58,7 +51,9 @@ public:
return fModifiers;
}
virtual VariableStorage storage() const = 0;
VariableStorage storage() const {
return fStorage;
}
DSLExpression x() {
return DSLExpression(*this, Position()).x();
@ -119,6 +114,11 @@ public:
}
protected:
/**
* Creates an empty, unpopulated var. Can be replaced with a real var later via `swap`.
*/
DSLVarBase(VariableStorage storage) : fType(kVoid_Type), fStorage(storage) {}
DSLPossibleExpression assignExpression(DSLExpression other);
void swap(DSLVarBase& other);
@ -134,8 +134,9 @@ protected:
Position fNamePosition;
std::string_view fName;
DSLExpression fInitialValue;
bool fInitialized = false;
Position fPosition;
VariableStorage fStorage;
bool fInitialized = false;
friend class DSLCore;
friend class DSLExpression;
@ -150,21 +151,16 @@ protected:
*/
class DSLVar : public DSLVarBase {
public:
DSLVar() = default;
DSLVar();
DSLVar(DSLType type, std::string_view name,
DSLExpression initialValue = DSLExpression(),
Position pos = {}, Position namePos = {})
: INHERITED(type, name, std::move(initialValue), pos, namePos) {}
DSLVar(DSLType type, std::string_view name, DSLExpression initialValue = DSLExpression(),
Position pos = {}, Position namePos = {});
DSLVar(const DSLModifiers& modifiers, DSLType type, std::string_view name,
DSLExpression initialValue = DSLExpression(), Position pos = {}, Position namePos = {})
: INHERITED(modifiers, type, name, std::move(initialValue), pos, namePos) {}
DSLExpression initialValue = DSLExpression(), Position pos = {}, Position namePos = {});
DSLVar(DSLVar&&) = default;
VariableStorage storage() const override;
void swap(DSLVar& other);
private:
@ -176,22 +172,19 @@ private:
*/
class DSLGlobalVar : public DSLVarBase {
public:
DSLGlobalVar() = default;
DSLGlobalVar();
DSLGlobalVar(DSLType type, std::string_view name,
DSLExpression initialValue = DSLExpression(), Position pos = {}, Position namePos = {})
: INHERITED(type, name, std::move(initialValue), pos, namePos) {}
DSLGlobalVar(DSLType type, std::string_view name, DSLExpression initialValue = DSLExpression(),
Position pos = {}, Position namePos = {});
DSLGlobalVar(const DSLModifiers& modifiers, DSLType type, std::string_view name,
DSLExpression initialValue = DSLExpression(), Position pos = {}, Position namePos = {})
: INHERITED(modifiers, type, name, std::move(initialValue), pos, namePos) {}
DSLExpression initialValue = DSLExpression(),
Position pos = {}, Position namePos = {});
DSLGlobalVar(const char* name);
DSLGlobalVar(DSLGlobalVar&&) = default;
VariableStorage storage() const override;
void swap(DSLGlobalVar& other);
/**
@ -205,8 +198,7 @@ public:
* Implements the following method call:
* half4 blender::eval(half4 src, half4 dst);
*/
DSLExpression eval(DSLExpression x, DSLExpression y,
Position pos = {});
DSLExpression eval(DSLExpression x, DSLExpression y, Position pos = {});
private:
DSLExpression eval(ExpressionArray args, Position pos);
@ -221,19 +213,15 @@ private:
*/
class DSLParameter : public DSLVarBase {
public:
DSLParameter() = default;
DSLParameter();
DSLParameter(DSLType type, std::string_view name, Position pos = {}, Position namePos = {})
: INHERITED(type, name, DSLExpression(), pos, namePos) {}
DSLParameter(DSLType type, std::string_view name, Position pos = {}, Position namePos = {});
DSLParameter(const DSLModifiers& modifiers, DSLType type, std::string_view name,
Position pos = {}, Position namePos = {})
: INHERITED(modifiers, type, name, DSLExpression(), pos, namePos) {}
Position pos = {}, Position namePos = {});
DSLParameter(DSLParameter&&) = default;
VariableStorage storage() const override;
void swap(DSLParameter& other);
private:

View File

@ -22,24 +22,31 @@
#include "src/sksl/ir/SkSLSymbolTable.h"
#include "src/sksl/ir/SkSLVariable.h"
#include <utility>
namespace SkSL {
namespace dsl {
DSLVarBase::DSLVarBase(DSLType type, std::string_view name, DSLExpression initialValue,
Position pos, Position namePos)
: DSLVarBase(DSLModifiers(), std::move(type), name, std::move(initialValue), pos, namePos) {}
/**
* DSLVarBase
*/
DSLVarBase::DSLVarBase(const DSLModifiers& modifiers, DSLType type, std::string_view name,
DSLVarBase::DSLVarBase(VariableStorage storage, DSLType type, std::string_view name,
DSLExpression initialValue, Position pos, Position namePos)
: DSLVarBase(storage, DSLModifiers(), std::move(type), name, std::move(initialValue),
pos, namePos) {}
DSLVarBase::DSLVarBase(VariableStorage storage, const DSLModifiers& modifiers, DSLType type,
std::string_view name, DSLExpression initialValue, Position pos,
Position namePos)
: fModifiers(std::move(modifiers))
, fType(std::move(type))
, fNamePosition(namePos)
, fName(name)
, fInitialValue(std::move(initialValue))
, fPosition(pos) {}
DSLVarBase::~DSLVarBase() {}
, fPosition(pos)
, fStorage(storage) {}
void DSLVarBase::swap(DSLVarBase& other) {
SkASSERT(this->storage() == other.storage());
@ -54,16 +61,55 @@ void DSLVarBase::swap(DSLVarBase& other) {
std::swap(fPosition, other.fPosition);
}
DSLPossibleExpression DSLVarBase::operator[](DSLExpression&& index) {
return DSLExpression(*this, Position())[std::move(index)];
}
DSLPossibleExpression DSLVarBase::assignExpression(DSLExpression expr) {
return BinaryExpression::Convert(ThreadContext::Context(), Position(),
DSLExpression(*this, Position()).release(), SkSL::Operator::Kind::EQ,
expr.release());
}
/**
* DSLVar
*/
DSLVar::DSLVar() : DSLVarBase(SkSL::VariableStorage::kLocal) {}
DSLVar::DSLVar(DSLType type, std::string_view name, DSLExpression initialValue,
Position pos, Position namePos)
: INHERITED(SkSL::VariableStorage::kLocal, type, name, std::move(initialValue),
pos, namePos) {}
DSLVar::DSLVar(const DSLModifiers& modifiers, DSLType type, std::string_view name,
DSLExpression initialValue, Position pos, Position namePos)
: INHERITED(SkSL::VariableStorage::kLocal, modifiers, type, name, std::move(initialValue),
pos, namePos) {}
void DSLVar::swap(DSLVar& other) {
INHERITED::swap(other);
}
VariableStorage DSLVar::storage() const {
return VariableStorage::kLocal;
}
/**
* DSLGlobalVar
*/
DSLGlobalVar::DSLGlobalVar() : DSLVarBase(SkSL::VariableStorage::kGlobal) {}
DSLGlobalVar::DSLGlobalVar(DSLType type, std::string_view name, DSLExpression initialValue,
Position pos, Position namePos)
: INHERITED(SkSL::VariableStorage::kGlobal, type, name, std::move(initialValue),
pos, namePos) {}
DSLGlobalVar::DSLGlobalVar(const DSLModifiers& modifiers, DSLType type, std::string_view name,
DSLExpression initialValue, Position pos, Position namePos)
: INHERITED(SkSL::VariableStorage::kGlobal, modifiers, type, name, std::move(initialValue),
pos, namePos) {}
DSLGlobalVar::DSLGlobalVar(const char* name)
: INHERITED(kVoid_Type, name, DSLExpression(), Position(), Position()) {
: INHERITED(SkSL::VariableStorage::kGlobal, kVoid_Type, name, DSLExpression(),
Position(), Position()) {
fName = name;
const SkSL::Symbol* result = (*ThreadContext::SymbolTable())[fName];
SkASSERTF(result, "could not find '%.*s' in symbol table", (int)fName.length(), fName.data());
@ -75,29 +121,6 @@ void DSLGlobalVar::swap(DSLGlobalVar& other) {
INHERITED::swap(other);
}
VariableStorage DSLGlobalVar::storage() const {
return VariableStorage::kGlobal;
}
void DSLParameter::swap(DSLParameter& other) {
INHERITED::swap(other);
}
VariableStorage DSLParameter::storage() const {
return VariableStorage::kParameter;
}
DSLPossibleExpression DSLVarBase::operator[](DSLExpression&& index) {
return DSLExpression(*this, Position())[std::move(index)];
}
DSLPossibleExpression DSLVarBase::assignExpression(DSLExpression expr) {
return BinaryExpression::Convert(ThreadContext::Context(), Position(),
DSLExpression(*this, Position()).release(), SkSL::Operator::Kind::EQ,
expr.release());
}
std::unique_ptr<SkSL::Expression> DSLGlobalVar::methodCall(std::string_view methodName,
Position pos) {
if (!this->fType.isEffectChild()) {
@ -130,6 +153,24 @@ DSLExpression DSLGlobalVar::eval(DSLExpression x, DSLExpression y, Position pos)
return this->eval(std::move(converted), pos);
}
/**
* DSLParameter
*/
DSLParameter::DSLParameter() : DSLVarBase(SkSL::VariableStorage::kParameter) {}
DSLParameter::DSLParameter(DSLType type, std::string_view name, Position pos, Position namePos)
: INHERITED(SkSL::VariableStorage::kParameter, type, name, DSLExpression(), pos, namePos) {}
DSLParameter::DSLParameter(const DSLModifiers& modifiers, DSLType type, std::string_view name,
Position pos, Position namePos)
: INHERITED(SkSL::VariableStorage::kParameter, modifiers, type, name, DSLExpression(),
pos, namePos) {}
void DSLParameter::swap(DSLParameter& other) {
INHERITED::swap(other);
}
} // namespace dsl
} // namespace SkSL