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