Deoptimization-based BCE for unknown loop bounds.
For loop like:
for (int i = start; i < end; i++) {
array[i] = 1;
}
We add the following to the loop pre-header:
if (start < 0) deoptimize();
if (end > array.length) deoptimize();
Then we can eliminate bounds-check of array[i] inside the loop.
We also take care of indexing with induction variable plus some offsets,
like array[i - 1]/array[i + 1] inside the loop, and adjust the condition
for deoptimization accordingly.
Change-Id: I9e24c6b5e134ff95eff5b5605ff8f95d6546616f
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 6b9d72d..181122f 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -1007,6 +1007,10 @@
}
void CopyFrom(HEnvironment* env);
+ // Copy from `env`. If it's a loop phi for `loop_header`, copy the first
+ // input to the loop phi instead. This is for inserting instructions that
+ // require an environment (like HDeoptimization) in the loop pre-header.
+ void CopyFromWithLoopPhiAdjustment(HEnvironment* env, HBasicBlock* loop_header);
void SetRawEnvAt(size_t index, HInstruction* instruction) {
vregs_.Put(index, HUserRecord<HEnvironment*>(instruction));
@@ -1242,6 +1246,13 @@
environment_->CopyFrom(environment);
}
+ void CopyEnvironmentFromWithLoopPhiAdjustment(HEnvironment* environment,
+ HBasicBlock* block) {
+ ArenaAllocator* allocator = GetBlock()->GetGraph()->GetArena();
+ environment_ = new (allocator) HEnvironment(allocator, environment->Size());
+ environment_->CopyFromWithLoopPhiAdjustment(environment, block);
+ }
+
// Returns the number of entries in the environment. Typically, that is the
// number of dex registers in a method. It could be more in case of inlining.
size_t EnvironmentSize() const;