diff options
Diffstat (limited to 'src/sksl/ir')
45 files changed, 310 insertions, 21 deletions
diff --git a/src/sksl/ir/SkSLAppendStage.h b/src/sksl/ir/SkSLAppendStage.h index 87a8210a83..268ae979d2 100644 --- a/src/sksl/ir/SkSLAppendStage.h +++ b/src/sksl/ir/SkSLAppendStage.h @@ -23,7 +23,16 @@ struct AppendStage : public Expression { , fStage(stage) , fArguments(std::move(arguments)) {} - String description() const { + std::unique_ptr<Expression> clone() const override { + std::vector<std::unique_ptr<Expression>> cloned; + for (const auto& arg : fArguments) { + cloned.push_back(arg->clone()); + } + return std::unique_ptr<Expression>(new AppendStage(fOffset, fStage, std::move(cloned), + &fType)); + } + + String description() const override { String result = "append("; const char* separator = ""; for (const auto& a : fArguments) { @@ -35,7 +44,7 @@ struct AppendStage : public Expression { return result; } - bool hasSideEffects() const { + bool hasSideEffects() const override { return true; } @@ -44,6 +53,14 @@ struct AppendStage : public Expression { std::vector<std::unique_ptr<Expression>> fArguments; typedef Expression INHERITED; + +private: + AppendStage(int offset, SkRasterPipeline::StockStage stage, + std::vector<std::unique_ptr<Expression>> arguments, const Type* type) + : INHERITED(offset, kAppendStage_Kind, *type) + , fStage(stage) + , fArguments(std::move(arguments)) {} + }; } // namespace diff --git a/src/sksl/ir/SkSLBinaryExpression.h b/src/sksl/ir/SkSLBinaryExpression.h index c26994edf2..ed1a5cc181 100644 --- a/src/sksl/ir/SkSLBinaryExpression.h +++ b/src/sksl/ir/SkSLBinaryExpression.h @@ -38,6 +38,11 @@ struct BinaryExpression : public Expression { fRight->hasSideEffects(); } + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new BinaryExpression(fOffset, fLeft->clone(), fOperator, + fRight->clone(), fType)); + } + String description() const override { return "(" + fLeft->description() + " " + Compiler::OperatorName(fOperator) + " " + fRight->description() + ")"; diff --git a/src/sksl/ir/SkSLBlock.h b/src/sksl/ir/SkSLBlock.h index af1975396e..0a03654488 100644 --- a/src/sksl/ir/SkSLBlock.h +++ b/src/sksl/ir/SkSLBlock.h @@ -32,6 +32,14 @@ struct Block : public Statement { return true; } + std::unique_ptr<Statement> clone() const override { + std::vector<std::unique_ptr<Statement>> cloned; + for (const auto& s : fStatements) { + cloned.push_back(s->clone()); + } + return std::unique_ptr<Statement>(new Block(fOffset, std::move(cloned), fSymbols)); + } + String description() const override { String result("{"); for (size_t i = 0; i < fStatements.size(); i++) { diff --git a/src/sksl/ir/SkSLBoolLiteral.h b/src/sksl/ir/SkSLBoolLiteral.h index 9a69f0f138..d979ed3939 100644 --- a/src/sksl/ir/SkSLBoolLiteral.h +++ b/src/sksl/ir/SkSLBoolLiteral.h @@ -38,9 +38,18 @@ struct BoolLiteral : public Expression { return fValue == b.fValue; } + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new BoolLiteral(fOffset, fValue, &fType)); + } + const bool fValue; typedef Expression INHERITED; + +private: + BoolLiteral(int offset, bool value, const Type* type) + : INHERITED(offset, kBoolLiteral_Kind, *type) + , fValue(value) {} }; } // namespace diff --git a/src/sksl/ir/SkSLBreakStatement.h b/src/sksl/ir/SkSLBreakStatement.h index da392f5960..272deb65cd 100644 --- a/src/sksl/ir/SkSLBreakStatement.h +++ b/src/sksl/ir/SkSLBreakStatement.h @@ -20,6 +20,10 @@ struct BreakStatement : public Statement { BreakStatement(int offset) : INHERITED(offset, kBreak_Kind) {} + std::unique_ptr<Statement> clone() const override { + return std::unique_ptr<Statement>(new BreakStatement(fOffset)); + } + String description() const override { return String("break;"); } diff --git a/src/sksl/ir/SkSLConstructor.h b/src/sksl/ir/SkSLConstructor.h index 5e7c3d0d79..145e117453 100644 --- a/src/sksl/ir/SkSLConstructor.h +++ b/src/sksl/ir/SkSLConstructor.h @@ -43,8 +43,7 @@ struct Constructor : public Expression { fType == *irGenerator.fContext.fUShort_Type) { // promote uint(1) to 1u int64_t intValue = ((IntLiteral&) *fArguments[0]).fValue; - return std::unique_ptr<Expression>(new IntLiteral(irGenerator.fContext, - fOffset, + return std::unique_ptr<Expression>(new IntLiteral(fOffset, intValue, &fType)); } @@ -61,6 +60,14 @@ struct Constructor : public Expression { return false; } + std::unique_ptr<Expression> clone() const override { + std::vector<std::unique_ptr<Expression>> cloned; + for (const auto& arg : fArguments) { + cloned.push_back(arg->clone()); + } + return std::unique_ptr<Expression>(new Constructor(fOffset, fType, std::move(cloned))); + } + String description() const override { String result = fType.description() + "("; String separator; diff --git a/src/sksl/ir/SkSLContinueStatement.h b/src/sksl/ir/SkSLContinueStatement.h index 6ed40c404f..9977fbecaf 100644 --- a/src/sksl/ir/SkSLContinueStatement.h +++ b/src/sksl/ir/SkSLContinueStatement.h @@ -20,6 +20,10 @@ struct ContinueStatement : public Statement { ContinueStatement(int offset) : INHERITED(offset, kContinue_Kind) {} + std::unique_ptr<Statement> clone() const override { + return std::unique_ptr<Statement>(new ContinueStatement(fOffset)); + } + String description() const override { return String("continue;"); } diff --git a/src/sksl/ir/SkSLDiscardStatement.h b/src/sksl/ir/SkSLDiscardStatement.h index b62530e6f3..8c406e9353 100644 --- a/src/sksl/ir/SkSLDiscardStatement.h +++ b/src/sksl/ir/SkSLDiscardStatement.h @@ -20,6 +20,10 @@ struct DiscardStatement : public Statement { DiscardStatement(int offset) : INHERITED(offset, kDiscard_Kind) {} + std::unique_ptr<Statement> clone() const override { + return std::unique_ptr<Statement>(new DiscardStatement(fOffset)); + } + String description() const override { return String("discard;"); } diff --git a/src/sksl/ir/SkSLDoStatement.h b/src/sksl/ir/SkSLDoStatement.h index 3abec550eb..af0fc5951b 100644 --- a/src/sksl/ir/SkSLDoStatement.h +++ b/src/sksl/ir/SkSLDoStatement.h @@ -23,6 +23,11 @@ struct DoStatement : public Statement { , fStatement(std::move(statement)) , fTest(std::move(test)) {} + std::unique_ptr<Statement> clone() const override { + return std::unique_ptr<Statement>(new DoStatement(fOffset, fStatement->clone(), + fTest->clone())); + } + String description() const override { return "do " + fStatement->description() + " while (" + fTest->description() + ");"; } diff --git a/src/sksl/ir/SkSLEnum.h b/src/sksl/ir/SkSLEnum.h index 6c44a67678..eea7e5c3a5 100644 --- a/src/sksl/ir/SkSLEnum.h +++ b/src/sksl/ir/SkSLEnum.h @@ -17,6 +17,10 @@ struct Enum : public ProgramElement { , fTypeName(typeName) , fSymbols(std::move(symbols)) {} + std::unique_ptr<ProgramElement> clone() const override { + return std::unique_ptr<ProgramElement>(new Enum(fOffset, fTypeName, fSymbols)); + } + String description() const override { String result = "enum class " + fTypeName + " {\n"; String separator; diff --git a/src/sksl/ir/SkSLExpression.h b/src/sksl/ir/SkSLExpression.h index c8ad1380e7..ddeed448a2 100644 --- a/src/sksl/ir/SkSLExpression.h +++ b/src/sksl/ir/SkSLExpression.h @@ -106,6 +106,8 @@ struct Expression : public IRNode { return fType.coercionCost(target); } + virtual std::unique_ptr<Expression> clone() const = 0; + const Kind fKind; const Type& fType; diff --git a/src/sksl/ir/SkSLExpressionStatement.h b/src/sksl/ir/SkSLExpressionStatement.h index 215763b8fd..90aa5415cc 100644 --- a/src/sksl/ir/SkSLExpressionStatement.h +++ b/src/sksl/ir/SkSLExpressionStatement.h @@ -21,6 +21,10 @@ struct ExpressionStatement : public Statement { : INHERITED(expression->fOffset, kExpression_Kind) , fExpression(std::move(expression)) {} + std::unique_ptr<Statement> clone() const override { + return std::unique_ptr<Statement>(new ExpressionStatement(fExpression->clone())); + } + String description() const override { return fExpression->description() + ";"; } diff --git a/src/sksl/ir/SkSLExtension.h b/src/sksl/ir/SkSLExtension.h index b5a48b94ab..3a103a63c6 100644 --- a/src/sksl/ir/SkSLExtension.h +++ b/src/sksl/ir/SkSLExtension.h @@ -20,6 +20,10 @@ struct Extension : public ProgramElement { : INHERITED(offset, kExtension_Kind) , fName(std::move(name)) {} + std::unique_ptr<ProgramElement> clone() const override { + return std::unique_ptr<ProgramElement>(new Extension(fOffset, fName)); + } + String description() const override { return "#extension " + fName + " : enable"; } diff --git a/src/sksl/ir/SkSLFieldAccess.h b/src/sksl/ir/SkSLFieldAccess.h index 0f66dec5a4..b3bd05096e 100644 --- a/src/sksl/ir/SkSLFieldAccess.h +++ b/src/sksl/ir/SkSLFieldAccess.h @@ -35,6 +35,11 @@ struct FieldAccess : public Expression { return fBase->hasSideEffects(); } + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new FieldAccess(fBase->clone(), fFieldIndex, + fOwnerKind)); + } + String description() const override { return fBase->description() + "." + fBase->fType.fields()[fFieldIndex].fName; } diff --git a/src/sksl/ir/SkSLFloatLiteral.h b/src/sksl/ir/SkSLFloatLiteral.h index 82c15c032b..e995e4c6e1 100644 --- a/src/sksl/ir/SkSLFloatLiteral.h +++ b/src/sksl/ir/SkSLFloatLiteral.h @@ -17,9 +17,12 @@ namespace SkSL { * A literal floating point number. */ struct FloatLiteral : public Expression { - FloatLiteral(const Context& context, int offset, double value, - const Type* type = nullptr) - : INHERITED(offset, kFloatLiteral_Kind, type ? *type : *context.fFloat_Type) + FloatLiteral(const Context& context, int offset, double value) + : INHERITED(offset, kFloatLiteral_Kind, *context.fFloat_Type) + , fValue(value) {} + + FloatLiteral(int offset, double value, const Type* type) + : INHERITED(offset, kFloatLiteral_Kind, *type) , fValue(value) {} String description() const override { @@ -43,6 +46,10 @@ struct FloatLiteral : public Expression { return fValue; } + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new FloatLiteral(fOffset, fValue, &fType)); + } + const double fValue; typedef Expression INHERITED; diff --git a/src/sksl/ir/SkSLForStatement.h b/src/sksl/ir/SkSLForStatement.h index 6896ceb902..220be9855b 100644 --- a/src/sksl/ir/SkSLForStatement.h +++ b/src/sksl/ir/SkSLForStatement.h @@ -28,6 +28,12 @@ struct ForStatement : public Statement { , fNext(std::move(next)) , fStatement(std::move(statement)) {} + std::unique_ptr<Statement> clone() const override { + return std::unique_ptr<Statement>(new ForStatement(fOffset, fInitializer->clone(), + fTest->clone(), fNext->clone(), + fStatement->clone(), fSymbols)); + } + String description() const override { String result("for ("); if (fInitializer) { diff --git a/src/sksl/ir/SkSLFunctionCall.h b/src/sksl/ir/SkSLFunctionCall.h index 115281d63d..7047c37067 100644 --- a/src/sksl/ir/SkSLFunctionCall.h +++ b/src/sksl/ir/SkSLFunctionCall.h @@ -32,6 +32,15 @@ struct FunctionCall : public Expression { return fFunction.fModifiers.fFlags & Modifiers::kHasSideEffects_Flag; } + std::unique_ptr<Expression> clone() const override { + std::vector<std::unique_ptr<Expression>> cloned; + for (const auto& arg : fArguments) { + cloned.push_back(arg->clone()); + } + return std::unique_ptr<Expression>(new FunctionCall(fOffset, fType, fFunction, + std::move(cloned))); + } + String description() const override { String result = String(fFunction.fName) + "("; String separator; diff --git a/src/sksl/ir/SkSLFunctionDefinition.h b/src/sksl/ir/SkSLFunctionDefinition.h index e0dabc5791..4ec559756c 100644 --- a/src/sksl/ir/SkSLFunctionDefinition.h +++ b/src/sksl/ir/SkSLFunctionDefinition.h @@ -24,6 +24,11 @@ struct FunctionDefinition : public ProgramElement { , fDeclaration(declaration) , fBody(std::move(body)) {} + std::unique_ptr<ProgramElement> clone() const override { + return std::unique_ptr<ProgramElement>(new FunctionDefinition(fOffset, fDeclaration, + fBody->clone())); + } + String description() const override { return fDeclaration.description() + " " + fBody->description(); } diff --git a/src/sksl/ir/SkSLFunctionReference.h b/src/sksl/ir/SkSLFunctionReference.h index 58fefce801..4c7f7670d0 100644 --- a/src/sksl/ir/SkSLFunctionReference.h +++ b/src/sksl/ir/SkSLFunctionReference.h @@ -28,6 +28,10 @@ struct FunctionReference : public Expression { return false; } + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new FunctionReference(fOffset, fFunctions, &fType)); + } + String description() const override { return String("<function>"); } @@ -35,7 +39,12 @@ struct FunctionReference : public Expression { const std::vector<const FunctionDeclaration*> fFunctions; typedef Expression INHERITED; -}; + +private: + FunctionReference(int offset, std::vector<const FunctionDeclaration*> function, + const Type* type) + : INHERITED(offset, kFunctionReference_Kind, *type) + , fFunctions(function) {}}; } // namespace diff --git a/src/sksl/ir/SkSLIfStatement.h b/src/sksl/ir/SkSLIfStatement.h index 4c2ca0b1fa..9d35fe8f7d 100644 --- a/src/sksl/ir/SkSLIfStatement.h +++ b/src/sksl/ir/SkSLIfStatement.h @@ -25,6 +25,11 @@ struct IfStatement : public Statement { , fIfTrue(std::move(ifTrue)) , fIfFalse(std::move(ifFalse)) {} + std::unique_ptr<Statement> clone() const override { + return std::unique_ptr<Statement>(new IfStatement(fOffset, fIsStatic, fTest->clone(), + fIfTrue->clone(), fIfFalse ? fIfFalse->clone() : nullptr)); + } + String description() const override { String result; if (fIsStatic) { diff --git a/src/sksl/ir/SkSLIndexExpression.h b/src/sksl/ir/SkSLIndexExpression.h index de44b1adb2..74288e5171 100644 --- a/src/sksl/ir/SkSLIndexExpression.h +++ b/src/sksl/ir/SkSLIndexExpression.h @@ -62,6 +62,11 @@ struct IndexExpression : public Expression { return fBase->hasSideEffects() || fIndex->hasSideEffects(); } + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new IndexExpression(fBase->clone(), fIndex->clone(), + &fType)); + } + String description() const override { return fBase->description() + "[" + fIndex->description() + "]"; } @@ -70,6 +75,13 @@ struct IndexExpression : public Expression { std::unique_ptr<Expression> fIndex; typedef Expression INHERITED; + +private: + IndexExpression(std::unique_ptr<Expression> base, std::unique_ptr<Expression> index, + const Type* type) + : INHERITED(base->fOffset, kIndex_Kind, *type) + , fBase(std::move(base)) + , fIndex(std::move(index)) {} }; } // namespace diff --git a/src/sksl/ir/SkSLIntLiteral.h b/src/sksl/ir/SkSLIntLiteral.h index 50337bfe6f..116796c16d 100644 --- a/src/sksl/ir/SkSLIntLiteral.h +++ b/src/sksl/ir/SkSLIntLiteral.h @@ -19,8 +19,12 @@ namespace SkSL { struct IntLiteral : public Expression { // FIXME: we will need to revisit this if/when we add full support for both signed and unsigned // 64-bit integers, but for right now an int64_t will hold every value we care about - IntLiteral(const Context& context, int offset, int64_t value, const Type* type = nullptr) - : INHERITED(offset, kIntLiteral_Kind, type ? *type : *context.fInt_Type) + IntLiteral(const Context& context, int offset, int64_t value) + : INHERITED(offset, kIntLiteral_Kind, *context.fInt_Type) + , fValue(value) {} + + IntLiteral(int offset, int64_t value, const Type* type = nullptr) + : INHERITED(offset, kIntLiteral_Kind, *type) , fValue(value) {} String description() const override { @@ -51,6 +55,10 @@ struct IntLiteral : public Expression { return fValue; } + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new IntLiteral(fOffset, fValue, &fType)); + } + const int64_t fValue; typedef Expression INHERITED; diff --git a/src/sksl/ir/SkSLInterfaceBlock.h b/src/sksl/ir/SkSLInterfaceBlock.h index 4a7bf9307b..08bf9d0f75 100644 --- a/src/sksl/ir/SkSLInterfaceBlock.h +++ b/src/sksl/ir/SkSLInterfaceBlock.h @@ -35,6 +35,17 @@ struct InterfaceBlock : public ProgramElement { , fSizes(std::move(sizes)) , fTypeOwner(typeOwner) {} + std::unique_ptr<ProgramElement> clone() const override { + std::vector<std::unique_ptr<Expression>> sizesClone; + for (const auto& s : fSizes) { + sizesClone.push_back(s->clone()); + } + return std::unique_ptr<ProgramElement>(new InterfaceBlock(fOffset, &fVariable, fTypeName, + fInstanceName, + std::move(sizesClone), + fTypeOwner)); + } + String description() const override { String result = fVariable.fModifiers.description() + fTypeName + " {\n"; const Type* structType = &fVariable.fType; diff --git a/src/sksl/ir/SkSLLayout.h b/src/sksl/ir/SkSLLayout.h index 3082b34133..5c99807ab5 100644 --- a/src/sksl/ir/SkSLLayout.h +++ b/src/sksl/ir/SkSLLayout.h @@ -311,6 +311,9 @@ struct Layout { if (result.size() > 0) { result = "layout (" + result + ")"; } + if (fKey) { + result += "/* key */"; + } return result; } diff --git a/src/sksl/ir/SkSLModifiersDeclaration.h b/src/sksl/ir/SkSLModifiersDeclaration.h index 5c9608f02f..1f31926a30 100644 --- a/src/sksl/ir/SkSLModifiersDeclaration.h +++ b/src/sksl/ir/SkSLModifiersDeclaration.h @@ -23,7 +23,11 @@ struct ModifiersDeclaration : public ProgramElement { : INHERITED(-1, kModifiers_Kind) , fModifiers(modifiers) {} - String description() const { + std::unique_ptr<ProgramElement> clone() const override { + return std::unique_ptr<ProgramElement>(new ModifiersDeclaration(fModifiers)); + } + + String description() const override { return fModifiers.description() + ";"; } diff --git a/src/sksl/ir/SkSLNop.h b/src/sksl/ir/SkSLNop.h index e7aae9b7b8..954fedb13b 100644 --- a/src/sksl/ir/SkSLNop.h +++ b/src/sksl/ir/SkSLNop.h @@ -28,6 +28,10 @@ struct Nop : public Statement { return String(";"); } + std::unique_ptr<Statement> clone() const override { + return std::unique_ptr<Statement>(new Nop()); + } + typedef Statement INHERITED; }; diff --git a/src/sksl/ir/SkSLPostfixExpression.h b/src/sksl/ir/SkSLPostfixExpression.h index c53f1de507..dd20efd3e7 100644 --- a/src/sksl/ir/SkSLPostfixExpression.h +++ b/src/sksl/ir/SkSLPostfixExpression.h @@ -26,6 +26,10 @@ struct PostfixExpression : public Expression { return true; } + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new PostfixExpression(fOperand->clone(), fOperator)); + } + String description() const override { return fOperand->description() + Compiler::OperatorName(fOperator); } diff --git a/src/sksl/ir/SkSLPrefixExpression.h b/src/sksl/ir/SkSLPrefixExpression.h index d5d97b2517..366f714fa3 100644 --- a/src/sksl/ir/SkSLPrefixExpression.h +++ b/src/sksl/ir/SkSLPrefixExpression.h @@ -45,6 +45,10 @@ struct PrefixExpression : public Expression { return nullptr; } + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new PrefixExpression(fOperator, fOperand->clone())); + } + String description() const override { return Compiler::OperatorName(fOperator) + fOperand->description(); } diff --git a/src/sksl/ir/SkSLProgram.h b/src/sksl/ir/SkSLProgram.h index 9f140877b7..59c91229f8 100644 --- a/src/sksl/ir/SkSLProgram.h +++ b/src/sksl/ir/SkSLProgram.h @@ -39,6 +39,10 @@ struct Program { : fKind(kInt_Kind) , fValue(i) {} + Value(unsigned int i) + : fKind(kInt_Kind) + , fValue(i) {} + std::unique_ptr<Expression> literal(const Context& context, int offset) const { switch (fKind) { case Program::Settings::Value::kBool_Kind: @@ -192,7 +196,7 @@ struct Program { kVertex_Kind, kGeometry_Kind, kFragmentProcessor_Kind, - kCPU_Kind + kPipelineStage_Kind }; Program(Kind kind, @@ -252,10 +256,13 @@ struct Program { // because destroying elements can modify reference counts in symbols std::shared_ptr<SymbolTable> fSymbols; Inputs fInputs; + bool fIsOptimized = false; private: std::vector<std::unique_ptr<ProgramElement>>* fInheritedElements; std::vector<std::unique_ptr<ProgramElement>> fElements; + + friend class Compiler; }; } // namespace diff --git a/src/sksl/ir/SkSLProgramElement.h b/src/sksl/ir/SkSLProgramElement.h index 9d1bdfe885..b14836ffb1 100644 --- a/src/sksl/ir/SkSLProgramElement.h +++ b/src/sksl/ir/SkSLProgramElement.h @@ -32,6 +32,8 @@ struct ProgramElement : public IRNode { Kind fKind; + virtual std::unique_ptr<ProgramElement> clone() const = 0; + typedef IRNode INHERITED; }; diff --git a/src/sksl/ir/SkSLReturnStatement.h b/src/sksl/ir/SkSLReturnStatement.h index 1b479b8097..774d803011 100644 --- a/src/sksl/ir/SkSLReturnStatement.h +++ b/src/sksl/ir/SkSLReturnStatement.h @@ -24,6 +24,13 @@ struct ReturnStatement : public Statement { : INHERITED(expression->fOffset, kReturn_Kind) , fExpression(std::move(expression)) {} + std::unique_ptr<Statement> clone() const override { + if (fExpression) { + return std::unique_ptr<Statement>(new ReturnStatement(fExpression->clone())); + } + return std::unique_ptr<Statement>(new ReturnStatement(fOffset)); + } + String description() const override { if (fExpression) { return "return " + fExpression->description() + ";"; diff --git a/src/sksl/ir/SkSLSection.h b/src/sksl/ir/SkSLSection.h index 96c257b1f8..d06b979c17 100644 --- a/src/sksl/ir/SkSLSection.h +++ b/src/sksl/ir/SkSLSection.h @@ -22,6 +22,10 @@ struct Section : public ProgramElement { , fArgument(std::move(arg)) , fText(std::move(text)) {} + std::unique_ptr<ProgramElement> clone() const override { + return std::unique_ptr<ProgramElement>(new Section(fOffset, fName, fArgument, fText)); + } + String description() const override { String result = "@" + fName; if (fArgument.size()) { diff --git a/src/sksl/ir/SkSLSetting.cpp b/src/sksl/ir/SkSLSetting.cpp index 2d4a8ba151..9885a2873f 100644 --- a/src/sksl/ir/SkSLSetting.cpp +++ b/src/sksl/ir/SkSLSetting.cpp @@ -13,10 +13,10 @@ namespace SkSL { std::unique_ptr<Expression> Setting::constantPropagate(const IRGenerator& irGenerator, const DefinitionMap& definitions) { - if (irGenerator.fSettings->fReplaceSettings) { - return VariableReference::copy_constant(irGenerator, fValue.get()); - } - return nullptr; + if (irGenerator.fSettings->fReplaceSettings) { + return VariableReference::copy_constant(irGenerator, fValue.get()); } -} // namespace + return nullptr; +} +} // namespace diff --git a/src/sksl/ir/SkSLSetting.h b/src/sksl/ir/SkSLSetting.h index 1396099102..cc1c551077 100644 --- a/src/sksl/ir/SkSLSetting.h +++ b/src/sksl/ir/SkSLSetting.h @@ -28,6 +28,10 @@ struct Setting : public Expression { std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator, const DefinitionMap& definitions) override; + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new Setting(fOffset, fName, fValue->clone())); + } + String description() const override { return fName; } diff --git a/src/sksl/ir/SkSLStatement.h b/src/sksl/ir/SkSLStatement.h index a116cc1c4c..99aab19208 100644 --- a/src/sksl/ir/SkSLStatement.h +++ b/src/sksl/ir/SkSLStatement.h @@ -43,6 +43,8 @@ struct Statement : public IRNode { return false; } + virtual std::unique_ptr<Statement> clone() const = 0; + const Kind fKind; typedef IRNode INHERITED; diff --git a/src/sksl/ir/SkSLSwitchCase.h b/src/sksl/ir/SkSLSwitchCase.h index c33224bdbb..b9e52180f3 100644 --- a/src/sksl/ir/SkSLSwitchCase.h +++ b/src/sksl/ir/SkSLSwitchCase.h @@ -23,6 +23,16 @@ struct SwitchCase : public Statement { , fValue(std::move(value)) , fStatements(std::move(statements)) {} + std::unique_ptr<Statement> clone() const override { + std::vector<std::unique_ptr<Statement>> cloned; + for (const auto& s : fStatements) { + cloned.push_back(s->clone()); + } + return std::unique_ptr<Statement>(new SwitchCase(fOffset, + fValue ? fValue->clone() : nullptr, + std::move(cloned))); + } + String description() const override { String result; if (fValue) { diff --git a/src/sksl/ir/SkSLSwitchStatement.h b/src/sksl/ir/SkSLSwitchStatement.h index 68d0ef02df..2c48bad1ba 100644 --- a/src/sksl/ir/SkSLSwitchStatement.h +++ b/src/sksl/ir/SkSLSwitchStatement.h @@ -26,6 +26,15 @@ struct SwitchStatement : public Statement { , fSymbols(std::move(symbols)) , fCases(std::move(cases)) {} + std::unique_ptr<Statement> clone() const override { + std::vector<std::unique_ptr<SwitchCase>> cloned; + for (const auto& s : fCases) { + cloned.push_back(std::unique_ptr<SwitchCase>((SwitchCase*) s->clone().release())); + } + return std::unique_ptr<Statement>(new SwitchStatement(fOffset, fIsStatic, fValue->clone(), + std::move(cloned), fSymbols)); + } + String description() const override { String result; if (fIsStatic) { diff --git a/src/sksl/ir/SkSLSwizzle.h b/src/sksl/ir/SkSLSwizzle.h index e713a323b3..412ed903bb 100644 --- a/src/sksl/ir/SkSLSwizzle.h +++ b/src/sksl/ir/SkSLSwizzle.h @@ -127,6 +127,10 @@ struct Swizzle : public Expression { return fBase->hasSideEffects(); } + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new Swizzle(fType, fBase->clone(), fComponents)); + } + String description() const override { String result = fBase->description() + "."; for (int x : fComponents) { @@ -139,6 +143,16 @@ struct Swizzle : public Expression { const std::vector<int> fComponents; typedef Expression INHERITED; + +private: + Swizzle(const Type& type, std::unique_ptr<Expression> base, std::vector<int> components) + : INHERITED(base->fOffset, kSwizzle_Kind, type) + , fBase(std::move(base)) + , fComponents(std::move(components)) { + SkASSERT(fComponents.size() >= 1 && fComponents.size() <= 4); + } + + }; } // namespace diff --git a/src/sksl/ir/SkSLTernaryExpression.h b/src/sksl/ir/SkSLTernaryExpression.h index b77e0e07f2..f7e4ea0be6 100644 --- a/src/sksl/ir/SkSLTernaryExpression.h +++ b/src/sksl/ir/SkSLTernaryExpression.h @@ -30,6 +30,12 @@ struct TernaryExpression : public Expression { return fTest->hasSideEffects() || fIfTrue->hasSideEffects() || fIfFalse->hasSideEffects(); } + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new TernaryExpression(fOffset, fTest->clone(), + fIfTrue->clone(), + fIfFalse->clone())); + } + String description() const override { return "(" + fTest->description() + " ? " + fIfTrue->description() + " : " + fIfFalse->description() + ")"; diff --git a/src/sksl/ir/SkSLTypeReference.h b/src/sksl/ir/SkSLTypeReference.h index f7065b7c3f..df3dc15abd 100644 --- a/src/sksl/ir/SkSLTypeReference.h +++ b/src/sksl/ir/SkSLTypeReference.h @@ -18,9 +18,9 @@ namespace SkSL { * always eventually replaced by Constructors in valid programs. */ struct TypeReference : public Expression { - TypeReference(const Context& context, int offset, const Type& type) + TypeReference(const Context& context, int offset, const Type& value) : INHERITED(offset, kTypeReference_Kind, *context.fInvalid_Type) - , fValue(type) {} + , fValue(value) {} bool hasSideEffects() const override { return false; @@ -30,9 +30,18 @@ struct TypeReference : public Expression { return String(fValue.fName); } + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new TypeReference(fOffset, fValue, &fType)); + } + const Type& fValue; typedef Expression INHERITED; + +private: + TypeReference(int offset, const Type& value, const Type* type) + : INHERITED(offset, kTypeReference_Kind, *type) + , fValue(value) {} }; } // namespace diff --git a/src/sksl/ir/SkSLVarDeclarations.h b/src/sksl/ir/SkSLVarDeclarations.h index 707715f6dc..b98e959ff0 100644 --- a/src/sksl/ir/SkSLVarDeclarations.h +++ b/src/sksl/ir/SkSLVarDeclarations.h @@ -29,7 +29,20 @@ struct VarDeclaration : public Statement { , fSizes(std::move(sizes)) , fValue(std::move(value)) {} - String description() const { + std::unique_ptr<Statement> clone() const override { + std::vector<std::unique_ptr<Expression>> sizesClone; + for (const auto& s : fSizes) { + if (s) { + sizesClone.push_back(s->clone()); + } else { + sizesClone.push_back(nullptr); + } + } + return std::unique_ptr<Statement>(new VarDeclaration(fVar, std::move(sizesClone), + fValue ? fValue->clone() : nullptr)); + } + + String description() const override { String result = fVar->fName; for (const auto& size : fSizes) { if (size) { @@ -64,6 +77,16 @@ struct VarDeclarations : public ProgramElement { } } + std::unique_ptr<ProgramElement> clone() const override { + std::vector<std::unique_ptr<VarDeclaration>> cloned; + for (const auto& v : fVars) { + cloned.push_back(std::unique_ptr<VarDeclaration>( + (VarDeclaration*) v->clone().release())); + } + return std::unique_ptr<ProgramElement>(new VarDeclarations(fOffset, &fBaseType, + std::move(cloned))); + } + String description() const override { if (!fVars.size()) { return String(); diff --git a/src/sksl/ir/SkSLVarDeclarationsStatement.h b/src/sksl/ir/SkSLVarDeclarationsStatement.h index 0258e66c6e..c9c1df175b 100644 --- a/src/sksl/ir/SkSLVarDeclarationsStatement.h +++ b/src/sksl/ir/SkSLVarDeclarationsStatement.h @@ -30,11 +30,16 @@ struct VarDeclarationsStatement : public Statement { return true; } + std::unique_ptr<Statement> clone() const override { + std::unique_ptr<VarDeclarations> cloned((VarDeclarations*) fDeclaration->clone().release()); + return std::unique_ptr<Statement>(new VarDeclarationsStatement(std::move(cloned))); + } + String description() const override { return fDeclaration->description() + ";"; } - std::shared_ptr<VarDeclarations> fDeclaration; + std::unique_ptr<VarDeclarations> fDeclaration; typedef Statement INHERITED; }; diff --git a/src/sksl/ir/SkSLVariableReference.cpp b/src/sksl/ir/SkSLVariableReference.cpp index fa23e4749b..e6092c940c 100644 --- a/src/sksl/ir/SkSLVariableReference.cpp +++ b/src/sksl/ir/SkSLVariableReference.cpp @@ -93,6 +93,11 @@ std::unique_ptr<Expression> VariableReference::constantPropagate(const IRGenerat if (fRefKind != kRead_RefKind) { return nullptr; } + if (irGenerator.fKind == Program::kPipelineStage_Kind && + fVariable.fStorage == Variable::kGlobal_Storage && + (fVariable.fModifiers.fFlags & Modifiers::kIn_Flag)) { + return irGenerator.getArg(fOffset, fVariable.fName); + } if ((fVariable.fModifiers.fFlags & Modifiers::kConst_Flag) && fVariable.fInitialValue && fVariable.fInitialValue->isConstant()) { return copy_constant(irGenerator, fVariable.fInitialValue); diff --git a/src/sksl/ir/SkSLVariableReference.h b/src/sksl/ir/SkSLVariableReference.h index 14ddf796ff..405a5d1f55 100644 --- a/src/sksl/ir/SkSLVariableReference.h +++ b/src/sksl/ir/SkSLVariableReference.h @@ -49,6 +49,10 @@ struct VariableReference : public Expression { return 0 != (fVariable.fModifiers.fFlags & Modifiers::kConst_Flag); } + std::unique_ptr<Expression> clone() const override { + return std::unique_ptr<Expression>(new VariableReference(fOffset, fVariable, fRefKind)); + } + String description() const override { return fVariable.fName; } diff --git a/src/sksl/ir/SkSLWhileStatement.h b/src/sksl/ir/SkSLWhileStatement.h index aed6494999..6695875c03 100644 --- a/src/sksl/ir/SkSLWhileStatement.h +++ b/src/sksl/ir/SkSLWhileStatement.h @@ -23,6 +23,11 @@ struct WhileStatement : public Statement { , fTest(std::move(test)) , fStatement(std::move(statement)) {} + std::unique_ptr<Statement> clone() const override { + return std::unique_ptr<Statement>(new WhileStatement(fOffset, fTest->clone(), + fStatement->clone())); + } + String description() const override { return "while (" + fTest->description() + ") " + fStatement->description(); } |