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