backend/rv64: Implement AssertNoMoreUses and some minor tweaks
This commit is contained in:
parent
b7cca7c53d
commit
cc2a6fd6fb
3 changed files with 43 additions and 30 deletions
|
@ -40,6 +40,7 @@ void EmitIR<IR::Opcode::LogicalShiftLeft32>(biscuit::Assembler& as, EmitContext&
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::GetCarryFromOp>(biscuit::Assembler&, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::GetCarryFromOp>(biscuit::Assembler&, EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ASSERT(ctx.reg_alloc.IsValueLive(inst));
|
ASSERT(ctx.reg_alloc.IsValueLive(inst));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +94,9 @@ EmittedBlockInfo EmitRV64(biscuit::Assembler& as, IR::Block block, const EmitCon
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reg_alloc.AssertNoMoreUses();
|
||||||
|
|
||||||
// TODO: Add Cycles
|
// TODO: Add Cycles
|
||||||
|
|
||||||
// TODO: Emit Terminal
|
// TODO: Emit Terminal
|
||||||
|
|
|
@ -102,6 +102,13 @@ bool RegAlloc::IsValueLive(IR::Inst* inst) const {
|
||||||
return !!ValueLocation(inst);
|
return !!ValueLocation(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegAlloc::AssertNoMoreUses() const {
|
||||||
|
const auto is_empty = [](const auto& i) { return i.values.empty() && !i.locked && !i.realized && !i.accumulated_uses && !i.expected_uses; };
|
||||||
|
ASSERT(std::all_of(gprs.begin(), gprs.end(), is_empty));
|
||||||
|
ASSERT(std::all_of(fprs.begin(), fprs.end(), is_empty));
|
||||||
|
ASSERT(std::all_of(spills.begin(), spills.end(), is_empty));
|
||||||
|
}
|
||||||
|
|
||||||
template<HostLoc::Kind kind>
|
template<HostLoc::Kind kind>
|
||||||
u32 RegAlloc::GenerateImmediate(const IR::Value& value) {
|
u32 RegAlloc::GenerateImmediate(const IR::Value& value) {
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -141,26 +148,7 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
||||||
ASSERT(!ValueInfo(*current_location).realized);
|
ASSERT(!ValueInfo(*current_location).realized);
|
||||||
ASSERT(!ValueInfo(*current_location).locked);
|
ASSERT(!ValueInfo(*current_location).locked);
|
||||||
|
|
||||||
if constexpr (required_kind == HostLoc::Kind::Fpr) {
|
if constexpr (required_kind == HostLoc::Kind::Gpr) {
|
||||||
const u32 new_location_index = AllocateRegister(fprs, fpr_order);
|
|
||||||
SpillFpr(new_location_index);
|
|
||||||
|
|
||||||
switch (current_location->kind) {
|
|
||||||
case HostLoc::Kind::Gpr:
|
|
||||||
as.FMV_D_X(biscuit::FPR{new_location_index}, biscuit::GPR(current_location->index));
|
|
||||||
break;
|
|
||||||
case HostLoc::Kind::Fpr:
|
|
||||||
ASSERT_FALSE("Logic error");
|
|
||||||
break;
|
|
||||||
case HostLoc::Kind::Spill:
|
|
||||||
as.FLD(biscuit::FPR{new_location_index}, spill_offset + new_location_index * spill_slot_size, biscuit::sp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprs[new_location_index] = std::exchange(ValueInfo(*current_location), {});
|
|
||||||
fprs[new_location_index].realized = true;
|
|
||||||
return new_location_index;
|
|
||||||
} else if constexpr (required_kind == HostLoc::Kind::Gpr) {
|
|
||||||
const u32 new_location_index = AllocateRegister(gprs, gpr_order);
|
const u32 new_location_index = AllocateRegister(gprs, gpr_order);
|
||||||
SpillGpr(new_location_index);
|
SpillGpr(new_location_index);
|
||||||
|
|
||||||
|
@ -180,6 +168,25 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
||||||
gprs[new_location_index] = std::exchange(ValueInfo(*current_location), {});
|
gprs[new_location_index] = std::exchange(ValueInfo(*current_location), {});
|
||||||
gprs[new_location_index].realized = true;
|
gprs[new_location_index].realized = true;
|
||||||
return new_location_index;
|
return new_location_index;
|
||||||
|
} else if constexpr (required_kind == HostLoc::Kind::Fpr) {
|
||||||
|
const u32 new_location_index = AllocateRegister(fprs, fpr_order);
|
||||||
|
SpillFpr(new_location_index);
|
||||||
|
|
||||||
|
switch (current_location->kind) {
|
||||||
|
case HostLoc::Kind::Gpr:
|
||||||
|
as.FMV_D_X(biscuit::FPR{new_location_index}, biscuit::GPR(current_location->index));
|
||||||
|
break;
|
||||||
|
case HostLoc::Kind::Fpr:
|
||||||
|
ASSERT_FALSE("Logic error");
|
||||||
|
break;
|
||||||
|
case HostLoc::Kind::Spill:
|
||||||
|
as.FLD(biscuit::FPR{new_location_index}, spill_offset + new_location_index * spill_slot_size, biscuit::sp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprs[new_location_index] = std::exchange(ValueInfo(*current_location), {});
|
||||||
|
fprs[new_location_index].realized = true;
|
||||||
|
return new_location_index;
|
||||||
} else {
|
} else {
|
||||||
static_assert(Common::always_false_v<mcl::mp::lift_value<required_kind>>);
|
static_assert(Common::always_false_v<mcl::mp::lift_value<required_kind>>);
|
||||||
}
|
}
|
||||||
|
@ -194,19 +201,19 @@ u32 RegAlloc::RealizeWriteImpl(const IR::Inst* value) {
|
||||||
info.values.emplace_back(value);
|
info.values.emplace_back(value);
|
||||||
info.locked = true;
|
info.locked = true;
|
||||||
info.realized = true;
|
info.realized = true;
|
||||||
info.expected_uses += value->UseCount();
|
info.expected_uses = value->UseCount();
|
||||||
};
|
};
|
||||||
|
|
||||||
if constexpr (required_kind == HostLoc::Kind::Fpr) {
|
if constexpr (required_kind == HostLoc::Kind::Gpr) {
|
||||||
const u32 new_location_index = AllocateRegister(fprs, fpr_order);
|
|
||||||
SpillFpr(new_location_index);
|
|
||||||
setup_location(fprs[new_location_index]);
|
|
||||||
return new_location_index;
|
|
||||||
} else if constexpr (required_kind == HostLoc::Kind::Gpr) {
|
|
||||||
const u32 new_location_index = AllocateRegister(gprs, gpr_order);
|
const u32 new_location_index = AllocateRegister(gprs, gpr_order);
|
||||||
SpillGpr(new_location_index);
|
SpillGpr(new_location_index);
|
||||||
setup_location(gprs[new_location_index]);
|
setup_location(gprs[new_location_index]);
|
||||||
return new_location_index;
|
return new_location_index;
|
||||||
|
} else if constexpr (required_kind == HostLoc::Kind::Fpr) {
|
||||||
|
const u32 new_location_index = AllocateRegister(fprs, fpr_order);
|
||||||
|
SpillFpr(new_location_index);
|
||||||
|
setup_location(fprs[new_location_index]);
|
||||||
|
return new_location_index;
|
||||||
} else {
|
} else {
|
||||||
static_assert(Common::always_false_v<mcl::mp::lift_value<required_kind>>);
|
static_assert(Common::always_false_v<mcl::mp::lift_value<required_kind>>);
|
||||||
}
|
}
|
||||||
|
@ -305,13 +312,13 @@ HostLocInfo& RegAlloc::ValueInfo(const IR::Inst* value) {
|
||||||
return info.Contains(value);
|
return info.Contains(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (const auto iter = std::find_if(gprs.begin(), gprs.end(), contains_value)) {
|
if (const auto iter = std::find_if(gprs.begin(), gprs.end(), contains_value); iter != gprs.end()) {
|
||||||
return *iter;
|
return *iter;
|
||||||
}
|
}
|
||||||
if (const auto iter = std::find_if(fprs.begin(), fprs.end(), contains_value)) {
|
if (const auto iter = std::find_if(fprs.begin(), fprs.end(), contains_value); iter != gprs.end()) {
|
||||||
return *iter;
|
return *iter;
|
||||||
}
|
}
|
||||||
if (const auto iter = std::find_if(spills.begin(), spills.end(), contains_value)) {
|
if (const auto iter = std::find_if(spills.begin(), spills.end(), contains_value); iter != gprs.end()) {
|
||||||
return *iter;
|
return *iter;
|
||||||
}
|
}
|
||||||
ASSERT_FALSE("RegAlloc::ValueInfo: Value not found");
|
ASSERT_FALSE("RegAlloc::ValueInfo: Value not found");
|
||||||
|
|
|
@ -124,6 +124,8 @@ public:
|
||||||
(rs.Realize(), ...);
|
(rs.Realize(), ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssertNoMoreUses() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename>
|
template<typename>
|
||||||
friend struct RAReg;
|
friend struct RAReg;
|
||||||
|
|
Loading…
Reference in a new issue