diff --git a/src/backend_x64/emit_x64.cpp b/src/backend_x64/emit_x64.cpp index 6052a12b..f9de17a8 100644 --- a/src/backend_x64/emit_x64.cpp +++ b/src/backend_x64/emit_x64.cpp @@ -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); } } diff --git a/src/backend_x64/reg_alloc.cpp b/src/backend_x64/reg_alloc.cpp index 925ed136..47e4fd5c 100644 --- a/src/backend_x64/reg_alloc.cpp +++ b/src/backend_x64/reg_alloc.cpp @@ -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 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 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 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); } diff --git a/src/backend_x64/reg_alloc.h b/src/backend_x64/reg_alloc.h index bfaa412e..c4f0b642 100644 --- a/src/backend_x64/reg_alloc.h +++ b/src/backend_x64/reg_alloc.h @@ -143,8 +143,6 @@ public: // TODO: Values in host flags - void DecrementRemainingUses(IR::Inst* value); - void EndOfAllocScope(); void AssertNoMoreUses(); diff --git a/src/frontend/ir/microinstruction.cpp b/src/frontend/ir/microinstruction.cpp index 92f5dbbc..eabfa83e 100644 --- a/src/frontend/ir/microinstruction.cpp +++ b/src/frontend/ir/microinstruction.cpp @@ -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) { diff --git a/src/frontend/ir/microinstruction.h b/src/frontend/ir/microinstruction.h index ed4e1e80..c9634a20 100644 --- a/src/frontend/ir/microinstruction.h +++ b/src/frontend/ir/microinstruction.h @@ -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 args; Inst* carry_inst = nullptr; diff --git a/src/ir_opt/verification_pass.cpp b/src/ir_opt/verification_pass.cpp index 32699ec1..5573f36e 100644 --- a/src/ir_opt/verification_pass.cpp +++ b/src/ir_opt/verification_pass.cpp @@ -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); } }