LLVM: lib/Bitcode/Reader/BitcodeAnalyzer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

16#include

17

18using namespace llvm;

19

22}

23

24

25static std::optional<const char *>

28

31 return "BLOCKINFO_BLOCK";

32 return std::nullopt;

33 }

34

35

38 if (Info->Name.empty())

39 return Info->Name.c_str();

40 }

41

43 return std::nullopt;

44

45 switch (BlockID) {

46 default:

47 return std::nullopt;

49 return "OPERAND_BUNDLE_TAGS_BLOCK";

51 return "MODULE_BLOCK";

53 return "PARAMATTR_BLOCK";

55 return "PARAMATTR_GROUP_BLOCK_ID";

57 return "TYPE_BLOCK_ID";

59 return "CONSTANTS_BLOCK";

61 return "FUNCTION_BLOCK";

63 return "IDENTIFICATION_BLOCK_ID";

65 return "VALUE_SYMTAB";

67 return "METADATA_BLOCK";

69 return "METADATA_KIND_BLOCK";

71 return "METADATA_ATTACHMENT_BLOCK";

73 return "USELIST_BLOCK_ID";

75 return "GLOBALVAL_SUMMARY_BLOCK";

77 return "FULL_LTO_GLOBALVAL_SUMMARY_BLOCK";

79 return "MODULE_STRTAB_BLOCK";

81 return "STRTAB_BLOCK";

83 return "SYMTAB_BLOCK";

84 }

85}

86

87

88static std::optional<const char *>

92

95 switch (CodeID) {

96 default:

97 return std::nullopt;

99 return "SETBID";

101 return "BLOCKNAME";

103 return "SETRECORDNAME";

104 }

105 }

106 return std::nullopt;

107 }

108

109

112 for (const std::pair<unsigned, std::string> &RN : Info->RecordNames)

113 if (RN.first == CodeID)

114 return RN.second.c_str();

115 }

116

118 return std::nullopt;

119

120#define STRINGIFY_CODE(PREFIX, CODE) \

121 case bitc::PREFIX##_##CODE: \

122 return #CODE;

123 switch (BlockID) {

124 default:

125 return std::nullopt;

127 switch (CodeID) {

128 default:

129 return std::nullopt;

135 STRINGIFY_CODE(MODULE_CODE, DEPLIB)

145 }

147 switch (CodeID) {

148 default:

149 return std::nullopt;

152 }

154 switch (CodeID) {

155 default:

156 return std::nullopt;

157

159 return "ENTRY";

161 return "ENTRY";

162 }

164 switch (CodeID) {

165 default:

166 return std::nullopt;

168 return "ENTRY";

169 }

171 switch (CodeID) {

172 default:

173 return std::nullopt;

196 }

197

199 switch (CodeID) {

200 default:

201 return std::nullopt;

227 return "CST_CODE_BLOCKADDRESS";

229 }

231 switch (CodeID) {

232 default:

233 return std::nullopt;

279 }

281 switch (CodeID) {

282 default:

283 return std::nullopt;

288 }

290 switch (CodeID) {

291 default:

292 return std::nullopt;

295 }

298 switch (CodeID) {

299 default:

300 return std::nullopt;

305 STRINGIFY_CODE(FS, PERMODULE_VTABLE_GLOBALVAR_INIT_REFS)

333 }

335 switch (CodeID) {

336 default:

337 return std::nullopt;

339 }

341 switch (CodeID) {

342 default:

343 return std::nullopt;

349 STRINGIFY_CODE(METADATA, KIND)

383 }

385 switch (CodeID) {

386 default:

387 return std::nullopt;

389 }

391 switch (CodeID) {

392 default:

393 return std::nullopt;

395 return "USELIST_CODE_DEFAULT";

397 return "USELIST_CODE_BB";

398 }

399

401 switch (CodeID) {

402 default:

403 return std::nullopt;

405 return "OPERAND_BUNDLE_TAG";

406 }

408 switch (CodeID) {

409 default:

410 return std::nullopt;

412 return "BLOB";

413 }

415 switch (CodeID) {

416 default:

417 return std::nullopt;

419 return "BLOB";

420 }

421 }

422#undef STRINGIFY_CODE

423}

424

426 OS << format("%.2f/%.2fB/%luW", Bits, Bits / 8, (unsigned long)(Bits / 32));

427}

