diff options
-rw-r--r-- | compiler/optimizing/bounds_check_elimination.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/licm.cc | 8 | ||||
-rw-r--r-- | compiler/optimizing/loop_optimization.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 55 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 55 | ||||
-rw-r--r-- | compiler/optimizing/nodes_test.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_unit_test.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/scheduler_test.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/superblock_cloner.cc | 2 |
10 files changed, 82 insertions, 54 deletions
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc index c0d4c37659..1ef4d751a2 100644 --- a/compiler/optimizing/bounds_check_elimination.cc +++ b/compiler/optimizing/bounds_check_elimination.cc @@ -1983,7 +1983,7 @@ class BCEVisitor final : public HGraphVisitor { } user->RemoveAsUserOfInput(index); user->SetRawEnvAt(index, phi); - phi->AddEnvUseAt(user, index); + phi->AddEnvUseAt(GetGraph()->GetAllocator(), user, index); } } } diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 1f2628c8ec..74880463c3 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -305,7 +305,7 @@ void HInstructionBuilder::InitializeInstruction(HInstruction* instruction) { graph_->GetArtMethod(), instruction->GetDexPc(), instruction); - environment->CopyFrom(ArrayRef<HInstruction* const>(*current_locals_)); + environment->CopyFrom(allocator_, ArrayRef<HInstruction* const>(*current_locals_)); instruction->SetRawEnvironment(environment); } } diff --git a/compiler/optimizing/licm.cc b/compiler/optimizing/licm.cc index 0c791b640d..729a277ee0 100644 --- a/compiler/optimizing/licm.cc +++ b/compiler/optimizing/licm.cc @@ -64,7 +64,9 @@ static bool InputsAreDefinedBeforeLoop(HInstruction* instruction) { /** * If `environment` has a loop header phi, we replace it with its first input. */ -static void UpdateLoopPhisIn(HEnvironment* environment, HLoopInformation* info) { +static void UpdateLoopPhisIn(ArenaAllocator* allocator, + HEnvironment* environment, + HLoopInformation* info) { for (; environment != nullptr; environment = environment->GetParent()) { for (size_t i = 0, e = environment->Size(); i < e; ++i) { HInstruction* input = environment->GetInstructionAt(i); @@ -72,7 +74,7 @@ static void UpdateLoopPhisIn(HEnvironment* environment, HLoopInformation* info) environment->RemoveAsUserOfInput(i); HInstruction* incoming = input->InputAt(0); environment->SetRawEnvAt(i, incoming); - incoming->AddEnvUseAt(environment, i); + incoming->AddEnvUseAt(allocator, environment, i); } } } @@ -152,7 +154,7 @@ bool LICM::Run() { // We need to update the environment if the instruction has a loop header // phi in it. if (instruction->NeedsEnvironment()) { - UpdateLoopPhisIn(instruction->GetEnvironment(), loop_info); + UpdateLoopPhisIn(graph_->GetAllocator(), instruction->GetEnvironment(), loop_info); } else { DCHECK(!instruction->HasEnvironment()); } diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc index 2f1aea68aa..18b2b56d00 100644 --- a/compiler/optimizing/loop_optimization.cc +++ b/compiler/optimizing/loop_optimization.cc @@ -3095,7 +3095,7 @@ bool HLoopOptimization::TryReplaceWithLastValue(HLoopInformation* loop_info, if (other_loop_info == nullptr || !other_loop_info->IsIn(*loop_info)) { user->RemoveAsUserOfInput(index); user->SetRawEnvAt(index, replacement); - replacement->AddEnvUseAt(user, index); + replacement->AddEnvUseAt(graph_->GetAllocator(), user, index); } } } diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 6be474a8c9..ae5e73ad0d 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -1035,10 +1035,13 @@ bool HBasicBlock::Dominates(const HBasicBlock* other) const { return false; } -static void UpdateInputsUsers(HInstruction* instruction) { +static void UpdateInputsUsers(HGraph* graph, HInstruction* instruction) { HInputsRef inputs = instruction->GetInputs(); - for (size_t i = 0; i < inputs.size(); ++i) { - inputs[i]->AddUseAt(instruction, i); + if (inputs.size() != 0u) { + ArenaAllocator* allocator = graph->GetAllocator(); + for (size_t i = 0; i < inputs.size(); ++i) { + inputs[i]->AddUseAt(allocator, instruction, i); + } } // Environment should be created later. DCHECK(!instruction->HasEnvironment()); @@ -1064,9 +1067,10 @@ void HBasicBlock::ReplaceAndRemoveInstructionWith(HInstruction* initial, DCHECK(initial->GetUses().empty()); DCHECK(initial->GetEnvUses().empty()); replacement->SetBlock(this); - replacement->SetId(GetGraph()->GetNextInstructionId()); + HGraph* graph = GetGraph(); + replacement->SetId(graph->GetNextInstructionId()); instructions_.InsertInstructionBefore(replacement, initial); - UpdateInputsUsers(replacement); + UpdateInputsUsers(graph, replacement); } else { InsertInstructionBefore(replacement, initial); initial->ReplaceWith(replacement); @@ -1080,8 +1084,9 @@ static void Add(HInstructionList* instruction_list, DCHECK(instruction->GetBlock() == nullptr); DCHECK_EQ(instruction->GetId(), -1); instruction->SetBlock(block); - instruction->SetId(block->GetGraph()->GetNextInstructionId()); - UpdateInputsUsers(instruction); + HGraph* graph = block->GetGraph(); + instruction->SetId(graph->GetNextInstructionId()); + UpdateInputsUsers(graph, instruction); instruction_list->AddInstruction(instruction); } @@ -1101,8 +1106,9 @@ void HBasicBlock::InsertInstructionBefore(HInstruction* instruction, HInstructio DCHECK_EQ(cursor->GetBlock(), this); DCHECK(!instruction->IsControlFlow()); instruction->SetBlock(this); - instruction->SetId(GetGraph()->GetNextInstructionId()); - UpdateInputsUsers(instruction); + HGraph* graph = GetGraph(); + instruction->SetId(graph->GetNextInstructionId()); + UpdateInputsUsers(graph, instruction); instructions_.InsertInstructionBefore(instruction, cursor); } @@ -1115,8 +1121,9 @@ void HBasicBlock::InsertInstructionAfter(HInstruction* instruction, HInstruction DCHECK(!instruction->IsControlFlow()); DCHECK(!cursor->IsControlFlow()); instruction->SetBlock(this); - instruction->SetId(GetGraph()->GetNextInstructionId()); - UpdateInputsUsers(instruction); + HGraph* graph = GetGraph(); + instruction->SetId(graph->GetNextInstructionId()); + UpdateInputsUsers(graph, instruction); instructions_.InsertInstructionAfter(instruction, cursor); } @@ -1125,8 +1132,9 @@ void HBasicBlock::InsertPhiAfter(HPhi* phi, HPhi* cursor) { DCHECK_NE(cursor->GetId(), -1); DCHECK_EQ(cursor->GetBlock(), this); phi->SetBlock(this); - phi->SetId(GetGraph()->GetNextInstructionId()); - UpdateInputsUsers(phi); + HGraph* graph = GetGraph(); + phi->SetId(graph->GetNextInstructionId()); + UpdateInputsUsers(graph, phi); phis_.InsertInstructionAfter(phi, cursor); } @@ -1161,27 +1169,30 @@ void HBasicBlock::RemoveInstructionOrPhi(HInstruction* instruction, bool ensure_ } } -void HEnvironment::CopyFrom(ArrayRef<HInstruction* const> locals) { +void HEnvironment::CopyFrom(ArenaAllocator* allocator, ArrayRef<HInstruction* const> locals) { + DCHECK_EQ(locals.size(), Size()); for (size_t i = 0; i < locals.size(); i++) { HInstruction* instruction = locals[i]; SetRawEnvAt(i, instruction); if (instruction != nullptr) { - instruction->AddEnvUseAt(this, i); + instruction->AddEnvUseAt(allocator, this, i); } } } -void HEnvironment::CopyFrom(const HEnvironment* env) { +void HEnvironment::CopyFrom(ArenaAllocator* allocator, const HEnvironment* env) { + DCHECK_EQ(env->Size(), Size()); for (size_t i = 0; i < env->Size(); i++) { HInstruction* instruction = env->GetInstructionAt(i); SetRawEnvAt(i, instruction); if (instruction != nullptr) { - instruction->AddEnvUseAt(this, i); + instruction->AddEnvUseAt(allocator, this, i); } } } -void HEnvironment::CopyFromWithLoopPhiAdjustment(HEnvironment* env, +void HEnvironment::CopyFromWithLoopPhiAdjustment(ArenaAllocator* allocator, + HEnvironment* env, HBasicBlock* loop_header) { DCHECK(loop_header->IsLoopHeader()); for (size_t i = 0; i < env->Size(); i++) { @@ -1195,9 +1206,9 @@ void HEnvironment::CopyFromWithLoopPhiAdjustment(HEnvironment* env, // is the first input of the phi. HInstruction* initial = instruction->AsPhi()->InputAt(0); SetRawEnvAt(i, initial); - initial->AddEnvUseAt(this, i); + initial->AddEnvUseAt(allocator, this, i); } else { - instruction->AddEnvUseAt(this, i); + instruction->AddEnvUseAt(allocator, this, i); } } } @@ -1538,7 +1549,7 @@ size_t HInstruction::EnvironmentSize() const { void HVariableInputSizeInstruction::AddInput(HInstruction* input) { DCHECK(input->GetBlock() != nullptr); inputs_.push_back(HUserRecord<HInstruction*>(input)); - input->AddUseAt(this, inputs_.size() - 1); + input->AddUseAt(GetBlock()->GetGraph()->GetAllocator(), this, inputs_.size() - 1); } void HVariableInputSizeInstruction::InsertInputAt(size_t index, HInstruction* input) { @@ -1550,7 +1561,7 @@ void HVariableInputSizeInstruction::InsertInputAt(size_t index, HInstruction* in } // Add the use after updating the indexes. If the `input` is already used by `this`, // the fixup after use insertion can use those indexes. - input->AddUseAt(this, index); + input->AddUseAt(GetBlock()->GetGraph()->GetAllocator(), this, index); } void HVariableInputSizeInstruction::RemoveInputAt(size_t index) { diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 99fbbc6357..fb56c281d9 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -1893,20 +1893,22 @@ class HEnvironment : public ArenaObject<kArenaAllocEnvironment> { parent_->SetAndCopyParentChain(allocator, parent); } else { parent_ = Create(allocator, *parent, holder_); - parent_->CopyFrom(parent); + parent_->CopyFrom(allocator, parent); if (parent->GetParent() != nullptr) { parent_->SetAndCopyParentChain(allocator, parent->GetParent()); } } } - void CopyFrom(ArrayRef<HInstruction* const> locals); - void CopyFrom(const HEnvironment* environment); + void CopyFrom(ArenaAllocator* allocator, ArrayRef<HInstruction* const> locals); + void CopyFrom(ArenaAllocator* allocator, const HEnvironment* environment); // Copy from `env`. If it's a loop phi for `loop_header`, copy the first // input to the loop phi instead. This is for inserting instructions that // require an environment (like HDeoptimization) in the loop pre-header. - void CopyFromWithLoopPhiAdjustment(HEnvironment* env, HBasicBlock* loop_header); + void CopyFromWithLoopPhiAdjustment(ArenaAllocator* allocator, + HEnvironment* env, + HBasicBlock* loop_header); void SetRawEnvAt(size_t index, HInstruction* instruction) { GetVRegs()[index] = HUserRecord<HEnvironment*>(instruction); @@ -2227,25 +2229,38 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { GetPackedFlag<kFlagReferenceTypeIsExact>()); } - void AddUseAt(HInstruction* user, size_t index) { + void AddUseAt(ArenaAllocator* allocator, HInstruction* user, size_t index) { DCHECK(user != nullptr); - // Note: fixup_end remains valid across push_front(). - auto fixup_end = uses_.empty() ? uses_.begin() : ++uses_.begin(); - ArenaAllocator* allocator = user->GetBlock()->GetGraph()->GetAllocator(); HUseListNode<HInstruction*>* new_node = new (allocator) HUseListNode<HInstruction*>(user, index); + // Note: `old_begin` remains valid across `push_front()`. + auto old_begin = uses_.begin(); uses_.push_front(*new_node); - FixUpUserRecordsAfterUseInsertion(fixup_end); + auto new_begin = uses_.begin(); + user->SetRawInputRecordAt(index, HUserRecord<HInstruction*>(this, uses_.before_begin())); + if (old_begin != uses_.end()) { + HInstruction* old_begin_user = old_begin->GetUser(); + size_t old_begin_index = old_begin->GetIndex(); + old_begin_user->SetRawInputRecordAt( + old_begin_index, HUserRecord<HInstruction*>(this, new_begin)); + } } - void AddEnvUseAt(HEnvironment* user, size_t index) { + void AddEnvUseAt(ArenaAllocator* allocator, HEnvironment* user, size_t index) { DCHECK(user != nullptr); - // Note: env_fixup_end remains valid across push_front(). - auto env_fixup_end = env_uses_.empty() ? env_uses_.begin() : ++env_uses_.begin(); HUseListNode<HEnvironment*>* new_node = - new (GetBlock()->GetGraph()->GetAllocator()) HUseListNode<HEnvironment*>(user, index); + new (allocator) HUseListNode<HEnvironment*>(user, index); + // Note: `old_env_begin` remains valid across `push_front()`. + auto old_env_begin = env_uses_.begin(); env_uses_.push_front(*new_node); - FixUpUserRecordsAfterEnvUseInsertion(env_fixup_end); + auto new_env_begin = env_uses_.begin(); + user->GetVRegs()[index] = HUserRecord<HEnvironment*>(this, env_uses_.before_begin()); + if (old_env_begin != env_uses_.end()) { + HEnvironment* old_env_begin_user = old_env_begin->GetUser(); + size_t old_env_begin_index = old_env_begin->GetIndex(); + old_env_begin_user->GetVRegs()[old_env_begin_index] = + HUserRecord<HEnvironment*>(this, new_env_begin); + } } void RemoveAsUserOfInput(size_t input) { @@ -2343,18 +2358,18 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { DCHECK(environment_ == nullptr); ArenaAllocator* allocator = GetBlock()->GetGraph()->GetAllocator(); environment_ = HEnvironment::Create(allocator, *environment, this); - environment_->CopyFrom(environment); + environment_->CopyFrom(allocator, environment); if (environment->GetParent() != nullptr) { environment_->SetAndCopyParentChain(allocator, environment->GetParent()); } } void CopyEnvironmentFromWithLoopPhiAdjustment(HEnvironment* environment, - HBasicBlock* block) { + HBasicBlock* loop_header) { DCHECK(environment_ == nullptr); - ArenaAllocator* allocator = GetBlock()->GetGraph()->GetAllocator(); + ArenaAllocator* allocator = loop_header->GetGraph()->GetAllocator(); environment_ = HEnvironment::Create(allocator, *environment, this); - environment_->CopyFromWithLoopPhiAdjustment(environment, block); + environment_->CopyFromWithLoopPhiAdjustment(allocator, environment, loop_header); if (environment->GetParent() != nullptr) { environment_->SetAndCopyParentChain(allocator, environment->GetParent()); } @@ -6845,7 +6860,7 @@ inline void HLoadClass::AddSpecialInput(HInstruction* special_input) { GetLoadKind() == LoadKind::kJitBootImageAddress) << GetLoadKind(); DCHECK(special_input_.GetInstruction() == nullptr); special_input_ = HUserRecord<HInstruction*>(special_input); - special_input->AddUseAt(this, 0); + special_input->AddUseAt(GetBlock()->GetGraph()->GetAllocator(), this, 0); } class HLoadString final : public HInstruction { @@ -7013,7 +7028,7 @@ inline void HLoadString::AddSpecialInput(HInstruction* special_input) { // so use the GetInputRecords() from the base class to set the input record. DCHECK(special_input_.GetInstruction() == nullptr); special_input_ = HUserRecord<HInstruction*>(special_input); - special_input->AddUseAt(this, 0); + special_input->AddUseAt(GetBlock()->GetGraph()->GetAllocator(), this, 0); } class HLoadMethodHandle final : public HInstruction { diff --git a/compiler/optimizing/nodes_test.cc b/compiler/optimizing/nodes_test.cc index 5f71d053c6..97f74cb7b9 100644 --- a/compiler/optimizing/nodes_test.cc +++ b/compiler/optimizing/nodes_test.cc @@ -248,7 +248,7 @@ TEST_F(NodeTest, ParentEnvironment) { graph->GetArtMethod(), /*dex_pc=*/ 0, /*holder=*/ nullptr); - parent1->CopyFrom(ArrayRef<HInstruction* const>(¶meter1, 1u)); + parent1->CopyFrom(GetAllocator(), ArrayRef<HInstruction* const>(¶meter1, 1u)); ASSERT_EQ(parameter1->GetEnvUses().SizeSlow(), 2u); @@ -258,7 +258,7 @@ TEST_F(NodeTest, ParentEnvironment) { graph->GetArtMethod(), /*dex_pc=*/ 0, /*holder=*/ nullptr); - parent2->CopyFrom(ArrayRef<HInstruction* const>(¶meter1, 1u)); + parent2->CopyFrom(GetAllocator(), ArrayRef<HInstruction* const>(¶meter1, 1u)); parent1->SetAndCopyParentChain(GetAllocator(), parent2); // One use for parent2, and one other use for the new parent of parent1. diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h index d81f3804dc..c40b918fee 100644 --- a/compiler/optimizing/optimizing_unit_test.h +++ b/compiler/optimizing/optimizing_unit_test.h @@ -446,7 +446,7 @@ class OptimizingUnitTestHelper { instruction->GetDexPc(), instruction); - environment->CopyFrom(ArrayRef<HInstruction* const>(*current_locals)); + environment->CopyFrom(GetAllocator(), ArrayRef<HInstruction* const>(*current_locals)); instruction->SetRawEnvironment(environment); return environment; } diff --git a/compiler/optimizing/scheduler_test.cc b/compiler/optimizing/scheduler_test.cc index 7003bd2715..6359119a87 100644 --- a/compiler/optimizing/scheduler_test.cc +++ b/compiler/optimizing/scheduler_test.cc @@ -118,9 +118,9 @@ class SchedulerTest : public CommonCompilerTest, public OptimizingUnitTestHelper div_check); div_check->SetRawEnvironment(environment); environment->SetRawEnvAt(0, add2); - add2->AddEnvUseAt(div_check->GetEnvironment(), 0); + add2->AddEnvUseAt(GetAllocator(), div_check->GetEnvironment(), 0); environment->SetRawEnvAt(1, mul); - mul->AddEnvUseAt(div_check->GetEnvironment(), 1); + mul->AddEnvUseAt(GetAllocator(), div_check->GetEnvironment(), 1); TestSchedulingGraph scheduling_graph(GetScopedAllocator()); // Instructions must be inserted in reverse order into the scheduling graph. diff --git a/compiler/optimizing/superblock_cloner.cc b/compiler/optimizing/superblock_cloner.cc index a7328a1218..5ab34fb1a8 100644 --- a/compiler/optimizing/superblock_cloner.cc +++ b/compiler/optimizing/superblock_cloner.cc @@ -144,7 +144,7 @@ void SuperblockCloner::DeepCloneEnvironmentWithRemapping(HInstruction* copy_inst } copy_env->SetRawEnvAt(i, env_input); if (env_input != nullptr) { - env_input->AddEnvUseAt(copy_env, i); + env_input->AddEnvUseAt(graph_->GetAllocator(), copy_env, i); } } // InsertRawEnvironment assumes that instruction already has an environment that's why we use |