Make slow paths easier to write
This adds a class LIRSlowPath that allows for deferred compilation
of slow paths. Using this object you can add code that will be
invoked out of line using a forward branch. The intention is to
move the slow paths out of the main flow and avoid branch-over
constructs that will almost always trigger. The forward branch
to the slow path code will be predicted false and this will
be correct most of the time. The slow path code returns to the
instruction after the original branch using an unconditional branch.
This is used in the following opcodes: sput, sget, const-string,
check-cast, const-class.
Others will follow.
Bug: 10864890
Change-Id: I17130c5dc20d369bc6bbf50b8cf04343263e888e
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 1f4122d..ae54fb8 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -839,6 +839,8 @@
next_bb = iter.Next();
} while ((next_bb != NULL) && (next_bb->block_type == kDead));
}
+ HandleSlowPaths();
+
cu_->NewTimingSplit("Launchpads");
HandleSuspendLaunchPads();
@@ -847,4 +849,15 @@
HandleIntrinsicLaunchPads();
}
+//
+// LIR Slow Path
+//
+
+LIR* Mir2Lir::LIRSlowPath::GenerateTargetLabel() {
+ LIR* target = m2l_->RawLIR(current_dex_pc_, kPseudoTargetLabel);
+ m2l_->AppendLIR(target);
+ fromfast_->target = target;
+ m2l_->SetCurrentDexPc(current_dex_pc_);
+ return target;
+}
} // namespace art