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