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 #include "SkSLCompiler.h" 9 10 #include "SkSLCFGGenerator.h" 11 #include "SkSLCPPCodeGenerator.h" 12 #include "SkSLGLSLCodeGenerator.h" 13 #include "SkSLHCodeGenerator.h" 14 #include "SkSLIRGenerator.h" 15 #include "SkSLSPIRVCodeGenerator.h" 16 #include "ir/SkSLExpression.h" 17 #include "ir/SkSLExpressionStatement.h" 18 #include "ir/SkSLIntLiteral.h" 19 #include "ir/SkSLModifiersDeclaration.h" 20 #include "ir/SkSLNop.h" 21 #include "ir/SkSLSymbolTable.h" 22 #include "ir/SkSLTernaryExpression.h" 23 #include "ir/SkSLUnresolvedFunction.h" 24 #include "ir/SkSLVarDeclarations.h" 25 26 #ifdef SK_ENABLE_SPIRV_VALIDATION 27 #include "spirv-tools/libspirv.hpp" 28 #endif 29 30 #define STRINGIFY(x) #x 31 32 // include the built-in shader symbols as static strings 33 34 static const char* SKSL_INCLUDE = 35 #include "sksl.include" 36 ; 37 38 static const char* SKSL_VERT_INCLUDE = 39 #include "sksl_vert.include" 40 ; 41 42 static const char* SKSL_FRAG_INCLUDE = 43 #include "sksl_frag.include" 44 ; 45 46 static const char* SKSL_GEOM_INCLUDE = 47 #include "sksl_geom.include" 48 ; 49 50 static const char* SKSL_FP_INCLUDE = 51 #include "sksl_fp.include" 52 ; 53 54 55 namespace SkSL { 56 57 Compiler::Compiler(Flags flags) 58 : fFlags(flags) 59 , fErrorCount(0) { 60 auto types = std::shared_ptr<SymbolTable>(new SymbolTable(this)); 61 auto symbols = std::shared_ptr<SymbolTable>(new SymbolTable(types, this)); 62 fIRGenerator = new IRGenerator(&fContext, symbols, *this); 63 fTypes = types; 64 #define ADD_TYPE(t) types->addWithoutOwnership(fContext.f ## t ## _Type->fName, \ 65 fContext.f ## t ## _Type.get()) 66 ADD_TYPE(Void); 67 ADD_TYPE(Float); 68 ADD_TYPE(Vec2); 69 ADD_TYPE(Vec3); 70 ADD_TYPE(Vec4); 71 ADD_TYPE(Double); 72 ADD_TYPE(DVec2); 73 ADD_TYPE(DVec3); 74 ADD_TYPE(DVec4); 75 ADD_TYPE(Int); 76 ADD_TYPE(IVec2); 77 ADD_TYPE(IVec3); 78 ADD_TYPE(IVec4); 79 ADD_TYPE(UInt); 80 ADD_TYPE(UVec2); 81 ADD_TYPE(UVec3); 82 ADD_TYPE(UVec4); 83 ADD_TYPE(Bool); 84 ADD_TYPE(BVec2); 85 ADD_TYPE(BVec3); 86 ADD_TYPE(BVec4); 87 ADD_TYPE(Mat2x2); 88 types->addWithoutOwnership(String("mat2x2"), fContext.fMat2x2_Type.get()); 89 ADD_TYPE(Mat2x3); 90 ADD_TYPE(Mat2x4); 91 ADD_TYPE(Mat3x2); 92 ADD_TYPE(Mat3x3); 93 types->addWithoutOwnership(String("mat3x3"), fContext.fMat3x3_Type.get()); 94 ADD_TYPE(Mat3x4); 95 ADD_TYPE(Mat4x2); 96 ADD_TYPE(Mat4x3); 97 ADD_TYPE(Mat4x4); 98 types->addWithoutOwnership(String("mat4x4"), fContext.fMat4x4_Type.get()); 99 ADD_TYPE(GenType); 100 ADD_TYPE(GenDType); 101 ADD_TYPE(GenIType); 102 ADD_TYPE(GenUType); 103 ADD_TYPE(GenBType); 104 ADD_TYPE(Mat); 105 ADD_TYPE(Vec); 106 ADD_TYPE(GVec); 107 ADD_TYPE(GVec2); 108 ADD_TYPE(GVec3); 109 ADD_TYPE(GVec4); 110 ADD_TYPE(DVec); 111 ADD_TYPE(IVec); 112 ADD_TYPE(UVec); 113 ADD_TYPE(BVec); 114 115 ADD_TYPE(Sampler1D); 116 ADD_TYPE(Sampler2D); 117 ADD_TYPE(Sampler3D); 118 ADD_TYPE(SamplerExternalOES); 119 ADD_TYPE(SamplerCube); 120 ADD_TYPE(Sampler2DRect); 121 ADD_TYPE(Sampler1DArray); 122 ADD_TYPE(Sampler2DArray); 123 ADD_TYPE(SamplerCubeArray); 124 ADD_TYPE(SamplerBuffer); 125 ADD_TYPE(Sampler2DMS); 126 ADD_TYPE(Sampler2DMSArray); 127 128 ADD_TYPE(ISampler2D); 129 130 ADD_TYPE(Image2D); 131 ADD_TYPE(IImage2D); 132 133 ADD_TYPE(SubpassInput); 134 ADD_TYPE(SubpassInputMS); 135 136 ADD_TYPE(GSampler1D); 137 ADD_TYPE(GSampler2D); 138 ADD_TYPE(GSampler3D); 139 ADD_TYPE(GSamplerCube); 140 ADD_TYPE(GSampler2DRect); 141 ADD_TYPE(GSampler1DArray); 142 ADD_TYPE(GSampler2DArray); 143 ADD_TYPE(GSamplerCubeArray); 144 ADD_TYPE(GSamplerBuffer); 145 ADD_TYPE(GSampler2DMS); 146 ADD_TYPE(GSampler2DMSArray); 147 148 ADD_TYPE(Sampler1DShadow); 149 ADD_TYPE(Sampler2DShadow); 150 ADD_TYPE(SamplerCubeShadow); 151 ADD_TYPE(Sampler2DRectShadow); 152 ADD_TYPE(Sampler1DArrayShadow); 153 ADD_TYPE(Sampler2DArrayShadow); 154 ADD_TYPE(SamplerCubeArrayShadow); 155 ADD_TYPE(GSampler2DArrayShadow); 156 ADD_TYPE(GSamplerCubeArrayShadow); 157 ADD_TYPE(ColorSpaceXform); 158 159 String skCapsName("sk_Caps"); 160 Variable* skCaps = new Variable(Position(), Modifiers(), skCapsName, 161 *fContext.fSkCaps_Type, Variable::kGlobal_Storage); 162 fIRGenerator->fSymbolTable->add(skCapsName, std::unique_ptr<Symbol>(skCaps)); 163 164 String skArgsName("sk_Args"); 165 Variable* skArgs = new Variable(Position(), Modifiers(), skArgsName, 166 *fContext.fSkArgs_Type, Variable::kGlobal_Storage); 167 fIRGenerator->fSymbolTable->add(skArgsName, std::unique_ptr<Symbol>(skArgs)); 168 169 Modifiers::Flag ignored1; 170 std::vector<std::unique_ptr<ProgramElement>> ignored2; 171 fIRGenerator->convertProgram(String(SKSL_INCLUDE), *fTypes, &ignored1, &ignored2); 172 fIRGenerator->fSymbolTable->markAllFunctionsBuiltin(); 173 ASSERT(!fErrorCount); 174 } 175 176 Compiler::~Compiler() { 177 delete fIRGenerator; 178 } 179 180 // add the definition created by assigning to the lvalue to the definition set 181 void Compiler::addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr, 182 DefinitionMap* definitions) { 183 switch (lvalue->fKind) { 184 case Expression::kVariableReference_Kind: { 185 const Variable& var = ((VariableReference*) lvalue)->fVariable; 186 if (var.fStorage == Variable::kLocal_Storage) { 187 (*definitions)[&var] = expr; 188 } 189 break; 190 } 191 case Expression::kSwizzle_Kind: 192 // We consider the variable written to as long as at least some of its components have 193 // been written to. This will lead to some false negatives (we won't catch it if you 194 // write to foo.x and then read foo.y), but being stricter could lead to false positives 195 // (we write to foo.x, and then pass foo to a function which happens to only read foo.x, 196 // but since we pass foo as a whole it is flagged as an error) unless we perform a much 197 // more complicated whole-program analysis. This is probably good enough. 198 this->addDefinition(((Swizzle*) lvalue)->fBase.get(), 199 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, 200 definitions); 201 break; 202 case Expression::kIndex_Kind: 203 // see comments in Swizzle 204 this->addDefinition(((IndexExpression*) lvalue)->fBase.get(), 205 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, 206 definitions); 207 break; 208 case Expression::kFieldAccess_Kind: 209 // see comments in Swizzle 210 this->addDefinition(((FieldAccess*) lvalue)->fBase.get(), 211 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, 212 definitions); 213 break; 214 default: 215 // not an lvalue, can't happen 216 ASSERT(false); 217 } 218 } 219 220 // add local variables defined by this node to the set 221 void Compiler::addDefinitions(const BasicBlock::Node& node, 222 DefinitionMap* definitions) { 223 switch (node.fKind) { 224 case BasicBlock::Node::kExpression_Kind: { 225 ASSERT(node.expression()); 226 const Expression* expr = (Expression*) node.expression()->get(); 227 switch (expr->fKind) { 228 case Expression::kBinary_Kind: { 229 BinaryExpression* b = (BinaryExpression*) expr; 230 if (b->fOperator == Token::EQ) { 231 this->addDefinition(b->fLeft.get(), &b->fRight, definitions); 232 } else if (Token::IsAssignment(b->fOperator)) { 233 this->addDefinition( 234 b->fLeft.get(), 235 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, 236 definitions); 237 238 } 239 break; 240 } 241 case Expression::kPrefix_Kind: { 242 const PrefixExpression* p = (PrefixExpression*) expr; 243 if (p->fOperator == Token::MINUSMINUS || p->fOperator == Token::PLUSPLUS) { 244 this->addDefinition( 245 p->fOperand.get(), 246 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, 247 definitions); 248 } 249 break; 250 } 251 case Expression::kPostfix_Kind: { 252 const PostfixExpression* p = (PostfixExpression*) expr; 253 if (p->fOperator == Token::MINUSMINUS || p->fOperator == Token::PLUSPLUS) { 254 this->addDefinition( 255 p->fOperand.get(), 256 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, 257 definitions); 258 } 259 break; 260 } 261 case Expression::kVariableReference_Kind: { 262 const VariableReference* v = (VariableReference*) expr; 263 if (v->fRefKind != VariableReference::kRead_RefKind) { 264 this->addDefinition( 265 v, 266 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, 267 definitions); 268 } 269 } 270 default: 271 break; 272 } 273 break; 274 } 275 case BasicBlock::Node::kStatement_Kind: { 276 const Statement* stmt = (Statement*) node.statement()->get(); 277 if (stmt->fKind == Statement::kVarDeclaration_Kind) { 278 VarDeclaration& vd = (VarDeclaration&) *stmt; 279 if (vd.fValue) { 280 (*definitions)[vd.fVar] = &vd.fValue; 281 } 282 } 283 break; 284 } 285 } 286 } 287 288 void Compiler::scanCFG(CFG* cfg, BlockId blockId, std::set<BlockId>* workList) { 289 BasicBlock& block = cfg->fBlocks[blockId]; 290 291 // compute definitions after this block 292 DefinitionMap after = block.fBefore; 293 for (const BasicBlock::Node& n : block.fNodes) { 294 this->addDefinitions(n, &after); 295 } 296 297 // propagate definitions to exits 298 for (BlockId exitId : block.fExits) { 299 BasicBlock& exit = cfg->fBlocks[exitId]; 300 for (const auto& pair : after) { 301 std::unique_ptr<Expression>* e1 = pair.second; 302 auto found = exit.fBefore.find(pair.first); 303 if (found == exit.fBefore.end()) { 304 // exit has no definition for it, just copy it 305 workList->insert(exitId); 306 exit.fBefore[pair.first] = e1; 307 } else { 308 // exit has a (possibly different) value already defined 309 std::unique_ptr<Expression>* e2 = exit.fBefore[pair.first]; 310 if (e1 != e2) { 311 // definition has changed, merge and add exit block to worklist 312 workList->insert(exitId); 313 if (e1 && e2) { 314 exit.fBefore[pair.first] = 315 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression; 316 } else { 317 exit.fBefore[pair.first] = nullptr; 318 } 319 } 320 } 321 } 322 } 323 } 324 325 // returns a map which maps all local variables in the function to null, indicating that their value 326 // is initially unknown 327 static DefinitionMap compute_start_state(const CFG& cfg) { 328 DefinitionMap result; 329 for (const auto& block : cfg.fBlocks) { 330 for (const auto& node : block.fNodes) { 331 if (node.fKind == BasicBlock::Node::kStatement_Kind) { 332 ASSERT(node.statement()); 333 const Statement* s = node.statement()->get(); 334 if (s->fKind == Statement::kVarDeclarations_Kind) { 335 const VarDeclarationsStatement* vd = (const VarDeclarationsStatement*) s; 336 for (const auto& decl : vd->fDeclaration->fVars) { 337 if (decl->fKind == Statement::kVarDeclaration_Kind) { 338 result[((VarDeclaration&) *decl).fVar] = nullptr; 339 } 340 } 341 } 342 } 343 } 344 } 345 return result; 346 } 347 348 /** 349 * Returns true if assigning to this lvalue has no effect. 350 */ 351 static bool is_dead(const Expression& lvalue) { 352 switch (lvalue.fKind) { 353 case Expression::kVariableReference_Kind: 354 return ((VariableReference&) lvalue).fVariable.dead(); 355 case Expression::kSwizzle_Kind: 356 return is_dead(*((Swizzle&) lvalue).fBase); 357 case Expression::kFieldAccess_Kind: 358 return is_dead(*((FieldAccess&) lvalue).fBase); 359 case Expression::kIndex_Kind: { 360 const IndexExpression& idx = (IndexExpression&) lvalue; 361 return is_dead(*idx.fBase) && !idx.fIndex->hasSideEffects(); 362 } 363 default: 364 ABORT("invalid lvalue: %s\n", lvalue.description().c_str()); 365 } 366 } 367 368 /** 369 * Returns true if this is an assignment which can be collapsed down to just the right hand side due 370 * to a dead target and lack of side effects on the left hand side. 371 */ 372 static bool dead_assignment(const BinaryExpression& b) { 373 if (!Token::IsAssignment(b.fOperator)) { 374 return false; 375 } 376 return is_dead(*b.fLeft); 377 } 378 379 void Compiler::computeDataFlow(CFG* cfg) { 380 cfg->fBlocks[cfg->fStart].fBefore = compute_start_state(*cfg); 381 std::set<BlockId> workList; 382 for (BlockId i = 0; i < cfg->fBlocks.size(); i++) { 383 workList.insert(i); 384 } 385 while (workList.size()) { 386 BlockId next = *workList.begin(); 387 workList.erase(workList.begin()); 388 this->scanCFG(cfg, next, &workList); 389 } 390 } 391 392 /** 393 * Attempts to replace the expression pointed to by iter with a new one (in both the CFG and the 394 * IR). If the expression can be cleanly removed, returns true and updates the iterator to point to 395 * the newly-inserted element. Otherwise updates only the IR and returns false (and the CFG will 396 * need to be regenerated). 397 */ 398 bool try_replace_expression(BasicBlock* b, 399 std::vector<BasicBlock::Node>::iterator* iter, 400 std::unique_ptr<Expression>* newExpression) { 401 std::unique_ptr<Expression>* target = (*iter)->expression(); 402 if (!b->tryRemoveExpression(iter)) { 403 *target = std::move(*newExpression); 404 return false; 405 } 406 *target = std::move(*newExpression); 407 return b->tryInsertExpression(iter, target); 408 } 409 410 /** 411 * Returns true if the expression is a constant numeric literal with the specified value, or a 412 * constant vector with all elements equal to the specified value. 413 */ 414 bool is_constant(const Expression& expr, double value) { 415 switch (expr.fKind) { 416 case Expression::kIntLiteral_Kind: 417 return ((IntLiteral&) expr).fValue == value; 418 case Expression::kFloatLiteral_Kind: 419 return ((FloatLiteral&) expr).fValue == value; 420 case Expression::kConstructor_Kind: { 421 Constructor& c = (Constructor&) expr; 422 if (c.fType.kind() == Type::kVector_Kind && c.isConstant()) { 423 for (int i = 0; i < c.fType.columns(); ++i) { 424 if (!is_constant(c.getVecComponent(i), value)) { 425 return false; 426 } 427 } 428 return true; 429 } 430 return false; 431 } 432 default: 433 return false; 434 } 435 } 436 437 /** 438 * Collapses the binary expression pointed to by iter down to just the right side (in both the IR 439 * and CFG structures). 440 */ 441 void delete_left(BasicBlock* b, 442 std::vector<BasicBlock::Node>::iterator* iter, 443 bool* outUpdated, 444 bool* outNeedsRescan) { 445 *outUpdated = true; 446 std::unique_ptr<Expression>* target = (*iter)->expression(); 447 ASSERT((*target)->fKind == Expression::kBinary_Kind); 448 BinaryExpression& bin = (BinaryExpression&) **target; 449 bool result; 450 if (bin.fOperator == Token::EQ) { 451 result = b->tryRemoveLValueBefore(iter, bin.fLeft.get()); 452 } else { 453 result = b->tryRemoveExpressionBefore(iter, bin.fLeft.get()); 454 } 455 *target = std::move(bin.fRight); 456 if (!result) { 457 *outNeedsRescan = true; 458 return; 459 } 460 if (*iter == b->fNodes.begin()) { 461 *outNeedsRescan = true; 462 return; 463 } 464 --(*iter); 465 if ((*iter)->fKind != BasicBlock::Node::kExpression_Kind || 466 (*iter)->expression() != &bin.fRight) { 467 *outNeedsRescan = true; 468 return; 469 } 470 *iter = b->fNodes.erase(*iter); 471 ASSERT((*iter)->expression() == target); 472 } 473 474 /** 475 * Collapses the binary expression pointed to by iter down to just the left side (in both the IR and 476 * CFG structures). 477 */ 478 void delete_right(BasicBlock* b, 479 std::vector<BasicBlock::Node>::iterator* iter, 480 bool* outUpdated, 481 bool* outNeedsRescan) { 482 *outUpdated = true; 483 std::unique_ptr<Expression>* target = (*iter)->expression(); 484 ASSERT((*target)->fKind == Expression::kBinary_Kind); 485 BinaryExpression& bin = (BinaryExpression&) **target; 486 if (!b->tryRemoveExpressionBefore(iter, bin.fRight.get())) { 487 *target = std::move(bin.fLeft); 488 *outNeedsRescan = true; 489 return; 490 } 491 *target = std::move(bin.fLeft); 492 if (*iter == b->fNodes.begin()) { 493 *outNeedsRescan = true; 494 return; 495 } 496 --(*iter); 497 if (((*iter)->fKind != BasicBlock::Node::kExpression_Kind || 498 (*iter)->expression() != &bin.fLeft)) { 499 *outNeedsRescan = true; 500 return; 501 } 502 *iter = b->fNodes.erase(*iter); 503 ASSERT((*iter)->expression() == target); 504 } 505 506 /** 507 * Constructs the specified type using a single argument. 508 */ 509 static std::unique_ptr<Expression> construct(const Type& type, std::unique_ptr<Expression> v) { 510 std::vector<std::unique_ptr<Expression>> args; 511 args.push_back(std::move(v)); 512 auto result = std::unique_ptr<Expression>(new Constructor(Position(), type, std::move(args))); 513 return result; 514 } 515 516 /** 517 * Used in the implementations of vectorize_left and vectorize_right. Given a vector type and an 518 * expression x, deletes the expression pointed to by iter and replaces it with <type>(x). 519 */ 520 static void vectorize(BasicBlock* b, 521 std::vector<BasicBlock::Node>::iterator* iter, 522 const Type& type, 523 std::unique_ptr<Expression>* otherExpression, 524 bool* outUpdated, 525 bool* outNeedsRescan) { 526 ASSERT((*(*iter)->expression())->fKind == Expression::kBinary_Kind); 527 ASSERT(type.kind() == Type::kVector_Kind); 528 ASSERT((*otherExpression)->fType.kind() == Type::kScalar_Kind); 529 *outUpdated = true; 530 std::unique_ptr<Expression>* target = (*iter)->expression(); 531 if (!b->tryRemoveExpression(iter)) { 532 *target = construct(type, std::move(*otherExpression)); 533 *outNeedsRescan = true; 534 } else { 535 *target = construct(type, std::move(*otherExpression)); 536 if (!b->tryInsertExpression(iter, target)) { 537 *outNeedsRescan = true; 538 } 539 } 540 } 541 542 /** 543 * Given a binary expression of the form x <op> vec<n>(y), deletes the right side and vectorizes the 544 * left to yield vec<n>(x). 545 */ 546 static void vectorize_left(BasicBlock* b, 547 std::vector<BasicBlock::Node>::iterator* iter, 548 bool* outUpdated, 549 bool* outNeedsRescan) { 550 BinaryExpression& bin = (BinaryExpression&) **(*iter)->expression(); 551 vectorize(b, iter, bin.fRight->fType, &bin.fLeft, outUpdated, outNeedsRescan); 552 } 553 554 /** 555 * Given a binary expression of the form vec<n>(x) <op> y, deletes the left side and vectorizes the 556 * right to yield vec<n>(y). 557 */ 558 static void vectorize_right(BasicBlock* b, 559 std::vector<BasicBlock::Node>::iterator* iter, 560 bool* outUpdated, 561 bool* outNeedsRescan) { 562 BinaryExpression& bin = (BinaryExpression&) **(*iter)->expression(); 563 vectorize(b, iter, bin.fLeft->fType, &bin.fRight, outUpdated, outNeedsRescan); 564 } 565 566 // Mark that an expression which we were writing to is no longer being written to 567 void clear_write(const Expression& expr) { 568 switch (expr.fKind) { 569 case Expression::kVariableReference_Kind: { 570 ((VariableReference&) expr).setRefKind(VariableReference::kRead_RefKind); 571 break; 572 } 573 case Expression::kFieldAccess_Kind: 574 clear_write(*((FieldAccess&) expr).fBase); 575 break; 576 case Expression::kSwizzle_Kind: 577 clear_write(*((Swizzle&) expr).fBase); 578 break; 579 case Expression::kIndex_Kind: 580 clear_write(*((IndexExpression&) expr).fBase); 581 break; 582 default: 583 ABORT("shouldn't be writing to this kind of expression\n"); 584 break; 585 } 586 } 587 588 void Compiler::simplifyExpression(DefinitionMap& definitions, 589 BasicBlock& b, 590 std::vector<BasicBlock::Node>::iterator* iter, 591 std::unordered_set<const Variable*>* undefinedVariables, 592 bool* outUpdated, 593 bool* outNeedsRescan) { 594 Expression* expr = (*iter)->expression()->get(); 595 ASSERT(expr); 596 if ((*iter)->fConstantPropagation) { 597 std::unique_ptr<Expression> optimized = expr->constantPropagate(*fIRGenerator, definitions); 598 if (optimized) { 599 *outUpdated = true; 600 if (!try_replace_expression(&b, iter, &optimized)) { 601 *outNeedsRescan = true; 602 return; 603 } 604 ASSERT((*iter)->fKind == BasicBlock::Node::kExpression_Kind); 605 expr = (*iter)->expression()->get(); 606 } 607 } 608 switch (expr->fKind) { 609 case Expression::kVariableReference_Kind: { 610 const Variable& var = ((VariableReference*) expr)->fVariable; 611 if (var.fStorage == Variable::kLocal_Storage && !definitions[&var] && 612 (*undefinedVariables).find(&var) == (*undefinedVariables).end()) { 613 (*undefinedVariables).insert(&var); 614 this->error(expr->fPosition, 615 "'" + var.fName + "' has not been assigned"); 616 } 617 break; 618 } 619 case Expression::kTernary_Kind: { 620 TernaryExpression* t = (TernaryExpression*) expr; 621 if (t->fTest->fKind == Expression::kBoolLiteral_Kind) { 622 // ternary has a constant test, replace it with either the true or 623 // false branch 624 if (((BoolLiteral&) *t->fTest).fValue) { 625 (*iter)->setExpression(std::move(t->fIfTrue)); 626 } else { 627 (*iter)->setExpression(std::move(t->fIfFalse)); 628 } 629 *outUpdated = true; 630 *outNeedsRescan = true; 631 } 632 break; 633 } 634 case Expression::kBinary_Kind: { 635 BinaryExpression* bin = (BinaryExpression*) expr; 636 if (dead_assignment(*bin)) { 637 delete_left(&b, iter, outUpdated, outNeedsRescan); 638 break; 639 } 640 // collapse useless expressions like x * 1 or x + 0 641 if (((bin->fLeft->fType.kind() != Type::kScalar_Kind) && 642 (bin->fLeft->fType.kind() != Type::kVector_Kind)) || 643 ((bin->fRight->fType.kind() != Type::kScalar_Kind) && 644 (bin->fRight->fType.kind() != Type::kVector_Kind))) { 645 break; 646 } 647 switch (bin->fOperator) { 648 case Token::STAR: 649 if (is_constant(*bin->fLeft, 1)) { 650 if (bin->fLeft->fType.kind() == Type::kVector_Kind && 651 bin->fRight->fType.kind() == Type::kScalar_Kind) { 652 // vec4(1) * x -> vec4(x) 653 vectorize_right(&b, iter, outUpdated, outNeedsRescan); 654 } else { 655 // 1 * x -> x 656 // 1 * vec4(x) -> vec4(x) 657 // vec4(1) * vec4(x) -> vec4(x) 658 delete_left(&b, iter, outUpdated, outNeedsRescan); 659 } 660 } 661 else if (is_constant(*bin->fLeft, 0)) { 662 if (bin->fLeft->fType.kind() == Type::kScalar_Kind && 663 bin->fRight->fType.kind() == Type::kVector_Kind) { 664 // 0 * vec4(x) -> vec4(0) 665 vectorize_left(&b, iter, outUpdated, outNeedsRescan); 666 } else { 667 // 0 * x -> 0 668 // vec4(0) * x -> vec4(0) 669 // vec4(0) * vec4(x) -> vec4(0) 670 delete_right(&b, iter, outUpdated, outNeedsRescan); 671 } 672 } 673 else if (is_constant(*bin->fRight, 1)) { 674 if (bin->fLeft->fType.kind() == Type::kScalar_Kind && 675 bin->fRight->fType.kind() == Type::kVector_Kind) { 676 // x * vec4(1) -> vec4(x) 677 vectorize_left(&b, iter, outUpdated, outNeedsRescan); 678 } else { 679 // x * 1 -> x 680 // vec4(x) * 1 -> vec4(x) 681 // vec4(x) * vec4(1) -> vec4(x) 682 delete_right(&b, iter, outUpdated, outNeedsRescan); 683 } 684 } 685 else if (is_constant(*bin->fRight, 0)) { 686 if (bin->fLeft->fType.kind() == Type::kVector_Kind && 687 bin->fRight->fType.kind() == Type::kScalar_Kind) { 688 // vec4(x) * 0 -> vec4(0) 689 vectorize_right(&b, iter, outUpdated, outNeedsRescan); 690 } else { 691 // x * 0 -> 0 692 // x * vec4(0) -> vec4(0) 693 // vec4(x) * vec4(0) -> vec4(0) 694 delete_left(&b, iter, outUpdated, outNeedsRescan); 695 } 696 } 697 break; 698 case Token::PLUS: 699 if (is_constant(*bin->fLeft, 0)) { 700 if (bin->fLeft->fType.kind() == Type::kVector_Kind && 701 bin->fRight->fType.kind() == Type::kScalar_Kind) { 702 // vec4(0) + x -> vec4(x) 703 vectorize_right(&b, iter, outUpdated, outNeedsRescan); 704 } else { 705 // 0 + x -> x 706 // 0 + vec4(x) -> vec4(x) 707 // vec4(0) + vec4(x) -> vec4(x) 708 delete_left(&b, iter, outUpdated, outNeedsRescan); 709 } 710 } else if (is_constant(*bin->fRight, 0)) { 711 if (bin->fLeft->fType.kind() == Type::kScalar_Kind && 712 bin->fRight->fType.kind() == Type::kVector_Kind) { 713 // x + vec4(0) -> vec4(x) 714 vectorize_left(&b, iter, outUpdated, outNeedsRescan); 715 } else { 716 // x + 0 -> x 717 // vec4(x) + 0 -> vec4(x) 718 // vec4(x) + vec4(0) -> vec4(x) 719 delete_right(&b, iter, outUpdated, outNeedsRescan); 720 } 721 } 722 break; 723 case Token::MINUS: 724 if (is_constant(*bin->fRight, 0)) { 725 if (bin->fLeft->fType.kind() == Type::kScalar_Kind && 726 bin->fRight->fType.kind() == Type::kVector_Kind) { 727 // x - vec4(0) -> vec4(x) 728 vectorize_left(&b, iter, outUpdated, outNeedsRescan); 729 } else { 730 // x - 0 -> x 731 // vec4(x) - 0 -> vec4(x) 732 // vec4(x) - vec4(0) -> vec4(x) 733 delete_right(&b, iter, outUpdated, outNeedsRescan); 734 } 735 } 736 break; 737 case Token::SLASH: 738 if (is_constant(*bin->fRight, 1)) { 739 if (bin->fLeft->fType.kind() == Type::kScalar_Kind && 740 bin->fRight->fType.kind() == Type::kVector_Kind) { 741 // x / vec4(1) -> vec4(x) 742 vectorize_left(&b, iter, outUpdated, outNeedsRescan); 743 } else { 744 // x / 1 -> x 745 // vec4(x) / 1 -> vec4(x) 746 // vec4(x) / vec4(1) -> vec4(x) 747 delete_right(&b, iter, outUpdated, outNeedsRescan); 748 } 749 } else if (is_constant(*bin->fLeft, 0)) { 750 if (bin->fLeft->fType.kind() == Type::kScalar_Kind && 751 bin->fRight->fType.kind() == Type::kVector_Kind) { 752 // 0 / vec4(x) -> vec4(0) 753 vectorize_left(&b, iter, outUpdated, outNeedsRescan); 754 } else { 755 // 0 / x -> 0 756 // vec4(0) / x -> vec4(0) 757 // vec4(0) / vec4(x) -> vec4(0) 758 delete_right(&b, iter, outUpdated, outNeedsRescan); 759 } 760 } 761 break; 762 case Token::PLUSEQ: 763 if (is_constant(*bin->fRight, 0)) { 764 clear_write(*bin->fLeft); 765 delete_right(&b, iter, outUpdated, outNeedsRescan); 766 } 767 break; 768 case Token::MINUSEQ: 769 if (is_constant(*bin->fRight, 0)) { 770 clear_write(*bin->fLeft); 771 delete_right(&b, iter, outUpdated, outNeedsRescan); 772 } 773 break; 774 case Token::STAREQ: 775 if (is_constant(*bin->fRight, 1)) { 776 clear_write(*bin->fLeft); 777 delete_right(&b, iter, outUpdated, outNeedsRescan); 778 } 779 break; 780 case Token::SLASHEQ: 781 if (is_constant(*bin->fRight, 1)) { 782 clear_write(*bin->fLeft); 783 delete_right(&b, iter, outUpdated, outNeedsRescan); 784 } 785 break; 786 default: 787 break; 788 } 789 } 790 default: 791 break; 792 } 793 } 794 795 // returns true if this statement could potentially execute a break at the current level (we ignore 796 // nested loops and switches, since any breaks inside of them will merely break the loop / switch) 797 static bool contains_break(Statement& s) { 798 switch (s.fKind) { 799 case Statement::kBlock_Kind: 800 for (const auto& sub : ((Block&) s).fStatements) { 801 if (contains_break(*sub)) { 802 return true; 803 } 804 } 805 return false; 806 case Statement::kBreak_Kind: 807 return true; 808 case Statement::kIf_Kind: { 809 const IfStatement& i = (IfStatement&) s; 810 return contains_break(*i.fIfTrue) || (i.fIfFalse && contains_break(*i.fIfFalse)); 811 } 812 default: 813 return false; 814 } 815 } 816 817 // Returns a block containing all of the statements that will be run if the given case matches 818 // (which, owing to the statements being owned by unique_ptrs, means the switch itself will be 819 // broken by this call and must then be discarded). 820 // Returns null (and leaves the switch unmodified) if no such simple reduction is possible, such as 821 // when break statements appear inside conditionals. 822 static std::unique_ptr<Statement> block_for_case(SwitchStatement* s, SwitchCase* c) { 823 bool capturing = false; 824 std::vector<std::unique_ptr<Statement>*> statementPtrs; 825 for (const auto& current : s->fCases) { 826 if (current.get() == c) { 827 capturing = true; 828 } 829 if (capturing) { 830 for (auto& stmt : current->fStatements) { 831 if (stmt->fKind == Statement::kBreak_Kind) { 832 capturing = false; 833 break; 834 } 835 if (contains_break(*stmt)) { 836 return nullptr; 837 } 838 statementPtrs.push_back(&stmt); 839 } 840 if (!capturing) { 841 break; 842 } 843 } 844 } 845 std::vector<std::unique_ptr<Statement>> statements; 846 for (const auto& s : statementPtrs) { 847 statements.push_back(std::move(*s)); 848 } 849 return std::unique_ptr<Statement>(new Block(Position(), std::move(statements), s->fSymbols)); 850 } 851 852 void Compiler::simplifyStatement(DefinitionMap& definitions, 853 BasicBlock& b, 854 std::vector<BasicBlock::Node>::iterator* iter, 855 std::unordered_set<const Variable*>* undefinedVariables, 856 bool* outUpdated, 857 bool* outNeedsRescan) { 858 Statement* stmt = (*iter)->statement()->get(); 859 switch (stmt->fKind) { 860 case Statement::kVarDeclaration_Kind: { 861 const auto& varDecl = (VarDeclaration&) *stmt; 862 if (varDecl.fVar->dead() && 863 (!varDecl.fValue || 864 !varDecl.fValue->hasSideEffects())) { 865 if (varDecl.fValue) { 866 ASSERT((*iter)->statement()->get() == stmt); 867 if (!b.tryRemoveExpressionBefore(iter, varDecl.fValue.get())) { 868 *outNeedsRescan = true; 869 } 870 } 871 (*iter)->setStatement(std::unique_ptr<Statement>(new Nop())); 872 *outUpdated = true; 873 } 874 break; 875 } 876 case Statement::kIf_Kind: { 877 IfStatement& i = (IfStatement&) *stmt; 878 if (i.fTest->fKind == Expression::kBoolLiteral_Kind) { 879 // constant if, collapse down to a single branch 880 if (((BoolLiteral&) *i.fTest).fValue) { 881 ASSERT(i.fIfTrue); 882 (*iter)->setStatement(std::move(i.fIfTrue)); 883 } else { 884 if (i.fIfFalse) { 885 (*iter)->setStatement(std::move(i.fIfFalse)); 886 } else { 887 (*iter)->setStatement(std::unique_ptr<Statement>(new Nop())); 888 } 889 } 890 *outUpdated = true; 891 *outNeedsRescan = true; 892 break; 893 } 894 if (i.fIfFalse && i.fIfFalse->isEmpty()) { 895 // else block doesn't do anything, remove it 896 i.fIfFalse.reset(); 897 *outUpdated = true; 898 *outNeedsRescan = true; 899 } 900 if (!i.fIfFalse && i.fIfTrue->isEmpty()) { 901 // if block doesn't do anything, no else block 902 if (i.fTest->hasSideEffects()) { 903 // test has side effects, keep it 904 (*iter)->setStatement(std::unique_ptr<Statement>( 905 new ExpressionStatement(std::move(i.fTest)))); 906 } else { 907 // no if, no else, no test side effects, kill the whole if 908 // statement 909 (*iter)->setStatement(std::unique_ptr<Statement>(new Nop())); 910 } 911 *outUpdated = true; 912 *outNeedsRescan = true; 913 } 914 break; 915 } 916 case Statement::kSwitch_Kind: { 917 SwitchStatement& s = (SwitchStatement&) *stmt; 918 if (s.fValue->isConstant()) { 919 // switch is constant, replace it with the case that matches 920 bool found = false; 921 SwitchCase* defaultCase = nullptr; 922 for (const auto& c : s.fCases) { 923 if (!c->fValue) { 924 defaultCase = c.get(); 925 continue; 926 } 927 ASSERT(c->fValue->fKind == s.fValue->fKind); 928 found = c->fValue->compareConstant(fContext, *s.fValue); 929 if (found) { 930 std::unique_ptr<Statement> newBlock = block_for_case(&s, c.get()); 931 if (newBlock) { 932 (*iter)->setStatement(std::move(newBlock)); 933 break; 934 } else { 935 if (s.fIsStatic && !(fFlags & kPermitInvalidStaticTests_Flag)) { 936 this->error(s.fPosition, 937 "static switch contains non-static conditional break"); 938 s.fIsStatic = false; 939 } 940 return; // can't simplify 941 } 942 } 943 } 944 if (!found) { 945 // no matching case. use default if it exists, or kill the whole thing 946 if (defaultCase) { 947 std::unique_ptr<Statement> newBlock = block_for_case(&s, defaultCase); 948 if (newBlock) { 949 (*iter)->setStatement(std::move(newBlock)); 950 } else { 951 if (s.fIsStatic && !(fFlags & kPermitInvalidStaticTests_Flag)) { 952 this->error(s.fPosition, 953 "static switch contains non-static conditional break"); 954 s.fIsStatic = false; 955 } 956 return; // can't simplify 957 } 958 } else { 959 (*iter)->setStatement(std::unique_ptr<Statement>(new Nop())); 960 } 961 } 962 *outUpdated = true; 963 *outNeedsRescan = true; 964 } 965 break; 966 } 967 case Statement::kExpression_Kind: { 968 ExpressionStatement& e = (ExpressionStatement&) *stmt; 969 ASSERT((*iter)->statement()->get() == &e); 970 if (!e.fExpression->hasSideEffects()) { 971 // Expression statement with no side effects, kill it 972 if (!b.tryRemoveExpressionBefore(iter, e.fExpression.get())) { 973 *outNeedsRescan = true; 974 } 975 ASSERT((*iter)->statement()->get() == stmt); 976 (*iter)->setStatement(std::unique_ptr<Statement>(new Nop())); 977 *outUpdated = true; 978 } 979 break; 980 } 981 default: 982 break; 983 } 984 } 985 986 void Compiler::scanCFG(FunctionDefinition& f) { 987 CFG cfg = CFGGenerator().getCFG(f); 988 this->computeDataFlow(&cfg); 989 990 // check for unreachable code 991 for (size_t i = 0; i < cfg.fBlocks.size(); i++) { 992 if (i != cfg.fStart && !cfg.fBlocks[i].fEntrances.size() && 993 cfg.fBlocks[i].fNodes.size()) { 994 Position p; 995 switch (cfg.fBlocks[i].fNodes[0].fKind) { 996 case BasicBlock::Node::kStatement_Kind: 997 p = (*cfg.fBlocks[i].fNodes[0].statement())->fPosition; 998 break; 999 case BasicBlock::Node::kExpression_Kind: 1000 p = (*cfg.fBlocks[i].fNodes[0].expression())->fPosition; 1001 break; 1002 } 1003 this->error(p, String("unreachable")); 1004 } 1005 } 1006 if (fErrorCount) { 1007 return; 1008 } 1009 1010 // check for dead code & undefined variables, perform constant propagation 1011 std::unordered_set<const Variable*> undefinedVariables; 1012 bool updated; 1013 bool needsRescan = false; 1014 do { 1015 if (needsRescan) { 1016 cfg = CFGGenerator().getCFG(f); 1017 this->computeDataFlow(&cfg); 1018 needsRescan = false; 1019 } 1020 1021 updated = false; 1022 for (BasicBlock& b : cfg.fBlocks) { 1023 DefinitionMap definitions = b.fBefore; 1024 1025 for (auto iter = b.fNodes.begin(); iter != b.fNodes.end() && !needsRescan; ++iter) { 1026 if (iter->fKind == BasicBlock::Node::kExpression_Kind) { 1027 this->simplifyExpression(definitions, b, &iter, &undefinedVariables, &updated, 1028 &needsRescan); 1029 } else { 1030 this->simplifyStatement(definitions, b, &iter, &undefinedVariables, &updated, 1031 &needsRescan); 1032 } 1033 if (needsRescan) { 1034 break; 1035 } 1036 this->addDefinitions(*iter, &definitions); 1037 } 1038 } 1039 } while (updated); 1040 ASSERT(!needsRescan); 1041 1042 // verify static ifs & switches, clean up dead variable decls 1043 for (BasicBlock& b : cfg.fBlocks) { 1044 DefinitionMap definitions = b.fBefore; 1045 1046 for (auto iter = b.fNodes.begin(); iter != b.fNodes.end() && !needsRescan;) { 1047 if (iter->fKind == BasicBlock::Node::kStatement_Kind) { 1048 const Statement& s = **iter->statement(); 1049 switch (s.fKind) { 1050 case Statement::kIf_Kind: 1051 if (((const IfStatement&) s).fIsStatic && 1052 !(fFlags & kPermitInvalidStaticTests_Flag)) { 1053 this->error(s.fPosition, "static if has non-static test"); 1054 } 1055 ++iter; 1056 break; 1057 case Statement::kSwitch_Kind: 1058 if (((const SwitchStatement&) s).fIsStatic && 1059 !(fFlags & kPermitInvalidStaticTests_Flag)) { 1060 this->error(s.fPosition, "static switch has non-static test"); 1061 } 1062 ++iter; 1063 break; 1064 case Statement::kVarDeclarations_Kind: { 1065 VarDeclarations& decls = *((VarDeclarationsStatement&) s).fDeclaration; 1066 for (auto varIter = decls.fVars.begin(); varIter != decls.fVars.end();) { 1067 if ((*varIter)->fKind == Statement::kNop_Kind) { 1068 varIter = decls.fVars.erase(varIter); 1069 } else { 1070 ++varIter; 1071 } 1072 } 1073 if (!decls.fVars.size()) { 1074 iter = b.fNodes.erase(iter); 1075 } else { 1076 ++iter; 1077 } 1078 break; 1079 } 1080 default: 1081 ++iter; 1082 break; 1083 } 1084 } else { 1085 ++iter; 1086 } 1087 } 1088 } 1089 1090 // check for missing return 1091 if (f.fDeclaration.fReturnType != *fContext.fVoid_Type) { 1092 if (cfg.fBlocks[cfg.fExit].fEntrances.size()) { 1093 this->error(f.fPosition, String("function can exit without returning a value")); 1094 } 1095 } 1096 } 1097 1098 std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, String text, 1099 const Program::Settings& settings) { 1100 fErrorText = ""; 1101 fErrorCount = 0; 1102 fIRGenerator->start(&settings); 1103 std::vector<std::unique_ptr<ProgramElement>> elements; 1104 Modifiers::Flag ignored; 1105 switch (kind) { 1106 case Program::kVertex_Kind: 1107 fIRGenerator->convertProgram(String(SKSL_VERT_INCLUDE), *fTypes, &ignored, &elements); 1108 break; 1109 case Program::kFragment_Kind: 1110 fIRGenerator->convertProgram(String(SKSL_FRAG_INCLUDE), *fTypes, &ignored, &elements); 1111 break; 1112 case Program::kGeometry_Kind: 1113 fIRGenerator->convertProgram(String(SKSL_GEOM_INCLUDE), *fTypes, &ignored, &elements); 1114 break; 1115 case Program::kFragmentProcessor_Kind: 1116 fIRGenerator->convertProgram(String(SKSL_FP_INCLUDE), *fTypes, &ignored, &elements); 1117 break; 1118 } 1119 fIRGenerator->fSymbolTable->markAllFunctionsBuiltin(); 1120 Modifiers::Flag defaultPrecision; 1121 fIRGenerator->convertProgram(text, *fTypes, &defaultPrecision, &elements); 1122 if (!fErrorCount) { 1123 for (auto& element : elements) { 1124 if (element->fKind == ProgramElement::kFunction_Kind) { 1125 this->scanCFG((FunctionDefinition&) *element); 1126 } 1127 } 1128 } 1129 auto result = std::unique_ptr<Program>(new Program(kind, settings, defaultPrecision, &fContext, 1130 std::move(elements), 1131 fIRGenerator->fSymbolTable, 1132 fIRGenerator->fInputs)); 1133 fIRGenerator->finish(); 1134 this->writeErrorCount(); 1135 if (fErrorCount) { 1136 return nullptr; 1137 } 1138 return result; 1139 } 1140 1141 bool Compiler::toSPIRV(const Program& program, OutputStream& out) { 1142 #ifdef SK_ENABLE_SPIRV_VALIDATION 1143 StringStream buffer; 1144 SPIRVCodeGenerator cg(&fContext, &program, this, &buffer); 1145 bool result = cg.generateCode(); 1146 if (result) { 1147 spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0); 1148 const String& data = buffer.str(); 1149 ASSERT(0 == data.size() % 4); 1150 auto dumpmsg = [](spv_message_level_t, const char*, const spv_position_t&, const char* m) { 1151 SkDebugf("SPIR-V validation error: %s\n", m); 1152 }; 1153 tools.SetMessageConsumer(dumpmsg); 1154 // Verify that the SPIR-V we produced is valid. If this assert fails, check the logs prior 1155 // to the failure to see the validation errors. 1156 ASSERT_RESULT(tools.Validate((const uint32_t*) data.c_str(), data.size() / 4)); 1157 out.write(data.c_str(), data.size()); 1158 } 1159 #else 1160 SPIRVCodeGenerator cg(&fContext, &program, this, &out); 1161 bool result = cg.generateCode(); 1162 #endif 1163 this->writeErrorCount(); 1164 return result; 1165 } 1166 1167 bool Compiler::toSPIRV(const Program& program, String* out) { 1168 StringStream buffer; 1169 bool result = this->toSPIRV(program, buffer); 1170 if (result) { 1171 *out = buffer.str(); 1172 } 1173 return result; 1174 } 1175 1176 bool Compiler::toGLSL(const Program& program, OutputStream& out) { 1177 GLSLCodeGenerator cg(&fContext, &program, this, &out); 1178 bool result = cg.generateCode(); 1179 this->writeErrorCount(); 1180 return result; 1181 } 1182 1183 bool Compiler::toGLSL(const Program& program, String* out) { 1184 StringStream buffer; 1185 bool result = this->toGLSL(program, buffer); 1186 if (result) { 1187 *out = buffer.str(); 1188 } 1189 return result; 1190 } 1191 1192 bool Compiler::toCPP(const Program& program, String name, OutputStream& out) { 1193 CPPCodeGenerator cg(&fContext, &program, this, name, &out); 1194 bool result = cg.generateCode(); 1195 this->writeErrorCount(); 1196 return result; 1197 } 1198 1199 bool Compiler::toH(const Program& program, String name, OutputStream& out) { 1200 HCodeGenerator cg(&program, this, name, &out); 1201 bool result = cg.generateCode(); 1202 this->writeErrorCount(); 1203 return result; 1204 } 1205 1206 void Compiler::error(Position position, String msg) { 1207 fErrorCount++; 1208 fErrorText += "error: " + position.description() + ": " + msg.c_str() + "\n"; 1209 } 1210 1211 String Compiler::errorText() { 1212 String result = fErrorText; 1213 return result; 1214 } 1215 1216 void Compiler::writeErrorCount() { 1217 if (fErrorCount) { 1218 fErrorText += to_string(fErrorCount) + " error"; 1219 if (fErrorCount > 1) { 1220 fErrorText += "s"; 1221 } 1222 fErrorText += "\n"; 1223 } 1224 } 1225 1226 } // namespace 1227