Better validation that values aren't moving between blocks.

This commit is contained in:
Ben Vanik 2014-08-06 09:00:59 -07:00
parent ff59f23de0
commit 19274ef26d
3 changed files with 16 additions and 2 deletions

View File

@ -143,7 +143,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) {
if (!allocated) {
// Failed to allocate register -- need to spill and try again.
// 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.
XELOGE("Unable to spill any registers");
assert_always();
@ -237,6 +237,8 @@ void RegisterAllocationPass::AdvanceUses(Instr* instr) {
// Remove the iterator.
auto value = it->value;
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);
}
}
@ -336,6 +338,8 @@ bool RegisterAllocationPass::SpillOneRegister(HIRBuilder* builder,
auto furthest_usage = std::max_element(usage_set->upcoming_uses.begin(),
usage_set->upcoming_uses.end(),
RegisterUsage::Comparer());
assert_true(furthest_usage->value->def->block == block);
assert_true(furthest_usage->use->instr->block == block);
auto spill_value = furthest_usage->value;
Value::Use* prev_use = furthest_usage->use->prev;
Value::Use* next_use = furthest_usage->use;

View File

@ -62,7 +62,8 @@ class RegisterAllocationPass : public CompilerPass {
bool TryAllocateRegister(hir::Value* value,
const hir::RegAssignment& preferred_reg);
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);

View File

@ -72,6 +72,15 @@ int ValidationPass::ValidateInstruction(Block* block, Instr* instr) {
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;
if (GET_OPCODE_SIG_TYPE_SRC1(signature) == OPCODE_SIG_TYPE_V) {
if (ValidateValue(block, instr, instr->src1.value)) {