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