Commit 81c965d4 authored by mtrofin's avatar mtrofin Committed by Commit bot

[turbofan] store block id with instruction

GetInstructionBlock shows up in some compile time-intensive profiles.
Changing it to a O(1) operation. The compile benchmark confirms the
improvement.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#35711}
parent 82a7c53e
......@@ -87,7 +87,6 @@ void InstructionSelector::SelectInstructions() {
#endif
}
void InstructionSelector::StartBlock(RpoNumber rpo) {
if (FLAG_turbo_instruction_scheduling &&
InstructionScheduler::SchedulerSupported()) {
......
......@@ -251,17 +251,16 @@ ExplicitOperand::ExplicitOperand(LocationKind kind, MachineRepresentation rep,
DoubleRegister::from_code(index).IsAllocatable());
}
Instruction::Instruction(InstructionCode opcode)
: opcode_(opcode),
bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) |
TempCountField::encode(0) | IsCallField::encode(false)),
reference_map_(nullptr) {
reference_map_(nullptr),
block_(nullptr) {
parallel_moves_[0] = nullptr;
parallel_moves_[1] = nullptr;
}
Instruction::Instruction(InstructionCode opcode, size_t output_count,
InstructionOperand* outputs, size_t input_count,
InstructionOperand* inputs, size_t temp_count,
......@@ -271,7 +270,8 @@ Instruction::Instruction(InstructionCode opcode, size_t output_count,
InputCountField::encode(input_count) |
TempCountField::encode(temp_count) |
IsCallField::encode(false)),
reference_map_(nullptr) {
reference_map_(nullptr),
block_(nullptr) {
parallel_moves_[0] = nullptr;
parallel_moves_[1] = nullptr;
size_t offset = 0;
......@@ -611,7 +611,6 @@ static InstructionBlock* InstructionBlockFor(Zone* zone,
return instr_block;
}
InstructionBlocks* InstructionSequence::InstructionBlocksFor(
Zone* zone, const Schedule* schedule) {
InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1);
......@@ -683,7 +682,6 @@ void InstructionSequence::ComputeAssemblyOrder(InstructionBlocks* blocks) {
}
}
InstructionSequence::InstructionSequence(Isolate* isolate,
Zone* instruction_zone,
InstructionBlocks* instruction_blocks)
......@@ -691,7 +689,6 @@ InstructionSequence::InstructionSequence(Isolate* isolate,
zone_(instruction_zone),
instruction_blocks_(instruction_blocks),
source_positions_(zone()),
block_starts_(zone()),
constants_(ConstantMap::key_compare(),
ConstantMap::allocator_type(zone())),
immediates_(zone()),
......@@ -699,10 +696,8 @@ InstructionSequence::InstructionSequence(Isolate* isolate,
next_virtual_register_(0),
reference_maps_(zone()),
representations_(zone()),
deoptimization_entries_(zone()) {
block_starts_.reserve(instruction_blocks_->size());
}
deoptimization_entries_(zone()),
current_block_(nullptr) {}
int InstructionSequence::NextVirtualRegister() {
int virtual_register = next_virtual_register_++;
......@@ -718,28 +713,31 @@ Instruction* InstructionSequence::GetBlockStart(RpoNumber rpo) const {
void InstructionSequence::StartBlock(RpoNumber rpo) {
DCHECK(block_starts_.size() == rpo.ToSize());
InstructionBlock* block = InstructionBlockAt(rpo);
DCHECK_NULL(current_block_);
current_block_ = InstructionBlockAt(rpo);
int code_start = static_cast<int>(instructions_.size());
block->set_code_start(code_start);
block_starts_.push_back(code_start);
current_block_->set_code_start(code_start);
}
void InstructionSequence::EndBlock(RpoNumber rpo) {
int end = static_cast<int>(instructions_.size());
InstructionBlock* block = InstructionBlockAt(rpo);
if (block->code_start() == end) { // Empty block. Insert a nop.
DCHECK_EQ(current_block_->rpo_number(), rpo);
if (current_block_->code_start() == end) { // Empty block. Insert a nop.
AddInstruction(Instruction::New(zone(), kArchNop));
end = static_cast<int>(instructions_.size());
}
DCHECK(block->code_start() >= 0 && block->code_start() < end);
block->set_code_end(end);
DCHECK(current_block_->code_start() >= 0 &&
current_block_->code_start() < end);
current_block_->set_code_end(end);
current_block_ = nullptr;
}
int InstructionSequence::AddInstruction(Instruction* instr) {
DCHECK_NOT_NULL(current_block_);
int index = static_cast<int>(instructions_.size());
instr->set_block(current_block_);
instructions_.push_back(instr);
if (instr->NeedsReferenceMap()) {
DCHECK(instr->reference_map() == nullptr);
......@@ -754,18 +752,7 @@ int InstructionSequence::AddInstruction(Instruction* instr) {
InstructionBlock* InstructionSequence::GetInstructionBlock(
int instruction_index) const {
DCHECK(instruction_blocks_->size() == block_starts_.size());
auto begin = block_starts_.begin();
auto end = std::lower_bound(begin, block_starts_.end(), instruction_index);
// Post condition of std::lower_bound:
DCHECK(end == block_starts_.end() || *end >= instruction_index);
if (end == block_starts_.end() || *end > instruction_index) --end;
DCHECK(*end <= instruction_index);
size_t index = std::distance(begin, end);
InstructionBlock* block = instruction_blocks_->at(index);
DCHECK(block->code_start() <= instruction_index &&
instruction_index < block->code_end());
return block;
return instructions()[instruction_index]->block();
}
......
......@@ -715,6 +715,8 @@ class ReferenceMap final : public ZoneObject {
std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm);
class InstructionBlock;
class Instruction final {
public:
size_t OutputCount() const { return OutputCountField::decode(bit_field_); }
......@@ -857,6 +859,15 @@ class Instruction final {
ParallelMove* const* parallel_moves() const { return &parallel_moves_[0]; }
ParallelMove** parallel_moves() { return &parallel_moves_[0]; }
// The block_id may be invalidated in JumpThreading. It is only important for
// register allocation, to avoid searching for blocks from instruction
// indexes.
InstructionBlock* block() const { return block_; }
void set_block(InstructionBlock* block) {
DCHECK_NOT_NULL(block);
block_ = block;
}
void Print(const RegisterConfiguration* config) const;
void Print() const;
......@@ -877,6 +888,7 @@ class Instruction final {
uint32_t bit_field_;
ParallelMove* parallel_moves_[2];
ReferenceMap* reference_map_;
InstructionBlock* block_;
InstructionOperand operands_[1];
DISALLOW_COPY_AND_ASSIGN(Instruction);
......@@ -1394,7 +1406,6 @@ class InstructionSequence final : public ZoneObject {
Zone* const zone_;
InstructionBlocks* const instruction_blocks_;
SourcePositionMap source_positions_;
IntVector block_starts_;
ConstantMap constants_;
Immediates immediates_;
InstructionDeque instructions_;
......@@ -1403,6 +1414,9 @@ class InstructionSequence final : public ZoneObject {
ZoneVector<MachineRepresentation> representations_;
DeoptimizationVector deoptimization_entries_;
// Used at construction time
InstructionBlock* current_block_;
DISALLOW_COPY_AND_ASSIGN(InstructionSequence);
};
......
......@@ -1509,7 +1509,6 @@ void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
CallDescriptor* descriptor,
bool run_verifier) {
PipelineData* data = this->data_;
// Don't track usage for this zone in compiler stats.
base::SmartPointer<Zone> verifier_zone;
RegisterAllocatorVerifier* verifier = nullptr;
......
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