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 
13 namespace IGC {
14     namespace SPIRMD
15     {
16         //typedefs and forward declarations
17         class VectorTypeHintMetaData;
18         typedef MetaObjectHandle<VectorTypeHintMetaData> VectorTypeHintMetaDataHandle;
19 
20         class VersionMetaData;
21         typedef MetaObjectHandle<VersionMetaData> VersionMetaDataHandle;
22 
23         class WorkGroupDimensionsMetaData;
24         typedef MetaObjectHandle<WorkGroupDimensionsMetaData> WorkGroupDimensionsMetaDataHandle;
25 
26         class SubGroupDimensionsMetaData;
27         typedef MetaObjectHandle<SubGroupDimensionsMetaData> SubGroupDimensionsMetaDataHandle;
28 
29         class WorkgroupWalkOrderMetaData;
30         typedef MetaObjectHandle<WorkgroupWalkOrderMetaData> WorkgroupWalkOrderMetaDataHandle;
31 
32         class KernelMetaData;
33         typedef MetaObjectHandle<KernelMetaData> KernelMetaDataHandle;
34 
35         typedef MetaDataList<VersionMetaDataHandle> OpenCLVersionsMetaDataList;
36         typedef MetaObjectHandle<OpenCLVersionsMetaDataList> OpenCLVersionsMetaDataListHandle;
37 
38         typedef MetaDataList<VersionMetaDataHandle> SpirVersionsMetaDataList;
39         typedef MetaObjectHandle<SpirVersionsMetaDataList> SpirVersionsMetaDataListHandle;
40 
41         typedef MetaDataList<std::string> InnerUsedKhrExtensionsMetaDataList;
42         typedef MetaObjectHandle<InnerUsedKhrExtensionsMetaDataList> InnerUsedKhrExtensionsMetaDataListHandle;
43 
44         typedef MetaDataList<InnerUsedKhrExtensionsMetaDataListHandle> UsedKhrExtensionsMetaDataList;
45         typedef MetaObjectHandle<UsedKhrExtensionsMetaDataList> UsedKhrExtensionsMetaDataListHandle;
46 
47         typedef MetaDataList<std::string> InnerUsedOptionalCoreFeaturesMetaDataList;
48         typedef MetaObjectHandle<InnerUsedOptionalCoreFeaturesMetaDataList> InnerUsedOptionalCoreFeaturesMetaDataListHandle;
49 
50         typedef MetaDataList<InnerUsedOptionalCoreFeaturesMetaDataListHandle> UsedOptionalCoreFeaturesMetaDataList;
51         typedef MetaObjectHandle<UsedOptionalCoreFeaturesMetaDataList> UsedOptionalCoreFeaturesMetaDataListHandle;
52 
53         typedef MetaDataList<int32_t> FloatingPointContractionsMetaDataList;
54         typedef MetaObjectHandle<FloatingPointContractionsMetaDataList> FloatingPointContractionsMetaDataListHandle;
55 
56         typedef MetaDataList<KernelMetaDataHandle> KernelsMetaDataList;
57         typedef MetaObjectHandle<KernelsMetaDataList> KernelsMetaDataListHandle;
58 
59         typedef MetaDataList<std::string> InnerCompilerOptionsMetaDataList;
60         typedef MetaObjectHandle<InnerCompilerOptionsMetaDataList> InnerCompilerOptionsMetaDataListHandle;
61 
62         typedef MetaDataList<InnerCompilerOptionsMetaDataListHandle> CompilerOptionsMetaDataList;
63         typedef MetaObjectHandle<CompilerOptionsMetaDataList> CompilerOptionsMetaDataListHandle;
64 
65         typedef MetaDataList<std::string> InnerCompilerExternalOptionsMetaDataList;
66         typedef MetaObjectHandle<InnerCompilerExternalOptionsMetaDataList> InnerCompilerExternalOptionsMetaDataListHandle;
67 
68         typedef MetaDataList<InnerCompilerExternalOptionsMetaDataListHandle> CompilerExternalOptionsMetaDataList;
69         typedef MetaObjectHandle<CompilerExternalOptionsMetaDataList> CompilerExternalOptionsMetaDataListHandle;
70 
71         typedef MetaDataList<int32_t> ArgAddressSpacesMetaDataList;
72         typedef MetaObjectHandle<ArgAddressSpacesMetaDataList> ArgAddressSpacesMetaDataListHandle;
73 
74         typedef MetaDataList<std::string> ArgAccessQualifiersMetaDataList;
75         typedef MetaObjectHandle<ArgAccessQualifiersMetaDataList> ArgAccessQualifiersMetaDataListHandle;
76 
77         typedef MetaDataList<std::string> ArgTypesMetaDataList;
78         typedef MetaObjectHandle<ArgTypesMetaDataList> ArgTypesMetaDataListHandle;
79 
80         typedef MetaDataList<std::string> ArgBaseTypesMetaDataList;
81         typedef MetaObjectHandle<ArgBaseTypesMetaDataList> ArgBaseTypesMetaDataListHandle;
82 
83         typedef MetaDataList<std::string> ArgTypeQualifiersMetaDataList;
84         typedef MetaObjectHandle<ArgTypeQualifiersMetaDataList> ArgTypeQualifiersMetaDataListHandle;
85 
86         typedef MetaDataList<std::string> ArgNamesMetaDataList;
87         typedef MetaObjectHandle<ArgNamesMetaDataList> ArgNamesMetaDataListHandle;
88 
89         ///
90         // Read/Write the VectorTypeHint structure from/to LLVM metadata
91         //
92         class VectorTypeHintMetaData :public IMetaDataObject
93         {
94         public:
95             typedef VectorTypeHintMetaData _Myt;
96             typedef IMetaDataObject _Mybase;
97             // typedefs for data member types
98             typedef MetaDataValue<llvm::UndefValue>::value_type VecTypeType;
99             typedef MetaDataValue<bool>::value_type SignType;
100 
101         public:
102             ///
103             // Factory method - creates the VectorTypeHintMetaData from the given metadata node
104             //
105             static _Myt* get(const llvm::MDNode* pNode, bool hasId = false)
106             {
107                 return new _Myt(pNode, hasId);
108             }
109 
110             ///
111             // Factory method - create the default empty VectorTypeHintMetaData object
get()112             static _Myt* get()
113             {
114                 return new _Myt();
115             }
116 
117             ///
118             // Factory method - create the default empty named VectorTypeHintMetaData object
get(const char * name)119             static _Myt* get(const char* name)
120             {
121                 return new _Myt(name);
122             }
123 
124             ///
125             // Ctor - loads the VectorTypeHintMetaData from the given metadata node
126             //
127             VectorTypeHintMetaData(const llvm::MDNode* pNode, bool hasId);
128 
129             ///
130             // Default Ctor - creates the empty, not named VectorTypeHintMetaData object
131             //
132             VectorTypeHintMetaData();
133 
134             ///
135             // Ctor - creates the empty, named VectorTypeHintMetaData object
136             //
137             VectorTypeHintMetaData(const char* name);
138 
139             /// VecType related methods
getVecType()140             VecTypeType getVecType() const
141             {
142                 return m_VecType.get();
143             }
144 
isVecTypeHasValue()145             bool isVecTypeHasValue() const
146             {
147                 return m_VecType.hasValue();
148             }
149 
150 
151             /// Sign related methods
getSign()152             SignType getSign() const
153             {
154                 return m_Sign.get();
155             }
156 
isSignHasValue()157             bool isSignHasValue() const
158             {
159                 return m_Sign.hasValue();
160             }
161 
162             ///
163             // Returns true if any of the VectorTypeHintMetaData`s members has changed
164             bool dirty() const;
165 
166             ///
167             // Returns true if the structure was loaded from the metadata or was changed
168             bool hasValue() const;
169 
170             ///
171             // Discards the changes done to the VectorTypeHintMetaData instance
172             void discardChanges();
173 
174             ///
175             // Generates the new MDNode hierarchy for the given structure
176             llvm::Metadata* generateNode(llvm::LLVMContext& context) const;
177 
178             ///
179             // Saves the structure changes to the given MDNode
180             void save(llvm::LLVMContext& context, llvm::MDNode* pNode) const;
181 
182         private:
183             ///
184             // Returns true if the given MDNode could be saved to without replacement
compatibleWith(const llvm::MDNode * pNode)185             bool compatibleWith(const llvm::MDNode* pNode) const
186             {
187                 return false;
188             }
189 
190         private:
191             typedef MetaDataIterator<llvm::MDNode> NodeIterator;
192 
193             llvm::Metadata* getVecTypeNode(const llvm::MDNode* pParentNode) const;
194             llvm::Metadata* getSignNode(const llvm::MDNode* pParentNode) const;
195 
196         private:
197             // data members
198             MetaDataValue<llvm::UndefValue> m_VecType;
199             MetaDataValue<bool> m_Sign;
200             // parent node
201             const llvm::MDNode* m_pNode;
202         };
203 
204         ///
205         // Read/Write the Version structure from/to LLVM metadata
206         //
207         class VersionMetaData :public IMetaDataObject
208         {
209         public:
210             typedef VersionMetaData _Myt;
211             typedef IMetaDataObject _Mybase;
212             // typedefs for data member types
213             typedef MetaDataValue<int32_t>::value_type MajorType;
214             typedef MetaDataValue<int32_t>::value_type MinorType;
215 
216         public:
217             ///
218             // Factory method - creates the VersionMetaData from the given metadata node
219             //
220             static _Myt* get(const llvm::MDNode* pNode, bool hasId = false)
221             {
222                 return new _Myt(pNode, hasId);
223             }
224 
225             ///
226             // Factory method - create the default empty VersionMetaData object
get()227             static _Myt* get()
228             {
229                 return new _Myt();
230             }
231 
232             ///
233             // Factory method - create the default empty named VersionMetaData object
get(const char * name)234             static _Myt* get(const char* name)
235             {
236                 return new _Myt(name);
237             }
238 
239             ///
240             // Ctor - loads the VersionMetaData from the given metadata node
241             //
242             VersionMetaData(const llvm::MDNode* pNode, bool hasId);
243 
244             ///
245             // Default Ctor - creates the empty, not named VersionMetaData object
246             //
247             VersionMetaData();
248 
249             ///
250             // Ctor - creates the empty, named VersionMetaData object
251             //
252             VersionMetaData(const char* name);
253 
254             /// Major related methods
getMajor()255             MajorType getMajor() const
256             {
257                 return m_Major.get();
258             }
259 
isMajorHasValue()260             bool isMajorHasValue() const
261             {
262                 return m_Major.hasValue();
263             }
264 
265 
266             /// Minor related methods
getMinor()267             MinorType getMinor() const
268             {
269                 return m_Minor.get();
270             }
271 
isMinorHasValue()272             bool isMinorHasValue() const
273             {
274                 return m_Minor.hasValue();
275             }
276 
277             ///
278             // Returns true if any of the VersionMetaData`s members has changed
279             bool dirty() const;
280 
281             ///
282             // Returns true if the structure was loaded from the metadata or was changed
283             bool hasValue() const;
284 
285             ///
286             // Discards the changes done to the VersionMetaData instance
287             void discardChanges();
288 
289             ///
290             // Generates the new MDNode hierarchy for the given structure
291             llvm::Metadata* generateNode(llvm::LLVMContext& context) const;
292 
293             ///
294             // Saves the structure changes to the given MDNode
295             void save(llvm::LLVMContext& context, llvm::MDNode* pNode) const;
296 
297         private:
298             ///
299             // Returns true if the given MDNode could be saved to without replacement
compatibleWith(const llvm::MDNode * pNode)300             bool compatibleWith(const llvm::MDNode* pNode) const
301             {
302                 return false;
303             }
304 
305         private:
306             typedef MetaDataIterator<llvm::MDNode> NodeIterator;
307 
308             llvm::Metadata* getMajorNode(const llvm::MDNode* pParentNode) const;
309             llvm::Metadata* getMinorNode(const llvm::MDNode* pParentNode) const;
310 
311         private:
312             // data members
313             MetaDataValue<int32_t> m_Major;
314             MetaDataValue<int32_t> m_Minor;
315             // parent node
316             const llvm::MDNode* m_pNode;
317         };
318 
319         ///
320         // Read/Write the WorkGroupDimensions structure from/to LLVM metadata
321         //
322         class WorkGroupDimensionsMetaData :public IMetaDataObject
323         {
324         public:
325             typedef WorkGroupDimensionsMetaData _Myt;
326             typedef IMetaDataObject _Mybase;
327             // typedefs for data member types
328             typedef MetaDataValue<int32_t>::value_type XDimType;
329             typedef MetaDataValue<int32_t>::value_type YDimType;
330             typedef MetaDataValue<int32_t>::value_type ZDimType;
331 
332         public:
333             ///
334             // Factory method - creates the WorkGroupDimensionsMetaData from the given metadata node
335             //
336             static _Myt* get(const llvm::MDNode* pNode, bool hasId = false)
337             {
338                 return new _Myt(pNode, hasId);
339             }
340 
341             ///
342             // Factory method - create the default empty WorkGroupDimensionsMetaData object
get()343             static _Myt* get()
344             {
345                 return new _Myt();
346             }
347 
348             ///
349             // Factory method - create the default empty named WorkGroupDimensionsMetaData object
get(const char * name)350             static _Myt* get(const char* name)
351             {
352                 return new _Myt(name);
353             }
354 
355             ///
356             // Ctor - loads the WorkGroupDimensionsMetaData from the given metadata node
357             //
358             WorkGroupDimensionsMetaData(const llvm::MDNode* pNode, bool hasId);
359 
360             ///
361             // Default Ctor - creates the empty, not named WorkGroupDimensionsMetaData object
362             //
363             WorkGroupDimensionsMetaData();
364 
365             ///
366             // Ctor - creates the empty, named WorkGroupDimensionsMetaData object
367             //
368             WorkGroupDimensionsMetaData(const char* name);
369 
370             /// XDim related methods
getXDim()371             XDimType getXDim() const
372             {
373                 return m_XDim.get();
374             }
375 
isXDimHasValue()376             bool isXDimHasValue() const
377             {
378                 return m_XDim.hasValue();
379             }
380 
381 
382             /// YDim related methods
getYDim()383             YDimType getYDim() const
384             {
385                 return m_YDim.get();
386             }
387 
isYDimHasValue()388             bool isYDimHasValue() const
389             {
390                 return m_YDim.hasValue();
391             }
392 
393 
394             /// ZDim related methods
getZDim()395             ZDimType getZDim() const
396             {
397                 return m_ZDim.get();
398             }
399 
isZDimHasValue()400             bool isZDimHasValue() const
401             {
402                 return m_ZDim.hasValue();
403             }
404 
405             ///
406             // Returns true if any of the WorkGroupDimensionsMetaData`s members has changed
407             bool dirty() const;
408 
409             ///
410             // Returns true if the structure was loaded from the metadata or was changed
411             bool hasValue() const;
412 
413             ///
414             // Discards the changes done to the WorkGroupDimensionsMetaData instance
415             void discardChanges();
416 
417             ///
418             // Generates the new MDNode hierarchy for the given structure
419             llvm::Metadata* generateNode(llvm::LLVMContext& context) const;
420 
421             ///
422             // Saves the structure changes to the given MDNode
423             void save(llvm::LLVMContext& context, llvm::MDNode* pNode) const;
424 
425         private:
426             ///
427             // Returns true if the given MDNode could be saved to without replacement
compatibleWith(const llvm::MDNode * pNode)428             bool compatibleWith(const llvm::MDNode* pNode) const
429             {
430                 return false;
431             }
432 
433         private:
434             typedef MetaDataIterator<llvm::MDNode> NodeIterator;
435 
436             llvm::Metadata* getXDimNode(const llvm::MDNode* pParentNode) const;
437             llvm::Metadata* getYDimNode(const llvm::MDNode* pParentNode) const;
438             llvm::Metadata* getZDimNode(const llvm::MDNode* pParentNode) const;
439 
440         private:
441             // data members
442             MetaDataValue<int32_t> m_XDim;
443             MetaDataValue<int32_t> m_YDim;
444             MetaDataValue<int32_t> m_ZDim;
445             // parent node
446             const llvm::MDNode* m_pNode;
447         };
448 
449         ///
450         // Read/Write the SubGroupDimensions structure from/to LLVM metadata
451         //
452         class SubGroupDimensionsMetaData :public IMetaDataObject
453         {
454         public:
455             typedef SubGroupDimensionsMetaData _Myt;
456             typedef IMetaDataObject _Mybase;
457             // typedefs for data member types
458             typedef MetaDataValue<int32_t>::value_type SIMD_SizeType;
459 
460         public:
461             ///
462             // Factory method - creates the SubGroupDimensionsMetaData from the given metadata node
463             //
464             static _Myt* get(const llvm::MDNode* pNode, bool hasId = false)
465             {
466                 return new _Myt(pNode, hasId);
467             }
468 
469             ///
470             // Factory method - create the default empty SubGroupDimensionsMetaData object
get()471             static _Myt* get()
472             {
473                 return new _Myt();
474             }
475 
476             ///
477             // Factory method - create the default empty named SubGroupDimensionsMetaData object
get(const char * name)478             static _Myt* get(const char* name)
479             {
480                 return new _Myt(name);
481             }
482 
483             ///
484             // Ctor - loads the SubGroupDimensionsMetaData from the given metadata node
485             //
486             SubGroupDimensionsMetaData(const llvm::MDNode* pNode, bool hasId);
487 
488             ///
489             // Default Ctor - creates the empty, not named SubGroupDimensionsMetaData object
490             //
491             SubGroupDimensionsMetaData();
492 
493             ///
494             // Ctor - creates the empty, named SubGroupDimensionsMetaData object
495             //
496             SubGroupDimensionsMetaData(const char* name);
497 
498             /// SIMD_Size related methods
getSIMD_Size()499             SIMD_SizeType getSIMD_Size() const
500             {
501                 return m_SIMD_Size.get();
502             }
503 
isSIMD_SizeHasValue()504             bool isSIMD_SizeHasValue() const
505             {
506                 return m_SIMD_Size.hasValue();
507             }
508 
509             ///
510             // Returns true if any of the SubGroupDimensionsMetaData`s members has changed
511             bool dirty() const;
512 
513             ///
514             // Returns true if the structure was loaded from the metadata or was changed
515             bool hasValue() const;
516 
517             ///
518             // Discards the changes done to the SubGroupDimensionsMetaData instance
519             void discardChanges();
520 
521             ///
522             // Generates the new MDNode hierarchy for the given structure
523             llvm::Metadata* generateNode(llvm::LLVMContext& context) const;
524 
525             ///
526             // Saves the structure changes to the given MDNode
527             void save(llvm::LLVMContext& context, llvm::MDNode* pNode) const;
528 
529         private:
530             ///
531             // Returns true if the given MDNode could be saved to without replacement
compatibleWith(const llvm::MDNode * pNode)532             bool compatibleWith(const llvm::MDNode* pNode) const
533             {
534                 return false;
535             }
536 
537         private:
538             typedef MetaDataIterator<llvm::MDNode> NodeIterator;
539 
540             llvm::Metadata* getSIMD_SizeNode(const llvm::MDNode* pParentNode) const;
541 
542         private:
543             // data members
544             MetaDataValue<int32_t> m_SIMD_Size;
545             // parent node
546             const llvm::MDNode* m_pNode;
547         };
548 
549         ///
550         // Read/Write the WorkgroupWalkOrder structure from/to LLVM metadata
551         //
552         class WorkgroupWalkOrderMetaData :public IMetaDataObject
553         {
554         public:
555             typedef WorkgroupWalkOrderMetaData _Myt;
556             typedef IMetaDataObject _Mybase;
557             // typedefs for data member types
558             typedef MetaDataValue<int32_t>::value_type WalkOrderDimType;
559 
560         public:
561             ///
562             // Factory method - creates the SubGroupSizeMetaData from the given metadata node
563             //
564             static _Myt* get(const llvm::MDNode* pNode, bool hasId = false)
565             {
566                 return new _Myt(pNode, hasId);
567             }
568 
569             ///
570             // Factory method - create the default empty SubGroupSizeMetaData object
get()571             static _Myt* get()
572             {
573                 return new _Myt();
574             }
575 
576             ///
577             // Factory method - create the default empty named SubGroupSizeMetaData object
get(const char * name)578             static _Myt* get(const char* name)
579             {
580                 return new _Myt(name);
581             }
582 
583             ///
584             // Ctor - loads the SubGroupSizeMetaData from the given metadata node
585             //
586             WorkgroupWalkOrderMetaData(const llvm::MDNode* pNode, bool hasId);
587 
588             ///
589             // Default Ctor - creates the empty, not named SubGroupSizeMetaData object
590             //
591             WorkgroupWalkOrderMetaData();
592 
593             ///
594             // Ctor - creates the empty, named SubGroupSizeMetaData object
595             //
596             WorkgroupWalkOrderMetaData(const char* name);
597 
598             /// workgroup walk order related methods
getDim0()599             WalkOrderDimType getDim0() const
600             {
601                 return m_Dim0.get();
602             }
getDim1()603             WalkOrderDimType getDim1() const
604             {
605                 return m_Dim1.get();
606             }
getDim2()607             WalkOrderDimType getDim2() const
608             {
609                 return m_Dim2.get();
610             }
611 
612             ///
613             // Returns true if any of the SubGroupSizeMetaData`s members has changed
614             bool dirty() const;
615 
616             ///
617             // Returns true if the structure was loaded from the metadata or was changed
618             bool hasValue() const;
619 
620             ///
621             // Discards the changes done to the SubGroupSizeMetaData instance
622             void discardChanges();
623 
624             ///
625             // Generates the new MDNode hierarchy for the given structure
626             llvm::Metadata* generateNode(llvm::LLVMContext& context) const;
627 
628             ///
629             // Saves the structure changes to the given MDNode
630             void save(llvm::LLVMContext& context, llvm::MDNode* pNode) const;
631 
632         private:
633             ///
634             // Returns true if the given MDNode could be saved to without replacement
compatibleWith(const llvm::MDNode * pNode)635             bool compatibleWith(const llvm::MDNode* pNode) const
636             {
637                 return false;
638             }
639 
640         private:
641             typedef MetaDataIterator<llvm::MDNode> NodeIterator;
642 
643             llvm::Metadata* getDim0Node(const llvm::MDNode* pParentNode) const;
644             llvm::Metadata* getDim1Node(const llvm::MDNode* pParentNode) const;
645             llvm::Metadata* getDim2Node(const llvm::MDNode* pParentNode) const;
646 
647         private:
648             // data members
649             MetaDataValue<int32_t> m_Dim0;
650             MetaDataValue<int32_t> m_Dim1;
651             MetaDataValue<int32_t> m_Dim2;
652             // parent node
653             const llvm::MDNode* m_pNode;
654         };
655 
656         ///
657         // Read/Write the Kernel structure from/to LLVM metadata
658         //
659         class KernelMetaData :public IMetaDataObject
660         {
661         public:
662             typedef KernelMetaData _Myt;
663             typedef IMetaDataObject _Mybase;
664             // typedefs for data member types
665             typedef MetaDataValue<llvm::Function>::value_type FunctionType;
666 
667 
668 
669 
670             typedef MetaDataList<int32_t> ArgAddressSpacesList;
671             typedef MetaDataList<std::string> ArgAccessQualifiersList;
672             typedef MetaDataList<std::string> ArgTypesList;
673             typedef MetaDataList<std::string> ArgBaseTypesList;
674             typedef MetaDataList<std::string> ArgTypeQualifiersList;
675             typedef MetaDataList<std::string> ArgNamesList;
676 
677         public:
678             ///
679             // Factory method - creates the KernelMetaData from the given metadata node
680             //
681             static _Myt* get(const llvm::MDNode* pNode, bool hasId = false)
682             {
683                 return new _Myt(pNode, hasId);
684             }
685 
686             ///
687             // Factory method - create the default empty KernelMetaData object
get()688             static _Myt* get()
689             {
690                 return new _Myt();
691             }
692 
693             ///
694             // Factory method - create the default empty named KernelMetaData object
get(const char * name)695             static _Myt* get(const char* name)
696             {
697                 return new _Myt(name);
698             }
699 
700             ///
701             // Ctor - loads the KernelMetaData from the given metadata node
702             //
703             KernelMetaData(const llvm::MDNode* pNode, bool hasId);
704 
705             ///
706             // Default Ctor - creates the empty, not named KernelMetaData object
707             //
708             KernelMetaData();
709 
710             ///
711             // Ctor - creates the empty, named KernelMetaData object
712             //
713             KernelMetaData(const char* name);
714 
715             /// Function related methods
getFunction()716             FunctionType getFunction() const
717             {
718                 return m_Function.get();
719             }
720 
isFunctionHasValue()721             bool isFunctionHasValue() const
722             {
723                 return m_Function.hasValue();
724             }
725 
726 
727             /// WorkGroupSizeHint related methods
728 
getWorkGroupSizeHint()729             const WorkGroupDimensionsMetaDataHandle getWorkGroupSizeHint()
730             {
731                 return m_WorkGroupSizeHint;
732             }
733 
734 
735             /// RequiredWorkGroupSize related methods
736 
getRequiredWorkGroupSize()737             const WorkGroupDimensionsMetaDataHandle getRequiredWorkGroupSize()
738             {
739                 return m_RequiredWorkGroupSize;
740             }
741 
742 
743             /// RequiredSubGroupSize related methods
744 
getRequiredSubGroupSize()745             const SubGroupDimensionsMetaDataHandle getRequiredSubGroupSize()
746             {
747                 return m_RequiredSubGroupSize;
748             }
749 
750             /// WorkgroupWalkOrder related methods
751 
getWorkgroupWalkOrder()752             const WorkgroupWalkOrderMetaDataHandle getWorkgroupWalkOrder()
753             {
754                 return m_WorkgroupWalkOrder;
755             }
756 
757 
758             /// VectorTypeHint related methods
759 
getVectorTypeHint()760             const VectorTypeHintMetaDataHandle getVectorTypeHint()
761             {
762                 return m_VectorTypeHint;
763             }
764 
765 
766             /// ArgAddressSpaces related methods
767 
begin_ArgAddressSpaces()768             ArgAddressSpacesList::const_iterator begin_ArgAddressSpaces() const
769             {
770                 return m_ArgAddressSpaces.begin();
771             }
772 
end_ArgAddressSpaces()773             ArgAddressSpacesList::const_iterator end_ArgAddressSpaces() const
774             {
775                 return m_ArgAddressSpaces.end();
776             }
777 
size_ArgAddressSpaces()778             size_t size_ArgAddressSpaces()  const
779             {
780                 return m_ArgAddressSpaces.size();
781             }
782 
empty_ArgAddressSpaces()783             bool empty_ArgAddressSpaces()  const
784             {
785                 return m_ArgAddressSpaces.empty();
786             }
787 
isArgAddressSpacesHasValue()788             bool isArgAddressSpacesHasValue() const
789             {
790                 return m_ArgAddressSpaces.hasValue();
791             }
792 
getArgAddressSpacesItem(size_t index)793             const ArgAddressSpacesList::item_type getArgAddressSpacesItem(size_t index) const
794             {
795                 return m_ArgAddressSpaces.getItem(index);
796             }
797 
798 
799 
800             /// ArgAccessQualifiers related methods
801 
begin_ArgAccessQualifiers()802             ArgAccessQualifiersList::const_iterator begin_ArgAccessQualifiers() const
803             {
804                 return m_ArgAccessQualifiers.begin();
805             }
806 
end_ArgAccessQualifiers()807             ArgAccessQualifiersList::const_iterator end_ArgAccessQualifiers() const
808             {
809                 return m_ArgAccessQualifiers.end();
810             }
811 
size_ArgAccessQualifiers()812             size_t size_ArgAccessQualifiers()  const
813             {
814                 return m_ArgAccessQualifiers.size();
815             }
816 
empty_ArgAccessQualifiers()817             bool empty_ArgAccessQualifiers()  const
818             {
819                 return m_ArgAccessQualifiers.empty();
820             }
821 
isArgAccessQualifiersHasValue()822             bool isArgAccessQualifiersHasValue() const
823             {
824                 return m_ArgAccessQualifiers.hasValue();
825             }
826 
getArgAccessQualifiersItem(size_t index)827             const ArgAccessQualifiersList::item_type getArgAccessQualifiersItem(size_t index) const
828             {
829                 return m_ArgAccessQualifiers.getItem(index);
830             }
831 
832 
833 
834             /// ArgTypes related methods
835 
begin_ArgTypes()836             ArgTypesList::const_iterator begin_ArgTypes() const
837             {
838                 return m_ArgTypes.begin();
839             }
840 
end_ArgTypes()841             ArgTypesList::const_iterator end_ArgTypes() const
842             {
843                 return m_ArgTypes.end();
844             }
845 
size_ArgTypes()846             size_t size_ArgTypes()  const
847             {
848                 return m_ArgTypes.size();
849             }
850 
empty_ArgTypes()851             bool empty_ArgTypes()  const
852             {
853                 return m_ArgTypes.empty();
854             }
855 
isArgTypesHasValue()856             bool isArgTypesHasValue() const
857             {
858                 return m_ArgTypes.hasValue();
859             }
860 
getArgTypesItem(size_t index)861             const ArgTypesList::item_type getArgTypesItem(size_t index) const
862             {
863                 return m_ArgTypes.getItem(index);
864             }
865 
866 
867 
868             /// ArgBaseTypes related methods
869 
begin_ArgBaseTypes()870             ArgBaseTypesList::const_iterator begin_ArgBaseTypes() const
871             {
872                 return m_ArgBaseTypes.begin();
873             }
874 
end_ArgBaseTypes()875             ArgBaseTypesList::const_iterator end_ArgBaseTypes() const
876             {
877                 return m_ArgBaseTypes.end();
878             }
879 
size_ArgBaseTypes()880             size_t size_ArgBaseTypes()  const
881             {
882                 return m_ArgBaseTypes.size();
883             }
884 
empty_ArgBaseTypes()885             bool empty_ArgBaseTypes()  const
886             {
887                 return m_ArgBaseTypes.empty();
888             }
889 
isArgBaseTypesHasValue()890             bool isArgBaseTypesHasValue() const
891             {
892                 return m_ArgBaseTypes.hasValue();
893             }
894 
getArgBaseTypesItem(size_t index)895             const ArgBaseTypesList::item_type getArgBaseTypesItem(size_t index) const
896             {
897                 return m_ArgBaseTypes.getItem(index);
898             }
899 
900 
901 
902             /// ArgTypeQualifiers related methods
903 
begin_ArgTypeQualifiers()904             ArgTypeQualifiersList::const_iterator begin_ArgTypeQualifiers() const
905             {
906                 return m_ArgTypeQualifiers.begin();
907             }
908 
end_ArgTypeQualifiers()909             ArgTypeQualifiersList::const_iterator end_ArgTypeQualifiers() const
910             {
911                 return m_ArgTypeQualifiers.end();
912             }
913 
size_ArgTypeQualifiers()914             size_t size_ArgTypeQualifiers()  const
915             {
916                 return m_ArgTypeQualifiers.size();
917             }
918 
empty_ArgTypeQualifiers()919             bool empty_ArgTypeQualifiers()  const
920             {
921                 return m_ArgTypeQualifiers.empty();
922             }
923 
isArgTypeQualifiersHasValue()924             bool isArgTypeQualifiersHasValue() const
925             {
926                 return m_ArgTypeQualifiers.hasValue();
927             }
928 
getArgTypeQualifiersItem(size_t index)929             const ArgTypeQualifiersList::item_type getArgTypeQualifiersItem(size_t index) const
930             {
931                 return m_ArgTypeQualifiers.getItem(index);
932             }
933 
934 
935 
936             /// ArgNames related methods
937 
begin_ArgNames()938             ArgNamesList::const_iterator begin_ArgNames() const
939             {
940                 return m_ArgNames.begin();
941             }
942 
end_ArgNames()943             ArgNamesList::const_iterator end_ArgNames() const
944             {
945                 return m_ArgNames.end();
946             }
947 
size_ArgNames()948             size_t size_ArgNames()  const
949             {
950                 return m_ArgNames.size();
951             }
952 
empty_ArgNames()953             bool empty_ArgNames()  const
954             {
955                 return m_ArgNames.empty();
956             }
957 
isArgNamesHasValue()958             bool isArgNamesHasValue() const
959             {
960                 return m_ArgNames.hasValue();
961             }
962 
getArgNamesItem(size_t index)963             const ArgNamesList::item_type getArgNamesItem(size_t index) const
964             {
965                 return m_ArgNames.getItem(index);
966             }
967 
968             ///
969             // Returns true if any of the KernelMetaData`s members has changed
970             bool dirty() const;
971 
972             ///
973             // Returns true if the structure was loaded from the metadata or was changed
974             bool hasValue() const;
975 
976             ///
977             // Discards the changes done to the KernelMetaData instance
978             void discardChanges();
979 
980             ///
981             // Generates the new MDNode hierarchy for the given structure
982             llvm::Metadata* generateNode(llvm::LLVMContext& context) const;
983 
984             ///
985             // Saves the structure changes to the given MDNode
986             void save(llvm::LLVMContext& context, llvm::MDNode* pNode) const;
987 
988         private:
989             ///
990             // Returns true if the given MDNode could be saved to without replacement
compatibleWith(const llvm::MDNode * pNode)991             bool compatibleWith(const llvm::MDNode* pNode) const
992             {
993                 return false;
994             }
995 
996         private:
997             typedef MetaDataIterator<llvm::MDNode> NodeIterator;
998 
999             llvm::Metadata* getFunctionNode(const llvm::MDNode* pParentNode) const;
1000             llvm::MDNode* getWorkGroupSizeHintNode(const llvm::MDNode* pParentNode) const;
1001             llvm::MDNode* getRequiredWorkGroupSizeNode(const llvm::MDNode* pParentNode) const;
1002             llvm::MDNode* getRequiredSubGroupSizeNode(const llvm::MDNode* pParentNode) const;
1003             llvm::MDNode* getWorkgroupWalkOrderNode(const llvm::MDNode* pParentNode) const;
1004             llvm::MDNode* getVectorTypeHintNode(const llvm::MDNode* pParentNode) const;
1005             llvm::MDNode* getArgAddressSpacesNode(const llvm::MDNode* pParentNode) const;
1006             llvm::MDNode* getArgAccessQualifiersNode(const llvm::MDNode* pParentNode) const;
1007             llvm::MDNode* getArgTypesNode(const llvm::MDNode* pParentNode) const;
1008             llvm::MDNode* getArgBaseTypesNode(const llvm::MDNode* pParentNode) const;
1009             llvm::MDNode* getArgTypeQualifiersNode(const llvm::MDNode* pParentNode) const;
1010             llvm::MDNode* getArgNamesNode(const llvm::MDNode* pParentNode) const;
1011 
1012         private:
1013             // data members
1014             MetaDataValue<llvm::Function> m_Function;
1015             WorkGroupDimensionsMetaDataHandle m_WorkGroupSizeHint;
1016             WorkGroupDimensionsMetaDataHandle m_RequiredWorkGroupSize;
1017             SubGroupDimensionsMetaDataHandle m_RequiredSubGroupSize;
1018             WorkgroupWalkOrderMetaDataHandle m_WorkgroupWalkOrder;
1019             VectorTypeHintMetaDataHandle m_VectorTypeHint;
1020             MetaDataList<int32_t> m_ArgAddressSpaces;
1021             MetaDataList<std::string> m_ArgAccessQualifiers;
1022             MetaDataList<std::string> m_ArgTypes;
1023             MetaDataList<std::string> m_ArgBaseTypes;
1024             MetaDataList<std::string> m_ArgTypeQualifiers;
1025             MetaDataList<std::string> m_ArgNames;
1026             // parent node
1027             const llvm::MDNode* m_pNode;
1028         };
1029 
1030 
1031         class SpirMetaDataUtils
1032         {
1033         public:
1034             // typedefs for the data members types
1035             typedef NamedMDNodeList<KernelMetaDataHandle> KernelsList;
1036             typedef NamedMDNodeList<InnerCompilerOptionsMetaDataListHandle> CompilerOptionsList;
1037             typedef NamedMDNodeList<InnerCompilerExternalOptionsMetaDataListHandle> CompilerExternalOptionsList;
1038             typedef NamedMDNodeList<int32_t> FloatingPointContractionsList;
1039             typedef NamedMDNodeList<InnerUsedOptionalCoreFeaturesMetaDataListHandle> UsedOptionalCoreFeaturesList;
1040             typedef NamedMDNodeList<InnerUsedKhrExtensionsMetaDataListHandle> UsedKhrExtensionsList;
1041             typedef NamedMDNodeList<VersionMetaDataHandle> SpirVersionsList;
1042             typedef NamedMDNodeList<VersionMetaDataHandle> OpenCLVersionsList;
1043 
1044         public:
1045             // If using this constructor, setting the llvm module by the setModule
1046             // function is needed for correct operation.
SpirMetaDataUtils()1047             SpirMetaDataUtils() {}
1048 
1049 
1050 
SpirMetaDataUtils(llvm::Module * pModule)1051             SpirMetaDataUtils(llvm::Module* pModule) :
1052                 m_Kernels(pModule->getNamedMetadata("opencl.kernels")),
1053                 m_CompilerOptions(pModule->getNamedMetadata("opencl.compiler.options")),
1054                 m_CompilerExternalOptions(pModule->getNamedMetadata("opencl.compiler.ext.options")),
1055                 m_FloatingPointContractions(pModule->getNamedMetadata("opencl.enable.FP_CONTRACT")),
1056                 m_UsedOptionalCoreFeatures(pModule->getNamedMetadata("opencl.used.optional.core.features")),
1057                 m_UsedKhrExtensions(pModule->getNamedMetadata("opencl.used.extensions")),
1058                 m_SpirVersions(pModule->getNamedMetadata("opencl.spir.version")),
1059                 m_OpenCLVersions(pModule->getNamedMetadata("opencl.ocl.version")),
1060                 m_pModule(pModule)
1061             {
1062             }
1063 
setModule(llvm::Module * pModule)1064             void setModule(llvm::Module* pModule) {
1065                 m_Kernels = pModule->getNamedMetadata("opencl.kernels");
1066                 m_CompilerOptions = pModule->getNamedMetadata("opencl.compiler.options");
1067                 m_CompilerExternalOptions = pModule->getNamedMetadata("opencl.compiler.ext.options");
1068                 m_FloatingPointContractions = pModule->getNamedMetadata("opencl.enable.FP_CONTRACT");
1069                 m_UsedOptionalCoreFeatures = pModule->getNamedMetadata("opencl.used.optional.core.features");
1070                 m_UsedKhrExtensions = pModule->getNamedMetadata("opencl.used.extensions");
1071                 m_SpirVersions = pModule->getNamedMetadata("opencl.spir.version");
1072                 m_OpenCLVersions = pModule->getNamedMetadata("opencl.ocl.version");
1073                 m_pModule = pModule;
1074             }
1075 
~SpirMetaDataUtils()1076             ~SpirMetaDataUtils() {}
1077 
1078             /// Kernels related methods
1079 
1080 
begin_Kernels()1081             KernelsList::const_iterator begin_Kernels() const
1082             {
1083                 return m_Kernels.begin();
1084             }
1085 
end_Kernels()1086             KernelsList::const_iterator end_Kernels() const
1087             {
1088                 return m_Kernels.end();
1089             }
1090 
size_Kernels()1091             size_t size_Kernels()  const
1092             {
1093                 return m_Kernels.size();
1094             }
1095 
empty_Kernels()1096             bool empty_Kernels()  const
1097             {
1098                 return m_Kernels.empty();
1099             }
1100 
isKernelsHasValue()1101             bool isKernelsHasValue() const
1102             {
1103                 return m_Kernels.hasValue();
1104             }
1105 
getKernelsItem(size_t index)1106             const KernelsList::item_type getKernelsItem(size_t index) const
1107             {
1108                 return m_Kernels.getItem(index);
1109             }
1110 
1111 
1112 
1113             /// CompilerOptions related methods
1114 
1115 
begin_CompilerOptions()1116             CompilerOptionsList::const_iterator begin_CompilerOptions() const
1117             {
1118                 return m_CompilerOptions.begin();
1119             }
1120 
end_CompilerOptions()1121             CompilerOptionsList::const_iterator end_CompilerOptions() const
1122             {
1123                 return m_CompilerOptions.end();
1124             }
1125 
size_CompilerOptions()1126             size_t size_CompilerOptions()  const
1127             {
1128                 return m_CompilerOptions.size();
1129             }
1130 
empty_CompilerOptions()1131             bool empty_CompilerOptions()  const
1132             {
1133                 return m_CompilerOptions.empty();
1134             }
1135 
isCompilerOptionsHasValue()1136             bool isCompilerOptionsHasValue() const
1137             {
1138                 return m_CompilerOptions.hasValue();
1139             }
1140 
getCompilerOptionsItem(size_t index)1141             const CompilerOptionsList::item_type getCompilerOptionsItem(size_t index) const
1142             {
1143                 return m_CompilerOptions.getItem(index);
1144             }
1145 
1146 
1147 
1148             /// CompilerExternalOptions related methods
1149 
1150 
begin_CompilerExternalOptions()1151             CompilerExternalOptionsList::const_iterator begin_CompilerExternalOptions() const
1152             {
1153                 return m_CompilerExternalOptions.begin();
1154             }
1155 
end_CompilerExternalOptions()1156             CompilerExternalOptionsList::const_iterator end_CompilerExternalOptions() const
1157             {
1158                 return m_CompilerExternalOptions.end();
1159             }
1160 
size_CompilerExternalOptions()1161             size_t size_CompilerExternalOptions()  const
1162             {
1163                 return m_CompilerExternalOptions.size();
1164             }
1165 
empty_CompilerExternalOptions()1166             bool empty_CompilerExternalOptions()  const
1167             {
1168                 return m_CompilerExternalOptions.empty();
1169             }
1170 
isCompilerExternalOptionsHasValue()1171             bool isCompilerExternalOptionsHasValue() const
1172             {
1173                 return m_CompilerExternalOptions.hasValue();
1174             }
1175 
getCompilerExternalOptionsItem(size_t index)1176             const CompilerExternalOptionsList::item_type getCompilerExternalOptionsItem(size_t index) const
1177             {
1178                 return m_CompilerExternalOptions.getItem(index);
1179             }
1180 
1181 
1182 
1183             /// FloatingPointContractions related methods
1184 
1185 
begin_FloatingPointContractions()1186             FloatingPointContractionsList::const_iterator begin_FloatingPointContractions() const
1187             {
1188                 return m_FloatingPointContractions.begin();
1189             }
1190 
end_FloatingPointContractions()1191             FloatingPointContractionsList::const_iterator end_FloatingPointContractions() const
1192             {
1193                 return m_FloatingPointContractions.end();
1194             }
1195 
size_FloatingPointContractions()1196             size_t size_FloatingPointContractions()  const
1197             {
1198                 return m_FloatingPointContractions.size();
1199             }
1200 
empty_FloatingPointContractions()1201             bool empty_FloatingPointContractions()  const
1202             {
1203                 return m_FloatingPointContractions.empty();
1204             }
1205 
isFloatingPointContractionsHasValue()1206             bool isFloatingPointContractionsHasValue() const
1207             {
1208                 return m_FloatingPointContractions.hasValue();
1209             }
1210 
getFloatingPointContractionsItem(size_t index)1211             const FloatingPointContractionsList::item_type getFloatingPointContractionsItem(size_t index) const
1212             {
1213                 return m_FloatingPointContractions.getItem(index);
1214             }
1215 
1216 
1217 
1218             /// UsedOptionalCoreFeatures related methods
1219 
1220 
begin_UsedOptionalCoreFeatures()1221             UsedOptionalCoreFeaturesList::const_iterator begin_UsedOptionalCoreFeatures() const
1222             {
1223                 return m_UsedOptionalCoreFeatures.begin();
1224             }
1225 
end_UsedOptionalCoreFeatures()1226             UsedOptionalCoreFeaturesList::const_iterator end_UsedOptionalCoreFeatures() const
1227             {
1228                 return m_UsedOptionalCoreFeatures.end();
1229             }
1230 
size_UsedOptionalCoreFeatures()1231             size_t size_UsedOptionalCoreFeatures()  const
1232             {
1233                 return m_UsedOptionalCoreFeatures.size();
1234             }
1235 
empty_UsedOptionalCoreFeatures()1236             bool empty_UsedOptionalCoreFeatures()  const
1237             {
1238                 return m_UsedOptionalCoreFeatures.empty();
1239             }
1240 
isUsedOptionalCoreFeaturesHasValue()1241             bool isUsedOptionalCoreFeaturesHasValue() const
1242             {
1243                 return m_UsedOptionalCoreFeatures.hasValue();
1244             }
1245 
getUsedOptionalCoreFeaturesItem(size_t index)1246             const UsedOptionalCoreFeaturesList::item_type getUsedOptionalCoreFeaturesItem(size_t index) const
1247             {
1248                 return m_UsedOptionalCoreFeatures.getItem(index);
1249             }
1250 
1251 
1252 
1253             /// UsedKhrExtensions related methods
1254 
1255 
begin_UsedKhrExtensions()1256             UsedKhrExtensionsList::const_iterator begin_UsedKhrExtensions() const
1257             {
1258                 return m_UsedKhrExtensions.begin();
1259             }
1260 
end_UsedKhrExtensions()1261             UsedKhrExtensionsList::const_iterator end_UsedKhrExtensions() const
1262             {
1263                 return m_UsedKhrExtensions.end();
1264             }
1265 
size_UsedKhrExtensions()1266             size_t size_UsedKhrExtensions()  const
1267             {
1268                 return m_UsedKhrExtensions.size();
1269             }
1270 
empty_UsedKhrExtensions()1271             bool empty_UsedKhrExtensions()  const
1272             {
1273                 return m_UsedKhrExtensions.empty();
1274             }
1275 
isUsedKhrExtensionsHasValue()1276             bool isUsedKhrExtensionsHasValue() const
1277             {
1278                 return m_UsedKhrExtensions.hasValue();
1279             }
1280 
getUsedKhrExtensionsItem(size_t index)1281             const UsedKhrExtensionsList::item_type getUsedKhrExtensionsItem(size_t index) const
1282             {
1283                 return m_UsedKhrExtensions.getItem(index);
1284             }
1285 
1286 
1287 
1288             /// SpirVersions related methods
1289 
1290 
begin_SpirVersions()1291             SpirVersionsList::const_iterator begin_SpirVersions() const
1292             {
1293                 return m_SpirVersions.begin();
1294             }
1295 
end_SpirVersions()1296             SpirVersionsList::const_iterator end_SpirVersions() const
1297             {
1298                 return m_SpirVersions.end();
1299             }
1300 
size_SpirVersions()1301             size_t size_SpirVersions()  const
1302             {
1303                 return m_SpirVersions.size();
1304             }
1305 
empty_SpirVersions()1306             bool empty_SpirVersions()  const
1307             {
1308                 return m_SpirVersions.empty();
1309             }
1310 
isSpirVersionsHasValue()1311             bool isSpirVersionsHasValue() const
1312             {
1313                 return m_SpirVersions.hasValue();
1314             }
1315 
getSpirVersionsItem(size_t index)1316             const SpirVersionsList::item_type getSpirVersionsItem(size_t index) const
1317             {
1318                 return m_SpirVersions.getItem(index);
1319             }
1320 
1321 
1322 
1323             /// OpenCLVersions related methods
1324 
1325 
begin_OpenCLVersions()1326             OpenCLVersionsList::const_iterator begin_OpenCLVersions() const
1327             {
1328                 return m_OpenCLVersions.begin();
1329             }
1330 
end_OpenCLVersions()1331             OpenCLVersionsList::const_iterator end_OpenCLVersions() const
1332             {
1333                 return m_OpenCLVersions.end();
1334             }
1335 
size_OpenCLVersions()1336             size_t size_OpenCLVersions()  const
1337             {
1338                 return m_OpenCLVersions.size();
1339             }
1340 
empty_OpenCLVersions()1341             bool empty_OpenCLVersions()  const
1342             {
1343                 return m_OpenCLVersions.empty();
1344             }
1345 
isOpenCLVersionsHasValue()1346             bool isOpenCLVersionsHasValue() const
1347             {
1348                 return m_OpenCLVersions.hasValue();
1349             }
1350 
getOpenCLVersionsItem(size_t index)1351             const OpenCLVersionsList::item_type getOpenCLVersionsItem(size_t index) const
1352             {
1353                 return m_OpenCLVersions.getItem(index);
1354             }
1355 
1356 
1357 
deleteMetadata()1358             void deleteMetadata()
1359             {
1360                 llvm::NamedMDNode* KernelsNode = m_pModule->getNamedMetadata("opencl.kernels");
1361                 if (KernelsNode)
1362                 {
1363                     m_pModule->eraseNamedMetadata(KernelsNode);
1364                 }
1365 
1366                 llvm::NamedMDNode* CompilerOptionsNode = m_pModule->getNamedMetadata("opencl.compiler.options");
1367                 if (CompilerOptionsNode)
1368                 {
1369                     m_pModule->eraseNamedMetadata(CompilerOptionsNode);
1370                 }
1371 
1372                 llvm::NamedMDNode* CompilerExternalOptionsNode = m_pModule->getNamedMetadata("opencl.compiler.ext.options");
1373                 if (CompilerExternalOptionsNode)
1374                 {
1375                     m_pModule->eraseNamedMetadata(CompilerExternalOptionsNode);
1376                 }
1377 
1378                 llvm::NamedMDNode* FloatingPointContractionsNode = m_pModule->getNamedMetadata("opencl.enable.FP_CONTRACT");
1379                 if (FloatingPointContractionsNode)
1380                 {
1381                     m_pModule->eraseNamedMetadata(FloatingPointContractionsNode);
1382                 }
1383 
1384                 llvm::NamedMDNode* UsedOptionalCoreFeaturesNode = m_pModule->getNamedMetadata("opencl.used.optional.core.features");
1385                 if (UsedOptionalCoreFeaturesNode)
1386                 {
1387                     m_pModule->eraseNamedMetadata(UsedOptionalCoreFeaturesNode);
1388                 }
1389 
1390                 llvm::NamedMDNode* UsedKhrExtensionsNode = m_pModule->getNamedMetadata("opencl.used.extensions");
1391                 if (UsedKhrExtensionsNode)
1392                 {
1393                     m_pModule->eraseNamedMetadata(UsedKhrExtensionsNode);
1394                 }
1395 
1396                 llvm::NamedMDNode* SpirVersionsNode = m_pModule->getNamedMetadata("opencl.spir.version");
1397                 if (SpirVersionsNode)
1398                 {
1399                     m_pModule->eraseNamedMetadata(SpirVersionsNode);
1400                 }
1401 
1402                 llvm::NamedMDNode* OpenCLVersionsNode = m_pModule->getNamedMetadata("opencl.ocl.version");
1403                 if (OpenCLVersionsNode)
1404                 {
1405                     m_pModule->eraseNamedMetadata(OpenCLVersionsNode);
1406                 }
1407             }
1408 
1409         private:
1410             // data members
1411             NamedMDNodeList<KernelMetaDataHandle> m_Kernels;
1412             NamedMDNodeList<InnerCompilerOptionsMetaDataListHandle> m_CompilerOptions;
1413             NamedMDNodeList<InnerCompilerExternalOptionsMetaDataListHandle> m_CompilerExternalOptions;
1414             NamedMDNodeList<int32_t> m_FloatingPointContractions;
1415             NamedMDNodeList<InnerUsedOptionalCoreFeaturesMetaDataListHandle> m_UsedOptionalCoreFeatures;
1416             NamedMDNodeList<InnerUsedKhrExtensionsMetaDataListHandle> m_UsedKhrExtensions;
1417             NamedMDNodeList<VersionMetaDataHandle> m_SpirVersions;
1418             NamedMDNodeList<VersionMetaDataHandle> m_OpenCLVersions;
1419             llvm::Module* m_pModule;
1420         };
1421 
1422 
1423     }
1424 } //namespace
1425