blob: cd70278e0354d9d525fb88c20904e6a512bf748d [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -07001/*
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 */
Ethan Nicholas0df1b042017-03-31 13:56:23 -04007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_COMPILER
9#define SKSL_COMPILER
10
ethannicholas22f939e2016-10-13 13:25:34 -070011#include <set>
Ethan Nicholascb670962017-04-20 19:31:52 -040012#include <unordered_set>
ethannicholasb3058bd2016-07-01 08:22:01 -070013#include <vector>
14#include "ir/SkSLProgram.h"
15#include "ir/SkSLSymbolTable.h"
ethannicholas22f939e2016-10-13 13:25:34 -070016#include "SkSLCFGGenerator.h"
ethannicholasd598f792016-07-25 10:08:54 -070017#include "SkSLContext.h"
ethannicholasb3058bd2016-07-01 08:22:01 -070018#include "SkSLErrorReporter.h"
Ethan Nicholasf7b88202017-09-18 14:10:39 -040019#include "SkSLLexer.h"
ethannicholasb3058bd2016-07-01 08:22:01 -070020
Ethan Nicholas762466e2017-06-29 10:03:38 -040021#define SK_FRAGCOLOR_BUILTIN 10001
22#define SK_IN_BUILTIN 10002
23#define SK_INCOLOR_BUILTIN 10003
24#define SK_OUTCOLOR_BUILTIN 10004
25#define SK_TRANSFORMEDCOORDS2D_BUILTIN 10005
26#define SK_TEXTURESAMPLERS_BUILTIN 10006
Ethan Nicholas16c11962018-03-16 12:20:54 -040027#define SK_OUT_BUILTIN 10007
Ethan Nicholaseab2baa2018-04-13 15:16:27 -040028#define SK_LASTFRAGCOLOR_BUILTIN 10008
Ethan Nicholas00543112018-07-31 09:44:36 -040029#define SK_MAIN_X_BUILTIN 10009
30#define SK_MAIN_Y_BUILTIN 10010
Ethan Nicholascd700e92018-08-24 16:43:57 -040031#define SK_WIDTH_BUILTIN 10011
32#define SK_HEIGHT_BUILTIN 10012
Ethan Nicholas762466e2017-06-29 10:03:38 -040033#define SK_FRAGCOORD_BUILTIN 15
Chris Dalton49d14e92018-07-27 12:38:35 -060034#define SK_CLOCKWISE_BUILTIN 17
Ethan Nicholas9eded2c2018-03-22 10:10:44 -040035#define SK_VERTEXID_BUILTIN 42
36#define SK_INSTANCEID_BUILTIN 43
Ethan Nicholas762466e2017-06-29 10:03:38 -040037#define SK_CLIPDISTANCE_BUILTIN 3
38#define SK_INVOCATIONID_BUILTIN 8
Ethan Nicholascc305772017-10-13 16:17:45 -040039#define SK_POSITION_BUILTIN 0
ethannicholas5961bc92016-10-12 06:39:56 -070040
ethannicholasb3058bd2016-07-01 08:22:01 -070041namespace SkSL {
42
43class IRGenerator;
44
45/**
46 * Main compiler entry point. This is a traditional compiler design which first parses the .sksl
Ethan Nicholas941e7e22016-12-12 15:33:30 -050047 * file into an abstract syntax tree (a tree of ASTNodes), then performs semantic analysis to
ethannicholasb3058bd2016-07-01 08:22:01 -070048 * produce a Program (a tree of IRNodes), then feeds the Program into a CodeGenerator to produce
49 * compiled output.
ethannicholas5961bc92016-10-12 06:39:56 -070050 *
51 * See the README for information about SkSL.
ethannicholasb3058bd2016-07-01 08:22:01 -070052 */
53class Compiler : public ErrorReporter {
54public:
Robert Phillipsfe8da172018-01-24 14:52:02 +000055 static constexpr const char* RTADJUST_NAME = "sk_RTAdjust";
56 static constexpr const char* PERVERTEX_NAME = "sk_PerVertex";
57
Ethan Nicholas6e1cbc02017-07-14 10:12:15 -040058 enum Flags {
59 kNone_Flags = 0,
60 // permits static if/switch statements to be used with non-constant tests. This is used when
61 // producing H and CPP code; the static tests don't have to have constant values *yet*, but
62 // the generated code will contain a static test which then does have to be a constant.
63 kPermitInvalidStaticTests_Flag = 1,
64 };
65
Ethan Nicholasce008112018-08-30 09:19:50 -040066 struct FormatArg {
67 enum class Kind {
68 kInput,
69 kOutput,
70 kUniform,
71 kChildProcessor
72 };
73
74 FormatArg(Kind kind)
75 : fKind(kind) {}
76
77 FormatArg(Kind kind, int index)
78 : fKind(kind)
79 , fIndex(index) {}
80
81 Kind fKind;
82
83 int fIndex;
Ethan Nicholas00543112018-07-31 09:44:36 -040084 };
85
Ethan Nicholas6e1cbc02017-07-14 10:12:15 -040086 Compiler(Flags flags = kNone_Flags);
ethannicholasb3058bd2016-07-01 08:22:01 -070087
Brian Salomond3b65972017-03-22 12:05:03 -040088 ~Compiler() override;
ethannicholasb3058bd2016-07-01 08:22:01 -070089
Ethan Nicholas0df1b042017-03-31 13:56:23 -040090 std::unique_ptr<Program> convertProgram(Program::Kind kind, String text,
Ethan Nicholas941e7e22016-12-12 15:33:30 -050091 const Program::Settings& settings);
ethannicholasb3058bd2016-07-01 08:22:01 -070092
Ethan Nicholas00543112018-07-31 09:44:36 -040093 bool optimize(Program& program);
ethannicholasf789b382016-08-03 12:43:36 -070094
Ethan Nicholas00543112018-07-31 09:44:36 -040095 std::unique_ptr<Program> specialize(Program& program,
96 const std::unordered_map<SkSL::String, SkSL::Program::Settings::Value>& inputs);
Ethan Nicholas941e7e22016-12-12 15:33:30 -050097
Ethan Nicholas00543112018-07-31 09:44:36 -040098 bool toSPIRV(Program& program, OutputStream& out);
Ethan Nicholas941e7e22016-12-12 15:33:30 -050099
Ethan Nicholas00543112018-07-31 09:44:36 -0400100 bool toSPIRV(Program& program, String* out);
ethannicholasb3058bd2016-07-01 08:22:01 -0700101
Ethan Nicholas00543112018-07-31 09:44:36 -0400102 bool toGLSL(Program& program, OutputStream& out);
Ethan Nicholascc305772017-10-13 16:17:45 -0400103
Ethan Nicholas00543112018-07-31 09:44:36 -0400104 bool toGLSL(Program& program, String* out);
Timothy Liangb8eeb802018-07-23 16:46:16 -0400105
Ethan Nicholas00543112018-07-31 09:44:36 -0400106 bool toMetal(Program& program, OutputStream& out);
Ethan Nicholas762466e2017-06-29 10:03:38 -0400107
Ethan Nicholas00543112018-07-31 09:44:36 -0400108 bool toMetal(Program& program, String* out);
109
110 bool toCPP(Program& program, String name, OutputStream& out);
111
112 bool toH(Program& program, String name, OutputStream& out);
113
114 bool toPipelineStage(const Program& program, String* out,
115 std::vector<FormatArg>* outFormatArgs);
Ethan Nicholas762466e2017-06-29 10:03:38 -0400116
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700117 void error(int offset, String msg) override;
ethannicholasb3058bd2016-07-01 08:22:01 -0700118
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400119 String errorText();
ethannicholasb3058bd2016-07-01 08:22:01 -0700120
121 void writeErrorCount();
122
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500123 int errorCount() override {
124 return fErrorCount;
125 }
126
Ethan Nicholas26a9aad2018-03-27 14:10:52 -0400127 Context& context() {
128 return *fContext;
129 }
130
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700131 static const char* OperatorName(Token::Kind token);
132
133 static bool IsAssignment(Token::Kind token);
134
ethannicholasb3058bd2016-07-01 08:22:01 -0700135private:
Ethan Nicholas86a43402017-01-19 13:32:00 -0500136 void addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr,
137 DefinitionMap* definitions);
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500138
Ethan Nicholas86a43402017-01-19 13:32:00 -0500139 void addDefinitions(const BasicBlock::Node& node, DefinitionMap* definitions);
ethannicholas22f939e2016-10-13 13:25:34 -0700140
141 void scanCFG(CFG* cfg, BlockId block, std::set<BlockId>* workList);
142
Ethan Nicholascb670962017-04-20 19:31:52 -0400143 void computeDataFlow(CFG* cfg);
144
145 /**
146 * Simplifies the expression pointed to by iter (in both the IR and CFG structures), if
147 * possible.
148 */
149 void simplifyExpression(DefinitionMap& definitions,
150 BasicBlock& b,
151 std::vector<BasicBlock::Node>::iterator* iter,
152 std::unordered_set<const Variable*>* undefinedVariables,
153 bool* outUpdated,
154 bool* outNeedsRescan);
155
156 /**
157 * Simplifies the statement pointed to by iter (in both the IR and CFG structures), if
158 * possible.
159 */
160 void simplifyStatement(DefinitionMap& definitions,
161 BasicBlock& b,
162 std::vector<BasicBlock::Node>::iterator* iter,
163 std::unordered_set<const Variable*>* undefinedVariables,
164 bool* outUpdated,
165 bool* outNeedsRescan);
166
167 void scanCFG(FunctionDefinition& f);
ethannicholasb3058bd2016-07-01 08:22:01 -0700168
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700169 Position position(int offset);
170
Ethan Nicholas3c6ae622018-04-24 13:06:09 -0400171 std::vector<std::unique_ptr<ProgramElement>> fVertexInclude;
172 std::shared_ptr<SymbolTable> fVertexSymbolTable;
173 std::vector<std::unique_ptr<ProgramElement>> fFragmentInclude;
174 std::shared_ptr<SymbolTable> fFragmentSymbolTable;
175 std::vector<std::unique_ptr<ProgramElement>> fGeometryInclude;
176 std::shared_ptr<SymbolTable> fGeometrySymbolTable;
177
ethannicholasb3058bd2016-07-01 08:22:01 -0700178 std::shared_ptr<SymbolTable> fTypes;
179 IRGenerator* fIRGenerator;
Ethan Nicholas6e1cbc02017-07-14 10:12:15 -0400180 int fFlags;
ethannicholasb3058bd2016-07-01 08:22:01 -0700181
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700182 const String* fSource;
Ethan Nicholas26a9aad2018-03-27 14:10:52 -0400183 std::shared_ptr<Context> fContext;
ethannicholasb3058bd2016-07-01 08:22:01 -0700184 int fErrorCount;
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400185 String fErrorText;
ethannicholasb3058bd2016-07-01 08:22:01 -0700186};
187
188} // namespace
189
190#endif