1 // Copyright (c) 2016 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // This file provides a class hierarchy for representing SPIR-V types. 16 17 #ifndef SOURCE_OPT_TYPES_H_ 18 #define SOURCE_OPT_TYPES_H_ 19 20 #include <map> 21 #include <memory> 22 #include <set> 23 #include <string> 24 #include <unordered_map> 25 #include <unordered_set> 26 #include <utility> 27 #include <vector> 28 29 #include "source/latest_version_spirv_header.h" 30 #include "source/opt/instruction.h" 31 #include "source/util/small_vector.h" 32 #include "spirv-tools/libspirv.h" 33 34 namespace spvtools { 35 namespace opt { 36 namespace analysis { 37 38 class Void; 39 class Bool; 40 class Integer; 41 class Float; 42 class Vector; 43 class Matrix; 44 class Image; 45 class Sampler; 46 class SampledImage; 47 class Array; 48 class RuntimeArray; 49 class Struct; 50 class Opaque; 51 class Pointer; 52 class Function; 53 class Event; 54 class DeviceEvent; 55 class ReserveId; 56 class Queue; 57 class Pipe; 58 class ForwardPointer; 59 class PipeStorage; 60 class NamedBarrier; 61 class AccelerationStructureNV; 62 class CooperativeMatrixNV; 63 class CooperativeMatrixKHR; 64 class RayQueryKHR; 65 class HitObjectNV; 66 67 // Abstract class for a SPIR-V type. It has a bunch of As<sublcass>() methods, 68 // which is used as a way to probe the actual <subclass>. 69 class Type { 70 public: 71 typedef std::set<std::pair<const Pointer*, const Pointer*>> IsSameCache; 72 73 using SeenTypes = spvtools::utils::SmallVector<const Type*, 8>; 74 75 // Available subtypes. 76 // 77 // When adding a new derived class of Type, please add an entry to the enum. 78 enum Kind { 79 kVoid, 80 kBool, 81 kInteger, 82 kFloat, 83 kVector, 84 kMatrix, 85 kImage, 86 kSampler, 87 kSampledImage, 88 kArray, 89 kRuntimeArray, 90 kStruct, 91 kOpaque, 92 kPointer, 93 kFunction, 94 kEvent, 95 kDeviceEvent, 96 kReserveId, 97 kQueue, 98 kPipe, 99 kForwardPointer, 100 kPipeStorage, 101 kNamedBarrier, 102 kAccelerationStructureNV, 103 kCooperativeMatrixNV, 104 kCooperativeMatrixKHR, 105 kRayQueryKHR, 106 kHitObjectNV, 107 kLast 108 }; 109 Type(Kind k)110 Type(Kind k) : kind_(k) {} 111 112 virtual ~Type() = default; 113 114 // Attaches a decoration directly on this type. AddDecoration(std::vector<uint32_t> && d)115 void AddDecoration(std::vector<uint32_t>&& d) { 116 decorations_.push_back(std::move(d)); 117 } 118 // Returns the decorations on this type as a string. 119 std::string GetDecorationStr() const; 120 // Returns true if this type has exactly the same decorations as |that| type. 121 bool HasSameDecorations(const Type* that) const; 122 // Returns true if this type is exactly the same as |that| type, including 123 // decorations. IsSame(const Type * that)124 bool IsSame(const Type* that) const { 125 IsSameCache seen; 126 return IsSameImpl(that, &seen); 127 } 128 129 // Returns true if this type is exactly the same as |that| type, including 130 // decorations. |seen| is the set of |Pointer*| pair that are currently being 131 // compared in a parent call to |IsSameImpl|. 132 virtual bool IsSameImpl(const Type* that, IsSameCache* seen) const = 0; 133 134 // Returns a human-readable string to represent this type. 135 virtual std::string str() const = 0; 136 kind()137 Kind kind() const { return kind_; } decorations()138 const std::vector<std::vector<uint32_t>>& decorations() const { 139 return decorations_; 140 } 141 142 // Returns true if there is no decoration on this type. For struct types, 143 // returns true only when there is no decoration for both the struct type 144 // and the struct members. decoration_empty()145 virtual bool decoration_empty() const { return decorations_.empty(); } 146 147 // Creates a clone of |this|. 148 std::unique_ptr<Type> Clone() const; 149 150 // Returns a clone of |this| minus any decorations. 151 std::unique_ptr<Type> RemoveDecorations() const; 152 153 // Returns true if this cannot hash to the same value as another type in the 154 // module. For example, structs are not unique types because the module could 155 // have two types 156 // 157 // %1 = OpTypeStruct %int 158 // %2 = OpTypeStruct %int 159 // 160 // The only way to distinguish these types is the result id. The type manager 161 // will hash them to the same value. 162 bool IsUniqueType() const; 163 164 bool operator==(const Type& other) const; 165 166 // Returns the hash value of this type. 167 size_t HashValue() const; 168 169 size_t ComputeHashValue(size_t hash, SeenTypes* seen) const; 170 171 // Returns the number of components in a composite type. Returns 0 for a 172 // non-composite type. 173 uint64_t NumberOfComponents() const; 174 175 // A bunch of methods for casting this type to a given type. Returns this if the 176 // cast can be done, nullptr otherwise. 177 // clang-format off 178 #define DeclareCastMethod(target) \ 179 virtual target* As##target() { return nullptr; } \ 180 virtual const target* As##target() const { return nullptr; } 181 DeclareCastMethod(Void) 182 DeclareCastMethod(Bool) 183 DeclareCastMethod(Integer) 184 DeclareCastMethod(Float) 185 DeclareCastMethod(Vector) 186 DeclareCastMethod(Matrix) 187 DeclareCastMethod(Image) 188 DeclareCastMethod(Sampler) 189 DeclareCastMethod(SampledImage) 190 DeclareCastMethod(Array) 191 DeclareCastMethod(RuntimeArray) 192 DeclareCastMethod(Struct) 193 DeclareCastMethod(Opaque) 194 DeclareCastMethod(Pointer) 195 DeclareCastMethod(Function) 196 DeclareCastMethod(Event) 197 DeclareCastMethod(DeviceEvent) 198 DeclareCastMethod(ReserveId) 199 DeclareCastMethod(Queue) 200 DeclareCastMethod(Pipe) 201 DeclareCastMethod(ForwardPointer) 202 DeclareCastMethod(PipeStorage) 203 DeclareCastMethod(NamedBarrier) 204 DeclareCastMethod(AccelerationStructureNV) 205 DeclareCastMethod(CooperativeMatrixNV) 206 DeclareCastMethod(CooperativeMatrixKHR) 207 DeclareCastMethod(RayQueryKHR) 208 DeclareCastMethod(HitObjectNV) 209 #undef DeclareCastMethod 210 211 protected: 212 // Add any type-specific state to |hash| and returns new hash. 213 virtual size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const = 0; 214 215 protected: 216 // Decorations attached to this type. Each decoration is encoded as a vector 217 // of uint32_t numbers. The first uint32_t number is the decoration value, 218 // and the rest are the parameters to the decoration (if exists). 219 std::vector<std::vector<uint32_t>> decorations_; 220 221 private: 222 // Removes decorations on this type. For struct types, also removes element 223 // decorations. ClearDecorations()224 virtual void ClearDecorations() { decorations_.clear(); } 225 226 Kind kind_; 227 }; 228 // clang-format on 229 230 class Integer : public Type { 231 public: Integer(uint32_t w,bool is_signed)232 Integer(uint32_t w, bool is_signed) 233 : Type(kInteger), width_(w), signed_(is_signed) {} 234 Integer(const Integer&) = default; 235 236 std::string str() const override; 237 AsInteger()238 Integer* AsInteger() override { return this; } AsInteger()239 const Integer* AsInteger() const override { return this; } width()240 uint32_t width() const { return width_; } IsSigned()241 bool IsSigned() const { return signed_; } 242 243 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 244 245 private: 246 bool IsSameImpl(const Type* that, IsSameCache*) const override; 247 248 uint32_t width_; // bit width 249 bool signed_; // true if this integer is signed 250 }; 251 252 class Float : public Type { 253 public: Float(uint32_t w)254 Float(uint32_t w) : Type(kFloat), width_(w) {} 255 Float(const Float&) = default; 256 257 std::string str() const override; 258 AsFloat()259 Float* AsFloat() override { return this; } AsFloat()260 const Float* AsFloat() const override { return this; } width()261 uint32_t width() const { return width_; } 262 263 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 264 265 private: 266 bool IsSameImpl(const Type* that, IsSameCache*) const override; 267 268 uint32_t width_; // bit width 269 }; 270 271 class Vector : public Type { 272 public: 273 Vector(const Type* element_type, uint32_t count); 274 Vector(const Vector&) = default; 275 276 std::string str() const override; element_type()277 const Type* element_type() const { return element_type_; } element_count()278 uint32_t element_count() const { return count_; } 279 AsVector()280 Vector* AsVector() override { return this; } AsVector()281 const Vector* AsVector() const override { return this; } 282 283 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 284 285 private: 286 bool IsSameImpl(const Type* that, IsSameCache*) const override; 287 288 const Type* element_type_; 289 uint32_t count_; 290 }; 291 292 class Matrix : public Type { 293 public: 294 Matrix(const Type* element_type, uint32_t count); 295 Matrix(const Matrix&) = default; 296 297 std::string str() const override; element_type()298 const Type* element_type() const { return element_type_; } element_count()299 uint32_t element_count() const { return count_; } 300 AsMatrix()301 Matrix* AsMatrix() override { return this; } AsMatrix()302 const Matrix* AsMatrix() const override { return this; } 303 304 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 305 306 private: 307 bool IsSameImpl(const Type* that, IsSameCache*) const override; 308 309 const Type* element_type_; 310 uint32_t count_; 311 }; 312 313 class Image : public Type { 314 public: 315 Image(Type* type, spv::Dim dimen, uint32_t d, bool array, bool multisample, 316 uint32_t sampling, spv::ImageFormat f, 317 spv::AccessQualifier qualifier = spv::AccessQualifier::ReadOnly); 318 Image(const Image&) = default; 319 320 std::string str() const override; 321 AsImage()322 Image* AsImage() override { return this; } AsImage()323 const Image* AsImage() const override { return this; } 324 sampled_type()325 const Type* sampled_type() const { return sampled_type_; } dim()326 spv::Dim dim() const { return dim_; } depth()327 uint32_t depth() const { return depth_; } is_arrayed()328 bool is_arrayed() const { return arrayed_; } is_multisampled()329 bool is_multisampled() const { return ms_; } sampled()330 uint32_t sampled() const { return sampled_; } format()331 spv::ImageFormat format() const { return format_; } access_qualifier()332 spv::AccessQualifier access_qualifier() const { return access_qualifier_; } 333 334 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 335 336 private: 337 bool IsSameImpl(const Type* that, IsSameCache*) const override; 338 339 Type* sampled_type_; 340 spv::Dim dim_; 341 uint32_t depth_; 342 bool arrayed_; 343 bool ms_; 344 uint32_t sampled_; 345 spv::ImageFormat format_; 346 spv::AccessQualifier access_qualifier_; 347 }; 348 349 class SampledImage : public Type { 350 public: SampledImage(Type * image)351 SampledImage(Type* image) : Type(kSampledImage), image_type_(image) {} 352 SampledImage(const SampledImage&) = default; 353 354 std::string str() const override; 355 AsSampledImage()356 SampledImage* AsSampledImage() override { return this; } AsSampledImage()357 const SampledImage* AsSampledImage() const override { return this; } 358 image_type()359 const Type* image_type() const { return image_type_; } 360 361 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 362 363 private: 364 bool IsSameImpl(const Type* that, IsSameCache*) const override; 365 Type* image_type_; 366 }; 367 368 class Array : public Type { 369 public: 370 // Data about the length operand, that helps us distinguish between one 371 // array length and another. 372 struct LengthInfo { 373 // The result id of the instruction defining the length. 374 const uint32_t id; 375 enum Case : uint32_t { 376 kConstant = 0, 377 kConstantWithSpecId = 1, 378 kDefiningId = 2 379 }; 380 // Extra words used to distinshish one array length and another. 381 // - if OpConstant, then it's 0, then the words in the literal constant 382 // value. 383 // - if OpSpecConstant, then it's 1, then the SpecID decoration if there 384 // is one, followed by the words in the literal constant value. 385 // The spec might not be overridden, in which case we'll end up using 386 // the literal value. 387 // - Otherwise, it's an OpSpecConsant, and this 2, then the ID (again). 388 const std::vector<uint32_t> words; 389 }; 390 391 // Constructs an array type with given element and length. If the length 392 // is an OpSpecConstant, then |spec_id| should be its SpecId decoration. 393 Array(const Type* element_type, const LengthInfo& length_info_arg); 394 Array(const Array&) = default; 395 396 std::string str() const override; element_type()397 const Type* element_type() const { return element_type_; } LengthId()398 uint32_t LengthId() const { return length_info_.id; } length_info()399 const LengthInfo& length_info() const { return length_info_; } 400 AsArray()401 Array* AsArray() override { return this; } AsArray()402 const Array* AsArray() const override { return this; } 403 404 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 405 406 void ReplaceElementType(const Type* element_type); 407 LengthInfo GetConstantLengthInfo(uint32_t const_id, uint32_t length) const; 408 409 private: 410 bool IsSameImpl(const Type* that, IsSameCache*) const override; 411 412 const Type* element_type_; 413 const LengthInfo length_info_; 414 }; 415 416 class RuntimeArray : public Type { 417 public: 418 RuntimeArray(const Type* element_type); 419 RuntimeArray(const RuntimeArray&) = default; 420 421 std::string str() const override; element_type()422 const Type* element_type() const { return element_type_; } 423 AsRuntimeArray()424 RuntimeArray* AsRuntimeArray() override { return this; } AsRuntimeArray()425 const RuntimeArray* AsRuntimeArray() const override { return this; } 426 427 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 428 429 void ReplaceElementType(const Type* element_type); 430 431 private: 432 bool IsSameImpl(const Type* that, IsSameCache*) const override; 433 434 const Type* element_type_; 435 }; 436 437 class Struct : public Type { 438 public: 439 Struct(const std::vector<const Type*>& element_types); 440 Struct(const Struct&) = default; 441 442 // Adds a decoration to the member at the given index. The first word is the 443 // decoration enum, and the remaining words, if any, are its operands. 444 void AddMemberDecoration(uint32_t index, std::vector<uint32_t>&& decoration); 445 446 std::string str() const override; element_types()447 const std::vector<const Type*>& element_types() const { 448 return element_types_; 449 } element_types()450 std::vector<const Type*>& element_types() { return element_types_; } decoration_empty()451 bool decoration_empty() const override { 452 return decorations_.empty() && element_decorations_.empty(); 453 } 454 455 const std::map<uint32_t, std::vector<std::vector<uint32_t>>>& element_decorations()456 element_decorations() const { 457 return element_decorations_; 458 } 459 AsStruct()460 Struct* AsStruct() override { return this; } AsStruct()461 const Struct* AsStruct() const override { return this; } 462 463 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 464 465 private: 466 bool IsSameImpl(const Type* that, IsSameCache*) const override; 467 ClearDecorations()468 void ClearDecorations() override { 469 decorations_.clear(); 470 element_decorations_.clear(); 471 } 472 473 std::vector<const Type*> element_types_; 474 // We can attach decorations to struct members and that should not affect the 475 // underlying element type. So we need an extra data structure here to keep 476 // track of element type decorations. They must be stored in an ordered map 477 // because |GetExtraHashWords| will traverse the structure. It must have a 478 // fixed order in order to hash to the same value every time. 479 std::map<uint32_t, std::vector<std::vector<uint32_t>>> element_decorations_; 480 }; 481 482 class Opaque : public Type { 483 public: Opaque(std::string n)484 Opaque(std::string n) : Type(kOpaque), name_(std::move(n)) {} 485 Opaque(const Opaque&) = default; 486 487 std::string str() const override; 488 AsOpaque()489 Opaque* AsOpaque() override { return this; } AsOpaque()490 const Opaque* AsOpaque() const override { return this; } 491 name()492 const std::string& name() const { return name_; } 493 494 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 495 496 private: 497 bool IsSameImpl(const Type* that, IsSameCache*) const override; 498 499 std::string name_; 500 }; 501 502 class Pointer : public Type { 503 public: 504 Pointer(const Type* pointee, spv::StorageClass sc); 505 Pointer(const Pointer&) = default; 506 507 std::string str() const override; pointee_type()508 const Type* pointee_type() const { return pointee_type_; } storage_class()509 spv::StorageClass storage_class() const { return storage_class_; } 510 AsPointer()511 Pointer* AsPointer() override { return this; } AsPointer()512 const Pointer* AsPointer() const override { return this; } 513 514 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 515 516 void SetPointeeType(const Type* type); 517 518 private: 519 bool IsSameImpl(const Type* that, IsSameCache*) const override; 520 521 const Type* pointee_type_; 522 spv::StorageClass storage_class_; 523 }; 524 525 class Function : public Type { 526 public: 527 Function(const Type* ret_type, const std::vector<const Type*>& params); 528 Function(const Type* ret_type, std::vector<const Type*>& params); 529 Function(const Function&) = default; 530 531 std::string str() const override; 532 AsFunction()533 Function* AsFunction() override { return this; } AsFunction()534 const Function* AsFunction() const override { return this; } 535 return_type()536 const Type* return_type() const { return return_type_; } param_types()537 const std::vector<const Type*>& param_types() const { return param_types_; } param_types()538 std::vector<const Type*>& param_types() { return param_types_; } 539 540 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 541 542 void SetReturnType(const Type* type); 543 544 private: 545 bool IsSameImpl(const Type* that, IsSameCache*) const override; 546 547 const Type* return_type_; 548 std::vector<const Type*> param_types_; 549 }; 550 551 class Pipe : public Type { 552 public: Pipe(spv::AccessQualifier qualifier)553 Pipe(spv::AccessQualifier qualifier) 554 : Type(kPipe), access_qualifier_(qualifier) {} 555 Pipe(const Pipe&) = default; 556 557 std::string str() const override; 558 AsPipe()559 Pipe* AsPipe() override { return this; } AsPipe()560 const Pipe* AsPipe() const override { return this; } 561 access_qualifier()562 spv::AccessQualifier access_qualifier() const { return access_qualifier_; } 563 564 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 565 566 private: 567 bool IsSameImpl(const Type* that, IsSameCache*) const override; 568 569 spv::AccessQualifier access_qualifier_; 570 }; 571 572 class ForwardPointer : public Type { 573 public: ForwardPointer(uint32_t id,spv::StorageClass sc)574 ForwardPointer(uint32_t id, spv::StorageClass sc) 575 : Type(kForwardPointer), 576 target_id_(id), 577 storage_class_(sc), 578 pointer_(nullptr) {} 579 ForwardPointer(const ForwardPointer&) = default; 580 target_id()581 uint32_t target_id() const { return target_id_; } SetTargetPointer(const Pointer * pointer)582 void SetTargetPointer(const Pointer* pointer) { pointer_ = pointer; } storage_class()583 spv::StorageClass storage_class() const { return storage_class_; } target_pointer()584 const Pointer* target_pointer() const { return pointer_; } 585 586 std::string str() const override; 587 AsForwardPointer()588 ForwardPointer* AsForwardPointer() override { return this; } AsForwardPointer()589 const ForwardPointer* AsForwardPointer() const override { return this; } 590 591 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 592 593 private: 594 bool IsSameImpl(const Type* that, IsSameCache*) const override; 595 596 uint32_t target_id_; 597 spv::StorageClass storage_class_; 598 const Pointer* pointer_; 599 }; 600 601 class CooperativeMatrixNV : public Type { 602 public: 603 CooperativeMatrixNV(const Type* type, const uint32_t scope, 604 const uint32_t rows, const uint32_t columns); 605 CooperativeMatrixNV(const CooperativeMatrixNV&) = default; 606 607 std::string str() const override; 608 AsCooperativeMatrixNV()609 CooperativeMatrixNV* AsCooperativeMatrixNV() override { return this; } AsCooperativeMatrixNV()610 const CooperativeMatrixNV* AsCooperativeMatrixNV() const override { 611 return this; 612 } 613 614 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 615 component_type()616 const Type* component_type() const { return component_type_; } scope_id()617 uint32_t scope_id() const { return scope_id_; } rows_id()618 uint32_t rows_id() const { return rows_id_; } columns_id()619 uint32_t columns_id() const { return columns_id_; } 620 621 private: 622 bool IsSameImpl(const Type* that, IsSameCache*) const override; 623 624 const Type* component_type_; 625 const uint32_t scope_id_; 626 const uint32_t rows_id_; 627 const uint32_t columns_id_; 628 }; 629 630 class CooperativeMatrixKHR : public Type { 631 public: 632 CooperativeMatrixKHR(const Type* type, const uint32_t scope, 633 const uint32_t rows, const uint32_t columns, 634 const uint32_t use); 635 CooperativeMatrixKHR(const CooperativeMatrixKHR&) = default; 636 637 std::string str() const override; 638 AsCooperativeMatrixKHR()639 CooperativeMatrixKHR* AsCooperativeMatrixKHR() override { return this; } AsCooperativeMatrixKHR()640 const CooperativeMatrixKHR* AsCooperativeMatrixKHR() const override { 641 return this; 642 } 643 644 size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; 645 component_type()646 const Type* component_type() const { return component_type_; } scope_id()647 uint32_t scope_id() const { return scope_id_; } rows_id()648 uint32_t rows_id() const { return rows_id_; } columns_id()649 uint32_t columns_id() const { return columns_id_; } use_id()650 uint32_t use_id() const { return use_id_; } 651 652 private: 653 bool IsSameImpl(const Type* that, IsSameCache*) const override; 654 655 const Type* component_type_; 656 const uint32_t scope_id_; 657 const uint32_t rows_id_; 658 const uint32_t columns_id_; 659 const uint32_t use_id_; 660 }; 661 662 #define DefineParameterlessType(type, name) \ 663 class type : public Type { \ 664 public: \ 665 type() : Type(k##type) {} \ 666 type(const type&) = default; \ 667 \ 668 std::string str() const override { return #name; } \ 669 \ 670 type* As##type() override { return this; } \ 671 const type* As##type() const override { return this; } \ 672 \ 673 size_t ComputeExtraStateHash(size_t hash, SeenTypes*) const override { \ 674 return hash; \ 675 } \ 676 \ 677 private: \ 678 bool IsSameImpl(const Type* that, IsSameCache*) const override { \ 679 return that->As##type() && HasSameDecorations(that); \ 680 } \ 681 } 682 DefineParameterlessType(Void, void); 683 DefineParameterlessType(Bool, bool); 684 DefineParameterlessType(Sampler, sampler); 685 DefineParameterlessType(Event, event); 686 DefineParameterlessType(DeviceEvent, device_event); 687 DefineParameterlessType(ReserveId, reserve_id); 688 DefineParameterlessType(Queue, queue); 689 DefineParameterlessType(PipeStorage, pipe_storage); 690 DefineParameterlessType(NamedBarrier, named_barrier); 691 DefineParameterlessType(AccelerationStructureNV, accelerationStructureNV); 692 DefineParameterlessType(RayQueryKHR, rayQueryKHR); 693 DefineParameterlessType(HitObjectNV, hitObjectNV); 694 #undef DefineParameterlessType 695 696 } // namespace analysis 697 } // namespace opt 698 } // namespace spvtools 699 700 #endif // SOURCE_OPT_TYPES_H_ 701