ART: Refactor GraphVisualizer attribute printing

This patch unifies the way GraphVisualizer prints instruction
attributes in preparation of changes to the Checker syntax.

Change-Id: I44e91e36c660985ddfe039a9f410fedc48b496ec
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index f56e446..93d0e5b 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -347,11 +347,11 @@
 }
 
 void CodeGeneratorARM::DumpCoreRegister(std::ostream& stream, int reg) const {
-  stream << ArmManagedRegister::FromCoreRegister(Register(reg));
+  stream << Register(reg);
 }
 
 void CodeGeneratorARM::DumpFloatingPointRegister(std::ostream& stream, int reg) const {
-  stream << ArmManagedRegister::FromSRegister(SRegister(reg));
+  stream << SRegister(reg);
 }
 
 size_t CodeGeneratorARM::SaveCoreRegister(size_t stack_index, uint32_t reg_id) {
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index b1cb880..0a0902b 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -691,11 +691,11 @@
 }
 
 void CodeGeneratorARM64::DumpCoreRegister(std::ostream& stream, int reg) const {
-  stream << Arm64ManagedRegister::FromXRegister(XRegister(reg));
+  stream << XRegister(reg);
 }
 
 void CodeGeneratorARM64::DumpFloatingPointRegister(std::ostream& stream, int reg) const {
-  stream << Arm64ManagedRegister::FromDRegister(DRegister(reg));
+  stream << DRegister(reg);
 }
 
 void CodeGeneratorARM64::MoveConstant(CPURegister destination, HConstant* constant) {
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 2848a48..0212da1 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -340,11 +340,11 @@
 }
 
 void CodeGeneratorX86::DumpCoreRegister(std::ostream& stream, int reg) const {
-  stream << X86ManagedRegister::FromCpuRegister(Register(reg));
+  stream << Register(reg);
 }
 
 void CodeGeneratorX86::DumpFloatingPointRegister(std::ostream& stream, int reg) const {
-  stream << X86ManagedRegister::FromXmmRegister(XmmRegister(reg));
+  stream << XmmRegister(reg);
 }
 
 size_t CodeGeneratorX86::SaveCoreRegister(size_t stack_index, uint32_t reg_id) {
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index e633970..63d6846 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -396,11 +396,11 @@
 }
 
 void CodeGeneratorX86_64::DumpCoreRegister(std::ostream& stream, int reg) const {
-  stream << X86_64ManagedRegister::FromCpuRegister(Register(reg));
+  stream << Register(reg);
 }
 
 void CodeGeneratorX86_64::DumpFloatingPointRegister(std::ostream& stream, int reg) const {
-  stream << X86_64ManagedRegister::FromXmmRegister(FloatRegister(reg));
+  stream << FloatRegister(reg);
 }
 
 size_t CodeGeneratorX86_64::SaveCoreRegister(size_t stack_index, uint32_t reg_id) {
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc
index f5c630b..189fa06 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -24,8 +24,57 @@
 #include "register_allocator.h"
 #include "ssa_liveness_analysis.h"
 
+#include <cctype>
+#include <sstream>
+
 namespace art {
 
+static bool HasWhitespace(const char* str) {
+  DCHECK(str != nullptr);
+  while (str[0] != 0) {
+    if (isspace(str[0])) {
+      return true;
+    }
+    str++;
+  }
+  return false;
+}
+
+class StringList {
+ public:
+  // Create an empty list
+  StringList() : is_empty_(true) {}
+
+  // Construct StringList from a linked list. List element class T
+  // must provide methods `GetNext` and `Dump`.
+  template<class T>
+  StringList(T* first_entry)
+    : StringList() {
+    for (T* current = first_entry; current != nullptr; current = current->GetNext()) {
+      current->Dump(NewEntryStream());
+    }
+  }
+
+  std::ostream& NewEntryStream() {
+    if (is_empty_) {
+      is_empty_ = false;
+    } else {
+      sstream_ << " ";
+    }
+    return sstream_;
+  }
+
+ private:
+  bool is_empty_;
+  std::ostringstream sstream_;
+
+  friend std::ostream& operator<<(std::ostream& os, const StringList& list);
+};
+
+std::ostream& operator<<(std::ostream& os, const StringList& list) {
+  return os << "[ " << list.sstream_.str() << " ]";
+}
+
 /**
  * HGraph visitor to generate a file suitable for the c1visualizer tool and IRHydra.
  */
@@ -125,76 +174,84 @@
     output_<< std::endl;
   }
 
-  void DumpLocation(Location location) {
+  void DumpLocation(std::ostream& stream, const Location& location) {
     if (location.IsRegister()) {
-      codegen_.DumpCoreRegister(output_, location.reg());
+      codegen_.DumpCoreRegister(stream, location.reg());
     } else if (location.IsFpuRegister()) {
-      codegen_.DumpFloatingPointRegister(output_, location.reg());
+      codegen_.DumpFloatingPointRegister(stream, location.reg());
     } else if (location.IsConstant()) {
-      output_ << "constant";
+      stream << "#";
       HConstant* constant = location.GetConstant();
       if (constant->IsIntConstant()) {
-        output_ << " " << constant->AsIntConstant()->GetValue();
+        stream << constant->AsIntConstant()->GetValue();
       } else if (constant->IsLongConstant()) {
-        output_ << " " << constant->AsLongConstant()->GetValue();
+        stream << constant->AsLongConstant()->GetValue();
       }
     } else if (location.IsInvalid()) {
-      output_ << "invalid";
+      stream << "invalid";
     } else if (location.IsStackSlot()) {
-      output_ << location.GetStackIndex() << "(sp)";
+      stream << location.GetStackIndex() << "(sp)";
     } else if (location.IsFpuRegisterPair()) {
-      codegen_.DumpFloatingPointRegister(output_, location.low());
-      output_ << " and ";
-      codegen_.DumpFloatingPointRegister(output_, location.high());
+      codegen_.DumpFloatingPointRegister(stream, location.low());
+      stream << "|";
+      codegen_.DumpFloatingPointRegister(stream, location.high());
     } else if (location.IsRegisterPair()) {
-      codegen_.DumpCoreRegister(output_, location.low());
-      output_ << " and ";
-      codegen_.DumpCoreRegister(output_, location.high());
+      codegen_.DumpCoreRegister(stream, location.low());
+      stream << "|";
+      codegen_.DumpCoreRegister(stream, location.high());
     } else if (location.IsUnallocated()) {
-      output_ << "<U>";
+      stream << "unallocated";
     } else {
       DCHECK(location.IsDoubleStackSlot());
-      output_ << "2x" << location.GetStackIndex() << "(sp)";
+      stream << "2x" << location.GetStackIndex() << "(sp)";
     }
   }
 
+  std::ostream& StartAttributeStream(const char* name = nullptr) {
+    if (name == nullptr) {
+      output_ << " ";
+    } else {
+      DCHECK(!HasWhitespace(name)) << "Checker does not allow spaces in attributes";
+      output_ << " " << name << ":";
+    }
+    return output_;
+  }
+
   void VisitParallelMove(HParallelMove* instruction) OVERRIDE {
-    output_ << " (";
+    StartAttributeStream("liveness") << instruction->GetLifetimePosition();
+    StringList moves;
     for (size_t i = 0, e = instruction->NumMoves(); i < e; ++i) {
       MoveOperands* move = instruction->MoveOperandsAt(i);
-      DumpLocation(move->GetSource());
-      output_ << " -> ";
-      DumpLocation(move->GetDestination());
-      if (i + 1 != e) {
-        output_ << ", ";
-      }
+      std::ostream& str = moves.NewEntryStream();
+      DumpLocation(str, move->GetSource());
+      str << "->";
+      DumpLocation(str, move->GetDestination());
     }
-    output_ << ")";
-    output_ << " (liveness: " << instruction->GetLifetimePosition() << ")";
+    StartAttributeStream("moves") <<  moves;
   }
 
   void VisitIntConstant(HIntConstant* instruction) OVERRIDE {
-    output_ << " " << instruction->GetValue();
+    StartAttributeStream() << instruction->GetValue();
   }
 
   void VisitLongConstant(HLongConstant* instruction) OVERRIDE {
-    output_ << " " << instruction->GetValue();
+    StartAttributeStream() << instruction->GetValue();
   }
 
   void VisitFloatConstant(HFloatConstant* instruction) OVERRIDE {
-    output_ << " " << instruction->GetValue();
+    StartAttributeStream() << instruction->GetValue();
   }
 
   void VisitDoubleConstant(HDoubleConstant* instruction) OVERRIDE {
-    output_ << " " << instruction->GetValue();
+    StartAttributeStream() << instruction->GetValue();
   }
 
   void VisitPhi(HPhi* phi) OVERRIDE {
-    output_ << " " << phi->GetRegNumber();
+    StartAttributeStream("reg") << phi->GetRegNumber();
   }
 
   void VisitMemoryBarrier(HMemoryBarrier* barrier) OVERRIDE {
-    output_ << " " << barrier->GetBarrierKind();
+    StartAttributeStream("kind") << barrier->GetBarrierKind();
   }
 
   bool IsPass(const char* name) {
@@ -203,65 +260,65 @@
 
   void PrintInstruction(HInstruction* instruction) {
     output_ << instruction->DebugName();
-    instruction->Accept(this);
     if (instruction->InputCount() > 0) {
-      output_ << " [ ";
-      for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) {
-        output_ << GetTypeId(inputs.Current()->GetType()) << inputs.Current()->GetId() << " ";
+      StringList inputs;
+      for (HInputIterator it(instruction); !it.Done(); it.Advance()) {
+        inputs.NewEntryStream() << GetTypeId(it.Current()->GetType()) << it.Current()->GetId();
       }
-      output_ << "]";
+      StartAttributeStream() << inputs;
     }
+    instruction->Accept(this);
     if (instruction->HasEnvironment()) {
-      output_ << " (env:";
+      StringList envs;
       for (HEnvironment* environment = instruction->GetEnvironment();
            environment != nullptr;
            environment = environment->GetParent()) {
-        output_ << " [ ";
+        StringList vregs;
         for (size_t i = 0, e = environment->Size(); i < e; ++i) {
           HInstruction* insn = environment->GetInstructionAt(i);
           if (insn != nullptr) {
-            output_ << GetTypeId(insn->GetType()) << insn->GetId() << " ";
+            vregs.NewEntryStream() << GetTypeId(insn->GetType()) << insn->GetId();
           } else {
-            output_ << " _ ";
+            vregs.NewEntryStream() << "_";
           }
         }
-        output_ << "]";
+        envs.NewEntryStream() << vregs;
       }
-      output_ << ")";
+      StartAttributeStream("env") << envs;
     }
     if (IsPass(SsaLivenessAnalysis::kLivenessPassName)
         && is_after_pass_
         && instruction->GetLifetimePosition() != kNoLifetime) {
-      output_ << " (liveness: " << instruction->GetLifetimePosition();
+      StartAttributeStream("liveness") << instruction->GetLifetimePosition();
       if (instruction->HasLiveInterval()) {
-        output_ << " ";
-        const LiveInterval& interval = *instruction->GetLiveInterval();
-        interval.Dump(output_);
+        LiveInterval* interval = instruction->GetLiveInterval();
+        StartAttributeStream("ranges") << StringList(interval->GetFirstRange());
+        StartAttributeStream("uses") << StringList(interval->GetFirstUse());
+        StartAttributeStream("env_uses") << StringList(interval->GetFirstEnvironmentUse());
+        StartAttributeStream("is_fixed") << interval->IsFixed();
+        StartAttributeStream("is_split") << interval->IsSplit();
+        StartAttributeStream("is_low") << interval->IsLowInterval();
+        StartAttributeStream("is_high") << interval->IsHighInterval();
       }
-      output_ << ")";
     } else if (IsPass(RegisterAllocator::kRegisterAllocatorPassName) && is_after_pass_) {
+      StartAttributeStream("liveness") << instruction->GetLifetimePosition();
       LocationSummary* locations = instruction->GetLocations();
       if (locations != nullptr) {
-        output_ << " ( ";
+        StringList inputs;
         for (size_t i = 0; i < instruction->InputCount(); ++i) {
-          DumpLocation(locations->InAt(i));
-          output_ << " ";
+          DumpLocation(inputs.NewEntryStream(), locations->InAt(i));
         }
-        output_ << ")";
-        if (locations->Out().IsValid()) {
-          output_ << " -> ";
-          DumpLocation(locations->Out());
-        }
+        std::ostream& attr = StartAttributeStream("locations");
+        attr << inputs << "->";
+        DumpLocation(attr, locations->Out());
       }
-      output_ << " (liveness: " << instruction->GetLifetimePosition() << ")";
     } else if (IsPass(LICM::kLoopInvariantCodeMotionPassName)
                || IsPass(HDeadCodeElimination::kFinalDeadCodeEliminationPassName)) {
-      output_ << " ( loop_header:";
       HLoopInformation* info = instruction->GetBlock()->GetLoopInformation();
       if (info == nullptr) {
-        output_ << "null )";
+        StartAttributeStream("loop") << "none";
       } else {
-        output_ << "B" << info->GetHeader()->GetBlockId() << " )";
+        StartAttributeStream("loop") << "B" << info->GetHeader()->GetBlockId();
       }
     }
   }
@@ -281,7 +338,7 @@
       output_ << bci << " " << num_uses << " "
               << GetTypeId(instruction->GetType()) << instruction->GetId() << " ";
       PrintInstruction(instruction);
-      output_ << kEndInstructionMarker << std::endl;
+      output_ << " " << kEndInstructionMarker << std::endl;
     }
   }
 
diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h
index 82c5454..bd55e9f 100644
--- a/compiler/optimizing/ssa_liveness_analysis.h
+++ b/compiler/optimizing/ssa_liveness_analysis.h
@@ -76,7 +76,7 @@
   }
 
   void Dump(std::ostream& stream) const {
-    stream << "[" << start_ << ", " << end_ << ")";
+    stream << start_ << "-" << end_;
   }
 
   LiveRange* Dup(ArenaAllocator* allocator) const {
diff --git a/test/445-checker-licm/src/Main.java b/test/445-checker-licm/src/Main.java
index 91ac2ed..c7a5f04 100644
--- a/test/445-checker-licm/src/Main.java
+++ b/test/445-checker-licm/src/Main.java
@@ -17,13 +17,13 @@
 public class Main {
 
   // CHECK-START: int Main.div() licm (before)
-  // CHECK-DAG: Div ( loop_header:{{B\d+}} )
+  // CHECK-DAG: Div loop:{{B\d+}}
 
   // CHECK-START: int Main.div() licm (after)
-  // CHECK-NOT: Div ( loop_header:{{B\d+}} )
+  // CHECK-NOT: Div loop:{{B\d+}}
 
   // CHECK-START: int Main.div() licm (after)
-  // CHECK-DAG: Div ( loop_header:null )
+  // CHECK-DAG: Div loop:none
 
   public static int div() {
     int result = 0;
@@ -34,13 +34,13 @@
   }
 
   // CHECK-START: int Main.innerDiv() licm (before)
-  // CHECK-DAG: Div ( loop_header:{{B\d+}} )
+  // CHECK-DAG: Div loop:{{B\d+}}
 
   // CHECK-START: int Main.innerDiv() licm (after)
-  // CHECK-NOT: Div ( loop_header:{{B\d+}} )
+  // CHECK-NOT: Div loop:{{B\d+}}
 
   // CHECK-START: int Main.innerDiv() licm (after)
-  // CHECK-DAG: Div ( loop_header:null )
+  // CHECK-DAG: Div loop:none
 
   public static int innerDiv() {
     int result = 0;
@@ -53,10 +53,10 @@
   }
 
   // CHECK-START: int Main.innerDiv2() licm (before)
-  // CHECK-DAG: Mul ( loop_header:{{B4}} )
+  // CHECK-DAG: Mul loop:B4
 
   // CHECK-START: int Main.innerDiv2() licm (after)
-  // CHECK-DAG: Mul ( loop_header:{{B2}} )
+  // CHECK-DAG: Mul loop:B2
 
   public static int innerDiv2() {
     int result = 0;
@@ -72,10 +72,10 @@
   }
 
   // CHECK-START: int Main.innerDiv3(int, int) licm (before)
-  // CHECK-DAG: Div ( loop_header:{{B\d+}} )
+  // CHECK-DAG: Div loop:{{B\d+}}
 
   // CHECK-START: int Main.innerDiv3(int, int) licm (after)
-  // CHECK-DAG: Div ( loop_header:{{B\d+}} )
+  // CHECK-DAG: Div loop:{{B\d+}}
 
   public static int innerDiv3(int a, int b) {
     int result = 0;
@@ -88,16 +88,16 @@
   }
 
   // CHECK-START: int Main.arrayLength(int[]) licm (before)
-  // CHECK-DAG: [[NullCheck:l\d+]] NullCheck ( loop_header:{{B\d+}} )
-  // CHECK-DAG:                    ArrayLength [ [[NullCheck]] ] ( loop_header:{{B\d+}} )
+  // CHECK-DAG: [[NullCheck:l\d+]] NullCheck loop:{{B\d+}}
+  // CHECK-DAG:                    ArrayLength [ [[NullCheck]] ] loop:{{B\d+}}
 
   // CHECK-START: int Main.arrayLength(int[]) licm (after)
-  // CHECK-NOT:                    NullCheck ( loop_header:{{B\d+}} )
-  // CHECK-NOT:                    ArrayLength ( loop_header:{{B\d+}} )
+  // CHECK-NOT:                    NullCheck loop:{{B\d+}}
+  // CHECK-NOT:                    ArrayLength loop:{{B\d+}}
 
   // CHECK-START: int Main.arrayLength(int[]) licm (after)
-  // CHECK-DAG: [[NullCheck:l\d+]] NullCheck ( loop_header:null )
-  // CHECK-DAG:                    ArrayLength [ [[NullCheck]] ] ( loop_header:null )
+  // CHECK-DAG: [[NullCheck:l\d+]] NullCheck loop:none
+  // CHECK-DAG:                    ArrayLength [ [[NullCheck]] ] loop:none
 
   public static int arrayLength(int[] array) {
     int result = 0;
diff --git a/test/476-checker-ctor-memory-barrier/src/Main.java b/test/476-checker-ctor-memory-barrier/src/Main.java
index 10aa2ab..769ae20 100644
--- a/test/476-checker-ctor-memory-barrier/src/Main.java
+++ b/test/476-checker-ctor-memory-barrier/src/Main.java
@@ -17,7 +17,7 @@
 
 class ClassWithoutFinals {
   // CHECK-START: void ClassWithoutFinals.<init>() register (after)
-  // CHECK-NOT: MemoryBarrier {{StoreStore}}
+  // CHECK-NOT: MemoryBarrier kind:StoreStore
   public ClassWithoutFinals() {}
 }
 
@@ -26,7 +26,7 @@
   public ClassWithFinals obj;
 
   // CHECK-START: void ClassWithFinals.<init>(boolean) register (after)
-  // CHECK:     MemoryBarrier {{StoreStore}}
+  // CHECK:     MemoryBarrier kind:StoreStore
   // CHECK-NOT: {{.*}}
   // CHECK:     ReturnVoid
   public ClassWithFinals(boolean cond) {
@@ -38,7 +38,7 @@
   }
 
   // CHECK-START: void ClassWithFinals.<init>() register (after)
-  // CHECK:     MemoryBarrier {{StoreStore}}
+  // CHECK:     MemoryBarrier kind:StoreStore
   // CHECK-NOT: {{.*}}
   // CHECK:     ReturnVoid
   public ClassWithFinals() {
@@ -46,8 +46,8 @@
   }
 
   // CHECK-START: void ClassWithFinals.<init>(int) register (after)
-  // CHECK:     MemoryBarrier {{StoreStore}}
-  // CHECK:     MemoryBarrier {{StoreStore}}
+  // CHECK:     MemoryBarrier kind:StoreStore
+  // CHECK:     MemoryBarrier kind:StoreStore
   // CHECK-NOT: {{.*}}
   // CHECK:     ReturnVoid
   public ClassWithFinals(int x) {
@@ -61,7 +61,7 @@
 
 class InheritFromClassWithFinals extends ClassWithFinals {
   // CHECK-START: void InheritFromClassWithFinals.<init>() register (after)
-  // CHECK:     MemoryBarrier {{StoreStore}}
+  // CHECK:     MemoryBarrier kind:StoreStore
   // CHECK-NOT: {{.*}}
   // CHECK:     ReturnVoid
 
@@ -75,7 +75,7 @@
   // CHECK:     InvokeStaticOrDirect
 
   // CHECK-START: void InheritFromClassWithFinals.<init>(boolean) register (after)
-  // CHECK-NOT: MemoryBarrier {{StoreStore}}
+  // CHECK-NOT: MemoryBarrier kind:StoreStore
   public InheritFromClassWithFinals(boolean cond) {
     super(cond);
     // should not inline the super constructor
@@ -86,8 +86,8 @@
   final int y;
 
   // CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>() register (after)
-  // CHECK:     MemoryBarrier {{StoreStore}}
-  // CHECK:     MemoryBarrier {{StoreStore}}
+  // CHECK:     MemoryBarrier kind:StoreStore
+  // CHECK:     MemoryBarrier kind:StoreStore
   // CHECK-NOT: {{.*}}
   // CHECK:     ReturnVoid
 
@@ -100,7 +100,7 @@
 
   // CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(boolean) register (after)
   // CHECK:     InvokeStaticOrDirect
-  // CHECK:     MemoryBarrier {{StoreStore}}
+  // CHECK:     MemoryBarrier kind:StoreStore
   // CHECK-NOT: {{.*}}
   // CHECK:     ReturnVoid
   public HaveFinalsAndInheritFromClassWithFinals(boolean cond) {
@@ -116,13 +116,13 @@
   // CHECK:     InvokeStaticOrDirect
 
   // CHECK-START: ClassWithFinals Main.noInlineNoConstructorBarrier() register (after)
-  // CHECK-NOT: MemoryBarrier {{StoreStore}}
+  // CHECK-NOT: MemoryBarrier kind:StoreStore
   public static ClassWithFinals noInlineNoConstructorBarrier() {
     return new ClassWithFinals(false);
   }
 
   // CHECK-START: ClassWithFinals Main.inlineConstructorBarrier() register (after)
-  // CHECK:     MemoryBarrier {{StoreStore}}
+  // CHECK:     MemoryBarrier kind:StoreStore
   // CHECK-NOT: {{.*}}
   // CHECK:     Return
 
@@ -133,7 +133,7 @@
   }
 
   // CHECK-START: InheritFromClassWithFinals Main.doubleInlineConstructorBarrier() register (after)
-  // CHECK:     MemoryBarrier {{StoreStore}}
+  // CHECK:     MemoryBarrier kind:StoreStore
   // CHECK-NOT: {{.*}}
   // CHECK:     Return
 
diff --git a/test/482-checker-loop-back-edge-use/src/Main.java b/test/482-checker-loop-back-edge-use/src/Main.java
index 74184e8..334792e 100644
--- a/test/482-checker-loop-back-edge-use/src/Main.java
+++ b/test/482-checker-loop-back-edge-use/src/Main.java
@@ -18,16 +18,16 @@
 public class Main {
 
   // CHECK-START: void Main.loop1(boolean) liveness (after)
-  // CHECK:         ParameterValue (liveness: 2 ranges: { [2, 22) }, uses: { 17 22 }
-  // CHECK:         Goto (liveness: 20)
+  // CHECK:         ParameterValue  liveness:2  ranges:[ 2-22 ] uses:[ 17 22 ]
+  // CHECK:         Goto            liveness:20
   public static void loop1(boolean incoming) {
     while (incoming) {}
   }
 
   // CHECK-START: void Main.loop2(boolean) liveness (after)
-  // CHECK:         ParameterValue (liveness: 2 ranges: { [2, 42) }, uses: { 33 38 42 }
-  // CHECK:         Goto (liveness: 36)
-  // CHECK:         Goto (liveness: 40)
+  // CHECK:         ParameterValue  liveness:2  ranges:[ 2-42 ] uses:[ 33 38 42 ]
+  // CHECK:         Goto            liveness:36
+  // CHECK:         Goto            liveness:40
   public static void loop2(boolean incoming) {
     while (true) {
       System.out.println("foo");
@@ -36,11 +36,11 @@
   }
 
   // CHECK-START: void Main.loop3(boolean) liveness (after)
-  // CHECK:         ParameterValue (liveness: 2 ranges: { [2, 60) }, uses: { 56 60 }
-  // CHECK:         Goto (liveness: 58)
+  // CHECK:         ParameterValue  liveness:2  ranges:[ 2-60 ] uses:[ 56 60 ]
+  // CHECK:         Goto            liveness:58
 
   // CHECK-START: void Main.loop3(boolean) liveness (after)
-  // CHECK-NOT:     Goto (liveness: 54)
+  // CHECK-NOT:     Goto liveness:54
   public static void loop3(boolean incoming) {
     // 'incoming' only needs a use at the outer loop's back edge.
     while (System.currentTimeMillis() != 42) {
@@ -50,10 +50,10 @@
   }
 
   // CHECK-START: void Main.loop4(boolean) liveness (after)
-  // CHECK:         ParameterValue (liveness: 2 ranges: { [2, 22) }, uses: { 22 }
+  // CHECK:         ParameterValue  liveness:2  ranges:[ 2-22 ] uses:[ 22 ]
 
   // CHECK-START: void Main.loop4(boolean) liveness (after)
-  // CHECK-NOT:     Goto (liveness: 20)
+  // CHECK-NOT:     Goto            liveness:20
   public static void loop4(boolean incoming) {
     // 'incoming' has no loop use, so should not have back edge uses.
     System.out.println(incoming);
@@ -63,9 +63,9 @@
   }
 
   // CHECK-START: void Main.loop5(boolean) liveness (after)
-  // CHECK:         ParameterValue (liveness: 2 ranges: { [2, 50) }, uses: { 33 42 46 50 }
-  // CHECK:         Goto (liveness: 44)
-  // CHECK:         Goto (liveness: 48)
+  // CHECK:         ParameterValue  liveness:2  ranges:[ 2-50 ] uses:[ 33 42 46 50 ]
+  // CHECK:         Goto            liveness:44
+  // CHECK:         Goto            liveness:48
   public static void loop5(boolean incoming) {
     // 'incoming' must have a use at both back edges.
     while (Runtime.getRuntime() != null) {
@@ -76,11 +76,11 @@
   }
 
   // CHECK-START: void Main.loop6(boolean) liveness (after)
-  // CHECK          ParameterValue (liveness: 2 ranges: { [2, 46) }, uses: { 24 46 }
-  // CHECK:         Goto (liveness: 44)
+  // CHECK          ParameterValue  liveness:2  ranges:[ 2-46 ] uses:[ 24 46 ]
+  // CHECK:         Goto            liveness:44
 
   // CHECK-START: void Main.loop6(boolean) liveness (after)
-  // CHECK-NOT:     Goto (liveness: 22)
+  // CHECK-NOT:     Goto            liveness:22
   public static void loop6(boolean incoming) {
     // 'incoming' must have a use only at the first loop's back edge.
     while (true) {
@@ -90,9 +90,9 @@
   }
 
   // CHECK-START: void Main.loop7(boolean) liveness (after)
-  // CHECK:         ParameterValue (liveness: 2 ranges: { [2, 50) }, uses: { 32 41 46 50 }
-  // CHECK:         Goto (liveness: 44)
-  // CHECK:         Goto (liveness: 48)
+  // CHECK:         ParameterValue  liveness:2  ranges:[ 2-50 ] uses:[ 32 41 46 50 ]
+  // CHECK:         Goto            liveness:44
+  // CHECK:         Goto            liveness:48
   public static void loop7(boolean incoming) {
     // 'incoming' must have a use at both back edges.
     while (Runtime.getRuntime() != null) {
@@ -102,9 +102,9 @@
   }
 
   // CHECK-START: void Main.loop8() liveness (after)
-  // CHECK:         StaticFieldGet (liveness: 12 ranges: { [12, 44) }, uses: { 35 40 44 }
-  // CHECK:         Goto (liveness: 38)
-  // CHECK:         Goto (liveness: 42)
+  // CHECK:         StaticFieldGet  liveness:12 ranges:[ 12-44 ] uses:[ 35 40 44 ]
+  // CHECK:         Goto            liveness:38
+  // CHECK:         Goto            liveness:42
   public static void loop8() {
     // 'incoming' must have a use at both back edges.
     boolean incoming = field;
@@ -114,8 +114,8 @@
   }
 
   // CHECK-START: void Main.loop9() liveness (after)
-  // CHECK:         StaticFieldGet (liveness: 22 ranges: { [22, 36) }, uses: { 31 36 }
-  // CHECK:         Goto (liveness: 38)
+  // CHECK:         StaticFieldGet  liveness:22 ranges:[ 22-36 ] uses:[ 31 36 ]
+  // CHECK:         Goto            liveness:38
   public static void loop9() {
     while (Runtime.getRuntime() != null) {
       // 'incoming' must only have a use in the inner loop.
diff --git a/test/485-checker-dce-loop-update/smali/TestCase.smali b/test/485-checker-dce-loop-update/smali/TestCase.smali
index 3873ac5..663a6ea 100644
--- a/test/485-checker-dce-loop-update/smali/TestCase.smali
+++ b/test/485-checker-dce-loop-update/smali/TestCase.smali
@@ -29,21 +29,21 @@
 # CHECK-DAG:     [[Cst1:i\d+]]  IntConstant 1
 # CHECK-DAG:     [[Cst5:i\d+]]  IntConstant 5
 # CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
-# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]]
-# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
-# CHECK-DAG:                    If [ [[Cst1]] ]                              loop_header:[[HeaderY]]
-# CHECK-DAG:     [[Add5]]       Add [ [[PhiX]] [[Cst5]] ]                    loop_header:[[HeaderY]]
-# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop_header:[[HeaderY]]
-# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop_header:null
+# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop:[[HeaderY:B\d+]]
+# CHECK-DAG:                    If [ [[ArgY]] ]                              loop:[[HeaderY]]
+# CHECK-DAG:                    If [ [[Cst1]] ]                              loop:[[HeaderY]]
+# CHECK-DAG:     [[Add5]]       Add [ [[PhiX]] [[Cst5]] ]                    loop:[[HeaderY]]
+# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop:[[HeaderY]]
+# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop:none
 
 # CHECK-START: int TestCase.testSingleExit(int, boolean) dead_code_elimination_final (after)
 # CHECK-DAG:     [[ArgX:i\d+]]  ParameterValue
 # CHECK-DAG:     [[ArgY:z\d+]]  ParameterValue
 # CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
-# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[AddX:i\d+]] ]               loop_header:[[HeaderY:B\d+]]
-# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
-# CHECK-DAG:     [[AddX]]       Add [ [[PhiX]] [[Cst7]] ]                    loop_header:[[HeaderY]]
-# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop_header:null
+# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[AddX:i\d+]] ]               loop:[[HeaderY:B\d+]]
+# CHECK-DAG:                    If [ [[ArgY]] ]                              loop:[[HeaderY]]
+# CHECK-DAG:     [[AddX]]       Add [ [[PhiX]] [[Cst7]] ]                    loop:[[HeaderY]]
+# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop:none
 
 .method public static testSingleExit(IZ)I
   .registers 3
@@ -80,24 +80,24 @@
 # CHECK-DAG:     [[Cst1:i\d+]]  IntConstant 1
 # CHECK-DAG:     [[Cst5:i\d+]]  IntConstant 5
 # CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
-# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]]
-# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
-# CHECK-DAG:                    If [ [[ArgZ]] ]                              loop_header:[[HeaderY]]
-# CHECK-DAG:                    If [ [[Cst1]] ]                              loop_header:[[HeaderY]]
-# CHECK-DAG:     [[Add5]]       Add [ [[PhiX]] [[Cst5]] ]                    loop_header:[[HeaderY]]
-# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop_header:[[HeaderY]]
-# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop_header:null
+# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop:[[HeaderY:B\d+]]
+# CHECK-DAG:                    If [ [[ArgY]] ]                              loop:[[HeaderY]]
+# CHECK-DAG:                    If [ [[ArgZ]] ]                              loop:[[HeaderY]]
+# CHECK-DAG:                    If [ [[Cst1]] ]                              loop:[[HeaderY]]
+# CHECK-DAG:     [[Add5]]       Add [ [[PhiX]] [[Cst5]] ]                    loop:[[HeaderY]]
+# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop:[[HeaderY]]
+# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop:none
 
 # CHECK-START: int TestCase.testMultipleExits(int, boolean, boolean) dead_code_elimination_final (after)
 # CHECK-DAG:     [[ArgX:i\d+]]  ParameterValue
 # CHECK-DAG:     [[ArgY:z\d+]]  ParameterValue
 # CHECK-DAG:     [[ArgZ:z\d+]]  ParameterValue
 # CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
-# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add7:i\d+]] ]               loop_header:[[HeaderY:B\d+]]
-# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
-# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop_header:[[HeaderY]]
-# CHECK-DAG:                    If [ [[ArgZ]] ]                              loop_header:null
-# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop_header:null
+# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add7:i\d+]] ]               loop:[[HeaderY:B\d+]]
+# CHECK-DAG:                    If [ [[ArgY]] ]                              loop:[[HeaderY]]
+# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop:[[HeaderY]]
+# CHECK-DAG:                    If [ [[ArgZ]] ]                              loop:none
+# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop:none
 
 .method public static testMultipleExits(IZZ)I
   .registers 4
@@ -137,15 +137,15 @@
 # CHECK-DAG:     [[Cst5:i\d+]]  IntConstant 5
 # CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
 # CHECK-DAG:     [[Cst9:i\d+]]  IntConstant 9
-# CHECK-DAG:     [[PhiX1:i\d+]] Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]]
-# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
-# CHECK-DAG:                    If [ [[ArgZ]] ]                              loop_header:[[HeaderY]]
-# CHECK-DAG:     [[Mul9:i\d+]]  Mul [ [[PhiX1]] [[Cst9]] ]                   loop_header:[[HeaderY]]
-# CHECK-DAG:     [[PhiX2:i\d+]] Phi [ [[Mul9]] [[PhiX1]] ]                   loop_header:[[HeaderY]]
-# CHECK-DAG:                    If [ [[Cst1]] ]                              loop_header:[[HeaderY]]
-# CHECK-DAG:     [[Add5]]       Add [ [[PhiX2]] [[Cst5]] ]                   loop_header:[[HeaderY]]
-# CHECK-DAG:     [[Add7]]       Add [ [[PhiX1]] [[Cst7]] ]                   loop_header:[[HeaderY]]
-# CHECK-DAG:                    Return [ [[PhiX2]] ]                         loop_header:null
+# CHECK-DAG:     [[PhiX1:i\d+]] Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop:[[HeaderY:B\d+]]
+# CHECK-DAG:                    If [ [[ArgY]] ]                              loop:[[HeaderY]]
+# CHECK-DAG:                    If [ [[ArgZ]] ]                              loop:[[HeaderY]]
+# CHECK-DAG:     [[Mul9:i\d+]]  Mul [ [[PhiX1]] [[Cst9]] ]                   loop:[[HeaderY]]
+# CHECK-DAG:     [[PhiX2:i\d+]] Phi [ [[Mul9]] [[PhiX1]] ]                   loop:[[HeaderY]]
+# CHECK-DAG:                    If [ [[Cst1]] ]                              loop:[[HeaderY]]
+# CHECK-DAG:     [[Add5]]       Add [ [[PhiX2]] [[Cst5]] ]                   loop:[[HeaderY]]
+# CHECK-DAG:     [[Add7]]       Add [ [[PhiX1]] [[Cst7]] ]                   loop:[[HeaderY]]
+# CHECK-DAG:                    Return [ [[PhiX2]] ]                         loop:none
 
 # CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination_final (after)
 # CHECK-DAG:     [[ArgX:i\d+]]  ParameterValue
@@ -153,13 +153,13 @@
 # CHECK-DAG:     [[ArgZ:z\d+]]  ParameterValue
 # CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
 # CHECK-DAG:     [[Cst9:i\d+]]  IntConstant 9
-# CHECK-DAG:     [[PhiX1:i\d+]] Phi [ [[ArgX]] [[Add7:i\d+]] ]               loop_header:[[HeaderY:B\d+]]
-# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
-# CHECK-DAG:     [[Add7]]       Add [ [[PhiX1]] [[Cst7]] ]                   loop_header:[[HeaderY]]
-# CHECK-DAG:                    If [ [[ArgZ]] ]                              loop_header:null
-# CHECK-DAG:     [[Mul9:i\d+]]  Mul [ [[PhiX1]] [[Cst9]] ]                   loop_header:null
-# CHECK-DAG:     [[PhiX2:i\d+]] Phi [ [[Mul9]] [[PhiX1]] ]                   loop_header:null
-# CHECK-DAG:                    Return [ [[PhiX2]] ]                         loop_header:null
+# CHECK-DAG:     [[PhiX1:i\d+]] Phi [ [[ArgX]] [[Add7:i\d+]] ]               loop:[[HeaderY:B\d+]]
+# CHECK-DAG:                    If [ [[ArgY]] ]                              loop:[[HeaderY]]
+# CHECK-DAG:     [[Add7]]       Add [ [[PhiX1]] [[Cst7]] ]                   loop:[[HeaderY]]
+# CHECK-DAG:                    If [ [[ArgZ]] ]                              loop:none
+# CHECK-DAG:     [[Mul9:i\d+]]  Mul [ [[PhiX1]] [[Cst9]] ]                   loop:none
+# CHECK-DAG:     [[PhiX2:i\d+]] Phi [ [[Mul9]] [[PhiX1]] ]                   loop:none
+# CHECK-DAG:                    Return [ [[PhiX2]] ]                         loop:none
 
 .method public static testExitPredecessors(IZZ)I
   .registers 4
@@ -205,19 +205,19 @@
 # CHECK-DAG:     [[Cst5:i\d+]]  IntConstant 5
 # CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
 #
-# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]]
-# CHECK-DAG:     [[PhiZ1:i\d+]] Phi [ [[ArgZ]] [[XorZ:i\d+]] [[PhiZ1]] ]     loop_header:[[HeaderY]]
-# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
+# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop:[[HeaderY:B\d+]]
+# CHECK-DAG:     [[PhiZ1:i\d+]] Phi [ [[ArgZ]] [[XorZ:i\d+]] [[PhiZ1]] ]     loop:[[HeaderY]]
+# CHECK-DAG:                    If [ [[ArgY]] ]                              loop:[[HeaderY]]
 #
 #                               ### Inner loop ###
-# CHECK-DAG:     [[PhiZ2:i\d+]] Phi [ [[PhiZ1]] [[XorZ]] ]                   loop_header:[[HeaderZ:B\d+]]
-# CHECK-DAG:     [[XorZ]]       Xor [ [[PhiZ2]] [[Cst1]] ]                   loop_header:[[HeaderZ]]
-# CHECK-DAG:     [[CondZ:z\d+]] Equal [ [[XorZ]] [[Cst0]] ]                  loop_header:[[HeaderZ]]
-# CHECK-DAG:                    If [ [[CondZ]] ]                             loop_header:[[HeaderZ]]
+# CHECK-DAG:     [[PhiZ2:i\d+]] Phi [ [[PhiZ1]] [[XorZ]] ]                   loop:[[HeaderZ:B\d+]]
+# CHECK-DAG:     [[XorZ]]       Xor [ [[PhiZ2]] [[Cst1]] ]                   loop:[[HeaderZ]]
+# CHECK-DAG:     [[CondZ:z\d+]] Equal [ [[XorZ]] [[Cst0]] ]                  loop:[[HeaderZ]]
+# CHECK-DAG:                    If [ [[CondZ]] ]                             loop:[[HeaderZ]]
 #
-# CHECK-DAG:     [[Add5]]       Add [ [[PhiX]] [[Cst5]] ]                    loop_header:[[HeaderY]]
-# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop_header:[[HeaderY]]
-# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop_header:null
+# CHECK-DAG:     [[Add5]]       Add [ [[PhiX]] [[Cst5]] ]                    loop:[[HeaderY]]
+# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop:[[HeaderY]]
+# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop:none
 
 # CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination_final (after)
 # CHECK-DAG:     [[ArgX:i\d+]]  ParameterValue
@@ -227,18 +227,18 @@
 # CHECK-DAG:     [[Cst1:i\d+]]  IntConstant 1
 # CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
 #
-# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add7:i\d+]] ]               loop_header:[[HeaderY:B\d+]]
-# CHECK-DAG:     [[PhiZ1:i\d+]] Phi [ [[ArgZ]] [[PhiZ1]] ]                   loop_header:[[HeaderY]]
-# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
-# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop_header:[[HeaderY]]
+# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add7:i\d+]] ]               loop:[[HeaderY:B\d+]]
+# CHECK-DAG:     [[PhiZ1:i\d+]] Phi [ [[ArgZ]] [[PhiZ1]] ]                   loop:[[HeaderY]]
+# CHECK-DAG:                    If [ [[ArgY]] ]                              loop:[[HeaderY]]
+# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop:[[HeaderY]]
 #
 #                               ### Inner loop ###
-# CHECK-DAG:     [[PhiZ2:i\d+]] Phi [ [[PhiZ1]] [[XorZ:i\d+]] ]              loop_header:[[HeaderZ:B\d+]]
-# CHECK-DAG:     [[XorZ]]       Xor [ [[PhiZ2]] [[Cst1]] ]                   loop_header:[[HeaderZ]]
-# CHECK-DAG:     [[CondZ:z\d+]] Equal [ [[XorZ]] [[Cst0]] ]                  loop_header:[[HeaderZ]]
-# CHECK-DAG:                    If [ [[CondZ]] ]                             loop_header:[[HeaderZ]]
+# CHECK-DAG:     [[PhiZ2:i\d+]] Phi [ [[PhiZ1]] [[XorZ:i\d+]] ]              loop:[[HeaderZ:B\d+]]
+# CHECK-DAG:     [[XorZ]]       Xor [ [[PhiZ2]] [[Cst1]] ]                   loop:[[HeaderZ]]
+# CHECK-DAG:     [[CondZ:z\d+]] Equal [ [[XorZ]] [[Cst0]] ]                  loop:[[HeaderZ]]
+# CHECK-DAG:                    If [ [[CondZ]] ]                             loop:[[HeaderZ]]
 #
-# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop_header:null
+# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop:none
 
 .method public static testInnerLoop(IZZ)I
   .registers 4