429 OS << format("%lub/%.2fB/%luW", (unsigned long)Bits, (double)Bits / 8,

430 (unsigned long)(Bits / 32));

431}

432

434 auto tryRead = [&Stream](char &Dest, size_t size) -> Error {

436 Dest = MaybeWord.get();

437 else

438 return MaybeWord.takeError();

440 };

441

442 char Signature[6];

443 if (Error Err = tryRead(Signature[0], 8))

444 return std::move(Err);

445 if (Error Err = tryRead(Signature[1], 8))

446 return std::move(Err);

447

448

449 if (Signature[0] == 'C' && Signature[1] == 'P') {

450 if (Error Err = tryRead(Signature[2], 8))

451 return std::move(Err);

452 if (Error Err = tryRead(Signature[3], 8))

453 return std::move(Err);

454 if (Signature[2] == 'C' && Signature[3] == 'H')

456 } else if (Signature[0] == 'D' && Signature[1] == 'I') {

457 if (Error Err = tryRead(Signature[2], 8))

458 return std::move(Err);

459 if (Error Err = tryRead(Signature[3], 8))

460 return std::move(Err);

461 if (Signature[2] == 'A' && Signature[3] == 'G')

463 } else if (Signature[0] == 'R' && Signature[1] == 'M') {

464 if (Error Err = tryRead(Signature[2], 8))

465 return std::move(Err);

466 if (Error Err = tryRead(Signature[3], 8))

467 return std::move(Err);

468 if (Signature[2] == 'R' && Signature[3] == 'K')

470 } else {

471 if (Error Err = tryRead(Signature[2], 4))

472 return std::move(Err);

473 if (Error Err = tryRead(Signature[3], 4))

474 return std::move(Err);

475 if (Error Err = tryRead(Signature[4], 4))

476 return std::move(Err);

477 if (Error Err = tryRead(Signature[5], 4))

478 return std::move(Err);

479 if (Signature[0] == 'B' && Signature[1] == 'C' && Signature[2] == 0x0 &&

480 Signature[3] == 0xC && Signature[4] == 0xE && Signature[5] == 0xD)

482 }

484}

485

489 const unsigned char *BufPtr = (const unsigned char *)Bytes.data();

490 const unsigned char *EndBufPtr = BufPtr + Bytes.size();

491

492

493

496 return reportError("Invalid bitcode wrapper header");

497

498 if (O) {

504

505 O->OS << "<BITCODE_WRAPPER_HEADER"

506 << " Magic=" << format_hex(Magic, 10)

507 << " Version=" << format_hex(Version, 10)

510 << " CPUType=" << format_hex(CPUType, 10) << "/>\n";

511 }

512

514 return reportError("Invalid bitcode wrapper header");

515 }

516

517

519

521}

522

525}

526

527Error BitcodeAnalyzer::decodeMetadataStringsBlob(StringRef Indent,

531 if (Blob.empty())

532 return reportError("Cannot decode empty blob.");

533

534 if (Record.size() != 2)

536 "Decoding metadata strings blob needs two record entries.");

537

538 unsigned NumStrings = Record[0];

539 unsigned StringsOffset = Record[1];

540 OS << " num-strings = " << NumStrings << " {\n";

541

545 do {

546 if (R.AtEndOfStream())

548

550 if (Error E = R.ReadVBR(6).moveInto(Size))

551 return E;

552 if (Strings.size() < Size)

554

555 OS << Indent << " '";

557 OS << "'\n";

558 Strings = Strings.drop_front(Size);

559 } while (--NumStrings);

560

561 OS << Indent << " }";

563}

564

566 std::optional BlockInfoBuffer)

567 : Stream(Buffer) {

568 if (BlockInfoBuffer)

569 BlockInfoStream.emplace(*BlockInfoBuffer);

570}

571

573 std::optional CheckHash) {

575 return E;

576

578

579

580

581 if (BlockInfoStream) {

584 return E;

585

588 if (!MaybeCode)

591 return reportError("Invalid record at top-level in block info file");

592

594 if (!MaybeBlockID)

597 std::optional NewBlockInfo;

600 .moveInto(NewBlockInfo))

601 return E;

602 if (!NewBlockInfo)

603 return reportError("Malformed BlockInfoBlock in block info file");

604 BlockInfo = std::move(*NewBlockInfo);

605 break;

606 }

607

609 return Err;

610 }

