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<Block> convertBlock(const ASTNode& block); 99 std::unique_ptr<Statement> convertBreak(const ASTNode& b); 100 std::unique_ptr<Expression> convertNumberConstructor( 101 int offset, 102 const Type& type, 103 std::vector<std::unique_ptr<Expression>> params); 104 std::unique_ptr<Expression> convertCompoundConstructor( 105 int offset, 106 const Type& type, 107 std::vector<std::unique_ptr<Expression>> params); 108 std::unique_ptr<Expression> convertConstructor(int offset, 109 const Type& type, 110 std::vector<std::unique_ptr<Expression>> params); 111 std::unique_ptr<Statement> convertContinue(const ASTNode& c); 112 std::unique_ptr<Statement> convertDiscard(const ASTNode& d); 113 std::unique_ptr<Statement> convertDo(const ASTNode& d); 114 std::unique_ptr<Statement> convertSwitch(const ASTNode& s); 115 std::unique_ptr<Expression> convertBinaryExpression(const ASTNode& expression); 116 std::unique_ptr<Extension> convertExtension(int offset, StringFragment name); 117 std::unique_ptr<Statement> convertExpressionStatement(const ASTNode& s); 118 std::unique_ptr<Statement> convertFor(const ASTNode& f); 119 std::unique_ptr<Expression> convertIdentifier(const ASTNode& identifier); 120 std::unique_ptr<Statement> convertIf(const ASTNode& s); 121 std::unique_ptr<Expression> convertIndex(std::unique_ptr<Expression> base, 122 const ASTNode& index); 123 std::unique_ptr<InterfaceBlock> convertInterfaceBlock(const ASTNode& s); 124 Modifiers convertModifiers(const Modifiers& m); 125 std::unique_ptr<Expression> convertPrefixExpression(const ASTNode& expression); 126 std::unique_ptr<Statement> convertReturn(const ASTNode& r); 127 std::unique_ptr<Section> convertSection(const ASTNode& e); 128 std::unique_ptr<Expression> getCap(int offset, String name); 129 std::unique_ptr<Expression> convertCallExpression(const ASTNode& expression); 130 std::unique_ptr<Expression> convertFieldExpression(const ASTNode& expression); 131 std::unique_ptr<Expression> convertIndexExpression(const ASTNode& expression); 132 std::unique_ptr<Expression> convertPostfixExpression(const ASTNode& expression); 133 std::unique_ptr<Expression> convertTypeField(int offset, const Type& type, 134 StringFragment field); 135 std::unique_ptr<Expression> convertField(std::unique_ptr<Expression> base, 136 StringFragment field); 137 std::unique_ptr<Expression> convertSwizzle(std::unique_ptr<Expression> base, 138 StringFragment fields); 139 std::unique_ptr<Expression> convertTernaryExpression(const ASTNode& expression); 140 std::unique_ptr<Statement> convertVarDeclarationStatement(const ASTNode& s); 141 std::unique_ptr<Statement> convertWhile(const ASTNode& w); 142 void convertEnum(const ASTNode& e); 143 std::unique_ptr<Block> applyInvocationIDWorkaround(std::unique_ptr<Block> main); 144 // returns a statement which converts sk_Position from device to normalized coordinates 145 std::unique_ptr<Statement> getNormalizeSkPositionCode(); 146 147 void checkValid(const Expression& expr); 148 void setRefKind(const Expression& expr, VariableReference::RefKind kind); 149 void getConstantInt(const Expression& value, int64_t* out); 150 bool checkSwizzleWrite(const Swizzle& swizzle); 151 152 std::unique_ptr<ASTFile> fFile; 153 const FunctionDeclaration* fCurrentFunction; 154 std::unordered_map<String, Program::Settings::Value> fCapsMap; 155 std::shared_ptr<SymbolTable> fRootSymbolTable; 156 std::shared_ptr<SymbolTable> fSymbolTable; 157 // holds extra temp variable declarations needed for the current function 158 std::vector<std::unique_ptr<Statement>> fExtraVars; 159 int fLoopLevel; 160 int fSwitchLevel; 161 // count of temporary variables we have created 162 int fTmpCount; 163 ErrorReporter& fErrors; 164 int fInvocations; 165 std::vector<std::unique_ptr<ProgramElement>>* fProgramElements; 166 const Variable* fSkPerVertex = nullptr; 167 Variable* fRTAdjust; 168 Variable* fRTAdjustInterfaceBlock; 169 int fRTAdjustFieldIndex; 170 bool fStarted = false; 171 172 friend class AutoSymbolTable; 173 friend class AutoLoopLevel; 174 friend class AutoSwitchLevel; 175 friend class Compiler; 176 }; 177 178 } 179 180 #endif 181