microinstruction: Make use_count private (#53)
Makes the operation a part of the direct interface.
This commit is contained in:
parent
3621a925b2
commit
de1f831d79
6 changed files with 31 additions and 32 deletions
|
@ -473,7 +473,7 @@ void EmitX64::EmitMostSignificantWord(IR::Block& block, IR::Inst* inst) {
|
|||
|
||||
if (carry_inst) {
|
||||
EraseInstruction(block, carry_inst);
|
||||
reg_alloc.DecrementRemainingUses(inst);
|
||||
inst->DecrementRemainingUses();
|
||||
Xbyak::Reg64 carry = reg_alloc.DefGpr(carry_inst);
|
||||
|
||||
code->setc(carry.cvt8());
|
||||
|
@ -524,7 +524,7 @@ void EmitX64::EmitLogicalShiftLeft(IR::Block& block, IR::Inst* inst) {
|
|||
if (!carry_inst) {
|
||||
if (!inst->GetArg(2).IsImmediate()) {
|
||||
// TODO: Remove redundant argument.
|
||||
reg_alloc.DecrementRemainingUses(inst->GetArg(2).GetInst());
|
||||
inst->GetArg(2).GetInst()->DecrementRemainingUses();
|
||||
}
|
||||
|
||||
auto shift_arg = inst->GetArg(1);
|
||||
|
@ -553,7 +553,7 @@ void EmitX64::EmitLogicalShiftLeft(IR::Block& block, IR::Inst* inst) {
|
|||
}
|
||||
} else {
|
||||
EraseInstruction(block, carry_inst);
|
||||
reg_alloc.DecrementRemainingUses(inst);
|
||||
inst->DecrementRemainingUses();
|
||||
|
||||
auto shift_arg = inst->GetArg(1);
|
||||
|
||||
|
@ -617,7 +617,7 @@ void EmitX64::EmitLogicalShiftRight(IR::Block& block, IR::Inst* inst) {
|
|||
if (!carry_inst) {
|
||||
if (!inst->GetArg(2).IsImmediate()) {
|
||||
// TODO: Remove redundant argument.
|
||||
reg_alloc.DecrementRemainingUses(inst->GetArg(2).GetInst());
|
||||
inst->GetArg(2).GetInst()->DecrementRemainingUses();
|
||||
}
|
||||
|
||||
auto shift_arg = inst->GetArg(1);
|
||||
|
@ -646,7 +646,7 @@ void EmitX64::EmitLogicalShiftRight(IR::Block& block, IR::Inst* inst) {
|
|||
}
|
||||
} else {
|
||||
EraseInstruction(block, carry_inst);
|
||||
reg_alloc.DecrementRemainingUses(inst);
|
||||
inst->DecrementRemainingUses();
|
||||
|
||||
auto shift_arg = inst->GetArg(1);
|
||||
|
||||
|
@ -722,7 +722,7 @@ void EmitX64::EmitArithmeticShiftRight(IR::Block& block, IR::Inst* inst) {
|
|||
if (!carry_inst) {
|
||||
if (!inst->GetArg(2).IsImmediate()) {
|
||||
// TODO: Remove redundant argument.
|
||||
reg_alloc.DecrementRemainingUses(inst->GetArg(2).GetInst());
|
||||
inst->GetArg(2).GetInst()->DecrementRemainingUses();
|
||||
}
|
||||
|
||||
auto shift_arg = inst->GetArg(1);
|
||||
|
@ -749,7 +749,7 @@ void EmitX64::EmitArithmeticShiftRight(IR::Block& block, IR::Inst* inst) {
|
|||
}
|
||||
} else {
|
||||
EraseInstruction(block, carry_inst);
|
||||
reg_alloc.DecrementRemainingUses(inst);
|
||||
inst->DecrementRemainingUses();
|
||||
|
||||
auto shift_arg = inst->GetArg(1);
|
||||
|
||||
|
@ -805,7 +805,7 @@ void EmitX64::EmitRotateRight(IR::Block& block, IR::Inst* inst) {
|
|||
if (!carry_inst) {
|
||||
if (!inst->GetArg(2).IsImmediate()) {
|
||||
// TODO: Remove redundant argument.
|
||||
reg_alloc.DecrementRemainingUses(inst->GetArg(2).GetInst());
|
||||
inst->GetArg(2).GetInst()->DecrementRemainingUses();
|
||||
}
|
||||
|
||||
auto shift_arg = inst->GetArg(1);
|
||||
|
@ -824,7 +824,7 @@ void EmitX64::EmitRotateRight(IR::Block& block, IR::Inst* inst) {
|
|||
}
|
||||
} else {
|
||||
EraseInstruction(block, carry_inst);
|
||||
reg_alloc.DecrementRemainingUses(inst);
|
||||
inst->DecrementRemainingUses();
|
||||
|
||||
auto shift_arg = inst->GetArg(1);
|
||||
|
||||
|
@ -886,7 +886,7 @@ void EmitX64::EmitRotateRightExtended(IR::Block& block, IR::Inst* inst) {
|
|||
|
||||
if (carry_inst) {
|
||||
EraseInstruction(block, carry_inst);
|
||||
reg_alloc.DecrementRemainingUses(inst);
|
||||
inst->DecrementRemainingUses();
|
||||
code->setc(carry);
|
||||
}
|
||||
}
|
||||
|
@ -946,12 +946,12 @@ void EmitX64::EmitAddWithCarry(IR::Block& block, IR::Inst* inst) {
|
|||
|
||||
if (carry_inst) {
|
||||
EraseInstruction(block, carry_inst);
|
||||
reg_alloc.DecrementRemainingUses(inst);
|
||||
inst->DecrementRemainingUses();
|
||||
code->setc(carry);
|
||||
}
|
||||
if (overflow_inst) {
|
||||
EraseInstruction(block, overflow_inst);
|
||||
reg_alloc.DecrementRemainingUses(inst);
|
||||
inst->DecrementRemainingUses();
|
||||
code->seto(overflow);
|
||||
}
|
||||
}
|
||||
|
@ -1015,12 +1015,12 @@ void EmitX64::EmitSubWithCarry(IR::Block& block, IR::Inst* inst) {
|
|||
|
||||
if (carry_inst) {
|
||||
EraseInstruction(block, carry_inst);
|
||||
reg_alloc.DecrementRemainingUses(inst);
|
||||
inst->DecrementRemainingUses();
|
||||
code->setnc(carry);
|
||||
}
|
||||
if (overflow_inst) {
|
||||
EraseInstruction(block, overflow_inst);
|
||||
reg_alloc.DecrementRemainingUses(inst);
|
||||
inst->DecrementRemainingUses();
|
||||
code->seto(overflow);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ void RegAlloc::RegisterAddDef(IR::Inst* def_inst, const IR::Value& use_inst) {
|
|||
DEBUG_ASSERT_MSG(ValueLocation(use_inst.GetInst()), "use_inst must already be defined");
|
||||
HostLoc location = *ValueLocation(use_inst.GetInst());
|
||||
LocInfo(location).values.emplace_back(def_inst);
|
||||
DecrementRemainingUses(use_inst.GetInst());
|
||||
use_inst.GetInst()->DecrementRemainingUses();
|
||||
DEBUG_ASSERT(LocInfo(location).IsIdle());
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ HostLoc RegAlloc::UseScratchHostLocReg(IR::Inst* use_inst, HostLocList desired_l
|
|||
if (HostLocIsSpill(current_location)) {
|
||||
EmitMove(new_location, current_location);
|
||||
LocInfo(new_location).is_being_used = true;
|
||||
DecrementRemainingUses(use_inst);
|
||||
use_inst->DecrementRemainingUses();
|
||||
DEBUG_ASSERT(LocInfo(new_location).IsScratch());
|
||||
return new_location;
|
||||
} else if (HostLocIsRegister(current_location)) {
|
||||
|
@ -249,7 +249,7 @@ HostLoc RegAlloc::UseScratchHostLocReg(IR::Inst* use_inst, HostLocList desired_l
|
|||
|
||||
LocInfo(new_location).is_being_used = true;
|
||||
LocInfo(new_location).values.clear();
|
||||
DecrementRemainingUses(use_inst);
|
||||
use_inst->DecrementRemainingUses();
|
||||
DEBUG_ASSERT(LocInfo(new_location).IsScratch());
|
||||
return new_location;
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ bool RegAlloc::IsRegisterAllocated(HostLoc loc) const {
|
|||
}
|
||||
|
||||
bool RegAlloc::IsLastUse(const IR::Inst* inst) const {
|
||||
if (inst->use_count > 1)
|
||||
if (inst->UseCount() > 1)
|
||||
return false;
|
||||
return LocInfo(*ValueLocation(inst)).values.size() == 1;
|
||||
}
|
||||
|
@ -390,11 +390,6 @@ void RegAlloc::EndOfAllocScope() {
|
|||
}
|
||||
}
|
||||
|
||||
void RegAlloc::DecrementRemainingUses(IR::Inst* value) {
|
||||
ASSERT_MSG(value->HasUses(), "value doesn't have any remaining uses");
|
||||
value->use_count--;
|
||||
}
|
||||
|
||||
void RegAlloc::AssertNoMoreUses() {
|
||||
ASSERT(std::all_of(hostloc_info.begin(), hostloc_info.end(), [](const auto& i){ return i.values.empty(); }));
|
||||
}
|
||||
|
@ -446,14 +441,14 @@ std::tuple<HostLoc, bool> RegAlloc::UseHostLoc(IR::Inst* use_inst, HostLocList d
|
|||
EmitMove(new_location, current_location);
|
||||
LocInfo(new_location).is_being_used = true;
|
||||
LocInfo(new_location).values.emplace_back(use_inst);
|
||||
DecrementRemainingUses(use_inst);
|
||||
use_inst->DecrementRemainingUses();
|
||||
DEBUG_ASSERT(LocInfo(new_location).IsUse());
|
||||
return std::make_tuple(new_location, false);
|
||||
} else {
|
||||
bool was_being_used = LocInfo(current_location).is_being_used;
|
||||
ASSERT(LocInfo(current_location).IsUse() || LocInfo(current_location).IsIdle());
|
||||
LocInfo(current_location).is_being_used = true;
|
||||
DecrementRemainingUses(use_inst);
|
||||
use_inst->DecrementRemainingUses();
|
||||
DEBUG_ASSERT(LocInfo(current_location).IsUse());
|
||||
return std::make_tuple(current_location, was_being_used);
|
||||
}
|
||||
|
@ -462,7 +457,7 @@ std::tuple<HostLoc, bool> RegAlloc::UseHostLoc(IR::Inst* use_inst, HostLocList d
|
|||
if (HostLocIsSpill(current_location)) {
|
||||
bool was_being_used = LocInfo(current_location).is_being_used;
|
||||
LocInfo(current_location).is_being_used = true;
|
||||
DecrementRemainingUses(use_inst);
|
||||
use_inst->DecrementRemainingUses();
|
||||
DEBUG_ASSERT(LocInfo(current_location).IsUse());
|
||||
return std::make_tuple(current_location, was_being_used);
|
||||
} else if (HostLocIsRegister(current_location)) {
|
||||
|
@ -471,7 +466,7 @@ std::tuple<HostLoc, bool> RegAlloc::UseHostLoc(IR::Inst* use_inst, HostLocList d
|
|||
EmitExchange(new_location, current_location);
|
||||
std::swap(LocInfo(new_location), LocInfo(current_location));
|
||||
LocInfo(new_location).is_being_used = true;
|
||||
DecrementRemainingUses(use_inst);
|
||||
use_inst->DecrementRemainingUses();
|
||||
DEBUG_ASSERT(LocInfo(new_location).IsUse());
|
||||
return std::make_tuple(new_location, false);
|
||||
}
|
||||
|
|
|
@ -143,8 +143,6 @@ public:
|
|||
|
||||
// TODO: Values in host flags
|
||||
|
||||
void DecrementRemainingUses(IR::Inst* value);
|
||||
|
||||
void EndOfAllocScope();
|
||||
|
||||
void AssertNoMoreUses();
|
||||
|
|
|
@ -217,7 +217,11 @@ bool Inst::MayHaveSideEffects() const {
|
|||
WritesToFPSCR() ||
|
||||
AltersExclusiveState() ||
|
||||
IsMemoryWrite();
|
||||
}
|
||||
|
||||
void Inst::DecrementRemainingUses() {
|
||||
ASSERT_MSG(HasUses(), "Microinstruction doesn't have any remaining uses");
|
||||
use_count--;
|
||||
}
|
||||
|
||||
Inst* Inst::GetAssociatedPseudoOperation(Opcode opcode) {
|
||||
|
|
|
@ -73,7 +73,10 @@ public:
|
|||
/// Determines whether or not this instruction may have side-effects.
|
||||
bool MayHaveSideEffects() const;
|
||||
|
||||
size_t UseCount() const { return use_count; }
|
||||
bool HasUses() const { return use_count > 0; }
|
||||
void DecrementRemainingUses();
|
||||
|
||||
/// Gets a pseudo-operation associated with this instruction.
|
||||
Inst* GetAssociatedPseudoOperation(Opcode opcode);
|
||||
|
||||
|
@ -91,13 +94,12 @@ public:
|
|||
|
||||
void ReplaceUsesWith(Value& replacement);
|
||||
|
||||
size_t use_count = 0;
|
||||
|
||||
private:
|
||||
void Use(Value& value);
|
||||
void UndoUse(Value& value);
|
||||
|
||||
Opcode op;
|
||||
size_t use_count = 0;
|
||||
std::array<Value, 3> args;
|
||||
|
||||
Inst* carry_inst = nullptr;
|
||||
|
|
|
@ -37,7 +37,7 @@ void VerificationPass(const IR::Block& block) {
|
|||
}
|
||||
|
||||
for (const auto& pair : actual_uses) {
|
||||
ASSERT(pair.first->use_count == pair.second);
|
||||
ASSERT(pair.first->UseCount() == pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue