microinstruction: Make use_count private (#53)

Makes the operation a part of the direct interface.
This commit is contained in:
Mat M 2016-11-30 16:51:06 -05:00 committed by Merry
parent 3621a925b2
commit de1f831d79
6 changed files with 31 additions and 32 deletions

View file

@ -473,7 +473,7 @@ void EmitX64::EmitMostSignificantWord(IR::Block& block, IR::Inst* inst) {
if (carry_inst) { if (carry_inst) {
EraseInstruction(block, carry_inst); EraseInstruction(block, carry_inst);
reg_alloc.DecrementRemainingUses(inst); inst->DecrementRemainingUses();
Xbyak::Reg64 carry = reg_alloc.DefGpr(carry_inst); Xbyak::Reg64 carry = reg_alloc.DefGpr(carry_inst);
code->setc(carry.cvt8()); code->setc(carry.cvt8());
@ -524,7 +524,7 @@ void EmitX64::EmitLogicalShiftLeft(IR::Block& block, IR::Inst* inst) {
if (!carry_inst) { if (!carry_inst) {
if (!inst->GetArg(2).IsImmediate()) { if (!inst->GetArg(2).IsImmediate()) {
// TODO: Remove redundant argument. // TODO: Remove redundant argument.
reg_alloc.DecrementRemainingUses(inst->GetArg(2).GetInst()); inst->GetArg(2).GetInst()->DecrementRemainingUses();
} }
auto shift_arg = inst->GetArg(1); auto shift_arg = inst->GetArg(1);
@ -553,7 +553,7 @@ void EmitX64::EmitLogicalShiftLeft(IR::Block& block, IR::Inst* inst) {
} }
} else { } else {
EraseInstruction(block, carry_inst); EraseInstruction(block, carry_inst);
reg_alloc.DecrementRemainingUses(inst); inst->DecrementRemainingUses();
auto shift_arg = inst->GetArg(1); auto shift_arg = inst->GetArg(1);
@ -617,7 +617,7 @@ void EmitX64::EmitLogicalShiftRight(IR::Block& block, IR::Inst* inst) {
if (!carry_inst) { if (!carry_inst) {
if (!inst->GetArg(2).IsImmediate()) { if (!inst->GetArg(2).IsImmediate()) {
// TODO: Remove redundant argument. // TODO: Remove redundant argument.
reg_alloc.DecrementRemainingUses(inst->GetArg(2).GetInst()); inst->GetArg(2).GetInst()->DecrementRemainingUses();
} }
auto shift_arg = inst->GetArg(1); auto shift_arg = inst->GetArg(1);
@ -646,7 +646,7 @@ void EmitX64::EmitLogicalShiftRight(IR::Block& block, IR::Inst* inst) {
} }
} else { } else {
EraseInstruction(block, carry_inst); EraseInstruction(block, carry_inst);
reg_alloc.DecrementRemainingUses(inst); inst->DecrementRemainingUses();
auto shift_arg = inst->GetArg(1); auto shift_arg = inst->GetArg(1);
@ -722,7 +722,7 @@ void EmitX64::EmitArithmeticShiftRight(IR::Block& block, IR::Inst* inst) {
if (!carry_inst) { if (!carry_inst) {
if (!inst->GetArg(2).IsImmediate()) { if (!inst->GetArg(2).IsImmediate()) {
// TODO: Remove redundant argument. // TODO: Remove redundant argument.
reg_alloc.DecrementRemainingUses(inst->GetArg(2).GetInst()); inst->GetArg(2).GetInst()->DecrementRemainingUses();
} }
auto shift_arg = inst->GetArg(1); auto shift_arg = inst->GetArg(1);
@ -749,7 +749,7 @@ void EmitX64::EmitArithmeticShiftRight(IR::Block& block, IR::Inst* inst) {
} }
} else { } else {
EraseInstruction(block, carry_inst); EraseInstruction(block, carry_inst);
reg_alloc.DecrementRemainingUses(inst); inst->DecrementRemainingUses();
auto shift_arg = inst->GetArg(1); auto shift_arg = inst->GetArg(1);
@ -805,7 +805,7 @@ void EmitX64::EmitRotateRight(IR::Block& block, IR::Inst* inst) {
if (!carry_inst) { if (!carry_inst) {
if (!inst->GetArg(2).IsImmediate()) { if (!inst->GetArg(2).IsImmediate()) {
// TODO: Remove redundant argument. // TODO: Remove redundant argument.
reg_alloc.DecrementRemainingUses(inst->GetArg(2).GetInst()); inst->GetArg(2).GetInst()->DecrementRemainingUses();
} }
auto shift_arg = inst->GetArg(1); auto shift_arg = inst->GetArg(1);
@ -824,7 +824,7 @@ void EmitX64::EmitRotateRight(IR::Block& block, IR::Inst* inst) {
} }
} else { } else {
EraseInstruction(block, carry_inst); EraseInstruction(block, carry_inst);
reg_alloc.DecrementRemainingUses(inst); inst->DecrementRemainingUses();
auto shift_arg = inst->GetArg(1); auto shift_arg = inst->GetArg(1);
@ -886,7 +886,7 @@ void EmitX64::EmitRotateRightExtended(IR::Block& block, IR::Inst* inst) {
if (carry_inst) { if (carry_inst) {
EraseInstruction(block, carry_inst); EraseInstruction(block, carry_inst);
reg_alloc.DecrementRemainingUses(inst); inst->DecrementRemainingUses();
code->setc(carry); code->setc(carry);
} }
} }
@ -946,12 +946,12 @@ void EmitX64::EmitAddWithCarry(IR::Block& block, IR::Inst* inst) {
if (carry_inst) { if (carry_inst) {
EraseInstruction(block, carry_inst); EraseInstruction(block, carry_inst);
reg_alloc.DecrementRemainingUses(inst); inst->DecrementRemainingUses();
code->setc(carry); code->setc(carry);
} }
if (overflow_inst) { if (overflow_inst) {
EraseInstruction(block, overflow_inst); EraseInstruction(block, overflow_inst);
reg_alloc.DecrementRemainingUses(inst); inst->DecrementRemainingUses();
code->seto(overflow); code->seto(overflow);
} }
} }
@ -1015,12 +1015,12 @@ void EmitX64::EmitSubWithCarry(IR::Block& block, IR::Inst* inst) {
if (carry_inst) { if (carry_inst) {
EraseInstruction(block, carry_inst); EraseInstruction(block, carry_inst);
reg_alloc.DecrementRemainingUses(inst); inst->DecrementRemainingUses();
code->setnc(carry); code->setnc(carry);
} }
if (overflow_inst) { if (overflow_inst) {
EraseInstruction(block, overflow_inst); EraseInstruction(block, overflow_inst);
reg_alloc.DecrementRemainingUses(inst); inst->DecrementRemainingUses();
code->seto(overflow); code->seto(overflow);
} }
} }

View file

@ -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"); DEBUG_ASSERT_MSG(ValueLocation(use_inst.GetInst()), "use_inst must already be defined");
HostLoc location = *ValueLocation(use_inst.GetInst()); HostLoc location = *ValueLocation(use_inst.GetInst());
LocInfo(location).values.emplace_back(def_inst); LocInfo(location).values.emplace_back(def_inst);
DecrementRemainingUses(use_inst.GetInst()); use_inst.GetInst()->DecrementRemainingUses();
DEBUG_ASSERT(LocInfo(location).IsIdle()); DEBUG_ASSERT(LocInfo(location).IsIdle());
} }
@ -233,7 +233,7 @@ HostLoc RegAlloc::UseScratchHostLocReg(IR::Inst* use_inst, HostLocList desired_l
if (HostLocIsSpill(current_location)) { if (HostLocIsSpill(current_location)) {
EmitMove(new_location, current_location); EmitMove(new_location, current_location);
LocInfo(new_location).is_being_used = true; LocInfo(new_location).is_being_used = true;
DecrementRemainingUses(use_inst); use_inst->DecrementRemainingUses();
DEBUG_ASSERT(LocInfo(new_location).IsScratch()); DEBUG_ASSERT(LocInfo(new_location).IsScratch());
return new_location; return new_location;
} else if (HostLocIsRegister(current_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).is_being_used = true;
LocInfo(new_location).values.clear(); LocInfo(new_location).values.clear();
DecrementRemainingUses(use_inst); use_inst->DecrementRemainingUses();
DEBUG_ASSERT(LocInfo(new_location).IsScratch()); DEBUG_ASSERT(LocInfo(new_location).IsScratch());
return new_location; return new_location;
} }
@ -348,7 +348,7 @@ bool RegAlloc::IsRegisterAllocated(HostLoc loc) const {
} }
bool RegAlloc::IsLastUse(const IR::Inst* inst) const { bool RegAlloc::IsLastUse(const IR::Inst* inst) const {
if (inst->use_count > 1) if (inst->UseCount() > 1)
return false; return false;
return LocInfo(*ValueLocation(inst)).values.size() == 1; 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() { void RegAlloc::AssertNoMoreUses() {
ASSERT(std::all_of(hostloc_info.begin(), hostloc_info.end(), [](const auto& i){ return i.values.empty(); })); 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); EmitMove(new_location, current_location);
LocInfo(new_location).is_being_used = true; LocInfo(new_location).is_being_used = true;
LocInfo(new_location).values.emplace_back(use_inst); LocInfo(new_location).values.emplace_back(use_inst);
DecrementRemainingUses(use_inst); use_inst->DecrementRemainingUses();
DEBUG_ASSERT(LocInfo(new_location).IsUse()); DEBUG_ASSERT(LocInfo(new_location).IsUse());
return std::make_tuple(new_location, false); return std::make_tuple(new_location, false);
} else { } else {
bool was_being_used = LocInfo(current_location).is_being_used; bool was_being_used = LocInfo(current_location).is_being_used;
ASSERT(LocInfo(current_location).IsUse() || LocInfo(current_location).IsIdle()); ASSERT(LocInfo(current_location).IsUse() || LocInfo(current_location).IsIdle());
LocInfo(current_location).is_being_used = true; LocInfo(current_location).is_being_used = true;
DecrementRemainingUses(use_inst); use_inst->DecrementRemainingUses();
DEBUG_ASSERT(LocInfo(current_location).IsUse()); DEBUG_ASSERT(LocInfo(current_location).IsUse());
return std::make_tuple(current_location, was_being_used); 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)) { if (HostLocIsSpill(current_location)) {
bool was_being_used = LocInfo(current_location).is_being_used; bool was_being_used = LocInfo(current_location).is_being_used;
LocInfo(current_location).is_being_used = true; LocInfo(current_location).is_being_used = true;
DecrementRemainingUses(use_inst); use_inst->DecrementRemainingUses();
DEBUG_ASSERT(LocInfo(current_location).IsUse()); DEBUG_ASSERT(LocInfo(current_location).IsUse());
return std::make_tuple(current_location, was_being_used); return std::make_tuple(current_location, was_being_used);
} else if (HostLocIsRegister(current_location)) { } 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); EmitExchange(new_location, current_location);
std::swap(LocInfo(new_location), LocInfo(current_location)); std::swap(LocInfo(new_location), LocInfo(current_location));
LocInfo(new_location).is_being_used = true; LocInfo(new_location).is_being_used = true;
DecrementRemainingUses(use_inst); use_inst->DecrementRemainingUses();
DEBUG_ASSERT(LocInfo(new_location).IsUse()); DEBUG_ASSERT(LocInfo(new_location).IsUse());
return std::make_tuple(new_location, false); return std::make_tuple(new_location, false);
} }

View file

@ -143,8 +143,6 @@ public:
// TODO: Values in host flags // TODO: Values in host flags
void DecrementRemainingUses(IR::Inst* value);
void EndOfAllocScope(); void EndOfAllocScope();
void AssertNoMoreUses(); void AssertNoMoreUses();

View file

@ -217,7 +217,11 @@ bool Inst::MayHaveSideEffects() const {
WritesToFPSCR() || WritesToFPSCR() ||
AltersExclusiveState() || AltersExclusiveState() ||
IsMemoryWrite(); IsMemoryWrite();
}
void Inst::DecrementRemainingUses() {
ASSERT_MSG(HasUses(), "Microinstruction doesn't have any remaining uses");
use_count--;
} }
Inst* Inst::GetAssociatedPseudoOperation(Opcode opcode) { Inst* Inst::GetAssociatedPseudoOperation(Opcode opcode) {

View file

@ -73,7 +73,10 @@ public:
/// Determines whether or not this instruction may have side-effects. /// Determines whether or not this instruction may have side-effects.
bool MayHaveSideEffects() const; bool MayHaveSideEffects() const;
size_t UseCount() const { return use_count; }
bool HasUses() const { return use_count > 0; } bool HasUses() const { return use_count > 0; }
void DecrementRemainingUses();
/// Gets a pseudo-operation associated with this instruction. /// Gets a pseudo-operation associated with this instruction.
Inst* GetAssociatedPseudoOperation(Opcode opcode); Inst* GetAssociatedPseudoOperation(Opcode opcode);
@ -91,13 +94,12 @@ public:
void ReplaceUsesWith(Value& replacement); void ReplaceUsesWith(Value& replacement);
size_t use_count = 0;
private: private:
void Use(Value& value); void Use(Value& value);
void UndoUse(Value& value); void UndoUse(Value& value);
Opcode op; Opcode op;
size_t use_count = 0;
std::array<Value, 3> args; std::array<Value, 3> args;
Inst* carry_inst = nullptr; Inst* carry_inst = nullptr;

View file

@ -37,7 +37,7 @@ void VerificationPass(const IR::Block& block) {
} }
for (const auto& pair : actual_uses) { for (const auto& pair : actual_uses) {
ASSERT(pair.first->use_count == pair.second); ASSERT(pair.first->UseCount() == pair.second);
} }
} }