address_space: Add ReverseGet

This commit is contained in:
Merry 2022-12-11 11:57:57 +00:00
parent 407a9d202a
commit 84ca6fef0d
2 changed files with 18 additions and 0 deletions

View file

@ -30,6 +30,15 @@ CodePtr AddressSpace::Get(IR::LocationDescriptor descriptor) {
return nullptr; return nullptr;
} }
std::optional<IR::LocationDescriptor> AddressSpace::ReverseGet(CodePtr host_pc) {
if (auto iter = reverse_block_entries.upper_bound(host_pc); iter != reverse_block_entries.begin()) {
// upper_bound locates the first value greater than host_pc, so we need to decrement
--iter;
return IR::LocationDescriptor{iter->second};
}
return std::nullopt;
}
CodePtr AddressSpace::GetOrEmit(IR::LocationDescriptor descriptor) { CodePtr AddressSpace::GetOrEmit(IR::LocationDescriptor descriptor) {
if (CodePtr block_entry = Get(descriptor)) { if (CodePtr block_entry = Get(descriptor)) {
return block_entry; return block_entry;
@ -40,11 +49,13 @@ CodePtr AddressSpace::GetOrEmit(IR::LocationDescriptor descriptor) {
block_infos.insert_or_assign(descriptor.Value(), block_info); block_infos.insert_or_assign(descriptor.Value(), block_info);
block_entries.insert_or_assign(descriptor.Value(), block_info.entry_point); block_entries.insert_or_assign(descriptor.Value(), block_info.entry_point);
reverse_block_entries.insert_or_assign(block_info.entry_point, descriptor.Value());
return block_info.entry_point; return block_info.entry_point;
} }
void AddressSpace::ClearCache() { void AddressSpace::ClearCache() {
block_entries.clear(); block_entries.clear();
reverse_block_entries.clear();
block_infos.clear(); block_infos.clear();
block_references.clear(); block_references.clear();
code.set_ptr(prelude_info.end_of_prelude); code.set_ptr(prelude_info.end_of_prelude);

View file

@ -5,6 +5,9 @@
#pragma once #pragma once
#include <map>
#include <optional>
#include <mcl/stdint.hpp> #include <mcl/stdint.hpp>
#include <oaknut/code_block.hpp> #include <oaknut/code_block.hpp>
#include <oaknut/oaknut.hpp> #include <oaknut/oaknut.hpp>
@ -27,6 +30,9 @@ public:
CodePtr Get(IR::LocationDescriptor descriptor); CodePtr Get(IR::LocationDescriptor descriptor);
// Returns "most likely" LocationDescriptor assocated with the emitted code at that location
std::optional<IR::LocationDescriptor> ReverseGet(CodePtr host_pc);
CodePtr GetOrEmit(IR::LocationDescriptor descriptor); CodePtr GetOrEmit(IR::LocationDescriptor descriptor);
void ClearCache(); void ClearCache();
@ -44,6 +50,7 @@ protected:
oaknut::CodeGenerator code; oaknut::CodeGenerator code;
tsl::robin_map<u64, CodePtr> block_entries; tsl::robin_map<u64, CodePtr> block_entries;
std::map<CodePtr, u64> reverse_block_entries;
tsl::robin_map<u64, EmittedBlockInfo> block_infos; tsl::robin_map<u64, EmittedBlockInfo> block_infos;
tsl::robin_map<u64, tsl::robin_set<u64>> block_references; tsl::robin_map<u64, tsl::robin_set<u64>> block_references;