summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/loop_optimization.cc20
-rw-r--r--compiler/optimizing/nodes.cc32
-rw-r--r--compiler/optimizing/nodes.h4
-rw-r--r--compiler/optimizing/prepare_for_register_allocation.cc4
4 files changed, 57 insertions, 3 deletions
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 274f065084..0ef7dcdb59 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -40,6 +40,8 @@ static void RemoveFromCycle(HInstruction* instruction) {
instruction->RemoveAsUserOfAllInputs();
instruction->RemoveEnvironmentUsers();
instruction->GetBlock()->RemoveInstructionOrPhi(instruction, /*ensure_safety=*/ false);
+ RemoveEnvironmentUses(instruction);
+ ResetEnvironmentInputRecords(instruction);
}
// Detect a goto block and sets succ to the single successor.
@@ -267,6 +269,21 @@ static HInstruction* Insert(HBasicBlock* block, HInstruction* instruction) {
return instruction;
}
+// Check that instructions from the induction sets are fully removed: have no uses
+// and no other instructions use them.
+static bool CheckInductionSetFullyRemoved(ArenaSet<HInstruction*>* iset) {
+ for (HInstruction* instr : *iset) {
+ if (instr->GetBlock() != nullptr ||
+ !instr->GetUses().empty() ||
+ !instr->GetEnvUses().empty() ||
+ HasEnvironmentUsedByOthers(instr)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
//
// Class methods.
//
@@ -448,6 +465,9 @@ void HLoopOptimization::SimplifyInduction(LoopNode* node) {
for (HInstruction* i : *iset_) {
RemoveFromCycle(i);
}
+
+ // Check that there are no records of the deleted instructions.
+ DCHECK(CheckInductionSetFullyRemoved(iset_));
simplified_ = true;
}
}
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);
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index fa29378e42..e4431422b2 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -7059,6 +7059,10 @@ inline HInstruction* HuntForDeclaration(HInstruction* instruction) {
return instruction;
}
+void RemoveEnvironmentUses(HInstruction* instruction);
+bool HasEnvironmentUsedByOthers(HInstruction* instruction);
+void ResetEnvironmentInputRecords(HInstruction* instruction);
+
} // namespace art
#endif // ART_COMPILER_OPTIMIZING_NODES_H_
diff --git a/compiler/optimizing/prepare_for_register_allocation.cc b/compiler/optimizing/prepare_for_register_allocation.cc
index aa42fd647b..7c6b69fb2f 100644
--- a/compiler/optimizing/prepare_for_register_allocation.cc
+++ b/compiler/optimizing/prepare_for_register_allocation.cc
@@ -208,8 +208,8 @@ void PrepareForRegisterAllocation::VisitConstructorFence(HConstructorFence* cons
void PrepareForRegisterAllocation::VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) {
if (invoke->IsStaticWithExplicitClinitCheck()) {
- HLoadClass* last_input = invoke->GetInputs().back()->AsLoadClass();
- DCHECK(last_input != nullptr)
+ HInstruction* last_input = invoke->GetInputs().back();
+ DCHECK(last_input->IsLoadClass())
<< "Last input is not HLoadClass. It is " << last_input->DebugName();
// Detach the explicit class initialization check from the invoke.