611 }

612

613

616 if (!MaybeCode)

619 return reportError("Invalid record at top-level");

620

622 if (!MaybeBlockID)

624

625 if (Error E = parseBlock(MaybeBlockID.get(), 0, O, CheckHash))

626 return E;

627 ++NumTopBlocks;

628 }

629

631}

632

634 std::optional Filename) {

636

637 O.OS << "Summary ";

638 if (Filename)

639 O.OS << "of " << Filename->data() << ":\n";

640 O.OS << " Total size: ";

642 O.OS << "\n";

643 O.OS << " Stream type: ";

644 switch (CurStreamType) {

646 O.OS << "unknown\n";

647 break;

649 O.OS << "LLVM IR\n";

650 break;

652 O.OS << "Clang Serialized AST\n";

653 break;

655 O.OS << "Clang Serialized Diagnostics\n";

656 break;

658 O.OS << "LLVM Remarks\n";

659 break;

660 }

661 O.OS << " # Toplevel Blocks: " << NumTopBlocks << "\n";

662 O.OS << "\n";

663

664

665 O.OS << "Per-block Summary:\n";

666 for (const auto &Stat : BlockIDStats) {

667 O.OS << " Block ID #" << Stat.first;

668 if (std::optional<const char *> BlockName =

669 GetBlockName(Stat.first, BlockInfo, CurStreamType))

670 O.OS << " (" << *BlockName << ")";

671 O.OS << ":\n";

672

673 const PerBlockIDStats &Stats = Stat.second;

674 O.OS << " Num Instances: " << Stats.NumInstances << "\n";

675 O.OS << " Total Size: ";

677 O.OS << "\n";

678 double pct = (Stats.NumBits * 100.0) / BufferSizeBits;

679 O.OS << " Percent of file: " << format("%2.4f%%", pct) << "\n";

680 if (Stats.NumInstances > 1) {

681 O.OS << " Average Size: ";

683 O.OS << "\n";

684 O.OS << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/"

685 << Stats.NumSubBlocks / (double)Stats.NumInstances << "\n";

686 O.OS << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/"

687 << Stats.NumAbbrevs / (double)Stats.NumInstances << "\n";

688 O.OS << " Tot/Avg Records: " << Stats.NumRecords << "/"

689 << Stats.NumRecords / (double)Stats.NumInstances << "\n";

690 } else {

691 O.OS << " Num SubBlocks: " << Stats.NumSubBlocks << "\n";

692 O.OS << " Num Abbrevs: " << Stats.NumAbbrevs << "\n";

693 O.OS << " Num Records: " << Stats.NumRecords << "\n";

694 }

695 if (Stats.NumRecords) {

696 double pct = (Stats.NumAbbreviatedRecords * 100.0) / Stats.NumRecords;

697 O.OS << " Percent Abbrevs: " << format("%2.4f%%", pct) << "\n";

698 }

699 O.OS << "\n";

700

701

702 if (O.Histogram && Stats.CodeFreq.empty()) {

703 std::vector<std::pair<unsigned, unsigned>> FreqPairs;

704 for (unsigned i = 0, e = Stats.CodeFreq.size(); i != e; ++i)

705 if (unsigned Freq = Stats.CodeFreq[i].NumInstances)

706 FreqPairs.push_back(std::make_pair(Freq, i));

708 std::reverse(FreqPairs.begin(), FreqPairs.end());

709

710 O.OS << "\tRecord Histogram:\n";

711 O.OS << "\t\t Count # Bits b/Rec % Abv Record Kind\n";

712 for (const auto &FreqPair : FreqPairs) {

713 const PerRecordStats &RecStats = Stats.CodeFreq[FreqPair.second];

714

715 O.OS << format("\t\t%7d %9lu", RecStats.NumInstances,

716 (unsigned long)RecStats.TotalBits);

717

718 if (RecStats.NumInstances > 1)

719 O.OS << format(" %9.1f",

720 (double)RecStats.TotalBits / RecStats.NumInstances);

721 else

722 O.OS << " ";

723

724 if (RecStats.NumAbbrev)

725 O.OS << format(" %7.2f", (double)RecStats.NumAbbrev /

726 RecStats.NumInstances * 100);

727 else

728 O.OS << " ";

729

730 O.OS << " ";

731 if (std::optional<const char *> CodeName = GetCodeName(

732 FreqPair.second, Stat.first, BlockInfo, CurStreamType))

733 O.OS << *CodeName << "\n";

734 else

735 O.OS << "UnknownCode" << FreqPair.second << "\n";

736 }

737 O.OS << "\n";

738 }

739 }

740}

