Browse Source

[dynarmic] remove redundant RegAlloc& stored on every argument

pull/3150/head
lizzie 3 weeks ago
committed by crueter
parent
commit
2d289bbaf3
  1. 2
      src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp
  2. 2
      src/dynarmic/src/dynarmic/backend/arm64/reg_alloc.cpp
  3. 16
      src/dynarmic/src/dynarmic/backend/arm64/reg_alloc.h
  4. 8
      src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp
  5. 6
      src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp
  6. 2
      src/dynarmic/src/dynarmic/backend/x64/emit_x64_data_processing.cpp
  7. 6
      src/dynarmic/src/dynarmic/backend/x64/emit_x64_packed.cpp
  8. 15
      src/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp
  9. 9
      src/dynarmic/src/dynarmic/backend/x64/reg_alloc.h

2
src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp

@ -60,7 +60,7 @@ void EmitIR<IR::Opcode::Pack2x32To1x64>(oaknut::CodeGenerator& code, EmitContext
template<> template<>
void EmitIR<IR::Opcode::Pack2x64To1x128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { void EmitIR<IR::Opcode::Pack2x64To1x128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
bool const args_in_gpr[] = { args[0].IsInGpr(), args[1].IsInGpr() };
bool const args_in_gpr[] = { args[0].IsInGpr(ctx.reg_alloc), args[1].IsInGpr(ctx.reg_alloc) };
if (args_in_gpr[0] && args_in_gpr[1]) { if (args_in_gpr[0] && args_in_gpr[1]) {
auto Xlo = ctx.reg_alloc.ReadX(args[0]); auto Xlo = ctx.reg_alloc.ReadX(args[0]);
auto Xhi = ctx.reg_alloc.ReadX(args[1]); auto Xhi = ctx.reg_alloc.ReadX(args[1]);

2
src/dynarmic/src/dynarmic/backend/arm64/reg_alloc.cpp

@ -84,7 +84,7 @@ IR::AccType Argument::GetImmediateAccType() const {
return value.GetAccType(); return value.GetAccType();
} }
HostLoc::Kind Argument::CurrentLocationKind() const {
HostLoc::Kind Argument::CurrentLocationKind(RegAlloc& reg_alloc) const {
return reg_alloc.ValueLocation(value.GetInst())->kind; return reg_alloc.ValueLocation(value.GetInst())->kind;
} }

16
src/dynarmic/src/dynarmic/backend/arm64/reg_alloc.h

@ -64,18 +64,18 @@ public:
IR::AccType GetImmediateAccType() const; IR::AccType GetImmediateAccType() const;
// Only valid if not immediate // Only valid if not immediate
HostLoc::Kind CurrentLocationKind() const;
bool IsInGpr() const { return !IsImmediate() && CurrentLocationKind() == HostLoc::Kind::Gpr; }
bool IsInFpr() const { return !IsImmediate() && CurrentLocationKind() == HostLoc::Kind::Fpr; }
HostLoc::Kind CurrentLocationKind(RegAlloc& reg_alloc) const;
bool IsInGpr(RegAlloc& reg_alloc) const {
return !IsImmediate() && CurrentLocationKind(reg_alloc) == HostLoc::Kind::Gpr;
}
bool IsInFpr(RegAlloc& reg_alloc) const {
return !IsImmediate() && CurrentLocationKind(reg_alloc) == HostLoc::Kind::Fpr;
}
private: private:
friend class RegAlloc; friend class RegAlloc;
explicit Argument(RegAlloc& reg_alloc)
: reg_alloc{reg_alloc} {}
bool allocated = false;
RegAlloc& reg_alloc;
IR::Value value; IR::Value value;
bool allocated = false;
}; };
struct FlagsTag final { struct FlagsTag final {

8
src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp

@ -332,7 +332,7 @@ void A32EmitX64::EmitA32SetRegister(A32EmitContext& ctx, IR::Inst* inst) {
if (args[1].IsImmediate()) { if (args[1].IsImmediate()) {
code.mov(MJitStateReg(reg), args[1].GetImmediateU32()); code.mov(MJitStateReg(reg), args[1].GetImmediateU32());
} else if (args[1].IsInXmm()) {
} else if (args[1].IsInXmm(ctx.reg_alloc)) {
const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[1]); const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[1]);
code.movd(MJitStateReg(reg), to_store); code.movd(MJitStateReg(reg), to_store);
} else { } else {
@ -346,7 +346,7 @@ void A32EmitX64::EmitA32SetExtendedRegister32(A32EmitContext& ctx, IR::Inst* ins
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsSingleExtReg(reg)); ASSERT(A32::IsSingleExtReg(reg));
if (args[1].IsInXmm()) {
if (args[1].IsInXmm(ctx.reg_alloc)) {
Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[1]); Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[1]);
code.movss(MJitStateExtReg(reg), to_store); code.movss(MJitStateExtReg(reg), to_store);
} else { } else {
@ -360,7 +360,7 @@ void A32EmitX64::EmitA32SetExtendedRegister64(A32EmitContext& ctx, IR::Inst* ins
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsDoubleExtReg(reg)); ASSERT(A32::IsDoubleExtReg(reg));
if (args[1].IsInXmm()) {
if (args[1].IsInXmm(ctx.reg_alloc)) {
const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[1]); const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[1]);
code.movsd(MJitStateExtReg(reg), to_store); code.movsd(MJitStateExtReg(reg), to_store);
} else { } else {
@ -635,7 +635,7 @@ void A32EmitX64::EmitA32SetGEFlags(A32EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(!args[0].IsImmediate()); ASSERT(!args[0].IsImmediate());
if (args[0].IsInXmm()) {
if (args[0].IsInXmm(ctx.reg_alloc)) {
const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[0]); const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[0]);
code.movd(dword[code.ABI_JIT_PTR + offsetof(A32JitState, cpsr_ge)], to_store); code.movd(dword[code.ABI_JIT_PTR + offsetof(A32JitState, cpsr_ge)], to_store);
} else { } else {

6
src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp

@ -405,7 +405,7 @@ void A64EmitX64::EmitA64SetX(A64EmitContext& ctx, IR::Inst* inst) {
const auto addr = qword[code.ABI_JIT_PTR + offsetof(A64JitState, reg) + sizeof(u64) * static_cast<size_t>(reg)]; const auto addr = qword[code.ABI_JIT_PTR + offsetof(A64JitState, reg) + sizeof(u64) * static_cast<size_t>(reg)];
if (args[1].FitsInImmediateS32()) { if (args[1].FitsInImmediateS32()) {
code.mov(addr, args[1].GetImmediateS32()); code.mov(addr, args[1].GetImmediateS32());
} else if (args[1].IsInXmm()) {
} else if (args[1].IsInXmm(ctx.reg_alloc)) {
const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[1]); const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[1]);
code.movq(addr, to_store); code.movq(addr, to_store);
} else { } else {
@ -451,7 +451,7 @@ void A64EmitX64::EmitA64SetSP(A64EmitContext& ctx, IR::Inst* inst) {
const auto addr = qword[code.ABI_JIT_PTR + offsetof(A64JitState, sp)]; const auto addr = qword[code.ABI_JIT_PTR + offsetof(A64JitState, sp)];
if (args[0].FitsInImmediateS32()) { if (args[0].FitsInImmediateS32()) {
code.mov(addr, args[0].GetImmediateS32()); code.mov(addr, args[0].GetImmediateS32());
} else if (args[0].IsInXmm()) {
} else if (args[0].IsInXmm(ctx.reg_alloc)) {
const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[0]); const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[0]);
code.movq(addr, to_store); code.movq(addr, to_store);
} else { } else {
@ -489,7 +489,7 @@ void A64EmitX64::EmitA64SetPC(A64EmitContext& ctx, IR::Inst* inst) {
const auto addr = qword[code.ABI_JIT_PTR + offsetof(A64JitState, pc)]; const auto addr = qword[code.ABI_JIT_PTR + offsetof(A64JitState, pc)];
if (args[0].FitsInImmediateS32()) { if (args[0].FitsInImmediateS32()) {
code.mov(addr, args[0].GetImmediateS32()); code.mov(addr, args[0].GetImmediateS32());
} else if (args[0].IsInXmm()) {
} else if (args[0].IsInXmm(ctx.reg_alloc)) {
const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[0]); const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[0]);
code.movq(addr, to_store); code.movq(addr, to_store);
} else { } else {

2
src/dynarmic/src/dynarmic/backend/x64/emit_x64_data_processing.cpp

@ -1523,7 +1523,7 @@ void EmitX64::EmitZeroExtendWordToLong(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitZeroExtendLongToQuad(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitZeroExtendLongToQuad(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
if (args[0].IsInGpr()) {
if (args[0].IsInGpr(ctx.reg_alloc)) {
const Xbyak::Reg64 source = ctx.reg_alloc.UseGpr(args[0]); const Xbyak::Reg64 source = ctx.reg_alloc.UseGpr(args[0]);
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(); const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm();
code.movq(result, source); code.movq(result, source);

6
src/dynarmic/src/dynarmic/backend/x64/emit_x64_packed.cpp

@ -248,7 +248,7 @@ void EmitX64::EmitPackedSubS16(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitPackedHalvingAddU8(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitPackedHalvingAddU8(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
if (args[0].IsInXmm() || args[1].IsInXmm()) {
if (args[0].IsInXmm(ctx.reg_alloc) || args[1].IsInXmm(ctx.reg_alloc)) {
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(args[0]); const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(args[0]);
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseScratchXmm(args[1]); const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseScratchXmm(args[1]);
const Xbyak::Xmm ones = ctx.reg_alloc.ScratchXmm(); const Xbyak::Xmm ones = ctx.reg_alloc.ScratchXmm();
@ -291,7 +291,7 @@ void EmitX64::EmitPackedHalvingAddU8(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitPackedHalvingAddU16(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitPackedHalvingAddU16(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
if (args[0].IsInXmm() || args[1].IsInXmm()) {
if (args[0].IsInXmm(ctx.reg_alloc) || args[1].IsInXmm(ctx.reg_alloc)) {
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(args[0]); const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(args[0]);
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(args[1]); const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(args[1]);
const Xbyak::Xmm tmp = ctx.reg_alloc.ScratchXmm(); const Xbyak::Xmm tmp = ctx.reg_alloc.ScratchXmm();
@ -654,7 +654,7 @@ void EmitX64::EmitPackedAbsDiffSumU8(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitPackedSelect(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitPackedSelect(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const size_t num_args_in_xmm = args[0].IsInXmm() + args[1].IsInXmm() + args[2].IsInXmm();
const size_t num_args_in_xmm = args[0].IsInXmm(ctx.reg_alloc) + args[1].IsInXmm(ctx.reg_alloc) + args[2].IsInXmm(ctx.reg_alloc);
if (num_args_in_xmm >= 2) { if (num_args_in_xmm >= 2) {
const Xbyak::Xmm ge = ctx.reg_alloc.UseScratchXmm(args[0]); const Xbyak::Xmm ge = ctx.reg_alloc.UseScratchXmm(args[0]);

15
src/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp

@ -174,21 +174,21 @@ IR::AccType Argument::GetImmediateAccType() const noexcept {
} }
/// Is this value currently in a GPR? /// Is this value currently in a GPR?
bool Argument::IsInGpr() const noexcept {
bool Argument::IsInGpr(RegAlloc& reg_alloc) const noexcept {
if (IsImmediate()) if (IsImmediate())
return false; return false;
return HostLocIsGPR(*reg_alloc.ValueLocation(value.GetInst())); return HostLocIsGPR(*reg_alloc.ValueLocation(value.GetInst()));
} }
/// Is this value currently in a XMM? /// Is this value currently in a XMM?
bool Argument::IsInXmm() const noexcept {
bool Argument::IsInXmm(RegAlloc& reg_alloc) const noexcept {
if (IsImmediate()) if (IsImmediate())
return false; return false;
return HostLocIsXMM(*reg_alloc.ValueLocation(value.GetInst())); return HostLocIsXMM(*reg_alloc.ValueLocation(value.GetInst()));
} }
/// Is this value currently in memory? /// Is this value currently in memory?
bool Argument::IsInMemory() const noexcept {
bool Argument::IsInMemory(RegAlloc& reg_alloc) const noexcept {
if (IsImmediate()) if (IsImmediate())
return false; return false;
return HostLocIsSpill(*reg_alloc.ValueLocation(value.GetInst())); return HostLocIsSpill(*reg_alloc.ValueLocation(value.GetInst()));
@ -200,10 +200,13 @@ RegAlloc::RegAlloc(BlockOfCode* code, boost::container::static_vector<HostLoc, 2
code(code) code(code)
{} {}
//static std::uint64_t Zfncwjkrt_blockOfCodeShim = 0;
RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(const IR::Inst* inst) noexcept { RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(const IR::Inst* inst) noexcept {
ArgumentInfo ret{Argument{*this}, Argument{*this}, Argument{*this}, Argument{*this}};
ArgumentInfo ret{
Argument{},
Argument{},
Argument{},
Argument{}
};
for (size_t i = 0; i < inst->NumArgs(); i++) { for (size_t i = 0; i < inst->NumArgs(); i++) {
const auto arg = inst->GetArg(i); const auto arg = inst->GetArg(i);
ret[i].value = arg; ret[i].value = arg;

9
src/dynarmic/src/dynarmic/backend/x64/reg_alloc.h

@ -129,16 +129,15 @@ public:
IR::AccType GetImmediateAccType() const noexcept; IR::AccType GetImmediateAccType() const noexcept;
/// Is this value currently in a GPR? /// Is this value currently in a GPR?
bool IsInGpr() const noexcept;
bool IsInXmm() const noexcept;
bool IsInMemory() const noexcept;
bool IsInGpr(RegAlloc& reg_alloc) const noexcept;
bool IsInXmm(RegAlloc& reg_alloc) const noexcept;
bool IsInMemory(RegAlloc& reg_alloc) const noexcept;
private: private:
friend class RegAlloc; friend class RegAlloc;
explicit Argument(RegAlloc& reg_alloc) : reg_alloc(reg_alloc) {}
explicit Argument() {}
//data //data
IR::Value value; //8 IR::Value value; //8
RegAlloc& reg_alloc; //8
bool allocated = false; //1 bool allocated = false; //1
}; };

Loading…
Cancel
Save