Commit aae66586 authored by dcarney's avatar dcarney Committed by Commit bot

[turbofan] delay inserting spill slots for parent ranges.

R=jarin@chromium.org,

BUG=

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

Cr-Commit-Position: refs/heads/master@{#25736}
parent 4161b54d
......@@ -15,8 +15,6 @@ std::ostream& operator<<(std::ostream& os,
const InstructionOperand& op = *printable.op_;
const RegisterConfiguration* conf = printable.register_configuration_;
switch (op.kind()) {
case InstructionOperand::INVALID:
return os << "(0)";
case InstructionOperand::UNALLOCATED: {
const UnallocatedOperand* unalloc = UnallocatedOperand::cast(&op);
os << "v" << unalloc->virtual_register();
......
......@@ -39,7 +39,6 @@ const InstructionCode kSourcePositionInstruction = -3;
class InstructionOperand : public ZoneObject {
public:
enum Kind {
INVALID,
UNALLOCATED,
CONSTANT,
IMMEDIATE,
......@@ -49,7 +48,6 @@ class InstructionOperand : public ZoneObject {
DOUBLE_REGISTER
};
InstructionOperand() : value_(KindField::encode(INVALID)) {}
InstructionOperand(Kind kind, int index) { ConvertTo(kind, index); }
Kind kind() const { return KindField::decode(value_); }
......@@ -58,7 +56,6 @@ class InstructionOperand : public ZoneObject {
bool Is##name() const { return kind() == type; }
INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE)
INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0)
INSTRUCTION_OPERAND_PREDICATE(Ignored, INVALID, 0)
#undef INSTRUCTION_OPERAND_PREDICATE
bool Equals(const InstructionOperand* other) const {
return value_ == other->value_;
......@@ -291,16 +288,12 @@ class MoveOperands FINAL {
}
// A move is redundant if it's been eliminated, if its source and
// destination are the same, or if its destination is unneeded or constant.
// destination are the same, or if its destination is constant.
bool IsRedundant() const {
return IsEliminated() || source_->Equals(destination_) || IsIgnored() ||
return IsEliminated() || source_->Equals(destination_) ||
(destination_ != NULL && destination_->IsConstant());
}
bool IsIgnored() const {
return destination_ != NULL && destination_->IsIgnored();
}
// We clear both operands to indicate move that's been eliminated.
void Eliminate() { source_ = destination_ = NULL; }
bool IsEliminated() const {
......@@ -348,7 +341,7 @@ class SubKindOperand FINAL : public InstructionOperand {
private:
static SubKindOperand* cache;
SubKindOperand() : InstructionOperand() {}
SubKindOperand() : InstructionOperand(kOperandKind, 0) {} // For the caches.
explicit SubKindOperand(int index)
: InstructionOperand(kOperandKind, index) {}
};
......
......@@ -559,6 +559,15 @@ struct ReuseSpillSlotsPhase {
};
struct CommitAssignmentPhase {
static const char* phase_name() { return "commit assignment"; }
void Run(PipelineData* data, Zone* temp_zone) {
data->register_allocator()->CommitAssignment();
}
};
struct PopulatePointerMapsPhase {
static const char* phase_name() { return "populate pointer maps"; }
......@@ -990,7 +999,9 @@ void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
os << "----- Instruction sequence before register allocation -----\n"
<< printable;
}
DCHECK(!data->register_allocator()->ExistsUseWithoutDefinition());
if (verifier != nullptr) {
CHECK(!data->register_allocator()->ExistsUseWithoutDefinition());
}
Run<AllocateGeneralRegistersPhase>();
if (!data->register_allocator()->AllocationOk()) {
data->set_compilation_failed();
......@@ -1004,6 +1015,7 @@ void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
if (FLAG_turbo_reuse_spill_slots) {
Run<ReuseSpillSlotsPhase>();
}
Run<CommitAssignmentPhase>();
Run<PopulatePointerMapsPhase>();
Run<ConnectRangesPhase>();
Run<ResolveControlFlowPhase>();
......
......@@ -276,10 +276,8 @@ class RegisterAllocatorVerifier::OutgoingMapping : public ZoneObject {
auto* moves = move->move_operands();
for (auto i = moves->begin(); i != moves->end(); ++i) {
if (i->IsEliminated()) continue;
CHECK(i->source()->kind() != InstructionOperand::INVALID);
auto cur = locations()->find(i->source());
CHECK(cur != locations()->end());
if (i->destination()->kind() == InstructionOperand::INVALID) continue;
to_insert.insert(std::make_pair(i->destination(), cur->second));
}
// Drop current mappings.
......
This diff is collapsed.
......@@ -196,8 +196,8 @@ class LiveRange FINAL : public ZoneObject {
InstructionOperand* CreateAssignedOperand(Zone* zone) const;
int assigned_register() const { return assigned_register_; }
int spill_start_index() const { return spill_start_index_; }
void set_assigned_register(int reg, Zone* zone);
void MakeSpilled(Zone* zone);
void set_assigned_register(int reg);
void MakeSpilled();
bool is_phi() const { return is_phi_; }
void set_is_phi(bool is_phi) { is_phi_ = is_phi; }
bool is_non_loop_phi() const { return is_non_loop_phi_; }
......@@ -260,13 +260,27 @@ class LiveRange FINAL : public ZoneObject {
return last_interval_->end();
}
bool HasAllocatedSpillOperand() const;
InstructionOperand* GetSpillOperand() const { return spill_operand_; }
void SetSpillOperand(InstructionOperand* operand);
enum class SpillType { kNoSpillType, kSpillOperand, kSpillRange };
SpillType spill_type() const { return spill_type_; }
InstructionOperand* GetSpillOperand() const {
return spill_type_ == SpillType::kSpillOperand ? spill_operand_ : nullptr;
}
SpillRange* GetSpillRange() const {
return spill_type_ == SpillType::kSpillRange ? spill_range_ : nullptr;
}
bool HasNoSpillType() const { return spill_type_ == SpillType::kNoSpillType; }
bool HasSpillOperand() const {
return spill_type_ == SpillType::kSpillOperand;
}
bool HasSpillRange() const { return spill_type_ == SpillType::kSpillRange; }
void SetSpillRange(SpillRange* spill_range) { spill_range_ = spill_range; }
SpillRange* GetSpillRange() const { return spill_range_; }
void SpillAtDefinition(Zone* zone, int gap_index,
InstructionOperand* operand);
void SetSpillOperand(InstructionOperand* operand);
void SetSpillRange(SpillRange* spill_range);
void CommitSpillOperand(InstructionOperand* operand);
void CommitSpillsAtDefinition(InstructionSequence* sequence,
InstructionOperand* operand);
void SetSpillStartIndex(int start) {
spill_start_index_ = Min(start, spill_start_index_);
......@@ -293,12 +307,14 @@ class LiveRange FINAL : public ZoneObject {
#endif
private:
void ConvertOperands(Zone* zone);
struct SpillAtDefinitionList;
void ConvertUsesToOperand(InstructionOperand* op);
UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const;
void AdvanceLastProcessedMarker(UseInterval* to_start_of,
LifetimePosition but_not_past) const;
// TODO(dcarney): pack this structure better.
int id_;
bool spilled_;
bool is_phi_;
......@@ -315,9 +331,13 @@ class LiveRange FINAL : public ZoneObject {
UsePosition* last_processed_use_;
// This is used as a cache, it's invalid outside of BuildLiveRanges.
InstructionOperand* current_hint_operand_;
InstructionOperand* spill_operand_;
int spill_start_index_;
SpillRange* spill_range_;
SpillType spill_type_;
union {
InstructionOperand* spill_operand_;
SpillRange* spill_range_;
};
SpillAtDefinitionList* spills_at_definition_;
friend class RegisterAllocator; // Assigns to kind_.
......@@ -386,13 +406,16 @@ class RegisterAllocator FINAL : public ZoneObject {
// Phase 5: reassign spill splots for maximal reuse.
void ReuseSpillSlots();
// Phase 6: compute values for pointer maps.
// Phase 6: commit assignment.
void CommitAssignment();
// Phase 7: compute values for pointer maps.
void PopulatePointerMaps(); // TODO(titzer): rename to PopulateReferenceMaps.
// Phase 7: reconnect split ranges with moves.
// Phase 8: reconnect split ranges with moves.
void ConnectRanges();
// Phase 8: insert moves to connect ranges across basic blocks.
// Phase 9: insert moves to connect ranges across basic blocks.
void ResolveControlFlow();
private:
......
......@@ -152,7 +152,7 @@ TEST_F(RegisterAllocatorTest, DoubleDiamondManyRedundantPhis) {
StartBlock();
VReg vals[kPhis];
for (int i = 0; i < kPhis; ++i) {
vals[i] = Parameter(Slot(i));
vals[i] = Parameter(Slot(-1 - i));
}
EndBlock(Branch(Reg(DefineConstant()), 1, 2));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment