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_IRGENERATOR 9 #define SKSL_IRGENERATOR 10 11 #include "src/sksl/SkSLASTFile.h" 12 #include "src/sksl/SkSLASTNode.h" 13 #include "src/sksl/SkSLErrorReporter.h" 14 #include "src/sksl/ir/SkSLBlock.h" 15 #include "src/sksl/ir/SkSLExpression.h" 16 #include "src/sksl/ir/SkSLExtension.h" 17 #include "src/sksl/ir/SkSLFunctionDefinition.h" 18 #include "src/sksl/ir/SkSLInterfaceBlock.h" 19 #include "src/sksl/ir/SkSLModifiers.h" 20 #include "src/sksl/ir/SkSLModifiersDeclaration.h" 21 #include "src/sksl/ir/SkSLProgram.h" 22 #include "src/sksl/ir/SkSLSection.h" 23 #include "src/sksl/ir/SkSLStatement.h" 24 #include "src/sksl/ir/SkSLSymbolTable.h" 25 #include "src/sksl/ir/SkSLType.h" 26 #include "src/sksl/ir/SkSLTypeReference.h" 27 #include "src/sksl/ir/SkSLVarDeclarations.h" 28 #include "src/sksl/ir/SkSLVariableReference.h" 29 30 namespace SkSL { 31 32 struct Swizzle; 33 34 /** 35 * Performs semantic analysis on an abstract syntax tree (AST) and produces the corresponding 36 * (unoptimized) intermediate representation (IR). 37 */ 38 class IRGenerator { 39 public: 40 IRGenerator(const Context* context, std::shared_ptr<SymbolTable> root, 41 ErrorReporter& errorReporter); 42 43 void convertProgram(Program::Kind kind, 44 const char* text, 45 size_t length, 46 SymbolTable& types, 47 std::vector<std::unique_ptr<ProgramElement>>* result); 48 49 /** 50 * If both operands are compile-time constants and can be folded, returns an expression 51 * representing the folded value. Otherwise, returns null. Note that unlike most other functions 52 * here, null does not represent a compilation error. 53 */ 54 std::unique_ptr<Expression> constantFold(const Expression& left, 55 Token::Kind op, 56 const Expression& right) const; 57 58 std::unique_ptr<Expression> getArg(int offset, String name) const; 59 60 Program::Inputs fInputs; 61 const Program::Settings* fSettings; 62 const Context& fContext; 63 Program::Kind fKind; 64 65 private: 66 /** 67 * Prepare to compile a program. Resets state, pushes a new symbol table, and installs the 68 * settings. 69 */ 70 void start(const Program::Settings* settings, 71 std::vector<std::unique_ptr<ProgramElement>>* inherited); 72 73 /** 74 * Performs cleanup after compilation is complete. 75 */ 76 void finish(); 77 78 void pushSymbolTable(); 79 void popSymbolTable(); 80 81 std::unique_ptr<VarDeclarations> convertVarDeclarations(const ASTNode& decl, 82 Variable::Storage storage); 83 void convertFunction(const ASTNode& f); 84 std::unique_ptr<Statement> convertStatement(const ASTNode& statement); 85 std::unique_ptr<Expression> convertExpression(const ASTNode& expression); 86 std::unique_ptr<ModifiersDeclaration> convertModifiersDeclaration(const ASTNode& m); 87 88 const Type* convertType(const ASTNode& type); 89 std::unique_ptr<Expression> call(int offset, 90 const FunctionDeclaration& function, 91 std::vector<std::unique_ptr<Expression>> arguments); 92 int callCost(const FunctionDeclaration& function, 93 const std::vector<std::unique_ptr<Expression>>& arguments); 94 std::unique_ptr<Expression> call(int offset, std::unique_ptr<Expression> function, 95 std::vector<std::unique_ptr<Expression>> arguments); 96 int coercionCost(const Expression& expr, const Type& type); 97 std::unique_ptr<Expression> coerce(std::unique_ptr<Expression> expr, const Type& type); 98 std::unique_ptr<Expression> convertAppend(int offset, const std::vector<ASTNode>& args); 99 std::unique_ptr<Block> convertBlock(const ASTNode& block); 100 std::unique_ptr<Statement> convertBreak(const ASTNode& b); 101 std::unique_ptr<Expression> convertNumberConstructor( 102 int offset, 103 const Type& type, 104 std::vector<std::unique_ptr<Expression>> params); 105 std::unique_ptr<Expression> convertCompoundConstructor( 106 int offset, 107 const Type& type, 108 std::vector<std::unique_ptr<Expression>> params); 109 std::unique_ptr<Expression> convertConstructor(int offset, 110 const Type& type, 111 std::vector<std::unique_ptr<Expression>> params); 112 std::unique_ptr<Statement> convertContinue(const ASTNode& c); 113 std::unique_ptr<Statement> convertDiscard(const ASTNode& d); 114 std::unique_ptr<Statement> convertDo(const ASTNode& d); 115 std::unique_ptr<Statement> convertSwitch(const ASTNode& s); 116 std::unique_ptr<Expression> convertBinaryExpression(const ASTNode& expression); 117 std::unique_ptr<Extension> convertExtension(int offset, StringFragment name); 118 std::unique_ptr<Statement> convertExpressionStatement(const ASTNode& s); 119 std::unique_ptr<Statement> convertFor(const ASTNode& f); 120 std::unique_ptr<Expression> convertIdentifier(const ASTNode& identifier); 121 std::unique_ptr<Statement> convertIf(const ASTNode& s); 122 std::unique_ptr<Expression> convertIndex(std::unique_ptr<Expression> base, 123 const ASTNode& index); 124 std::unique_ptr<InterfaceBlock> convertInterfaceBlock(const ASTNode& s); 125 Modifiers convertModifiers(const Modifiers& m); 126 std::unique_ptr<Expression> convertPrefixExpression(const ASTNode& expression); 127 std::unique_ptr<Statement> convertReturn(const ASTNode& r); 128 std::unique_ptr<Section> convertSection(const ASTNode& e); 129 std::unique_ptr<Expression> getCap(int offset, String name); 130 std::unique_ptr<Expression> convertCallExpression(const ASTNode& expression); 131 std::unique_ptr<Expression> convertFieldExpression(const ASTNode& expression); 132 std::unique_ptr<Expression> convertIndexExpression(const ASTNode& expression); 133 std::unique_ptr<Expression> convertPostfixExpression(const ASTNode& expression); 134 std::unique_ptr<Expression> convertTypeField(int offset, const Type& type, 135 StringFragment field); 136 std::unique_ptr<Expression> convertField(std::unique_ptr<Expression> base, 137 StringFragment field); 138 std::unique_ptr<Expression> convertSwizzle(std::unique_ptr<Expression> base, 139 StringFragment fields); 140 std::unique_ptr<Expression> convertTernaryExpression(const ASTNode& expression); 141 std::unique_ptr<Statement> convertVarDeclarationStatement(const ASTNode& s); 142 std::unique_ptr<Statement> convertWhile(const ASTNode& w); 143 void convertEnum(const ASTNode& e); 144 std::unique_ptr<Block> applyInvocationIDWorkaround(std::unique_ptr<Block> main); 145 // returns a statement which converts sk_Position from device to normalized coordinates 146 std::unique_ptr<Statement> getNormalizeSkPositionCode(); 147 148 void checkValid(const Expression& expr); 149 void setRefKind(const Expression& expr, VariableReference::RefKind kind); 150 void getConstantInt(const Expression& value, int64_t* out); 151 bool checkSwizzleWrite(const Swizzle& swizzle); 152 153 std::unique_ptr<ASTFile> fFile; 154 const FunctionDeclaration* fCurrentFunction; 155 std::unordered_map<String, Program::Settings::Value> fCapsMap; 156 std::shared_ptr<SymbolTable> fRootSymbolTable; 157 std::shared_ptr<SymbolTable> fSymbolTable; 158 // holds extra temp variable declarations needed for the current function 159 std::vector<std::unique_ptr<Statement>> fExtraVars; 160 int fLoopLevel; 161 int fSwitchLevel; 162 // count of temporary variables we have created 163 int fTmpCount; 164 ErrorReporter& fErrors; 165 int fInvocations; 166 std::vector<std::unique_ptr<ProgramElement>>* fProgramElements; 167 const Variable* fSkPerVertex = nullptr; 168 Variable* fRTAdjust; 169 Variable* fRTAdjustInterfaceBlock; 170 int fRTAdjustFieldIndex; 171 bool fStarted = false; 172 173 friend class AutoSymbolTable; 174 friend class AutoLoopLevel; 175 friend class AutoSwitchLevel; 176 friend class Compiler; 177 }; 178 179 } 180 181 #endif 182