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