741

742Error BitcodeAnalyzer::parseBlock(unsigned BlockID, unsigned IndentLevel,

743 std::optional O,

744 std::optional CheckHash) {

745 std::string Indent(IndentLevel * 2, ' ');

747

748

749 PerBlockIDStats &BlockStats = BlockIDStats[BlockID];

750

751 BlockStats.NumInstances++;

752

753

754 bool DumpRecords = O.has_value();

756 if (O && !O->DumpBlockinfo)

757 O->OS << Indent << "<BLOCKINFO_BLOCK/>\n";

758 std::optional NewBlockInfo;

760 .moveInto(NewBlockInfo))

761 return E;

762 if (!NewBlockInfo)

763 return reportError("Malformed BlockInfoBlock");

764 BlockInfo = std::move(*NewBlockInfo);

766 return Err;

767

768

769 DumpRecords = O && O->DumpBlockinfo;

770 }

771

772 unsigned NumWords = 0;

774 return Err;

775

776

778

779 std::optional<const char *> BlockName;

780 if (DumpRecords) {

781 O->OS << Indent << "<";

782 if ((BlockName = GetBlockName(BlockID, BlockInfo, CurStreamType)))

783 O->OS << *BlockName;

784 else

785 O->OS << "UnknownBlock" << BlockID;

786

787 if (!O->Symbolic && BlockName)

788 O->OS << " BlockID=" << BlockID;

789

790 O->OS << " NumWords=" << NumWords

792 }

793

795

796

797 uint64_t MetadataIndexOffset = 0;

798

799

800 while (true) {

802 return reportError("Premature end of bitstream");

803

805

808 .moveInto(Entry))

809 return E;

810

811 switch (Entry.Kind) {

813 return reportError("malformed bitcode file");

816 BlockStats.NumBits += BlockBitEnd - BlockBitStart;

817 if (DumpRecords) {

818 O->OS << Indent << "</";

819 if (BlockName)

820 O->OS << *BlockName << ">\n";

821 else

822 O->OS << "UnknownBlock" << BlockID << ">\n";

823 }

825 }

826

829 if (Error E = parseBlock(Entry.ID, IndentLevel + 1, O, CheckHash))

830 return E;

831 ++BlockStats.NumSubBlocks;

833

834

835 BlockBitStart += SubBlockBitEnd - SubBlockBitStart;

836 continue;

837 }

839

840 break;

841 }

842

845 return Err;

846 ++BlockStats.NumAbbrevs;

847 continue;

848 }

849

851

852 ++BlockStats.NumRecords;

853

856 unsigned Code;

858 return E;

859

860

861 if (BlockStats.CodeFreq.size() <= Code)

862 BlockStats.CodeFreq.resize(Code + 1);

863 BlockStats.CodeFreq[Code].NumInstances++;

864 BlockStats.CodeFreq[Code].TotalBits +=

867 BlockStats.CodeFreq[Code].NumAbbrev++;

868 ++BlockStats.NumAbbreviatedRecords;

869 }

870

871 if (DumpRecords) {

872 O->OS << Indent << " <";

873 std::optional<const char *> CodeName =

874 GetCodeName(Code, BlockID, BlockInfo, CurStreamType);

875 if (CodeName)

876 O->OS << *CodeName;

877 else

878 O->OS << "UnknownCode" << Code;

879 if (O->Symbolic && CodeName)

880 O->OS << " codeid=" << Code;

884 if (!MaybeAbbv)

886 Abbv = MaybeAbbv.get();

887 O->OS << " abbrevid=" << Entry.ID;

888 }

889

890 for (unsigned i = 0, e = Record.size(); i != e; ++i)

891 O->OS << " op" << i << "=" << (int64_t)Record[i];

892

893

894

897 if (Record.size() != 2)

898 O->OS << "(Invalid record)";

899 else {

902 }

903 }

905 O->OS << " (offset ";

906 if (MetadataIndexOffset == RecordStartBit)

907 O->OS << "match)";

908 else

909 O->OS << "mismatch: " << MetadataIndexOffset << " vs "

910 << RecordStartBit << ")";

