ART: Update loop info of all nested loops when inlining

When inlining into a nested loop, the inliner would only add the new
blocks into the innermost loop info object. This patch fixes that and
modifies SsaChecker to verify the property.

Change-Id: I21d343a6f7d972f5b7420701f816c65ab3f20566
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index 2216cec..e743d8e 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -276,6 +276,17 @@
                             id));
     }
   }
+
+  // If this is a nested loop, ensure the outer loops contain a superset of the blocks.
+  for (HLoopInformationOutwardIterator it(*loop_header); !it.Done(); it.Advance()) {
+    HLoopInformation* outer_info = it.Current();
+    if (!loop_blocks.IsSubsetOf(&outer_info->GetBlocks())) {
+      AddError(StringPrintf("Blocks of loop defined by header %d are not a subset of blocks of "
+                            "an outer loop defined by header %d.",
+                            loop_header->GetBlockId(),
+                            outer_info->GetHeader()->GetBlockId()));
+    }
+  }
 }
 
 void SSAChecker::VisitInstruction(HInstruction* instruction) {
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 5fca4fa..4b9d4fc 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -1064,8 +1064,10 @@
         outer_graph->AddBlock(current);
         outer_graph->reverse_post_order_.Put(++index_of_at, current);
         if (info != nullptr) {
-          info->Add(current);
           current->SetLoopInformation(info);
+          for (HLoopInformationOutwardIterator loop_it(*at); !loop_it.Done(); loop_it.Advance()) {
+            loop_it.Current()->Add(current);
+          }
         }
       }
     }
@@ -1075,8 +1077,10 @@
     outer_graph->AddBlock(to);
     outer_graph->reverse_post_order_.Put(++index_of_at, to);
     if (info != nullptr) {
-      info->Add(to);
       to->SetLoopInformation(info);
+      for (HLoopInformationOutwardIterator loop_it(*at); !loop_it.Done(); loop_it.Advance()) {
+        loop_it.Current()->Add(to);
+      }
       if (info->IsBackEdge(*at)) {
         // Only `at` can become a back edge, as the inlined blocks
         // are predecessors of `at`.