From e6ad608226a6c2c53e1c9a14816837f49617219f Mon Sep 17 00:00:00 2001 From: lioncash Date: Wed, 24 Nov 2021 15:09:14 -0500 Subject: [PATCH 1/2] IR: Add alias for Node IDs In quite a few places we have a raw primitive to represent an IR node's ID. This can make reading some bits of the API (or the passes) a little confusing to take in, since there's no meaningful type name for some data structure members. We can provide an alias that communicates this directly to the reader. This also has the nice benefit of providing a single point of definition for node IDs which can allow for easier changes in the future (e.g. making Node IDs strongly-typed etc). --- .../Interface/Core/Interpreter/ALUOps.cpp | 2 +- .../Interface/Core/Interpreter/AtomicOps.cpp | 2 +- .../Interface/Core/Interpreter/BranchOps.cpp | 2 +- .../Core/Interpreter/ConversionOps.cpp | 2 +- .../Core/Interpreter/EncryptionOps.cpp | 2 +- .../Interface/Core/Interpreter/F80Ops.cpp | 2 +- .../Interface/Core/Interpreter/FlagOps.cpp | 2 +- .../Core/Interpreter/InterpreterDefines.h | 2 +- .../Core/Interpreter/InterpreterOps.cpp | 8 +-- .../Core/Interpreter/InterpreterOps.h | 6 +-- .../Interface/Core/Interpreter/MemoryOps.cpp | 2 +- .../Interface/Core/Interpreter/MiscOps.cpp | 2 +- .../Interface/Core/Interpreter/MoveOps.cpp | 2 +- .../Interface/Core/Interpreter/VectorOps.cpp | 2 +- .../Interface/Core/JIT/Arm64/ALUOps.cpp | 2 +- .../Interface/Core/JIT/Arm64/AtomicOps.cpp | 2 +- .../Interface/Core/JIT/Arm64/BranchOps.cpp | 2 +- .../Core/JIT/Arm64/ConversionOps.cpp | 2 +- .../Core/JIT/Arm64/EncryptionOps.cpp | 2 +- .../Interface/Core/JIT/Arm64/FlagOps.cpp | 2 +- .../Source/Interface/Core/JIT/Arm64/JIT.cpp | 28 +++++------ .../Interface/Core/JIT/Arm64/JITClass.h | 30 +++++------ .../Interface/Core/JIT/Arm64/MemoryOps.cpp | 2 +- .../Interface/Core/JIT/Arm64/MiscOps.cpp | 2 +- .../Interface/Core/JIT/Arm64/MoveOps.cpp | 2 +- .../Interface/Core/JIT/Arm64/VectorOps.cpp | 2 +- .../Interface/Core/JIT/x86_64/ALUOps.cpp | 2 +- .../Interface/Core/JIT/x86_64/AtomicOps.cpp | 2 +- .../Interface/Core/JIT/x86_64/BranchOps.cpp | 2 +- .../Core/JIT/x86_64/ConversionOps.cpp | 2 +- .../Core/JIT/x86_64/EncryptionOps.cpp | 2 +- .../Interface/Core/JIT/x86_64/FlagOps.cpp | 2 +- .../Source/Interface/Core/JIT/x86_64/JIT.cpp | 50 +++++++++---------- .../Interface/Core/JIT/x86_64/JITClass.h | 22 ++++---- .../Interface/Core/JIT/x86_64/MemoryOps.cpp | 2 +- .../Interface/Core/JIT/x86_64/MiscOps.cpp | 2 +- .../Interface/Core/JIT/x86_64/MoveOps.cpp | 2 +- .../Interface/Core/JIT/x86_64/VectorOps.cpp | 2 +- External/FEXCore/include/FEXCore/IR/IR.h | 13 +++-- .../include/FEXCore/IR/IntrusiveIRList.h | 2 +- .../FEXCore/IR/RegisterAllocationData.h | 2 +- 41 files changed, 115 insertions(+), 110 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/ALUOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/ALUOps.cpp index 947669f8d7..2f0bb81bad 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/ALUOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/ALUOps.cpp @@ -13,7 +13,7 @@ tags: backend|interpreter #include namespace FEXCore::CPU { -#define DEF_OP(x) void InterpreterOps::Op_##x(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) +#define DEF_OP(x) void InterpreterOps::Op_##x(IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) DEF_OP(TruncElementPair) { auto Op = IROp->C(); diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/AtomicOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/AtomicOps.cpp index d4126e8c8f..9ea7677ac3 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/AtomicOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/AtomicOps.cpp @@ -310,7 +310,7 @@ uint64_t AtomicCompareAndSwap(uint64_t expected, uint64_t desired, uint64_t *add #endif -#define DEF_OP(x) void InterpreterOps::Op_##x(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) +#define DEF_OP(x) void InterpreterOps::Op_##x(IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) DEF_OP(CASPair) { auto Op = IROp->C(); uint8_t OpSize = IROp->Size; diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/BranchOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/BranchOps.cpp index cdf657d5f8..d75c3cf846 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/BranchOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/BranchOps.cpp @@ -24,7 +24,7 @@ static void SignalReturn(FEXCore::Core::InternalThreadState *Thread) { FEX_UNREACHABLE; } -#define DEF_OP(x) void InterpreterOps::Op_##x(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) +#define DEF_OP(x) void InterpreterOps::Op_##x(IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) DEF_OP(GuestCallDirect) { LogMan::Msg::DFmt("Unimplemented"); } diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/ConversionOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/ConversionOps.cpp index 5a62d6bccd..6523fa1cd6 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/ConversionOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/ConversionOps.cpp @@ -11,7 +11,7 @@ tags: backend|interpreter #include namespace FEXCore::CPU { -#define DEF_OP(x) void InterpreterOps::Op_##x(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) +#define DEF_OP(x) void InterpreterOps::Op_##x(IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) DEF_OP(VInsGPR) { auto Op = IROp->C(); uint8_t OpSize = IROp->Size; diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/EncryptionOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/EncryptionOps.cpp index a8d72c47fa..c666906c71 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/EncryptionOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/EncryptionOps.cpp @@ -299,7 +299,7 @@ namespace AES { } namespace FEXCore::CPU { -#define DEF_OP(x) void InterpreterOps::Op_##x(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) +#define DEF_OP(x) void InterpreterOps::Op_##x(IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) DEF_OP(AESImc) { auto Op = IROp->C(); diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/F80Ops.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/F80Ops.cpp index 9370c596ae..ae77232153 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/F80Ops.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/F80Ops.cpp @@ -13,7 +13,7 @@ tags: backend|interpreter #include namespace FEXCore::CPU { -#define DEF_OP(x) void InterpreterOps::Op_##x(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) +#define DEF_OP(x) void InterpreterOps::Op_##x(IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) DEF_OP(F80LOADFCW) { FEXCore::CPU::OpHandlers::handle(*GetSrc(Data->SSAData, IROp->Args[0])); } diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/FlagOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/FlagOps.cpp index a331f920ac..45239d13f4 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/FlagOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/FlagOps.cpp @@ -11,7 +11,7 @@ tags: backend|interpreter #include namespace FEXCore::CPU { -#define DEF_OP(x) void InterpreterOps::Op_##x(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) +#define DEF_OP(x) void InterpreterOps::Op_##x(IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) DEF_OP(GetHostFlag) { auto Op = IROp->C(); GD = (*GetSrc(Data->SSAData, Op->Header.Args[0]) >> Op->Flag) & 1; diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterDefines.h b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterDefines.h index 7651e51f0f..3b0698abaa 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterDefines.h +++ b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterDefines.h @@ -166,7 +166,7 @@ Res GetDest(void* SSAData, FEXCore::IR::OrderedNodeWrapper Op) { } template -Res GetDest(void* SSAData, uint32_t Op) { +Res GetDest(void* SSAData, FEXCore::IR::NodeID Op) { auto DstPtr = &reinterpret_cast<__uint128_t*>(SSAData)[Op]; return reinterpret_cast(DstPtr); } diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterOps.cpp index 17d8c360bb..f0ca286ab8 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterOps.cpp @@ -35,11 +35,11 @@ namespace FEXCore::CPU { std::array InterpreterOps::OpHandlers; -void InterpreterOps::Op_Unhandled(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) { +void InterpreterOps::Op_Unhandled(FEXCore::IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) { LOGMAN_MSG_A_FMT("Unhandled IR Op: {}", FEXCore::IR::GetName(IROp->Op)); } -void InterpreterOps::Op_NoOp(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) { +void InterpreterOps::Op_NoOp(FEXCore::IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) { } template @@ -280,8 +280,8 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin auto CodeLast = CurrentIR->at(BlockIROp->Last); for (auto [CodeNode, IROp] : CurrentIR->GetCode(BlockNode)) { - uint32_t ID = CurrentIR->GetID(CodeNode); - uint32_t Op = IROp->Op; + const auto ID = CurrentIR->GetID(CodeNode); + const uint32_t Op = IROp->Op; // Execute handler OpHandler Handler = InterpreterOps::OpHandlers[Op]; diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterOps.h b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterOps.h index a8949d41e4..8e3c6aba3d 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterOps.h +++ b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterOps.h @@ -72,10 +72,10 @@ namespace FEXCore::CPU { IR::NodeIterator BlockIterator{0, 0}; }; - using OpHandler = std::function; - static std::array OpHandlers; + using OpHandler = std::function; + static std::array OpHandlers; -#define DEF_OP(x) static void Op_##x(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) +#define DEF_OP(x) static void Op_##x(IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) ///< Unhandled handler DEF_OP(Unhandled); diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/MemoryOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/MemoryOps.cpp index bd7c19221a..eb9bcf28e7 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/MemoryOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/MemoryOps.cpp @@ -22,7 +22,7 @@ static inline void CacheLineFlush(char *Addr) { #endif } -#define DEF_OP(x) void InterpreterOps::Op_##x(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) +#define DEF_OP(x) void InterpreterOps::Op_##x(IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) DEF_OP(LoadContext) { auto Op = IROp->C(); uint8_t OpSize = IROp->Size; diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/MiscOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/MiscOps.cpp index b1f7418a5f..62902da8e3 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/MiscOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/MiscOps.cpp @@ -22,7 +22,7 @@ static void StopThread(FEXCore::Core::InternalThreadState *Thread) { FEX_UNREACHABLE; } -#define DEF_OP(x) void InterpreterOps::Op_##x(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) +#define DEF_OP(x) void InterpreterOps::Op_##x(IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) DEF_OP(Fence) { auto Op = IROp->C(); switch (Op->Fence) { diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/MoveOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/MoveOps.cpp index 8be0e5bfac..fbf2c65eda 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/MoveOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/MoveOps.cpp @@ -11,7 +11,7 @@ tags: backend|interpreter #include namespace FEXCore::CPU { -#define DEF_OP(x) void InterpreterOps::Op_##x(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) +#define DEF_OP(x) void InterpreterOps::Op_##x(IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) DEF_OP(ExtractElementPair) { auto Op = IROp->C(); uintptr_t Src = GetSrc(Data->SSAData, Op->Header.Args[0]); diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp index 4f4158c048..0d28481fc2 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp @@ -11,7 +11,7 @@ tags: backend|interpreter #include namespace FEXCore::CPU { -#define DEF_OP(x) void InterpreterOps::Op_##x(FEXCore::IR::IROp_Header *IROp, IROpData *Data, uint32_t Node) +#define DEF_OP(x) void InterpreterOps::Op_##x(IR::IROp_Header *IROp, IROpData *Data, IR::NodeID Node) DEF_OP(VectorZero) { uint8_t OpSize = IROp->Size; memset(GDP, 0, OpSize); diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp index 4735bcc414..760ec0bc59 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp @@ -34,7 +34,7 @@ static int64_t LREM(int64_t SrcHigh, int64_t SrcLow, int64_t Divisor) { using namespace vixl; using namespace vixl::aarch64; -#define DEF_OP(x) void Arm64JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void Arm64JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(TruncElementPair) { auto Op = IROp->C(); diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/AtomicOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/AtomicOps.cpp index a78fd36b68..3eb2d66a83 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/AtomicOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/AtomicOps.cpp @@ -9,7 +9,7 @@ tags: backend|arm64 namespace FEXCore::CPU { using namespace vixl; using namespace vixl::aarch64; -#define DEF_OP(x) void Arm64JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void Arm64JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(CASPair) { auto Op = IROp->C(); uint8_t OpSize = IROp->Size; diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp index e15b2fdbf6..ff420dc810 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp @@ -17,7 +17,7 @@ tags: backend|arm64 namespace FEXCore::CPU { using namespace vixl; using namespace vixl::aarch64; -#define DEF_OP(x) void Arm64JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void Arm64JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(GuestCallDirect) { LogMan::Msg::DFmt("Unimplemented"); } diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/ConversionOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/ConversionOps.cpp index 1945f43386..33723f3ea9 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/ConversionOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/ConversionOps.cpp @@ -10,7 +10,7 @@ namespace FEXCore::CPU { using namespace vixl; using namespace vixl::aarch64; -#define DEF_OP(x) void Arm64JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void Arm64JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(VInsGPR) { auto Op = IROp->C(); mov(GetDst(Node), GetSrc(Op->Header.Args[0].ID())); diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/EncryptionOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/EncryptionOps.cpp index 0d4f44061f..35221c20ce 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/EncryptionOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/EncryptionOps.cpp @@ -10,7 +10,7 @@ tags: backend|arm64 namespace FEXCore::CPU { using namespace vixl; using namespace vixl::aarch64; -#define DEF_OP(x) void Arm64JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void Arm64JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(AESImc) { auto Op = IROp->C(); diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/FlagOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/FlagOps.cpp index 050b1ab02f..00bc94b8d8 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/FlagOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/FlagOps.cpp @@ -10,7 +10,7 @@ namespace FEXCore::CPU { using namespace vixl; using namespace vixl::aarch64; -#define DEF_OP(x) void Arm64JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void Arm64JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(GetHostFlag) { auto Op = IROp->C(); ubfx(GetReg(Node), GetReg(Op->Header.Args[0].ID()), Op->Flag, 1); diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp index d4a5848d05..8ab870fe78 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp @@ -42,7 +42,7 @@ void Arm64JITCore::CopyNecessaryDataForCompileThread(CPUBackend *Original) { using namespace vixl; using namespace vixl::aarch64; -void Arm64JITCore::Op_Unhandled(FEXCore::IR::IROp_Header *IROp, uint32_t Node) { +void Arm64JITCore::Op_Unhandled(IR::IROp_Header *IROp, IR::NodeID Node) { FallbackInfo Info; if (!InterpreterOps::GetFallbackHandler(IROp, &Info)) { #if defined(ASSERTIONS_ENABLED) && ASSERTIONS_ENABLED @@ -307,7 +307,7 @@ void Arm64JITCore::Op_Unhandled(FEXCore::IR::IROp_Header *IROp, uint32_t Node) { } } -void Arm64JITCore::Op_NoOp(FEXCore::IR::IROp_Header *IROp, uint32_t Node) { +void Arm64JITCore::Op_NoOp(IR::IROp_Header *IROp, IR::NodeID Node) { } Arm64JITCore::CodeBuffer Arm64JITCore::AllocateNewCodeBuffer(size_t Size) { @@ -484,7 +484,7 @@ Arm64JITCore::~Arm64JITCore() { FreeCodeBuffer(InitialCodeBuffer); } -IR::PhysicalRegister Arm64JITCore::GetPhys(uint32_t Node) const { +IR::PhysicalRegister Arm64JITCore::GetPhys(IR::NodeID Node) const { auto PhyReg = RAData->GetNodeRegister(Node); LOGMAN_THROW_A_FMT(!PhyReg.IsInvalid(), "Couldn't Allocate register for node: ssa{}. Class: {}", Node, PhyReg.Class); @@ -493,7 +493,7 @@ IR::PhysicalRegister Arm64JITCore::GetPhys(uint32_t Node) const { } template<> -aarch64::Register Arm64JITCore::GetReg(uint32_t Node) const { +aarch64::Register Arm64JITCore::GetReg(IR::NodeID Node) const { auto Reg = GetPhys(Node); if (Reg.Class == IR::GPRFixedClass.Val) { @@ -508,7 +508,7 @@ aarch64::Register Arm64JITCore::GetReg(uint32_t Node) const } template<> -aarch64::Register Arm64JITCore::GetReg(uint32_t Node) const { +aarch64::Register Arm64JITCore::GetReg(IR::NodeID Node) const { auto Reg = GetPhys(Node); if (Reg.Class == IR::GPRFixedClass.Val) { @@ -523,18 +523,18 @@ aarch64::Register Arm64JITCore::GetReg(uint32_t Node) const } template<> -std::pair Arm64JITCore::GetSrcPair(uint32_t Node) const { +std::pair Arm64JITCore::GetSrcPair(IR::NodeID Node) const { uint32_t Reg = GetPhys(Node).Reg; return RA32Pair[Reg]; } template<> -std::pair Arm64JITCore::GetSrcPair(uint32_t Node) const { +std::pair Arm64JITCore::GetSrcPair(IR::NodeID Node) const { uint32_t Reg = GetPhys(Node).Reg; return RA64Pair[Reg]; } -aarch64::VRegister Arm64JITCore::GetSrc(uint32_t Node) const { +aarch64::VRegister Arm64JITCore::GetSrc(IR::NodeID Node) const { auto Reg = GetPhys(Node); if (Reg.Class == IR::FPRFixedClass.Val) { @@ -548,7 +548,7 @@ aarch64::VRegister Arm64JITCore::GetSrc(uint32_t Node) const { FEX_UNREACHABLE; } -aarch64::VRegister Arm64JITCore::GetDst(uint32_t Node) const { +aarch64::VRegister Arm64JITCore::GetDst(IR::NodeID Node) const { auto Reg = GetPhys(Node); if (Reg.Class == IR::FPRFixedClass.Val) { @@ -590,18 +590,18 @@ bool Arm64JITCore::IsInlineEntrypointOffset(const IR::OrderedNodeWrapper& WNode, } } -FEXCore::IR::RegisterClassType Arm64JITCore::GetRegClass(uint32_t Node) const { +FEXCore::IR::RegisterClassType Arm64JITCore::GetRegClass(IR::NodeID Node) const { return FEXCore::IR::RegisterClassType {GetPhys(Node).Class}; } -bool Arm64JITCore::IsFPR(uint32_t Node) const { +bool Arm64JITCore::IsFPR(IR::NodeID Node) const { auto Class = GetRegClass(Node); return Class == IR::FPRClass || Class == IR::FPRFixedClass; } -bool Arm64JITCore::IsGPR(uint32_t Node) const { +bool Arm64JITCore::IsGPR(IR::NodeID Node) const { auto Class = GetRegClass(Node); return Class == IR::GPRClass || Class == IR::GPRFixedClass; @@ -697,7 +697,7 @@ void *Arm64JITCore::CompileCode(uint64_t Entry, [[maybe_unused]] FEXCore::IR::IR #endif { - uint32_t Node = IR->GetID(BlockNode); + const auto Node = IR->GetID(BlockNode); auto IsTarget = JumpTargets.find(Node); if (IsTarget == JumpTargets.end()) { IsTarget = JumpTargets.try_emplace(Node).first; @@ -718,7 +718,7 @@ void *Arm64JITCore::CompileCode(uint64_t Entry, [[maybe_unused]] FEXCore::IR::IR } for (auto [CodeNode, IROp] : IR->GetCode(BlockNode)) { - uint32_t ID = IR->GetID(CodeNode); + const auto ID = IR->GetID(CodeNode); // Execute handler OpHandler Handler = OpHandlers[IROp->Op]; diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h index 5aea0a3ec0..4e7a62b677 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h @@ -102,30 +102,30 @@ class Arm64JITCore final : public CPUBackend, public Arm64Emitter { constexpr static uint8_t RA_FPR = 2; template - [[nodiscard]] aarch64::Register GetReg(uint32_t Node) const; + [[nodiscard]] aarch64::Register GetReg(IR::NodeID Node) const; template<> - [[nodiscard]] aarch64::Register GetReg(uint32_t Node) const; + [[nodiscard]] aarch64::Register GetReg(IR::NodeID Node) const; template<> - [[nodiscard]] aarch64::Register GetReg(uint32_t Node) const; + [[nodiscard]] aarch64::Register GetReg(IR::NodeID Node) const; template - [[nodiscard]] std::pair GetSrcPair(uint32_t Node) const; + [[nodiscard]] std::pair GetSrcPair(IR::NodeID Node) const; template<> - [[nodiscard]] std::pair GetSrcPair(uint32_t Node) const; + [[nodiscard]] std::pair GetSrcPair(IR::NodeID Node) const; template<> - [[nodiscard]] std::pair GetSrcPair(uint32_t Node) const; + [[nodiscard]] std::pair GetSrcPair(IR::NodeID Node) const; - [[nodiscard]] aarch64::VRegister GetSrc(uint32_t Node) const; - [[nodiscard]] aarch64::VRegister GetDst(uint32_t Node) const; + [[nodiscard]] aarch64::VRegister GetSrc(IR::NodeID Node) const; + [[nodiscard]] aarch64::VRegister GetDst(IR::NodeID Node) const; - [[nodiscard]] FEXCore::IR::RegisterClassType GetRegClass(uint32_t Node) const; + [[nodiscard]] FEXCore::IR::RegisterClassType GetRegClass(IR::NodeID Node) const; - [[nodiscard]] IR::PhysicalRegister GetPhys(uint32_t Node) const; + [[nodiscard]] IR::PhysicalRegister GetPhys(IR::NodeID Node) const; - [[nodiscard]] bool IsFPR(uint32_t Node) const; - [[nodiscard]] bool IsGPR(uint32_t Node) const; + [[nodiscard]] bool IsFPR(IR::NodeID Node) const; + [[nodiscard]] bool IsGPR(IR::NodeID Node) const; [[nodiscard]] MemOperand GenerateMemOperand(uint8_t AccessSize, aarch64::Register Base, @@ -185,8 +185,8 @@ class Arm64JITCore final : public CPUBackend, public Arm64Emitter { IR::RegisterAllocationPass *RAPass; IR::RegisterAllocationData *RAData; - using OpHandler = void (Arm64JITCore::*)(FEXCore::IR::IROp_Header *IROp, uint32_t Node); - std::array OpHandlers {}; + using OpHandler = void (Arm64JITCore::*)(IR::IROp_Header *IROp, IR::NodeID Node); + std::array OpHandlers {}; void RegisterALUHandlers(); void RegisterAtomicHandlers(); void RegisterBranchHandlers(); @@ -197,7 +197,7 @@ class Arm64JITCore final : public CPUBackend, public Arm64Emitter { void RegisterMoveHandlers(); void RegisterVectorHandlers(); void RegisterEncryptionHandlers(); -#define DEF_OP(x) void Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) ///< Unhandled handler DEF_OP(Unhandled); diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/MemoryOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/MemoryOps.cpp index baf76ca636..125f09f45f 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/MemoryOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/MemoryOps.cpp @@ -11,7 +11,7 @@ namespace FEXCore::CPU { using namespace vixl; using namespace vixl::aarch64; -#define DEF_OP(x) void Arm64JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void Arm64JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(LoadContext) { auto Op = IROp->C(); diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/MiscOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/MiscOps.cpp index 55d6949f84..e70f6b7d95 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/MiscOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/MiscOps.cpp @@ -17,7 +17,7 @@ static void PrintVectorValue(uint64_t Value, uint64_t ValueUpper) { using namespace vixl; using namespace vixl::aarch64; -#define DEF_OP(x) void Arm64JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void Arm64JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(Fence) { auto Op = IROp->C(); diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/MoveOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/MoveOps.cpp index fed66091c4..9b578df9bd 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/MoveOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/MoveOps.cpp @@ -10,7 +10,7 @@ namespace FEXCore::CPU { using namespace vixl; using namespace vixl::aarch64; -#define DEF_OP(x) void Arm64JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void Arm64JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(ExtractElementPair) { auto Op = IROp->C(); switch (Op->Header.Size) { diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp index f0d8bd6616..8339a67e8a 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp @@ -10,7 +10,7 @@ namespace FEXCore::CPU { using namespace vixl; using namespace vixl::aarch64; -#define DEF_OP(x) void Arm64JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void Arm64JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(VectorZero) { uint8_t OpSize = IROp->Size; switch (OpSize) { diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/ALUOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/ALUOps.cpp index 8a09305177..5ff9c3db48 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/ALUOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/ALUOps.cpp @@ -20,7 +20,7 @@ namespace FEXCore::CPU { #define GRD(Node) (IROp->Size <= 4 ? GetDst(Node) : GetDst(Node)) #define GRCMP(Node) (Op->CompareSize == 4 ? GetSrc(Node) : GetSrc(Node)) -#define DEF_OP(x) void X86JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void X86JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(TruncElementPair) { auto Op = IROp->C(); diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/AtomicOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/AtomicOps.cpp index 4404441074..0f956f2702 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/AtomicOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/AtomicOps.cpp @@ -15,7 +15,7 @@ tags: backend|x86-64 #include namespace FEXCore::CPU { -#define DEF_OP(x) void X86JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void X86JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(CASPair) { auto Op = IROp->C(); uint8_t OpSize = IROp->Size; diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/BranchOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/BranchOps.cpp index 3832f29b5e..2694ea3d33 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/BranchOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/BranchOps.cpp @@ -28,7 +28,7 @@ tags: backend|x86-64 #include namespace FEXCore::CPU { -#define DEF_OP(x) void X86JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void X86JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(GuestCallDirect) { LogMan::Msg::DFmt("Unimplemented"); } diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/ConversionOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/ConversionOps.cpp index 586dbae6e1..50f82edd70 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/ConversionOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/ConversionOps.cpp @@ -15,7 +15,7 @@ tags: backend|x86-64 namespace FEXCore::CPU { -#define DEF_OP(x) void X86JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void X86JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(VInsGPR) { auto Op = IROp->C(); movapd(GetDst(Node), GetSrc(Op->Header.Args[0].ID())); diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/EncryptionOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/EncryptionOps.cpp index 8e1ca1684e..863f55433d 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/EncryptionOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/EncryptionOps.cpp @@ -13,7 +13,7 @@ tags: backend|x86-64 #include namespace FEXCore::CPU { -#define DEF_OP(x) void X86JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void X86JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(AESImc) { auto Op = IROp->C(); diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/FlagOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/FlagOps.cpp index 1a44a9c77a..5e59d8a0d3 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/FlagOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/FlagOps.cpp @@ -14,7 +14,7 @@ tags: backend|x86-64 namespace FEXCore::CPU { -#define DEF_OP(x) void X86JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void X86JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(GetHostFlag) { auto Op = IROp->C(); diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp index bfca38f088..6bde4bf350 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp @@ -98,7 +98,7 @@ void X86JITCore::PopRegs() { add(rsp, 16 * RAXMM_x.size()); } -void X86JITCore::Op_Unhandled(FEXCore::IR::IROp_Header *IROp, uint32_t Node) { +void X86JITCore::Op_Unhandled(IR::IROp_Header *IROp, IR::NodeID Node) { FallbackInfo Info; if (!InterpreterOps::GetFallbackHandler(IROp, &Info)) { #if defined(ASSERTIONS_ENABLED) && ASSERTIONS_ENABLED @@ -308,7 +308,7 @@ void X86JITCore::Op_Unhandled(FEXCore::IR::IROp_Header *IROp, uint32_t Node) { } } -void X86JITCore::Op_NoOp(FEXCore::IR::IROp_Header *IROp, uint32_t Node) { +void X86JITCore::Op_NoOp(IR::IROp_Header *IROp, IR::NodeID Node) { } X86JITCore::X86JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread, CodeBuffer Buffer, bool CompileThread) @@ -433,7 +433,7 @@ void X86JITCore::ClearCache() { } } -IR::PhysicalRegister X86JITCore::GetPhys(uint32_t Node) const { +IR::PhysicalRegister X86JITCore::GetPhys(IR::NodeID Node) const { auto PhyReg = RAData->GetNodeRegister(Node); LOGMAN_THROW_A_FMT(PhyReg.Raw != 255, "Couldn't Allocate register for node: ssa{}. Class: {}", Node, PhyReg.Class); @@ -441,16 +441,16 @@ IR::PhysicalRegister X86JITCore::GetPhys(uint32_t Node) const { return PhyReg; } -bool X86JITCore::IsFPR(uint32_t Node) const { +bool X86JITCore::IsFPR(IR::NodeID Node) const { return RAData->GetNodeRegister(Node).Class == IR::FPRClass.Val; } -bool X86JITCore::IsGPR(uint32_t Node) const { +bool X86JITCore::IsGPR(IR::NodeID Node) const { return RAData->GetNodeRegister(Node).Class == IR::GPRClass.Val; } template -Xbyak::Reg X86JITCore::GetSrc(uint32_t Node) const { +Xbyak::Reg X86JITCore::GetSrc(IR::NodeID Node) const { // rax, rcx, rdx, rsi, r8, r9, // r10 // Callee Saved @@ -469,24 +469,24 @@ Xbyak::Reg X86JITCore::GetSrc(uint32_t Node) const { } template -Xbyak::Reg X86JITCore::GetSrc(uint32_t Node) const; +Xbyak::Reg X86JITCore::GetSrc(IR::NodeID Node) const; template -Xbyak::Reg X86JITCore::GetSrc(uint32_t Node) const; +Xbyak::Reg X86JITCore::GetSrc(IR::NodeID Node) const; template -Xbyak::Reg X86JITCore::GetSrc(uint32_t Node) const; +Xbyak::Reg X86JITCore::GetSrc(IR::NodeID Node) const; template -Xbyak::Reg X86JITCore::GetSrc(uint32_t Node) const; +Xbyak::Reg X86JITCore::GetSrc(IR::NodeID Node) const; -Xbyak::Xmm X86JITCore::GetSrc(uint32_t Node) const { +Xbyak::Xmm X86JITCore::GetSrc(IR::NodeID Node) const { auto PhyReg = GetPhys(Node); return RAXMM_x[PhyReg.Reg]; } template -Xbyak::Reg X86JITCore::GetDst(uint32_t Node) const { +Xbyak::Reg X86JITCore::GetDst(IR::NodeID Node) const { auto PhyReg = GetPhys(Node); if constexpr (RAType == RA_64) return RA64[PhyReg.Reg].cvt64(); @@ -501,19 +501,19 @@ Xbyak::Reg X86JITCore::GetDst(uint32_t Node) const { } template -Xbyak::Reg X86JITCore::GetDst(uint32_t Node) const; +Xbyak::Reg X86JITCore::GetDst(IR::NodeID Node) const; template -Xbyak::Reg X86JITCore::GetDst(uint32_t Node) const; +Xbyak::Reg X86JITCore::GetDst(IR::NodeID Node) const; template -Xbyak::Reg X86JITCore::GetDst(uint32_t Node) const; +Xbyak::Reg X86JITCore::GetDst(IR::NodeID Node) const; template -Xbyak::Reg X86JITCore::GetDst(uint32_t Node) const; +Xbyak::Reg X86JITCore::GetDst(IR::NodeID Node) const; template -std::pair X86JITCore::GetSrcPair(uint32_t Node) const { +std::pair X86JITCore::GetSrcPair(IR::NodeID Node) const { auto PhyReg = GetPhys(Node); if constexpr (RAType == RA_64) return RA64Pair[PhyReg.Reg]; @@ -522,12 +522,12 @@ std::pair X86JITCore::GetSrcPair(uint32_t Node) const { } template -std::pair X86JITCore::GetSrcPair(uint32_t Node) const; +std::pair X86JITCore::GetSrcPair(IR::NodeID Node) const; template -std::pair X86JITCore::GetSrcPair(uint32_t Node) const; +std::pair X86JITCore::GetSrcPair(IR::NodeID Node) const; -Xbyak::Xmm X86JITCore::GetDst(uint32_t Node) const { +Xbyak::Xmm X86JITCore::GetDst(IR::NodeID Node) const { auto PhyReg = GetPhys(Node); return RAXMM_x[PhyReg.Reg]; } @@ -689,7 +689,7 @@ void *X86JITCore::CompileCode(uint64_t Entry, [[maybe_unused]] FEXCore::IR::IRLi LOGMAN_THROW_A_FMT(BlockIROp->Header.Op == IR::OP_CODEBLOCK, "IR type failed to be a code block"); #endif - uint32_t Node = IR->GetID(BlockNode); + const auto Node = IR->GetID(BlockNode); auto IsTarget = JumpTargets.find(Node); if (IsTarget == JumpTargets.end()) { IsTarget = JumpTargets.try_emplace(Node).first; @@ -726,10 +726,10 @@ void *X86JITCore::CompileCode(uint64_t Entry, [[maybe_unused]] FEXCore::IR::IRLi Inst << "\t" << Name << " "; } - uint8_t NumArgs = IR::GetArgs(IROp->Op); + const uint8_t NumArgs = IR::GetArgs(IROp->Op); for (uint8_t i = 0; i < NumArgs; ++i) { - uint32_t ArgNode = IROp->Args[i].ID(); - uint64_t PhysReg = RAPass->GetNodeRegister(ArgNode); + const auto ArgNode = IROp->Args[i].ID(); + const uint64_t PhysReg = RAPass->GetNodeRegister(ArgNode); if (PhysReg >= GPRPairBase) Inst << "Pair" << GetPhys(ArgNode) << (i + 1 == NumArgs ? "" : ", "); else if (PhysReg >= XMMBase) @@ -741,7 +741,7 @@ void *X86JITCore::CompileCode(uint64_t Entry, [[maybe_unused]] FEXCore::IR::IRLi LogMan::Msg::DFmt("{}", Inst.str()); } #endif - uint32_t ID = IR->GetID(CodeNode); + const auto ID = IR->GetID(CodeNode); // Execute handler OpHandler Handler = OpHandlers[IROp->Op]; diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h index 4ba11d676f..d1bc794ada 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h @@ -117,21 +117,21 @@ class X86JITCore final : public CPUBackend, public Xbyak::CodeGenerator { constexpr static uint8_t RA_64 = 3; constexpr static uint8_t RA_XMM = 4; - [[nodiscard]] IR::PhysicalRegister GetPhys(uint32_t Node) const; + [[nodiscard]] IR::PhysicalRegister GetPhys(IR::NodeID Node) const; - [[nodiscard]] bool IsFPR(uint32_t Node) const; - [[nodiscard]] bool IsGPR(uint32_t Node) const; + [[nodiscard]] bool IsFPR(IR::NodeID Node) const; + [[nodiscard]] bool IsGPR(IR::NodeID Node) const; template - [[nodiscard]] Xbyak::Reg GetSrc(uint32_t Node) const; + [[nodiscard]] Xbyak::Reg GetSrc(IR::NodeID Node) const; template - [[nodiscard]] std::pair GetSrcPair(uint32_t Node) const; + [[nodiscard]] std::pair GetSrcPair(IR::NodeID Node) const; template - [[nodiscard]] Xbyak::Reg GetDst(uint32_t Node) const; + [[nodiscard]] Xbyak::Reg GetDst(IR::NodeID Node) const; - [[nodiscard]] Xbyak::Xmm GetSrc(uint32_t Node) const; - [[nodiscard]] Xbyak::Xmm GetDst(uint32_t Node) const; + [[nodiscard]] Xbyak::Xmm GetSrc(IR::NodeID Node) const; + [[nodiscard]] Xbyak::Xmm GetDst(IR::NodeID Node) const; [[nodiscard]] Xbyak::RegExp GenerateModRM(Xbyak::Reg Base, IR::OrderedNodeWrapper Offset, IR::MemOffsetType OffsetType, uint8_t OffsetScale) const; @@ -182,8 +182,8 @@ class X86JITCore final : public CPUBackend, public Xbyak::CodeGenerator { std::tuple GetCC(IR::CondClassType cond); - using OpHandler = void (X86JITCore::*)(FEXCore::IR::IROp_Header *IROp, uint32_t Node); - std::array OpHandlers {}; + using OpHandler = void (X86JITCore::*)(IR::IROp_Header *IROp, IR::NodeID Node); + std::array OpHandlers {}; void RegisterALUHandlers(); void RegisterAtomicHandlers(); void RegisterBranchHandlers(); @@ -197,7 +197,7 @@ class X86JITCore final : public CPUBackend, public Xbyak::CodeGenerator { void PushRegs(); void PopRegs(); -#define DEF_OP(x) void Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) ///< Unhandled handler DEF_OP(Unhandled); diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/MemoryOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/MemoryOps.cpp index 1633a88691..52e9bc8f55 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/MemoryOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/MemoryOps.cpp @@ -17,7 +17,7 @@ tags: backend|x86-64 namespace FEXCore::CPU { -#define DEF_OP(x) void X86JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void X86JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(LoadContext) { auto Op = IROp->C(); diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/MiscOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/MiscOps.cpp index b7196bc4b8..739e0cade1 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/MiscOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/MiscOps.cpp @@ -26,7 +26,7 @@ static void PrintVectorValue(uint64_t Value, uint64_t ValueUpper) { LogMan::Msg::DFmt("Value: 0x{:016x}'{:016x}", ValueUpper, Value); } -#define DEF_OP(x) void X86JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void X86JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(Fence) { auto Op = IROp->C(); diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/MoveOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/MoveOps.cpp index 9fbf8496fd..e4427af14f 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/MoveOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/MoveOps.cpp @@ -15,7 +15,7 @@ tags: backend|x86-64 namespace FEXCore::CPU { -#define DEF_OP(x) void X86JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void X86JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(ExtractElementPair) { auto Op = IROp->C(); switch (Op->Header.Size) { diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp index 71b74e6faa..f4c922b26c 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp @@ -16,7 +16,7 @@ tags: backend|x86-64 namespace FEXCore::CPU { -#define DEF_OP(x) void X86JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node) +#define DEF_OP(x) void X86JITCore::Op_##x(IR::IROp_Header *IROp, IR::NodeID Node) DEF_OP(VectorZero) { auto Dst = GetDst(Node); vpxor(Dst, Dst, Dst); diff --git a/External/FEXCore/include/FEXCore/IR/IR.h b/External/FEXCore/include/FEXCore/IR/IR.h index 278898e1a1..14a72799c7 100644 --- a/External/FEXCore/include/FEXCore/IR/IR.h +++ b/External/FEXCore/include/FEXCore/IR/IR.h @@ -11,6 +11,7 @@ #include namespace FEXCore::IR { +class OrderedNode; class RegisterAllocationPass; class RegisterAllocationData; @@ -22,7 +23,11 @@ class RegisterAllocationData; */ struct IROp_Header; -class OrderedNode; +/** + * @brief Represents the ID of a given IR node. + */ +using NodeID = uint32_t; + /** * @brief This is a very simple wrapper for our node pointers * You probably don't want to use this directly @@ -64,7 +69,7 @@ struct NodeWrapperBase final { return Node.GetNode(Base); } - uint32_t ID() const; + NodeID ID() const; bool IsInvalid() const { return NodeOffset == 0; } @@ -399,7 +404,7 @@ class NodeIterator { return { RealNode, RealNode->Op(IRList) }; } - uint32_t ID() const { + NodeID ID() const { return Node.ID(); } @@ -483,6 +488,6 @@ FEX_DEFAULT_VISIBILITY void Dump(std::stringstream *out, IRListView const* IR, I FEX_DEFAULT_VISIBILITY std::unique_ptr Parse(std::istream *in); template -inline uint32_t NodeWrapperBase::ID() const { return NodeOffset / sizeof(IR::OrderedNode); } +inline NodeID NodeWrapperBase::ID() const { return NodeOffset / sizeof(IR::OrderedNode); } }; diff --git a/External/FEXCore/include/FEXCore/IR/IntrusiveIRList.h b/External/FEXCore/include/FEXCore/IR/IntrusiveIRList.h index 644880d6af..8f12c4647c 100644 --- a/External/FEXCore/include/FEXCore/IR/IntrusiveIRList.h +++ b/External/FEXCore/include/FEXCore/IR/IntrusiveIRList.h @@ -176,7 +176,7 @@ class IRListView final { bool IsShared() const { return Flags & FLAG_Shared; } void SetShared(bool Set) { if (Set) Flags |= FLAG_Shared; else Flags &= ~FLAG_Shared; } - uint32_t GetID(OrderedNode *Node) const { + NodeID GetID(OrderedNode *Node) const { return Node->Wrapped(GetListData()).ID(); } diff --git a/External/FEXCore/include/FEXCore/IR/RegisterAllocationData.h b/External/FEXCore/include/FEXCore/IR/RegisterAllocationData.h index 98e944648f..bbe66c82a7 100644 --- a/External/FEXCore/include/FEXCore/IR/RegisterAllocationData.h +++ b/External/FEXCore/include/FEXCore/IR/RegisterAllocationData.h @@ -35,7 +35,7 @@ class RegisterAllocationData { bool IsShared {false}; PhysicalRegister Map[0]; - PhysicalRegister GetNodeRegister(uint32_t Node) const { + PhysicalRegister GetNodeRegister(NodeID Node) const { return Map[Node]; } uint32_t SpillSlots() const { return SpillSlotCount; } From 0c697af5fb1f0820a6dae05326791a43fc9149e1 Mon Sep 17 00:00:00 2001 From: lioncash Date: Wed, 24 Nov 2021 16:17:15 -0500 Subject: [PATCH 2/2] Passes: Make use of NodeID alias where applicable Unifies the passes so that they're using the NodeID alias as well. --- .../FEXCore/Source/Interface/IR/IRDumper.cpp | 4 +- .../IR/Passes/DeadContextStoreElimination.cpp | 2 +- .../Interface/IR/Passes/IRCompaction.cpp | 6 +- .../Interface/IR/Passes/IRValidation.cpp | 9 +- .../Source/Interface/IR/Passes/IRValidation.h | 2 +- .../Interface/IR/Passes/RAValidation.cpp | 44 +++---- .../IR/Passes/RegisterAllocationPass.cpp | 124 ++++++++++-------- .../IR/Passes/ValueDominanceValidation.cpp | 6 +- 8 files changed, 101 insertions(+), 96 deletions(-) diff --git a/External/FEXCore/Source/Interface/IR/IRDumper.cpp b/External/FEXCore/Source/Interface/IR/IRDumper.cpp index 34a1a49927..3607dbf4ec 100644 --- a/External/FEXCore/Source/Interface/IR/IRDumper.cpp +++ b/External/FEXCore/Source/Interface/IR/IRDumper.cpp @@ -199,9 +199,9 @@ void Dump(std::stringstream *out, IRListView const* IR, IR::RegisterAllocationDa ++CurrentIndent; for (auto [CodeNode, IROp] : IR->GetCode(BlockNode)) { - uint32_t ID = IR->GetID(CodeNode); + const auto ID = IR->GetID(CodeNode); + const auto Name = FEXCore::IR::GetName(IROp->Op); - auto Name = FEXCore::IR::GetName(IROp->Op); bool Skip{}; switch (IROp->Op) { case IR::OP_PHIVALUE: diff --git a/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp b/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp index 30cf283d31..c99509642d 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp +++ b/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp @@ -337,7 +337,7 @@ class RCLSE final : public FEXCore::IR::Pass { std::unique_ptr DCE; ContextInfo ClassifiedStruct; - std::unordered_map OffsetToBlockMap; + std::unordered_map OffsetToBlockMap; ContextMemberInfo *FindMemberInfo(ContextInfo *ClassifiedInfo, uint32_t Offset, uint8_t Size); ContextMemberInfo *RecordAccess(ContextMemberInfo *Info, FEXCore::IR::RegisterClassType RegClass, uint32_t Offset, uint8_t Size, LastAccessType AccessType, FEXCore::IR::OrderedNode *Node, FEXCore::IR::OrderedNode *StoreNode = nullptr); diff --git a/External/FEXCore/Source/Interface/IR/Passes/IRCompaction.cpp b/External/FEXCore/Source/Interface/IR/Passes/IRCompaction.cpp index 956d6afc89..64b234e1fc 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/IRCompaction.cpp +++ b/External/FEXCore/Source/Interface/IR/Passes/IRCompaction.cpp @@ -24,7 +24,7 @@ namespace FEXCore::IR { // struct to avoid zero-initialization struct RemapNode { - IR::OrderedNodeWrapper::NodeOffsetType NodeID; + IR::NodeID NodeID; }; static_assert(sizeof(RemapNode) == 4); @@ -172,9 +172,9 @@ bool IRCompaction::Run(IREmitter *IREmit) { // Now that we have the op copied over, we need to modify SSA values to point to the new correct locations // This doesn't use IR::GetArgs(Op) because we need to remap all SSA nodes // Including ones that we don't RA - uint8_t NumArgs = LocalIROp->NumArgs; + const uint8_t NumArgs = LocalIROp->NumArgs; for (uint8_t i = 0; i < NumArgs; ++i) { - uint32_t OldArg = LocalIROp->Args[i].ID(); + const auto OldArg = LocalIROp->Args[i].ID(); #ifndef NDEBUG LOGMAN_THROW_A_FMT(OldToNewRemap[OldArg].NodeID != ~0U, "Tried remapping unfound node %ssa{}", OldArg); #endif diff --git a/External/FEXCore/Source/Interface/IR/Passes/IRValidation.cpp b/External/FEXCore/Source/Interface/IR/Passes/IRValidation.cpp index 8b45f015b0..d295ab6a1c 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/IRValidation.cpp +++ b/External/FEXCore/Source/Interface/IR/Passes/IRValidation.cpp @@ -69,15 +69,12 @@ bool IRValidation::Run(IREmitter *IREmit) { EntryBlock = BlockNode; } - uint32_t BlockID = CurrentIR.GetID(BlockNode); - + const auto BlockID = CurrentIR.GetID(BlockNode); BlockInfo *CurrentBlock = &OffsetToBlockMap.try_emplace(BlockID).first->second; - for (auto [CodeNode, IROp] : CurrentIR.GetCode(BlockNode)) { - uint32_t ID = CurrentIR.GetID(CodeNode); - - uint8_t OpSize = IROp->Size; + const auto ID = CurrentIR.GetID(CodeNode); + const uint8_t OpSize = IROp->Size; if (IROp->HasDest) { HadError |= OpSize == 0; diff --git a/External/FEXCore/Source/Interface/IR/Passes/IRValidation.h b/External/FEXCore/Source/Interface/IR/Passes/IRValidation.h index 7c3ee4d0ed..118b6a8696 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/IRValidation.h +++ b/External/FEXCore/Source/Interface/IR/Passes/IRValidation.h @@ -24,7 +24,7 @@ class IRValidation final : public FEXCore::IR::Pass { BitSet NodeIsLive; OrderedNode *EntryBlock; - std::unordered_map OffsetToBlockMap; + std::unordered_map OffsetToBlockMap; size_t MaxNodes{}; friend class RAValidation; diff --git a/External/FEXCore/Source/Interface/IR/Passes/RAValidation.cpp b/External/FEXCore/Source/Interface/IR/Passes/RAValidation.cpp index 5e1406e707..195623b747 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/RAValidation.cpp +++ b/External/FEXCore/Source/Interface/IR/Passes/RAValidation.cpp @@ -31,7 +31,7 @@ struct RegState { // These assumptions were all true for the state of the arm64 and x86 jits at the time this was written // Mark a physical register as containing a SSA id - bool Set(PhysicalRegister Reg, uint32_t ssa) { + bool Set(PhysicalRegister Reg, IR::NodeID ssa) { LOGMAN_THROW_A_FMT(ssa != 0, "RegState assumes ssa0 will be the block header and never assigned to a register"); // PhyscialRegisters aren't fully mapped until assembly emission @@ -96,12 +96,12 @@ struct RegState { // Mark a spill slot as containing a SSA id - void Spill(uint32_t SpillSlot, uint32_t ssa) { + void Spill(uint32_t SpillSlot, IR::NodeID ssa) { Spills[SpillSlot] = ssa; } // Consume (and return) the SSA id currently in a spill slot - uint32_t Unspill(uint32_t SpillSlot) { + IR::NodeID Unspill(uint32_t SpillSlot) { if (Spills.contains(SpillSlot)) { uint32_t Value = Spills[SpillSlot]; Spills.erase(SpillSlot); @@ -165,10 +165,10 @@ struct RegState { } private: - std::array GPRs = {}; - std::array FPRs = {}; + std::array GPRs = {}; + std::array FPRs = {}; - std::unordered_map Spills; + std::unordered_map Spills; public: uint32_t Version{}; // Used to force regeneration of RegStates after following backward edges @@ -181,7 +181,7 @@ class RAValidation final : public FEXCore::IR::Pass { private: // Holds the calculated RegState at the exit of each block - std::unordered_map BlockExitState; + std::unordered_map BlockExitState; // A queue of blocks we need to visit (or revisit) std::deque BlocksToVisit; @@ -213,10 +213,10 @@ bool RAValidation::Run(IREmitter *IREmit) { while (!BlocksToVisit.empty()) { auto BlockNode = BlocksToVisit.front(); - uint32_t BlockID = CurrentIR.GetID(BlockNode); + const auto BlockID = CurrentIR.GetID(BlockNode); auto& BlockInfo = OffsetToBlockMap[BlockID]; - auto IsFowardsEdge = [&] (uint32_t PredecessorID) { + const auto IsFowardsEdge = [&](IR::NodeID PredecessorID) { // Blocks are sorted in FEXes IR, so backwards edges always go to a lower (or equal) Block ID return PredecessorID < BlockID; }; @@ -226,8 +226,8 @@ bool RAValidation::Run(IREmitter *IREmit) { bool MissingPredecessor = false; for (auto Predecessor : BlockInfo.Predecessors) { - auto PredecessorID = CurrentIR.GetID(Predecessor); - bool HaveState = BlockExitState.contains(PredecessorID) && BlockExitState[PredecessorID].Version == CurrentVersion; + const auto PredecessorID = CurrentIR.GetID(Predecessor); + const bool HaveState = BlockExitState.contains(PredecessorID) && BlockExitState[PredecessorID].Version == CurrentVersion; if (IsFowardsEdge(PredecessorID) && !HaveState) { // We are probably about to visit this node anyway, remove it @@ -252,7 +252,7 @@ bool RAValidation::Run(IREmitter *IREmit) { // Second, we need to determine the register status as of Block entry auto BlockOp = CurrentIR.GetOp(BlockNode); - uint32_t FirstSSA = BlockOp->Begin.ID(); + const auto FirstSSA = BlockOp->Begin.ID(); auto& BlockRegState = BlockExitState.try_emplace(BlockID).first->second; bool EmptyRegState = true; @@ -281,9 +281,9 @@ bool RAValidation::Run(IREmitter *IREmit) { // Thrid, we need to iterate over all IR ops in the block for (auto [CodeNode, IROp] : CurrentIR.GetCode(BlockNode)) { - uint32_t ID = CurrentIR.GetID(CodeNode); + const auto ID = CurrentIR.GetID(CodeNode); - auto CheckArg = [&] (uint32_t i, OrderedNodeWrapper Arg) { + const auto CheckArg = [&](uint32_t i, OrderedNodeWrapper Arg) { const auto PhyReg = RAData->GetNodeRegister(Arg.ID()); if (PhyReg.IsInvalid()) @@ -330,8 +330,8 @@ bool RAValidation::Run(IREmitter *IREmit) { case OP_FILLREGISTER: { auto FillRegister = IROp->C(); - uint32_t ExpectedValue = FillRegister->OriginalValue.ID(); - uint32_t Value = BlockRegState.Unspill(FillRegister->Slot); + const auto ExpectedValue = FillRegister->OriginalValue.ID(); + const auto Value = BlockRegState.Unspill(FillRegister->Slot); // TODO: This only proves that the Spill has a consistent SSA value // In the future we need to prove it contains the correct SSA value @@ -400,14 +400,14 @@ bool RAValidation::Run(IREmitter *IREmit) { HadError |= true; for (auto [BlockNode, BlockHeader] : CurrentIR.GetBlocks()) { - uint32_t BlockID = CurrentIR.GetID(BlockNode); - auto& BlockInfo = OffsetToBlockMap[BlockID]; + const auto BlockID = CurrentIR.GetID(BlockNode); + const auto& BlockInfo = OffsetToBlockMap[BlockID]; Errors << fmt::format("Block {}\n\tPredecessors: ", BlockID); for (auto Predecessor : BlockInfo.Predecessors) { - auto PredecessorID = CurrentIR.GetID(Predecessor); - bool FowardsEdge = PredecessorID < BlockID; + const auto PredecessorID = CurrentIR.GetID(Predecessor); + const bool FowardsEdge = PredecessorID < BlockID; if (!FowardsEdge) { Errors << "(Backwards): "; } @@ -417,8 +417,8 @@ bool RAValidation::Run(IREmitter *IREmit) { Errors << "\n\tSuccessors: "; for (auto Successor : BlockInfo.Successors) { - auto SuccessorID = CurrentIR.GetID(Successor); - bool FowardsEdge = SuccessorID > BlockID; + const auto SuccessorID = CurrentIR.GetID(Successor); + const bool FowardsEdge = SuccessorID > BlockID; if (!FowardsEdge) { Errors << "(Backwards): "; diff --git a/External/FEXCore/Source/Interface/IR/Passes/RegisterAllocationPass.cpp b/External/FEXCore/Source/Interface/IR/Passes/RegisterAllocationPass.cpp index cdb713a77e..cc5874353b 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/RegisterAllocationPass.cpp +++ b/External/FEXCore/Source/Interface/IR/Passes/RegisterAllocationPass.cpp @@ -29,9 +29,8 @@ tags: ir|opts #define SRA_DEBUG(...) // fmt::print(__VA_ARGS__) +namespace FEXCore::IR { namespace { - using FEXCore::IR::PhysicalRegister; - constexpr uint32_t INVALID_REG = FEXCore::IR::InvalidReg; constexpr uint32_t INVALID_CLASS = FEXCore::IR::InvalidClass.Val; @@ -51,12 +50,12 @@ namespace { struct RegisterNode { struct VolatileHeader { - uint32_t BlockID; + IR::NodeID BlockID; uint32_t SpillSlot; RegisterNode *PhiPartner; } Head { ~0U, ~0U, nullptr }; - FEXCore::BucketList Interferences; + FEXCore::BucketList Interferences; }; static_assert(sizeof(RegisterNode) == 128 * 4); @@ -79,20 +78,20 @@ namespace { }; struct SpillStackUnit { - uint32_t Node; - FEXCore::IR::RegisterClassType Class; + IR::NodeID Node; + IR::RegisterClassType Class; LiveRange SpillRange; - FEXCore::IR::OrderedNode *SpilledNode; + IR::OrderedNode *SpilledNode; }; struct RegisterGraph { - std::unique_ptr AllocData; + std::unique_ptr AllocData; RegisterSet Set; std::vector Nodes{}; uint32_t NodeCount{}; std::vector SpillStack; - std::unordered_map> BlockPredecessors; - std::unordered_map> VisitedNodePredecessors; + std::unordered_map> BlockPredecessors; + std::unordered_map> VisitedNodePredecessors; }; void ResetRegisterGraph(RegisterGraph *Graph, uint64_t NodeCount); @@ -157,11 +156,11 @@ namespace { Graph->NodeCount = NodeCount; } - void SetNodeClass(RegisterGraph *Graph, uint32_t Node, FEXCore::IR::RegisterClassType Class) { + void SetNodeClass(RegisterGraph *Graph, IR::NodeID Node, FEXCore::IR::RegisterClassType Class) { Graph->AllocData->Map[Node].Class = Class.Val; } - void SetNodePartner(RegisterGraph *Graph, uint32_t Node, uint32_t Partner) { + void SetNodePartner(RegisterGraph *Graph, IR::NodeID Node, IR::NodeID Partner) { Graph->Nodes[Node].Head.PhiPartner = &Graph->Nodes[Partner]; } @@ -178,7 +177,7 @@ namespace { */ bool DoesNodeInterfereWithRegister(RegisterGraph *Graph, RegisterNode const *Node, PhysicalRegister RegAndClass) { // Walk the node's interference list and see if it interferes with this register - return Node->Interferences.Find([Graph, RegAndClass](uint32_t InterferenceNodeId) { + return Node->Interferences.Find([Graph, RegAndClass](IR::NodeID InterferenceNodeId) { auto InterferenceRegAndClass = Graph->AllocData->Map[InterferenceNodeId]; return IsConflict(Graph, InterferenceRegAndClass, RegAndClass); }); @@ -262,9 +261,8 @@ namespace { } } } -} +} // Anonymous namespace -namespace FEXCore::IR { class ConstrainedRAPass final : public RegisterAllocationPass { public: ConstrainedRAPass(FEXCore::IR::Pass* _CompactionPass, bool OptimizeSRA); @@ -301,9 +299,9 @@ namespace FEXCore::IR { std::vector LiveRanges; - using BlockInterferences = std::vector; + using BlockInterferences = std::vector; - std::unordered_map LocalBlockInterferences; + std::unordered_map LocalBlockInterferences; BlockInterferences GlobalBlockInterferences; void CalculateLiveRange(FEXCore::IR::IRListView *IR); @@ -313,13 +311,17 @@ namespace FEXCore::IR { void CalculateNodeInterference(FEXCore::IR::IRListView *IR); void AllocateVirtualRegisters(); void CalculatePredecessors(FEXCore::IR::IRListView *IR); - void RecursiveLiveRangeExpansion(FEXCore::IR::IRListView *IR, uint32_t Node, uint32_t DefiningBlockID, LiveRange *LiveRange, const std::unordered_set &Predecessors, std::unordered_set &VisitedPredecessors); + void RecursiveLiveRangeExpansion(FEXCore::IR::IRListView *IR, + IR::NodeID Node, IR::NodeID DefiningBlockID, + LiveRange *LiveRange, + const std::unordered_set &Predecessors, + std::unordered_set &VisitedPredecessors); FEXCore::IR::AllNodesIterator FindFirstUse(FEXCore::IR::IREmitter *IREmit, FEXCore::IR::OrderedNode* Node, FEXCore::IR::AllNodesIterator Begin, FEXCore::IR::AllNodesIterator End); FEXCore::IR::AllNodesIterator FindLastUseBefore(FEXCore::IR::IREmitter *IREmit, FEXCore::IR::OrderedNode* Node, FEXCore::IR::AllNodesIterator Begin, FEXCore::IR::AllNodesIterator End); - uint32_t FindNodeToSpill(IREmitter *IREmit, RegisterNode *RegisterNode, uint32_t CurrentLocation, LiveRange const *OpLiveRange, int32_t RematCost = -1); - uint32_t FindSpillSlot(uint32_t Node, FEXCore::IR::RegisterClassType RegisterClass); + IR::NodeID FindNodeToSpill(IREmitter *IREmit, RegisterNode *RegisterNode, uint32_t CurrentLocation, LiveRange const *OpLiveRange, int32_t RematCost = -1); + uint32_t FindSpillSlot(IR::NodeID Node, FEXCore::IR::RegisterClassType RegisterClass); bool RunAllocateVirtualRegisters(IREmitter *IREmit); }; @@ -364,7 +366,11 @@ namespace FEXCore::IR { return std::move(Graph->AllocData); } - void ConstrainedRAPass::RecursiveLiveRangeExpansion(FEXCore::IR::IRListView *IR, uint32_t Node, uint32_t DefiningBlockID, LiveRange *LiveRange, const std::unordered_set &Predecessors, std::unordered_set &VisitedPredecessors) { + void ConstrainedRAPass::RecursiveLiveRangeExpansion(IR::IRListView *IR, + IR::NodeID Node, IR::NodeID DefiningBlockID, + LiveRange *LiveRange, + const std::unordered_set &Predecessors, + std::unordered_set &VisitedPredecessors) { for (auto PredecessorId: Predecessors) { if (DefiningBlockID != PredecessorId && !VisitedPredecessors.contains(PredecessorId)) { // do the magic @@ -396,9 +402,9 @@ namespace FEXCore::IR { constexpr uint32_t DEFAULT_REMAT_COST = 1000; for (auto [BlockNode, BlockHeader] : IR->GetBlocks()) { - uint32_t BlockNodeID = IR->GetID(BlockNode); + const auto BlockNodeID = IR->GetID(BlockNode); for (auto [CodeNode, IROp] : IR->GetCode(BlockNode)) { - uint32_t Node = IR->GetID(CodeNode); + const auto Node = IR->GetID(CodeNode); // If the destination hasn't yet been set then set it now if (IROp->HasDest) { @@ -431,16 +437,16 @@ namespace FEXCore::IR { // to impact the live range. if (IROp->Op == OP_FILLREGISTER) continue; - uint8_t NumArgs = IR::GetArgs(IROp->Op); + const uint8_t NumArgs = IR::GetArgs(IROp->Op); for (uint8_t i = 0; i < NumArgs; ++i) { if (IROp->Args[i].IsInvalid()) continue; if (IR->GetOp(IROp->Args[i])->Op == OP_INLINECONSTANT) continue; if (IR->GetOp(IROp->Args[i])->Op == OP_INLINEENTRYPOINTOFFSET) continue; if (IR->GetOp(IROp->Args[i])->Op == OP_IRHEADER) continue; - uint32_t ArgNode = IROp->Args[i].ID(); + const auto ArgNode = IROp->Args[i].ID(); LOGMAN_THROW_A_FMT(LiveRanges[ArgNode].Begin != ~0U, "%ssa{} used by %ssa{} before defined?", ArgNode, Node); - auto ArgNodeBlockID = Graph->Nodes[ArgNode].Head.BlockID; + const auto ArgNodeBlockID = Graph->Nodes[ArgNode].Head.BlockID; if (ArgNodeBlockID == BlockNodeID) { // Set the node end to be at least here LiveRanges[ArgNode].End = Node; @@ -465,7 +471,7 @@ namespace FEXCore::IR { auto Op = IROp->C(); auto NodeBegin = IR->at(Op->PhiBegin); - uint32_t CurrentSourcePartner = Node; + auto CurrentSourcePartner = Node; while (NodeBegin != NodeBegin.Invalid()) { auto [ValueNode, ValueHeader] = NodeBegin(); auto ValueOp = ValueHeader->CW(); @@ -568,7 +574,7 @@ namespace FEXCore::IR { //First pass: Mark pre-writes for (auto [BlockNode, BlockHeader] : IR->GetBlocks()) { for (auto [CodeNode, IROp] : IR->GetCode(BlockNode)) { - uint32_t Node = IR->GetID(CodeNode); + const auto Node = IR->GetID(CodeNode); if (IROp->Op == OP_STOREREGISTER) { auto Op = IROp->C(); //int -1 /*vreg*/ = (int)(Op->Offset / 8) - 1; @@ -594,16 +600,16 @@ namespace FEXCore::IR { for (auto [BlockNode, BlockHeader] : IR->GetBlocks()) { memset(StaticMaps, 0, MapsSize * sizeof(LiveRange*)); for (auto [CodeNode, IROp] : IR->GetCode(BlockNode)) { - uint32_t Node = IR->GetID(CodeNode); + const auto Node = IR->GetID(CodeNode); // Check for read-after-write and demote if it happens - uint8_t NumArgs = IR::GetArgs(IROp->Op); + const uint8_t NumArgs = IR::GetArgs(IROp->Op); for (uint8_t i = 0; i < NumArgs; ++i) { if (IROp->Args[i].IsInvalid()) continue; if (IR->GetOp(IROp->Args[i])->Op == OP_INLINECONSTANT) continue; if (IR->GetOp(IROp->Args[i])->Op == OP_INLINEENTRYPOINTOFFSET) continue; if (IR->GetOp(IROp->Args[i])->Op == OP_IRHEADER) continue; - uint32_t ArgNode = IROp->Args[i].ID(); + const auto ArgNode = IROp->Args[i].ID(); // ACCESSED after write, let's not SRA this one if (LiveRanges[ArgNode].Written) { @@ -705,7 +711,7 @@ namespace FEXCore::IR { BlockInterferenceVector->reserve(BlockIROp->Last.ID() - BlockIROp->Begin.ID()); for (auto [CodeNode, IROp] : IR->GetCode(BlockNode)) { - uint32_t Node = IR->GetID(CodeNode); + const auto Node = IR->GetID(CodeNode); LiveRange *NodeLiveRange = &LiveRanges[Node]; if (NodeLiveRange->Begin >= BlockIROp->Begin.ID() && @@ -724,13 +730,13 @@ namespace FEXCore::IR { void ConstrainedRAPass::CalculateBlockNodeInterference(FEXCore::IR::IRListView *IR) { #if 0 - auto AddInterference = [&](uint32_t Node1, uint32_t Node2) { + const auto AddInterference = [&](IR::NodeID Node1, IR::NodeID Node2) { RegisterNode *Node = &Graph->Nodes[Node1]; Node->Interference.Set(Node2); Node->InterferenceList[Node->Head.InterferenceCount++] = Node2; }; - auto CheckInterferenceNodeSizes = [&](uint32_t Node1, uint32_t MaxNewNodes) { + const auto CheckInterferenceNodeSizes = [&](IR::NodeID Node1, uint32_t MaxNewNodes) { RegisterNode *Node = &Graph->Nodes[Node1]; uint32_t NewListMax = Node->Head.InterferenceCount + MaxNewNodes; if (Node->InterferenceListSize <= NewListMax) { @@ -744,11 +750,11 @@ namespace FEXCore::IR { for (auto [BlockNode, BlockHeader] : IR->GetBlocks()) { BlockInterferences *BlockInterferenceVector = &LocalBlockInterferences.try_emplace(IR->GetID(BlockNode)).first->second; - std::vector Interferences; + std::vector Interferences; Interferences.reserve(BlockInterferenceVector->size() + GlobalBlockInterferences.size()); for (auto [CodeNode, IROp] : IR->GetCode(BlockNode)) { - uint32_t Node = IR->GetID(CodeNode); + const auto Node = IR->GetID(CodeNode); // Check for every interference with the local block's interference for (auto RHSNode : *BlockInterferenceVector) { @@ -783,16 +789,16 @@ namespace FEXCore::IR { } void ConstrainedRAPass::CalculateNodeInterference(FEXCore::IR::IRListView *IR) { - auto AddInterference = [this](uint32_t Node1, uint32_t Node2) { + const auto AddInterference = [this](IR::NodeID Node1, IR::NodeID Node2) { RegisterNode *Node = &Graph->Nodes[Node1]; Node->Interferences.Append(Node2); }; - uint32_t NodeCount = IR->GetSSACount(); + const uint32_t NodeCount = IR->GetSSACount(); // Now that we have all the live ranges calculated we need to add them to our interference graph - auto GetClass = [](PhysicalRegister PhyReg) { + const auto GetClass = [](PhysicalRegister PhyReg) { if (PhyReg.Class == IR::GPRPairClass.Val) return IR::GPRClass.Val; else @@ -892,7 +898,7 @@ namespace FEXCore::IR { RegAndClass = LiveRange->PrefferedRegister; } else { uint32_t RegisterConflicts = 0; - CurrentNode->Interferences.Iterate([&](const uint32_t InterferenceNode) { + CurrentNode->Interferences.Iterate([&](const IR::NodeID InterferenceNode) { RegisterConflicts |= GetConflicts(Graph, Graph->AllocData->Map[InterferenceNode], {RegClass}); }); @@ -922,14 +928,14 @@ namespace FEXCore::IR { FEXCore::IR::AllNodesIterator ConstrainedRAPass::FindFirstUse(FEXCore::IR::IREmitter *IREmit, FEXCore::IR::OrderedNode* Node, FEXCore::IR::AllNodesIterator Begin, FEXCore::IR::AllNodesIterator End) { using namespace FEXCore::IR; - uint32_t SearchID = IREmit->ViewIR().GetID(Node); + const auto SearchID = IREmit->ViewIR().GetID(Node); while(1) { auto [RealNode, IROp] = Begin(); - uint8_t NumArgs = FEXCore::IR::GetArgs(IROp->Op); + const uint8_t NumArgs = FEXCore::IR::GetArgs(IROp->Op); for (uint8_t i = 0; i < NumArgs; ++i) { - uint32_t ArgNode = IROp->Args[i].ID(); + const auto ArgNode = IROp->Args[i].ID(); if (ArgNode == SearchID) { return Begin; } @@ -948,7 +954,7 @@ namespace FEXCore::IR { FEXCore::IR::AllNodesIterator ConstrainedRAPass::FindLastUseBefore(FEXCore::IR::IREmitter *IREmit, FEXCore::IR::OrderedNode* Node, FEXCore::IR::AllNodesIterator Begin, FEXCore::IR::AllNodesIterator End) { auto CurrentIR = IREmit->ViewIR(); - uint32_t SearchID = CurrentIR.GetID(Node); + const auto SearchID = CurrentIR.GetID(Node); while (1) { using namespace FEXCore::IR; @@ -959,9 +965,9 @@ namespace FEXCore::IR { return End; } - uint8_t NumArgs = FEXCore::IR::GetArgs(IROp->Op); + const uint8_t NumArgs = FEXCore::IR::GetArgs(IROp->Op); for (uint8_t i = 0; i < NumArgs; ++i) { - uint32_t ArgNode = IROp->Args[i].ID(); + const auto ArgNode = IROp->Args[i].ID(); if (ArgNode == SearchID) { return End; } @@ -978,10 +984,10 @@ namespace FEXCore::IR { return FEXCore::IR::AllNodesIterator::Invalid(); } - uint32_t ConstrainedRAPass::FindNodeToSpill(IREmitter *IREmit, RegisterNode *RegisterNode, uint32_t CurrentLocation, LiveRange const *OpLiveRange, int32_t RematCost) { + IR::NodeID ConstrainedRAPass::FindNodeToSpill(IREmitter *IREmit, RegisterNode *RegisterNode, uint32_t CurrentLocation, LiveRange const *OpLiveRange, int32_t RematCost) { auto IR = IREmit->ViewIR(); - uint32_t InterferenceIdToSpill = 0; + IR::NodeID InterferenceIdToSpill = 0; uint32_t InterferenceFarthestNextUse = 0; IR::OrderedNodeWrapper NodeOpBegin = IR::OrderedNodeWrapper::WrapOffset(CurrentLocation * sizeof(IR::OrderedNode)); @@ -992,7 +998,7 @@ namespace FEXCore::IR { // Couldn't find register to spill // Be more aggressive if (InterferenceIdToSpill == 0) { - RegisterNode->Interferences.Iterate([&](uint32_t InterferenceNode) { + RegisterNode->Interferences.Iterate([&](IR::NodeID InterferenceNode) { auto *InterferenceLiveRange = &LiveRanges[InterferenceNode]; if (InterferenceLiveRange->RematCost == -1 || (RematCost != -1 && InterferenceLiveRange->RematCost != RematCost)) { @@ -1054,7 +1060,9 @@ namespace FEXCore::IR { auto InterferenceNodePrevUse = FindLastUseBefore(IREmit, InterferenceOrderedNode, InterferenceNodeOpBeginIter, NodeOpBeginIter); LOGMAN_THROW_A_FMT(InterferenceNodeNextUse != IR::NodeIterator::Invalid(), "Couldn't find next usage of op"); // If there is no use of the interference op prior to our op then it only has initial definition - if (InterferenceNodePrevUse == IR::NodeIterator::Invalid()) InterferenceNodePrevUse = InterferenceNodeOpBeginIter; + if (InterferenceNodePrevUse == IR::NodeIterator::Invalid()) { + InterferenceNodePrevUse = InterferenceNodeOpBeginIter; + } uint32_t NextUseDistance = InterferenceNodeNextUse.ID() - CurrentLocation; if (NextUseDistance >= InterferenceFarthestNextUse) { @@ -1069,7 +1077,7 @@ namespace FEXCore::IR { if (InterferenceIdToSpill == 0) { - RegisterNode->Interferences.Iterate([&](uint32_t InterferenceNode) { + RegisterNode->Interferences.Iterate([&](IR::NodeID InterferenceNode) { auto *InterferenceLiveRange = &LiveRanges[InterferenceNode]; if (InterferenceLiveRange->RematCost == -1 || (RematCost != -1 && InterferenceLiveRange->RematCost != RematCost)) { @@ -1175,7 +1183,7 @@ namespace FEXCore::IR { // Heuristics failed to spill ? if (InterferenceIdToSpill == 0) { // Panic spill: Spill any value not used by the current op - std::set CurrentNodes; + std::set CurrentNodes; // Get all used nodes for current IR op { @@ -1190,7 +1198,7 @@ namespace FEXCore::IR { } - RegisterNode->Interferences.Find([&](uint32_t InterferenceNode) { + RegisterNode->Interferences.Find([&](IR::NodeID InterferenceNode) { auto *InterferenceLiveRange = &LiveRanges[InterferenceNode]; if (InterferenceLiveRange->RematCost == -1 || (RematCost != -1 && InterferenceLiveRange->RematCost != RematCost)) { @@ -1212,7 +1220,7 @@ namespace FEXCore::IR { CurrentLocation, -1, OpLiveRange->Begin, OpLiveRange->End); - RegisterNode->Interferences.Iterate([&](uint32_t InterferenceNode) { + RegisterNode->Interferences.Iterate([&](IR::NodeID InterferenceNode) { auto *InterferenceLiveRange = &LiveRanges[InterferenceNode]; LogMan::Msg::DFmt("\tInt{}: %ssa{} Remat: {} [{}, {})", j++, InterferenceNode, InterferenceLiveRange->RematCost, InterferenceLiveRange->Begin, InterferenceLiveRange->End); @@ -1223,7 +1231,7 @@ namespace FEXCore::IR { return InterferenceIdToSpill; } - uint32_t ConstrainedRAPass::FindSpillSlot(uint32_t Node, FEXCore::IR::RegisterClassType RegisterClass) { + uint32_t ConstrainedRAPass::FindSpillSlot(IR::NodeID Node, FEXCore::IR::RegisterClassType RegisterClass) { RegisterNode *CurrentNode = &Graph->Nodes[Node]; LiveRange *NodeLiveRange = &LiveRanges[Node]; if (ReuseSpillSlots) { @@ -1257,7 +1265,7 @@ namespace FEXCore::IR { LOGMAN_THROW_A_FMT(IROp->HasDest, "Can't spill with no dest"); - uint32_t Node = IR.GetID(CodeNode); + const auto Node = IR.GetID(CodeNode); RegisterNode *CurrentNode = &Graph->Nodes[Node]; auto &CurrentRegAndClass = Graph->AllocData->Map[Node]; LiveRange *OpLiveRange = &LiveRanges[Node]; @@ -1270,7 +1278,7 @@ namespace FEXCore::IR { bool Spilled = false; // First let's just check for constants that we can just rematerialize instead of spilling - uint32_t InterferenceNode = FindNodeToSpill(IREmit, CurrentNode, Node, OpLiveRange, 1); + const auto InterferenceNode = FindNodeToSpill(IREmit, CurrentNode, Node, OpLiveRange, 1); if (InterferenceNode != ~0U) { // We want to end the live range of this value here and continue it on first use auto [ConstantNode, _] = IR.at(InterferenceNode)(); @@ -1292,7 +1300,7 @@ namespace FEXCore::IR { // If we didn't remat a constant then we need to do some real spilling if (!Spilled) { - uint32_t InterferenceNode = FindNodeToSpill(IREmit, CurrentNode, Node, OpLiveRange); + const auto InterferenceNode = FindNodeToSpill(IREmit, CurrentNode, Node, OpLiveRange); if (InterferenceNode != ~0U) { FEXCore::IR::RegisterClassType InterferenceRegClass = FEXCore::IR::RegisterClassType{Graph->AllocData->Map[InterferenceNode].Class}; uint32_t SpillSlot = FindSpillSlot(InterferenceNode, InterferenceRegClass); diff --git a/External/FEXCore/Source/Interface/IR/Passes/ValueDominanceValidation.cpp b/External/FEXCore/Source/Interface/IR/Passes/ValueDominanceValidation.cpp index d360ff7498..5c086751af 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/ValueDominanceValidation.cpp +++ b/External/FEXCore/Source/Interface/IR/Passes/ValueDominanceValidation.cpp @@ -40,7 +40,7 @@ bool ValueDominanceValidation::Run(IREmitter *IREmit) { auto CurrentIR = IREmit->ViewIR(); std::ostringstream Errors; - std::unordered_map OffsetToBlockMap; + std::unordered_map OffsetToBlockMap; for (auto [BlockNode, BlockHeader] : CurrentIR.GetBlocks()) { @@ -89,9 +89,9 @@ bool ValueDominanceValidation::Run(IREmitter *IREmit) { auto BlockIROp = BlockHeader->CW(); for (auto [CodeNode, IROp] : CurrentIR.GetCode(BlockNode)) { - uint32_t CodeID = CurrentIR.GetID(CodeNode); + const auto CodeID = CurrentIR.GetID(CodeNode); - uint8_t NumArgs = IR::GetArgs(IROp->Op); + const uint8_t NumArgs = IR::GetArgs(IROp->Op); for (uint32_t i = 0; i < NumArgs; ++i) { if (IROp->Args[i].IsInvalid()) continue; if (CurrentIR.GetOp(IROp->Args[i])->Op == OP_IRHEADER) continue;