Skip to content

Commit

Permalink
Merge pull request #9 from GranLte/interference_graph_support
Browse files Browse the repository at this point in the history
Interference graph support
  • Loading branch information
9Tempest authored Dec 13, 2023
2 parents 2e8055f + c227bcb commit 369d3c8
Show file tree
Hide file tree
Showing 24 changed files with 894 additions and 407,597 deletions.
113 changes: 90 additions & 23 deletions gematria/basic_block/basic_block.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ std::string AddressTuple::ToString() const {
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) {
for (const std::string& interfered_register :
base_register_intefered_register) {
buffer << "'" << interfered_register << "', ";
}
buffer << "}, ";
Expand All @@ -74,7 +75,8 @@ std::string AddressTuple::ToString() const {
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) {
for (const std::string& interfered_register :
index_register_intefered_register) {
buffer << "'" << interfered_register << "', ";
}
buffer << "}, ";
Expand All @@ -86,7 +88,8 @@ std::string AddressTuple::ToString() const {
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) {
for (const std::string& interfered_register :
segment_register_intefered_register) {
buffer << "'" << interfered_register << "', ";
}
buffer << "}, ";
Expand Down Expand Up @@ -126,12 +129,15 @@ bool InstructionOperand::operator==(const InstructionOperand& other) const {
}

InstructionOperand InstructionOperand::VirtualRegister(
const std::string register_name, size_t size, const std::vector<std::string>& interfered_registers) {
const std::string register_name, size_t size,
const std::vector<std::string>& interfered_registers,
std::vector<int> interfered_registers_size) {
InstructionOperand result;
result.type_ = OperandType::kVirtualRegister;
result.register_name_ = std::move(register_name);
result.size_ = size;
result.interfered_registers_ = std::move(interfered_registers);
result.interfered_registers_size_ = std::move(interfered_registers_size);
return result;
}

Expand Down Expand Up @@ -166,14 +172,16 @@ InstructionOperand InstructionOperand::Address(AddressTuple address_tuple) {
return result;
}

InstructionOperand InstructionOperand::Address(std::string base_register,
int64_t displacement,
std::string index_register,
int scaling,
std::string segment_register,
int base_register_size,
int index_register_size,
int segment_register_size) {
InstructionOperand InstructionOperand::Address(
std::string base_register, int64_t displacement, std::string index_register,
int scaling, std::string segment_register, int base_register_size,
int index_register_size, int segment_register_size,
const std::vector<std::string>& base_register_intefered_register,
const std::vector<std::string>& index_register_intefered_register,
const std::vector<std::string>& segment_register_intefered_register,
const std::vector<int>& base_register_intefered_register_size,
const std::vector<int>& index_register_intefered_register_size,
const std::vector<int>& segment_register_intefered_register_size) {
InstructionOperand result;
result.type_ = OperandType::kAddress;
result.address_.base_register = std::move(base_register);
Expand All @@ -184,9 +192,18 @@ InstructionOperand InstructionOperand::Address(std::string base_register,
result.address_.base_register_size = base_register_size;
result.address_.index_register_size = index_register_size;
result.address_.segment_register_size = segment_register_size;
result.address_.base_register_intefered_register = {};
result.address_.index_register_intefered_register = {};
result.address_.segment_register_intefered_register = {};
result.address_.base_register_intefered_register =
std::move(base_register_intefered_register);
result.address_.index_register_intefered_register =
std::move(index_register_intefered_register);
result.address_.segment_register_intefered_register =
std::move(segment_register_intefered_register);
result.address_.base_register_intefered_register_sizes =
std::move(base_register_intefered_register_size);
result.address_.index_register_intefered_register_sizes =
std::move(index_register_intefered_register_size);
result.address_.segment_register_intefered_register_sizes =
std::move(segment_register_intefered_register_size);
return result;
}

Expand All @@ -213,14 +230,56 @@ void InstructionOperand::AddTokensToList(
break;
case OperandType::kAddress:
tokens.emplace_back(kAddressToken);
tokens.emplace_back(address().base_register.empty()
? kNoRegisterToken
: address().base_register);
tokens.emplace_back(address().index_register.empty()
? kNoRegisterToken
: address().index_register);
if (!address().segment_register.empty()) {
tokens.push_back(address().segment_register);
if (address().base_register.empty()){
tokens.emplace_back(kNoRegisterToken);
} else {
if (address().base_register_size == '%'){
tokens.emplace_back(getVREG_TOKEN(address().base_register_size));
assert(address().base_register_intefered_register.size() == address().base_register_intefered_register_sizes.size());
for (int i = 0; i < address().base_register_intefered_register.size(); ++i) {
if (address().base_register_intefered_register_sizes[i] == '%'){
tokens.emplace_back(getVREG_TOKEN(address().base_register_intefered_register_sizes[i]));
} else {
tokens.emplace_back(address().base_register_intefered_register[i]);
}
}
} else {
tokens.emplace_back(address().base_register);
}
}
if (address().index_register.empty()){
tokens.emplace_back(kNoRegisterToken);
} else {
if (address().index_register_size == '%'){
tokens.emplace_back(getVREG_TOKEN(address().index_register_size));
assert(address().index_register_intefered_register.size() == address().index_register_intefered_register_sizes.size());
for (int i = 0; i < address().index_register_intefered_register.size(); ++i) {
if (address().index_register_intefered_register_sizes[i] == '%'){
tokens.emplace_back(getVREG_TOKEN(address().index_register_intefered_register_sizes[i]));
} else {
tokens.emplace_back(address().index_register_intefered_register[i]);
}
}
} else {
tokens.emplace_back(address().index_register);
}
}
if (address().segment_register.empty()){
tokens.emplace_back(kNoRegisterToken);
} else {
if (address().segment_register_size == '%'){
tokens.emplace_back(getVREG_TOKEN(address().segment_register_size));
assert(address().segment_register_intefered_register.size() == address().segment_register_intefered_register_sizes.size());
for (int i = 0; i < address().segment_register_intefered_register.size(); ++i) {
if (address().segment_register_intefered_register_sizes[i] == '%'){
tokens.emplace_back(getVREG_TOKEN(address().segment_register_intefered_register_sizes[i]));
} else {
tokens.emplace_back(address().segment_register_intefered_register[i]);
}
}
} else {
tokens.emplace_back(address().segment_register);
}
}
if (address().displacement != 0) {
tokens.emplace_back(kDisplacementToken);
Expand All @@ -231,6 +290,14 @@ void InstructionOperand::AddTokensToList(
break;
case OperandType::kVirtualRegister:
tokens.emplace_back(getVREG_TOKEN(size()));
assert(interfered_registers_.size() == interfered_registers_size_.size());
for (int i = 0; i < interfered_registers_.size(); ++i) {
if (interfered_registers_size_[i] == '%'){
tokens.emplace_back(getVREG_TOKEN(interfered_registers_size_[i]));
} else {
tokens.emplace_back(interfered_registers_[i]);
}
}
break;
}
}
Expand Down
82 changes: 57 additions & 25 deletions gematria/basic_block/basic_block.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ inline constexpr std::string_view kDisplacementToken = "_DISPLACEMENT_";
inline constexpr std::string_view kVirtualRegisterToken = "_VREG";
inline std::string getVREG_TOKEN(size_t size) {
return std::string(kVirtualRegisterToken) + std::to_string(size) + "_";
}
}

// The type of an operand of an instruction.
enum class OperandType {
Expand Down Expand Up @@ -83,13 +83,17 @@ struct AddressTuple {
AddressTuple() {}
AddressTuple(const AddressTuple&) = default;
AddressTuple(AddressTuple&&) = default;
AddressTuple(std::string base_register, int64_t displacement,
std::string index_register, int scaling,
std::string segment_register, int base_register_size = 64,
int index_register_size = 64, int segment_register_size = 64,
const std::vector<std::string> base_register_intefered_register = {},
const std::vector<std::string> index_register_intefered_register = {},
const std::vector<std::string> segment_register_intefered_register = {})
AddressTuple(
std::string base_register, int64_t displacement,
std::string index_register, int scaling, std::string segment_register,
int base_register_size = 64, int index_register_size = 64,
int segment_register_size = 64,
const std::vector<std::string> base_register_intefered_register = {},
const std::vector<std::string> index_register_intefered_register = {},
const std::vector<std::string> segment_register_intefered_register = {},
const std::vector<int> base_register_intefered_register_sizes = {},
const std::vector<int> index_register_intefered_register_sizes = {},
const std::vector<int> segment_register_intefered_register_sizes = {})
: base_register(std::move(base_register)),
displacement(displacement),
index_register(std::move(index_register)),
Expand All @@ -98,10 +102,18 @@ struct AddressTuple {
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))
{}
base_register_intefered_register(
std::move(base_register_intefered_register)),
base_register_intefered_register_sizes(
std::move(base_register_intefered_register_sizes)),
index_register_intefered_register(
std::move(index_register_intefered_register)),
index_register_intefered_register_sizes(
std::move(index_register_intefered_register_sizes)),
segment_register_intefered_register(
std::move(segment_register_intefered_register)),
segment_register_intefered_register_sizes(
std::move(segment_register_intefered_register_sizes)) {}

AddressTuple& operator=(const AddressTuple&) = default;
AddressTuple& operator=(AddressTuple&&) = default;
Expand Down Expand Up @@ -144,12 +156,18 @@ struct AddressTuple {
// The size of the segment register. Used only when segment_register is
size_t segment_register_size;

// The name of the index register of the address. When empty, index register
// The name and size of the base register of the address. When empty, base
// register
std::vector<std::string> base_register_intefered_register;
// The name of the index register of the address. When empty, index register
std::vector<int> base_register_intefered_register_sizes;
// The name and size of the index register of the address. When empty, index
// register
std::vector<std::string> index_register_intefered_register;
// The name of the index register of the address. When empty, index register
std::vector<int> index_register_intefered_register_sizes;
// The name of the segment register of the address. When empty, segment
// register
std::vector<std::string> segment_register_intefered_register;
std::vector<int> segment_register_intefered_register_sizes;
};

std::ostream& operator<<(std::ostream& os, const AddressTuple& address_tuple);
Expand All @@ -170,19 +188,25 @@ class InstructionOperand {
InstructionOperand& operator=(InstructionOperand&&) = default;

// The operands must be created through one of the factory functions.
static InstructionOperand VirtualRegister(std::string register_name,
size_t size, const std::vector<std::string>& interfered_registers);
static InstructionOperand VirtualRegister(
std::string register_name, size_t size,
const std::vector<std::string>& interfered_registers,
std::vector<int> interfered_registers_size);
static InstructionOperand Register(std::string register_name);
static InstructionOperand ImmediateValue(uint64_t immediate_value);
static InstructionOperand FpImmediateValue(double fp_immediate_value);
static InstructionOperand Address(AddressTuple address_tuple);
static InstructionOperand Address(std::string base_register,
int64_t displacement,
std::string index_register, int scaling,
std::string segment_register,
int base_register_size = 64,
int index_register_size = 64,
int segment_register_size = 64);
static InstructionOperand Address(
std::string base_register, int64_t displacement,
std::string index_register, int scaling, std::string segment_register,
int base_register_size = 64, int index_register_size = 64,
int segment_register_size = 64,
const std::vector<std::string>& base_register_intefered_register = {},
const std::vector<std::string>& index_register_intefered_register = {},
const std::vector<std::string>& segment_register_intefered_register = {},
const std::vector<int>& base_register_intefered_register_sizes = {},
const std::vector<int>& index_register_intefered_register_sizes = {},
const std::vector<int>& segment_register_intefered_register_sizes = {});
static InstructionOperand MemoryLocation(int alias_group_id);

bool operator==(const InstructionOperand&) const;
Expand All @@ -196,11 +220,18 @@ class InstructionOperand {
// Returns the list of tokens representing this instruction.
std::vector<std::string> AsTokenList() const;

std::vector<std::string> getInterferedRegisters() const {
const std::vector<std::string>& getInterferedRegisters() const {
assert(type_ == OperandType::kVirtualRegister);
assert(interfered_registers_.size() == interfered_registers_size_.size());
return interfered_registers_;
}

const std::vector<int>& getInterferedRegistersSize() const {
assert(type_ == OperandType::kVirtualRegister);
assert(interfered_registers_.size() == interfered_registers_size_.size());
return interfered_registers_size_;
}

// Returns a human-readable representation of the operand.
//
// This method implements the __str__() and __repr__() methods in the Python
Expand Down Expand Up @@ -258,6 +289,7 @@ class InstructionOperand {
AddressTuple address_;
int alias_group_id_ = 0;
std::vector<std::string> interfered_registers_;
std::vector<int> interfered_registers_size_;
};

std::ostream& operator<<(std::ostream& os, const InstructionOperand& operand);
Expand Down
Loading

0 comments on commit 369d3c8

Please sign in to comment.