summaryrefslogtreecommitdiff
path: root/compiler/optimizing/loop_optimization.cc
diff options
context:
space:
mode:
authorAart Bik <ajcbik@google.com>2017-06-28 14:08:00 -0700
committerAart Bik <ajcbik@google.com>2017-06-29 11:20:56 -0700
commit37dc4df47fec811ea52f7180880961565f013434 (patch)
treeeac308a6c7ef8b7d53f64889ff0a93740a2dc62a /compiler/optimizing/loop_optimization.cc
parent76754cc816af46b41a8d1f419a38334b5db59b6e (diff)
Improved subscript and data dependence analysis.
Rationale: We missed vectorizing a simple stencil operation due to inaccurate unit stride analysis and failure to detect single runtime data dependence test. Test: test-art-host, test-art-target Change-Id: I07ba03455bfb1c0aff371c1244a1328f885d0916
Diffstat (limited to 'compiler/optimizing/loop_optimization.cc')
-rw-r--r--compiler/optimizing/loop_optimization.cc20
1 files changed, 12 insertions, 8 deletions
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 32f40024d3..b61d7b80d1 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -620,12 +620,15 @@ bool HLoopOptimization::ShouldVectorize(LoopNode* node, HBasicBlock* block, int6
// Conservatively assume a potential loop-carried data dependence otherwise, avoided by
// generating an explicit a != b disambiguation runtime test on the two references.
if (x != y) {
- // For now, we reject after one test to avoid excessive overhead.
- if (vector_runtime_test_a_ != nullptr) {
- return false;
+ // To avoid excessive overhead, we only accept one a != b test.
+ if (vector_runtime_test_a_ == nullptr) {
+ // First test found.
+ vector_runtime_test_a_ = a;
+ vector_runtime_test_b_ = b;
+ } else if ((vector_runtime_test_a_ != a || vector_runtime_test_b_ != b) &&
+ (vector_runtime_test_a_ != b || vector_runtime_test_b_ != a)) {
+ return false; // second test would be needed
}
- vector_runtime_test_a_ = a;
- vector_runtime_test_b_ = b;
}
}
}
@@ -842,7 +845,7 @@ bool HLoopOptimization::VectorizeDef(LoopNode* node,
HInstruction* offset = nullptr;
if (TrySetVectorType(type, &restrictions) &&
node->loop_info->IsDefinedOutOfTheLoop(base) &&
- induction_range_.IsUnitStride(instruction, index, &offset) &&
+ induction_range_.IsUnitStride(instruction, index, graph_, &offset) &&
VectorizeUse(node, value, generate_code, type, restrictions)) {
if (generate_code) {
GenerateVecSub(index, offset);
@@ -900,7 +903,7 @@ bool HLoopOptimization::VectorizeUse(LoopNode* node,
HInstruction* offset = nullptr;
if (type == instruction->GetType() &&
node->loop_info->IsDefinedOutOfTheLoop(base) &&
- induction_range_.IsUnitStride(instruction, index, &offset)) {
+ induction_range_.IsUnitStride(instruction, index, graph_, &offset)) {
if (generate_code) {
GenerateVecSub(index, offset);
GenerateVecMem(instruction, vector_map_->Get(index), nullptr, offset, type);
@@ -1216,7 +1219,8 @@ void HLoopOptimization::GenerateVecInv(HInstruction* org, Primitive::Type type)
void HLoopOptimization::GenerateVecSub(HInstruction* org, HInstruction* offset) {
if (vector_map_->find(org) == vector_map_->end()) {
HInstruction* subscript = vector_index_;
- if (offset != nullptr) {
+ int64_t value = 0;
+ if (!IsInt64AndGet(offset, &value) || value != 0) {
subscript = new (global_allocator_) HAdd(Primitive::kPrimInt, subscript, offset);
if (org->IsPhi()) {
Insert(vector_body_, subscript); // lacks layout placeholder