Switching up std::vector use in register allocator.

This commit is contained in:
Ben Vanik 2015-05-11 21:01:48 -07:00
parent 21edd65354
commit fc02a0c404
2 changed files with 22 additions and 17 deletions

View File

@ -10,6 +10,9 @@
<ControlFlowGuard>Guard</ControlFlowGuard> <ControlFlowGuard>Guard</ControlFlowGuard>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<PreprocessorDefinitions>CHECKED;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>CHECKED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<BufferSecurityCheck>true</BufferSecurityCheck>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup /> <ItemGroup />

View File

@ -210,46 +210,48 @@ void RegisterAllocationPass::AdvanceUses(Instr* instr) {
if (!usage_set) { if (!usage_set) {
break; break;
} }
std::vector<RegisterUsage> to_add;
auto& upcoming_uses = usage_set->upcoming_uses; auto& upcoming_uses = usage_set->upcoming_uses;
for (auto& it = upcoming_uses.begin(); it != upcoming_uses.end();) { for (int i = 0; i < upcoming_uses.size();) {
if (!it->use) { auto& upcoming_use = upcoming_uses.at(i);
if (!upcoming_use.use) {
// No uses at all - we can remove right away. // No uses at all - we can remove right away.
// This comes up from instructions where the dest is never used, // This comes up from instructions where the dest is never used,
// like the ATOMIC ops. // like the ATOMIC ops.
MarkRegAvailable(it->value->reg); MarkRegAvailable(upcoming_use.value->reg);
it = upcoming_uses.erase(it); upcoming_uses.erase(upcoming_uses.begin() + i);
// i remains the same.
continue; continue;
} }
if (it->use->instr != instr) { if (upcoming_use.use->instr != instr) {
// Not yet at this instruction. // Not yet at this instruction.
++it; ++i;
continue; continue;
} }
// The use is from this instruction. // The use is from this instruction.
if (!it->use->next) { if (!upcoming_use.use->next) {
// Last use of the value. We can retire it now. // Last use of the value. We can retire it now.
MarkRegAvailable(it->value->reg); MarkRegAvailable(upcoming_use.value->reg);
it = upcoming_uses.erase(it); upcoming_uses.erase(upcoming_uses.begin() + i);
// i remains the same.
continue;
} else { } else {
// Used again. Push back the next use. // Used again. Push back the next use.
// Note that we may be used multiple times this instruction, so // Note that we may be used multiple times this instruction, so
// eat those. // eat those.
auto next_use = it->use->next; auto next_use = upcoming_use.use->next;
while (next_use->next && next_use->instr == instr) { while (next_use->next && next_use->instr == instr) {
next_use = next_use->next; next_use = next_use->next;
} }
// Remove the iterator. // Remove the iterator.
auto value = it->value; auto value = upcoming_use.value;
it = upcoming_uses.erase(it); upcoming_uses.erase(upcoming_uses.begin() + i);
assert_true(next_use->instr->block == instr->block); assert_true(next_use->instr->block == instr->block);
assert_true(value->def->block == instr->block); assert_true(value->def->block == instr->block);
to_add.emplace_back(value, next_use); upcoming_uses.emplace_back(value, next_use);
// i remains the same.
continue;
} }
} }
for (auto& use : to_add) {
upcoming_uses.emplace_back(use);
}
} }
DumpUsage("AdvanceUses"); DumpUsage("AdvanceUses");
} }