[turbofan] resolve all references before populating reference maps

BUG=

Review URL: https://codereview.chromium.org/1112213005

Cr-Commit-Position: refs/heads/master@{#28157}
This commit is contained in:
dcarney 2015-04-30 04:07:54 -07:00 committed by Commit bot
parent ac1c88a9b2
commit c5c8eb3fd1
4 changed files with 39 additions and 19 deletions

View File

@ -210,7 +210,7 @@ std::ostream& operator<<(std::ostream& os,
} }
void ReferenceMap::RecordReference(const InstructionOperand& op) { void ReferenceMap::RecordReference(const AllocatedOperand& op) {
// Do not record arguments as pointers. // Do not record arguments as pointers.
if (op.IsStackSlot() && StackSlotOperand::cast(op).index() < 0) return; if (op.IsStackSlot() && StackSlotOperand::cast(op).index() < 0) return;
DCHECK(!op.IsDoubleRegister() && !op.IsDoubleStackSlot()); DCHECK(!op.IsDoubleRegister() && !op.IsDoubleStackSlot());

View File

@ -592,7 +592,7 @@ class ReferenceMap final : public ZoneObject {
instruction_position_ = pos; instruction_position_ = pos;
} }
void RecordReference(const InstructionOperand& op); void RecordReference(const AllocatedOperand& op);
private: private:
friend std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm); friend std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm);

View File

