OSDN Git Service

Move loop invariant utility to more general place.
authorAart Bik <ajcbik@google.com>
Wed, 28 Oct 2015 22:28:08 +0000 (15:28 -0700)
committerAart Bik <ajcbik@google.com>
Thu, 29 Oct 2015 20:29:50 +0000 (13:29 -0700)
Change-Id: I15ebfbf9684f0fcce9e63d078ff8dc1381fd1ca3

compiler/optimizing/induction_var_analysis.cc
compiler/optimizing/nodes.cc
compiler/optimizing/nodes.h

index b6220fc..fdf8cc9 100644 (file)
 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;
index 3480265..8b28ff9 100644 (file)
@@ -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()) {
index 7ac39d1..0565c9a 100644 (file)
@@ -551,6 +551,12 @@ class HLoopInformation : public ArenaObject<kArenaAllocLoopInfo> {
   // 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);