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
{
public:
bool IsActive() const { return realized || bind || write || read || kill_imm; }
bool IsRealized() const { return realized; }
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()
bool IsRealized() const { return realized != RealizedLoc::Invalid; }
bool IsActive() const
{
realized = true;
bind = true;
return IsRealized() || write || read || kill_imm || kill_mem || revertable;
}
void AddUse(RCMode mode) { AddConstraint(false, mode, false, false); }
void AddUseNoImm(RCMode mode) { AddConstraint(false, mode, true, false); }
void AddBind(RCMode mode) { AddConstraint(true, mode, false, false); }
void AddRevertableBind(RCMode mode) { AddConstraint(true, mode, false, true); }
bool ShouldLoad() const { return read; }
bool ShouldDirty() const { return write; }
bool ShouldBeRevertable() const { return revertable; }
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:
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;
}
if (should_bind)
bind = true;
if (should_kill_imm)
kill_imm = true;
if (should_revertable)
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)
{
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)
return false;
switch (mode)
{
case RCMode::Read:
return read;
case RCMode::Write:
return write;
case RCMode::ReadWrite:
return read && write;
return false;
}
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;
bool bind = false;
RealizedLoc realized = RealizedLoc::Invalid;
bool write = false;
bool read = false;
bool kill_imm = false;
bool kill_mem = false;
bool revertable = false;
};

View File

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

View File

@ -234,6 +234,7 @@ public:
RCOpArg Use(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 RevertableBind(preg_t preg, RCMode mode);
RCX64Reg Scratch(Gen::X64Reg xr);