911 }

912 }

913

914

916 CheckHash) {

917 if (Record.size() != 5)

918 O->OS << " (invalid)";

919 else {

920

922 std::array<uint8_t, 20> Hash;

923 Hasher.update(*CheckHash);

924 {

925 int BlockSize = (CurrentRecordPos / 8) - BlockEntryPos;

928 Hash = Hasher.result();

929 }

930 std::array<uint8_t, 20> RecordedHash;

931 int Pos = 0;

932 for (auto &Val : Record) {

933 assert(!(Val >> 32) && "Unexpected high bits set");

935 Pos += 4;

936 }

937 if (Hash == RecordedHash)

938 O->OS << " (match)";

939 else

940 O->OS << " (!mismatch!)";

941 }

942 }

943

944 O->OS << "/>";

945

946 if (Abbv) {

950 continue;

951 assert(i + 2 == e && "Array op not second to last");

952 std::string Str;

953 bool ArrayIsPrintable = true;

954 for (unsigned j = i - 1, je = Record.size(); j != je; ++j) {

955 if (isPrint(static_cast<unsigned char>(Record[j]))) {

956 ArrayIsPrintable = false;

957 break;

958 }

960 }

961 if (ArrayIsPrintable)

962 O->OS << " record string = '" << Str << "'";

963 break;

964 }

965 }

966

967 if (Blob.data()) {

969 if (Error E = decodeMetadataStringsBlob(Indent, Record, Blob, O->OS))

970 return E;

971 } else {

972 O->OS << " blob data = ";

973 if (O->ShowBinaryBlobs) {

974 O->OS << "'";

975 O->OS.write_escaped(Blob, true) << "'";

976 } else {

977 bool BlobIsPrintable = true;

978 for (char C : Blob)

979 if (isPrint(static_cast<unsigned char>(C))) {

980 BlobIsPrintable = false;

981 break;

982 }

983

984 if (BlobIsPrintable)

985 O->OS << "'" << Blob << "'";

986 else

987 O->OS << "unprintable, " << Blob.size() << " bytes.";

988 }

989 }

990 }

991

992 O->OS << "\n";

993 }

994

995

996 if (Error Err = Stream.JumpToBit(CurrentRecordPos))

997 return Err;

999 ;

1000 else

1001 return Skipped.takeError();

1002 }

1003}

1004

#define STRINGIFY_CODE(PREFIX, CODE)

static bool canDecodeBlob(unsigned Code, unsigned BlockID)

static std::optional< const char * > GetBlockName(unsigned BlockID, const BitstreamBlockInfo &BlockInfo, CurStreamTypeType CurStreamType)

Return a symbolic block name if known, otherwise return null.

static Expected< CurStreamTypeType > ReadSignature(BitstreamCursor &Stream)

static std::optional< const char * > GetCodeName(unsigned CodeID, unsigned BlockID, const BitstreamBlockInfo &BlockInfo, CurStreamTypeType CurStreamType)

Return a symbolic code name if known, otherwise return null.

static void printSize(raw_ostream &OS, double Bits)

static Expected< CurStreamTypeType > analyzeHeader(std::optional< BCDumpOptions > O, BitstreamCursor &Stream)

static Error reportError(StringRef Message)

Analysis containing CSE Info

#define FUNCTION(NAME, NARG, ROUND_MODE, INTRINSIC)

#define KIND(ENUM, FIELD)

#define ENTRY(ASMNAME, ENUM)

block placement Basic Block Placement Stats

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

static const int BlockSize

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

BitCodeAbbrevOp - This describes one or more operands in an abbreviation.

BitCodeAbbrev - This class represents an abbreviation record.

unsigned getNumOperandInfos() const

const BitCodeAbbrevOp & getOperandInfo(unsigned N) const

BitcodeAnalyzer(StringRef Buffer, std::optional< StringRef > BlockInfoBuffer=std::nullopt)

Error analyze(std::optional< BCDumpOptions > O=std::nullopt, std::optional< StringRef > CheckHash=std::nullopt)

Analyze the bitcode file.

void printStats(BCDumpOptions O, std::optional< StringRef > Filename=std::nullopt)

Print stats about the bitcode file.

This class maintains the abbreviations read from a block info block.

const BlockInfo * getBlockInfo(unsigned BlockID) const

If there is block info for the specified ID, return it, otherwise return null.

