JitRegCache: Add BindOrImm

This commit is contained in:
MerryMage 2018-10-15 21:00:53 +01:00
parent 590ec866b0
commit 2e955012b2
3 changed files with 110 additions and 59 deletions

View File

@ -154,45 +154,74 @@ private:
class RCConstraint class RCConstraint
{ {
public: public:
bool IsActive() const { return realized || bind || write || read || kill_imm; } bool IsRealized() const { return realized != RealizedLoc::Invalid; }
bool IsRealized() const { return realized; } bool IsActive() const
bool ShouldBind() const { return bind; }
bool ShouldLoad() const { return read; }
bool ShouldDirty() const { return write; }
bool ShouldKillImmediate() const { return kill_imm; }
bool ShouldBeRevertable() const { return revertable; }
void Realized() { realized = true; }
void RealizedBound()
{ {
realized = true; return IsRealized() || write || read || kill_imm || kill_mem || revertable;
bind = true;
} }
void AddUse(RCMode mode) { AddConstraint(false, mode, false, false); } bool ShouldLoad() const { return read; }
void AddUseNoImm(RCMode mode) { AddConstraint(false, mode, true, false); } bool ShouldDirty() const { return write; }
void AddBind(RCMode mode) { AddConstraint(true, mode, false, false); } bool ShouldBeRevertable() const { return revertable; }
void AddRevertableBind(RCMode mode) { AddConstraint(true, mode, false, true); } bool ShouldKillImmediate() const { return kill_imm; }
bool ShouldKillMemory() const { return kill_mem; }
enum class RealizedLoc
{
Invalid,
Bound,
Imm,
Mem,
};
void Realized(RealizedLoc loc)
{
realized = loc;
ASSERT(IsRealized());
}
enum class ConstraintLoc
{
Bound,
BoundOrImm,
BoundOrMem,
Any,
};
void AddUse(RCMode mode) { AddConstraint(mode, ConstraintLoc::Any, false); }
void AddUseNoImm(RCMode mode) { AddConstraint(mode, ConstraintLoc::BoundOrMem, false); }
void AddBindOrImm(RCMode mode) { AddConstraint(mode, ConstraintLoc::BoundOrImm, false); }
void AddBind(RCMode mode) { AddConstraint(mode, ConstraintLoc::Bound, false); }
void AddRevertableBind(RCMode mode) { AddConstraint(mode, ConstraintLoc::Bound, true); }
private: private:
void AddConstraint(bool should_bind, RCMode mode, bool should_kill_imm, bool should_revertable) void AddConstraint(RCMode mode, ConstraintLoc loc, bool should_revertable)
{ {
if (realized) if (IsRealized())
{ {
ASSERT(IsCompatible(should_bind, mode, should_kill_imm, should_revertable)); ASSERT(IsCompatible(mode, loc, should_revertable));
return; return;
} }
if (should_bind)
bind = true;
if (should_kill_imm)
kill_imm = true;
if (should_revertable) if (should_revertable)
revertable = true; revertable = true;
switch (loc)
{
case ConstraintLoc::Bound:
kill_imm = true;
kill_mem = true;
break;
case ConstraintLoc::BoundOrImm:
kill_mem = true;
break;
case ConstraintLoc::BoundOrMem:
kill_imm = true;
break;
case ConstraintLoc::Any:
break;
}
switch (mode) switch (mode)
{ {
case RCMode::Read: case RCMode::Read:
@ -208,30 +237,50 @@ private:
} }
} }
bool IsCompatible(bool should_bind, RCMode mode, bool should_kill_imm, bool should_revertable) bool IsCompatible(RCMode mode, ConstraintLoc loc, bool should_revertable) const
{ {
if (should_bind && !bind)
return false;
if (should_kill_imm && !kill_imm)
return false;
if (should_revertable && !revertable) if (should_revertable && !revertable)
return false;
switch (mode)
{ {
case RCMode::Read: return false;
return read;
case RCMode::Write:
return write;
case RCMode::ReadWrite:
return read && write;
} }
const bool is_loc_compatible = [&] {
switch (loc)
{
case ConstraintLoc::Bound:
return realized == RealizedLoc::Bound;
case ConstraintLoc::BoundOrImm:
return realized == RealizedLoc::Bound || realized == RealizedLoc::Imm;
case ConstraintLoc::BoundOrMem:
return realized == RealizedLoc::Bound || realized == RealizedLoc::Mem;
case ConstraintLoc::Any:
return true;
}
ASSERT(false);
return false;
}();
const bool is_mode_compatible = [&] {
switch (mode)
{
case RCMode::Read:
return read;
case RCMode::Write:
return write;
case RCMode::ReadWrite:
return read && write;
}
ASSERT(false);
return false;
}();
return is_loc_compatible && is_mode_compatible;
} }
bool realized = false; RealizedLoc realized = RealizedLoc::Invalid;
bool bind = false;
bool write = false; bool write = false;
bool read = false; bool read = false;
bool kill_imm = false; bool kill_imm = false;
bool kill_mem = false;
bool revertable = false; bool revertable = false;
}; };

