From 19274ef26d65303294cfc5a37e2b28536fc1cffc Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 09:00:59 -0700 Subject: [PATCH] Better validation that values aren't moving between blocks. --- src/alloy/compiler/passes/register_allocation_pass.cc | 6 +++++- src/alloy/compiler/passes/register_allocation_pass.h | 3 ++- src/alloy/compiler/passes/validation_pass.cc | 9 +++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc index 00f60179a..1481e80d4 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.cc +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -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; diff --git a/src/alloy/compiler/passes/register_allocation_pass.h b/src/alloy/compiler/passes/register_allocation_pass.h index aa8b03fb2..6090ed527 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.h +++ b/src/alloy/compiler/passes/register_allocation_pass.h @@ -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); diff --git a/src/alloy/compiler/passes/validation_pass.cc b/src/alloy/compiler/passes/validation_pass.cc index 27e85f7b6..bc6c8d536 100644 --- a/src/alloy/compiler/passes/validation_pass.cc +++ b/src/alloy/compiler/passes/validation_pass.cc @@ -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)) {