summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Anton Shamin <anton.shamin@intel.com> 2016-05-16 16:44:13 +0600
committer Anton Shamin <anton.shamin@intel.com> 2016-06-07 01:11:44 +0600
commitf89381fed12faf96c45a83a989ae2fff82c05f3b (patch)
treefafdf6e995bbea12c62220e9e8cda6a7d22fc139 /compiler/optimizing
parent2e1c66e37db7eaa713459e15b115d5c217d6e414 (diff)
ART: ArrayGet hoisting restriction added.
Currently if we hoist ArrayGet from loop there is no guarantee that insn will be executed at runtime. Because of that we could face issues like crashes in generated code. This patch introduces restriction for ArrayGet hoisting. We say that ArrayGet execution is guaranteed at least one time if its bb dominates all exit blocks. Change-Id: I9f72c0f4c33b358341109238bea46cb5a82f490f Signed-off-by: Anton Shamin <anton.shamin@intel.com>
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/bounds_check_elimination.cc14
-rw-r--r--compiler/optimizing/nodes.cc9
-rw-r--r--compiler/optimizing/nodes.h2
3 files changed, 17 insertions, 8 deletions
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc
index 6c6e5af0b2..96c9e3d3c5 100644
--- a/compiler/optimizing/bounds_check_elimination.cc
+++ b/compiler/optimizing/bounds_check_elimination.cc
@@ -1169,7 +1169,11 @@ class BCEVisitor : public HGraphVisitor {
loop->IsDefinedOutOfTheLoop(array_get->InputAt(1))) {
SideEffects loop_effects = side_effects_.GetLoopEffects(loop->GetHeader());
if (!array_get->GetSideEffects().MayDependOn(loop_effects)) {
- HoistToPreHeaderOrDeoptBlock(loop, array_get);
+ // We can hoist ArrayGet only if its execution is guaranteed on every iteration.
+ // In other words only if array_get_bb dominates all back branches.
+ if (loop->DominatesAllBackEdges(array_get->GetBlock())) {
+ HoistToPreHeaderOrDeoptBlock(loop, array_get);
+ }
}
}
}
@@ -1394,13 +1398,7 @@ class BCEVisitor : public HGraphVisitor {
}
// Does the current basic block dominate all back edges? If not,
// don't apply dynamic bce to something that may not be executed.
- for (HBasicBlock* back_edge : loop->GetBackEdges()) {
- if (!block->Dominates(back_edge)) {
- return false;
- }
- }
- // Success!
- return true;
+ return loop->DominatesAllBackEdges(block);
}
return false;
}
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 60329ccff2..f4d3842ff9 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -734,6 +734,15 @@ bool HLoopInformation::HasBackEdgeNotDominatedByHeader() const {
return false;
}
+bool HLoopInformation::DominatesAllBackEdges(HBasicBlock* block) {
+ for (HBasicBlock* back_edge : GetBackEdges()) {
+ if (!block->Dominates(back_edge)) {
+ return false;
+ }
+ }
+ return true;
+}
+
bool HBasicBlock::Dominates(HBasicBlock* other) const {
// Walk up the dominator tree from `other`, to find out if `this`
// is an ancestor.
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index c08323a0c6..38472cf8e8 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -733,6 +733,8 @@ class HLoopInformation : public ArenaObject<kArenaAllocLoopInfo> {
return blocks_.GetHighestBitSet() != -1;
}
+ bool DominatesAllBackEdges(HBasicBlock* block);
+
private:
// Internal recursive implementation of `Populate`.
void PopulateRecursive(HBasicBlock* block);