1 /*========================== begin_copyright_notice ============================ 2 3 Copyright (C) 2017-2021 Intel Corporation 4 5 SPDX-License-Identifier: MIT 6 7 ============================= end_copyright_notice ===========================*/ 8 9 #pragma once 10 11 #include "MetaDataApiUtils.h" 12 #include "MDFrameWork.h" 13 14 namespace IGC { 15 namespace IGCMD 16 { 17 //typedefs and forward declarations 18 class ArgInfoMetaData; 19 typedef MetaObjectHandle<ArgInfoMetaData> ArgInfoMetaDataHandle; 20 21 class SubGroupSizeMetaData; 22 typedef MetaObjectHandle<SubGroupSizeMetaData> SubGroupSizeMetaDataHandle; 23 24 class VectorTypeHintMetaData; 25 typedef MetaObjectHandle<VectorTypeHintMetaData> VectorTypeHintMetaDataHandle; 26 27 class ThreadGroupSizeMetaData; 28 typedef MetaObjectHandle<ThreadGroupSizeMetaData> ThreadGroupSizeMetaDataHandle; 29 30 class FunctionInfoMetaData; 31 typedef MetaObjectHandle<FunctionInfoMetaData> FunctionInfoMetaDataHandle; 32 33 typedef MetaDataList<ArgInfoMetaDataHandle> ArgInfoListMetaDataList; 34 typedef MetaObjectHandle<ArgInfoListMetaDataList> ArgInfoListMetaDataListHandle; 35 36 /// 37 // Read/Write the ArgInfo structure from/to LLVM metadata 38 // 39 class ArgInfoMetaData :public IMetaDataObject 40 { 41 public: 42 typedef ArgInfoMetaData _Myt; 43 typedef IMetaDataObject _Mybase; 44 // typedefs for data member types 45 typedef MetaDataValue<int32_t>::value_type ArgIdType; 46 typedef NamedMetaDataValue<int32_t>::value_type ExplicitArgNumType; 47 typedef NamedMetaDataValue<int32_t>::value_type StructArgOffsetType; 48 typedef NamedMetaDataValue<bool>::value_type ImgAccessFloatCoordsType; 49 typedef NamedMetaDataValue<bool>::value_type ImgAccessIntCoordsType; 50 51 public: 52 /// 53 // Factory method - creates the ArgInfoMetaData from the given metadata node 54 // 55 static _Myt* get(const llvm::MDNode* pNode, bool hasId = false) 56 { 57 return new _Myt(pNode, hasId); 58 } 59 60 /// 61 // Factory method - create the default empty ArgInfoMetaData object get()62 static _Myt* get() 63 { 64 return new _Myt(); 65 } 66 67 /// 68 // Factory method - create the default empty named ArgInfoMetaData object get(const char * name)69 static _Myt* get(const char* name) 70 { 71 return new _Myt(name); 72 } 73 74 /// 75 // Ctor - loads the ArgInfoMetaData from the given metadata node 76 // 77 ArgInfoMetaData(const llvm::MDNode* pNode, bool hasId); 78 79 /// 80 // Default Ctor - creates the empty, not named ArgInfoMetaData object 81 // 82 ArgInfoMetaData(); 83 84 /// 85 // Ctor - creates the empty, named ArgInfoMetaData object 86 // 87 ArgInfoMetaData(const char* name); 88 89 /// ArgId related methods getArgId()90 ArgIdType getArgId() const 91 { 92 return m_ArgId.get(); 93 } setArgId(const ArgIdType & val)94 void setArgId(const ArgIdType& val) 95 { 96 m_ArgId.set(val); 97 } isArgIdHasValue()98 bool isArgIdHasValue() const 99 { 100 return m_ArgId.hasValue(); 101 } 102 103 104 /// ExplicitArgNum related methods getExplicitArgNum()105 ExplicitArgNumType getExplicitArgNum() const 106 { 107 return m_ExplicitArgNum.get(); 108 } setExplicitArgNum(const ExplicitArgNumType & val)109 void setExplicitArgNum(const ExplicitArgNumType& val) 110 { 111 m_ExplicitArgNum.set(val); 112 } isExplicitArgNumHasValue()113 bool isExplicitArgNumHasValue() const 114 { 115 return m_ExplicitArgNum.hasValue(); 116 } 117 118 119 /// StructArgOffset related methods getStructArgOffset()120 StructArgOffsetType getStructArgOffset() const 121 { 122 return m_StructArgOffset.get(); 123 } setStructArgOffset(const StructArgOffsetType & val)124 void setStructArgOffset(const StructArgOffsetType& val) 125 { 126 m_StructArgOffset.set(val); 127 } isStructArgOffsetHasValue()128 bool isStructArgOffsetHasValue() const 129 { 130 return m_StructArgOffset.hasValue(); 131 } 132 133 134 /// ImgAccessFloatCoords related methods getImgAccessFloatCoords()135 ImgAccessFloatCoordsType getImgAccessFloatCoords() const 136 { 137 return m_ImgAccessFloatCoords.get(); 138 } setImgAccessFloatCoords(const ImgAccessFloatCoordsType & val)139 void setImgAccessFloatCoords(const ImgAccessFloatCoordsType& val) 140 { 141 m_ImgAccessFloatCoords.set(val); 142 } isImgAccessFloatCoordsHasValue()143 bool isImgAccessFloatCoordsHasValue() const 144 { 145 return m_ImgAccessFloatCoords.hasValue(); 146 } 147 148 149 /// ImgAccessIntCoords related methods getImgAccessIntCoords()150 ImgAccessIntCoordsType getImgAccessIntCoords() const 151 { 152 return m_ImgAccessIntCoords.get(); 153 } setImgAccessIntCoords(const ImgAccessIntCoordsType & val)154 void setImgAccessIntCoords(const ImgAccessIntCoordsType& val) 155 { 156 m_ImgAccessIntCoords.set(val); 157 } isImgAccessIntCoordsHasValue()158 bool isImgAccessIntCoordsHasValue() const 159 { 160 return m_ImgAccessIntCoords.hasValue(); 161 } 162 163 /// 164 // Returns true if any of the ArgInfoMetaData`s members has changed 165 bool dirty() const; 166 167 /// 168 // Returns true if the structure was loaded from the metadata or was changed 169 bool hasValue() const; 170 171 /// 172 // Discards the changes done to the ArgInfoMetaData instance 173 void discardChanges(); 174 175 /// 176 // Generates the new MDNode hierarchy for the given structure 177 llvm::Metadata* generateNode(llvm::LLVMContext& context) const; 178 179 /// 180 // Saves the structure changes to the given MDNode 181 void save(llvm::LLVMContext& context, llvm::MDNode* pNode) const; 182 183 private: 184 /// 185 // Returns true if the given MDNode could be saved to without replacement compatibleWith(const llvm::MDNode * pNode)186 bool compatibleWith(const llvm::MDNode* pNode) const 187 { 188 return false; 189 } 190 191 private: 192 typedef MetaDataIterator<llvm::MDNode> NodeIterator; 193 194 llvm::Metadata* getArgIdNode(const llvm::MDNode* pParentNode) const; 195 llvm::Metadata* getExplicitArgNumNode(const llvm::MDNode* pParentNode) const; 196 llvm::Metadata* getStructArgOffsetNode(const llvm::MDNode* pParentNode) const; 197 llvm::Metadata* getImgAccessFloatCoordsNode(const llvm::MDNode* pParentNode) const; 198 llvm::Metadata* getImgAccessIntCoordsNode(const llvm::MDNode* pParentNode) const; 199 200 private: 201 // data members 202 MetaDataValue<int32_t> m_ArgId; 203 NamedMetaDataValue<int32_t> m_ExplicitArgNum; 204 NamedMetaDataValue<int32_t> m_StructArgOffset; 205 NamedMetaDataValue<bool> m_ImgAccessFloatCoords; 206 NamedMetaDataValue<bool> m_ImgAccessIntCoords; 207 // parent node 208 const llvm::MDNode* m_pNode; 209 }; 210 211 /// 212 // Read/Write the ArgDependencyInfo structure from/to LLVM metadata 213 // 214 class ArgDependencyInfoMetaData :public IMetaDataObject 215 { 216 public: 217 typedef ArgDependencyInfoMetaData _Myt; 218 typedef IMetaDataObject _Mybase; 219 // typedefs for data member types 220 typedef MetaDataValue<std::string>::value_type ArgType; 221 typedef MetaDataValue<int32_t>::value_type ArgDependencyType; 222 223 public: 224 /// 225 // Factory method - creates the ArgDependencyInfoMetaData from the given metadata node 226 // 227 static _Myt* get(const llvm::MDNode* pNode, bool hasId = false) 228 { 229 return new _Myt(pNode, hasId); 230 } 231 232 /// 233 // Factory method - create the default empty ArgDependencyInfoMetaData object get()234 static _Myt* get() 235 { 236 return new _Myt(); 237 } 238 239 /// 240 // Factory method - create the default empty named ArgDependencyInfoMetaData object get(const char * name)241 static _Myt* get(const char* name) 242 { 243 return new _Myt(name); 244 } 245 246 /// 247 // Ctor - loads the ArgDependencyInfoMetaData from the given metadata node 248 // 249 ArgDependencyInfoMetaData(const llvm::MDNode* pNode, bool hasId); 250 251 /// 252 // Default Ctor - creates the empty, not named ArgDependencyInfoMetaData object 253 // 254 ArgDependencyInfoMetaData(); 255 256 /// 257 // Ctor - creates the empty, named ArgDependencyInfoMetaData object 258 // 259 ArgDependencyInfoMetaData(const char* name); 260 261 /// Arg related methods getArg()262 ArgType getArg() const 263 { 264 return m_Arg.get(); 265 } setArg(const ArgType & val)266 void setArg(const ArgType& val) 267 { 268 m_Arg.set(val); 269 } isArgHasValue()270 bool isArgHasValue() const 271 { 272 return m_Arg.hasValue(); 273 } 274 275 276 /// ArgDependency related methods getArgDependency()277 ArgDependencyType getArgDependency() const 278 { 279 return m_ArgDependency.get(); 280 } setArgDependency(const ArgDependencyType & val)281 void setArgDependency(const ArgDependencyType& val) 282 { 283 m_ArgDependency.set(val); 284 } isArgDependencyHasValue()285 bool isArgDependencyHasValue() const 286 { 287 return m_ArgDependency.hasValue(); 288 } 289 290 /// 291 // Returns true if any of the ArgDependencyInfoMetaData`s members has changed 292 bool dirty() const; 293 294 /// 295 // Returns true if the structure was loaded from the metadata or was changed 296 bool hasValue() const; 297 298 /// 299 // Discards the changes done to the ArgDependencyInfoMetaData instance 300 void discardChanges(); 301 302 /// 303 // Generates the new MDNode hierarchy for the given structure 304 llvm::Metadata* generateNode(llvm::LLVMContext& context) const; 305 306 /// 307 // Saves the structure changes to the given MDNode 308 void save(llvm::LLVMContext& context, llvm::MDNode* pNode) const; 309 310 private: 311 /// 312 // Returns true if the given MDNode could be saved to without replacement compatibleWith(const llvm::MDNode * pNode)313 bool compatibleWith(const llvm::MDNode* pNode) const 314 { 315 return false; 316 } 317 318 private: 319 typedef MetaDataIterator<llvm::MDNode> NodeIterator; 320 321 llvm::Metadata* getArgNode(const llvm::MDNode* pParentNode) const; 322 llvm::Metadata* getArgDependencyNode(const llvm::MDNode* pParentNode) const; 323 324 private: 325 // data members 326 MetaDataValue<std::string> m_Arg; 327 MetaDataValue<int32_t> m_ArgDependency; 328 // parent node 329 const llvm::MDNode* m_pNode; 330 }; 331 332 /// 333 // Read/Write the SubGroupSize structure from/to LLVM metadata 334 // 335 class SubGroupSizeMetaData :public IMetaDataObject 336 { 337 public: 338 typedef SubGroupSizeMetaData _Myt; 339 typedef IMetaDataObject _Mybase; 340 // typedefs for data member types 341 typedef MetaDataValue<int32_t>::value_type SIMD_sizeType; 342 343 public: 344 /// 345 // Factory method - creates the SubGroupSizeMetaData from the given metadata node 346 // 347 static _Myt* get(const llvm::MDNode* pNode, bool hasId = false) 348 { 349 return new _Myt(pNode, hasId); 350 } 351 352 /// 353 // Factory method - create the default empty SubGroupSizeMetaData object get()354 static _Myt* get() 355 { 356 return new _Myt(); 357 } 358 359 /// 360 // Factory method - create the default empty named SubGroupSizeMetaData object get(const char * name)361 static _Myt* get(const char* name) 362 { 363 return new _Myt(name); 364 } 365 366 /// 367 // Ctor - loads the SubGroupSizeMetaData from the given metadata node 368 // 369 SubGroupSizeMetaData(const llvm::MDNode* pNode, bool hasId); 370 371 /// 372 // Default Ctor - creates the empty, not named SubGroupSizeMetaData object 373 // 374 SubGroupSizeMetaData(); 375 376 /// 377 // Ctor - creates the empty, named SubGroupSizeMetaData object 378 // 379 SubGroupSizeMetaData(const char* name); 380 381 /// SIMD_size related methods getSIMD_size()382 SIMD_sizeType getSIMD_size() const 383 { 384 return m_SIMD_size.get(); 385 } setSIMD_size(const SIMD_sizeType & val)386 void setSIMD_size(const SIMD_sizeType& val) 387 { 388 m_SIMD_size.set(val); 389 } isSIMD_sizeHasValue()390 bool isSIMD_sizeHasValue() const 391 { 392 return m_SIMD_size.hasValue(); 393 } 394 395 /// 396 // Returns true if any of the SubGroupSizeMetaData`s members has changed 397 bool dirty() const; 398 399 /// 400 // Returns true if the structure was loaded from the metadata or was changed 401 bool hasValue() const; 402 403 /// 404 // Discards the changes done to the SubGroupSizeMetaData instance 405 void discardChanges(); 406 407 /// 408 // Generates the new MDNode hierarchy for the given structure 409 llvm::Metadata* generateNode(llvm::LLVMContext& context) const; 410 411 /// 412 // Saves the structure changes to the given MDNode 413 void save(llvm::LLVMContext& context, llvm::MDNode* pNode) const; 414 415 private: 416 /// 417 // Returns true if the given MDNode could be saved to without replacement compatibleWith(const llvm::MDNode * pNode)418 bool compatibleWith(const llvm::MDNode* pNode) const 419 { 420 return false; 421 } 422 423 private: 424 typedef MetaDataIterator<llvm::MDNode> NodeIterator; 425 426 llvm::Metadata* getSIMD_sizeNode(const llvm::MDNode* pParentNode) const; 427 428 private: 429 // data members 430 MetaDataValue<int32_t> m_SIMD_size; 431 // parent node 432 const llvm::MDNode* m_pNode; 433 }; 434 435 /// 436 // Read/Write the VectorTypeHint structure from/to LLVM metadata 437 // 438 class VectorTypeHintMetaData :public IMetaDataObject 439 { 440 public: 441 typedef VectorTypeHintMetaData _Myt; 442 typedef IMetaDataObject _Mybase; 443 // typedefs for data member types 444 typedef MetaDataValue<llvm::UndefValue>::value_type VecTypeType; 445 typedef MetaDataValue<bool>::value_type SignType; 446 447 public: 448 /// 449 // Factory method - creates the VectorTypeHintMetaData from the given metadata node 450 // 451 static _Myt* get(const llvm::MDNode* pNode, bool hasId = false) 452 { 453 return new _Myt(pNode, hasId); 454 } 455 456 /// 457 // Factory method - create the default empty VectorTypeHintMetaData object get()458 static _Myt* get() 459 { 460 return new _Myt(); 461 } 462 463 /// 464 // Factory method - create the default empty named VectorTypeHintMetaData object get(const char * name)465 static _Myt* get(const char* name) 466 { 467 return new _Myt(name); 468 } 469 470 /// 471 // Ctor - loads the VectorTypeHintMetaData from the given metadata node 472 // 473 VectorTypeHintMetaData(const llvm::MDNode* pNode, bool hasId); 474 475 /// 476 // Default Ctor - creates the empty, not named VectorTypeHintMetaData object 477 // 478 VectorTypeHintMetaData(); 479 480 /// 481 // Ctor - creates the empty, named VectorTypeHintMetaData object 482 // 483 VectorTypeHintMetaData(const char* name); 484 485 /// VecType related methods getVecType()486 VecTypeType getVecType() const 487 { 488 return m_VecType.get(); 489 } setVecType(const VecTypeType & val)490 void setVecType(const VecTypeType& val) 491 { 492 m_VecType.set(val); 493 } isVecTypeHasValue()494 bool isVecTypeHasValue() const 495 { 496 return m_VecType.hasValue(); 497 } 498 499 500 /// Sign related methods getSign()501 SignType getSign() const 502 { 503 return m_Sign.get(); 504 } setSign(const SignType & val)505 void setSign(const SignType& val) 506 { 507 m_Sign.set(val); 508 } isSignHasValue()509 bool isSignHasValue() const 510 { 511 return m_Sign.hasValue(); 512 } 513 514 /// 515 // Returns true if any of the VectorTypeHintMetaData`s members has changed 516 bool dirty() const; 517 518 /// 519 // Returns true if the structure was loaded from the metadata or was changed 520 bool hasValue() const; 521 522 /// 523 // Discards the changes done to the VectorTypeHintMetaData instance 524 void discardChanges(); 525 526 /// 527 // Generates the new MDNode hierarchy for the given structure 528 llvm::Metadata* generateNode(llvm::LLVMContext& context) const; 529 530 /// 531 // Saves the structure changes to the given MDNode 532 void save(llvm::LLVMContext& context, llvm::MDNode* pNode) const; 533 534 private: 535 /// 536 // Returns true if the given MDNode could be saved to without replacement compatibleWith(const llvm::MDNode * pNode)537 bool compatibleWith(const llvm::MDNode* pNode) const 538 { 539 return false; 540 } 541 542 private: 543 typedef MetaDataIterator<llvm::MDNode> NodeIterator; 544 545 llvm::Metadata* getVecTypeNode(const llvm::MDNode* pParentNode) const; 546 llvm::Metadata* getSignNode(const llvm::MDNode* pParentNode) const; 547 548 private: 549 // data members 550 MetaDataValue<llvm::UndefValue> m_VecType; 551 MetaDataValue<bool> m_Sign; 552 // parent node 553 const llvm::MDNode* m_pNode; 554 }; 555 556 /// 557 // Read/Write the ThreadGroupSize structure from/to LLVM metadata 558 // 559 class ThreadGroupSizeMetaData :public IMetaDataObject 560 { 561 public: 562 typedef ThreadGroupSizeMetaData _Myt; 563 typedef IMetaDataObject _Mybase; 564 // typedefs for data member types 565 typedef MetaDataValue<int32_t>::value_type XDimType; 566 typedef MetaDataValue<int32_t>::value_type YDimType; 567 typedef MetaDataValue<int32_t>::value_type ZDimType; 568 569 public: 570 /// 571 // Factory method - creates the ThreadGroupSizeMetaData from the given metadata node 572 // 573 static _Myt* get(const llvm::MDNode* pNode, bool hasId = false) 574 { 575 return new _Myt(pNode, hasId); 576 } 577 578 /// 579 // Factory method - create the default empty ThreadGroupSizeMetaData object get()580 static _Myt* get() 581 { 582 return new _Myt(); 583 } 584 585 /// 586 // Factory method - create the default empty named ThreadGroupSizeMetaData object get(const char * name)587 static _Myt* get(const char* name) 588 { 589 return new _Myt(name); 590 } 591 592 /// 593 // Ctor - loads the ThreadGroupSizeMetaData from the given metadata node 594 // 595 ThreadGroupSizeMetaData(const llvm::MDNode* pNode, bool hasId); 596 597 /// 598 // Default Ctor - creates the empty, not named ThreadGroupSizeMetaData object 599 // 600 ThreadGroupSizeMetaData(); 601 602 /// 603 // Ctor - creates the empty, named ThreadGroupSizeMetaData object 604 // 605 ThreadGroupSizeMetaData(const char* name); 606 607 /// XDim related methods getXDim()608 XDimType getXDim() const 609 { 610 return m_XDim.get(); 611 } setXDim(const XDimType & val)612 void setXDim(const XDimType& val) 613 { 614 m_XDim.set(val); 615 } isXDimHasValue()616 bool isXDimHasValue() const 617 { 618 return m_XDim.hasValue(); 619 } 620 621 622 /// YDim related methods getYDim()623 YDimType getYDim() const 624 { 625 return m_YDim.get(); 626 } setYDim(const YDimType & val)627 void setYDim(const YDimType& val) 628 { 629 m_YDim.set(val); 630 } isYDimHasValue()631 bool isYDimHasValue() const 632 { 633 return m_YDim.hasValue(); 634 } 635 636 637 /// ZDim related methods getZDim()638 ZDimType getZDim() const 639 { 640 return m_ZDim.get(); 641 } setZDim(const ZDimType & val)642 void setZDim(const ZDimType& val) 643 { 644 m_ZDim.set(val); 645 } isZDimHasValue()646 bool isZDimHasValue() const 647 { 648 return m_ZDim.hasValue(); 649 } 650 651 /// 652 // Returns true if any of the ThreadGroupSizeMetaData`s members has changed 653 bool dirty() const; 654 655 /// 656 // Returns true if the structure was loaded from the metadata or was changed 657 bool hasValue() const; 658 659 /// 660 // Discards the changes done to the ThreadGroupSizeMetaData instance 661 void discardChanges(); 662 663 /// 664 // Generates the new MDNode hierarchy for the given structure 665 llvm::Metadata* generateNode(llvm::LLVMContext& context) const; 666 667 /// 668 // Saves the structure changes to the given MDNode 669 void save(llvm::LLVMContext& context, llvm::MDNode* pNode) const; 670 671 private: 672 /// 673 // Returns true if the given MDNode could be saved to without replacement compatibleWith(const llvm::MDNode * pNode)674 bool compatibleWith(const llvm::MDNode* pNode) const 675 { 676 return false; 677 } 678 679 private: 680 typedef MetaDataIterator<llvm::MDNode> NodeIterator; 681 682 llvm::Metadata* getXDimNode(const llvm::MDNode* pParentNode) const; 683 llvm::Metadata* getYDimNode(const llvm::MDNode* pParentNode) const; 684 llvm::Metadata* getZDimNode(const llvm::MDNode* pParentNode) const; 685 686 private: 687 // data members 688 MetaDataValue<int32_t> m_XDim; 689 MetaDataValue<int32_t> m_YDim; 690 MetaDataValue<int32_t> m_ZDim; 691 // parent node 692 const llvm::MDNode* m_pNode; 693 }; 694 695 /// 696 // Read/Write the FunctionInfo structure from/to LLVM metadata 697 // 698 class FunctionInfoMetaData :public IMetaDataObject 699 { 700 public: 701 typedef FunctionInfoMetaData _Myt; 702 typedef IMetaDataObject _Mybase; 703 // typedefs for data member types 704 typedef NamedMetaDataValue<int32_t>::value_type TypeType; 705 typedef MetaDataList<ArgInfoMetaDataHandle> ArgInfoListList; 706 typedef MetaDataList<ArgInfoMetaDataHandle> ImplicitArgInfoListList; 707 typedef NamedMetaDataValue<int32_t>::value_type PrivateMemoryPerWIType; 708 709 typedef NamedMetaDataValue<int32_t>::value_type NeedBindlessHandleType; 710 711 712 public: 713 /// 714 // Factory method - creates the FunctionInfoMetaData from the given metadata node 715 // 716 static _Myt* get(const llvm::MDNode* pNode, bool hasId = false) 717 { 718 return new _Myt(pNode, hasId); 719 } 720 721 /// 722 // Factory method - create the default empty FunctionInfoMetaData object get()723 static _Myt* get() 724 { 725 return new _Myt(); 726 } 727 728 /// 729 // Factory method - create the default empty named FunctionInfoMetaData object get(const char * name)730 static _Myt* get(const char* name) 731 { 732 return new _Myt(name); 733 } 734 735 /// 736 // Ctor - loads the FunctionInfoMetaData from the given metadata node 737 // 738 FunctionInfoMetaData(const llvm::MDNode* pNode, bool hasId); 739 740 /// 741 // Default Ctor - creates the empty, not named FunctionInfoMetaData object 742 // 743 FunctionInfoMetaData(); 744 745 /// 746 // Ctor - creates the empty, named FunctionInfoMetaData object 747 // 748 FunctionInfoMetaData(const char* name); 749 750 /// Type related methods getType()751 TypeType getType() const 752 { 753 return m_Type.get(); 754 } setType(const TypeType & val)755 void setType(const TypeType& val) 756 { 757 m_Type.set(val); 758 } isTypeHasValue()759 bool isTypeHasValue() const 760 { 761 return m_Type.hasValue(); 762 } 763 764 765 /// ArgInfoList related methods begin_ArgInfoList()766 ArgInfoListList::iterator begin_ArgInfoList() 767 { 768 return m_ArgInfoList.begin(); 769 } 770 end_ArgInfoList()771 ArgInfoListList::iterator end_ArgInfoList() 772 { 773 return m_ArgInfoList.end(); 774 } begin_ArgInfoList()775 ArgInfoListList::const_iterator begin_ArgInfoList() const 776 { 777 return m_ArgInfoList.begin(); 778 } 779 end_ArgInfoList()780 ArgInfoListList::const_iterator end_ArgInfoList() const 781 { 782 return m_ArgInfoList.end(); 783 } 784 size_ArgInfoList()785 size_t size_ArgInfoList() const 786 { 787 return m_ArgInfoList.size(); 788 } 789 empty_ArgInfoList()790 bool empty_ArgInfoList() const 791 { 792 return m_ArgInfoList.empty(); 793 } 794 isArgInfoListHasValue()795 bool isArgInfoListHasValue() const 796 { 797 return m_ArgInfoList.hasValue(); 798 } 799 getArgInfoListItem(size_t index)800 ArgInfoListList::item_type getArgInfoListItem(size_t index) const 801 { 802 return m_ArgInfoList.getItem(index); 803 } clearArgInfoList()804 void clearArgInfoList() 805 { 806 m_ArgInfoList.clear(); 807 } 808 setArgInfoListItem(size_t index,const ArgInfoListList::item_type & item)809 void setArgInfoListItem(size_t index, const ArgInfoListList::item_type& item) 810 { 811 return m_ArgInfoList.setItem(index, item); 812 } 813 addArgInfoListItem(const ArgInfoListList::item_type & val)814 void addArgInfoListItem(const ArgInfoListList::item_type& val) 815 { 816 m_ArgInfoList.push_back(val); 817 } 818 eraseArgInfoListItem(ArgInfoListList::iterator i)819 ArgInfoListList::iterator eraseArgInfoListItem(ArgInfoListList::iterator i) 820 { 821 return m_ArgInfoList.erase(i); 822 } 823 824 825 /// ImplicitArgInfoList related methods begin_ImplicitArgInfoList()826 ImplicitArgInfoListList::iterator begin_ImplicitArgInfoList() 827 { 828 return m_ImplicitArgInfoList.begin(); 829 } 830 end_ImplicitArgInfoList()831 ImplicitArgInfoListList::iterator end_ImplicitArgInfoList() 832 { 833 return m_ImplicitArgInfoList.end(); 834 } begin_ImplicitArgInfoList()835 ImplicitArgInfoListList::const_iterator begin_ImplicitArgInfoList() const 836 { 837 return m_ImplicitArgInfoList.begin(); 838 } 839 end_ImplicitArgInfoList()840 ImplicitArgInfoListList::const_iterator end_ImplicitArgInfoList() const 841 { 842 return m_ImplicitArgInfoList.end(); 843 } 844 size_ImplicitArgInfoList()845 size_t size_ImplicitArgInfoList() const 846 { 847 return m_ImplicitArgInfoList.size(); 848 } 849 empty_ImplicitArgInfoList()850 bool empty_ImplicitArgInfoList() const 851 { 852 return m_ImplicitArgInfoList.empty(); 853 } 854 isImplicitArgInfoListHasValue()855 bool isImplicitArgInfoListHasValue() const 856 { 857 return m_ImplicitArgInfoList.hasValue(); 858 } 859 getImplicitArgInfoListItem(size_t index)860 ImplicitArgInfoListList::item_type getImplicitArgInfoListItem(size_t index) const 861 { 862 return m_ImplicitArgInfoList.getItem(index); 863 } 864 clearImplicitArgInfoList()865 void clearImplicitArgInfoList() 866 { 867 m_ImplicitArgInfoList.clear(); 868 } 869 setImplicitArgInfoListItem(size_t index,const ImplicitArgInfoListList::item_type & item)870 void setImplicitArgInfoListItem(size_t index, const ImplicitArgInfoListList::item_type& item) 871 { 872 return m_ImplicitArgInfoList.setItem(index, item); 873 } 874 addImplicitArgInfoListItem(const ImplicitArgInfoListList::item_type & val)875 void addImplicitArgInfoListItem(const ImplicitArgInfoListList::item_type& val) 876 { 877 m_ImplicitArgInfoList.push_back(val); 878 } 879 eraseImplicitArgInfoListItem(ImplicitArgInfoListList::iterator i)880 ImplicitArgInfoListList::iterator eraseImplicitArgInfoListItem(ImplicitArgInfoListList::iterator i) 881 { 882 return m_ImplicitArgInfoList.erase(i); 883 } 884 885 886 /// ThreadGroupSize related methods 887 getThreadGroupSize()888 ThreadGroupSizeMetaDataHandle getThreadGroupSize() 889 { 890 return m_ThreadGroupSize; 891 } 892 893 894 /// ThreadGroupSizeHint related methods 895 getThreadGroupSizeHint()896 ThreadGroupSizeMetaDataHandle getThreadGroupSizeHint() 897 { 898 return m_ThreadGroupSizeHint; 899 } 900 901 902 /// SubGroupSize related methods 903 getSubGroupSize()904 SubGroupSizeMetaDataHandle getSubGroupSize() 905 { 906 return m_SubGroupSize; 907 } 908 909 /// OpenCLVectorTypeHint related methods 910 getOpenCLVectorTypeHint()911 VectorTypeHintMetaDataHandle getOpenCLVectorTypeHint() 912 { 913 return m_OpenCLVectorTypeHint; 914 } 915 916 /// 917 // Returns true if any of the FunctionInfoMetaData`s members has changed 918 bool dirty() const; 919 920 /// 921 // Returns true if the structure was loaded from the metadata or was changed 922 bool hasValue() const; 923 924 /// 925 // Discards the changes done to the FunctionInfoMetaData instance 926 void discardChanges(); 927 928 /// 929 // Generates the new MDNode hierarchy for the given structure 930 llvm::Metadata* generateNode(llvm::LLVMContext& context) const; 931 932 /// 933 // Saves the structure changes to the given MDNode 934 void save(llvm::LLVMContext& context, llvm::MDNode* pNode) const; 935 936 private: 937 /// 938 // Returns true if the given MDNode could be saved to without replacement compatibleWith(const llvm::MDNode * pNode)939 bool compatibleWith(const llvm::MDNode* pNode) const 940 { 941 return false; 942 } 943 944 private: 945 typedef MetaDataIterator<llvm::MDNode> NodeIterator; 946 947 llvm::Metadata* getTypeNode(const llvm::MDNode* pParentNode) const; 948 llvm::MDNode* getArgInfoListNode(const llvm::MDNode* pParentNode) const; 949 llvm::MDNode* getImplicitArgInfoListNode(const llvm::MDNode* pParentNode) const; 950 llvm::MDNode* getThreadGroupSizeNode(const llvm::MDNode* pParentNode) const; 951 llvm::MDNode* getThreadGroupSizeHintNode(const llvm::MDNode* pParentNode) const; 952 llvm::MDNode* getSubGroupSizeNode(const llvm::MDNode* pParentNode) const; 953 llvm::MDNode* getWorkgroupWalkOrderNode(const llvm::MDNode* pParentNode) const; 954 llvm::Metadata* getLocalSizeNode(const llvm::MDNode* pParentNode) const; 955 llvm::MDNode* getOpenCLVectorTypeHintNode(const llvm::MDNode* pParentNode) const; 956 957 private: 958 // data members 959 NamedMetaDataValue<int32_t> m_Type; 960 MetaDataList<ArgInfoMetaDataHandle> m_ArgInfoList; 961 MetaDataList<ArgInfoMetaDataHandle> m_ImplicitArgInfoList; 962 ThreadGroupSizeMetaDataHandle m_ThreadGroupSize; 963 ThreadGroupSizeMetaDataHandle m_ThreadGroupSizeHint; 964 SubGroupSizeMetaDataHandle m_SubGroupSize; 965 966 VectorTypeHintMetaDataHandle m_OpenCLVectorTypeHint; 967 // parent node 968 const llvm::MDNode* m_pNode; 969 }; 970 971 class MetaDataUtils 972 { 973 public: 974 // typedefs for the data members types 975 typedef NamedMetaDataMap<llvm::Function, FunctionInfoMetaDataHandle> FunctionsInfoMap; 976 977 public: 978 // If using this constructor, setting the llvm module by the setModule 979 // function is needed for correct operation. MetaDataUtils()980 MetaDataUtils() {} MetaDataUtils(llvm::Module * pModule)981 MetaDataUtils(llvm::Module* pModule) : 982 m_FunctionsInfo(pModule->getOrInsertNamedMetadata("igc.functions")), 983 m_pModule(pModule) 984 { 985 } 986 setModule(llvm::Module * pModule)987 void setModule(llvm::Module* pModule) { 988 m_FunctionsInfo = pModule->getOrInsertNamedMetadata("igc.functions"); 989 m_pModule = pModule; 990 } 991 ~MetaDataUtils()992 ~MetaDataUtils() {} 993 994 /// FunctionsInfo related methods clearFunctionsInfo()995 void clearFunctionsInfo() 996 { 997 m_FunctionsInfo.clear(); 998 } 999 deleteFunctionsInfo()1000 void deleteFunctionsInfo() 1001 { 1002 llvm::NamedMDNode* FunctionsInfoNode = m_pModule->getNamedMetadata("igc.functions"); 1003 if (FunctionsInfoNode) 1004 { 1005 m_nodesToDelete.push_back(FunctionsInfoNode); 1006 } 1007 } 1008 begin_FunctionsInfo()1009 FunctionsInfoMap::iterator begin_FunctionsInfo() 1010 { 1011 return m_FunctionsInfo.begin(); 1012 } 1013 end_FunctionsInfo()1014 FunctionsInfoMap::iterator end_FunctionsInfo() 1015 { 1016 return m_FunctionsInfo.end(); 1017 } 1018 begin_FunctionsInfo()1019 FunctionsInfoMap::const_iterator begin_FunctionsInfo() const 1020 { 1021 return m_FunctionsInfo.begin(); 1022 } 1023 end_FunctionsInfo()1024 FunctionsInfoMap::const_iterator end_FunctionsInfo() const 1025 { 1026 return m_FunctionsInfo.end(); 1027 } 1028 size_FunctionsInfo()1029 size_t size_FunctionsInfo() const 1030 { 1031 return m_FunctionsInfo.size(); 1032 } 1033 empty_FunctionsInfo()1034 bool empty_FunctionsInfo() const 1035 { 1036 return m_FunctionsInfo.empty(); 1037 } 1038 isFunctionsInfoHasValue()1039 bool isFunctionsInfoHasValue() const 1040 { 1041 return m_FunctionsInfo.hasValue(); 1042 } 1043 getFunctionsInfoItem(const FunctionsInfoMap::key_type & index)1044 FunctionsInfoMap::item_type getFunctionsInfoItem(const FunctionsInfoMap::key_type& index) const 1045 { 1046 return m_FunctionsInfo.getItem(index); 1047 } 1048 getOrInsertFunctionsInfoItem(const FunctionsInfoMap::key_type & index)1049 FunctionsInfoMap::item_type getOrInsertFunctionsInfoItem(const FunctionsInfoMap::key_type& index) 1050 { 1051 return m_FunctionsInfo.getOrInsertItem(index); 1052 } 1053 setFunctionsInfoItem(const FunctionsInfoMap::key_type & index,const FunctionsInfoMap::item_type & item)1054 void setFunctionsInfoItem(const FunctionsInfoMap::key_type& index, const FunctionsInfoMap::item_type& item) 1055 { 1056 return m_FunctionsInfo.setItem(index, item); 1057 } 1058 findFunctionsInfoItem(const FunctionsInfoMap::key_type & key)1059 FunctionsInfoMap::iterator findFunctionsInfoItem(const FunctionsInfoMap::key_type& key) 1060 { 1061 return m_FunctionsInfo.find(key); 1062 } findFunctionsInfoItem(const FunctionsInfoMap::key_type & key)1063 FunctionsInfoMap::const_iterator findFunctionsInfoItem(const FunctionsInfoMap::key_type& key) const 1064 { 1065 return m_FunctionsInfo.find(key); 1066 } 1067 eraseFunctionsInfoItem(FunctionsInfoMap::iterator it)1068 void eraseFunctionsInfoItem(FunctionsInfoMap::iterator it) 1069 { 1070 m_FunctionsInfo.erase(it); 1071 } 1072 save(llvm::LLVMContext & context)1073 void save(llvm::LLVMContext& context) 1074 { 1075 if (m_FunctionsInfo.dirty()) 1076 { 1077 llvm::NamedMDNode* pNode = m_pModule->getOrInsertNamedMetadata("igc.functions"); 1078 m_FunctionsInfo.save(context, pNode); 1079 } 1080 1081 for (auto node : m_nodesToDelete) 1082 { 1083 m_pModule->eraseNamedMetadata(node); 1084 } 1085 m_nodesToDelete.clear(); 1086 1087 discardChanges(); 1088 } 1089 discardChanges()1090 void discardChanges() 1091 { 1092 m_FunctionsInfo.discardChanges(); 1093 m_nodesToDelete.clear(); 1094 } 1095 deleteMetadata()1096 void deleteMetadata() 1097 { 1098 llvm::NamedMDNode* FunctionsInfoNode = m_pModule->getNamedMetadata("igc.functions"); 1099 if (FunctionsInfoNode) 1100 { 1101 m_nodesToDelete.push_back(FunctionsInfoNode); 1102 } 1103 } 1104 1105 private: 1106 // data members 1107 NamedMetaDataMap<llvm::Function, FunctionInfoMetaDataHandle> m_FunctionsInfo; 1108 llvm::Module* m_pModule; 1109 std::vector<llvm::NamedMDNode*> m_nodesToDelete; 1110 }; 1111 1112 1113 } 1114 } //namespace 1115