View File

@ -610,18 +610,18 @@ RCOpArg RegCache::UseNoImm(preg_t preg, RCMode mode)
return RCOpArg{this, preg}; return RCOpArg{this, preg};
} }
RCOpArg RegCache::BindOrImm(preg_t preg, RCMode mode)
{
m_constraints[preg].AddBindOrImm(mode);
return RCOpArg{this, preg};
}
RCX64Reg RegCache::Bind(preg_t preg, RCMode mode) RCX64Reg RegCache::Bind(preg_t preg, RCMode mode)
{ {
m_constraints[preg].AddBind(mode); m_constraints[preg].AddBind(mode);
return RCX64Reg{this, preg}; return RCX64Reg{this, preg};
} }
RCX64Reg RegCache::BindOrImm(preg_t preg, RCMode mode)
{
m_constraints[preg].AddBindOrImm(mode);
return RCX64Reg{this, preg};
}
RCX64Reg RegCache::RevertableBind(preg_t preg, RCMode mode) RCX64Reg RegCache::RevertableBind(preg_t preg, RCMode mode)
{ {
m_constraints[preg].AddRevertableBind(mode); m_constraints[preg].AddRevertableBind(mode);
@ -704,10 +704,11 @@ void RegCache::Realize(preg_t preg)
const bool load = m_constraints[preg].ShouldLoad(); const bool load = m_constraints[preg].ShouldLoad();
const bool dirty = m_constraints[preg].ShouldDirty(); const bool dirty = m_constraints[preg].ShouldDirty();
const bool kill_imm = m_constraints[preg].ShouldKillImmediate(); const bool kill_imm = m_constraints[preg].ShouldKillImmediate();
const bool kill_mem = m_constraints[preg].ShouldKillMemory();
const auto do_bind = [&] { const auto do_bind = [&] {
BindToRegister(preg, load, dirty); BindToRegister(preg, load, dirty);
m_constraints[preg].RealizedBound(); m_constraints[preg].Realized(RCConstraint::RealizedLoc::Bound);
}; };
if (m_constraints[preg].ShouldBeRevertable()) if (m_constraints[preg].ShouldBeRevertable())
@ -718,29 +719,29 @@ void RegCache::Realize(preg_t preg)
return; return;
} }
if (m_constraints[preg].ShouldBind())
{
do_bind();
return;
}
switch (m_regs[preg].GetLocationType()) switch (m_regs[preg].GetLocationType())
{ {
case PPCCachedReg::LocationType::Default: case PPCCachedReg::LocationType::Default:
break; if (kill_mem)
{
do_bind();
return;
}
m_constraints[preg].Realized(RCConstraint::RealizedLoc::Mem);
return;
case PPCCachedReg::LocationType::Bound: case PPCCachedReg::LocationType::Bound:
do_bind(); do_bind();
break; return;
case PPCCachedReg::LocationType::Immediate: case PPCCachedReg::LocationType::Immediate:
case PPCCachedReg::LocationType::SpeculativeImmediate: case PPCCachedReg::LocationType::SpeculativeImmediate:
if (dirty || kill_imm) if (dirty || kill_imm)
{ {
do_bind(); do_bind();
return;
} }
m_constraints[preg].Realized(RCConstraint::RealizedLoc::Imm);
break; break;
} }
m_constraints[preg].Realized();
} }
bool RegCache::IsAnyConstraintActive() const bool RegCache::IsAnyConstraintActive() const

View File

@ -234,6 +234,7 @@ public:
RCOpArg Use(preg_t preg, RCMode mode); RCOpArg Use(preg_t preg, RCMode mode);
RCOpArg UseNoImm(preg_t preg, RCMode mode); RCOpArg UseNoImm(preg_t preg, RCMode mode);
RCOpArg BindOrImm(preg_t preg, RCMode mode);
RCX64Reg Bind(preg_t preg, RCMode mode); RCX64Reg Bind(preg_t preg, RCMode mode);
RCX64Reg RevertableBind(preg_t preg, RCMode mode); RCX64Reg RevertableBind(preg_t preg, RCMode mode);
RCX64Reg Scratch(Gen::X64Reg xr); RCX64Reg Scratch(Gen::X64Reg xr);