30 return "BLOCKINFO_BLOCK";
37 if (!
Info->Name.empty())
38 return Info->Name.c_str();
48 return "OPERAND_BUNDLE_TAGS_BLOCK";
50 return "MODULE_BLOCK";
52 return "PARAMATTR_BLOCK";
54 return "PARAMATTR_GROUP_BLOCK_ID";
56 return "TYPE_BLOCK_ID";
58 return "CONSTANTS_BLOCK";
60 return "FUNCTION_BLOCK";
62 return "IDENTIFICATION_BLOCK_ID";
64 return "VALUE_SYMTAB";
66 return "METADATA_BLOCK";
68 return "METADATA_KIND_BLOCK";
70 return "METADATA_ATTACHMENT_BLOCK";
72 return "USELIST_BLOCK_ID";
74 return "GLOBALVAL_SUMMARY_BLOCK";
76 return "FULL_LTO_GLOBALVAL_SUMMARY_BLOCK";
78 return "MODULE_STRTAB_BLOCK";
80 return "STRTAB_BLOCK";
82 return "SYMTAB_BLOCK";
101 return "SETRECORDNAME";
110 for (
const std::pair<unsigned, std::string> &
RN :
Info->RecordNames)
111 if (
RN.first == CodeID)
112 return RN.second.c_str();
118 #define STRINGIFY_CODE(PREFIX, CODE) \
119 case bitc::PREFIX##_##CODE: \
224 return "CST_CODE_BLOCKADDRESS";
380 return "USELIST_CODE_DEFAULT";
382 return "USELIST_CODE_BB";
390 return "OPERAND_BUNDLE_TAG";
407 #undef STRINGIFY_CODE
414 OS <<
format(
"%lub/%.2fB/%luW", (
unsigned long)
Bits, (
double)
Bits / 8,
415 (
unsigned long)(
Bits / 32));
419 auto tryRead = [&Stream](
char &Dest,
size_t size) ->
Error {
421 Dest = MaybeWord.get();
423 return MaybeWord.takeError();
428 if (
Error Err = tryRead(Signature[0], 8))
430 if (
Error Err = tryRead(Signature[1], 8))
434 if (Signature[0] ==
'C' && Signature[1] ==
'P') {
435 if (
Error Err = tryRead(Signature[2], 8))
437 if (
Error Err = tryRead(Signature[3], 8))
439 if (Signature[2] ==
'C' && Signature[3] ==
'H')
441 }
else if (Signature[0] ==
'D' && Signature[1] ==
'I') {
442 if (
Error Err = tryRead(Signature[2], 8))
444 if (
Error Err = tryRead(Signature[3], 8))
446 if (Signature[2] ==
'A' && Signature[3] ==
'G')
448 }
else if (Signature[0] ==
'R' && Signature[1] ==
'M') {
449 if (
Error Err = tryRead(Signature[2], 8))
451 if (
Error Err = tryRead(Signature[3], 8))
453 if (Signature[2] ==
'R' && Signature[3] ==
'K')
456 if (
Error Err = tryRead(Signature[2], 4))
458 if (
Error Err = tryRead(Signature[3], 4))
460 if (
Error Err = tryRead(Signature[4], 4))
462 if (
Error Err = tryRead(Signature[5], 4))
464 if (Signature[0] ==
'B' && Signature[1] ==
'C' && Signature[2] == 0x0 &&
465 Signature[3] == 0xC && Signature[4] == 0xE && Signature[5] == 0xD)
474 const unsigned char *BufPtr = (
const unsigned char *)Bytes.
data();
475 const unsigned char *EndBufPtr = BufPtr + Bytes.
size();
481 return reportError(
"Invalid bitcode wrapper header");
490 O->OS <<
"<BITCODE_WRAPPER_HEADER"
499 return reportError(
"Invalid bitcode wrapper header");
512 Error BitcodeAnalyzer::decodeMetadataStringsBlob(
StringRef Indent,
521 "Decoding metadata strings blob needs two record entries.");
523 unsigned NumStrings =
Record[0];
524 unsigned StringsOffset =
Record[1];
525 OS <<
" num-strings = " << NumStrings <<
" {\n";
531 if (
R.AtEndOfStream())
535 if (
Error E =
R.ReadVBR(6).moveInto(Size))
537 if (Strings.size() < Size)
540 OS << Indent <<
" '";
543 Strings = Strings.drop_front(Size);
544 }
while (--NumStrings);
546 OS << Indent <<
" }";
554 BlockInfoStream.emplace(*BlockInfoBuffer);
566 if (BlockInfoStream) {
576 return reportError(
"Invalid record at top-level in block info file");
585 .moveInto(NewBlockInfo))
588 return reportError(
"Malformed BlockInfoBlock in block info file");
610 if (
Error E = parseBlock(MaybeBlockID.
get(), 0,
O, CheckHash))
624 O.OS <<
"of " << Filename->
data() <<
":\n";
625 O.OS <<
" Total size: ";
628 O.OS <<
" Stream type: ";
629 switch (CurStreamType) {
637 O.OS <<
"Clang Serialized AST\n";
640 O.OS <<
"Clang Serialized Diagnostics\n";
643 O.OS <<
"LLVM Remarks\n";
646 O.OS <<
" # Toplevel Blocks: " << NumTopBlocks <<
"\n";
650 O.OS <<
"Per-block Summary:\n";
651 for (
const auto &Stat : BlockIDStats) {
652 O.OS <<
" Block ID #" << Stat.first;
655 O.OS <<
" (" << *BlockName <<
")";
658 const PerBlockIDStats &
Stats = Stat.second;
659 O.OS <<
" Num Instances: " <<
Stats.NumInstances <<
"\n";
660 O.OS <<
" Total Size: ";
663 double pct = (
Stats.NumBits * 100.0) / BufferSizeBits;
664 O.OS <<
" Percent of file: " <<
format(
"%2.4f%%", pct) <<
"\n";
665 if (
Stats.NumInstances > 1) {
666 O.OS <<
" Average Size: ";
669 O.OS <<
" Tot/Avg SubBlocks: " <<
Stats.NumSubBlocks <<
"/"
671 O.OS <<
" Tot/Avg Abbrevs: " <<
Stats.NumAbbrevs <<
"/"
672 <<
Stats.NumAbbrevs / (
double)
Stats.NumInstances <<
"\n";
673 O.OS <<
" Tot/Avg Records: " <<
Stats.NumRecords <<
"/"
676 O.OS <<
" Num SubBlocks: " <<
Stats.NumSubBlocks <<
"\n";
677 O.OS <<
" Num Abbrevs: " <<
Stats.NumAbbrevs <<
"\n";
678 O.OS <<
" Num Records: " <<
Stats.NumRecords <<
"\n";
680 if (
Stats.NumRecords) {
681 double pct = (
Stats.NumAbbreviatedRecords * 100.0) /
Stats.NumRecords;
682 O.OS <<
" Percent Abbrevs: " <<
format(
"%2.4f%%", pct) <<
"\n";
687 if (
O.Histogram && !
Stats.CodeFreq.empty()) {
688 std::vector<std::pair<unsigned, unsigned>> FreqPairs;
689 for (
unsigned i = 0,
e =
Stats.CodeFreq.size();
i !=
e; ++
i)
690 if (
unsigned Freq =
Stats.CodeFreq[
i].NumInstances)
691 FreqPairs.push_back(std::make_pair(Freq,
i));
695 O.OS <<
"\tRecord Histogram:\n";
696 O.OS <<
"\t\t Count # Bits b/Rec % Abv Record Kind\n";
697 for (
const auto &FreqPair : FreqPairs) {
698 const PerRecordStats &RecStats =
Stats.CodeFreq[FreqPair.second];
700 O.OS <<
format(
"\t\t%7d %9lu", RecStats.NumInstances,
701 (
unsigned long)RecStats.TotalBits);
703 if (RecStats.NumInstances > 1)
705 (
double)RecStats.TotalBits / RecStats.NumInstances);
709 if (RecStats.NumAbbrev)
710 O.OS <<
format(
" %7.2f", (
double)RecStats.NumAbbrev /
711 RecStats.NumInstances * 100);
717 FreqPair.second, Stat.first, BlockInfo, CurStreamType))
718 O.OS << *CodeName <<
"\n";
720 O.OS <<
"UnknownCode" << FreqPair.second <<
"\n";
727 Error BitcodeAnalyzer::parseBlock(
unsigned BlockID,
unsigned IndentLevel,
730 std::string Indent(IndentLevel * 2,
' ');
734 PerBlockIDStats &BlockStats = BlockIDStats[BlockID];
736 BlockStats.NumInstances++;
739 bool DumpRecords =
O.has_value();
741 if (
O && !
O->DumpBlockinfo)
742 O->OS << Indent <<
"<BLOCKINFO_BLOCK/>\n";
745 .moveInto(NewBlockInfo))
754 DumpRecords =
O &&
O->DumpBlockinfo;
757 unsigned NumWords = 0;
766 O->OS << Indent <<
"<";
767 if ((BlockName =
GetBlockName(BlockID, BlockInfo, CurStreamType)))
770 O->OS <<
"UnknownBlock" << BlockID;
772 if (!
O->Symbolic && BlockName)
773 O->OS <<
" BlockID=" << BlockID;
775 O->OS <<
" NumWords=" << NumWords
796 switch (Entry.Kind) {
801 BlockStats.NumBits += BlockBitEnd - BlockBitStart;
803 O->OS << Indent <<
"</";
805 O->OS << *BlockName <<
">\n";
807 O->OS <<
"UnknownBlock" << BlockID <<
">\n";
814 if (
Error E = parseBlock(Entry.ID, IndentLevel + 1,
O, CheckHash))
816 ++BlockStats.NumSubBlocks;
820 BlockBitStart += SubBlockBitEnd - SubBlockBitStart;
831 ++BlockStats.NumAbbrevs;
837 ++BlockStats.NumRecords;
846 if (BlockStats.CodeFreq.size() <= Code)
847 BlockStats.CodeFreq.resize(Code + 1);
848 BlockStats.CodeFreq[
Code].NumInstances++;
849 BlockStats.CodeFreq[
Code].TotalBits +=
852 BlockStats.CodeFreq[
Code].NumAbbrev++;
853 ++BlockStats.NumAbbreviatedRecords;
857 O->OS << Indent <<
" <";
859 GetCodeName(Code, BlockID, BlockInfo, CurStreamType);
863 O->OS <<
"UnknownCode" <<
Code;
864 if (!
O->Symbolic && CodeName)
865 O->OS <<
" codeid=" <<
Code;
871 Abbv = MaybeAbbv.
get();
872 O->OS <<
" abbrevid=" << Entry.ID;
875 for (
unsigned i = 0,
e =
Record.size();
i !=
e; ++
i)
876 O->OS <<
" op" <<
i <<
"=" << (int64_t)
Record[
i];
883 O->OS <<
"(Invalid record)";
890 O->OS <<
" (offset ";
891 if (MetadataIndexOffset == RecordStartBit)
894 O->OS <<
"mismatch: " << MetadataIndexOffset <<
" vs "
895 << RecordStartBit <<
")";
903 O->OS <<
" (invalid)";
907 std::array<uint8_t, 20> Hash;
908 Hasher.
update(*CheckHash);
910 int BlockSize = (CurrentRecordPos / 8) - BlockEntryPos;
913 Hash = Hasher.result();
915 std::array<uint8_t, 20> RecordedHash;
917 for (
auto &Val :
Record) {
918 assert(!(Val >> 32) &&
"Unexpected high bits set");
922 if (Hash == RecordedHash)
925 O->OS <<
" (!mismatch!)";
936 assert(
i + 2 ==
e &&
"Array op not second to last");
938 bool ArrayIsPrintable =
true;
939 for (
unsigned j =
i - 1, je =
Record.size();
j != je; ++
j) {
941 ArrayIsPrintable =
false;
946 if (ArrayIsPrintable)
947 O->OS <<
" record string = '" << Str <<
"'";
954 if (
Error E = decodeMetadataStringsBlob(Indent,
Record, Blob,
O->OS))
957 O->OS <<
" blob data = ";
958 if (
O->ShowBinaryBlobs) {
960 O->OS.write_escaped(Blob,
true) <<
"'";
962 bool BlobIsPrintable =
true;
964 if (!
isPrint(
static_cast<unsigned char>(
C))) {
965 BlobIsPrintable =
false;
970 O->OS <<
"'" << Blob <<
"'";
972 O->OS <<
"unprintable, " << Blob.size() <<
" bytes.";
981 if (
Error Err =
Stream.JumpToBit(CurrentRecordPos))
986 return Skipped.takeError();