From c7dfbc4a25869fe0ce4d07022215b9ec94b664b2 Mon Sep 17 00:00:00 2001 From: z277zhu Date: Tue, 5 Dec 2023 19:53:40 -0500 Subject: [PATCH] Added virtual register info proto support --- gematria/basic_block/basic_block.cc | 18 +++++ gematria/basic_block/basic_block.h | 28 ++++++- gematria/basic_block/basic_block_test.cc | 79 +++++++++++-------- gematria/datasets/bhive_importer.cc | 2 +- .../proto/canonicalized_instruction.proto | 21 ++++- 5 files changed, 107 insertions(+), 41 deletions(-) diff --git a/gematria/basic_block/basic_block.cc b/gematria/basic_block/basic_block.cc index 4047a61c..a6fe599e 100644 --- a/gematria/basic_block/basic_block.cc +++ b/gematria/basic_block/basic_block.cc @@ -60,18 +60,36 @@ std::string AddressTuple::ToString() const { buffer << "AddressTuple("; if (!base_register.empty()) { buffer << "base_register='" << base_register << "', "; + buffer << "base_register_size=" << base_register_size << ", "; + buffer << "base_register_intefered_register={"; + for (const std::string& interfered_register : base_register_intefered_register) { + buffer << "'" << interfered_register << "', "; + } + buffer << "}, "; } if (displacement != 0) { buffer << "displacement=" << displacement << ", "; } if (!index_register.empty()) { buffer << "index_Register='" << index_register << "', "; + buffer << "index_register_size=" << index_register_size << ", "; + buffer << "index_register_intefered_register={"; + for (const std::string& interfered_register : index_register_intefered_register) { + buffer << "'" << interfered_register << "', "; + } + buffer << "}, "; } if (!index_register.empty() || scaling != 0) { buffer << "scaling=" << scaling << ", "; } if (!segment_register.empty()) { buffer << "segment_register='" << segment_register << "', "; + buffer << "segment_register_size=" << segment_register_size << ", "; + buffer << "segment_register_intefered_register={"; + for (const std::string& interfered_register : segment_register_intefered_register) { + buffer << "'" << interfered_register << "', "; + } + buffer << "}, "; } // If we added any keyword args to the buffer, drop the last two characters // (a comma and a space). This is not strictly necessary, but it looks better. diff --git a/gematria/basic_block/basic_block.h b/gematria/basic_block/basic_block.h index 9dd8741f..005b4053 100644 --- a/gematria/basic_block/basic_block.h +++ b/gematria/basic_block/basic_block.h @@ -85,12 +85,23 @@ struct AddressTuple { AddressTuple(AddressTuple&&) = default; AddressTuple(std::string base_register, int64_t displacement, std::string index_register, int scaling, - std::string segment_register) + std::string segment_register, int base_register_size = 64, + int index_register_size = 64, int segment_register_size = 64, + const std::vector base_register_intefered_register = {}, + const std::vector index_register_intefered_register = {}, + const std::vector segment_register_intefered_register = {}) : base_register(std::move(base_register)), displacement(displacement), index_register(std::move(index_register)), scaling(scaling), - segment_register(std::move(segment_register)) {} + segment_register(std::move(segment_register)), + base_register_size(std::move(base_register_size)), + index_register_size(std::move(index_register_size)), + segment_register_size(std::move(segment_register_size)), + base_register_intefered_register(std::move(base_register_intefered_register)), + index_register_intefered_register(std::move(index_register_intefered_register)), + segment_register_intefered_register(std::move(segment_register_intefered_register)) + {} AddressTuple& operator=(const AddressTuple&) = default; AddressTuple& operator=(AddressTuple&&) = default; @@ -126,6 +137,19 @@ struct AddressTuple { // The name of the segment register. When empty, the default segment register // for the instruction is used. std::string segment_register; + // The size of the base register. Used only when base_register is non-empty. + int base_register_size; + // The size of the index register. Used only when index_register is non-empty. + int index_register_size; + // The size of the segment register. Used only when segment_register is + int segment_register_size; + + // The name of the index register of the address. When empty, index register + std::vector base_register_intefered_register; + // The name of the index register of the address. When empty, index register + std::vector index_register_intefered_register; + // The name of the index register of the address. When empty, index register + std::vector segment_register_intefered_register; }; std::ostream& operator<<(std::ostream& os, const AddressTuple& address_tuple); diff --git a/gematria/basic_block/basic_block_test.cc b/gematria/basic_block/basic_block_test.cc index c77f3aea..b5cd3c4b 100644 --- a/gematria/basic_block/basic_block_test.cc +++ b/gematria/basic_block/basic_block_test.cc @@ -50,39 +50,49 @@ TEST(AddressTupleTest, ToString) { const struct { AddressTuple address; const char* expected_string; - } kTestCases[] = { - {AddressTuple(/* base_register = */ "RAX", - /* displacement = */ 0, - /* index_register = */ "", - /* scaling = */ 0, - /* segment_register = */ ""), - "AddressTuple(base_register='RAX')"}, - {AddressTuple(/* base_register = */ "RAX", - /* displacement = */ 16, - /* index_register = */ "", - /* scaling = */ 0, - /* segment_register = */ ""), - "AddressTuple(base_register='RAX', displacement=16)"}, - {AddressTuple(/* base_register = */ "RAX", - /* displacement = */ 0, - /* index_register = */ "RSI", - /* scaling = */ 0, - /* segment_register = */ ""), - "AddressTuple(base_register='RAX', index_Register='RSI', scaling=0)"}, - {AddressTuple(/* base_register = */ "RAX", - /* displacement = */ -8, - /* index_register = */ "RSI", - /* scaling = */ 1, - /* segment_register = */ ""), - "AddressTuple(base_register='RAX', displacement=-8, " - "index_Register='RSI', scaling=1)"}, - {AddressTuple(/* base_register = */ "RAX", - /* displacement = */ -123, - /* index_register = */ "RSI", - /* scaling = */ 1, - /* segment_register = */ "ES"), - "AddressTuple(base_register='RAX', displacement=-123, " - "index_Register='RSI', scaling=1, segment_register='ES')"}}; + } kTestCases[] = {{AddressTuple(/* base_register = */ "RAX", + /* displacement = */ 0, + /* index_register = */ "", + /* scaling = */ 0, + /* segment_register = */ ""), + "AddressTuple(base_register='RAX', base_register_size=64, " + "base_register_intefered_register={})"}, + {AddressTuple(/* base_register = */ "RAX", + /* displacement = */ 16, + /* index_register = */ "", + /* scaling = */ 0, + /* segment_register = */ ""), + "AddressTuple(base_register='RAX', base_register_size=64, " + "base_register_intefered_register={}, displacement=16)"}, + {AddressTuple(/* base_register = */ "RAX", + /* displacement = */ 0, + /* index_register = */ "RSI", + /* scaling = */ 0, + /* segment_register = */ ""), + "AddressTuple(base_register='RAX', base_register_size=64, " + "base_register_intefered_register={}, " + "index_Register='RSI', index_register_size=64, " + "index_register_intefered_register={}, scaling=0)"}, + {AddressTuple(/* base_register = */ "RAX", + /* displacement = */ -8, + /* index_register = */ "RSI", + /* scaling = */ 1, + /* segment_register = */ ""), + "AddressTuple(base_register='RAX', base_register_size=64, " + "base_register_intefered_register={}, displacement=-8, " + "index_Register='RSI', index_register_size=64, " + "index_register_intefered_register={}, scaling=1)"}, + {AddressTuple(/* base_register = */ "RAX", + /* displacement = */ -123, + /* index_register = */ "RSI", + /* scaling = */ 1, + /* segment_register = */ "ES"), + "AddressTuple(base_register='RAX', base_register_size=64, " + "base_register_intefered_register={}, displacement=-123, " + "index_Register='RSI', index_register_size=64, " + "index_register_intefered_register={}, scaling=1, " + "segment_register='ES', segment_register_size=64, " + "segment_register_intefered_register={})"}}; for (const auto& test_case : kTestCases) { SCOPED_TRACE(test_case.expected_string); @@ -287,7 +297,8 @@ TEST(InstructionOperandTest, ToString) { {InstructionOperand::FpImmediateValue(3.14), "InstructionOperand.from_fp_immediate_value(3.14)"}, {InstructionOperand::Address("RAX", 0, "", 0, ""), - "InstructionOperand.from_address(AddressTuple(base_register='RAX'))"}, + "InstructionOperand.from_address(AddressTuple(base_register='RAX', " + "base_register_size=3, base_register_intefered_register={}))"}, {InstructionOperand::MemoryLocation(32), "InstructionOperand.from_memory(32)"}}; diff --git a/gematria/datasets/bhive_importer.cc b/gematria/datasets/bhive_importer.cc index 29f447f8..6e5ed1e3 100644 --- a/gematria/datasets/bhive_importer.cc +++ b/gematria/datasets/bhive_importer.cc @@ -96,7 +96,7 @@ BHiveImporter::BHiveImporter(const Canonicalizer* canonicalizer) } } // prettyPrintName2Reg(); - prettyPrintSuperReg2SubReg(); + // prettyPrintSuperReg2SubReg(); } absl::StatusOr BHiveImporter::BasicBlockProtoFromMachineCode( diff --git a/gematria/proto/canonicalized_instruction.proto b/gematria/proto/canonicalized_instruction.proto index a5b1ca77..a72ece20 100644 --- a/gematria/proto/canonicalized_instruction.proto +++ b/gematria/proto/canonicalized_instruction.proto @@ -60,15 +60,28 @@ message CanonicalizedOperandProto { message AddressTuple { // The name of the base register; empty when a base register is not used. string base_register = 1; + // The size of the base register in bytes; zero when a base register is not used + int32 base_register_size = 2; + // Optional. The name of the registers where the current register interfered with + repeated string base_register_intefered_register = 3; // The name of the index register; empty when an index register is not used. - string index_register = 2; + string index_register = 4; + // The size of the index register in bytes; zero when an index register is not used + int32 index_register_size = 5; + // Optional. The name of the registers where the current register interfered with + repeated string index_register_intefered_register = 6; // The value of the displacement; zero if displacement is not used. - int64 displacement = 3; + int64 displacement = 7; // The value of the scaling factor; one if scaling is not used. - int32 scaling = 4; + int32 scaling = 8; // The name of the segment register; empty when an explicit segment register // is not given. - string segment = 5; + string segment = 9; + // The size of the segment register in bytes; zero when an explicit segment + // register is not given. + int32 segment_size = 10; + // Optional. The name of the registers where the current register interfered with + repeated string segment_intefered_register = 11; } // Contains information about a memory operand of an instruction. We allow