diff options
author | 2015-05-15 13:21:51 +0000 | |
---|---|---|
committer | 2015-05-15 13:21:52 +0000 | |
commit | 1cad536d675846ac9c110b5b3a412dfc55ace3ed (patch) | |
tree | 6d727dc91afa0ad51abf277604ee1b32ae07f419 | |
parent | 38b06de7de49400d83bfe3221649a0e1a1a96dec (diff) | |
parent | c74652867cd9293e86232324e5e057cd73c48e74 (diff) |
Merge "ART: Refactor GraphVisualizer attribute printing"
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/graph_visualizer.cc | 177 | ||||
-rw-r--r-- | compiler/optimizing/ssa_liveness_analysis.h | 2 | ||||
-rw-r--r-- | test/445-checker-licm/src/Main.java | 32 | ||||
-rw-r--r-- | test/476-checker-ctor-memory-barrier/src/Main.java | 26 | ||||
-rw-r--r-- | test/482-checker-loop-back-edge-use/src/Main.java | 48 | ||||
-rw-r--r-- | test/485-checker-dce-loop-update/smali/TestCase.smali | 114 |
10 files changed, 236 insertions, 179 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index f56e446605..93d0e5b2bf 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -347,11 +347,11 @@ inline Condition ARMOppositeCondition(IfCondition cond) { } 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 b1cb8802b3..0a0902b0e9 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -691,11 +691,11 @@ size_t CodeGeneratorARM64::RestoreFloatingPointRegister(size_t stack_index, uint } 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 2848a48a64..0212da106b 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -340,11 +340,11 @@ inline Condition X86Condition(IfCondition cond) { } 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 e633970279..63d68465d0 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -396,11 +396,11 @@ void CodeGeneratorX86_64::GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invo } 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 f5c630bf97..189fa0618e 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 @@ class HGraphVisualizerPrinter : public HGraphVisitor { 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 @@ class HGraphVisualizerPrinter : public HGraphVisitor { 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_ << " "; - } - output_ << ")"; - if (locations->Out().IsValid()) { - output_ << " -> "; - DumpLocation(locations->Out()); + DumpLocation(inputs.NewEntryStream(), locations->InAt(i)); } + 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 @@ class HGraphVisualizerPrinter : public HGraphVisitor { 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 82c5454bb0..bd55e9fc7f 100644 --- a/compiler/optimizing/ssa_liveness_analysis.h +++ b/compiler/optimizing/ssa_liveness_analysis.h @@ -76,7 +76,7 @@ class LiveRange FINAL : public ArenaObject<kArenaAllocMisc> { } 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 91ac2edbdc..c7a5f04884 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 @@ public class Main { } // 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 @@ public class Main { } // 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 @@ public class Main { } // 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 @@ public class Main { } // 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 10aa2ab164..769ae208d9 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 @@ class ClassWithFinals { 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 @@ class ClassWithFinals { } // CHECK-START: void ClassWithFinals.<init>() register (after) - // CHECK: MemoryBarrier {{StoreStore}} + // CHECK: MemoryBarrier kind:StoreStore // CHECK-NOT: {{.*}} // CHECK: ReturnVoid public ClassWithFinals() { @@ -46,8 +46,8 @@ class ClassWithFinals { } // 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 ClassWithFinals { 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 @@ class InheritFromClassWithFinals extends ClassWithFinals { // 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 @@ class HaveFinalsAndInheritFromClassWithFinals extends ClassWithFinals { 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 @@ class HaveFinalsAndInheritFromClassWithFinals extends ClassWithFinals { // 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 @@ public class Main { // 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 @@ public class Main { } // 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 74184e8252..334792e475 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 @@ public class Main { } // 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 @@ public class Main { } // 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 @@ public class Main { } // 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 @@ public class Main { } // 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 @@ public class Main { } // 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 @@ public class Main { } // 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 @@ public class Main { } // 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 3873ac50c7..663a6ea1d5 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 |