Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: src/sksl/SkSLIRGenerator.cpp

Issue 2405383003: added basic dataflow analysis to skslc (Closed)
Patch Set: various fixes Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkSLIRGenerator.h" 8 #include "SkSLIRGenerator.h"
9 9
10 #include "limits.h" 10 #include "limits.h"
(...skipping 24 matching lines...) Expand all
35 #include "ir/SkSLInterfaceBlock.h" 35 #include "ir/SkSLInterfaceBlock.h"
36 #include "ir/SkSLIntLiteral.h" 36 #include "ir/SkSLIntLiteral.h"
37 #include "ir/SkSLLayout.h" 37 #include "ir/SkSLLayout.h"
38 #include "ir/SkSLPostfixExpression.h" 38 #include "ir/SkSLPostfixExpression.h"
39 #include "ir/SkSLPrefixExpression.h" 39 #include "ir/SkSLPrefixExpression.h"
40 #include "ir/SkSLReturnStatement.h" 40 #include "ir/SkSLReturnStatement.h"
41 #include "ir/SkSLSwizzle.h" 41 #include "ir/SkSLSwizzle.h"
42 #include "ir/SkSLTernaryExpression.h" 42 #include "ir/SkSLTernaryExpression.h"
43 #include "ir/SkSLUnresolvedFunction.h" 43 #include "ir/SkSLUnresolvedFunction.h"
44 #include "ir/SkSLVariable.h" 44 #include "ir/SkSLVariable.h"
45 #include "ir/SkSLVarDeclaration.h" 45 #include "ir/SkSLVarDeclarations.h"
46 #include "ir/SkSLVarDeclarationStatement.h" 46 #include "ir/SkSLVarDeclarationsStatement.h"
47 #include "ir/SkSLVariableReference.h" 47 #include "ir/SkSLVariableReference.h"
48 #include "ir/SkSLWhileStatement.h" 48 #include "ir/SkSLWhileStatement.h"
49 49
50 namespace SkSL { 50 namespace SkSL {
51 51
52 class AutoSymbolTable { 52 class AutoSymbolTable {
53 public: 53 public:
54 AutoSymbolTable(IRGenerator* ir) 54 AutoSymbolTable(IRGenerator* ir)
55 : fIR(ir) 55 : fIR(ir)
56 , fPrevious(fIR->fSymbolTable) { 56 , fPrevious(fIR->fSymbolTable) {
57 fIR->pushSymbolTable(); 57 fIR->pushSymbolTable();
58 } 58 }
59 59
60 ~AutoSymbolTable() { 60 ~AutoSymbolTable() {
61 fIR->popSymbolTable(); 61 fIR->popSymbolTable();
62 ASSERT(fPrevious == fIR->fSymbolTable); 62 ASSERT(fPrevious == fIR->fSymbolTable);
63 } 63 }
64 64
65 IRGenerator* fIR; 65 IRGenerator* fIR;
66 std::shared_ptr<SymbolTable> fPrevious; 66 std::shared_ptr<SymbolTable> fPrevious;
67 }; 67 };
68 68
69 class AutoLoopLevel {
70 public:
71 AutoLoopLevel(IRGenerator* ir)
72 : fIR(ir) {
73 fIR->fLoopLevel++;
74 }
75
76 ~AutoLoopLevel() {
77 fIR->fLoopLevel--;
78 }
79
80 IRGenerator* fIR;
81 };
82
69 IRGenerator::IRGenerator(const Context* context, std::shared_ptr<SymbolTable> sy mbolTable, 83 IRGenerator::IRGenerator(const Context* context, std::shared_ptr<SymbolTable> sy mbolTable,
70 ErrorReporter& errorReporter) 84 ErrorReporter& errorReporter)
71 : fContext(*context) 85 : fContext(*context)
72 , fCurrentFunction(nullptr) 86 , fCurrentFunction(nullptr)
73 , fSymbolTable(std::move(symbolTable)) 87 , fSymbolTable(std::move(symbolTable))
88 , fLoopLevel(0)
74 , fErrors(errorReporter) {} 89 , fErrors(errorReporter) {}
75 90
76 void IRGenerator::pushSymbolTable() { 91 void IRGenerator::pushSymbolTable() {
77 fSymbolTable.reset(new SymbolTable(std::move(fSymbolTable), fErrors)); 92 fSymbolTable.reset(new SymbolTable(std::move(fSymbolTable), fErrors));
78 } 93 }
79 94
80 void IRGenerator::popSymbolTable() { 95 void IRGenerator::popSymbolTable() {
81 fSymbolTable = fSymbolTable->fParent; 96 fSymbolTable = fSymbolTable->fParent;
82 } 97 }
83 98
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 ifFalse = this->convertStatement(*s.fIfFalse); 243 ifFalse = this->convertStatement(*s.fIfFalse);
229 if (!ifFalse) { 244 if (!ifFalse) {
230 return nullptr; 245 return nullptr;
231 } 246 }
232 } 247 }
233 return std::unique_ptr<Statement>(new IfStatement(s.fPosition, std::move(tes t), 248 return std::unique_ptr<Statement>(new IfStatement(s.fPosition, std::move(tes t),
234 std::move(ifTrue), std::mo ve(ifFalse))); 249 std::move(ifTrue), std::mo ve(ifFalse)));
235 } 250 }
236 251
237 std::unique_ptr<Statement> IRGenerator::convertFor(const ASTForStatement& f) { 252 std::unique_ptr<Statement> IRGenerator::convertFor(const ASTForStatement& f) {
253 AutoLoopLevel level(this);
238 AutoSymbolTable table(this); 254 AutoSymbolTable table(this);
239 std::unique_ptr<Statement> initializer = this->convertStatement(*f.fInitiali zer); 255 std::unique_ptr<Statement> initializer;
240 if (!initializer) { 256 if (f.fInitializer) {
241 return nullptr; 257 initializer = this->convertStatement(*f.fInitializer);
258 if (!initializer) {
259 return nullptr;
260 }
261 } else {
262 initializer = nullptr;
dogben 2016/10/13 03:55:43 nit: unneeded x3
ethannicholas 2016/10/13 17:41:27 Fixed.
242 } 263 }
243 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*f.f Test), 264 std::unique_ptr<Expression> test;
244 *fContext.fBool_Type); 265 if (f.fTest) {
245 if (!test) { 266 test = this->coerce(this->convertExpression(*f.fTest), *fContext.fBool_T ype);
246 return nullptr; 267 if (!test) {
268 return nullptr;
269 }
270 } else {
271 test = nullptr;
247 } 272 }
248 std::unique_ptr<Expression> next = this->convertExpression(*f.fNext); 273 std::unique_ptr<Expression> next;
249 if (!next) { 274 if (f.fNext) {
250 return nullptr; 275 next = this->convertExpression(*f.fNext);
276 if (!next) {
277 return nullptr;
278 }
279 this->checkValid(*next);
280 } else {
281 next = nullptr;
251 } 282 }
252 this->checkValid(*next);
253 std::unique_ptr<Statement> statement = this->convertStatement(*f.fStatement) ; 283 std::unique_ptr<Statement> statement = this->convertStatement(*f.fStatement) ;
254 if (!statement) { 284 if (!statement) {
255 return nullptr; 285 return nullptr;
256 } 286 }
257 return std::unique_ptr<Statement>(new ForStatement(f.fPosition, std::move(in itializer), 287 return std::unique_ptr<Statement>(new ForStatement(f.fPosition, std::move(in itializer),
258 std::move(test), std::mov e(next), 288 std::move(test), std::mov e(next),
259 std::move(statement), fSy mbolTable)); 289 std::move(statement), fSy mbolTable));
260 } 290 }
261 291
262 std::unique_ptr<Statement> IRGenerator::convertWhile(const ASTWhileStatement& w) { 292 std::unique_ptr<Statement> IRGenerator::convertWhile(const ASTWhileStatement& w) {
293 AutoLoopLevel level(this);
263 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*w.f Test), 294 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*w.f Test),
264 *fContext.fBool_Type); 295 *fContext.fBool_Type);
265 if (!test) { 296 if (!test) {
266 return nullptr; 297 return nullptr;
267 } 298 }
268 std::unique_ptr<Statement> statement = this->convertStatement(*w.fStatement) ; 299 std::unique_ptr<Statement> statement = this->convertStatement(*w.fStatement) ;
269 if (!statement) { 300 if (!statement) {
270 return nullptr; 301 return nullptr;
271 } 302 }
272 return std::unique_ptr<Statement>(new WhileStatement(w.fPosition, std::move( test), 303 return std::unique_ptr<Statement>(new WhileStatement(w.fPosition, std::move( test),
273 std::move(statement))); 304 std::move(statement)));
274 } 305 }
275 306
276 std::unique_ptr<Statement> IRGenerator::convertDo(const ASTDoStatement& d) { 307 std::unique_ptr<Statement> IRGenerator::convertDo(const ASTDoStatement& d) {
308 AutoLoopLevel level(this);
277 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*d.f Test), 309 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*d.f Test),
278 *fContext.fBool_Type); 310 *fContext.fBool_Type);
279 if (!test) { 311 if (!test) {
280 return nullptr; 312 return nullptr;
281 } 313 }
282 std::unique_ptr<Statement> statement = this->convertStatement(*d.fStatement) ; 314 std::unique_ptr<Statement> statement = this->convertStatement(*d.fStatement) ;
283 if (!statement) { 315 if (!statement) {
284 return nullptr; 316 return nullptr;
285 } 317 }
286 return std::unique_ptr<Statement>(new DoStatement(d.fPosition, std::move(sta tement), 318 return std::unique_ptr<Statement>(new DoStatement(d.fPosition, std::move(sta tement),
(...skipping 29 matching lines...) Expand all
316 } else { 348 } else {
317 if (fCurrentFunction->fReturnType != *fContext.fVoid_Type) { 349 if (fCurrentFunction->fReturnType != *fContext.fVoid_Type) {
318 fErrors.error(r.fPosition, "expected function to return '" + 350 fErrors.error(r.fPosition, "expected function to return '" +
319 fCurrentFunction->fReturnType.description () + "'"); 351 fCurrentFunction->fReturnType.description () + "'");
320 } 352 }
321 return std::unique_ptr<Statement>(new ReturnStatement(r.fPosition)); 353 return std::unique_ptr<Statement>(new ReturnStatement(r.fPosition));
322 } 354 }
323 } 355 }
324 356
325 std::unique_ptr<Statement> IRGenerator::convertBreak(const ASTBreakStatement& b) { 357 std::unique_ptr<Statement> IRGenerator::convertBreak(const ASTBreakStatement& b) {
326 return std::unique_ptr<Statement>(new BreakStatement(b.fPosition)); 358 if (fLoopLevel > 0) {
359 return std::unique_ptr<Statement>(new BreakStatement(b.fPosition));
360 } else {
361 fErrors.error(b.fPosition, "break statement must be inside a loop");
362 return nullptr;
363 }
327 } 364 }
328 365
329 std::unique_ptr<Statement> IRGenerator::convertContinue(const ASTContinueStateme nt& c) { 366 std::unique_ptr<Statement> IRGenerator::convertContinue(const ASTContinueStateme nt& c) {
330 return std::unique_ptr<Statement>(new ContinueStatement(c.fPosition)); 367 if (fLoopLevel > 0) {
368 return std::unique_ptr<Statement>(new ContinueStatement(c.fPosition));
369 } else {
370 fErrors.error(c.fPosition, "continue statement must be inside a loop");
371 return nullptr;
372 }
331 } 373 }
332 374
333 std::unique_ptr<Statement> IRGenerator::convertDiscard(const ASTDiscardStatement & d) { 375 std::unique_ptr<Statement> IRGenerator::convertDiscard(const ASTDiscardStatement & d) {
334 return std::unique_ptr<Statement>(new DiscardStatement(d.fPosition)); 376 return std::unique_ptr<Statement>(new DiscardStatement(d.fPosition));
335 } 377 }
336 378
337 static const Type& expand_generics(const Type& type, int i) { 379 static const Type& expand_generics(const Type& type, int i) {
338 if (type.kind() == Type::kGeneric_Kind) { 380 if (type.kind() == Type::kGeneric_Kind) {
339 return *type.coercibleTypes()[i]; 381 return *type.coercibleTypes()[i];
340 } 382 }
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after
1299 case Expression::kIndex_Kind: 1341 case Expression::kIndex_Kind:
1300 this->markWrittenTo(*((IndexExpression&) expr).fBase); 1342 this->markWrittenTo(*((IndexExpression&) expr).fBase);
1301 break; 1343 break;
1302 default: 1344 default:
1303 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio n() + "'"); 1345 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio n() + "'");
1304 break; 1346 break;
1305 } 1347 }
1306 } 1348 }
1307 1349
1308 } 1350 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698