mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 17:00:19 +02:00
IR: drop RegisterAllocationData
This sideband is now unused, registers are encoded directly in the IR. So we can garbage collect all this code for quite some savings. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
1 parent
49f8332c5b
commit
65ee1fafa8
18 files changed
+23
-154
No files matched your search
@@ -575,7 +575,7 @@ def print_ir_arg_printer():
|
||||
|
||||
if arg.IsSSA:
|
||||
# SSA value
|
||||
output_file.write("\tPrintArg(out, IR, Op->Header.Args[{}], RAData);\n".format(SSAArgNum))
|
||||
output_file.write("\tPrintArg(out, IR, Op->Header.Args[{}]);\n".format(SSAArgNum))
|
||||
SSAArgNum = SSAArgNum + 1
|
||||
else:
|
||||
# User defined op that is stored
|
||||
|
||||
@@ -50,7 +50,6 @@ namespace HLE {
|
||||
} // namespace FEXCore
|
||||
|
||||
namespace FEXCore::IR {
|
||||
class RegisterAllocationData;
|
||||
struct IRListCopy;
|
||||
class IRListView;
|
||||
namespace Validation {
|
||||
@@ -271,7 +270,6 @@ public:
|
||||
|
||||
struct GenerateIRResult {
|
||||
std::optional<IR::IRListView> IRView;
|
||||
IR::RegisterAllocationData* RAData;
|
||||
uint64_t TotalInstructions;
|
||||
uint64_t TotalInstructionsLength;
|
||||
uint64_t StartAddr;
|
||||
|
||||
@@ -18,7 +18,6 @@ namespace FEXCore {
|
||||
|
||||
namespace IR {
|
||||
class IRListView;
|
||||
class RegisterAllocationData;
|
||||
} // namespace IR
|
||||
|
||||
namespace Core {
|
||||
@@ -119,7 +118,7 @@ namespace CPU {
|
||||
*/
|
||||
[[nodiscard]]
|
||||
virtual CompiledCode CompileCode(uint64_t Entry, uint64_t Size, bool SingleInst, const FEXCore::IR::IRListView* IR,
|
||||
FEXCore::Core::DebugData* DebugData, const FEXCore::IR::RegisterAllocationData* RAData, bool CheckTF) = 0;
|
||||
FEXCore::Core::DebugData* DebugData, bool CheckTF) = 0;
|
||||
|
||||
/**
|
||||
* @brief Relocates a block of code from the JIT code object cache
|
||||
|
||||
@@ -509,11 +509,11 @@ void ContextImpl::ClearCodeCache(FEXCore::Core::InternalThreadState* Thread) {
|
||||
Thread->CPUBackend->ClearCache();
|
||||
}
|
||||
|
||||
static void IRDumper(FEXCore::Core::InternalThreadState* Thread, IR::IREmitter* IREmitter, uint64_t GuestRIP, IR::RegisterAllocationData* RA) {
|
||||
static void IRDumper(FEXCore::Core::InternalThreadState* Thread, IR::IREmitter* IREmitter, uint64_t GuestRIP) {
|
||||
FEXCore::File::File FD = FEXCore::File::File::GetStdERR();
|
||||
fextl::stringstream out;
|
||||
auto NewIR = IREmitter->ViewIR();
|
||||
FEXCore::IR::Dump(&out, &NewIR, RA);
|
||||
FEXCore::IR::Dump(&out, &NewIR);
|
||||
fextl::fmt::print(FD, "IR-ShouldDump-{} 0x{:x}:\n{}\n@@@@@\n", NewIR.PostRA() ? "post" : "pre", GuestRIP, out.str());
|
||||
};
|
||||
|
||||
@@ -686,7 +686,7 @@ ContextImpl::GenerateIR(FEXCore::Core::InternalThreadState* Thread, uint64_t Gue
|
||||
if (HadDispatchError && TotalInstructions == 0) {
|
||||
// Couldn't handle any instruction in op dispatcher
|
||||
Thread->OpDispatcher->ResetWorkingList();
|
||||
return {{}, nullptr, 0, 0, 0, 0};
|
||||
return {{}, 0, 0, 0, 0};
|
||||
}
|
||||
|
||||
if (NeedsBlockEnd) {
|
||||
@@ -712,22 +712,19 @@ ContextImpl::GenerateIR(FEXCore::Core::InternalThreadState* Thread, uint64_t Gue
|
||||
auto ShouldDump = Thread->OpDispatcher->ShouldDumpIR();
|
||||
// Debug
|
||||
if (ShouldDump) {
|
||||
IRDumper(Thread, IREmitter, GuestRIP, nullptr);
|
||||
IRDumper(Thread, IREmitter, GuestRIP);
|
||||
}
|
||||
|
||||
// Run the passmanager over the IR from the dispatcher
|
||||
Thread->PassManager->Run(IREmitter);
|
||||
|
||||
auto RAData = Thread->PassManager->HasPass("RA") ? Thread->PassManager->GetPass<IR::RegisterAllocationPass>("RA")->GetAllocationData() : nullptr;
|
||||
|
||||
// Debug
|
||||
if (ShouldDump) {
|
||||
IRDumper(Thread, IREmitter, GuestRIP, RAData);
|
||||
IRDumper(Thread, IREmitter, GuestRIP);
|
||||
}
|
||||
|
||||
return {
|
||||
.IRView = IREmitter->ViewIR(),
|
||||
.RAData = RAData,
|
||||
.TotalInstructions = TotalInstructions,
|
||||
.TotalInstructionsLength = TotalInstructionsLength,
|
||||
.StartAddr = Thread->FrontendDecoder->DecodedMinAddress,
|
||||
@@ -760,8 +757,7 @@ ContextImpl::CompileCodeResult ContextImpl::CompileCode(FEXCore::Core::InternalT
|
||||
}
|
||||
|
||||
// Generate IR + Meta Info
|
||||
auto [IRView, RAData, TotalInstructions, TotalInstructionsLength, StartAddr, Length] =
|
||||
GenerateIR(Thread, GuestRIP, Config.GDBSymbols(), MaxInst);
|
||||
auto [IRView, TotalInstructions, TotalInstructionsLength, StartAddr, Length] = GenerateIR(Thread, GuestRIP, Config.GDBSymbols(), MaxInst);
|
||||
if (!IRView) {
|
||||
return {nullptr, nullptr, 0, 0};
|
||||
}
|
||||
@@ -772,7 +768,7 @@ ContextImpl::CompileCodeResult ContextImpl::CompileCode(FEXCore::Core::InternalT
|
||||
|
||||
// Attempt to get the CPU backend to compile this code
|
||||
|
||||
auto CompiledCode = Thread->CPUBackend->CompileCode(GuestRIP, Length, TotalInstructions == 1, &*IRView, DebugData.get(), RAData, TFSet);
|
||||
auto CompiledCode = Thread->CPUBackend->CompileCode(GuestRIP, Length, TotalInstructions == 1, &*IRView, DebugData.get(), TFSet);
|
||||
|
||||
// Release the IR
|
||||
Thread->OpDispatcher->DelayedDisownBuffer();
|
||||
|
||||
@@ -681,15 +681,13 @@ void Arm64JITCore::EmitInterruptChecks(bool CheckTF) {
|
||||
}
|
||||
|
||||
CPUBackend::CompiledCode Arm64JITCore::CompileCode(uint64_t Entry, uint64_t Size, bool SingleInst, const FEXCore::IR::IRListView* IR,
|
||||
FEXCore::Core::DebugData* DebugData, const FEXCore::IR::RegisterAllocationData* RAData,
|
||||
bool CheckTF) {
|
||||
FEXCore::Core::DebugData* DebugData, bool CheckTF) {
|
||||
FEXCORE_PROFILE_SCOPED("Arm64::CompileCode");
|
||||
|
||||
JumpTargets.clear();
|
||||
uint32_t SSACount = IR->GetSSACount();
|
||||
|
||||
this->Entry = Entry;
|
||||
this->RAData = RAData;
|
||||
this->DebugData = DebugData;
|
||||
this->IR = IR;
|
||||
|
||||
|
||||
@@ -38,9 +38,8 @@ public:
|
||||
~Arm64JITCore() override;
|
||||
|
||||
[[nodiscard]]
|
||||
CPUBackend::CompiledCode
|
||||
CompileCode(uint64_t Entry, uint64_t Size, bool SingleInst, const FEXCore::IR::IRListView* IR, FEXCore::Core::DebugData* DebugData,
|
||||
const FEXCore::IR::RegisterAllocationData* RAData, bool CheckTF) override;
|
||||
CPUBackend::CompiledCode CompileCode(uint64_t Entry, uint64_t Size, bool SingleInst, const FEXCore::IR::IRListView* IR,
|
||||
FEXCore::Core::DebugData* DebugData, bool CheckTF) override;
|
||||
|
||||
void ClearCache() override;
|
||||
|
||||
@@ -292,7 +291,6 @@ private:
|
||||
// This is purely a debugging aid for developers to see if they are in JIT code space when inspecting raw memory
|
||||
void EmitDetectionString();
|
||||
IR::RegisterAllocationPass* RAPass {};
|
||||
const IR::RegisterAllocationData* RAData {};
|
||||
FEXCore::Core::DebugData* DebugData {};
|
||||
|
||||
void ResetStack();
|
||||
|
||||
@@ -47,19 +47,12 @@ AOTIRInlineEntry* AOTIRInlineIndex::Find(uint64_t GuestStart) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IR::RegisterAllocationData* AOTIRInlineEntry::GetRAData() {
|
||||
return (IR::RegisterAllocationData*)InlineData;
|
||||
}
|
||||
|
||||
IR::IRListView* AOTIRInlineEntry::GetIRData() {
|
||||
auto RAData = GetRAData();
|
||||
auto Offset = RAData->Size(RAData->MapCount);
|
||||
|
||||
return (IR::IRListView*)&InlineData[Offset];
|
||||
return (IR::IRListView*)InlineData;
|
||||
}
|
||||
|
||||
void AOTIRCaptureCacheEntry::AppendAOTIRCaptureCache(uint64_t GuestRIP, uint64_t Start, uint64_t Length, uint64_t Hash,
|
||||
const FEXCore::IR::IRListView& IRList, const FEXCore::IR::RegisterAllocationData* RAData) {
|
||||
const FEXCore::IR::IRListView& IRList) {
|
||||
auto Inserted = Index.emplace(GuestRIP, Stream->Offset());
|
||||
|
||||
if (Inserted.second) {
|
||||
@@ -69,8 +62,6 @@ void AOTIRCaptureCacheEntry::AppendAOTIRCaptureCache(uint64_t GuestRIP, uint64_t
|
||||
};
|
||||
Stream->Write((const char*)&entry, sizeof(entry));
|
||||
|
||||
RAData->Serialize(*Stream);
|
||||
|
||||
// IRData (inline)
|
||||
IRList.Serialize(*Stream);
|
||||
}
|
||||
@@ -265,9 +256,6 @@ class IRInlineStorage : public IRStorageBase {
|
||||
public:
|
||||
IRInlineStorage(AOTIRInlineEntry& entry)
|
||||
: entry(entry) {}
|
||||
const RegisterAllocationData* RAData() override {
|
||||
return entry.GetRAData();
|
||||
}
|
||||
IRListView GetIRView() override {
|
||||
return entry.GetIRData();
|
||||
}
|
||||
@@ -332,7 +320,7 @@ bool AOTIRCaptureCache::PostCompileCode(FEXCore::Core::InternalThreadState* Thre
|
||||
}
|
||||
|
||||
// Add to AOT cache if aot generation is enabled
|
||||
if (GeneratedIR && IR->RAData() && (CTX->Config.AOTIRCapture() || CTX->Config.AOTIRGenerate())) {
|
||||
if (GeneratedIR && (CTX->Config.AOTIRCapture() || CTX->Config.AOTIRGenerate())) {
|
||||
|
||||
auto hash = XXH3_64bits((void*)StartAddr, Length);
|
||||
|
||||
@@ -356,7 +344,7 @@ bool AOTIRCaptureCache::PostCompileCode(FEXCore::Core::InternalThreadState* Thre
|
||||
uint64_t tag = FEXCore::IR::AOTIR_COOKIE;
|
||||
AotFile->Stream->Write(&tag, sizeof(tag));
|
||||
}
|
||||
AotFile->AppendAOTIRCaptureCache(LocalRIP, LocalStartAddr, Length, hash, IR->GetIRView(), IR->RAData());
|
||||
AotFile->AppendAOTIRCaptureCache(LocalRIP, LocalStartAddr, Length, hash, IR->GetIRView());
|
||||
});
|
||||
|
||||
if (CTX->Config.AOTIRGenerate()) {
|
||||
|
||||
@@ -50,7 +50,6 @@ class ContextImpl;
|
||||
}
|
||||
|
||||
namespace FEXCore::IR {
|
||||
class RegisterAllocationData;
|
||||
class IRListView;
|
||||
|
||||
constexpr auto COOKIE_VERSION = [](const char CookieText[4], uint32_t Version) {
|
||||
@@ -75,10 +74,9 @@ struct AOTIRInlineEntry {
|
||||
uint64_t GuestHash;
|
||||
uint64_t GuestLength;
|
||||
|
||||
/* RAData followed by IRData */
|
||||
/* IRData */
|
||||
uint8_t InlineData[0];
|
||||
|
||||
IR::RegisterAllocationData* GetRAData();
|
||||
IR::IRListView* GetIRData();
|
||||
};
|
||||
|
||||
@@ -100,8 +98,7 @@ struct AOTIRCaptureCacheEntry {
|
||||
fextl::unique_ptr<FEXCore::Context::AOTIRWriter> Stream;
|
||||
fextl::map<uint64_t, uint64_t> Index;
|
||||
|
||||
void AppendAOTIRCaptureCache(uint64_t GuestRIP, uint64_t Start, uint64_t Length, uint64_t Hash, const FEXCore::IR::IRListView& IRList,
|
||||
const FEXCore::IR::RegisterAllocationData* RAData);
|
||||
void AppendAOTIRCaptureCache(uint64_t GuestRIP, uint64_t Start, uint64_t Length, uint64_t Hash, const FEXCore::IR::IRListView& IRList);
|
||||
};
|
||||
|
||||
struct AOTIRCacheEntry {
|
||||
|
||||
@@ -11,7 +11,6 @@ namespace FEXCore::IR {
|
||||
|
||||
class OrderedNode;
|
||||
class RegisterAllocationPass;
|
||||
class RegisterAllocationData;
|
||||
|
||||
/**
|
||||
* @brief The IROp_Header is an dynamically sized array
|
||||
@@ -766,7 +765,7 @@ inline NodeID NodeWrapperBase<Type>::ID() const {
|
||||
bool IsFragmentExit(FEXCore::IR::IROps Op);
|
||||
bool IsBlockExit(FEXCore::IR::IROps Op);
|
||||
|
||||
void Dump(fextl::stringstream* out, const IRListView* IR, const IR::RegisterAllocationData* RAData);
|
||||
void Dump(fextl::stringstream* out, const IRListView* IR);
|
||||
} // namespace FEXCore::IR
|
||||
|
||||
template<>
|
||||
|
||||
@@ -82,7 +82,7 @@ static void PrintArg(fextl::stringstream* out, [[maybe_unused]] const IRListView
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintArg(fextl::stringstream* out, const IRListView* IR, OrderedNodeWrapper Arg, const IR::RegisterAllocationData* RAData) {
|
||||
static void PrintArg(fextl::stringstream* out, const IRListView* IR, OrderedNodeWrapper Arg) {
|
||||
if (Arg.IsImmediate()) {
|
||||
auto PhyReg = PhysicalRegister(Arg);
|
||||
|
||||
@@ -272,7 +272,7 @@ static void PrintArg(fextl::stringstream* out, [[maybe_unused]] const IRListView
|
||||
}
|
||||
}
|
||||
|
||||
void Dump(fextl::stringstream* out, const IRListView* IR, const IR::RegisterAllocationData* RAData) {
|
||||
void Dump(fextl::stringstream* out, const IRListView* IR) {
|
||||
auto HeaderOp = IR->GetHeader();
|
||||
|
||||
int8_t CurrentIndent = 0;
|
||||
|
||||
@@ -419,9 +419,6 @@ class IRStorageBase {
|
||||
public:
|
||||
virtual ~IRStorageBase() = default;
|
||||
|
||||
// Optional RA data. Returns nullptr if none present
|
||||
virtual const RegisterAllocationData* RAData() = 0;
|
||||
|
||||
virtual IRListView GetIRView() = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ class IntrusivePooledAllocator;
|
||||
namespace FEXCore::IR {
|
||||
class Pass;
|
||||
class RegisterAllocationPass;
|
||||
class RegisterAllocationData;
|
||||
|
||||
fextl::unique_ptr<FEXCore::IR::Pass> CreateConstProp(bool SupportsTSOImm9, const FEXCore::CPUIDEmu* CPUID);
|
||||
fextl::unique_ptr<FEXCore::IR::Pass> CreateDeadFlagCalculationEliminination();
|
||||
|
||||
@@ -38,12 +38,6 @@ IRDumper::IRDumper() {
|
||||
}
|
||||
|
||||
void IRDumper::Run(IREmitter* IREmit) {
|
||||
auto RAPass = Manager->GetPass<IR::RegisterAllocationPass>("RA");
|
||||
IR::RegisterAllocationData* RA {};
|
||||
if (RAPass) {
|
||||
RA = RAPass->GetAllocationData();
|
||||
}
|
||||
|
||||
FEXCore::File::File FD {};
|
||||
if (DumpIR() == "stderr") {
|
||||
FD = FEXCore::File::File::GetStdERR();
|
||||
@@ -64,7 +58,7 @@ void IRDumper::Run(IREmitter* IREmit) {
|
||||
|
||||
if (FD.IsValid() || DumpToLog) {
|
||||
fextl::stringstream out;
|
||||
FEXCore::IR::Dump(&out, &IR, RA);
|
||||
FEXCore::IR::Dump(&out, &IR);
|
||||
if (FD.IsValid()) {
|
||||
fextl::fmt::print(FD, "IR-{} 0x{:x}:\n{}\n@@@@@\n", IR.PostRA() ? "post" : "pre", HeaderOp->OriginalRIP, out.str());
|
||||
} else {
|
||||
|
||||
@@ -58,11 +58,6 @@ void IRValidation::Run(IREmitter* IREmit) {
|
||||
LOGMAN_THROW_A_FMT(HeaderOp->Header.Op == OP_IRHEADER, "First op wasn't IRHeader");
|
||||
#endif
|
||||
|
||||
IR::RegisterAllocationData* RAData {};
|
||||
if (Manager->HasPass("RA")) {
|
||||
RAData = Manager->GetPass<IR::RegisterAllocationPass>("RA")->GetAllocationData();
|
||||
}
|
||||
|
||||
for (auto [BlockNode, BlockHeader] : CurrentIR.GetBlocks()) {
|
||||
auto BlockIROp = BlockHeader->CW<FEXCore::IR::IROp_CodeBlock>();
|
||||
LOGMAN_THROW_A_FMT(BlockIROp->Header.Op == OP_CODEBLOCK, "IR type failed to be a code block");
|
||||
@@ -257,7 +252,7 @@ void IRValidation::Run(IREmitter* IREmit) {
|
||||
HadWarning = false;
|
||||
if (HadError || HadWarning) {
|
||||
fextl::stringstream Out;
|
||||
FEXCore::IR::Dump(&Out, &CurrentIR, RAData);
|
||||
FEXCore::IR::Dump(&Out, &CurrentIR);
|
||||
|
||||
if (HadError) {
|
||||
Out << "Errors:" << std::endl << Errors.str() << std::endl;
|
||||
|
||||
@@ -58,11 +58,7 @@ public:
|
||||
void Run(IREmitter* IREmit) override;
|
||||
void AddRegisters(IR::RegisterClassType Class, uint32_t RegisterCount) override;
|
||||
|
||||
RegisterAllocationData* GetAllocationData() override;
|
||||
RegisterAllocationData::UniquePtr PullAllocationData() override;
|
||||
|
||||
private:
|
||||
IR::RegisterAllocationData::UniquePtr AllocData;
|
||||
RegisterClass Classes[INVALID_CLASS];
|
||||
|
||||
IREmitter* IREmit;
|
||||
@@ -445,14 +441,6 @@ void ConstrainedRAPass::AddRegisters(IR::RegisterClassType Class, uint32_t Regis
|
||||
Classes[Class].Count = RegisterCount;
|
||||
}
|
||||
|
||||
RegisterAllocationData* ConstrainedRAPass::GetAllocationData() {
|
||||
return AllocData.get();
|
||||
}
|
||||
|
||||
RegisterAllocationData::UniquePtr ConstrainedRAPass::PullAllocationData() {
|
||||
return std::move(AllocData);
|
||||
}
|
||||
|
||||
void ConstrainedRAPass::Run(IREmitter* IREmit_) {
|
||||
FEXCORE_PROFILE_SCOPED("PassManager::RA");
|
||||
|
||||
@@ -673,13 +661,6 @@ void ConstrainedRAPass::Run(IREmitter* IREmit_) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that we're done growing things, we can finalize our results.
|
||||
*
|
||||
* TODO: Rework RegisterAllocationData to remove this memcpy, it's pointless.
|
||||
*/
|
||||
AllocData = RegisterAllocationData::Create(SSAToReg.size());
|
||||
memcpy(AllocData->Map, SSAToReg.data(), sizeof(PhysicalRegister) * SSAToReg.size());
|
||||
|
||||
PreferredReg.clear();
|
||||
SSAToNewSSA.clear();
|
||||
NewSSAToSSA.clear();
|
||||
|
||||
@@ -12,8 +12,6 @@ $end_info$
|
||||
#include <stdint.h>
|
||||
|
||||
namespace FEXCore::IR {
|
||||
class RegisterAllocationData;
|
||||
struct RegisterAllocationDataDeleter;
|
||||
struct RegisterClassType;
|
||||
|
||||
class RegisterAllocationPass : public FEXCore::IR::Pass {
|
||||
@@ -22,16 +20,6 @@ public:
|
||||
|
||||
// Number of GPRs usable for pairs at start of GPR set. Must be even.
|
||||
uint32_t PairRegs;
|
||||
|
||||
/**
|
||||
* @brief Returns the register and class map array
|
||||
*/
|
||||
virtual RegisterAllocationData* GetAllocationData() = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns and transfers ownership of the register and class map array
|
||||
*/
|
||||
virtual std::unique_ptr<RegisterAllocationData, RegisterAllocationDataDeleter> PullAllocationData() = 0;
|
||||
};
|
||||
|
||||
} // namespace FEXCore::IR
|
||||
@@ -41,61 +41,4 @@ union PhysicalRegister {
|
||||
|
||||
static_assert(sizeof(PhysicalRegister) == 1);
|
||||
|
||||
struct RegisterAllocationDataDeleter;
|
||||
|
||||
// This class is serialized, can't have any holes in the structure
|
||||
// otherwise ASAN complains about reading uninitialized memory
|
||||
class FEX_PACKED RegisterAllocationData {
|
||||
public:
|
||||
uint32_t SpillSlotCount {};
|
||||
uint32_t MapCount {};
|
||||
PhysicalRegister Map[0];
|
||||
|
||||
PhysicalRegister GetNodeRegister(NodeID Node) const {
|
||||
return Map[Node.Value];
|
||||
}
|
||||
uint32_t SpillSlots() const {
|
||||
return SpillSlotCount;
|
||||
}
|
||||
|
||||
static size_t Size(uint32_t NodeCount) {
|
||||
return sizeof(RegisterAllocationData) + NodeCount * sizeof(Map[0]);
|
||||
}
|
||||
|
||||
using UniquePtr = std::unique_ptr<FEXCore::IR::RegisterAllocationData, RegisterAllocationDataDeleter>;
|
||||
|
||||
static UniquePtr Create(uint32_t NodeCount);
|
||||
|
||||
UniquePtr CreateCopy() const;
|
||||
|
||||
void Serialize(FEXCore::Context::AOTIRWriter& stream) const {
|
||||
stream.Write((const char*)&SpillSlotCount, sizeof(SpillSlotCount));
|
||||
stream.Write((const char*)&MapCount, sizeof(MapCount));
|
||||
// RAData (inline)
|
||||
stream.Write((const char*)&Map[0], sizeof(Map[0]) * MapCount);
|
||||
}
|
||||
};
|
||||
|
||||
struct RegisterAllocationDataDeleter {
|
||||
void operator()(RegisterAllocationData* r) const {
|
||||
FEXCore::Allocator::free(r);
|
||||
}
|
||||
};
|
||||
|
||||
inline auto RegisterAllocationData::Create(uint32_t NodeCount) -> UniquePtr {
|
||||
auto Ret = (RegisterAllocationData*)FEXCore::Allocator::malloc(Size(NodeCount));
|
||||
memset(&Ret->Map[0], PhysicalRegister::Invalid().Raw, NodeCount);
|
||||
Ret->SpillSlotCount = 0;
|
||||
Ret->MapCount = NodeCount;
|
||||
return UniquePtr {Ret};
|
||||
}
|
||||
|
||||
inline auto RegisterAllocationData::CreateCopy() const -> UniquePtr {
|
||||
auto copy = (RegisterAllocationData*)FEXCore::Allocator::malloc(Size(MapCount));
|
||||
memcpy((void*)©->Map[0], (void*)&Map[0], MapCount * sizeof(Map[0]));
|
||||
copy->SpillSlotCount = SpillSlotCount;
|
||||
copy->MapCount = MapCount;
|
||||
return UniquePtr {copy};
|
||||
}
|
||||
|
||||
} // namespace FEXCore::IR
|
||||
@@ -17,7 +17,6 @@ namespace FEXCore::IR {
|
||||
|
||||
class OrderedNode;
|
||||
class RegisterAllocationPass;
|
||||
class RegisterAllocationData;
|
||||
|
||||
enum class SyscallFlags : uint8_t {
|
||||
DEFAULT = 0,
|
||||
|
||||
Reference in new issue
Block a user