1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SKSL_COMPILER 9 #define SKSL_COMPILER 10 11 #include <set> 12 #include <unordered_set> 13 #include <vector> 14 #include "ir/SkSLProgram.h" 15 #include "ir/SkSLSymbolTable.h" 16 #include "SkSLCFGGenerator.h" 17 #include "SkSLContext.h" 18 #include "SkSLErrorReporter.h" 19 #include "SkSLLexer.h" 20 21 #define SK_FRAGCOLOR_BUILTIN 10001 22 #define SK_IN_BUILTIN 10002 23 #define SK_INCOLOR_BUILTIN 10003 24 #define SK_OUTCOLOR_BUILTIN 10004 25 #define SK_TRANSFORMEDCOORDS2D_BUILTIN 10005 26 #define SK_TEXTURESAMPLERS_BUILTIN 10006 27 #define SK_FRAGCOORD_BUILTIN 15 28 #define SK_VERTEXID_BUILTIN 42 29 #define SK_INSTANCEID_BUILTIN 43 30 #define SK_CLIPDISTANCE_BUILTIN 3 31 #define SK_INVOCATIONID_BUILTIN 8 32 #define SK_POSITION_BUILTIN 0 33 34 namespace SkSL { 35 36 class IRGenerator; 37 38 /** 39 * Main compiler entry point. This is a traditional compiler design which first parses the .sksl 40 * file into an abstract syntax tree (a tree of ASTNodes), then performs semantic analysis to 41 * produce a Program (a tree of IRNodes), then feeds the Program into a CodeGenerator to produce 42 * compiled output. 43 * 44 * See the README for information about SkSL. 45 */ 46 class Compiler : public ErrorReporter { 47 public: 48 static constexpr const char* RTADJUST_NAME = "sk_RTAdjust"; 49 static constexpr const char* PERVERTEX_NAME = "sk_PerVertex"; 50 51 enum Flags { 52 kNone_Flags = 0, 53 // permits static if/switch statements to be used with non-constant tests. This is used when 54 // producing H and CPP code; the static tests don't have to have constant values *yet*, but 55 // the generated code will contain a static test which then does have to be a constant. 56 kPermitInvalidStaticTests_Flag = 1, 57 }; 58 59 Compiler(Flags flags = kNone_Flags); 60 61 ~Compiler() override; 62 63 std::unique_ptr<Program> convertProgram(Program::Kind kind, String text, 64 const Program::Settings& settings); 65 66 bool toSPIRV(const Program& program, OutputStream& out); 67 68 bool toSPIRV(const Program& program, String* out); 69 70 bool toGLSL(const Program& program, OutputStream& out); 71 72 bool toGLSL(const Program& program, String* out); 73 74 bool toMetal(const Program& program, OutputStream& out); 75 76 bool toCPP(const Program& program, String name, OutputStream& out); 77 78 bool toH(const Program& program, String name, OutputStream& out); 79 80 void error(int offset, String msg) override; 81 82 String errorText(); 83 84 void writeErrorCount(); 85 86 int errorCount() override { 87 return fErrorCount; 88 } 89 90 static const char* OperatorName(Token::Kind token); 91 92 static bool IsAssignment(Token::Kind token); 93 94 private: 95 void addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr, 96 DefinitionMap* definitions); 97 98 void addDefinitions(const BasicBlock::Node& node, DefinitionMap* definitions); 99 100 void scanCFG(CFG* cfg, BlockId block, std::set<BlockId>* workList); 101 102 void computeDataFlow(CFG* cfg); 103 104 /** 105 * Simplifies the expression pointed to by iter (in both the IR and CFG structures), if 106 * possible. 107 */ 108 void simplifyExpression(DefinitionMap& definitions, 109 BasicBlock& b, 110 std::vector<BasicBlock::Node>::iterator* iter, 111 std::unordered_set<const Variable*>* undefinedVariables, 112 bool* outUpdated, 113 bool* outNeedsRescan); 114 115 /** 116 * Simplifies the statement pointed to by iter (in both the IR and CFG structures), if 117 * possible. 118 */ 119 void simplifyStatement(DefinitionMap& definitions, 120 BasicBlock& b, 121 std::vector<BasicBlock::Node>::iterator* iter, 122 std::unordered_set<const Variable*>* undefinedVariables, 123 bool* outUpdated, 124 bool* outNeedsRescan); 125 126 void scanCFG(FunctionDefinition& f); 127 128 Position position(int offset); 129 130 std::shared_ptr<SymbolTable> fTypes; 131 IRGenerator* fIRGenerator; 132 String fSkiaVertText; // FIXME store parsed version instead 133 int fFlags; 134 135 const String* fSource; 136 Context fContext; 137 int fErrorCount; 138 String fErrorText; 139 }; 140 141 } // namespace 142 143 #endif 144