Mark instruction blocks with spills (for frame elision).
Review URL: https://codereview.chromium.org/1119683002 Cr-Commit-Position: refs/heads/master@{#28171}
This commit is contained in:
parent
dfe01818fe
commit
f17a297e1d
@ -20,6 +20,7 @@ void FrameElider::Run() {
|
||||
|
||||
void FrameElider::MarkBlocks() {
|
||||
for (auto block : instruction_blocks()) {
|
||||
if (block->needs_frame()) continue;
|
||||
for (auto i = block->code_start(); i < block->code_end(); ++i) {
|
||||
if (InstructionAt(i)->IsCall()) {
|
||||
block->mark_needs_frame();
|
||||
|
@ -559,7 +559,7 @@ int InstructionSequence::AddInstruction(Instruction* instr) {
|
||||
}
|
||||
|
||||
|
||||
const InstructionBlock* InstructionSequence::GetInstructionBlock(
|
||||
InstructionBlock* InstructionSequence::GetInstructionBlock(
|
||||
int instruction_index) const {
|
||||
DCHECK(instruction_blocks_->size() == block_starts_.size());
|
||||
auto begin = block_starts_.begin();
|
||||
@ -760,6 +760,9 @@ std::ostream& operator<<(std::ostream& os,
|
||||
os << "B" << block->rpo_number();
|
||||
os << ": AO#" << block->ao_number();
|
||||
if (block->IsDeferred()) os << " (deferred)";
|
||||
if (!block->needs_frame()) os << " (no frame)";
|
||||
if (block->must_construct_frame()) os << " (construct frame)";
|
||||
if (block->must_deconstruct_frame()) os << " (deconstruct frame)";
|
||||
if (block->IsLoopHeader()) {
|
||||
os << " loop blocks: [" << block->rpo_number() << ", "
|
||||
<< block->loop_end() << ")";
|
||||
|
@ -1052,7 +1052,7 @@ class InstructionSequence final : public ZoneObject {
|
||||
return instruction_blocks_->at(rpo_number.ToSize());
|
||||
}
|
||||
|
||||
const InstructionBlock* GetInstructionBlock(int instruction_index) const;
|
||||
InstructionBlock* GetInstructionBlock(int instruction_index) const;
|
||||
|
||||
static MachineType DefaultRepresentation() {
|
||||
return kPointerSize == 8 ? kRepWord64 : kRepWord32;
|
||||
|
@ -779,6 +779,16 @@ struct AllocateDoubleRegistersPhase {
|
||||
};
|
||||
|
||||
|
||||
struct LocateSpillSlotsPhase {
|
||||
static const char* phase_name() { return "locate spill slots"; }
|
||||
|
||||
void Run(PipelineData* data, Zone* temp_zone) {
|
||||
SpillSlotLocator locator(data->register_allocation_data());
|
||||
locator.LocateSpillSlots();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct AssignSpillSlotsPhase {
|
||||
static const char* phase_name() { return "assign spill slots"; }
|
||||
|
||||
@ -1200,10 +1210,6 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
|
||||
return Handle<Code>();
|
||||
}
|
||||
|
||||
if (FLAG_turbo_frame_elision) {
|
||||
Run<FrameElisionPhase>();
|
||||
}
|
||||
|
||||
BeginPhaseKind("code generation");
|
||||
|
||||
// Optimimize jumps.
|
||||
@ -1299,6 +1305,12 @@ void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
|
||||
Run<AllocateGeneralRegistersPhase<LinearScanAllocator>>();
|
||||
Run<AllocateDoubleRegistersPhase<LinearScanAllocator>>();
|
||||
}
|
||||
|
||||
if (FLAG_turbo_frame_elision) {
|
||||
Run<LocateSpillSlotsPhase>();
|
||||
Run<FrameElisionPhase>();
|
||||
}
|
||||
|
||||
Run<AssignSpillSlotsPhase>();
|
||||
|
||||
Run<CommitAssignmentPhase>();
|
||||
|
@ -2694,6 +2694,25 @@ bool GreedyAllocator::AllocateBlockedRange(
|
||||
}
|
||||
|
||||
|
||||
SpillSlotLocator::SpillSlotLocator(RegisterAllocationData* data)
|
||||
: data_(data) {}
|
||||
|
||||
|
||||
void SpillSlotLocator::LocateSpillSlots() {
|
||||
auto code = data()->code();
|
||||
for (auto range : data()->live_ranges()) {
|
||||
if (range == nullptr || range->IsEmpty() || range->IsChild()) continue;
|
||||
// We care only about ranges which spill in the frame.
|
||||
if (!range->HasSpillRange()) continue;
|
||||
auto spills = range->spills_at_definition();
|
||||
DCHECK_NOT_NULL(spills);
|
||||
for (; spills != nullptr; spills = spills->next) {
|
||||
code->GetInstructionBlock(spills->gap_index)->mark_needs_frame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OperandAssigner::OperandAssigner(RegisterAllocationData* data) : data_(data) {}
|
||||
|
||||
|
||||
|
@ -418,9 +418,13 @@ class LiveRange final : public ZoneObject {
|
||||
void SetUseHints(int register_index);
|
||||
void UnsetUseHints() { SetUseHints(kUnassignedRegister); }
|
||||
|
||||
private:
|
||||
struct SpillAtDefinitionList;
|
||||
|
||||
SpillAtDefinitionList* spills_at_definition() const {
|
||||
return spills_at_definition_;
|
||||
}
|
||||
|
||||
private:
|
||||
void set_spill_type(SpillType value) {
|
||||
bits_ = SpillTypeField::update(bits_, value);
|
||||
}
|
||||
@ -863,6 +867,21 @@ class GreedyAllocator final : public RegisterAllocator {
|
||||
};
|
||||
|
||||
|
||||
class SpillSlotLocator final : public ZoneObject {
|
||||
public:
|
||||
explicit SpillSlotLocator(RegisterAllocationData* data);
|
||||
|
||||
void LocateSpillSlots();
|
||||
|
||||
private:
|
||||
RegisterAllocationData* data() const { return data_; }
|
||||
|
||||
RegisterAllocationData* const data_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(SpillSlotLocator);
|
||||
};
|
||||
|
||||
|
||||
class OperandAssigner final : public ZoneObject {
|
||||
public:
|
||||
explicit OperandAssigner(RegisterAllocationData* data);
|
||||
|
Loading…
Reference in New Issue
Block a user