@ -902,6 +902,7 @@ RegisterAllocationData::RegisterAllocationData(
fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr, fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
allocation_zone()), allocation_zone()),
spill_ranges_(allocation_zone()), spill_ranges_(allocation_zone()),
delayed_references_(allocation_zone()),
assigned_registers_(nullptr), assigned_registers_(nullptr),
assigned_double_registers_(nullptr), assigned_double_registers_(nullptr),
virtual_register_count_(code->VirtualRegisterCount()) { virtual_register_count_(code->VirtualRegisterCount()) {
@ -1057,7 +1058,7 @@ InstructionOperand* ConstraintBuilder::AllocateFixed(
TRACE("Fixed reg is tagged at %d\n", pos); TRACE("Fixed reg is tagged at %d\n", pos);
auto instr = InstructionAt(pos); auto instr = InstructionAt(pos);
if (instr->HasReferenceMap()) { if (instr->HasReferenceMap()) {
instr->reference_map()->RecordReference(*operand); instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand));
} }
} }
return operand; return operand;
@ -1206,10 +1207,13 @@ void ConstraintBuilder::MeetConstraintsBefore(int instr_index) {
int input_vreg = cur_input->virtual_register(); int input_vreg = cur_input->virtual_register();
UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg); UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg);
cur_input->set_virtual_register(second_output->virtual_register()); cur_input->set_virtual_register(second_output->virtual_register());
data()->AddGapMove(instr_index, Instruction::END, input_copy, *cur_input); auto gap_move = data()->AddGapMove(instr_index, Instruction::END,
input_copy, *cur_input);
if (IsReference(input_vreg) && !IsReference(output_vreg)) { if (IsReference(input_vreg) && !IsReference(output_vreg)) {
if (second->HasReferenceMap()) { if (second->HasReferenceMap()) {
second->reference_map()->RecordReference(input_copy); RegisterAllocationData::DelayedReference delayed_reference = {
second->reference_map(), &gap_move->source()};
data()->delayed_references().push_back(delayed_reference);
} }
} else if (!IsReference(input_vreg) && IsReference(output_vreg)) { } else if (!IsReference(input_vreg) && IsReference(output_vreg)) {
// The input is assumed to immediately have a tagged representation, // The input is assumed to immediately have a tagged representation,
@ -2755,7 +2759,11 @@ bool ReferenceMapPopulator::SafePointsAreInOrder() const {
void ReferenceMapPopulator::PopulateReferenceMaps() { void ReferenceMapPopulator::PopulateReferenceMaps() {
DCHECK(SafePointsAreInOrder()); DCHECK(SafePointsAreInOrder());
// Map all delayed references.
for (auto& delayed_reference : data()->delayed_references()) {
delayed_reference.map->RecordReference(
AllocatedOperand::cast(*delayed_reference.operand));
}
// Iterate over all safe point positions and record a pointer // Iterate over all safe point positions and record a pointer
// for all spilled live ranges at this point. // for all spilled live ranges at this point.
int last_range_start = 0; int last_range_start = 0;
@ -2792,6 +2800,20 @@ void ReferenceMapPopulator::PopulateReferenceMaps() {
if (map->instruction_position() >= start) break; if (map->instruction_position() >= start) break;
} }
InstructionOperand spill_operand;
if (((range->HasSpillOperand() &&
!range->GetSpillOperand()->IsConstant()) ||
range->HasSpillRange())) {
if (range->HasSpillOperand()) {
spill_operand = *range->GetSpillOperand();
} else {
spill_operand = range->GetSpillRangeOperand();
}
DCHECK(spill_operand.IsStackSlot());
DCHECK_EQ(kRepTagged,
AllocatedOperand::cast(spill_operand).machine_type());
}
// Step through the safe points to see whether they are in the range. // Step through the safe points to see whether they are in the range.
for (auto it = first_it; it != reference_maps->end(); ++it) { for (auto it = first_it; it != reference_maps->end(); ++it) {
auto map = *it; auto map = *it;
@ -2812,21 +2834,11 @@ void ReferenceMapPopulator::PopulateReferenceMaps() {
// Check if the live range is spilled and the safe point is after // Check if the live range is spilled and the safe point is after
// the spill position. // the spill position.
if (((range->HasSpillOperand() && if (!spill_operand.IsInvalid() &&
!range->GetSpillOperand()->IsConstant()) ||
range->HasSpillRange()) &&
safe_point >= range->spill_start_index()) { safe_point >= range->spill_start_index()) {
TRACE("Pointer for range %d (spilled at %d) at safe point %d\n", TRACE("Pointer for range %d (spilled at %d) at safe point %d\n",
range->id(), range->spill_start_index(), safe_point); range->id(), range->spill_start_index(), safe_point);
InstructionOperand operand; map->RecordReference(AllocatedOperand::cast(spill_operand));
if (range->HasSpillOperand()) {
operand = *range->GetSpillOperand();
} else {
operand = range->GetSpillRangeOperand();
}
DCHECK(operand.IsStackSlot());
DCHECK_EQ(kRepTagged, AllocatedOperand::cast(operand).machine_type());
map->RecordReference(operand);
} }
if (!cur->spilled()) { if (!cur->spilled()) {
@ -2837,7 +2849,7 @@ void ReferenceMapPopulator::PopulateReferenceMaps() {
auto operand = cur->GetAssignedOperand(); auto operand = cur->GetAssignedOperand();
DCHECK(!operand.IsStackSlot()); DCHECK(!operand.IsStackSlot());
DCHECK_EQ(kRepTagged, AllocatedOperand::cast(operand).machine_type()); DCHECK_EQ(kRepTagged, AllocatedOperand::cast(operand).machine_type());
map->RecordReference(operand); map->RecordReference(AllocatedOperand::cast(operand));
} }
} }
} }

View File

@ -528,6 +528,12 @@ class RegisterAllocationData final : public ZoneObject {
}; };
typedef ZoneMap<int, PhiMapValue*> PhiMap; typedef ZoneMap<int, PhiMapValue*> PhiMap;
struct DelayedReference {
ReferenceMap* map;
InstructionOperand* operand;
};
typedef ZoneVector<DelayedReference> DelayedReferences;
RegisterAllocationData(const RegisterConfiguration* config, RegisterAllocationData(const RegisterConfiguration* config,
Zone* allocation_zone, Frame* frame, Zone* allocation_zone, Frame* frame,
InstructionSequence* code, InstructionSequence* code,
@ -547,6 +553,7 @@ class RegisterAllocationData final : public ZoneObject {
} }
ZoneVector<BitVector*>& live_in_sets() { return live_in_sets_; } ZoneVector<BitVector*>& live_in_sets() { return live_in_sets_; }
ZoneVector<SpillRange*>& spill_ranges() { return spill_ranges_; } ZoneVector<SpillRange*>& spill_ranges() { return spill_ranges_; }
DelayedReferences& delayed_references() { return delayed_references_; }
InstructionSequence* code() const { return code_; } InstructionSequence* code() const { return code_; }
// This zone is for datastructures only needed during register allocation // This zone is for datastructures only needed during register allocation
// phases. // phases.
@ -595,6 +602,7 @@ class RegisterAllocationData final : public ZoneObject {
ZoneVector<LiveRange*> fixed_live_ranges_; ZoneVector<LiveRange*> fixed_live_ranges_;
ZoneVector<LiveRange*> fixed_double_live_ranges_; ZoneVector<LiveRange*> fixed_double_live_ranges_;
ZoneVector<SpillRange*> spill_ranges_; ZoneVector<SpillRange*> spill_ranges_;
DelayedReferences delayed_references_;
BitVector* assigned_registers_; BitVector* assigned_registers_;
BitVector* assigned_double_registers_; BitVector* assigned_double_registers_;
int virtual_register_count_; int virtual_register_count_;