[spirv-dis] Add some context comments to disassembly. (#3847)

This CL adds some extra new lines and context comments into the
spirv-dis output format. This CL adds:

 - Blank line and '; Annotations' before decorations
 - Blank line and '; Debug Information' before debug instructions
 - Blank line and '; Types, variables and constants' before type section
 - Blank line and '; Function <name>' before each function.

Issue #788
This commit is contained in:
dan sinclair 2020-09-28 10:59:50 -04:00 коммит произвёл GitHub
Родитель 446adb05ff
Коммит c6ca885c0b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 47 добавлений и 3 удалений

Просмотреть файл

@ -325,6 +325,8 @@ typedef enum spv_binary_to_text_options_t {
// time, but will use common names for scalar types, and debug names from
// OpName instructions.
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES = SPV_BIT(6),
// Add some comments to the generated assembly
SPV_BINARY_TO_TEXT_OPTION_COMMENT = SPV_BIT(7),
SPV_FORCE_32_BIT_ENUM(spv_binary_to_text_options_t)
} spv_binary_to_text_options_t;

Просмотреть файл

@ -54,6 +54,7 @@ class Disassembler {
indent_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_INDENT, options)
? kStandardIndent
: 0),
comment_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_COMMENT, options)),
text_(),
out_(print_ ? out_stream() : out_stream(text_)),
stream_(out_.get()),
@ -118,6 +119,7 @@ class Disassembler {
const bool print_; // Should we also print to the standard output stream?
const bool color_; // Should we print in colour?
const int indent_; // How much to indent. 0 means don't indent
const int comment_; // Should we comment the source
spv_endianness_t endian_; // The detected endianness of the binary.
std::stringstream text_; // Captures the text, if not printing.
out_stream out_; // The Output stream. Either to text_ or standard output.
@ -126,6 +128,9 @@ class Disassembler {
const bool show_byte_offset_; // Should we print byte offset, in hex?
size_t byte_offset_; // The number of bytes processed so far.
spvtools::NameMapper name_mapper_;
bool inserted_decoration_space_ = false;
bool inserted_debug_space_ = false;
bool inserted_type_space_ = false;
};
spv_result_t Disassembler::HandleHeader(spv_endianness_t endian,
@ -134,7 +139,6 @@ spv_result_t Disassembler::HandleHeader(spv_endianness_t endian,
endian_ = endian;
if (header_) {
SetGrey();
const char* generator_tool =
spvGeneratorStr(SPV_GENERATOR_TOOL_PART(generator));
stream_ << "; SPIR-V\n"
@ -150,7 +154,6 @@ spv_result_t Disassembler::HandleHeader(spv_endianness_t endian,
stream_ << "; " << SPV_GENERATOR_MISC_PART(generator) << "\n"
<< "; Bound: " << id_bound << "\n"
<< "; Schema: " << schema << "\n";
ResetColor();
}
byte_offset_ = SPV_INDEX_INSTRUCTION * sizeof(uint32_t);
@ -160,6 +163,32 @@ spv_result_t Disassembler::HandleHeader(spv_endianness_t endian,
spv_result_t Disassembler::HandleInstruction(
const spv_parsed_instruction_t& inst) {
auto opcode = static_cast<SpvOp>(inst.opcode);
if (comment_ && opcode == SpvOpFunction) {
stream_ << std::endl;
stream_ << std::string(indent_, ' ');
stream_ << "; Function " << name_mapper_(inst.result_id) << std::endl;
}
if (comment_ && !inserted_decoration_space_ &&
spvOpcodeIsDecoration(opcode)) {
inserted_decoration_space_ = true;
stream_ << std::endl;
stream_ << std::string(indent_, ' ');
stream_ << "; Annotations" << std::endl;
}
if (comment_ && !inserted_debug_space_ && spvOpcodeIsDebug(opcode)) {
inserted_debug_space_ = true;
stream_ << std::endl;
stream_ << std::string(indent_, ' ');
stream_ << "; Debug Information" << std::endl;
}
if (comment_ && !inserted_type_space_ && spvOpcodeGeneratesType(opcode)) {
inserted_type_space_ = true;
stream_ << std::endl;
stream_ << std::string(indent_, ' ');
stream_ << "; Types, variables and constants" << std::endl;
}
if (inst.result_id) {
SetBlue();
const std::string id_name = name_mapper_(inst.result_id);
@ -172,7 +201,7 @@ spv_result_t Disassembler::HandleInstruction(
stream_ << std::string(indent_, ' ');
}
stream_ << "Op" << spvOpcodeString(static_cast<SpvOp>(inst.opcode));
stream_ << "Op" << spvOpcodeString(opcode);
for (uint16_t i = 0; i < inst.num_operands; i++) {
const spv_operand_type_t type = inst.operands[i].type;
@ -182,6 +211,12 @@ spv_result_t Disassembler::HandleInstruction(
EmitOperand(inst, i);
}
if (comment_ && opcode == SpvOpName) {
const spv_parsed_operand_t& operand = inst.operands[0];
const uint32_t word = inst.words[operand.offset];
stream_ << " ; id %" << word;
}
if (show_byte_offset_) {
SetGrey();
auto saved_flags = stream_.flags();

Просмотреть файл

@ -56,6 +56,8 @@ Options:
--raw-id Show raw Id values instead of friendly names.
--offsets Show byte offsets for each instruction.
--comment Add comments to make reading easier
)",
argv0, argv0);
}
@ -79,6 +81,7 @@ int main(int argc, char** argv) {
bool show_byte_offsets = false;
bool no_header = false;
bool friendly_names = true;
bool comments = false;
for (int argi = 1; argi < argc; ++argi) {
if ('-' == argv[argi][0]) {
@ -102,6 +105,8 @@ int main(int argc, char** argv) {
} else if (0 == strcmp(argv[argi], "--color")) {
force_no_color = false;
force_color = true;
} else if (0 == strcmp(argv[argi], "--comment")) {
comments = true;
} else if (0 == strcmp(argv[argi], "--no-indent")) {
allow_indent = false;
} else if (0 == strcmp(argv[argi], "--offsets")) {
@ -156,6 +161,8 @@ int main(int argc, char** argv) {
if (friendly_names) options |= SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES;
if (comments) options |= SPV_BINARY_TO_TEXT_OPTION_COMMENT;
if (!outFile || (0 == strcmp("-", outFile))) {
// Print to standard output.
options |= SPV_BINARY_TO_TEXT_OPTION_PRINT;