ARM: Port instr simplification of array accesses.
After changing the addressing mode for array accesses (in
https://android-review.googlesource.com/248406) the 'add'
instruction that calculates the base address for the array can be
shared across accesses to the same array.
Before https://android-review.googlesource.com/248406:
add IP, r[Array], r[Index0], LSL #2
ldr r0, [IP, #12]
add IP, r[Array], r[Index1], LSL #2
ldr r0, [IP, #12]
Before this CL:
add IP. r[Array], #12
ldr r0, [IP, r[Index0], LSL #2]
add IP. r[Array], #12
ldr r0, [IP, r[Index1], LSL #2]
After this CL:
add IP. r[Array], #12
ldr r0, [IP, r[Index0], LSL #2]
ldr r0, [IP, r[Index1], LSL #2]
Link to the original optimization:
https://android-review.googlesource.com/#/c/127310/
Test: Run ART test suite on Nexus 6.
Change-Id: Iee26f9a0a7ca46abb90e3f60d19d22dc8dee4d8f
diff --git a/compiler/optimizing/instruction_simplifier_arm.cc b/compiler/optimizing/instruction_simplifier_arm.cc
index cd026b8..495f3fd 100644
--- a/compiler/optimizing/instruction_simplifier_arm.cc
+++ b/compiler/optimizing/instruction_simplifier_arm.cc
@@ -14,8 +14,10 @@
* limitations under the License.
*/
+#include "code_generator.h"
#include "instruction_simplifier_arm.h"
#include "instruction_simplifier_shared.h"
+#include "mirror/array-inl.h"
namespace art {
namespace arm {
@@ -38,6 +40,46 @@
}
}
+void InstructionSimplifierArmVisitor::VisitArrayGet(HArrayGet* instruction) {
+ size_t data_offset = CodeGenerator::GetArrayDataOffset(instruction);
+ Primitive::Type type = instruction->GetType();
+
+ if (type == Primitive::kPrimLong
+ || type == Primitive::kPrimFloat
+ || type == Primitive::kPrimDouble) {
+ // T32 doesn't support ShiftedRegOffset mem address mode for these types
+ // to enable optimization.
+ return;
+ }
+
+ if (TryExtractArrayAccessAddress(instruction,
+ instruction->GetArray(),
+ instruction->GetIndex(),
+ data_offset)) {
+ RecordSimplification();
+ }
+}
+
+void InstructionSimplifierArmVisitor::VisitArraySet(HArraySet* instruction) {
+ size_t access_size = Primitive::ComponentSize(instruction->GetComponentType());
+ size_t data_offset = mirror::Array::DataOffset(access_size).Uint32Value();
+ Primitive::Type type = instruction->GetComponentType();
+
+ if (type == Primitive::kPrimLong
+ || type == Primitive::kPrimFloat
+ || type == Primitive::kPrimDouble) {
+ // T32 doesn't support ShiftedRegOffset mem address mode for these types
+ // to enable optimization.
+ return;
+ }
+
+ if (TryExtractArrayAccessAddress(instruction,
+ instruction->GetArray(),
+ instruction->GetIndex(),
+ data_offset)) {
+ RecordSimplification();
+ }
+}
} // namespace arm
} // namespace art