1 // 2 //Copyright (C) 2002-2005 3Dlabs Inc. Ltd. 3 //Copyright (C) 2012-2015 LunarG, Inc. 4 //Copyright (C) 2015-2016 Google, Inc. 5 // 6 //All rights reserved. 7 // 8 //Redistribution and use in source and binary forms, with or without 9 //modification, are permitted provided that the following conditions 10 //are met: 11 // 12 // Redistributions of source code must retain the above copyright 13 // notice, this list of conditions and the following disclaimer. 14 // 15 // Redistributions in binary form must reproduce the above 16 // copyright notice, this list of conditions and the following 17 // disclaimer in the documentation and/or other materials provided 18 // with the distribution. 19 // 20 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its 21 // contributors may be used to endorse or promote products derived 22 // from this software without specific prior written permission. 23 // 24 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 //COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 //CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 //ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 //POSSIBILITY OF SUCH DAMAGE. 36 // 37 38 // 39 // Build the intermediate representation. 40 // 41 42 #include "localintermediate.h" 43 #include "RemoveTree.h" 44 #include "SymbolTable.h" 45 #include "propagateNoContraction.h" 46 47 #include <float.h> 48 49 namespace glslang { 50 51 //////////////////////////////////////////////////////////////////////////// 52 // 53 // First set of functions are to help build the intermediate representation. 54 // These functions are not member functions of the nodes. 55 // They are called from parser productions. 56 // 57 ///////////////////////////////////////////////////////////////////////////// 58 59 // 60 // Add a terminal node for an identifier in an expression. 61 // 62 // Returns the added node. 63 // 64 65 TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TConstUnionArray& constArray, 66 TIntermTyped* constSubtree, const TSourceLoc& loc) 67 { 68 TIntermSymbol* node = new TIntermSymbol(id, name, type); 69 node->setLoc(loc); 70 node->setConstArray(constArray); 71 node->setConstSubtree(constSubtree); 72 73 return node; 74 } 75 76 TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable) 77 { 78 glslang::TSourceLoc loc; // just a null location 79 loc.init(); 80 81 return addSymbol(variable, loc); 82 } 83 84 TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable, const TSourceLoc& loc) 85 { 86 return addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), variable.getConstArray(), variable.getConstSubtree(), loc); 87 } 88 89 TIntermSymbol* TIntermediate::addSymbol(const TType& type, const TSourceLoc& loc) 90 { 91 TConstUnionArray unionArray; // just a null constant 92 93 return addSymbol(0, "", type, unionArray, nullptr, loc); 94 } 95 96 // 97 // Connect two nodes with a new parent that does a binary operation on the nodes. 98 // 99 // Returns the added node. 100 // 101 TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) 102 { 103 // No operations work on blocks 104 if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) 105 return 0; 106 107 // Try converting the children's base types to compatible types. 108 TIntermTyped* child = addConversion(op, left->getType(), right); 109 if (child) 110 right = child; 111 else { 112 child = addConversion(op, right->getType(), left); 113 if (child) 114 left = child; 115 else 116 return 0; 117 } 118 119 // 120 // Need a new node holding things together. Make 121 // one and promote it to the right type. 122 // 123 TIntermBinary* node = new TIntermBinary(op); 124 if (loc.line == 0) 125 loc = right->getLoc(); 126 node->setLoc(loc); 127 128 node->setLeft(left); 129 node->setRight(right); 130 if (! node->promote()) 131 return 0; 132 133 node->updatePrecision(); 134 135 // 136 // If they are both (non-specialization) constants, they must be folded. 137 // (Unless it's the sequence (comma) operator, but that's handled in addComma().) 138 // 139 TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion(); 140 TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion(); 141 if (leftTempConstant && rightTempConstant) { 142 TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant); 143 if (folded) 144 return folded; 145 } 146 147 // If either is a specialization constant, while the other is 148 // a constant (or specialization constant), the result is still 149 // a specialization constant, if the operation is an allowed 150 // specialization-constant operation. 151 if (( left->getType().getQualifier().isSpecConstant() && right->getType().getQualifier().isConstant()) || 152 (right->getType().getQualifier().isSpecConstant() && left->getType().getQualifier().isConstant())) 153 if (isSpecializationOperation(*node)) 154 node->getWritableType().getQualifier().makeSpecConstant(); 155 156 return node; 157 } 158 159 // 160 // Connect two nodes through an assignment. 161 // 162 // Returns the added node. 163 // 164 TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) 165 { 166 // No block assignment 167 if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) 168 return 0; 169 170 // 171 // Like adding binary math, except the conversion can only go 172 // from right to left. 173 // 174 TIntermBinary* node = new TIntermBinary(op); 175 if (loc.line == 0) 176 loc = left->getLoc(); 177 node->setLoc(loc); 178 179 TIntermTyped* child = addConversion(op, left->getType(), right); 180 if (child == 0) 181 return 0; 182 183 node->setLeft(left); 184 node->setRight(child); 185 if (! node->promote()) 186 return 0; 187 188 node->updatePrecision(); 189 190 return node; 191 } 192 193 // 194 // Connect two nodes through an index operator, where the left node is the base 195 // of an array or struct, and the right node is a direct or indirect offset. 196 // 197 // Returns the added node. 198 // The caller should set the type of the returned node. 199 // 200 TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc) 201 { 202 TIntermBinary* node = new TIntermBinary(op); 203 if (loc.line == 0) 204 loc = index->getLoc(); 205 node->setLoc(loc); 206 node->setLeft(base); 207 node->setRight(index); 208 209 // caller should set the type 210 211 return node; 212 } 213 214 // 215 // Add one node as the parent of another that it operates on. 216 // 217 // Returns the added node. 218 // 219 TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSourceLoc loc) 220 { 221 if (child == 0) 222 return 0; 223 224 if (child->getType().getBasicType() == EbtBlock) 225 return 0; 226 227 switch (op) { 228 case EOpLogicalNot: 229 if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) { 230 return 0; 231 } 232 break; 233 234 case EOpPostIncrement: 235 case EOpPreIncrement: 236 case EOpPostDecrement: 237 case EOpPreDecrement: 238 case EOpNegative: 239 if (child->getType().getBasicType() == EbtStruct || child->getType().isArray()) 240 return 0; 241 default: break; // some compilers want this 242 } 243 244 // 245 // Do we need to promote the operand? 246 // 247 TBasicType newType = EbtVoid; 248 switch (op) { 249 case EOpConstructInt: newType = EbtInt; break; 250 case EOpConstructUint: newType = EbtUint; break; 251 case EOpConstructInt64: newType = EbtInt64; break; 252 case EOpConstructUint64: newType = EbtUint64; break; 253 case EOpConstructBool: newType = EbtBool; break; 254 case EOpConstructFloat: newType = EbtFloat; break; 255 case EOpConstructDouble: newType = EbtDouble; break; 256 default: break; // some compilers want this 257 } 258 259 if (newType != EbtVoid) { 260 child = addConversion(op, TType(newType, EvqTemporary, child->getVectorSize(), 261 child->getMatrixCols(), 262 child->getMatrixRows()), 263 child); 264 if (child == 0) 265 return 0; 266 } 267 268 // 269 // For constructors, we are now done, it was all in the conversion. 270 // TODO: but, did this bypass constant folding? 271 // 272 switch (op) { 273 case EOpConstructInt: 274 case EOpConstructUint: 275 case EOpConstructInt64: 276 case EOpConstructUint64: 277 case EOpConstructBool: 278 case EOpConstructFloat: 279 case EOpConstructDouble: 280 return child; 281 default: break; // some compilers want this 282 } 283 284 // 285 // Make a new node for the operator. 286 // 287 TIntermUnary* node = new TIntermUnary(op); 288 if (loc.line == 0) 289 loc = child->getLoc(); 290 node->setLoc(loc); 291 node->setOperand(child); 292 293 if (! node->promote()) 294 return 0; 295 296 node->updatePrecision(); 297 298 // If it's a (non-specialization) constant, it must be folded. 299 if (child->getAsConstantUnion()) 300 return child->getAsConstantUnion()->fold(op, node->getType()); 301 302 // If it's a specialization constant, the result is too, 303 // if the operation is allowed for specialization constants. 304 if (child->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node)) 305 node->getWritableType().getQualifier().makeSpecConstant(); 306 307 return node; 308 } 309 310 TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOperator op, bool unary, TIntermNode* childNode, const TType& returnType) 311 { 312 if (unary) { 313 // 314 // Treat it like a unary operator. 315 // addUnaryMath() should get the type correct on its own; 316 // including constness (which would differ from the prototype). 317 // 318 TIntermTyped* child = childNode->getAsTyped(); 319 if (child == 0) 320 return 0; 321 322 if (child->getAsConstantUnion()) { 323 TIntermTyped* folded = child->getAsConstantUnion()->fold(op, returnType); 324 if (folded) 325 return folded; 326 } 327 328 TIntermUnary* node = new TIntermUnary(op); 329 node->setLoc(child->getLoc()); 330 node->setOperand(child); 331 node->setType(returnType); 332 333 // propagate precision up from child 334 if (profile == EEsProfile && returnType.getQualifier().precision == EpqNone && returnType.getBasicType() != EbtBool) 335 node->getQualifier().precision = child->getQualifier().precision; 336 337 // propagate precision down to child 338 if (node->getQualifier().precision != EpqNone) 339 child->propagatePrecision(node->getQualifier().precision); 340 341 return node; 342 } else { 343 // setAggregateOperater() calls fold() for constant folding 344 TIntermTyped* node = setAggregateOperator(childNode, op, returnType, loc); 345 346 // if not folded, we'll still have an aggregate node to propagate precision with 347 if (node->getAsAggregate()) { 348 TPrecisionQualifier correctPrecision = returnType.getQualifier().precision; 349 if (correctPrecision == EpqNone && profile == EEsProfile) { 350 // find the maximum precision from the arguments, for the built-in's return precision 351 TIntermSequence& sequence = node->getAsAggregate()->getSequence(); 352 for (unsigned int arg = 0; arg < sequence.size(); ++arg) 353 correctPrecision = std::max(correctPrecision, sequence[arg]->getAsTyped()->getQualifier().precision); 354 } 355 356 // Propagate precision through this node and its children. That algorithm stops 357 // when a precision is found, so start by clearing this subroot precision 358 node->getQualifier().precision = EpqNone; 359 node->propagatePrecision(correctPrecision); 360 } 361 362 return node; 363 } 364 } 365 366 // 367 // This is the safe way to change the operator on an aggregate, as it 368 // does lots of error checking and fixing. Especially for establishing 369 // a function call's operation on it's set of parameters. Sequences 370 // of instructions are also aggregates, but they just directly set 371 // their operator to EOpSequence. 372 // 373 // Returns an aggregate node, which could be the one passed in if 374 // it was already an aggregate. 375 // 376 TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc loc) 377 { 378 TIntermAggregate* aggNode; 379 380 // 381 // Make sure we have an aggregate. If not turn it into one. 382 // 383 if (node) { 384 aggNode = node->getAsAggregate(); 385 if (aggNode == 0 || aggNode->getOp() != EOpNull) { 386 // 387 // Make an aggregate containing this node. 388 // 389 aggNode = new TIntermAggregate(); 390 aggNode->getSequence().push_back(node); 391 if (loc.line == 0) 392 loc = node->getLoc(); 393 } 394 } else 395 aggNode = new TIntermAggregate(); 396 397 // 398 // Set the operator. 399 // 400 aggNode->setOperator(op); 401 if (loc.line != 0) 402 aggNode->setLoc(loc); 403 404 aggNode->setType(type); 405 406 return fold(aggNode); 407 } 408 409 // 410 // Convert the node's type to the given type, as allowed by the operation involved: 'op'. 411 // For implicit conversions, 'op' is not the requested conversion, it is the explicit 412 // operation requiring the implicit conversion. 413 // 414 // Returns a node representing the conversion, which could be the same 415 // node passed in if no conversion was needed. 416 // 417 // Return 0 if a conversion can't be done. 418 // 419 TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) const 420 { 421 // 422 // Does the base type even allow the operation? 423 // 424 switch (node->getBasicType()) { 425 case EbtVoid: 426 return 0; 427 case EbtAtomicUint: 428 case EbtSampler: 429 // opaque types can be passed to functions 430 if (op == EOpFunction) 431 break; 432 // samplers can get assigned via a sampler constructor 433 // (well, not yet, but code in the rest of this function is ready for it) 434 if (node->getBasicType() == EbtSampler && op == EOpAssign && 435 node->getAsOperator() != nullptr && node->getAsOperator()->getOp() == EOpConstructTextureSampler) 436 break; 437 438 // otherwise, opaque types can't even be operated on, let alone converted 439 return 0; 440 default: 441 break; 442 } 443 444 // Otherwise, if types are identical, no problem 445 if (type == node->getType()) 446 return node; 447 448 // If one's a structure, then no conversions. 449 if (type.isStruct() || node->isStruct()) 450 return 0; 451 452 // If one's an array, then no conversions. 453 if (type.isArray() || node->getType().isArray()) 454 return 0; 455 456 // Note: callers are responsible for other aspects of shape, 457 // like vector and matrix sizes. 458 459 TBasicType promoteTo; 460 461 switch (op) { 462 // 463 // Explicit conversions (unary operations) 464 // 465 case EOpConstructBool: 466 promoteTo = EbtBool; 467 break; 468 case EOpConstructFloat: 469 promoteTo = EbtFloat; 470 break; 471 case EOpConstructDouble: 472 promoteTo = EbtDouble; 473 break; 474 case EOpConstructInt: 475 promoteTo = EbtInt; 476 break; 477 case EOpConstructUint: 478 promoteTo = EbtUint; 479 break; 480 case EOpConstructInt64: 481 promoteTo = EbtInt64; 482 break; 483 case EOpConstructUint64: 484 promoteTo = EbtUint64; 485 break; 486 487 // 488 // List all the binary ops that can implicitly convert one operand to the other's type; 489 // This implements the 'policy' for implicit type conversion. 490 // 491 case EOpLessThan: 492 case EOpGreaterThan: 493 case EOpLessThanEqual: 494 case EOpGreaterThanEqual: 495 case EOpEqual: 496 case EOpNotEqual: 497 498 case EOpAdd: 499 case EOpSub: 500 case EOpMul: 501 case EOpDiv: 502 case EOpMod: 503 504 case EOpVectorTimesScalar: 505 case EOpVectorTimesMatrix: 506 case EOpMatrixTimesVector: 507 case EOpMatrixTimesScalar: 508 509 case EOpAnd: 510 case EOpInclusiveOr: 511 case EOpExclusiveOr: 512 case EOpAndAssign: 513 case EOpInclusiveOrAssign: 514 case EOpExclusiveOrAssign: 515 516 case EOpFunctionCall: 517 case EOpReturn: 518 case EOpAssign: 519 case EOpAddAssign: 520 case EOpSubAssign: 521 case EOpMulAssign: 522 case EOpVectorTimesScalarAssign: 523 case EOpMatrixTimesScalarAssign: 524 case EOpDivAssign: 525 case EOpModAssign: 526 527 case EOpSequence: 528 case EOpConstructStruct: 529 530 if (type.getBasicType() == node->getType().getBasicType()) 531 return node; 532 533 if (canImplicitlyPromote(node->getType().getBasicType(), type.getBasicType())) 534 promoteTo = type.getBasicType(); 535 else 536 return 0; 537 538 break; 539 540 // Shifts can have mixed types as long as they are integer, without converting. 541 // It's the left operand's type that determines the resulting type, so no issue 542 // with assign shift ops either. 543 case EOpLeftShift: 544 case EOpRightShift: 545 case EOpLeftShiftAssign: 546 case EOpRightShiftAssign: 547 if ((type.getBasicType() == EbtInt || 548 type.getBasicType() == EbtUint || 549 type.getBasicType() == EbtInt64 || 550 type.getBasicType() == EbtUint64) && 551 (node->getType().getBasicType() == EbtInt || 552 node->getType().getBasicType() == EbtUint || 553 node->getType().getBasicType() == EbtInt64 || 554 node->getType().getBasicType() == EbtUint64)) 555 556 return node; 557 else 558 return 0; 559 560 default: 561 // default is to require a match; all exceptions should have case statements above 562 563 if (type.getBasicType() == node->getType().getBasicType()) 564 return node; 565 else 566 return 0; 567 } 568 569 if (node->getAsConstantUnion()) 570 return promoteConstantUnion(promoteTo, node->getAsConstantUnion()); 571 572 // 573 // Add a new newNode for the conversion. 574 // 575 TIntermUnary* newNode = 0; 576 577 TOperator newOp = EOpNull; 578 579 // This is 'mechanism' here, it does any conversion told. The policy comes 580 // from the shader or the above code. 581 switch (promoteTo) { 582 case EbtDouble: 583 switch (node->getBasicType()) { 584 case EbtInt: newOp = EOpConvIntToDouble; break; 585 case EbtUint: newOp = EOpConvUintToDouble; break; 586 case EbtBool: newOp = EOpConvBoolToDouble; break; 587 case EbtFloat: newOp = EOpConvFloatToDouble; break; 588 case EbtInt64: newOp = EOpConvInt64ToDouble; break; 589 case EbtUint64: newOp = EOpConvUint64ToDouble; break; 590 default: 591 return 0; 592 } 593 break; 594 case EbtFloat: 595 switch (node->getBasicType()) { 596 case EbtInt: newOp = EOpConvIntToFloat; break; 597 case EbtUint: newOp = EOpConvUintToFloat; break; 598 case EbtBool: newOp = EOpConvBoolToFloat; break; 599 case EbtDouble: newOp = EOpConvDoubleToFloat; break; 600 case EbtInt64: newOp = EOpConvInt64ToFloat; break; 601 case EbtUint64: newOp = EOpConvUint64ToFloat; break; 602 default: 603 return 0; 604 } 605 break; 606 case EbtBool: 607 switch (node->getBasicType()) { 608 case EbtInt: newOp = EOpConvIntToBool; break; 609 case EbtUint: newOp = EOpConvUintToBool; break; 610 case EbtFloat: newOp = EOpConvFloatToBool; break; 611 case EbtDouble: newOp = EOpConvDoubleToBool; break; 612 case EbtInt64: newOp = EOpConvInt64ToBool; break; 613 case EbtUint64: newOp = EOpConvUint64ToBool; break; 614 default: 615 return 0; 616 } 617 break; 618 case EbtInt: 619 switch (node->getBasicType()) { 620 case EbtUint: newOp = EOpConvUintToInt; break; 621 case EbtBool: newOp = EOpConvBoolToInt; break; 622 case EbtFloat: newOp = EOpConvFloatToInt; break; 623 case EbtDouble: newOp = EOpConvDoubleToInt; break; 624 case EbtInt64: newOp = EOpConvInt64ToInt; break; 625 case EbtUint64: newOp = EOpConvUint64ToInt; break; 626 default: 627 return 0; 628 } 629 break; 630 case EbtUint: 631 switch (node->getBasicType()) { 632 case EbtInt: newOp = EOpConvIntToUint; break; 633 case EbtBool: newOp = EOpConvBoolToUint; break; 634 case EbtFloat: newOp = EOpConvFloatToUint; break; 635 case EbtDouble: newOp = EOpConvDoubleToUint; break; 636 case EbtInt64: newOp = EOpConvInt64ToUint; break; 637 case EbtUint64: newOp = EOpConvUint64ToUint; break; 638 default: 639 return 0; 640 } 641 break; 642 case EbtInt64: 643 switch (node->getBasicType()) { 644 case EbtInt: newOp = EOpConvIntToInt64; break; 645 case EbtUint: newOp = EOpConvUintToInt64; break; 646 case EbtBool: newOp = EOpConvBoolToInt64; break; 647 case EbtFloat: newOp = EOpConvFloatToInt64; break; 648 case EbtDouble: newOp = EOpConvDoubleToInt64; break; 649 case EbtUint64: newOp = EOpConvUint64ToInt64; break; 650 default: 651 return 0; 652 } 653 break; 654 case EbtUint64: 655 switch (node->getBasicType()) { 656 case EbtInt: newOp = EOpConvIntToUint64; break; 657 case EbtUint: newOp = EOpConvUintToUint64; break; 658 case EbtBool: newOp = EOpConvBoolToUint64; break; 659 case EbtFloat: newOp = EOpConvFloatToUint64; break; 660 case EbtDouble: newOp = EOpConvDoubleToUint64; break; 661 case EbtInt64: newOp = EOpConvInt64ToUint64; break; 662 default: 663 return 0; 664 } 665 break; 666 default: 667 return 0; 668 } 669 670 TType newType(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows()); 671 newNode = new TIntermUnary(newOp, newType); 672 newNode->setLoc(node->getLoc()); 673 newNode->setOperand(node); 674 675 // TODO: it seems that some unary folding operations should occur here, but are not 676 677 // Propagate specialization-constant-ness, if allowed 678 if (node->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*newNode)) 679 newNode->getWritableType().getQualifier().makeSpecConstant(); 680 681 return newNode; 682 } 683 684 // 685 // See if the 'from' type is allowed to be implicitly converted to the 686 // 'to' type. This is not about vector/array/struct, only about basic type. 687 // 688 bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to) const 689 { 690 if (profile == EEsProfile || version == 110) 691 return false; 692 693 switch (to) { 694 case EbtDouble: 695 switch (from) { 696 case EbtInt: 697 case EbtUint: 698 case EbtInt64: 699 case EbtUint64: 700 case EbtFloat: 701 case EbtDouble: 702 return true; 703 default: 704 return false; 705 } 706 case EbtFloat: 707 switch (from) { 708 case EbtInt: 709 case EbtUint: 710 case EbtFloat: 711 return true; 712 default: 713 return false; 714 } 715 case EbtUint: 716 switch (from) { 717 case EbtInt: 718 return version >= 400; 719 case EbtUint: 720 return true; 721 default: 722 return false; 723 } 724 case EbtInt: 725 switch (from) { 726 case EbtInt: 727 return true; 728 default: 729 return false; 730 } 731 case EbtUint64: 732 switch (from) { 733 case EbtInt: 734 case EbtUint: 735 case EbtInt64: 736 case EbtUint64: 737 return true; 738 default: 739 return false; 740 } 741 case EbtInt64: 742 switch (from) { 743 case EbtInt: 744 case EbtInt64: 745 return true; 746 default: 747 return false; 748 } 749 default: 750 return false; 751 } 752 } 753 754 // 755 // Safe way to combine two nodes into an aggregate. Works with null pointers, 756 // a node that's not a aggregate yet, etc. 757 // 758 // Returns the resulting aggregate, unless 0 was passed in for 759 // both existing nodes. 760 // 761 TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right) 762 { 763 if (left == 0 && right == 0) 764 return 0; 765 766 TIntermAggregate* aggNode = 0; 767 if (left) 768 aggNode = left->getAsAggregate(); 769 if (! aggNode || aggNode->getOp() != EOpNull) { 770 aggNode = new TIntermAggregate; 771 if (left) 772 aggNode->getSequence().push_back(left); 773 } 774 775 if (right) 776 aggNode->getSequence().push_back(right); 777 778 return aggNode; 779 } 780 781 TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& loc) 782 { 783 TIntermAggregate* aggNode = growAggregate(left, right); 784 if (aggNode) 785 aggNode->setLoc(loc); 786 787 return aggNode; 788 } 789 790 // 791 // Turn an existing node into an aggregate. 792 // 793 // Returns an aggregate, unless 0 was passed in for the existing node. 794 // 795 TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node) 796 { 797 if (node == 0) 798 return 0; 799 800 TIntermAggregate* aggNode = new TIntermAggregate; 801 aggNode->getSequence().push_back(node); 802 aggNode->setLoc(node->getLoc()); 803 804 return aggNode; 805 } 806 807 TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& loc) 808 { 809 if (node == 0) 810 return 0; 811 812 TIntermAggregate* aggNode = new TIntermAggregate; 813 aggNode->getSequence().push_back(node); 814 aggNode->setLoc(loc); 815 816 return aggNode; 817 } 818 819 // 820 // For "if" test nodes. There are three children; a condition, 821 // a true path, and a false path. The two paths are in the 822 // nodePair. 823 // 824 // Returns the selection node created. 825 // 826 TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc) 827 { 828 // 829 // Don't prune the false path for compile-time constants; it's needed 830 // for static access analysis. 831 // 832 833 TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2); 834 node->setLoc(loc); 835 836 return node; 837 } 838 839 840 TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc) 841 { 842 // However, the lowest precedence operators of the sequence operator ( , ) and the assignment operators 843 // ... are not included in the operators that can create a constant expression. 844 // 845 //if (left->getType().getQualifier().storage == EvqConst && 846 // right->getType().getQualifier().storage == EvqConst) { 847 848 // return right; 849 //} 850 851 TIntermTyped *commaAggregate = growAggregate(left, right, loc); 852 commaAggregate->getAsAggregate()->setOperator(EOpComma); 853 commaAggregate->setType(right->getType()); 854 commaAggregate->getWritableType().getQualifier().makeTemporary(); 855 856 return commaAggregate; 857 } 858 859 TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, const TSourceLoc& loc) 860 { 861 TIntermMethod* method = new TIntermMethod(object, type, *name); 862 method->setLoc(loc); 863 864 return method; 865 } 866 867 // 868 // For "?:" test nodes. There are three children; a condition, 869 // a true path, and a false path. The two paths are specified 870 // as separate parameters. 871 // 872 // Returns the selection node created, or 0 if one could not be. 873 // 874 TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc) 875 { 876 // 877 // Get compatible types. 878 // 879 TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock); 880 if (child) 881 falseBlock = child; 882 else { 883 child = addConversion(EOpSequence, falseBlock->getType(), trueBlock); 884 if (child) 885 trueBlock = child; 886 else 887 return 0; 888 } 889 890 // After conversion, types have to match. 891 if (falseBlock->getType() != trueBlock->getType()) 892 return 0; 893 894 // 895 // See if all the operands are constant, then fold it otherwise not. 896 // 897 898 if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) { 899 if (cond->getAsConstantUnion()->getConstArray()[0].getBConst()) 900 return trueBlock; 901 else 902 return falseBlock; 903 } 904 905 // 906 // Make a selection node. 907 // 908 TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType()); 909 node->getQualifier().makeTemporary(); 910 node->setLoc(loc); 911 node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision); 912 913 return node; 914 } 915 916 // 917 // Constant terminal nodes. Has a union that contains bool, float or int constants 918 // 919 // Returns the constant union node created. 920 // 921 922 TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, const TSourceLoc& loc, bool literal) const 923 { 924 TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t); 925 node->getQualifier().storage = EvqConst; 926 node->setLoc(loc); 927 if (literal) 928 node->setLiteral(); 929 930 return node; 931 } 932 933 TIntermConstantUnion* TIntermediate::addConstantUnion(int i, const TSourceLoc& loc, bool literal) const 934 { 935 TConstUnionArray unionArray(1); 936 unionArray[0].setIConst(i); 937 938 return addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc, literal); 939 } 940 941 TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned int u, const TSourceLoc& loc, bool literal) const 942 { 943 TConstUnionArray unionArray(1); 944 unionArray[0].setUConst(u); 945 946 return addConstantUnion(unionArray, TType(EbtUint, EvqConst), loc, literal); 947 } 948 949 TIntermConstantUnion* TIntermediate::addConstantUnion(long long i64, const TSourceLoc& loc, bool literal) const 950 { 951 TConstUnionArray unionArray(1); 952 unionArray[0].setI64Const(i64); 953 954 return addConstantUnion(unionArray, TType(EbtInt64, EvqConst), loc, literal); 955 } 956 957 TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned long long u64, const TSourceLoc& loc, bool literal) const 958 { 959 TConstUnionArray unionArray(1); 960 unionArray[0].setU64Const(u64); 961 962 return addConstantUnion(unionArray, TType(EbtUint64, EvqConst), loc, literal); 963 } 964 965 TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const 966 { 967 TConstUnionArray unionArray(1); 968 unionArray[0].setBConst(b); 969 970 return addConstantUnion(unionArray, TType(EbtBool, EvqConst), loc, literal); 971 } 972 973 TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseType, const TSourceLoc& loc, bool literal) const 974 { 975 assert(baseType == EbtFloat || baseType == EbtDouble); 976 977 TConstUnionArray unionArray(1); 978 unionArray[0].setDConst(d); 979 980 return addConstantUnion(unionArray, TType(baseType, EvqConst), loc, literal); 981 } 982 983 TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc& loc) 984 { 985 TIntermAggregate* node = new TIntermAggregate(EOpSequence); 986 987 node->setLoc(loc); 988 TIntermConstantUnion* constIntNode; 989 TIntermSequence &sequenceVector = node->getSequence(); 990 991 for (int i = 0; i < fields.num; i++) { 992 constIntNode = addConstantUnion(fields.offsets[i], loc); 993 sequenceVector.push_back(constIntNode); 994 } 995 996 return node; 997 } 998 999 // 1000 // Follow the left branches down to the root of an l-value 1001 // expression (just "." and []). 1002 // 1003 // Return the base of the l-value (where following indexing quits working). 1004 // Return nullptr if a chain following dereferences cannot be followed. 1005 // 1006 // 'swizzleOkay' says whether or not it is okay to consider a swizzle 1007 // a valid part of the dereference chain. 1008 // 1009 const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay) 1010 { 1011 do { 1012 const TIntermBinary* binary = node->getAsBinaryNode(); 1013 if (binary == nullptr) 1014 return node; 1015 TOperator op = binary->getOp(); 1016 if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle) 1017 return nullptr; 1018 if (! swizzleOkay) { 1019 if (op == EOpVectorSwizzle) 1020 return nullptr; 1021 if ((op == EOpIndexDirect || op == EOpIndexIndirect) && 1022 (binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) && 1023 ! binary->getLeft()->getType().isArray()) 1024 return nullptr; 1025 } 1026 node = node->getAsBinaryNode()->getLeft(); 1027 } while (true); 1028 } 1029 1030 // 1031 // Create while and do-while loop nodes. 1032 // 1033 TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc) 1034 { 1035 TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst); 1036 node->setLoc(loc); 1037 1038 return node; 1039 } 1040 1041 // 1042 // Create a for-loop sequence. 1043 // 1044 TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc) 1045 { 1046 TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst); 1047 node->setLoc(loc); 1048 1049 // make a sequence of the initializer and statement 1050 TIntermAggregate* loopSequence = makeAggregate(initializer, loc); 1051 loopSequence = growAggregate(loopSequence, node); 1052 loopSequence->setOperator(EOpSequence); 1053 1054 return loopSequence; 1055 } 1056 1057 // 1058 // Add branches. 1059 // 1060 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& loc) 1061 { 1062 return addBranch(branchOp, 0, loc); 1063 } 1064 1065 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& loc) 1066 { 1067 TIntermBranch* node = new TIntermBranch(branchOp, expression); 1068 node->setLoc(loc); 1069 1070 return node; 1071 } 1072 1073 // 1074 // This is to be executed after the final root is put on top by the parsing 1075 // process. 1076 // 1077 bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/) 1078 { 1079 if (root == 0) 1080 return true; 1081 1082 // Finish off the top-level sequence 1083 TIntermAggregate* aggRoot = root->getAsAggregate(); 1084 if (aggRoot && aggRoot->getOp() == EOpNull) 1085 aggRoot->setOperator(EOpSequence); 1086 1087 // Propagate 'noContraction' label in backward from 'precise' variables. 1088 glslang::PropagateNoContraction(*this); 1089 1090 return true; 1091 } 1092 1093 void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage language, TSymbolTable& symbolTable) 1094 { 1095 // Add top-level nodes for declarations that must be checked cross 1096 // compilation unit by a linker, yet might not have been referenced 1097 // by the AST. 1098 // 1099 // Almost entirely, translation of symbols is driven by what's present 1100 // in the AST traversal, not by translating the symbol table. 1101 // 1102 // However, there are some special cases: 1103 // - From the specification: "Special built-in inputs gl_VertexID and 1104 // gl_InstanceID are also considered active vertex attributes." 1105 // - Linker-based type mismatch error reporting needs to see all 1106 // uniforms/ins/outs variables and blocks. 1107 // - ftransform() can make gl_Vertex and gl_ModelViewProjectionMatrix active. 1108 // 1109 1110 //if (ftransformUsed) { 1111 // TODO: 1.1 lowering functionality: track ftransform() usage 1112 // addSymbolLinkageNode(root, symbolTable, "gl_Vertex"); 1113 // addSymbolLinkageNode(root, symbolTable, "gl_ModelViewProjectionMatrix"); 1114 //} 1115 1116 if (language == EShLangVertex) { 1117 // the names won't be found in the symbol table unless the versions are right, 1118 // so version logic does not need to be repeated here 1119 addSymbolLinkageNode(linkage, symbolTable, "gl_VertexID"); 1120 addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID"); 1121 } 1122 1123 // Add a child to the root node for the linker objects 1124 linkage->setOperator(EOpLinkerObjects); 1125 treeRoot = growAggregate(treeRoot, linkage); 1126 } 1127 1128 // 1129 // Add the given name or symbol to the list of nodes at the end of the tree used 1130 // for link-time checking and external linkage. 1131 // 1132 1133 void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable& symbolTable, const TString& name) 1134 { 1135 TSymbol* symbol = symbolTable.find(name); 1136 if (symbol) 1137 addSymbolLinkageNode(linkage, *symbol->getAsVariable()); 1138 } 1139 1140 void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol& symbol) 1141 { 1142 const TVariable* variable = symbol.getAsVariable(); 1143 if (! variable) { 1144 // This must be a member of an anonymous block, and we need to add the whole block 1145 const TAnonMember* anon = symbol.getAsAnonMember(); 1146 variable = &anon->getAnonContainer(); 1147 } 1148 TIntermSymbol* node = addSymbol(*variable); 1149 linkage = growAggregate(linkage, node); 1150 } 1151 1152 // 1153 // Add a caller->callee relationship to the call graph. 1154 // Assumes the strings are unique per signature. 1155 // 1156 void TIntermediate::addToCallGraph(TInfoSink& /*infoSink*/, const TString& caller, const TString& callee) 1157 { 1158 // Duplicates are okay, but faster to not keep them, and they come grouped by caller, 1159 // as long as new ones are push on the same end we check on for duplicates 1160 for (TGraph::const_iterator call = callGraph.begin(); call != callGraph.end(); ++call) { 1161 if (call->caller != caller) 1162 break; 1163 if (call->callee == callee) 1164 return; 1165 } 1166 1167 callGraph.push_front(TCall(caller, callee)); 1168 } 1169 1170 // 1171 // This deletes the tree. 1172 // 1173 void TIntermediate::removeTree() 1174 { 1175 if (treeRoot) 1176 RemoveAllTreeNodes(treeRoot); 1177 } 1178 1179 // 1180 // Implement the part of KHR_vulkan_glsl that lists the set of operations 1181 // that can result in a specialization constant operation. 1182 // 1183 // "5.x Specialization Constant Operations" 1184 // 1185 // Only some operations discussed in this section may be applied to a 1186 // specialization constant and still yield a result that is as 1187 // specialization constant. The operations allowed are listed below. 1188 // When a specialization constant is operated on with one of these 1189 // operators and with another constant or specialization constant, the 1190 // result is implicitly a specialization constant. 1191 // 1192 // - int(), uint(), and bool() constructors for type conversions 1193 // from any of the following types to any of the following types: 1194 // * int 1195 // * uint 1196 // * bool 1197 // - vector versions of the above conversion constructors 1198 // - allowed implicit conversions of the above 1199 // - swizzles (e.g., foo.yx) 1200 // - The following when applied to integer or unsigned integer types: 1201 // * unary negative ( - ) 1202 // * binary operations ( + , - , * , / , % ) 1203 // * shift ( <<, >> ) 1204 // * bitwise operations ( & , | , ^ ) 1205 // - The following when applied to integer or unsigned integer scalar types: 1206 // * comparison ( == , != , > , >= , < , <= ) 1207 // - The following when applied to the Boolean scalar type: 1208 // * not ( ! ) 1209 // * logical operations ( && , || , ^^ ) 1210 // * comparison ( == , != )" 1211 // 1212 // This function just handles binary and unary nodes. Construction 1213 // rules are handled in construction paths that are not covered by the unary 1214 // and binary paths, while required conversions will still show up here 1215 // as unary converters in the from a construction operator. 1216 // 1217 bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const 1218 { 1219 // The operations resulting in floating point are quite limited 1220 // (However, some floating-point operations result in bool, like ">", 1221 // so are handled later.) 1222 if (node.getType().isFloatingDomain()) { 1223 switch (node.getOp()) { 1224 case EOpIndexDirect: 1225 case EOpIndexIndirect: 1226 case EOpIndexDirectStruct: 1227 case EOpVectorSwizzle: 1228 return true; 1229 default: 1230 return false; 1231 } 1232 } 1233 1234 // Check for floating-point arguments 1235 if (const TIntermBinary* bin = node.getAsBinaryNode()) 1236 if (bin->getLeft() ->getType().isFloatingDomain() || 1237 bin->getRight()->getType().isFloatingDomain()) 1238 return false; 1239 1240 // So, for now, we can assume everything left is non-floating-point... 1241 1242 // Now check for integer/bool-based operations 1243 switch (node.getOp()) { 1244 1245 // dereference/swizzle 1246 case EOpIndexDirect: 1247 case EOpIndexIndirect: 1248 case EOpIndexDirectStruct: 1249 case EOpVectorSwizzle: 1250 1251 // conversion constructors 1252 case EOpConvIntToBool: 1253 case EOpConvUintToBool: 1254 case EOpConvUintToInt: 1255 case EOpConvBoolToInt: 1256 case EOpConvIntToUint: 1257 case EOpConvBoolToUint: 1258 1259 // unary operations 1260 case EOpNegative: 1261 case EOpLogicalNot: 1262 case EOpBitwiseNot: 1263 1264 // binary operations 1265 case EOpAdd: 1266 case EOpSub: 1267 case EOpMul: 1268 case EOpVectorTimesScalar: 1269 case EOpDiv: 1270 case EOpMod: 1271 case EOpRightShift: 1272 case EOpLeftShift: 1273 case EOpAnd: 1274 case EOpInclusiveOr: 1275 case EOpExclusiveOr: 1276 case EOpLogicalOr: 1277 case EOpLogicalXor: 1278 case EOpLogicalAnd: 1279 case EOpEqual: 1280 case EOpNotEqual: 1281 case EOpLessThan: 1282 case EOpGreaterThan: 1283 case EOpLessThanEqual: 1284 case EOpGreaterThanEqual: 1285 return true; 1286 default: 1287 return false; 1288 } 1289 } 1290 1291 //////////////////////////////////////////////////////////////// 1292 // 1293 // Member functions of the nodes used for building the tree. 1294 // 1295 //////////////////////////////////////////////////////////////// 1296 1297 // 1298 // Say whether or not an operation node changes the value of a variable. 1299 // 1300 // Returns true if state is modified. 1301 // 1302 bool TIntermOperator::modifiesState() const 1303 { 1304 switch (op) { 1305 case EOpPostIncrement: 1306 case EOpPostDecrement: 1307 case EOpPreIncrement: 1308 case EOpPreDecrement: 1309 case EOpAssign: 1310 case EOpAddAssign: 1311 case EOpSubAssign: 1312 case EOpMulAssign: 1313 case EOpVectorTimesMatrixAssign: 1314 case EOpVectorTimesScalarAssign: 1315 case EOpMatrixTimesScalarAssign: 1316 case EOpMatrixTimesMatrixAssign: 1317 case EOpDivAssign: 1318 case EOpModAssign: 1319 case EOpAndAssign: 1320 case EOpInclusiveOrAssign: 1321 case EOpExclusiveOrAssign: 1322 case EOpLeftShiftAssign: 1323 case EOpRightShiftAssign: 1324 return true; 1325 default: 1326 return false; 1327 } 1328 } 1329 1330 // 1331 // returns true if the operator is for one of the constructors 1332 // 1333 bool TIntermOperator::isConstructor() const 1334 { 1335 return op > EOpConstructGuardStart && op < EOpConstructGuardEnd; 1336 } 1337 1338 // 1339 // Make sure the type of a unary operator is appropriate for its 1340 // combination of operation and operand type. 1341 // 1342 // Returns false in nothing makes sense. 1343 // 1344 bool TIntermUnary::promote() 1345 { 1346 switch (op) { 1347 case EOpLogicalNot: 1348 if (operand->getBasicType() != EbtBool) 1349 1350 return false; 1351 break; 1352 case EOpBitwiseNot: 1353 if (operand->getBasicType() != EbtInt && 1354 operand->getBasicType() != EbtUint && 1355 operand->getBasicType() != EbtInt64 && 1356 operand->getBasicType() != EbtUint64) 1357 1358 return false; 1359 break; 1360 case EOpNegative: 1361 case EOpPostIncrement: 1362 case EOpPostDecrement: 1363 case EOpPreIncrement: 1364 case EOpPreDecrement: 1365 if (operand->getBasicType() != EbtInt && 1366 operand->getBasicType() != EbtUint && 1367 operand->getBasicType() != EbtInt64 && 1368 operand->getBasicType() != EbtUint64 && 1369 operand->getBasicType() != EbtFloat && 1370 operand->getBasicType() != EbtDouble) 1371 1372 return false; 1373 break; 1374 1375 default: 1376 if (operand->getBasicType() != EbtFloat) 1377 1378 return false; 1379 } 1380 1381 setType(operand->getType()); 1382 getWritableType().getQualifier().makeTemporary(); 1383 1384 return true; 1385 } 1386 1387 void TIntermUnary::updatePrecision() 1388 { 1389 if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) { 1390 if (operand->getQualifier().precision > getQualifier().precision) 1391 getQualifier().precision = operand->getQualifier().precision; 1392 } 1393 } 1394 1395 // 1396 // Establishes the type of the resultant operation, as well as 1397 // makes the operator the correct one for the operands. 1398 // 1399 // Returns false if operator can't work on operands. 1400 // 1401 bool TIntermBinary::promote() 1402 { 1403 // Arrays and structures have to be exact matches. 1404 if ((left->isArray() || right->isArray() || left->getBasicType() == EbtStruct || right->getBasicType() == EbtStruct) 1405 && left->getType() != right->getType()) 1406 return false; 1407 1408 // Base assumption: just make the type the same as the left 1409 // operand. Only deviations from this will be coded. 1410 setType(left->getType()); 1411 type.getQualifier().clear(); 1412 1413 // Composite and opaque types don't having pending operator changes, e.g., 1414 // array, structure, and samplers. Just establish final type and correctness. 1415 if (left->isArray() || left->getBasicType() == EbtStruct || left->getBasicType() == EbtSampler) { 1416 switch (op) { 1417 case EOpEqual: 1418 case EOpNotEqual: 1419 if (left->getBasicType() == EbtSampler) { 1420 // can't compare samplers 1421 return false; 1422 } else { 1423 // Promote to conditional 1424 setType(TType(EbtBool)); 1425 } 1426 1427 return true; 1428 1429 case EOpAssign: 1430 // Keep type from above 1431 1432 return true; 1433 1434 default: 1435 return false; 1436 } 1437 } 1438 1439 // 1440 // We now have only scalars, vectors, and matrices to worry about. 1441 // 1442 1443 // Do general type checks against individual operands (comparing left and right is coming up, checking mixed shapes after that) 1444 switch (op) { 1445 case EOpLessThan: 1446 case EOpGreaterThan: 1447 case EOpLessThanEqual: 1448 case EOpGreaterThanEqual: 1449 // Relational comparisons need matching numeric types and will promote to scalar Boolean. 1450 if (left->getBasicType() == EbtBool || left->getType().isVector() || left->getType().isMatrix()) 1451 return false; 1452 1453 // Fall through 1454 1455 case EOpEqual: 1456 case EOpNotEqual: 1457 // All the above comparisons result in a bool (but not the vector compares) 1458 setType(TType(EbtBool)); 1459 break; 1460 1461 case EOpLogicalAnd: 1462 case EOpLogicalOr: 1463 case EOpLogicalXor: 1464 // logical ops operate only on scalar Booleans and will promote to scalar Boolean. 1465 if (left->getBasicType() != EbtBool || left->isVector() || left->isMatrix()) 1466 return false; 1467 1468 setType(TType(EbtBool)); 1469 break; 1470 1471 case EOpRightShift: 1472 case EOpLeftShift: 1473 case EOpRightShiftAssign: 1474 case EOpLeftShiftAssign: 1475 1476 case EOpMod: 1477 case EOpModAssign: 1478 1479 case EOpAnd: 1480 case EOpInclusiveOr: 1481 case EOpExclusiveOr: 1482 case EOpAndAssign: 1483 case EOpInclusiveOrAssign: 1484 case EOpExclusiveOrAssign: 1485 // Check for integer-only operands. 1486 if ((left->getBasicType() != EbtInt && left->getBasicType() != EbtUint && 1487 left->getBasicType() != EbtInt64 && left->getBasicType() != EbtUint64) || 1488 (right->getBasicType() != EbtInt && right->getBasicType() != EbtUint && 1489 right->getBasicType() != EbtInt64 && right->getBasicType() != EbtUint64)) 1490 return false; 1491 if (left->isMatrix() || right->isMatrix()) 1492 return false; 1493 1494 break; 1495 1496 case EOpAdd: 1497 case EOpSub: 1498 case EOpDiv: 1499 case EOpMul: 1500 case EOpAddAssign: 1501 case EOpSubAssign: 1502 case EOpMulAssign: 1503 case EOpDivAssign: 1504 // check for non-Boolean operands 1505 if (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool) 1506 return false; 1507 1508 default: 1509 break; 1510 } 1511 1512 // Compare left and right, and finish with the cases where the operand types must match 1513 switch (op) { 1514 case EOpLessThan: 1515 case EOpGreaterThan: 1516 case EOpLessThanEqual: 1517 case EOpGreaterThanEqual: 1518 1519 case EOpEqual: 1520 case EOpNotEqual: 1521 1522 case EOpLogicalAnd: 1523 case EOpLogicalOr: 1524 case EOpLogicalXor: 1525 return left->getType() == right->getType(); 1526 1527 // no shifts: they can mix types (scalar int can shift a vector uint, etc.) 1528 1529 case EOpMod: 1530 case EOpModAssign: 1531 1532 case EOpAnd: 1533 case EOpInclusiveOr: 1534 case EOpExclusiveOr: 1535 case EOpAndAssign: 1536 case EOpInclusiveOrAssign: 1537 case EOpExclusiveOrAssign: 1538 1539 case EOpAdd: 1540 case EOpSub: 1541 case EOpDiv: 1542 case EOpAddAssign: 1543 case EOpSubAssign: 1544 case EOpDivAssign: 1545 // Quick out in case the types do match 1546 if (left->getType() == right->getType()) 1547 return true; 1548 1549 // Fall through 1550 1551 case EOpMul: 1552 case EOpMulAssign: 1553 // At least the basic type has to match 1554 if (left->getBasicType() != right->getBasicType()) 1555 return false; 1556 1557 default: 1558 break; 1559 } 1560 1561 // Finish handling the case, for all ops, where both operands are scalars. 1562 if (left->isScalar() && right->isScalar()) 1563 return true; 1564 1565 // Finish handling the case, for all ops, where there are two vectors of different sizes 1566 if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize()) 1567 return false; 1568 1569 // 1570 // We now have a mix of scalars, vectors, or matrices, for non-relational operations. 1571 // 1572 1573 // Can these two operands be combined, what is the resulting type? 1574 TBasicType basicType = left->getBasicType(); 1575 switch (op) { 1576 case EOpMul: 1577 if (!left->isMatrix() && right->isMatrix()) { 1578 if (left->isVector()) { 1579 if (left->getVectorSize() != right->getMatrixRows()) 1580 return false; 1581 op = EOpVectorTimesMatrix; 1582 setType(TType(basicType, EvqTemporary, right->getMatrixCols())); 1583 } else { 1584 op = EOpMatrixTimesScalar; 1585 setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), right->getMatrixRows())); 1586 } 1587 } else if (left->isMatrix() && !right->isMatrix()) { 1588 if (right->isVector()) { 1589 if (left->getMatrixCols() != right->getVectorSize()) 1590 return false; 1591 op = EOpMatrixTimesVector; 1592 setType(TType(basicType, EvqTemporary, left->getMatrixRows())); 1593 } else { 1594 op = EOpMatrixTimesScalar; 1595 } 1596 } else if (left->isMatrix() && right->isMatrix()) { 1597 if (left->getMatrixCols() != right->getMatrixRows()) 1598 return false; 1599 op = EOpMatrixTimesMatrix; 1600 setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), left->getMatrixRows())); 1601 } else if (! left->isMatrix() && ! right->isMatrix()) { 1602 if (left->isVector() && right->isVector()) { 1603 ; // leave as component product 1604 } else if (left->isVector() || right->isVector()) { 1605 op = EOpVectorTimesScalar; 1606 if (right->isVector()) 1607 setType(TType(basicType, EvqTemporary, right->getVectorSize())); 1608 } 1609 } else { 1610 return false; 1611 } 1612 break; 1613 case EOpMulAssign: 1614 if (! left->isMatrix() && right->isMatrix()) { 1615 if (left->isVector()) { 1616 if (left->getVectorSize() != right->getMatrixRows() || left->getVectorSize() != right->getMatrixCols()) 1617 return false; 1618 op = EOpVectorTimesMatrixAssign; 1619 } else { 1620 return false; 1621 } 1622 } else if (left->isMatrix() && !right->isMatrix()) { 1623 if (right->isVector()) { 1624 return false; 1625 } else { 1626 op = EOpMatrixTimesScalarAssign; 1627 } 1628 } else if (left->isMatrix() && right->isMatrix()) { 1629 if (left->getMatrixCols() != left->getMatrixRows() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixCols() != right->getMatrixRows()) 1630 return false; 1631 op = EOpMatrixTimesMatrixAssign; 1632 } else if (!left->isMatrix() && !right->isMatrix()) { 1633 if (left->isVector() && right->isVector()) { 1634 // leave as component product 1635 } else if (left->isVector() || right->isVector()) { 1636 if (! left->isVector()) 1637 return false; 1638 op = EOpVectorTimesScalarAssign; 1639 } 1640 } else { 1641 return false; 1642 } 1643 break; 1644 1645 case EOpRightShift: 1646 case EOpLeftShift: 1647 case EOpRightShiftAssign: 1648 case EOpLeftShiftAssign: 1649 if (right->isVector() && (! left->isVector() || right->getVectorSize() != left->getVectorSize())) 1650 return false; 1651 break; 1652 1653 case EOpAssign: 1654 if (left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows()) 1655 return false; 1656 // fall through 1657 1658 case EOpAdd: 1659 case EOpSub: 1660 case EOpDiv: 1661 case EOpMod: 1662 case EOpAnd: 1663 case EOpInclusiveOr: 1664 case EOpExclusiveOr: 1665 case EOpAddAssign: 1666 case EOpSubAssign: 1667 case EOpDivAssign: 1668 case EOpModAssign: 1669 case EOpAndAssign: 1670 case EOpInclusiveOrAssign: 1671 case EOpExclusiveOrAssign: 1672 if ((left->isMatrix() && right->isVector()) || 1673 (left->isVector() && right->isMatrix()) || 1674 left->getBasicType() != right->getBasicType()) 1675 return false; 1676 if (left->isMatrix() && right->isMatrix() && (left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows())) 1677 return false; 1678 if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize()) 1679 return false; 1680 if (right->isVector() || right->isMatrix()) { 1681 type.shallowCopy(right->getType()); 1682 type.getQualifier().makeTemporary(); 1683 } 1684 break; 1685 1686 default: 1687 return false; 1688 } 1689 1690 // 1691 // One more check for assignment. 1692 // 1693 switch (op) { 1694 // The resulting type has to match the left operand. 1695 case EOpAssign: 1696 case EOpAddAssign: 1697 case EOpSubAssign: 1698 case EOpMulAssign: 1699 case EOpDivAssign: 1700 case EOpModAssign: 1701 case EOpAndAssign: 1702 case EOpInclusiveOrAssign: 1703 case EOpExclusiveOrAssign: 1704 case EOpLeftShiftAssign: 1705 case EOpRightShiftAssign: 1706 if (getType() != left->getType()) 1707 return false; 1708 break; 1709 default: 1710 break; 1711 } 1712 1713 return true; 1714 } 1715 1716 void TIntermBinary::updatePrecision() 1717 { 1718 if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) { 1719 getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision); 1720 if (getQualifier().precision != EpqNone) { 1721 left->propagatePrecision(getQualifier().precision); 1722 right->propagatePrecision(getQualifier().precision); 1723 } 1724 } 1725 } 1726 1727 void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision) 1728 { 1729 if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat)) 1730 return; 1731 1732 getQualifier().precision = newPrecision; 1733 1734 TIntermBinary* binaryNode = getAsBinaryNode(); 1735 if (binaryNode) { 1736 binaryNode->getLeft()->propagatePrecision(newPrecision); 1737 binaryNode->getRight()->propagatePrecision(newPrecision); 1738 1739 return; 1740 } 1741 1742 TIntermUnary* unaryNode = getAsUnaryNode(); 1743 if (unaryNode) { 1744 unaryNode->getOperand()->propagatePrecision(newPrecision); 1745 1746 return; 1747 } 1748 1749 TIntermAggregate* aggregateNode = getAsAggregate(); 1750 if (aggregateNode) { 1751 TIntermSequence operands = aggregateNode->getSequence(); 1752 for (unsigned int i = 0; i < operands.size(); ++i) { 1753 TIntermTyped* typedNode = operands[i]->getAsTyped(); 1754 if (! typedNode) 1755 break; 1756 typedNode->propagatePrecision(newPrecision); 1757 } 1758 1759 return; 1760 } 1761 1762 TIntermSelection* selectionNode = getAsSelectionNode(); 1763 if (selectionNode) { 1764 TIntermTyped* typedNode = selectionNode->getTrueBlock()->getAsTyped(); 1765 if (typedNode) { 1766 typedNode->propagatePrecision(newPrecision); 1767 typedNode = selectionNode->getFalseBlock()->getAsTyped(); 1768 if (typedNode) 1769 typedNode->propagatePrecision(newPrecision); 1770 } 1771 1772 return; 1773 } 1774 } 1775 1776 TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) const 1777 { 1778 const TConstUnionArray& rightUnionArray = node->getConstArray(); 1779 int size = node->getType().computeNumComponents(); 1780 1781 TConstUnionArray leftUnionArray(size); 1782 1783 for (int i=0; i < size; i++) { 1784 switch (promoteTo) { 1785 case EbtFloat: 1786 switch (node->getType().getBasicType()) { 1787 case EbtInt: 1788 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst())); 1789 break; 1790 case EbtUint: 1791 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst())); 1792 break; 1793 case EbtInt64: 1794 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getI64Const())); 1795 break; 1796 case EbtUint64: 1797 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getU64Const())); 1798 break; 1799 case EbtBool: 1800 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst())); 1801 break; 1802 case EbtFloat: 1803 leftUnionArray[i] = rightUnionArray[i]; 1804 break; 1805 case EbtDouble: 1806 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getDConst())); 1807 break; 1808 default: 1809 return node; 1810 } 1811 break; 1812 case EbtDouble: 1813 switch (node->getType().getBasicType()) { 1814 case EbtInt: 1815 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst())); 1816 break; 1817 case EbtUint: 1818 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst())); 1819 break; 1820 case EbtInt64: 1821 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getI64Const())); 1822 break; 1823 case EbtUint64: 1824 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getU64Const())); 1825 break; 1826 case EbtBool: 1827 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst())); 1828 break; 1829 case EbtFloat: 1830 case EbtDouble: 1831 leftUnionArray[i] = rightUnionArray[i]; 1832 break; 1833 default: 1834 return node; 1835 } 1836 break; 1837 case EbtInt: 1838 switch (node->getType().getBasicType()) { 1839 case EbtInt: 1840 leftUnionArray[i] = rightUnionArray[i]; 1841 break; 1842 case EbtUint: 1843 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getUConst())); 1844 break; 1845 case EbtInt64: 1846 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getI64Const())); 1847 break; 1848 case EbtUint64: 1849 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getU64Const())); 1850 break; 1851 case EbtBool: 1852 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getBConst())); 1853 break; 1854 case EbtFloat: 1855 case EbtDouble: 1856 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getDConst())); 1857 break; 1858 default: 1859 return node; 1860 } 1861 break; 1862 case EbtUint: 1863 switch (node->getType().getBasicType()) { 1864 case EbtInt: 1865 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getIConst())); 1866 break; 1867 case EbtUint: 1868 leftUnionArray[i] = rightUnionArray[i]; 1869 break; 1870 case EbtInt64: 1871 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getI64Const())); 1872 break; 1873 case EbtUint64: 1874 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getU64Const())); 1875 break; 1876 case EbtBool: 1877 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getBConst())); 1878 break; 1879 case EbtFloat: 1880 case EbtDouble: 1881 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getDConst())); 1882 break; 1883 default: 1884 return node; 1885 } 1886 break; 1887 case EbtBool: 1888 switch (node->getType().getBasicType()) { 1889 case EbtInt: 1890 leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0); 1891 break; 1892 case EbtUint: 1893 leftUnionArray[i].setBConst(rightUnionArray[i].getUConst() != 0); 1894 break; 1895 case EbtInt64: 1896 leftUnionArray[i].setBConst(rightUnionArray[i].getI64Const() != 0); 1897 break; 1898 case EbtUint64: 1899 leftUnionArray[i].setBConst(rightUnionArray[i].getU64Const() != 0); 1900 break; 1901 case EbtBool: 1902 leftUnionArray[i] = rightUnionArray[i]; 1903 break; 1904 case EbtFloat: 1905 case EbtDouble: 1906 leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0); 1907 break; 1908 default: 1909 return node; 1910 } 1911 break; 1912 case EbtInt64: 1913 switch (node->getType().getBasicType()) { 1914 case EbtInt: 1915 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getIConst())); 1916 break; 1917 case EbtUint: 1918 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getUConst())); 1919 break; 1920 case EbtInt64: 1921 leftUnionArray[i] = rightUnionArray[i]; 1922 break; 1923 case EbtUint64: 1924 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getU64Const())); 1925 break; 1926 case EbtBool: 1927 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getBConst())); 1928 break; 1929 case EbtFloat: 1930 case EbtDouble: 1931 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getDConst())); 1932 break; 1933 default: 1934 return node; 1935 } 1936 break; 1937 case EbtUint64: 1938 switch (node->getType().getBasicType()) { 1939 case EbtInt: 1940 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getIConst())); 1941 break; 1942 case EbtUint: 1943 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getUConst())); 1944 break; 1945 case EbtInt64: 1946 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getI64Const())); 1947 break; 1948 case EbtUint64: 1949 leftUnionArray[i] = rightUnionArray[i]; 1950 break; 1951 case EbtBool: 1952 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getBConst())); 1953 break; 1954 case EbtFloat: 1955 case EbtDouble: 1956 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getDConst())); 1957 break; 1958 default: 1959 return node; 1960 } 1961 break; 1962 default: 1963 return node; 1964 } 1965 } 1966 1967 const TType& t = node->getType(); 1968 1969 return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getVectorSize(), t.getMatrixCols(), t.getMatrixRows()), 1970 node->getLoc()); 1971 } 1972 1973 void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable) 1974 { 1975 assert(!pragmaTable); 1976 pragmaTable = new TPragmaTable(); 1977 *pragmaTable = pTable; 1978 } 1979 1980 } // end namespace glslang 1981