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 /*========================== begin_copyright_notice ============================
10 
11 This file is distributed under the University of Illinois Open Source License.
12 See LICENSE.TXT for details.
13 
14 ============================= end_copyright_notice ===========================*/
15 
16 ///////////////////////////////////////////////////////////////////////////////
17 // This file is based on llvm-3.4\lib\CodeGen\AsmPrinter\DIE.h
18 ///////////////////////////////////////////////////////////////////////////////
19 
20 #pragma once
21 #include "llvm/Config/llvm-config.h"
22 #include "common/LLVMWarningsPush.hpp"
23 #include "llvm/ADT/FoldingSet.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/Support/Compiler.h"
26 #include "llvm/BinaryFormat/Dwarf.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "common/LLVMWarningsPop.hpp"
29 
30 #include "Probe/Assertion.h"
31 
32 #include <vector>
33 
34 
35 namespace llvm
36 {
37 
38 //namespace dwarf
39 // Intel extensions
40 #ifndef DW_AT_INTEL_simd_width
41 #define DW_AT_INTEL_simd_width 0x2400
42 #endif
43 #ifndef DW_OP_INTEL_regs
44 #define DW_OP_INTEL_regs 0xeb
45 #endif
46 #ifndef DW_OP_INTEL_push_bit_piece_stack
47 #define DW_OP_INTEL_push_bit_piece_stack 0xec
48 #endif
49 #ifndef DW_OP_INTEL_push_simd_lane
50 #define DW_OP_INTEL_push_simd_lane 0xed
51 #endif
52 #ifndef DW_OP_INTEL_piece_stack
53 #define DW_OP_INTEL_piece_stack 0xee
54 #endif
55 #ifndef DW_OP_INTEL_bit_piece_stack
56 #define DW_OP_INTEL_bit_piece_stack 0xef
57 #endif
58 
59     class MCSymbol;
60     class raw_ostream;
61     class MCExpr;
62 }
63 
64 namespace IGC
65 {
66     class RegisterNumbering
67     {
68     public:
69         constexpr static unsigned int IP = 0;
70         constexpr static unsigned int EMask = 1;
71         constexpr static unsigned int BTBase = 5;
72         constexpr static unsigned int ScratchBase = 6;
73         constexpr static unsigned int GenStateBase = 7;
74         constexpr static unsigned int SurfStateBase = 8;
75         constexpr static unsigned int BindlessSurfStateBase = 9;
76         constexpr static unsigned int BindlessSamplerStateBase = 10;
77         constexpr static unsigned int GRFBase = 16;
78         constexpr static unsigned int A0Base = 272;
79         constexpr static unsigned int F0Base = 288;
80         constexpr static unsigned int Acc0Base = 304;
81         constexpr static unsigned int Mme0Base = 335;
82     };
83 
84     // Use following templated method to get encoded register number
85     // for regx and bregx operations. For eg, if GRF to encode in regx is
86     // 10 then invoke method as GetEncodedRegNum<RegisterNumbering::GRFBase>(10).
87     template<unsigned int EncodeBase>
GetEncodedRegNum(unsigned int i)88     unsigned int GetEncodedRegNum(unsigned int i) { return (EncodeBase + i); }
89 
90     class StreamEmitter;
91 
92     //===--------------------------------------------------------------------===//
93     /// DIEAbbrevData - Dwarf abbreviation data, describes one attribute of a
94     /// Dwarf abbreviation.
95     class DIEAbbrevData
96     {
97         /// Attribute - Dwarf attribute code.
98         ///
99         llvm::dwarf::Attribute Attribute;
100 
101         /// Form - Dwarf form code.
102         ///
103         llvm::dwarf::Form Form;
104     public:
DIEAbbrevData(llvm::dwarf::Attribute A,llvm::dwarf::Form F)105         DIEAbbrevData(llvm::dwarf::Attribute A, llvm::dwarf::Form F) : Attribute(A), Form(F) {}
106 
107         // Accessors.
getAttribute() const108         llvm::dwarf::Attribute getAttribute() const { return Attribute; }
getForm() const109         llvm::dwarf::Form getForm() const { return Form; }
110 
111         /// Profile - Used to gather unique data for the abbreviation folding set.
112         ///
113         void Profile(llvm::FoldingSetNodeID& ID) const;
114     };
115 
116     //===--------------------------------------------------------------------===//
117     /// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug
118     /// information object.
119     class DIEAbbrev : public llvm::FoldingSetNode
120     {
121         /// Tag - Dwarf tag code.
122         ///
123         llvm::dwarf::Tag Tag;
124 
125         /// ChildrenFlag - Dwarf children flag.
126         ///
127         uint16_t ChildrenFlag;
128 
129         /// Unique number for node.
130         ///
131         unsigned Number;
132 
133         /// Data - Raw data bytes for abbreviation.
134         ///
135         llvm::SmallVector<DIEAbbrevData, 12> Data;
136 
137     public:
DIEAbbrev(llvm::dwarf::Tag T,uint16_t C)138         DIEAbbrev(llvm::dwarf::Tag T, uint16_t C) : Tag(T), ChildrenFlag(C), Data() {}
139 
140         // Accessors.
getTag() const141         llvm::dwarf::Tag getTag() const { return Tag; }
getNumber() const142         unsigned getNumber() const { return Number; }
getChildrenFlag() const143         uint16_t getChildrenFlag() const { return ChildrenFlag; }
getData() const144         const llvm::SmallVectorImpl<DIEAbbrevData>& getData() const { return Data; }
setChildrenFlag(uint16_t CF)145         void setChildrenFlag(uint16_t CF) { ChildrenFlag = CF; }
setNumber(unsigned N)146         void setNumber(unsigned N) { Number = N; }
147 
148         /// AddAttribute - Adds another set of attribute information to the
149         /// abbreviation.
AddAttribute(llvm::dwarf::Attribute Attribute,llvm::dwarf::Form Form)150         void AddAttribute(llvm::dwarf::Attribute Attribute, llvm::dwarf::Form Form)
151         {
152             Data.push_back(DIEAbbrevData(Attribute, Form));
153         }
154 
155         /// Profile - Used to gather unique data for the abbreviation folding set.
156         ///
157         void Profile(llvm::FoldingSetNodeID& ID) const;
158 
159         /// Emit - Print the abbreviation using the specified asm printer.
160         ///
161         void Emit(StreamEmitter* AP) const;
162 
163 #ifndef NDEBUG
164         void print(llvm::raw_ostream& O);
165         void dump();
166 #endif
167     };
168 
169     //===--------------------------------------------------------------------===//
170     /// DIE - A structured debug information entry.  Has an abbreviation which
171     /// describes its organization.
172     class DIEValue;
173 
174     class DIE
175     {
176     protected:
177         /// Offset - Offset in debug info section.
178         ///
179         unsigned Offset;
180 
181         /// Size - Size of instance + children.
182         ///
183         unsigned Size;
184 
185         /// Abbrev - Buffer for constructing abbreviation.
186         ///
187         DIEAbbrev Abbrev;
188 
189         /// Children DIEs.
190         ///
191         std::vector<DIE*> Children;
192 
193         DIE* Parent;
194 
195         /// Attribute values.
196         ///
197         llvm::SmallVector<DIEValue*, 12> Values;
198 
199     public:
DIE(unsigned Tag)200         explicit DIE(unsigned Tag)
201             : Offset(0), Size(0), Abbrev((llvm::dwarf::Tag)Tag, llvm::dwarf::DW_CHILDREN_no),
202             Parent(0) {}
203         virtual ~DIE();
204 
205         // Accessors.
getAbbrev()206         DIEAbbrev& getAbbrev() { return Abbrev; }
getAbbrev() const207         const DIEAbbrev& getAbbrev() const { return Abbrev; }
getAbbrevNumber() const208         unsigned getAbbrevNumber() const { return Abbrev.getNumber(); }
getTag() const209         llvm::dwarf::Tag getTag() const { return Abbrev.getTag(); }
getOffset() const210         unsigned getOffset() const { return Offset; }
getSize() const211         unsigned getSize() const { return Size; }
getChildren() const212         const std::vector<DIE*>& getChildren() const { return Children; }
getValues() const213         const llvm::SmallVectorImpl<DIEValue*>& getValues() const { return Values; }
getParent() const214         DIE* getParent() const { return Parent; }
215         /// Climb up the parent chain to get the compile unit DIE this DIE belongs
216         /// to.
217         const DIE* getCompileUnit() const;
218         /// Similar to getCompileUnit, returns null when DIE is not added to an
219         /// owner yet.
220         const DIE* getCompileUnitOrNull() const;
setOffset(unsigned O)221         void setOffset(unsigned O) { Offset = O; }
setSize(unsigned S)222         void setSize(unsigned S) { Size = S; }
223 
224         /// addValue - Add a value and attributes to a DIE.
225         ///
addValue(llvm::dwarf::Attribute Attribute,llvm::dwarf::Form Form,DIEValue * Value)226         void addValue(llvm::dwarf::Attribute Attribute, llvm::dwarf::Form Form, DIEValue* Value)
227         {
228             Abbrev.AddAttribute(Attribute, Form);
229             Values.push_back(Value);
230         }
231 
232         /// addChild - Add a child to the DIE.
233         ///
addChild(DIE * Child)234         void addChild(DIE* Child)
235         {
236             IGC_ASSERT(!Child->getParent());
237             Abbrev.setChildrenFlag(llvm::dwarf::DW_CHILDREN_yes);
238             Children.push_back(Child);
239             Child->Parent = this;
240         }
241 
242         /// findAttribute - Find a value in the DIE with the attribute given, returns NULL
243         /// if no such attribute exists.
244         DIEValue* findAttribute(uint16_t Attribute);
245 
246 #ifndef NDEBUG
247         void print(llvm::raw_ostream& O, unsigned IndentCount = 0) const;
248         void dump();
249 #endif
250     };
251 
252     //===--------------------------------------------------------------------===//
253     /// DIEValue - A debug information entry value.
254     ///
255     class DIEValue
256     {
anchor()257         virtual void anchor() {}
258     public:
259         enum
260         {
261             isInteger,
262             isString,
263             isExpr,
264             isLabel,
265             isDelta,
266             isEntry,
267             isBlock,
268             isInlinedString
269         };
270     protected:
271         /// Type - Type of data stored in the value.
272         ///
273         unsigned Type;
274     public:
DIEValue(unsigned T)275         explicit DIEValue(unsigned T) : Type(T) {}
~DIEValue()276         virtual ~DIEValue() {}
277 
278         // Accessors
getType() const279         unsigned getType()  const { return Type; }
280 
281         /// EmitValue - Emit value via the Dwarf writer.
282         ///
283         virtual void EmitValue(StreamEmitter* AP, llvm::dwarf::Form Form) const = 0;
284 
285         /// SizeOf - Return the size of a value in bytes.
286         ///
287         virtual unsigned SizeOf(StreamEmitter* AP, llvm::dwarf::Form Form) const = 0;
288 
289 #ifndef NDEBUG
290         virtual void print(llvm::raw_ostream& O) const = 0;
291         void dump() const;
292 #endif
293     };
294 
295     //===--------------------------------------------------------------------===//
296     /// DIEInteger - An integer value DIE.
297     ///
298     class DIEInteger : public DIEValue
299     {
300         uint64_t Integer;
301     public:
DIEInteger(uint64_t I)302         explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {}
303 
304         /// BestForm - Choose the best form for integer.
305         ///
BestForm(bool IsSigned,uint64_t Int)306         static llvm::dwarf::Form BestForm(bool IsSigned, uint64_t Int)
307         {
308             if (IsSigned)
309             {
310                 const int64_t SignedInt = Int;
311                 if ((char)Int == SignedInt)     return llvm::dwarf::DW_FORM_data1;
312                 if ((short)Int == SignedInt)    return llvm::dwarf::DW_FORM_data2;
313                 if ((int)Int == SignedInt)      return llvm::dwarf::DW_FORM_data4;
314             }
315             else
316             {
317                 if ((unsigned char)Int == Int)  return llvm::dwarf::DW_FORM_data1;
318                 if ((unsigned short)Int == Int) return llvm::dwarf::DW_FORM_data2;
319                 if ((unsigned int)Int == Int)   return llvm::dwarf::DW_FORM_data4;
320             }
321             return llvm::dwarf::DW_FORM_data8;
322         }
323 
324         /// EmitValue - Emit integer of appropriate size.
325         ///
326         virtual void EmitValue(StreamEmitter* AP, llvm::dwarf::Form Form) const;
327 
getValue() const328         uint64_t getValue() const { return Integer; }
329 
setValue(uint64_t v)330         void setValue(uint64_t v) { Integer = v; }
331 
332         /// SizeOf - Determine size of integer value in bytes.
333         ///
334         virtual unsigned SizeOf(StreamEmitter* AP, llvm::dwarf::Form Form) const;
335 
336         // Implement isa/cast/dyncast.
classof(const DIEValue * I)337         static bool classof(const DIEValue* I) { return I->getType() == isInteger; }
338 
339 #ifndef NDEBUG
340         virtual void print(llvm::raw_ostream& O) const;
341 #endif
342     };
343 
344     //===--------------------------------------------------------------------===//
345     /// DIEExpr - An expression DIE.
346     //
347     class DIEExpr : public DIEValue
348     {
349         const llvm::MCExpr* Expr;
350     public:
DIEExpr(const llvm::MCExpr * E)351         explicit DIEExpr(const llvm::MCExpr* E) : DIEValue(isExpr), Expr(E) {}
352 
353         /// EmitValue - Emit expression value.
354         ///
355         virtual void EmitValue(StreamEmitter* AP, llvm::dwarf::Form Form) const;
356 
357         /// getValue - Get llvm::MCExpr.
358         ///
getValue() const359         const llvm::MCExpr* getValue() const { return Expr; }
360 
361         /// SizeOf - Determine size of expression value in bytes.
362         ///
363         virtual unsigned SizeOf(StreamEmitter* AP, llvm::dwarf::Form Form) const;
364 
365         // Implement isa/cast/dyncast.
classof(const DIEValue * E)366         static bool classof(const DIEValue* E) { return E->getType() == isExpr; }
367 
368 #ifndef NDEBUG
369         virtual void print(llvm::raw_ostream& O) const;
370 #endif
371     };
372 
373     //===--------------------------------------------------------------------===//
374     /// DIELabel - A label DIE.
375     //
376     class DIELabel : public DIEValue
377     {
378         const llvm::MCSymbol* Label;
379     public:
DIELabel(const llvm::MCSymbol * L)380         explicit DIELabel(const llvm::MCSymbol* L) : DIEValue(isLabel), Label(L) {}
381 
382         /// EmitValue - Emit label value.
383         ///
384         virtual void EmitValue(StreamEmitter* AP, llvm::dwarf::Form Form) const;
385 
386         /// getValue - Get llvm::MCSymbol.
387         ///
getValue() const388         const llvm::MCSymbol* getValue() const { return Label; }
389 
390         /// SizeOf - Determine size of label value in bytes.
391         ///
392         virtual unsigned SizeOf(StreamEmitter* AP, llvm::dwarf::Form Form) const;
393 
394         // Implement isa/cast/dyncast.
classof(const DIEValue * L)395         static bool classof(const DIEValue* L) { return L->getType() == isLabel; }
396 
397 #ifndef NDEBUG
398         virtual void print(llvm::raw_ostream& O) const;
399 #endif
400     };
401 
402     //===--------------------------------------------------------------------===//
403     /// DIEDelta - A simple label difference DIE.
404     ///
405     class DIEDelta : public DIEValue
406     {
407         const llvm::MCSymbol* LabelHi;
408         const llvm::MCSymbol* LabelLo;
409     public:
DIEDelta(const llvm::MCSymbol * Hi,const llvm::MCSymbol * Lo)410         DIEDelta(const llvm::MCSymbol* Hi, const llvm::MCSymbol* Lo)
411             : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
412 
413         /// EmitValue - Emit delta value.
414         ///
415         virtual void EmitValue(StreamEmitter* AP, llvm::dwarf::Form Form) const;
416 
417         /// SizeOf - Determine size of delta value in bytes.
418         ///
419         virtual unsigned SizeOf(StreamEmitter* AP, llvm::dwarf::Form Form) const;
420 
421         // Implement isa/cast/dyncast.
classof(const DIEValue * D)422         static bool classof(const DIEValue* D) { return D->getType() == isDelta; }
423 
424 #ifndef NDEBUG
425         virtual void print(llvm::raw_ostream& O) const;
426 #endif
427     };
428 
429     //===--------------------------------------------------------------------===//
430     /// DIEString - A container for string values.
431     ///
432     class DIEString : public DIEValue
433     {
434         const DIEValue* Access;
435         const llvm::StringRef Str;
436 
437     public:
DIEString(const DIEValue * Acc,const llvm::StringRef S)438         DIEString(const DIEValue* Acc, const llvm::StringRef S)
439             : DIEValue(isString), Access(Acc), Str(S) {}
440 
441         /// getString - Grab the string out of the object.
getString() const442         llvm::StringRef getString() const { return Str; }
443 
444         /// EmitValue - Emit delta value.
445         ///
446         virtual void EmitValue(StreamEmitter* AP, llvm::dwarf::Form Form) const;
447 
448         /// SizeOf - Determine size of delta value in bytes.
449         ///
450         virtual unsigned SizeOf(StreamEmitter* AP, llvm::dwarf::Form Form) const;
451 
452         // Implement isa/cast/dyncast.
classof(const DIEValue * D)453         static bool classof(const DIEValue* D) { return D->getType() == isString; }
454 
455 #ifndef NDEBUG
456         virtual void print(llvm::raw_ostream& O) const;
457 #endif
458     };
459 
460     //===--------------------------------------------------------------------===//
461     /// DIEInlinedString - A container for inlined string values.
462     ///
463     class DIEInlinedString : public DIEValue
464     {
465         std::string Str;
466 
467     public:
DIEInlinedString(const llvm::StringRef S)468         DIEInlinedString(const llvm::StringRef S)
469             : DIEValue(isInlinedString)
470         {
471             Str = S.str();
472         }
473 
474         /// getString - Grab the string out of the object.
getString() const475         llvm::StringRef getString() const { return Str; }
476 
477         /// EmitValue - Emit delta value.
478         ///
479         virtual void EmitValue(StreamEmitter* AP, llvm::dwarf::Form Form) const;
480 
481         /// SizeOf - Determine size of delta value in bytes.
482         ///
483         virtual unsigned SizeOf(StreamEmitter* AP, llvm::dwarf::Form Form) const;
484 
485         // Implement isa/cast/dyncast.
classof(const DIEValue * D)486         static bool classof(const DIEValue* D) { return D->getType() == isInlinedString; }
487 
488 #ifndef NDEBUG
489         virtual void print(llvm::raw_ostream& O) const;
490 #endif
491     };
492 
493     //===--------------------------------------------------------------------===//
494     /// DIEEntry - A pointer to another debug information entry.  An instance of
495     /// this class can also be used as a proxy for a debug information entry not
496     /// yet defined (ie. types.)
497     class DIEEntry : public DIEValue
498     {
499         DIE* const Entry;
500         unsigned DwarfVersion;
501     public:
DIEEntry(DIE * E,unsigned Version)502         explicit DIEEntry(DIE* E, unsigned Version) : DIEValue(isEntry), Entry(E), DwarfVersion(Version)
503         {
504             IGC_ASSERT_MESSAGE(nullptr != E, "Cannot construct a DIEEntry with a null DIE");
505         }
506 
getEntry() const507         DIE* getEntry() const { return Entry; }
508 
509         /// EmitValue - Emit debug information entry offset.
510         ///
511         virtual void EmitValue(StreamEmitter* AP, llvm::dwarf::Form Form) const;
512 
513         /// SizeOf - Determine size of debug information entry in bytes.
514         ///
SizeOf(StreamEmitter * AP,llvm::dwarf::Form Form) const515         virtual unsigned SizeOf(StreamEmitter* AP, llvm::dwarf::Form Form) const
516         {
517             return Form == llvm::dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP, DwarfVersion) : sizeof(int32_t);
518         }
519 
520         /// Returns size of a ref_addr entry.
521         static unsigned getRefAddrSize(StreamEmitter* AP, unsigned DwarfVersion);
522 
523         // Implement isa/cast/dyncast.
classof(const DIEValue * E)524         static bool classof(const DIEValue* E) { return E->getType() == isEntry; }
525 
526 #ifndef NDEBUG
527         virtual void print(llvm::raw_ostream& O) const;
528 #endif
529     };
530 
531     //===--------------------------------------------------------------------===//
532     /// DIEBlock - A block of values.  Primarily used for location expressions.
533     //
534     class DIEBlock : public DIEValue, public DIE
535     {
536         unsigned Size;                // Size in bytes excluding size header.
537     public:
DIEBlock()538         DIEBlock() : DIEValue(isBlock), DIE(0), Size(0) {}
539 
540         /// ComputeSize - calculate the size of the block.
541         ///
542         unsigned ComputeSize(StreamEmitter* AP);
543 
544         /// ComputeSizeOnTheFly - calculate size of block on the fly.
545         ///
546         unsigned ComputeSizeOnTheFly(StreamEmitter* AP) const;
547 
548         /// EmitToRawBuffer - emit data to raw buffer for encoding in debug_loc
549         ///
550         void EmitToRawBuffer(std::vector<unsigned char>& buffer);
551 
552         /// BestForm - Choose the best form for data.
553         ///
BestForm() const554         llvm::dwarf::Form BestForm() const
555         {
556             if ((unsigned char)Size == Size)  return llvm::dwarf::DW_FORM_block1;
557             if ((unsigned short)Size == Size) return llvm::dwarf::DW_FORM_block2;
558             if ((unsigned int)Size == Size)   return llvm::dwarf::DW_FORM_block4;
559             return llvm::dwarf::DW_FORM_block;
560         }
561 
562         /// EmitValue - Emit block data.
563         ///
564         virtual void EmitValue(StreamEmitter* AP, llvm::dwarf::Form Form) const;
565 
566         /// SizeOf - Determine size of block data in bytes.
567         ///
568         virtual unsigned SizeOf(StreamEmitter* AP, llvm::dwarf::Form Form) const;
569 
570         // Implement isa/cast/dyncast.
classof(const DIEValue * E)571         static bool classof(const DIEValue* E) { return E->getType() == isBlock; }
572 
573 #ifndef NDEBUG
574         virtual void print(llvm::raw_ostream& O) const;
575 #endif
576     };
577 
578 } // namespace IGC
579