Implement irreducible loop support in optimizing.
So we don't fallback to the interpreter in the presence of
irreducible loops.
Implications:
- A loop pre-header does not necessarily dominate a loop header.
- Non-constant redundant phis will be kept in loop headers, to
satisfy our linear scan register allocation algorithm.
- while-graph optimizations, such as gvn, licm, lse, and dce
need to know when they are dealing with irreducible loops.
Change-Id: I2cea8934ce0b40162d215353497c7f77d6c9137e
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc
index 5f1328f..32c3a92 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -486,7 +486,9 @@
StartAttributeStream("is_low") << interval->IsLowInterval();
StartAttributeStream("is_high") << interval->IsHighInterval();
}
- } else if (IsPass(RegisterAllocator::kRegisterAllocatorPassName) && is_after_pass_) {
+ }
+
+ if (IsPass(RegisterAllocator::kRegisterAllocatorPassName) && is_after_pass_) {
StartAttributeStream("liveness") << instruction->GetLifetimePosition();
LocationSummary* locations = instruction->GetLocations();
if (locations != nullptr) {
@@ -498,15 +500,29 @@
attr << inputs << "->";
DumpLocation(attr, locations->Out());
}
- } else if (IsPass(LICM::kLoopInvariantCodeMotionPassName)
- || IsPass(HDeadCodeElimination::kFinalDeadCodeEliminationPassName)) {
+ }
+
+ if (IsPass(LICM::kLoopInvariantCodeMotionPassName)
+ || IsPass(HDeadCodeElimination::kFinalDeadCodeEliminationPassName)
+ || IsPass(HDeadCodeElimination::kInitialDeadCodeEliminationPassName)
+ || IsPass(SsaBuilder::kSsaBuilderPassName)) {
HLoopInformation* info = instruction->GetBlock()->GetLoopInformation();
if (info == nullptr) {
StartAttributeStream("loop") << "none";
} else {
StartAttributeStream("loop") << "B" << info->GetHeader()->GetBlockId();
+ HLoopInformation* outer = info->GetPreHeader()->GetLoopInformation();
+ if (outer != nullptr) {
+ StartAttributeStream("outer_loop") << "B" << outer->GetHeader()->GetBlockId();
+ } else {
+ StartAttributeStream("outer_loop") << "none";
+ }
+ StartAttributeStream("irreducible")
+ << std::boolalpha << info->IsIrreducible() << std::noboolalpha;
}
- } else if ((IsPass(SsaBuilder::kSsaBuilderPassName)
+ }
+
+ if ((IsPass(SsaBuilder::kSsaBuilderPassName)
|| IsPass(HInliner::kInlinerPassName))
&& (instruction->GetType() == Primitive::kPrimNot)) {
ReferenceTypeInfo info = instruction->IsLoadClass()