This represents a position within a bitcode file, implemented on top of a SimpleBitstreamCursor.

Error JumpToBit(uint64_t BitNo)

Reset the stream to the specified bit number.

uint64_t GetCurrentBitNo() const

Return the bit # of the bit we are reading.

Expected< unsigned > ReadSubBlockID()

Having read the ENTER_SUBBLOCK code, read the BlockID for the block.

ArrayRef< uint8_t > getBitcodeBytes() const

Expected< word_t > Read(unsigned NumBits)

Expected< BitstreamEntry > advance(unsigned Flags=0)

Advance the current bitstream, returning the next entry in the stream.

Expected< const BitCodeAbbrev * > getAbbrev(unsigned AbbrevID)

Return the abbreviation for the specified AbbrevId.

void setBlockInfo(BitstreamBlockInfo *BI)

Set the block info to be used by this BitstreamCursor to interpret abbreviated records.

const uint8_t * getPointerToByte(uint64_t ByteNo, uint64_t NumBytes)

Get a pointer into the bitstream at the specified byte offset.

Expected< unsigned > readRecord(unsigned AbbrevID, SmallVectorImpl< uint64_t > &Vals, StringRef *Blob=nullptr)

Error EnterSubBlock(unsigned BlockID, unsigned *NumWordsP=nullptr)

Having read the ENTER_SUBBLOCK abbrevid, and enter the block.

@ AF_DontAutoprocessAbbrevs

If this flag is used, abbrev entries are returned just like normal records.

Error SkipBlock()

Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip over the body of this block.

uint64_t getCurrentByteNo() const

Expected< unsigned > ReadCode()

Expected< std::optional< BitstreamBlockInfo > > ReadBlockInfoBlock(bool ReadBlockInfoNames=false)

Read and return a block info block from the bitstream.

unsigned getAbbrevIDWidth() const

Return the number of bits used to encode an abbrev #.

This class represents an Operation in the Expression.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

reference get()

Returns a reference to the stored T value.

A class that wrap the SHA1 algorithm.

void update(ArrayRef< uint8_t > Data)

Digest more data.

This represents a position within a bitstream.

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

constexpr bool empty() const

empty - Check if the string is empty.

StringRef drop_front(size_t N=1) const

Return a StringRef equal to 'this' but with the first N elements dropped.

StringRef slice(size_t Start, size_t End) const

Return a reference to the substring from [Start, End).

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

This class implements an extremely fast bulk output stream that can only output to a stream.

raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)

Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an esca...

@ C

The default llvm calling convention, compatible with C.

@ BLOCKINFO_CODE_BLOCKNAME

@ BLOCKINFO_CODE_SETRECORDNAME

@ PARAMATTR_GROUP_BLOCK_ID

@ IDENTIFICATION_BLOCK_ID

@ GLOBALVAL_SUMMARY_BLOCK_ID

@ FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID

@ OPERAND_BUNDLE_TAGS_BLOCK_ID

@ BLOCKINFO_BLOCK_ID

BLOCKINFO_BLOCK is used to define metadata about blocks, for example, standard abbrevs that should be...

@ FIRST_APPLICATION_BLOCKID

@ DEFINE_ABBREV

DEFINE_ABBREV - Defines an abbrev for the current block.

@ PARAMATTR_CODE_ENTRY_OLD

@ PARAMATTR_GRP_CODE_ENTRY

NodeAddr< CodeNode * > Code

void write32be(void *P, uint32_t V)

uint32_t read32le(const void *P)

This is an optimization pass for GlobalISel generic memory operations.

void stable_sort(R &&Range)

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)

format_hex - Output N as a fixed width hexadecimal.

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

CurStreamTypeType

CurStreamTypeType - A type for CurStreamType.

@ ClangSerializedDiagnosticsBitstream

@ ClangSerializedASTBitstream

bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr, const unsigned char *&BufEnd, bool VerifyBufferSize)

SkipBitcodeWrapperHeader - Some systems wrap bc files with a special header for padding or other reas...

bool isBitcodeWrapper(const unsigned char *BufPtr, const unsigned char *BufEnd)

isBitcodeWrapper - Return true if the given bytes are the magic bytes for an LLVM IR bitcode wrapper.

This contains information emitted to BLOCKINFO_BLOCK blocks.

When advancing through a bitstream cursor, each advance can discover a few different kinds of entries...