mirror of
https://github.com/xenia-project/xenia.git
synced 2025-01-06 02:39:02 +00:00
Better validation that values aren't moving between blocks.
This commit is contained in:
parent
ff59f23de0
commit
19274ef26d
@ -143,7 +143,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) {
|
|||||||
if (!allocated) {
|
if (!allocated) {
|
||||||
// Failed to allocate register -- need to spill and try again.
|
// Failed to allocate register -- need to spill and try again.
|
||||||
// We spill only those registers we aren't using.
|
// We spill only those registers we aren't using.
|
||||||
if (!SpillOneRegister(builder, instr->dest->type)) {
|
if (!SpillOneRegister(builder, block, instr->dest->type)) {
|
||||||
// Unable to spill anything - this shouldn't happen.
|
// Unable to spill anything - this shouldn't happen.
|
||||||
XELOGE("Unable to spill any registers");
|
XELOGE("Unable to spill any registers");
|
||||||
assert_always();
|
assert_always();
|
||||||
@ -237,6 +237,8 @@ void RegisterAllocationPass::AdvanceUses(Instr* instr) {
|
|||||||
// Remove the iterator.
|
// Remove the iterator.
|
||||||
auto value = it->value;
|
auto value = it->value;
|
||||||
it = upcoming_uses.erase(it);
|
it = upcoming_uses.erase(it);
|
||||||
|
assert_true(next_use->instr->block == instr->block);
|
||||||
|
assert_true(value->def->block == instr->block);
|
||||||
upcoming_uses.emplace_back(value, next_use);
|
upcoming_uses.emplace_back(value, next_use);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -336,6 +338,8 @@ bool RegisterAllocationPass::SpillOneRegister(HIRBuilder* builder,
|
|||||||
auto furthest_usage = std::max_element(usage_set->upcoming_uses.begin(),
|
auto furthest_usage = std::max_element(usage_set->upcoming_uses.begin(),
|
||||||
usage_set->upcoming_uses.end(),
|
usage_set->upcoming_uses.end(),
|
||||||
RegisterUsage::Comparer());
|
RegisterUsage::Comparer());
|
||||||
|
assert_true(furthest_usage->value->def->block == block);
|
||||||
|
assert_true(furthest_usage->use->instr->block == block);
|
||||||
auto spill_value = furthest_usage->value;
|
auto spill_value = furthest_usage->value;
|
||||||
Value::Use* prev_use = furthest_usage->use->prev;
|
Value::Use* prev_use = furthest_usage->use->prev;
|
||||||
Value::Use* next_use = furthest_usage->use;
|
Value::Use* next_use = furthest_usage->use;
|
||||||
|
@ -62,7 +62,8 @@ class RegisterAllocationPass : public CompilerPass {
|
|||||||
bool TryAllocateRegister(hir::Value* value,
|
bool TryAllocateRegister(hir::Value* value,
|
||||||
const hir::RegAssignment& preferred_reg);
|
const hir::RegAssignment& preferred_reg);
|
||||||
bool TryAllocateRegister(hir::Value* value);
|
bool TryAllocateRegister(hir::Value* value);
|
||||||
bool SpillOneRegister(hir::HIRBuilder* builder, hir::TypeName required_type);
|
bool SpillOneRegister(hir::HIRBuilder* builder, hir::Block* block,
|
||||||
|
hir::TypeName required_type);
|
||||||
|
|
||||||
RegisterSetUsage* RegisterSetForValue(const hir::Value* value);
|
RegisterSetUsage* RegisterSetForValue(const hir::Value* value);
|
||||||
|
|
||||||
|
@ -72,6 +72,15 @@ int ValidationPass::ValidateInstruction(Block* block, Instr* instr) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instr->dest) {
|
||||||
|
assert_true(instr->dest->def == instr);
|
||||||
|
auto use = instr->dest->use_head;
|
||||||
|
while (use) {
|
||||||
|
assert_true(use->instr->block == block);
|
||||||
|
use = use->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t signature = instr->opcode->signature;
|
uint32_t signature = instr->opcode->signature;
|
||||||
if (GET_OPCODE_SIG_TYPE_SRC1(signature) == OPCODE_SIG_TYPE_V) {
|
if (GET_OPCODE_SIG_TYPE_SRC1(signature) == OPCODE_SIG_TYPE_V) {
|
||||||
if (ValidateValue(block, instr, instr->src1.value)) {
|
if (ValidateValue(block, instr, instr->src1.value)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user