From 73f1f3be46652d3f6df61b4234c366ebbf81274a Mon Sep 17 00:00:00 2001 From: Aart Bik Date: Wed, 28 Oct 2015 15:28:08 -0700 Subject: [PATCH] Move loop invariant utility to more general place. Change-Id: I15ebfbf9684f0fcce9e63d078ff8dc1381fd1ca3 --- compiler/optimizing/induction_var_analysis.cc | 15 +-------------- compiler/optimizing/nodes.cc | 11 +++++++++++ compiler/optimizing/nodes.h | 6 ++++++ 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/compiler/optimizing/induction_var_analysis.cc b/compiler/optimizing/induction_var_analysis.cc index b6220fc13..fdf8cc9c1 100644 --- a/compiler/optimizing/induction_var_analysis.cc +++ b/compiler/optimizing/induction_var_analysis.cc @@ -20,19 +20,6 @@ namespace art { /** - * Returns true if instruction is invariant within the given loop - * (instruction is not defined in same or more inner loop). - */ -static bool IsLoopInvariant(HLoopInformation* loop, HInstruction* instruction) { - HLoopInformation* other_loop = instruction->GetBlock()->GetLoopInformation(); - if (other_loop != loop && (other_loop == nullptr || !other_loop->IsIn(*loop))) { - DCHECK(instruction->GetBlock()->Dominates(loop->GetHeader())); - return true; - } - return false; -} - -/** * Since graph traversal may enter a SCC at any position, an initial representation may be rotated, * along dependences, viz. any of (a, b, c, d), (d, a, b, c) (c, d, a, b), (b, c, d, a) assuming * a chain of dependences (mutual independent items may occur in arbitrary order). For proper @@ -718,7 +705,7 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::LookupInfo(HLoopInf return loop_it->second; } } - if (IsLoopInvariant(loop, instruction)) { + if (loop->IsLoopInvariant(instruction, true)) { InductionInfo* info = CreateInvariantFetch(instruction); AssignInfo(loop, instruction, info); return info; diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 348026551..8b28ff91d 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -574,6 +574,17 @@ bool HLoopInformation::IsIn(const HLoopInformation& other) const { return other.blocks_.IsBitSet(header_->GetBlockId()); } +bool HLoopInformation::IsLoopInvariant(HInstruction* instruction, bool must_dominate) const { + HLoopInformation* other_loop = instruction->GetBlock()->GetLoopInformation(); + if (other_loop != this && (other_loop == nullptr || !other_loop->IsIn(*this))) { + if (must_dominate) { + return instruction->GetBlock()->Dominates(GetHeader()); + } + return true; + } + return false; +} + size_t HLoopInformation::GetLifetimeEnd() const { size_t last_position = 0; for (HBasicBlock* back_edge : GetBackEdges()) { diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 7ac39d1a8..0565c9a1c 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -551,6 +551,12 @@ class HLoopInformation : public ArenaObject { // Note that `other` *must* be populated before entering this function. bool IsIn(const HLoopInformation& other) const; + // Returns true if instruction is not defined within this loop or any loop nested inside + // this loop. If must_dominate is set, only definitions that actually dominate the loop + // header can be invariant. Otherwise, any definition outside the loop, including + // definitions that appear after the loop, is invariant. + bool IsLoopInvariant(HInstruction* instruction, bool must_dominate) const; + const ArenaBitVector& GetBlocks() const { return blocks_; } void Add(HBasicBlock* block); -- 2.11.0