SkSL enum changes
Changed a couple of SkSL enums to enum classes and rearranged things to make their storage within IRNode type safe. Change-Id: I6509d027d79161c1a09473e90943aae061583f20 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/324624 Reviewed-by: John Stiles <johnstiles@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
e70a30d46f
commit
453f67ff0a
@ -193,9 +193,10 @@ public:
|
||||
bool visitExpression(const Expression& e) override {
|
||||
if (e.is<VariableReference>()) {
|
||||
const VariableReference& ref = e.as<VariableReference>();
|
||||
if (ref.variable() == fVar && (ref.refKind() == VariableReference::kWrite_RefKind ||
|
||||
ref.refKind() == VariableReference::kReadWrite_RefKind ||
|
||||
ref.refKind() == VariableReference::kPointer_RefKind)) {
|
||||
if (ref.variable() == fVar &&
|
||||
(ref.refKind() == VariableReference::RefKind::kWrite ||
|
||||
ref.refKind() == VariableReference::RefKind::kReadWrite ||
|
||||
ref.refKind() == VariableReference::RefKind::kPointer)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ std::unique_ptr<ByteCodeFunction> ByteCodeGenerator::writeFunction(const Functio
|
||||
static int expression_as_builtin(const Expression& e) {
|
||||
if (e.is<VariableReference>()) {
|
||||
const Variable& var(*e.as<VariableReference>().variable());
|
||||
if (var.storage() == Variable::kGlobal_Storage) {
|
||||
if (var.storage() == Variable::Storage::kGlobal) {
|
||||
return var.modifiers().fLayout.fBuiltin;
|
||||
}
|
||||
}
|
||||
@ -424,7 +424,7 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Variable& var)
|
||||
// given that we seldom have more than a couple of variables, linear search is probably the most
|
||||
// efficient way to handle lookups
|
||||
switch (var.storage()) {
|
||||
case Variable::kLocal_Storage: {
|
||||
case Variable::Storage::kLocal: {
|
||||
for (int i = fLocals.size() - 1; i >= 0; --i) {
|
||||
if (fLocals[i] == &var) {
|
||||
SkASSERT(fParameterCount + i <= 255);
|
||||
@ -439,7 +439,7 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Variable& var)
|
||||
SkASSERT(result <= 255);
|
||||
return { result, Storage::kLocal };
|
||||
}
|
||||
case Variable::kParameter_Storage: {
|
||||
case Variable::Storage::kParameter: {
|
||||
int offset = 0;
|
||||
for (const auto& p : fFunction->fDeclaration.parameters()) {
|
||||
if (p == &var) {
|
||||
@ -451,7 +451,7 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Variable& var)
|
||||
SkASSERT(false);
|
||||
return Location::MakeInvalid();
|
||||
}
|
||||
case Variable::kGlobal_Storage: {
|
||||
case Variable::Storage::kGlobal: {
|
||||
if (var.type() == *fContext.fFragmentProcessor_Type) {
|
||||
int offset = 0;
|
||||
for (const auto& e : fProgram.elements()) {
|
||||
|
@ -138,7 +138,7 @@ static bool is_private(const Variable& var) {
|
||||
const Modifiers& modifiers = var.modifiers();
|
||||
return !(modifiers.fFlags & Modifiers::kUniform_Flag) &&
|
||||
!(modifiers.fFlags & Modifiers::kIn_Flag) &&
|
||||
var.storage() == Variable::kGlobal_Storage &&
|
||||
var.storage() == Variable::Storage::kGlobal &&
|
||||
modifiers.fLayout.fBuiltin == -1;
|
||||
}
|
||||
|
||||
|
@ -207,8 +207,10 @@ Compiler::Compiler(Flags flags)
|
||||
StringFragment skCapsName("sk_Caps");
|
||||
fRootSymbolTable->add(std::make_unique<Variable>(/*offset=*/-1,
|
||||
fIRGenerator->fModifiers->handle(Modifiers()),
|
||||
skCapsName, fContext->fSkCaps_Type.get(),
|
||||
/*builtin=*/false, Variable::kGlobal_Storage));
|
||||
skCapsName,
|
||||
fContext->fSkCaps_Type.get(),
|
||||
/*builtin=*/false,
|
||||
Variable::Storage::kGlobal));
|
||||
|
||||
fRootModule = {fRootSymbolTable, /*fIntrinsics=*/nullptr};
|
||||
|
||||
@ -350,7 +352,7 @@ void Compiler::addDefinition(const Expression* lvalue, std::unique_ptr<Expressio
|
||||
switch (lvalue->kind()) {
|
||||
case Expression::Kind::kVariableReference: {
|
||||
const Variable& var = *lvalue->as<VariableReference>().variable();
|
||||
if (var.storage() == Variable::kLocal_Storage) {
|
||||
if (var.storage() == Variable::Storage::kLocal) {
|
||||
definitions->set(&var, expr);
|
||||
}
|
||||
break;
|
||||
@ -452,7 +454,7 @@ void Compiler::addDefinitions(const BasicBlock::Node& node, DefinitionMap* defin
|
||||
}
|
||||
case Expression::Kind::kVariableReference: {
|
||||
const VariableReference* v = &expr->as<VariableReference>();
|
||||
if (v->refKind() != VariableReference::kRead_RefKind) {
|
||||
if (v->refKind() != VariableReference::RefKind::kRead) {
|
||||
this->addDefinition(
|
||||
v,
|
||||
(std::unique_ptr<Expression>*) &fContext->fDefined_Expression,
|
||||
@ -785,7 +787,7 @@ static void vectorize_right(BasicBlock* b,
|
||||
static void clear_write(Expression& expr) {
|
||||
switch (expr.kind()) {
|
||||
case Expression::Kind::kVariableReference: {
|
||||
expr.as<VariableReference>().setRefKind(VariableReference::kRead_RefKind);
|
||||
expr.as<VariableReference>().setRefKind(VariableReference::RefKind::kRead);
|
||||
break;
|
||||
}
|
||||
case Expression::Kind::kFieldAccess:
|
||||
@ -829,9 +831,9 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
case Expression::Kind::kVariableReference: {
|
||||
const VariableReference& ref = expr->as<VariableReference>();
|
||||
const Variable* var = ref.variable();
|
||||
if (ref.refKind() != VariableReference::kWrite_RefKind &&
|
||||
ref.refKind() != VariableReference::kPointer_RefKind &&
|
||||
var->storage() == Variable::kLocal_Storage && !definitions[var] &&
|
||||
if (ref.refKind() != VariableReference::RefKind::kWrite &&
|
||||
ref.refKind() != VariableReference::RefKind::kPointer &&
|
||||
var->storage() == Variable::Storage::kLocal && !definitions[var] &&
|
||||
(*undefinedVariables).find(var) == (*undefinedVariables).end()) {
|
||||
(*undefinedVariables).insert(var);
|
||||
this->error(expr->fOffset,
|
||||
|
@ -220,7 +220,7 @@ void Dehydrator::write(const Symbol& s) {
|
||||
this->write(v.modifiers());
|
||||
this->write(v.name());
|
||||
this->write(v.type());
|
||||
this->writeU8(v.storage());
|
||||
this->writeU8((int8_t) v.storage());
|
||||
break;
|
||||
}
|
||||
case Symbol::Kind::kField: {
|
||||
@ -379,7 +379,7 @@ void Dehydrator::write(const Expression* e) {
|
||||
const VariableReference& v = e->as<VariableReference>();
|
||||
this->writeCommand(Rehydrator::kVariableReference_Command);
|
||||
this->writeId(v.variable());
|
||||
this->writeU8(v.refKind());
|
||||
this->writeU8((int8_t) v.refKind());
|
||||
break;
|
||||
}
|
||||
case Expression::Kind::kFunctionReference:
|
||||
|
@ -296,7 +296,7 @@ std::unique_ptr<Block> IRGenerator::convertBlock(const ASTNode& block) {
|
||||
|
||||
std::unique_ptr<Statement> IRGenerator::convertVarDeclarationStatement(const ASTNode& s) {
|
||||
SkASSERT(s.fKind == ASTNode::Kind::kVarDeclarations);
|
||||
auto decls = this->convertVarDeclarations(s, Variable::kLocal_Storage);
|
||||
auto decls = this->convertVarDeclarations(s, Variable::Storage::kLocal);
|
||||
if (decls.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -320,7 +320,7 @@ std::vector<std::unique_ptr<Statement>> IRGenerator::convertVarDeclarations(
|
||||
return {};
|
||||
}
|
||||
if (baseType->nonnullable() == *fContext.fFragmentProcessor_Type &&
|
||||
storage != Variable::kGlobal_Storage) {
|
||||
storage != Variable::Storage::kGlobal) {
|
||||
fErrors.error(decls.fOffset,
|
||||
"variables of type '" + baseType->displayName() + "' must be global");
|
||||
}
|
||||
@ -397,7 +397,7 @@ std::vector<std::unique_ptr<Statement>> IRGenerator::convertVarDeclarations(
|
||||
}
|
||||
}
|
||||
int permitted = Modifiers::kConst_Flag;
|
||||
if (storage == Variable::kGlobal_Storage) {
|
||||
if (storage == Variable::Storage::kGlobal) {
|
||||
permitted |= Modifiers::kIn_Flag | Modifiers::kOut_Flag | Modifiers::kUniform_Flag |
|
||||
Modifiers::kFlat_Flag | Modifiers::kVarying_Flag |
|
||||
Modifiers::kNoPerspective_Flag | Modifiers::kPLS_Flag |
|
||||
@ -468,9 +468,9 @@ std::vector<std::unique_ptr<Statement>> IRGenerator::convertVarDeclarations(
|
||||
var->setInitialValue(value.get());
|
||||
}
|
||||
Symbol* symbol = (*fSymbolTable)[var->name()];
|
||||
if (symbol && storage == Variable::kGlobal_Storage && var->name() == "sk_FragColor") {
|
||||
if (symbol && storage == Variable::Storage::kGlobal && var->name() == "sk_FragColor") {
|
||||
// Already defined, ignore.
|
||||
} else if (symbol && storage == Variable::kGlobal_Storage &&
|
||||
} else if (symbol && storage == Variable::Storage::kGlobal &&
|
||||
symbol->kind() == Symbol::Kind::kVariable &&
|
||||
symbol->as<Variable>().modifiers().fLayout.fBuiltin >= 0) {
|
||||
// Already defined, just update the modifiers.
|
||||
@ -789,9 +789,9 @@ std::unique_ptr<Block> IRGenerator::applyInvocationIDWorkaround(std::unique_ptr<
|
||||
fContext.fBool_Type.get()));
|
||||
std::unique_ptr<Expression> next(new PostfixExpression(
|
||||
std::unique_ptr<Expression>(
|
||||
new VariableReference(-1,
|
||||
loopIdx,
|
||||
VariableReference::kReadWrite_RefKind)),
|
||||
new VariableReference(-1,
|
||||
loopIdx,
|
||||
VariableReference::RefKind::kReadWrite)),
|
||||
Token::Kind::TK_PLUSPLUS));
|
||||
ASTNode endPrimitiveID(&fFile->fNodes, -1, ASTNode::Kind::kIdentifier, "EndPrimitive");
|
||||
std::unique_ptr<Expression> endPrimitive = this->convertExpression(endPrimitiveID);
|
||||
@ -809,7 +809,7 @@ std::unique_ptr<Block> IRGenerator::applyInvocationIDWorkaround(std::unique_ptr<
|
||||
std::vector<std::unique_ptr<Expression>>()))));
|
||||
std::unique_ptr<Expression> assignment(new BinaryExpression(-1,
|
||||
std::unique_ptr<Expression>(new VariableReference(-1, loopIdx,
|
||||
VariableReference::kWrite_RefKind)),
|
||||
VariableReference::RefKind::kWrite)),
|
||||
Token::Kind::TK_EQ,
|
||||
std::make_unique<IntLiteral>(fContext, -1, 0),
|
||||
fContext.fInt_Type.get()));
|
||||
@ -832,9 +832,9 @@ std::unique_ptr<Statement> IRGenerator::getNormalizeSkPositionCode() {
|
||||
// sk_Position.w);
|
||||
SkASSERT(fSkPerVertex && fRTAdjust);
|
||||
#define REF(var) std::unique_ptr<Expression>(\
|
||||
new VariableReference(-1, var, VariableReference::kRead_RefKind))
|
||||
new VariableReference(-1, var, VariableReference::RefKind::kRead))
|
||||
#define WREF(var) std::unique_ptr<Expression>(\
|
||||
new VariableReference(-1, var, VariableReference::kWrite_RefKind))
|
||||
new VariableReference(-1, var, VariableReference::RefKind::kWrite))
|
||||
#define FIELD(var, idx) std::unique_ptr<Expression>(\
|
||||
new FieldAccess(REF(var), idx, FieldAccess::kAnonymousInterfaceBlock_OwnerKind))
|
||||
#define POS std::unique_ptr<Expression>(new FieldAccess(WREF(fSkPerVertex), 0, \
|
||||
@ -964,7 +964,7 @@ void IRGenerator::convertFunction(const ASTNode& f) {
|
||||
Variable* var = fSymbolTable->takeOwnershipOfSymbol(
|
||||
std::make_unique<Variable>(param.fOffset, fModifiers->handle(pd.fModifiers),
|
||||
name, type, fIsBuiltinCode,
|
||||
Variable::kParameter_Storage));
|
||||
Variable::Storage::kParameter));
|
||||
parameters.push_back(var);
|
||||
}
|
||||
|
||||
@ -1137,7 +1137,7 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode
|
||||
auto iter = intf.begin();
|
||||
for (size_t i = 0; i < id.fDeclarationCount; ++i) {
|
||||
std::vector<std::unique_ptr<Statement>> decls =
|
||||
this->convertVarDeclarations(*(iter++), Variable::kInterfaceBlock_Storage);
|
||||
this->convertVarDeclarations(*(iter++), Variable::Storage::kInterfaceBlock);
|
||||
if (decls.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -1205,7 +1205,7 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode
|
||||
id.fInstanceName.fLength ? id.fInstanceName : id.fTypeName,
|
||||
type,
|
||||
fIsBuiltinCode,
|
||||
Variable::kGlobal_Storage));
|
||||
Variable::Storage::kGlobal));
|
||||
if (foundRTAdjust) {
|
||||
fRTAdjustInterfaceBlock = var;
|
||||
}
|
||||
@ -1274,7 +1274,7 @@ void IRGenerator::convertEnum(const ASTNode& e) {
|
||||
++currentValue;
|
||||
fSymbolTable->add(std::make_unique<Variable>(e.fOffset, fModifiers->handle(modifiers),
|
||||
child.getString(), type, fIsBuiltinCode,
|
||||
Variable::kGlobal_Storage, value.get()));
|
||||
Variable::Storage::kGlobal, value.get()));
|
||||
fSymbolTable->takeOwnershipOfIRNode(std::move(value));
|
||||
}
|
||||
// Now we orphanize the Enum's symbol table, so that future lookups in it are strict
|
||||
@ -1431,12 +1431,12 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTNode& identi
|
||||
// default to kRead_RefKind; this will be corrected later if the variable is written to
|
||||
return std::make_unique<VariableReference>(identifier.fOffset,
|
||||
var,
|
||||
VariableReference::kRead_RefKind);
|
||||
VariableReference::RefKind::kRead);
|
||||
}
|
||||
case Symbol::Kind::kField: {
|
||||
const Field* field = &result->as<Field>();
|
||||
auto base = std::make_unique<VariableReference>(identifier.fOffset, &field->owner(),
|
||||
VariableReference::kRead_RefKind);
|
||||
VariableReference::RefKind::kRead);
|
||||
return std::make_unique<FieldAccess>(std::move(base),
|
||||
field->fieldIndex(),
|
||||
FieldAccess::kAnonymousInterfaceBlock_OwnerKind);
|
||||
@ -1967,8 +1967,8 @@ std::unique_ptr<Expression> IRGenerator::convertBinaryExpression(const ASTNode&
|
||||
}
|
||||
if (Compiler::IsAssignment(op)) {
|
||||
if (!this->setRefKind(*left, op != Token::Kind::TK_EQ
|
||||
? VariableReference::kReadWrite_RefKind
|
||||
: VariableReference::kWrite_RefKind)) {
|
||||
? VariableReference::RefKind::kReadWrite
|
||||
: VariableReference::RefKind::kWrite)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -2122,8 +2122,8 @@ std::unique_ptr<Expression> IRGenerator::call(int offset,
|
||||
const Modifiers& paramModifiers = function.parameters()[i]->modifiers();
|
||||
if (paramModifiers.fFlags & Modifiers::kOut_Flag) {
|
||||
if (!this->setRefKind(*arguments[i], paramModifiers.fFlags & Modifiers::kIn_Flag
|
||||
? VariableReference::kReadWrite_RefKind
|
||||
: VariableReference::kPointer_RefKind)) {
|
||||
? VariableReference::RefKind::kReadWrite
|
||||
: VariableReference::RefKind::kPointer)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -2407,7 +2407,7 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(const ASTNode&
|
||||
"' cannot operate on '" + baseType.displayName() + "'");
|
||||
return nullptr;
|
||||
}
|
||||
if (!this->setRefKind(*base, VariableReference::kReadWrite_RefKind)) {
|
||||
if (!this->setRefKind(*base, VariableReference::RefKind::kReadWrite)) {
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
@ -2418,7 +2418,7 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(const ASTNode&
|
||||
"' cannot operate on '" + baseType.displayName() + "'");
|
||||
return nullptr;
|
||||
}
|
||||
if (!this->setRefKind(*base, VariableReference::kReadWrite_RefKind)) {
|
||||
if (!this->setRefKind(*base, VariableReference::RefKind::kReadWrite)) {
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
@ -2832,7 +2832,7 @@ std::unique_ptr<Expression> IRGenerator::convertPostfixExpression(const ASTNode&
|
||||
"' cannot operate on '" + baseType.displayName() + "'");
|
||||
return nullptr;
|
||||
}
|
||||
if (!this->setRefKind(*base, VariableReference::kReadWrite_RefKind)) {
|
||||
if (!this->setRefKind(*base, VariableReference::RefKind::kReadWrite)) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<PostfixExpression>(std::move(base), expression.getToken().fKind);
|
||||
@ -2975,7 +2975,7 @@ void IRGenerator::convertProgram(Program::Kind kind,
|
||||
switch (decl.fKind) {
|
||||
case ASTNode::Kind::kVarDeclarations: {
|
||||
std::vector<std::unique_ptr<Statement>> decls =
|
||||
this->convertVarDeclarations(decl, Variable::kGlobal_Storage);
|
||||
this->convertVarDeclarations(decl, Variable::Storage::kGlobal);
|
||||
for (auto& varDecl : decls) {
|
||||
fProgramElements->push_back(std::make_unique<GlobalVarDeclaration>(
|
||||
decl.fOffset, std::move(varDecl)));
|
||||
|
@ -503,7 +503,8 @@ std::unique_ptr<Statement> Inliner::inlineStatement(int offset,
|
||||
auto assignment =
|
||||
std::make_unique<ExpressionStatement>(std::make_unique<BinaryExpression>(
|
||||
offset,
|
||||
clone_with_ref_kind(*resultExpr, VariableReference::kWrite_RefKind),
|
||||
clone_with_ref_kind(*resultExpr,
|
||||
VariableReference::RefKind::kWrite),
|
||||
Token::Kind::TK_EQ,
|
||||
expr(r.expression()),
|
||||
&resultExpr->type()));
|
||||
@ -633,7 +634,7 @@ Inliner::InlinedCall Inliner::inlineCall(FunctionCall* call,
|
||||
const Variable* variableSymbol = symbolTableForCall->add(std::make_unique<Variable>(
|
||||
/*offset=*/-1, fModifiers->handle(Modifiers()),
|
||||
nameFrag, type, caller->isBuiltin(),
|
||||
Variable::kLocal_Storage, initialValue->get()));
|
||||
Variable::Storage::kLocal, initialValue->get()));
|
||||
|
||||
// Prepare the variable declaration (taking extra care with `out` params to not clobber any
|
||||
// initial value).
|
||||
@ -719,7 +720,7 @@ Inliner::InlinedCall Inliner::inlineCall(FunctionCall* call,
|
||||
inlinedBody.children().push_back(
|
||||
std::make_unique<ExpressionStatement>(std::make_unique<BinaryExpression>(
|
||||
offset,
|
||||
clone_with_ref_kind(*arguments[i], VariableReference::kWrite_RefKind),
|
||||
clone_with_ref_kind(*arguments[i], VariableReference::RefKind::kWrite),
|
||||
Token::Kind::TK_EQ,
|
||||
std::move(varMap[p]),
|
||||
&arguments[i]->type())));
|
||||
@ -727,7 +728,8 @@ Inliner::InlinedCall Inliner::inlineCall(FunctionCall* call,
|
||||
|
||||
if (resultExpr != nullptr) {
|
||||
// Return our result variable as our replacement expression.
|
||||
SkASSERT(resultExpr->as<VariableReference>().refKind() == VariableReference::kRead_RefKind);
|
||||
SkASSERT(resultExpr->as<VariableReference>().refKind() ==
|
||||
VariableReference::RefKind::kRead);
|
||||
inlinedCall.fReplacementExpr = std::move(resultExpr);
|
||||
} else {
|
||||
// It's a void function, so it doesn't actually result in anything, but we have to return
|
||||
|
@ -702,7 +702,7 @@ void MetalCodeGenerator::writeVariableReference(const VariableReference& ref) {
|
||||
break;
|
||||
default:
|
||||
const Variable& var = *ref.variable();
|
||||
if (var.storage() == Variable::kGlobal_Storage) {
|
||||
if (var.storage() == Variable::Storage::kGlobal) {
|
||||
if (var.modifiers().fFlags & Modifiers::kIn_Flag) {
|
||||
this->write("_in.");
|
||||
} else if (var.modifiers().fFlags & Modifiers::kOut_Flag) {
|
||||
@ -839,7 +839,7 @@ void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
|
||||
this->write("(");
|
||||
}
|
||||
if (Compiler::IsAssignment(op) && left.is<VariableReference>() &&
|
||||
left.as<VariableReference>().variable()->storage() == Variable::kParameter_Storage &&
|
||||
left.as<VariableReference>().variable()->storage() == Variable::Storage::kParameter &&
|
||||
left.as<VariableReference>().variable()->modifiers().fFlags & Modifiers::kOut_Flag) {
|
||||
// writing to an out parameter. Since we have to turn those into pointers, we have to
|
||||
// dereference it here.
|
||||
@ -1723,7 +1723,7 @@ MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Expressi
|
||||
Requirements result = kNo_Requirements;
|
||||
if (modifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN) {
|
||||
result = kGlobals_Requirement | kFragCoord_Requirement;
|
||||
} else if (Variable::kGlobal_Storage == v.variable()->storage()) {
|
||||
} else if (Variable::Storage::kGlobal == v.variable()->storage()) {
|
||||
if (modifiers.fFlags & Modifiers::kIn_Flag) {
|
||||
result = kInputs_Requirement;
|
||||
} else if (modifiers.fFlags & Modifiers::kOut_Flag) {
|
||||
|
@ -1565,7 +1565,7 @@ SpvStorageClass_ get_storage_class(const Expression& expr) {
|
||||
switch (expr.kind()) {
|
||||
case Expression::Kind::kVariableReference: {
|
||||
const Variable& var = *expr.as<VariableReference>().variable();
|
||||
if (var.storage() != Variable::kGlobal_Storage) {
|
||||
if (var.storage() != Variable::Storage::kGlobal) {
|
||||
return SpvStorageClassFunction;
|
||||
}
|
||||
SpvStorageClass_ result = get_storage_class(var.modifiers());
|
||||
@ -1883,7 +1883,7 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
|
||||
name,
|
||||
&intfStruct,
|
||||
/*builtin=*/false,
|
||||
Variable::kGlobal_Storage));
|
||||
Variable::Storage::kGlobal));
|
||||
InterfaceBlock intf(-1, intfVar, name, String(""),
|
||||
std::vector<std::unique_ptr<Expression>>(), st);
|
||||
|
||||
@ -3232,7 +3232,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
||||
}
|
||||
for (auto entry : fVariableMap) {
|
||||
const Variable* var = entry.first;
|
||||
if (var->storage() == Variable::kGlobal_Storage &&
|
||||
if (var->storage() == Variable::Storage::kGlobal &&
|
||||
((var->modifiers().fFlags & Modifiers::kIn_Flag) ||
|
||||
(var->modifiers().fFlags & Modifiers::kOut_Flag)) && !is_dead(*var)) {
|
||||
interfaceVars.insert(entry.second);
|
||||
|
@ -35,8 +35,8 @@ static inline bool check_ref(const Expression& expr) {
|
||||
}
|
||||
case Expression::Kind::kVariableReference: {
|
||||
const VariableReference& ref = expr.as<VariableReference>();
|
||||
return ref.refKind() == VariableReference::kWrite_RefKind ||
|
||||
ref.refKind() == VariableReference::kReadWrite_RefKind;
|
||||
return ref.refKind() == VariableReference::RefKind::kWrite ||
|
||||
ref.refKind() == VariableReference::RefKind::kReadWrite;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
|
@ -29,6 +29,8 @@ class SymbolTable;
|
||||
class Type;
|
||||
class Variable;
|
||||
class VariableReference;
|
||||
enum class VariableRefKind : int8_t;
|
||||
enum class VariableStorage : int8_t;
|
||||
|
||||
/**
|
||||
* Represents a node in the intermediate representation (IR) tree. The IR is a fully-resolved
|
||||
@ -165,13 +167,13 @@ protected:
|
||||
// Tracks how many sites write to the variable. If this is zero, the variable is dead and
|
||||
// may be eliminated.
|
||||
mutable int16_t fWriteCount;
|
||||
/*Variable::Storage*/int8_t fStorage;
|
||||
VariableStorage fStorage;
|
||||
bool fBuiltin;
|
||||
};
|
||||
|
||||
struct VariableReferenceData {
|
||||
const Variable* fVariable;
|
||||
/*VariableReference::RefKind*/int8_t fRefKind;
|
||||
VariableRefKind fRefKind;
|
||||
};
|
||||
|
||||
struct NodeData {
|
||||
|
@ -18,6 +18,13 @@ namespace SkSL {
|
||||
|
||||
class Expression;
|
||||
|
||||
enum class VariableStorage : int8_t {
|
||||
kGlobal,
|
||||
kInterfaceBlock,
|
||||
kLocal,
|
||||
kParameter
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a variable, whether local, global, or a function parameter. This represents the
|
||||
* variable itself (the storage location), which is shared between all VariableReferences which
|
||||
@ -25,20 +32,15 @@ class Expression;
|
||||
*/
|
||||
class Variable : public Symbol {
|
||||
public:
|
||||
static constexpr Kind kSymbolKind = Kind::kVariable;
|
||||
using Storage = VariableStorage;
|
||||
|
||||
enum Storage {
|
||||
kGlobal_Storage,
|
||||
kInterfaceBlock_Storage,
|
||||
kLocal_Storage,
|
||||
kParameter_Storage
|
||||
};
|
||||
static constexpr Kind kSymbolKind = Kind::kVariable;
|
||||
|
||||
Variable(int offset, ModifiersPool::Handle modifiers, StringFragment name, const Type* type,
|
||||
bool builtin, Storage storage, const Expression* initialValue = nullptr)
|
||||
: INHERITED(offset, VariableData{name, type, initialValue, modifiers, /*readCount=*/0,
|
||||
/*writeCount=*/(int16_t) (initialValue ? 1 : 0),
|
||||
(int8_t) storage, builtin}) {}
|
||||
storage, builtin}) {}
|
||||
|
||||
~Variable() override {
|
||||
// can't destroy a variable while there are remaining references to it
|
||||
@ -102,7 +104,7 @@ public:
|
||||
bool dead() const {
|
||||
const VariableData& data = this->variableData();
|
||||
const Modifiers& modifiers = this->modifiers();
|
||||
if ((data.fStorage != kLocal_Storage && this->variableData().fReadCount) ||
|
||||
if ((data.fStorage != Storage::kLocal && this->variableData().fReadCount) ||
|
||||
(modifiers.fFlags & (Modifiers::kIn_Flag | Modifiers::kOut_Flag |
|
||||
Modifiers::kUniform_Flag | Modifiers::kVarying_Flag))) {
|
||||
return false;
|
||||
@ -114,19 +116,19 @@ public:
|
||||
|
||||
private:
|
||||
void referenceCreated(VariableReference::RefKind refKind) const {
|
||||
if (refKind != VariableReference::kRead_RefKind) {
|
||||
if (refKind != VariableReference::RefKind::kRead) {
|
||||
++this->variableData().fWriteCount;
|
||||
}
|
||||
if (refKind != VariableReference::kWrite_RefKind) {
|
||||
if (refKind != VariableReference::RefKind::kWrite) {
|
||||
++this->variableData().fReadCount;
|
||||
}
|
||||
}
|
||||
|
||||
void referenceDestroyed(VariableReference::RefKind refKind) const {
|
||||
if (refKind != VariableReference::kRead_RefKind) {
|
||||
if (refKind != VariableReference::RefKind::kRead) {
|
||||
--this->variableData().fWriteCount;
|
||||
}
|
||||
if (refKind != VariableReference::kWrite_RefKind) {
|
||||
if (refKind != VariableReference::RefKind::kWrite) {
|
||||
--this->variableData().fReadCount;
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
namespace SkSL {
|
||||
|
||||
VariableReference::VariableReference(int offset, const Variable* variable, RefKind refKind)
|
||||
: INHERITED(offset, VariableReferenceData{variable, (int8_t)refKind}) {
|
||||
: INHERITED(offset, VariableReferenceData{variable, refKind}) {
|
||||
SkASSERT(this->variable());
|
||||
this->variable()->referenceCreated(refKind);
|
||||
}
|
||||
@ -60,7 +60,7 @@ void VariableReference::setVariable(const Variable* variable) {
|
||||
|
||||
std::unique_ptr<Expression> VariableReference::constantPropagate(const IRGenerator& irGenerator,
|
||||
const DefinitionMap& definitions) {
|
||||
if (this->refKind() != kRead_RefKind) {
|
||||
if (this->refKind() != RefKind::kRead) {
|
||||
return nullptr;
|
||||
}
|
||||
const Expression* initialValue = this->variable()->initialValue();
|
||||
|
@ -15,6 +15,15 @@ namespace SkSL {
|
||||
class IRGenerator;
|
||||
class Variable;
|
||||
|
||||
enum class VariableRefKind : int8_t {
|
||||
kRead,
|
||||
kWrite,
|
||||
kReadWrite,
|
||||
// taking the address of a variable - we consider this a read & write but don't complain if
|
||||
// the variable was not previously assigned
|
||||
kPointer
|
||||
};
|
||||
|
||||
/**
|
||||
* A reference to a variable, through which it can be read or written. In the statement:
|
||||
*
|
||||
@ -24,18 +33,11 @@ class Variable;
|
||||
*/
|
||||
class VariableReference : public Expression {
|
||||
public:
|
||||
using RefKind = VariableRefKind;
|
||||
|
||||
static constexpr Kind kExpressionKind = Kind::kVariableReference;
|
||||
|
||||
enum RefKind {
|
||||
kRead_RefKind,
|
||||
kWrite_RefKind,
|
||||
kReadWrite_RefKind,
|
||||
// taking the address of a variable - we consider this a read & write but don't complain if
|
||||
// the variable was not previously assigned
|
||||
kPointer_RefKind
|
||||
};
|
||||
|
||||
VariableReference(int offset, const Variable* variable, RefKind refKind = kRead_RefKind);
|
||||
VariableReference(int offset, const Variable* variable, RefKind refKind = RefKind::kRead);
|
||||
|
||||
~VariableReference() override;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user