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_OUT_BUILTIN 10007 28 #define SK_LASTFRAGCOLOR_BUILTIN 10008 29 #define SK_MAIN_X_BUILTIN 10009 30 #define SK_MAIN_Y_BUILTIN 10010 31 #define SK_WIDTH_BUILTIN 10011 32 #define SK_HEIGHT_BUILTIN 10012 33 #define SK_FRAGCOORD_BUILTIN 15 34 #define SK_CLOCKWISE_BUILTIN 17 35 #define SK_VERTEXID_BUILTIN 42 36 #define SK_INSTANCEID_BUILTIN 43 37 #define SK_CLIPDISTANCE_BUILTIN 3 38 #define SK_INVOCATIONID_BUILTIN 8 39 #define SK_POSITION_BUILTIN 0 40 41 namespace SkSL { 42 43 class IRGenerator; 44 45 /** 46 * Main compiler entry point. This is a traditional compiler design which first parses the .sksl 47 * file into an abstract syntax tree (a tree of ASTNodes), then performs semantic analysis to 48 * produce a Program (a tree of IRNodes), then feeds the Program into a CodeGenerator to produce 49 * compiled output. 50 * 51 * See the README for information about SkSL. 52 */ 53 class Compiler : public ErrorReporter { 54 public: 55 static constexpr const char* RTADJUST_NAME = "sk_RTAdjust"; 56 static constexpr const char* PERVERTEX_NAME = "sk_PerVertex"; 57 58 enum Flags { 59 kNone_Flags = 0, 60 // permits static if/switch statements to be used with non-constant tests. This is used when 61 // producing H and CPP code; the static tests don't have to have constant values *yet*, but 62 // the generated code will contain a static test which then does have to be a constant. 63 kPermitInvalidStaticTests_Flag = 1, 64 }; 65 66 struct FormatArg { 67 enum class Kind { 68 kInput, 69 kOutput, 70 kUniform, 71 kChildProcessor 72 }; 73 FormatArgFormatArg74 FormatArg(Kind kind) 75 : fKind(kind) {} 76 FormatArgFormatArg77 FormatArg(Kind kind, int index) 78 : fKind(kind) 79 , fIndex(index) {} 80 81 Kind fKind; 82 83 int fIndex; 84 }; 85 86 Compiler(Flags flags = kNone_Flags); 87 88 ~Compiler() override; 89 90 std::unique_ptr<Program> convertProgram(Program::Kind kind, String text, 91 const Program::Settings& settings); 92 93 bool optimize(Program& program); 94 95 std::unique_ptr<Program> specialize(Program& program, 96 const std::unordered_map<SkSL::String, SkSL::Program::Settings::Value>& inputs); 97 98 bool toSPIRV(Program& program, OutputStream& out); 99 100 bool toSPIRV(Program& program, String* out); 101 102 bool toGLSL(Program& program, OutputStream& out); 103 104 bool toGLSL(Program& program, String* out); 105 106 bool toMetal(Program& program, OutputStream& out); 107 108 bool toMetal(Program& program, String* out); 109 110 bool toCPP(Program& program, String name, OutputStream& out); 111 112 bool toH(Program& program, String name, OutputStream& out); 113 114 bool toPipelineStage(const Program& program, String* out, 115 std::vector<FormatArg>* outFormatArgs); 116 117 void error(int offset, String msg) override; 118 119 String errorText(); 120 121 void writeErrorCount(); 122 errorCount()123 int errorCount() override { 124 return fErrorCount; 125 } 126 context()127 Context& context() { 128 return *fContext; 129 } 130 131 static const char* OperatorName(Token::Kind token); 132 133 static bool IsAssignment(Token::Kind token); 134 135 private: 136 void addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr, 137 DefinitionMap* definitions); 138 139 void addDefinitions(const BasicBlock::Node& node, DefinitionMap* definitions); 140 141 void scanCFG(CFG* cfg, BlockId block, std::set<BlockId>* workList); 142 143 void computeDataFlow(CFG* cfg); 144 145 /** 146 * Simplifies the expression pointed to by iter (in both the IR and CFG structures), if 147 * possible. 148 */ 149 void simplifyExpression(DefinitionMap& definitions, 150 BasicBlock& b, 151 std::vector<BasicBlock::Node>::iterator* iter, 152 std::unordered_set<const Variable*>* undefinedVariables, 153 bool* outUpdated, 154 bool* outNeedsRescan); 155 156 /** 157 * Simplifies the statement pointed to by iter (in both the IR and CFG structures), if 158 * possible. 159 */ 160 void simplifyStatement(DefinitionMap& definitions, 161 BasicBlock& b, 162 std::vector<BasicBlock::Node>::iterator* iter, 163 std::unordered_set<const Variable*>* undefinedVariables, 164 bool* outUpdated, 165 bool* outNeedsRescan); 166 167 void scanCFG(FunctionDefinition& f); 168 169 Position position(int offset); 170 171 std::vector<std::unique_ptr<ProgramElement>> fVertexInclude; 172 std::shared_ptr<SymbolTable> fVertexSymbolTable; 173 std::vector<std::unique_ptr<ProgramElement>> fFragmentInclude; 174 std::shared_ptr<SymbolTable> fFragmentSymbolTable; 175 std::vector<std::unique_ptr<ProgramElement>> fGeometryInclude; 176 std::shared_ptr<SymbolTable> fGeometrySymbolTable; 177 178 std::shared_ptr<SymbolTable> fTypes; 179 IRGenerator* fIRGenerator; 180 int fFlags; 181 182 const String* fSource; 183 std::shared_ptr<Context> fContext; 184 int fErrorCount; 185 String fErrorText; 186 }; 187 188 } // namespace 189 190 #endif 191