JitRegCache: Add BindOrImm
This commit is contained in:
parent
590ec866b0
commit
2e955012b2
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue