From 21c7e6fbcabef2f22b467e1e89f4abe1aa43e459 Mon Sep 17 00:00:00 2001 From: Artem Serov Date: Thu, 27 Jul 2017 16:04:42 +0100 Subject: ART: Fix SimplifyInduction for an instruction with HEnvironment. After an instruction is removed during RemoveFromCycle its environment isn't properly cleaned: it still has input instructions present and registered (those instructions still hold records for that). Test: test-art-target, test-art-host. Change-Id: Iea315bdf735d75fe477f43671f05b40dfecc63a8 --- compiler/optimizing/nodes.cc | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'compiler/optimizing/nodes.cc') diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index ca48e08a7c..3a1864b2ae 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -90,7 +90,8 @@ void HGraph::FindBackEdges(ArenaBitVector* visited) { } } -static void RemoveEnvironmentUses(HInstruction* instruction) { +// Remove the environment use records of the instruction for users. +void RemoveEnvironmentUses(HInstruction* instruction) { for (HEnvironment* environment = instruction->GetEnvironment(); environment != nullptr; environment = environment->GetParent()) { @@ -102,6 +103,35 @@ static void RemoveEnvironmentUses(HInstruction* instruction) { } } +// Return whether the instruction has an environment and it's used by others. +bool HasEnvironmentUsedByOthers(HInstruction* instruction) { + for (HEnvironment* environment = instruction->GetEnvironment(); + environment != nullptr; + environment = environment->GetParent()) { + for (size_t i = 0, e = environment->Size(); i < e; ++i) { + HInstruction* user = environment->GetInstructionAt(i); + if (user != nullptr) { + return true; + } + } + } + return false; +} + +// Reset environment records of the instruction itself. +void ResetEnvironmentInputRecords(HInstruction* instruction) { + for (HEnvironment* environment = instruction->GetEnvironment(); + environment != nullptr; + environment = environment->GetParent()) { + for (size_t i = 0, e = environment->Size(); i < e; ++i) { + DCHECK(environment->GetHolder() == instruction); + if (environment->GetInstructionAt(i) != nullptr) { + environment->SetRawEnvAt(i, nullptr); + } + } + } +} + static void RemoveAsUser(HInstruction* instruction) { instruction->RemoveAsUserOfAllInputs(); RemoveEnvironmentUses(instruction); -- cgit v1.2.3-59-g8ed1b