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 54namespace SkSL { 55 56/** 57 * Performs semantic analysis on an abstract syntax tree (AST) and produces the corresponding 58 * (unoptimized) intermediate representation (IR). 59 */ 60class IRGenerator { 61public: 62 IRGenerator(const Context* context, std::shared_ptr<SymbolTable> root, 63 ErrorReporter& errorReporter); 64 65 void convertProgram(Program::Kind kind, 66 const char* text, 67 size_t length, 68 SymbolTable& types, 69 std::vector<std::unique_ptr<ProgramElement>>* result); 70 71 /** 72 * If both operands are compile-time constants and can be folded, returns an expression 73 * representing the folded value. Otherwise, returns null. Note that unlike most other functions 74 * here, null does not represent a compilation error. 75 */ 76 std::unique_ptr<Expression> constantFold(const Expression& left, 77 Token::Kind op, 78 const Expression& right) const; 79 Program::Inputs fInputs; 80 const Program::Settings* fSettings; 81 const Context& fContext; 82 83private: 84 /** 85 * Prepare to compile a program. Resets state, pushes a new symbol table, and installs the 86 * settings. 87 */ 88 void start(const Program::Settings* settings); 89 90 /** 91 * Performs cleanup after compilation is complete. 92 */ 93 void finish(); 94 95 void pushSymbolTable(); 96 void popSymbolTable(); 97 98 std::unique_ptr<VarDeclarations> convertVarDeclarations(const ASTVarDeclarations& decl, 99 Variable::Storage storage); 100 void convertFunction(const ASTFunction& f); 101 std::unique_ptr<Statement> convertStatement(const ASTStatement& statement); 102 std::unique_ptr<Expression> convertExpression(const ASTExpression& expression); 103 std::unique_ptr<ModifiersDeclaration> convertModifiersDeclaration( 104 const ASTModifiersDeclaration& m); 105 106 const Type* convertType(const ASTType& type); 107 std::unique_ptr<Expression> call(int offset, 108 const FunctionDeclaration& function, 109 std::vector<std::unique_ptr<Expression>> arguments); 110 int callCost(const FunctionDeclaration& function, 111 const std::vector<std::unique_ptr<Expression>>& arguments); 112 std::unique_ptr<Expression> call(int offset, std::unique_ptr<Expression> function, 113 std::vector<std::unique_ptr<Expression>> arguments); 114 int coercionCost(const Expression& expr, const Type& type); 115 std::unique_ptr<Expression> coerce(std::unique_ptr<Expression> expr, const Type& type); 116 std::unique_ptr<Block> convertBlock(const ASTBlock& block); 117 std::unique_ptr<Statement> convertBreak(const ASTBreakStatement& b); 118 std::unique_ptr<Expression> convertNumberConstructor( 119 int offset, 120 const Type& type, 121 std::vector<std::unique_ptr<Expression>> params); 122 std::unique_ptr<Expression> convertCompoundConstructor( 123 int offset, 124 const Type& type, 125 std::vector<std::unique_ptr<Expression>> params); 126 std::unique_ptr<Expression> convertConstructor(int offset, 127 const Type& type, 128 std::vector<std::unique_ptr<Expression>> params); 129 std::unique_ptr<Statement> convertContinue(const ASTContinueStatement& c); 130 std::unique_ptr<Statement> convertDiscard(const ASTDiscardStatement& d); 131 std::unique_ptr<Statement> convertDo(const ASTDoStatement& d); 132 std::unique_ptr<Statement> convertSwitch(const ASTSwitchStatement& s); 133 std::unique_ptr<Expression> convertBinaryExpression(const ASTBinaryExpression& expression); 134 std::unique_ptr<Extension> convertExtension(const ASTExtension& e); 135 std::unique_ptr<Statement> convertExpressionStatement(const ASTExpressionStatement& s); 136 std::unique_ptr<Statement> convertFor(const ASTForStatement& f); 137 std::unique_ptr<Expression> convertIdentifier(const ASTIdentifier& identifier); 138 std::unique_ptr<Statement> convertIf(const ASTIfStatement& s); 139 std::unique_ptr<Expression> convertIndex(std::unique_ptr<Expression> base, 140 const ASTExpression& index); 141 std::unique_ptr<InterfaceBlock> convertInterfaceBlock(const ASTInterfaceBlock& s); 142 Modifiers convertModifiers(const Modifiers& m); 143 std::unique_ptr<Expression> convertPrefixExpression(const ASTPrefixExpression& expression); 144 std::unique_ptr<Statement> convertReturn(const ASTReturnStatement& r); 145 std::unique_ptr<Section> convertSection(const ASTSection& e); 146 std::unique_ptr<Expression> getCap(int offset, String name); 147 std::unique_ptr<Expression> getArg(int offset, String name); 148 std::unique_ptr<Expression> convertSuffixExpression(const ASTSuffixExpression& expression); 149 std::unique_ptr<Expression> convertTypeField(int offset, const Type& type, 150 StringFragment field); 151 std::unique_ptr<Expression> convertField(std::unique_ptr<Expression> base, 152 StringFragment field); 153 std::unique_ptr<Expression> convertSwizzle(std::unique_ptr<Expression> base, 154 StringFragment fields); 155 std::unique_ptr<Expression> convertTernaryExpression(const ASTTernaryExpression& expression); 156 std::unique_ptr<Statement> convertVarDeclarationStatement(const ASTVarDeclarationStatement& s); 157 std::unique_ptr<Statement> convertWhile(const ASTWhileStatement& w); 158 void convertEnum(const ASTEnum& e); 159 std::unique_ptr<Block> applyInvocationIDWorkaround(std::unique_ptr<Block> main); 160 // returns a statement which converts sk_Position from device to normalized coordinates 161 std::unique_ptr<Statement> getNormalizeSkPositionCode(); 162 163 void fixRectSampling(std::vector<std::unique_ptr<Expression>>& arguments); 164 void checkValid(const Expression& expr); 165 void markWrittenTo(const Expression& expr, bool readWrite); 166 void getConstantInt(const Expression& value, int64_t* out); 167 168 Program::Kind fKind; 169 const FunctionDeclaration* fCurrentFunction; 170 std::unordered_map<String, Program::Settings::Value> fCapsMap; 171 std::shared_ptr<SymbolTable> fRootSymbolTable; 172 std::shared_ptr<SymbolTable> fSymbolTable; 173 // holds extra temp variable declarations needed for the current function 174 std::vector<std::unique_ptr<Statement>> fExtraVars; 175 int fLoopLevel; 176 int fSwitchLevel; 177 // count of temporary variables we have created 178 int fTmpCount; 179 ErrorReporter& fErrors; 180 int fInvocations; 181 std::vector<std::unique_ptr<ProgramElement>>* fProgramElements; 182 Variable* fSkPerVertex; 183 Variable* fRTAdjust; 184 Variable* fRTAdjustInterfaceBlock; 185 int fRTAdjustFieldIndex; 186 187 friend class AutoSymbolTable; 188 friend class AutoLoopLevel; 189 friend class AutoSwitchLevel; 190 friend class Compiler; 191}; 192 193} 194 195#endif 196