/* * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SKSL_COMPILER #define SKSL_COMPILER #include #include #include #include "ir/SkSLProgram.h" #include "ir/SkSLSymbolTable.h" #include "SkSLCFGGenerator.h" #include "SkSLContext.h" #include "SkSLErrorReporter.h" #include "SkSLLexer.h" #define SK_FRAGCOLOR_BUILTIN 10001 #define SK_IN_BUILTIN 10002 #define SK_INCOLOR_BUILTIN 10003 #define SK_OUTCOLOR_BUILTIN 10004 #define SK_TRANSFORMEDCOORDS2D_BUILTIN 10005 #define SK_TEXTURESAMPLERS_BUILTIN 10006 #define SK_OUT_BUILTIN 10007 #define SK_LASTFRAGCOLOR_BUILTIN 10008 #define SK_MAIN_X_BUILTIN 10009 #define SK_MAIN_Y_BUILTIN 10010 #define SK_FRAGCOORD_BUILTIN 15 #define SK_CLOCKWISE_BUILTIN 17 #define SK_VERTEXID_BUILTIN 42 #define SK_INSTANCEID_BUILTIN 43 #define SK_CLIPDISTANCE_BUILTIN 3 #define SK_INVOCATIONID_BUILTIN 8 #define SK_POSITION_BUILTIN 0 namespace SkSL { class IRGenerator; /** * Main compiler entry point. This is a traditional compiler design which first parses the .sksl * file into an abstract syntax tree (a tree of ASTNodes), then performs semantic analysis to * produce a Program (a tree of IRNodes), then feeds the Program into a CodeGenerator to produce * compiled output. * * See the README for information about SkSL. */ class Compiler : public ErrorReporter { public: static constexpr const char* RTADJUST_NAME = "sk_RTAdjust"; static constexpr const char* PERVERTEX_NAME = "sk_PerVertex"; enum Flags { kNone_Flags = 0, // permits static if/switch statements to be used with non-constant tests. This is used when // producing H and CPP code; the static tests don't have to have constant values *yet*, but // the generated code will contain a static test which then does have to be a constant. kPermitInvalidStaticTests_Flag = 1, }; enum class FormatArg { kInput, kOutput }; Compiler(Flags flags = kNone_Flags); ~Compiler() override; std::unique_ptr convertProgram(Program::Kind kind, String text, const Program::Settings& settings); bool optimize(Program& program); std::unique_ptr specialize(Program& program, const std::unordered_map& inputs); bool toSPIRV(Program& program, OutputStream& out); bool toSPIRV(Program& program, String* out); bool toGLSL(Program& program, OutputStream& out); bool toGLSL(Program& program, String* out); bool toMetal(Program& program, OutputStream& out); bool toMetal(Program& program, String* out); bool toCPP(Program& program, String name, OutputStream& out); bool toH(Program& program, String name, OutputStream& out); bool toPipelineStage(const Program& program, String* out, std::vector* outFormatArgs); void error(int offset, String msg) override; String errorText(); void writeErrorCount(); int errorCount() override { return fErrorCount; } Context& context() { return *fContext; } static const char* OperatorName(Token::Kind token); static bool IsAssignment(Token::Kind token); private: void addDefinition(const Expression* lvalue, std::unique_ptr* expr, DefinitionMap* definitions); void addDefinitions(const BasicBlock::Node& node, DefinitionMap* definitions); void scanCFG(CFG* cfg, BlockId block, std::set* workList); void computeDataFlow(CFG* cfg); /** * Simplifies the expression pointed to by iter (in both the IR and CFG structures), if * possible. */ void simplifyExpression(DefinitionMap& definitions, BasicBlock& b, std::vector::iterator* iter, std::unordered_set* undefinedVariables, bool* outUpdated, bool* outNeedsRescan); /** * Simplifies the statement pointed to by iter (in both the IR and CFG structures), if * possible. */ void simplifyStatement(DefinitionMap& definitions, BasicBlock& b, std::vector::iterator* iter, std::unordered_set* undefinedVariables, bool* outUpdated, bool* outNeedsRescan); void scanCFG(FunctionDefinition& f); Position position(int offset); std::vector> fVertexInclude; std::shared_ptr fVertexSymbolTable; std::vector> fFragmentInclude; std::shared_ptr fFragmentSymbolTable; std::vector> fGeometryInclude; std::shared_ptr fGeometrySymbolTable; std::shared_ptr fTypes; IRGenerator* fIRGenerator; int fFlags; const String* fSource; std::shared_ptr fContext; int fErrorCount; String fErrorText; }; } // namespace #endif