summaryrefslogtreecommitdiff
path: root/compiler/optimizing/loop_optimization.cc
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2022-03-07 09:29:40 +0000
committer Vladimir Marko <vmarko@google.com> 2022-03-21 15:39:27 +0000
commitde4d195dc0f643b2108f5bb9262df89ac4069271 (patch)
treeb6fcd0012cc061cf7859437f73c321b5d2a0ac7c /compiler/optimizing/loop_optimization.cc
parenta0512eb2112cc925d177c7364be72d429156a5e9 (diff)
Clean up InductionVarAnalysis.
Move temporary members to local variables and allocations from `ArenaAllocator` to `ScopedArenaAllocator`. While this requires passing more parameters around, it also exposes whether these parameters are constant or mutable. Rewrite the strongly connected component (SCC) search to avoid recursion. The recursion depth was dependent on the input code, so essentially arbitrary, and therefore there was a risk of stack overflow. Clean up a few other minor things in `InductionVarAnalysis` and `LoopOptimization`. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Bug: 216762268 Change-Id: Ifed50b8e62e47487edc683564352880df2158247
Diffstat (limited to 'compiler/optimizing/loop_optimization.cc')
-rw-r--r--compiler/optimizing/loop_optimization.cc18
1 files changed, 10 insertions, 8 deletions
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 23c86ce3f9..9e298a5418 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -2387,7 +2387,7 @@ bool HLoopOptimization::TrySetPhiInduction(HPhi* phi, bool restrict_uses) {
}
bool HLoopOptimization::TrySetPhiReduction(HPhi* phi) {
- DCHECK(iset_->empty());
+ DCHECK(phi->IsLoopHeaderPhi());
// Only unclassified phi cycles are candidates for reductions.
if (induction_range_.IsClassified(phi)) {
return false;
@@ -2399,15 +2399,18 @@ bool HLoopOptimization::TrySetPhiReduction(HPhi* phi) {
HInstruction* reduction = inputs[1];
if (HasReductionFormat(reduction, phi)) {
HLoopInformation* loop_info = phi->GetBlock()->GetLoopInformation();
- uint32_t use_count = 0;
- bool single_use_inside_loop =
+ DCHECK(loop_info->Contains(*reduction->GetBlock()));
+ const bool single_use_inside_loop =
// Reduction update only used by phi.
reduction->GetUses().HasExactlyOneElement() &&
!reduction->HasEnvironmentUses() &&
// Reduction update is only use of phi inside the loop.
- IsOnlyUsedAfterLoop(loop_info, phi, /*collect_loop_uses*/ true, &use_count) &&
- iset_->size() == 1;
- iset_->clear(); // leave the way you found it
+ std::none_of(phi->GetUses().begin(),
+ phi->GetUses().end(),
+ [loop_info, reduction](const HUseListNode<HInstruction*>& use) {
+ HInstruction* user = use.GetUser();
+ return user != reduction && loop_info->Contains(*user->GetBlock());
+ });
if (single_use_inside_loop) {
// Link reduction back, and start recording feed value.
reductions_->Put(reduction, phi);
@@ -2497,8 +2500,7 @@ bool HLoopOptimization::IsOnlyUsedAfterLoop(HLoopInformation* loop_info,
for (const HUseListNode<HInstruction*>& use : instruction->GetUses()) {
HInstruction* user = use.GetUser();
if (iset_->find(user) == iset_->end()) { // not excluded?
- HLoopInformation* other_loop_info = user->GetBlock()->GetLoopInformation();
- if (other_loop_info != nullptr && other_loop_info->IsIn(*loop_info)) {
+ if (loop_info->Contains(*user->GetBlock())) {
// If collect_loop_uses is set, simply keep adding those uses to the set.
// Otherwise, reject uses inside the loop that were not already in the set.
if (collect_loop_uses) {