Mercurial > hg > CbC > CbC_llvm
comparison tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
comparison
equal
deleted
inserted
replaced
146:3fc4d5c3e21e | 148:63bd29f05246 |
---|---|
1 //===-- llvm-bcanalyzer.cpp - Bitcode Analyzer --------------------------===// | 1 //===-- llvm-bcanalyzer.cpp - Bitcode Analyzer --------------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 // | 4 // See https://llvm.org/LICENSE.txt for license information. |
5 // This file is distributed under the University of Illinois Open Source | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // License. See LICENSE.TXT for details. | |
7 // | 6 // |
8 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
9 // | 8 // |
10 // This tool may be invoked in the following manner: | 9 // This tool may be invoked in the following manner: |
11 // llvm-bcanalyzer [options] - Read LLVM bitcode from stdin | 10 // llvm-bcanalyzer [options] - Read LLVM bitcode from stdin |
25 // format that shows the containment and relationships of the information in | 24 // format that shows the containment and relationships of the information in |
26 // the bitcode file (-dump option). | 25 // the bitcode file (-dump option). |
27 // | 26 // |
28 //===----------------------------------------------------------------------===// | 27 //===----------------------------------------------------------------------===// |
29 | 28 |
30 #include "llvm/ADT/StringExtras.h" | 29 #include "llvm/ADT/Optional.h" |
31 #include "llvm/Bitcode/BitcodeReader.h" | 30 #include "llvm/Bitcode/BitcodeAnalyzer.h" |
32 #include "llvm/Bitcode/BitstreamReader.h" | |
33 #include "llvm/Bitcode/LLVMBitCodes.h" | |
34 #include "llvm/Support/CommandLine.h" | 31 #include "llvm/Support/CommandLine.h" |
35 #include "llvm/Support/Format.h" | 32 #include "llvm/Support/Error.h" |
36 #include "llvm/Support/ManagedStatic.h" | 33 #include "llvm/Support/InitLLVM.h" |
37 #include "llvm/Support/MemoryBuffer.h" | 34 #include "llvm/Support/MemoryBuffer.h" |
38 #include "llvm/Support/PrettyStackTrace.h" | |
39 #include "llvm/Support/SHA1.h" | |
40 #include "llvm/Support/Signals.h" | |
41 #include "llvm/Support/raw_ostream.h" | 35 #include "llvm/Support/raw_ostream.h" |
36 #include <memory> | |
42 using namespace llvm; | 37 using namespace llvm; |
43 | 38 |
44 static cl::opt<std::string> | 39 static cl::opt<std::string> |
45 InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); | 40 InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); |
46 | 41 |
47 static cl::opt<bool> Dump("dump", cl::desc("Dump low level bitcode trace")); | 42 static cl::opt<bool> Dump("dump", cl::desc("Dump low level bitcode trace")); |
48 | 43 |
49 //===----------------------------------------------------------------------===// | 44 //===----------------------------------------------------------------------===// |
50 // Bitcode specific analysis. | 45 // Bitcode specific analysis. |
51 //===----------------------------------------------------------------------===// | 46 //===----------------------------------------------------------------------===// |
52 | 47 |
53 static cl::opt<bool> NoHistogram("disable-histogram", | 48 static cl::opt<bool> NoHistogram("disable-histogram", |
54 cl::desc("Do not print per-code histogram")); | 49 cl::desc("Do not print per-code histogram")); |
55 | 50 |
56 static cl::opt<bool> | 51 static cl::opt<bool> NonSymbolic("non-symbolic", |
57 NonSymbolic("non-symbolic", | 52 cl::desc("Emit numeric info in dump even if" |
58 cl::desc("Emit numeric info in dump even if" | 53 " symbolic info is available")); |
59 " symbolic info is available")); | |
60 | 54 |
61 static cl::opt<std::string> | 55 static cl::opt<std::string> |
62 BlockInfoFilename("block-info", | 56 BlockInfoFilename("block-info", |
63 cl::desc("Use the BLOCK_INFO from the given file")); | 57 cl::desc("Use the BLOCK_INFO from the given file")); |
64 | 58 |
65 static cl::opt<bool> | 59 static cl::opt<bool> |
66 ShowBinaryBlobs("show-binary-blobs", | 60 ShowBinaryBlobs("show-binary-blobs", |
67 cl::desc("Print binary blobs using hex escapes")); | 61 cl::desc("Print binary blobs using hex escapes")); |
68 | 62 |
69 static cl::opt<std::string> CheckHash( | 63 static cl::opt<std::string> CheckHash( |
70 "check-hash", | 64 "check-hash", |
71 cl::desc("Check module hash using the argument as a string table")); | 65 cl::desc("Check module hash using the argument as a string table")); |
72 | 66 |
73 namespace { | 67 static Error reportError(StringRef Message) { |
74 | 68 return createStringError(std::errc::illegal_byte_sequence, Message.data()); |
75 /// CurStreamTypeType - A type for CurStreamType | |
76 enum CurStreamTypeType { | |
77 UnknownBitstream, | |
78 LLVMIRBitstream | |
79 }; | |
80 | |
81 } | 69 } |
82 | 70 |
83 /// GetBlockName - Return a symbolic block name if known, otherwise return | 71 static Expected<std::unique_ptr<MemoryBuffer>> openBitcodeFile(StringRef Path) { |
84 /// null. | 72 // Read the input file. |
85 static const char *GetBlockName(unsigned BlockID, | 73 Expected<std::unique_ptr<MemoryBuffer>> MemBufOrErr = |
86 const BitstreamBlockInfo &BlockInfo, | 74 errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Path)); |
87 CurStreamTypeType CurStreamType) { | 75 if (Error E = MemBufOrErr.takeError()) |
88 // Standard blocks for all bitcode files. | 76 return std::move(E); |
89 if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) { | |
90 if (BlockID == bitc::BLOCKINFO_BLOCK_ID) | |
91 return "BLOCKINFO_BLOCK"; | |
92 return nullptr; | |
93 } | |
94 | 77 |
95 // Check to see if we have a blockinfo record for this block, with a name. | 78 std::unique_ptr<MemoryBuffer> MemBuf = std::move(*MemBufOrErr); |
96 if (const BitstreamBlockInfo::BlockInfo *Info = | |
97 BlockInfo.getBlockInfo(BlockID)) { | |
98 if (!Info->Name.empty()) | |
99 return Info->Name.c_str(); | |
100 } | |
101 | 79 |
102 | 80 if (MemBuf->getBufferSize() & 3) |
103 if (CurStreamType != LLVMIRBitstream) return nullptr; | 81 return reportError( |
104 | 82 "Bitcode stream should be a multiple of 4 bytes in length"); |
105 switch (BlockID) { | 83 return std::move(MemBuf); |
106 default: return nullptr; | |
107 case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID: return "OPERAND_BUNDLE_TAGS_BLOCK"; | |
108 case bitc::MODULE_BLOCK_ID: return "MODULE_BLOCK"; | |
109 case bitc::PARAMATTR_BLOCK_ID: return "PARAMATTR_BLOCK"; | |
110 case bitc::PARAMATTR_GROUP_BLOCK_ID: return "PARAMATTR_GROUP_BLOCK_ID"; | |
111 case bitc::TYPE_BLOCK_ID_NEW: return "TYPE_BLOCK_ID"; | |
112 case bitc::CONSTANTS_BLOCK_ID: return "CONSTANTS_BLOCK"; | |
113 case bitc::FUNCTION_BLOCK_ID: return "FUNCTION_BLOCK"; | |
114 case bitc::IDENTIFICATION_BLOCK_ID: | |
115 return "IDENTIFICATION_BLOCK_ID"; | |
116 case bitc::VALUE_SYMTAB_BLOCK_ID: return "VALUE_SYMTAB"; | |
117 case bitc::METADATA_BLOCK_ID: return "METADATA_BLOCK"; | |
118 case bitc::METADATA_KIND_BLOCK_ID: return "METADATA_KIND_BLOCK"; | |
119 case bitc::METADATA_ATTACHMENT_ID: return "METADATA_ATTACHMENT_BLOCK"; | |
120 case bitc::USELIST_BLOCK_ID: return "USELIST_BLOCK_ID"; | |
121 case bitc::GLOBALVAL_SUMMARY_BLOCK_ID: | |
122 return "GLOBALVAL_SUMMARY_BLOCK"; | |
123 case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID: | |
124 return "FULL_LTO_GLOBALVAL_SUMMARY_BLOCK"; | |
125 case bitc::MODULE_STRTAB_BLOCK_ID: return "MODULE_STRTAB_BLOCK"; | |
126 case bitc::STRTAB_BLOCK_ID: return "STRTAB_BLOCK"; | |
127 case bitc::SYMTAB_BLOCK_ID: return "SYMTAB_BLOCK"; | |
128 } | |
129 } | 84 } |
130 | 85 |
131 /// GetCodeName - Return a symbolic code name if known, otherwise return | 86 int main(int argc, char **argv) { |
132 /// null. | 87 InitLLVM X(argc, argv); |
133 static const char *GetCodeName(unsigned CodeID, unsigned BlockID, | 88 cl::ParseCommandLineOptions(argc, argv, "llvm-bcanalyzer file analyzer\n"); |
134 const BitstreamBlockInfo &BlockInfo, | 89 ExitOnError ExitOnErr("llvm-bcanalyzer: "); |
135 CurStreamTypeType CurStreamType) { | |
136 // Standard blocks for all bitcode files. | |
137 if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) { | |
138 if (BlockID == bitc::BLOCKINFO_BLOCK_ID) { | |
139 switch (CodeID) { | |
140 default: return nullptr; | |
141 case bitc::BLOCKINFO_CODE_SETBID: return "SETBID"; | |
142 case bitc::BLOCKINFO_CODE_BLOCKNAME: return "BLOCKNAME"; | |
143 case bitc::BLOCKINFO_CODE_SETRECORDNAME: return "SETRECORDNAME"; | |
144 } | |
145 } | |
146 return nullptr; | |
147 } | |
148 | 90 |
149 // Check to see if we have a blockinfo record for this record, with a name. | 91 std::unique_ptr<MemoryBuffer> MB = ExitOnErr(openBitcodeFile(InputFilename)); |
150 if (const BitstreamBlockInfo::BlockInfo *Info = | 92 std::unique_ptr<MemoryBuffer> BlockInfoMB = nullptr; |
151 BlockInfo.getBlockInfo(BlockID)) { | 93 if (!BlockInfoFilename.empty()) |
152 for (unsigned i = 0, e = Info->RecordNames.size(); i != e; ++i) | 94 BlockInfoMB = ExitOnErr(openBitcodeFile(BlockInfoFilename)); |
153 if (Info->RecordNames[i].first == CodeID) | |
154 return Info->RecordNames[i].second.c_str(); | |
155 } | |
156 | 95 |
96 BitcodeAnalyzer BA(MB->getBuffer(), | |
97 BlockInfoMB ? Optional<StringRef>(BlockInfoMB->getBuffer()) | |
98 : None); | |
157 | 99 |
158 if (CurStreamType != LLVMIRBitstream) return nullptr; | 100 BCDumpOptions O(outs()); |
101 O.Histogram = !NoHistogram; | |
102 O.Symbolic = !NonSymbolic; | |
103 O.ShowBinaryBlobs = ShowBinaryBlobs; | |
159 | 104 |
160 #define STRINGIFY_CODE(PREFIX, CODE) \ | 105 ExitOnErr( |
161 case bitc::PREFIX##_##CODE: \ | 106 BA.analyze(O, CheckHash.empty() ? None : Optional<StringRef>(CheckHash))); |
162 return #CODE; | |
163 switch (BlockID) { | |
164 default: return nullptr; | |
165 case bitc::MODULE_BLOCK_ID: | |
166 switch (CodeID) { | |
167 default: return nullptr; | |
168 STRINGIFY_CODE(MODULE_CODE, VERSION) | |
169 STRINGIFY_CODE(MODULE_CODE, TRIPLE) | |
170 STRINGIFY_CODE(MODULE_CODE, DATALAYOUT) | |
171 STRINGIFY_CODE(MODULE_CODE, ASM) | |
172 STRINGIFY_CODE(MODULE_CODE, SECTIONNAME) | |
173 STRINGIFY_CODE(MODULE_CODE, DEPLIB) // FIXME: Remove in 4.0 | |
174 STRINGIFY_CODE(MODULE_CODE, GLOBALVAR) | |
175 STRINGIFY_CODE(MODULE_CODE, FUNCTION) | |
176 STRINGIFY_CODE(MODULE_CODE, ALIAS) | |
177 STRINGIFY_CODE(MODULE_CODE, GCNAME) | |
178 STRINGIFY_CODE(MODULE_CODE, VSTOFFSET) | |
179 STRINGIFY_CODE(MODULE_CODE, METADATA_VALUES_UNUSED) | |
180 STRINGIFY_CODE(MODULE_CODE, SOURCE_FILENAME) | |
181 STRINGIFY_CODE(MODULE_CODE, HASH) | |
182 } | |
183 case bitc::IDENTIFICATION_BLOCK_ID: | |
184 switch (CodeID) { | |
185 default: | |
186 return nullptr; | |
187 STRINGIFY_CODE(IDENTIFICATION_CODE, STRING) | |
188 STRINGIFY_CODE(IDENTIFICATION_CODE, EPOCH) | |
189 } | |
190 case bitc::PARAMATTR_BLOCK_ID: | |
191 switch (CodeID) { | |
192 default: return nullptr; | |
193 // FIXME: Should these be different? | |
194 case bitc::PARAMATTR_CODE_ENTRY_OLD: return "ENTRY"; | |
195 case bitc::PARAMATTR_CODE_ENTRY: return "ENTRY"; | |
196 } | |
197 case bitc::PARAMATTR_GROUP_BLOCK_ID: | |
198 switch (CodeID) { | |
199 default: return nullptr; | |
200 case bitc::PARAMATTR_GRP_CODE_ENTRY: return "ENTRY"; | |
201 } | |
202 case bitc::TYPE_BLOCK_ID_NEW: | |
203 switch (CodeID) { | |
204 default: return nullptr; | |
205 STRINGIFY_CODE(TYPE_CODE, NUMENTRY) | |
206 STRINGIFY_CODE(TYPE_CODE, VOID) | |
207 STRINGIFY_CODE(TYPE_CODE, FLOAT) | |
208 STRINGIFY_CODE(TYPE_CODE, DOUBLE) | |
209 STRINGIFY_CODE(TYPE_CODE, LABEL) | |
210 STRINGIFY_CODE(TYPE_CODE, OPAQUE) | |
211 STRINGIFY_CODE(TYPE_CODE, INTEGER) | |
212 STRINGIFY_CODE(TYPE_CODE, POINTER) | |
213 STRINGIFY_CODE(TYPE_CODE, ARRAY) | |
214 STRINGIFY_CODE(TYPE_CODE, VECTOR) | |
215 STRINGIFY_CODE(TYPE_CODE, X86_FP80) | |
216 STRINGIFY_CODE(TYPE_CODE, FP128) | |
217 STRINGIFY_CODE(TYPE_CODE, PPC_FP128) | |
218 STRINGIFY_CODE(TYPE_CODE, METADATA) | |
219 STRINGIFY_CODE(TYPE_CODE, STRUCT_ANON) | |
220 STRINGIFY_CODE(TYPE_CODE, STRUCT_NAME) | |
221 STRINGIFY_CODE(TYPE_CODE, STRUCT_NAMED) | |
222 STRINGIFY_CODE(TYPE_CODE, FUNCTION) | |
223 } | |
224 | 107 |
225 case bitc::CONSTANTS_BLOCK_ID: | 108 if (Dump) |
226 switch (CodeID) { | 109 outs() << "\n\n"; |
227 default: return nullptr; | |
228 STRINGIFY_CODE(CST_CODE, SETTYPE) | |
229 STRINGIFY_CODE(CST_CODE, NULL) | |
230 STRINGIFY_CODE(CST_CODE, UNDEF) | |
231 STRINGIFY_CODE(CST_CODE, INTEGER) | |
232 STRINGIFY_CODE(CST_CODE, WIDE_INTEGER) | |
233 STRINGIFY_CODE(CST_CODE, FLOAT) | |
234 STRINGIFY_CODE(CST_CODE, AGGREGATE) | |
235 STRINGIFY_CODE(CST_CODE, STRING) | |
236 STRINGIFY_CODE(CST_CODE, CSTRING) | |
237 STRINGIFY_CODE(CST_CODE, CE_BINOP) | |
238 STRINGIFY_CODE(CST_CODE, CE_CAST) | |
239 STRINGIFY_CODE(CST_CODE, CE_GEP) | |
240 STRINGIFY_CODE(CST_CODE, CE_INBOUNDS_GEP) | |
241 STRINGIFY_CODE(CST_CODE, CE_SELECT) | |
242 STRINGIFY_CODE(CST_CODE, CE_EXTRACTELT) | |
243 STRINGIFY_CODE(CST_CODE, CE_INSERTELT) | |
244 STRINGIFY_CODE(CST_CODE, CE_SHUFFLEVEC) | |
245 STRINGIFY_CODE(CST_CODE, CE_CMP) | |
246 STRINGIFY_CODE(CST_CODE, INLINEASM) | |
247 STRINGIFY_CODE(CST_CODE, CE_SHUFVEC_EX) | |
248 case bitc::CST_CODE_BLOCKADDRESS: return "CST_CODE_BLOCKADDRESS"; | |
249 STRINGIFY_CODE(CST_CODE, DATA) | |
250 } | |
251 case bitc::FUNCTION_BLOCK_ID: | |
252 switch (CodeID) { | |
253 default: return nullptr; | |
254 STRINGIFY_CODE(FUNC_CODE, DECLAREBLOCKS) | |
255 STRINGIFY_CODE(FUNC_CODE, INST_BINOP) | |
256 STRINGIFY_CODE(FUNC_CODE, INST_CAST) | |
257 STRINGIFY_CODE(FUNC_CODE, INST_GEP_OLD) | |
258 STRINGIFY_CODE(FUNC_CODE, INST_INBOUNDS_GEP_OLD) | |
259 STRINGIFY_CODE(FUNC_CODE, INST_SELECT) | |
260 STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTELT) | |
261 STRINGIFY_CODE(FUNC_CODE, INST_INSERTELT) | |
262 STRINGIFY_CODE(FUNC_CODE, INST_SHUFFLEVEC) | |
263 STRINGIFY_CODE(FUNC_CODE, INST_CMP) | |
264 STRINGIFY_CODE(FUNC_CODE, INST_RET) | |
265 STRINGIFY_CODE(FUNC_CODE, INST_BR) | |
266 STRINGIFY_CODE(FUNC_CODE, INST_SWITCH) | |
267 STRINGIFY_CODE(FUNC_CODE, INST_INVOKE) | |
268 STRINGIFY_CODE(FUNC_CODE, INST_UNREACHABLE) | |
269 STRINGIFY_CODE(FUNC_CODE, INST_CLEANUPRET) | |
270 STRINGIFY_CODE(FUNC_CODE, INST_CATCHRET) | |
271 STRINGIFY_CODE(FUNC_CODE, INST_CATCHPAD) | |
272 STRINGIFY_CODE(FUNC_CODE, INST_PHI) | |
273 STRINGIFY_CODE(FUNC_CODE, INST_ALLOCA) | |
274 STRINGIFY_CODE(FUNC_CODE, INST_LOAD) | |
275 STRINGIFY_CODE(FUNC_CODE, INST_VAARG) | |
276 STRINGIFY_CODE(FUNC_CODE, INST_STORE) | |
277 STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTVAL) | |
278 STRINGIFY_CODE(FUNC_CODE, INST_INSERTVAL) | |
279 STRINGIFY_CODE(FUNC_CODE, INST_CMP2) | |
280 STRINGIFY_CODE(FUNC_CODE, INST_VSELECT) | |
281 STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC_AGAIN) | |
282 STRINGIFY_CODE(FUNC_CODE, INST_CALL) | |
283 STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC) | |
284 STRINGIFY_CODE(FUNC_CODE, INST_GEP) | |
285 STRINGIFY_CODE(FUNC_CODE, OPERAND_BUNDLE) | |
286 } | |
287 case bitc::VALUE_SYMTAB_BLOCK_ID: | |
288 switch (CodeID) { | |
289 default: return nullptr; | |
290 STRINGIFY_CODE(VST_CODE, ENTRY) | |
291 STRINGIFY_CODE(VST_CODE, BBENTRY) | |
292 STRINGIFY_CODE(VST_CODE, FNENTRY) | |
293 STRINGIFY_CODE(VST_CODE, COMBINED_ENTRY) | |
294 } | |
295 case bitc::MODULE_STRTAB_BLOCK_ID: | |
296 switch (CodeID) { | |
297 default: | |
298 return nullptr; | |
299 STRINGIFY_CODE(MST_CODE, ENTRY) | |
300 STRINGIFY_CODE(MST_CODE, HASH) | |
301 } | |
302 case bitc::GLOBALVAL_SUMMARY_BLOCK_ID: | |
303 case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID: | |
304 switch (CodeID) { | |
305 default: | |
306 return nullptr; | |
307 STRINGIFY_CODE(FS, PERMODULE) | |
308 STRINGIFY_CODE(FS, PERMODULE_PROFILE) | |
309 STRINGIFY_CODE(FS, PERMODULE_RELBF) | |
310 STRINGIFY_CODE(FS, PERMODULE_GLOBALVAR_INIT_REFS) | |
311 STRINGIFY_CODE(FS, COMBINED) | |
312 STRINGIFY_CODE(FS, COMBINED_PROFILE) | |
313 STRINGIFY_CODE(FS, COMBINED_GLOBALVAR_INIT_REFS) | |
314 STRINGIFY_CODE(FS, ALIAS) | |
315 STRINGIFY_CODE(FS, COMBINED_ALIAS) | |
316 STRINGIFY_CODE(FS, COMBINED_ORIGINAL_NAME) | |
317 STRINGIFY_CODE(FS, VERSION) | |
318 STRINGIFY_CODE(FS, FLAGS) | |
319 STRINGIFY_CODE(FS, TYPE_TESTS) | |
320 STRINGIFY_CODE(FS, TYPE_TEST_ASSUME_VCALLS) | |
321 STRINGIFY_CODE(FS, TYPE_CHECKED_LOAD_VCALLS) | |
322 STRINGIFY_CODE(FS, TYPE_TEST_ASSUME_CONST_VCALL) | |
323 STRINGIFY_CODE(FS, TYPE_CHECKED_LOAD_CONST_VCALL) | |
324 STRINGIFY_CODE(FS, VALUE_GUID) | |
325 STRINGIFY_CODE(FS, CFI_FUNCTION_DEFS) | |
326 STRINGIFY_CODE(FS, CFI_FUNCTION_DECLS) | |
327 STRINGIFY_CODE(FS, TYPE_ID) | |
328 } | |
329 case bitc::METADATA_ATTACHMENT_ID: | |
330 switch(CodeID) { | |
331 default:return nullptr; | |
332 STRINGIFY_CODE(METADATA, ATTACHMENT) | |
333 } | |
334 case bitc::METADATA_BLOCK_ID: | |
335 switch(CodeID) { | |
336 default:return nullptr; | |
337 STRINGIFY_CODE(METADATA, STRING_OLD) | |
338 STRINGIFY_CODE(METADATA, VALUE) | |
339 STRINGIFY_CODE(METADATA, NODE) | |
340 STRINGIFY_CODE(METADATA, NAME) | |
341 STRINGIFY_CODE(METADATA, DISTINCT_NODE) | |
342 STRINGIFY_CODE(METADATA, KIND) // Older bitcode has it in a MODULE_BLOCK | |
343 STRINGIFY_CODE(METADATA, LOCATION) | |
344 STRINGIFY_CODE(METADATA, OLD_NODE) | |
345 STRINGIFY_CODE(METADATA, OLD_FN_NODE) | |
346 STRINGIFY_CODE(METADATA, NAMED_NODE) | |
347 STRINGIFY_CODE(METADATA, GENERIC_DEBUG) | |
348 STRINGIFY_CODE(METADATA, SUBRANGE) | |
349 STRINGIFY_CODE(METADATA, ENUMERATOR) | |
350 STRINGIFY_CODE(METADATA, BASIC_TYPE) | |
351 STRINGIFY_CODE(METADATA, FILE) | |
352 STRINGIFY_CODE(METADATA, DERIVED_TYPE) | |
353 STRINGIFY_CODE(METADATA, COMPOSITE_TYPE) | |
354 STRINGIFY_CODE(METADATA, SUBROUTINE_TYPE) | |
355 STRINGIFY_CODE(METADATA, COMPILE_UNIT) | |
356 STRINGIFY_CODE(METADATA, SUBPROGRAM) | |
357 STRINGIFY_CODE(METADATA, LEXICAL_BLOCK) | |
358 STRINGIFY_CODE(METADATA, LEXICAL_BLOCK_FILE) | |
359 STRINGIFY_CODE(METADATA, NAMESPACE) | |
360 STRINGIFY_CODE(METADATA, TEMPLATE_TYPE) | |
361 STRINGIFY_CODE(METADATA, TEMPLATE_VALUE) | |
362 STRINGIFY_CODE(METADATA, GLOBAL_VAR) | |
363 STRINGIFY_CODE(METADATA, LOCAL_VAR) | |
364 STRINGIFY_CODE(METADATA, EXPRESSION) | |
365 STRINGIFY_CODE(METADATA, OBJC_PROPERTY) | |
366 STRINGIFY_CODE(METADATA, IMPORTED_ENTITY) | |
367 STRINGIFY_CODE(METADATA, MODULE) | |
368 STRINGIFY_CODE(METADATA, MACRO) | |
369 STRINGIFY_CODE(METADATA, MACRO_FILE) | |
370 STRINGIFY_CODE(METADATA, STRINGS) | |
371 STRINGIFY_CODE(METADATA, GLOBAL_DECL_ATTACHMENT) | |
372 STRINGIFY_CODE(METADATA, GLOBAL_VAR_EXPR) | |
373 STRINGIFY_CODE(METADATA, INDEX_OFFSET) | |
374 STRINGIFY_CODE(METADATA, INDEX) | |
375 } | |
376 case bitc::METADATA_KIND_BLOCK_ID: | |
377 switch (CodeID) { | |
378 default: | |
379 return nullptr; | |
380 STRINGIFY_CODE(METADATA, KIND) | |
381 } | |
382 case bitc::USELIST_BLOCK_ID: | |
383 switch(CodeID) { | |
384 default:return nullptr; | |
385 case bitc::USELIST_CODE_DEFAULT: return "USELIST_CODE_DEFAULT"; | |
386 case bitc::USELIST_CODE_BB: return "USELIST_CODE_BB"; | |
387 } | |
388 | 110 |
389 case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID: | 111 BA.printStats(O, StringRef(InputFilename.getValue())); |
390 switch(CodeID) { | |
391 default: return nullptr; | |
392 case bitc::OPERAND_BUNDLE_TAG: return "OPERAND_BUNDLE_TAG"; | |
393 } | |
394 case bitc::STRTAB_BLOCK_ID: | |
395 switch(CodeID) { | |
396 default: return nullptr; | |
397 case bitc::STRTAB_BLOB: return "BLOB"; | |
398 } | |
399 case bitc::SYMTAB_BLOCK_ID: | |
400 switch(CodeID) { | |
401 default: return nullptr; | |
402 case bitc::SYMTAB_BLOB: return "BLOB"; | |
403 } | |
404 } | |
405 #undef STRINGIFY_CODE | |
406 } | |
407 | |
408 struct PerRecordStats { | |
409 unsigned NumInstances; | |
410 unsigned NumAbbrev; | |
411 uint64_t TotalBits; | |
412 | |
413 PerRecordStats() : NumInstances(0), NumAbbrev(0), TotalBits(0) {} | |
414 }; | |
415 | |
416 struct PerBlockIDStats { | |
417 /// NumInstances - This the number of times this block ID has been seen. | |
418 unsigned NumInstances; | |
419 | |
420 /// NumBits - The total size in bits of all of these blocks. | |
421 uint64_t NumBits; | |
422 | |
423 /// NumSubBlocks - The total number of blocks these blocks contain. | |
424 unsigned NumSubBlocks; | |
425 | |
426 /// NumAbbrevs - The total number of abbreviations. | |
427 unsigned NumAbbrevs; | |
428 | |
429 /// NumRecords - The total number of records these blocks contain, and the | |
430 /// number that are abbreviated. | |
431 unsigned NumRecords, NumAbbreviatedRecords; | |
432 | |
433 /// CodeFreq - Keep track of the number of times we see each code. | |
434 std::vector<PerRecordStats> CodeFreq; | |
435 | |
436 PerBlockIDStats() | |
437 : NumInstances(0), NumBits(0), | |
438 NumSubBlocks(0), NumAbbrevs(0), NumRecords(0), NumAbbreviatedRecords(0) {} | |
439 }; | |
440 | |
441 static std::map<unsigned, PerBlockIDStats> BlockIDStats; | |
442 | |
443 | |
444 | |
445 /// ReportError - All bitcode analysis errors go through this function, making this a | |
446 /// good place to breakpoint if debugging. | |
447 static bool ReportError(const Twine &Err) { | |
448 errs() << Err << "\n"; | |
449 return true; | |
450 } | |
451 | |
452 static bool decodeMetadataStringsBlob(StringRef Indent, | |
453 ArrayRef<uint64_t> Record, | |
454 StringRef Blob) { | |
455 if (Blob.empty()) | |
456 return true; | |
457 | |
458 if (Record.size() != 2) | |
459 return true; | |
460 | |
461 unsigned NumStrings = Record[0]; | |
462 unsigned StringsOffset = Record[1]; | |
463 outs() << " num-strings = " << NumStrings << " {\n"; | |
464 | |
465 StringRef Lengths = Blob.slice(0, StringsOffset); | |
466 SimpleBitstreamCursor R(Lengths); | |
467 StringRef Strings = Blob.drop_front(StringsOffset); | |
468 do { | |
469 if (R.AtEndOfStream()) | |
470 return ReportError("bad length"); | |
471 | |
472 unsigned Size = R.ReadVBR(6); | |
473 if (Strings.size() < Size) | |
474 return ReportError("truncated chars"); | |
475 | |
476 outs() << Indent << " '"; | |
477 outs().write_escaped(Strings.slice(0, Size), /*hex=*/true); | |
478 outs() << "'\n"; | |
479 Strings = Strings.drop_front(Size); | |
480 } while (--NumStrings); | |
481 | |
482 outs() << Indent << " }"; | |
483 return false; | |
484 } | |
485 | |
486 static bool decodeBlob(unsigned Code, unsigned BlockID, StringRef Indent, | |
487 ArrayRef<uint64_t> Record, StringRef Blob) { | |
488 if (BlockID != bitc::METADATA_BLOCK_ID) | |
489 return true; | |
490 if (Code != bitc::METADATA_STRINGS) | |
491 return true; | |
492 | |
493 return decodeMetadataStringsBlob(Indent, Record, Blob); | |
494 } | |
495 | |
496 /// ParseBlock - Read a block, updating statistics, etc. | |
497 static bool ParseBlock(BitstreamCursor &Stream, BitstreamBlockInfo &BlockInfo, | |
498 unsigned BlockID, unsigned IndentLevel, | |
499 CurStreamTypeType CurStreamType) { | |
500 std::string Indent(IndentLevel*2, ' '); | |
501 uint64_t BlockBitStart = Stream.GetCurrentBitNo(); | |
502 | |
503 // Get the statistics for this BlockID. | |
504 PerBlockIDStats &BlockStats = BlockIDStats[BlockID]; | |
505 | |
506 BlockStats.NumInstances++; | |
507 | |
508 // BLOCKINFO is a special part of the stream. | |
509 bool DumpRecords = Dump; | |
510 if (BlockID == bitc::BLOCKINFO_BLOCK_ID) { | |
511 if (Dump) outs() << Indent << "<BLOCKINFO_BLOCK/>\n"; | |
512 Optional<BitstreamBlockInfo> NewBlockInfo = | |
513 Stream.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true); | |
514 if (!NewBlockInfo) | |
515 return ReportError("Malformed BlockInfoBlock"); | |
516 BlockInfo = std::move(*NewBlockInfo); | |
517 Stream.JumpToBit(BlockBitStart); | |
518 // It's not really interesting to dump the contents of the blockinfo block. | |
519 DumpRecords = false; | |
520 } | |
521 | |
522 unsigned NumWords = 0; | |
523 if (Stream.EnterSubBlock(BlockID, &NumWords)) | |
524 return ReportError("Malformed block record"); | |
525 | |
526 // Keep it for later, when we see a MODULE_HASH record | |
527 uint64_t BlockEntryPos = Stream.getCurrentByteNo(); | |
528 | |
529 const char *BlockName = nullptr; | |
530 if (DumpRecords) { | |
531 outs() << Indent << "<"; | |
532 if ((BlockName = GetBlockName(BlockID, BlockInfo, CurStreamType))) | |
533 outs() << BlockName; | |
534 else | |
535 outs() << "UnknownBlock" << BlockID; | |
536 | |
537 if (NonSymbolic && BlockName) | |
538 outs() << " BlockID=" << BlockID; | |
539 | |
540 outs() << " NumWords=" << NumWords | |
541 << " BlockCodeSize=" << Stream.getAbbrevIDWidth() << ">\n"; | |
542 } | |
543 | |
544 SmallVector<uint64_t, 64> Record; | |
545 | |
546 // Keep the offset to the metadata index if seen. | |
547 uint64_t MetadataIndexOffset = 0; | |
548 | |
549 // Read all the records for this block. | |
550 while (1) { | |
551 if (Stream.AtEndOfStream()) | |
552 return ReportError("Premature end of bitstream"); | |
553 | |
554 uint64_t RecordStartBit = Stream.GetCurrentBitNo(); | |
555 | |
556 BitstreamEntry Entry = | |
557 Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs); | |
558 | |
559 switch (Entry.Kind) { | |
560 case BitstreamEntry::Error: | |
561 return ReportError("malformed bitcode file"); | |
562 case BitstreamEntry::EndBlock: { | |
563 uint64_t BlockBitEnd = Stream.GetCurrentBitNo(); | |
564 BlockStats.NumBits += BlockBitEnd-BlockBitStart; | |
565 if (DumpRecords) { | |
566 outs() << Indent << "</"; | |
567 if (BlockName) | |
568 outs() << BlockName << ">\n"; | |
569 else | |
570 outs() << "UnknownBlock" << BlockID << ">\n"; | |
571 } | |
572 return false; | |
573 } | |
574 | |
575 case BitstreamEntry::SubBlock: { | |
576 uint64_t SubBlockBitStart = Stream.GetCurrentBitNo(); | |
577 if (ParseBlock(Stream, BlockInfo, Entry.ID, IndentLevel + 1, | |
578 CurStreamType)) | |
579 return true; | |
580 ++BlockStats.NumSubBlocks; | |
581 uint64_t SubBlockBitEnd = Stream.GetCurrentBitNo(); | |
582 | |
583 // Don't include subblock sizes in the size of this block. | |
584 BlockBitStart += SubBlockBitEnd-SubBlockBitStart; | |
585 continue; | |
586 } | |
587 case BitstreamEntry::Record: | |
588 // The interesting case. | |
589 break; | |
590 } | |
591 | |
592 if (Entry.ID == bitc::DEFINE_ABBREV) { | |
593 Stream.ReadAbbrevRecord(); | |
594 ++BlockStats.NumAbbrevs; | |
595 continue; | |
596 } | |
597 | |
598 Record.clear(); | |
599 | |
600 ++BlockStats.NumRecords; | |
601 | |
602 StringRef Blob; | |
603 unsigned CurrentRecordPos = Stream.GetCurrentBitNo(); | |
604 unsigned Code = Stream.readRecord(Entry.ID, Record, &Blob); | |
605 | |
606 // Increment the # occurrences of this code. | |
607 if (BlockStats.CodeFreq.size() <= Code) | |
608 BlockStats.CodeFreq.resize(Code+1); | |
609 BlockStats.CodeFreq[Code].NumInstances++; | |
610 BlockStats.CodeFreq[Code].TotalBits += | |
611 Stream.GetCurrentBitNo()-RecordStartBit; | |
612 if (Entry.ID != bitc::UNABBREV_RECORD) { | |
613 BlockStats.CodeFreq[Code].NumAbbrev++; | |
614 ++BlockStats.NumAbbreviatedRecords; | |
615 } | |
616 | |
617 if (DumpRecords) { | |
618 outs() << Indent << " <"; | |
619 if (const char *CodeName = | |
620 GetCodeName(Code, BlockID, BlockInfo, CurStreamType)) | |
621 outs() << CodeName; | |
622 else | |
623 outs() << "UnknownCode" << Code; | |
624 if (NonSymbolic && GetCodeName(Code, BlockID, BlockInfo, CurStreamType)) | |
625 outs() << " codeid=" << Code; | |
626 const BitCodeAbbrev *Abbv = nullptr; | |
627 if (Entry.ID != bitc::UNABBREV_RECORD) { | |
628 Abbv = Stream.getAbbrev(Entry.ID); | |
629 outs() << " abbrevid=" << Entry.ID; | |
630 } | |
631 | |
632 for (unsigned i = 0, e = Record.size(); i != e; ++i) | |
633 outs() << " op" << i << "=" << (int64_t)Record[i]; | |
634 | |
635 // If we found a metadata index, let's verify that we had an offset before | |
636 // and validate its forward reference offset was correct! | |
637 if (BlockID == bitc::METADATA_BLOCK_ID) { | |
638 if (Code == bitc::METADATA_INDEX_OFFSET) { | |
639 if (Record.size() != 2) | |
640 outs() << "(Invalid record)"; | |
641 else { | |
642 auto Offset = Record[0] + (Record[1] << 32); | |
643 MetadataIndexOffset = Stream.GetCurrentBitNo() + Offset; | |
644 } | |
645 } | |
646 if (Code == bitc::METADATA_INDEX) { | |
647 outs() << " (offset "; | |
648 if (MetadataIndexOffset == RecordStartBit) | |
649 outs() << "match)"; | |
650 else | |
651 outs() << "mismatch: " << MetadataIndexOffset << " vs " | |
652 << RecordStartBit << ")"; | |
653 } | |
654 } | |
655 | |
656 // If we found a module hash, let's verify that it matches! | |
657 if (BlockID == bitc::MODULE_BLOCK_ID && Code == bitc::MODULE_CODE_HASH && | |
658 !CheckHash.empty()) { | |
659 if (Record.size() != 5) | |
660 outs() << " (invalid)"; | |
661 else { | |
662 // Recompute the hash and compare it to the one in the bitcode | |
663 SHA1 Hasher; | |
664 StringRef Hash; | |
665 Hasher.update(CheckHash); | |
666 { | |
667 int BlockSize = (CurrentRecordPos / 8) - BlockEntryPos; | |
668 auto Ptr = Stream.getPointerToByte(BlockEntryPos, BlockSize); | |
669 Hasher.update(ArrayRef<uint8_t>(Ptr, BlockSize)); | |
670 Hash = Hasher.result(); | |
671 } | |
672 SmallString<20> RecordedHash; | |
673 RecordedHash.resize(20); | |
674 int Pos = 0; | |
675 for (auto &Val : Record) { | |
676 assert(!(Val >> 32) && "Unexpected high bits set"); | |
677 RecordedHash[Pos++] = (Val >> 24) & 0xFF; | |
678 RecordedHash[Pos++] = (Val >> 16) & 0xFF; | |
679 RecordedHash[Pos++] = (Val >> 8) & 0xFF; | |
680 RecordedHash[Pos++] = (Val >> 0) & 0xFF; | |
681 } | |
682 if (Hash == RecordedHash) | |
683 outs() << " (match)"; | |
684 else | |
685 outs() << " (!mismatch!)"; | |
686 } | |
687 } | |
688 | |
689 outs() << "/>"; | |
690 | |
691 if (Abbv) { | |
692 for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) { | |
693 const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); | |
694 if (!Op.isEncoding() || Op.getEncoding() != BitCodeAbbrevOp::Array) | |
695 continue; | |
696 assert(i + 2 == e && "Array op not second to last"); | |
697 std::string Str; | |
698 bool ArrayIsPrintable = true; | |
699 for (unsigned j = i - 1, je = Record.size(); j != je; ++j) { | |
700 if (!isprint(static_cast<unsigned char>(Record[j]))) { | |
701 ArrayIsPrintable = false; | |
702 break; | |
703 } | |
704 Str += (char)Record[j]; | |
705 } | |
706 if (ArrayIsPrintable) | |
707 outs() << " record string = '" << Str << "'"; | |
708 break; | |
709 } | |
710 } | |
711 | |
712 if (Blob.data() && decodeBlob(Code, BlockID, Indent, Record, Blob)) { | |
713 outs() << " blob data = "; | |
714 if (ShowBinaryBlobs) { | |
715 outs() << "'"; | |
716 outs().write_escaped(Blob, /*hex=*/true) << "'"; | |
717 } else { | |
718 bool BlobIsPrintable = true; | |
719 for (unsigned i = 0, e = Blob.size(); i != e; ++i) | |
720 if (!isprint(static_cast<unsigned char>(Blob[i]))) { | |
721 BlobIsPrintable = false; | |
722 break; | |
723 } | |
724 | |
725 if (BlobIsPrintable) | |
726 outs() << "'" << Blob << "'"; | |
727 else | |
728 outs() << "unprintable, " << Blob.size() << " bytes."; | |
729 } | |
730 } | |
731 | |
732 outs() << "\n"; | |
733 } | |
734 | |
735 // Make sure that we can skip the current record. | |
736 Stream.JumpToBit(CurrentRecordPos); | |
737 Stream.skipRecord(Entry.ID); | |
738 } | |
739 } | |
740 | |
741 static void PrintSize(double Bits) { | |
742 outs() << format("%.2f/%.2fB/%luW", Bits, Bits/8,(unsigned long)(Bits/32)); | |
743 } | |
744 static void PrintSize(uint64_t Bits) { | |
745 outs() << format("%lub/%.2fB/%luW", (unsigned long)Bits, | |
746 (double)Bits/8, (unsigned long)(Bits/32)); | |
747 } | |
748 | |
749 static bool openBitcodeFile(StringRef Path, | |
750 std::unique_ptr<MemoryBuffer> &MemBuf, | |
751 BitstreamCursor &Stream, | |
752 CurStreamTypeType &CurStreamType) { | |
753 // Read the input file. | |
754 ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr = | |
755 MemoryBuffer::getFileOrSTDIN(Path); | |
756 if (std::error_code EC = MemBufOrErr.getError()) | |
757 return ReportError(Twine("ReportError reading '") + Path + "': " + EC.message()); | |
758 MemBuf = std::move(MemBufOrErr.get()); | |
759 | |
760 if (MemBuf->getBufferSize() & 3) | |
761 return ReportError("Bitcode stream should be a multiple of 4 bytes in length"); | |
762 | |
763 const unsigned char *BufPtr = (const unsigned char *)MemBuf->getBufferStart(); | |
764 const unsigned char *EndBufPtr = BufPtr + MemBuf->getBufferSize(); | |
765 | |
766 // If we have a wrapper header, parse it and ignore the non-bc file contents. | |
767 // The magic number is 0x0B17C0DE stored in little endian. | |
768 if (isBitcodeWrapper(BufPtr, EndBufPtr)) { | |
769 if (MemBuf->getBufferSize() < BWH_HeaderSize) | |
770 return ReportError("Invalid bitcode wrapper header"); | |
771 | |
772 if (Dump) { | |
773 unsigned Magic = support::endian::read32le(&BufPtr[BWH_MagicField]); | |
774 unsigned Version = support::endian::read32le(&BufPtr[BWH_VersionField]); | |
775 unsigned Offset = support::endian::read32le(&BufPtr[BWH_OffsetField]); | |
776 unsigned Size = support::endian::read32le(&BufPtr[BWH_SizeField]); | |
777 unsigned CPUType = support::endian::read32le(&BufPtr[BWH_CPUTypeField]); | |
778 | |
779 outs() << "<BITCODE_WRAPPER_HEADER" | |
780 << " Magic=" << format_hex(Magic, 10) | |
781 << " Version=" << format_hex(Version, 10) | |
782 << " Offset=" << format_hex(Offset, 10) | |
783 << " Size=" << format_hex(Size, 10) | |
784 << " CPUType=" << format_hex(CPUType, 10) << "/>\n"; | |
785 } | |
786 | |
787 if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true)) | |
788 return ReportError("Invalid bitcode wrapper header"); | |
789 } | |
790 | |
791 Stream = BitstreamCursor(ArrayRef<uint8_t>(BufPtr, EndBufPtr)); | |
792 | |
793 // Read the stream signature. | |
794 char Signature[6]; | |
795 Signature[0] = Stream.Read(8); | |
796 Signature[1] = Stream.Read(8); | |
797 Signature[2] = Stream.Read(4); | |
798 Signature[3] = Stream.Read(4); | |
799 Signature[4] = Stream.Read(4); | |
800 Signature[5] = Stream.Read(4); | |
801 | |
802 // Autodetect the file contents, if it is one we know. | |
803 CurStreamType = UnknownBitstream; | |
804 if (Signature[0] == 'B' && Signature[1] == 'C' && | |
805 Signature[2] == 0x0 && Signature[3] == 0xC && | |
806 Signature[4] == 0xE && Signature[5] == 0xD) | |
807 CurStreamType = LLVMIRBitstream; | |
808 | |
809 return false; | |
810 } | |
811 | |
812 /// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename. | |
813 static int AnalyzeBitcode() { | |
814 std::unique_ptr<MemoryBuffer> StreamBuffer; | |
815 BitstreamCursor Stream; | |
816 BitstreamBlockInfo BlockInfo; | |
817 CurStreamTypeType CurStreamType; | |
818 if (openBitcodeFile(InputFilename, StreamBuffer, Stream, CurStreamType)) | |
819 return true; | |
820 Stream.setBlockInfo(&BlockInfo); | |
821 | |
822 // Read block info from BlockInfoFilename, if specified. | |
823 // The block info must be a top-level block. | |
824 if (!BlockInfoFilename.empty()) { | |
825 std::unique_ptr<MemoryBuffer> BlockInfoBuffer; | |
826 BitstreamCursor BlockInfoCursor; | |
827 CurStreamTypeType BlockInfoStreamType; | |
828 if (openBitcodeFile(BlockInfoFilename, BlockInfoBuffer, BlockInfoCursor, | |
829 BlockInfoStreamType)) | |
830 return true; | |
831 | |
832 while (!BlockInfoCursor.AtEndOfStream()) { | |
833 unsigned Code = BlockInfoCursor.ReadCode(); | |
834 if (Code != bitc::ENTER_SUBBLOCK) | |
835 return ReportError("Invalid record at top-level in block info file"); | |
836 | |
837 unsigned BlockID = BlockInfoCursor.ReadSubBlockID(); | |
838 if (BlockID == bitc::BLOCKINFO_BLOCK_ID) { | |
839 Optional<BitstreamBlockInfo> NewBlockInfo = | |
840 BlockInfoCursor.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true); | |
841 if (!NewBlockInfo) | |
842 return ReportError("Malformed BlockInfoBlock in block info file"); | |
843 BlockInfo = std::move(*NewBlockInfo); | |
844 break; | |
845 } | |
846 | |
847 BlockInfoCursor.SkipBlock(); | |
848 } | |
849 } | |
850 | |
851 unsigned NumTopBlocks = 0; | |
852 | |
853 // Parse the top-level structure. We only allow blocks at the top-level. | |
854 while (!Stream.AtEndOfStream()) { | |
855 unsigned Code = Stream.ReadCode(); | |
856 if (Code != bitc::ENTER_SUBBLOCK) | |
857 return ReportError("Invalid record at top-level"); | |
858 | |
859 unsigned BlockID = Stream.ReadSubBlockID(); | |
860 | |
861 if (ParseBlock(Stream, BlockInfo, BlockID, 0, CurStreamType)) | |
862 return true; | |
863 ++NumTopBlocks; | |
864 } | |
865 | |
866 if (Dump) outs() << "\n\n"; | |
867 | |
868 uint64_t BufferSizeBits = Stream.getBitcodeBytes().size() * CHAR_BIT; | |
869 // Print a summary of the read file. | |
870 outs() << "Summary of " << InputFilename << ":\n"; | |
871 outs() << " Total size: "; | |
872 PrintSize(BufferSizeBits); | |
873 outs() << "\n"; | |
874 outs() << " Stream type: "; | |
875 switch (CurStreamType) { | |
876 case UnknownBitstream: outs() << "unknown\n"; break; | |
877 case LLVMIRBitstream: outs() << "LLVM IR\n"; break; | |
878 } | |
879 outs() << " # Toplevel Blocks: " << NumTopBlocks << "\n"; | |
880 outs() << "\n"; | |
881 | |
882 // Emit per-block stats. | |
883 outs() << "Per-block Summary:\n"; | |
884 for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(), | |
885 E = BlockIDStats.end(); I != E; ++I) { | |
886 outs() << " Block ID #" << I->first; | |
887 if (const char *BlockName = | |
888 GetBlockName(I->first, BlockInfo, CurStreamType)) | |
889 outs() << " (" << BlockName << ")"; | |
890 outs() << ":\n"; | |
891 | |
892 const PerBlockIDStats &Stats = I->second; | |
893 outs() << " Num Instances: " << Stats.NumInstances << "\n"; | |
894 outs() << " Total Size: "; | |
895 PrintSize(Stats.NumBits); | |
896 outs() << "\n"; | |
897 double pct = (Stats.NumBits * 100.0) / BufferSizeBits; | |
898 outs() << " Percent of file: " << format("%2.4f%%", pct) << "\n"; | |
899 if (Stats.NumInstances > 1) { | |
900 outs() << " Average Size: "; | |
901 PrintSize(Stats.NumBits/(double)Stats.NumInstances); | |
902 outs() << "\n"; | |
903 outs() << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/" | |
904 << Stats.NumSubBlocks/(double)Stats.NumInstances << "\n"; | |
905 outs() << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/" | |
906 << Stats.NumAbbrevs/(double)Stats.NumInstances << "\n"; | |
907 outs() << " Tot/Avg Records: " << Stats.NumRecords << "/" | |
908 << Stats.NumRecords/(double)Stats.NumInstances << "\n"; | |
909 } else { | |
910 outs() << " Num SubBlocks: " << Stats.NumSubBlocks << "\n"; | |
911 outs() << " Num Abbrevs: " << Stats.NumAbbrevs << "\n"; | |
912 outs() << " Num Records: " << Stats.NumRecords << "\n"; | |
913 } | |
914 if (Stats.NumRecords) { | |
915 double pct = (Stats.NumAbbreviatedRecords * 100.0) / Stats.NumRecords; | |
916 outs() << " Percent Abbrevs: " << format("%2.4f%%", pct) << "\n"; | |
917 } | |
918 outs() << "\n"; | |
919 | |
920 // Print a histogram of the codes we see. | |
921 if (!NoHistogram && !Stats.CodeFreq.empty()) { | |
922 std::vector<std::pair<unsigned, unsigned> > FreqPairs; // <freq,code> | |
923 for (unsigned i = 0, e = Stats.CodeFreq.size(); i != e; ++i) | |
924 if (unsigned Freq = Stats.CodeFreq[i].NumInstances) | |
925 FreqPairs.push_back(std::make_pair(Freq, i)); | |
926 std::stable_sort(FreqPairs.begin(), FreqPairs.end()); | |
927 std::reverse(FreqPairs.begin(), FreqPairs.end()); | |
928 | |
929 outs() << "\tRecord Histogram:\n"; | |
930 outs() << "\t\t Count # Bits b/Rec % Abv Record Kind\n"; | |
931 for (unsigned i = 0, e = FreqPairs.size(); i != e; ++i) { | |
932 const PerRecordStats &RecStats = Stats.CodeFreq[FreqPairs[i].second]; | |
933 | |
934 outs() << format("\t\t%7d %9lu", | |
935 RecStats.NumInstances, | |
936 (unsigned long)RecStats.TotalBits); | |
937 | |
938 if (RecStats.NumInstances > 1) | |
939 outs() << format(" %9.1f", | |
940 (double)RecStats.TotalBits/RecStats.NumInstances); | |
941 else | |
942 outs() << " "; | |
943 | |
944 if (RecStats.NumAbbrev) | |
945 outs() << | |
946 format(" %7.2f", | |
947 (double)RecStats.NumAbbrev/RecStats.NumInstances*100); | |
948 else | |
949 outs() << " "; | |
950 | |
951 outs() << " "; | |
952 if (const char *CodeName = GetCodeName(FreqPairs[i].second, I->first, | |
953 BlockInfo, CurStreamType)) | |
954 outs() << CodeName << "\n"; | |
955 else | |
956 outs() << "UnknownCode" << FreqPairs[i].second << "\n"; | |
957 } | |
958 outs() << "\n"; | |
959 | |
960 } | |
961 } | |
962 return 0; | 112 return 0; |
963 } | 113 } |
964 | |
965 | |
966 int main(int argc, char **argv) { | |
967 // Print a stack trace if we signal out. | |
968 sys::PrintStackTraceOnErrorSignal(argv[0]); | |
969 PrettyStackTraceProgram X(argc, argv); | |
970 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. | |
971 cl::ParseCommandLineOptions(argc, argv, "llvm-bcanalyzer file analyzer\n"); | |
972 | |
973 return AnalyzeBitcode(); | |
974 } |