summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_generator_mips.cc
diff options
context:
space:
mode:
authorLena Djokic <Lena.Djokic@imgtec.com>2017-09-21 13:50:52 +0200
committerLena Djokic <Lena.Djokic@imgtec.com>2017-10-05 11:43:34 +0200
commita290160f74ee53c0ffb51c7b3ac916d239c9556a (patch)
tree0bfc9728ccee68dbd359b023319423f703448aac /compiler/optimizing/code_generator_mips.cc
parent86d244ec33f333b32301a9ee09088300c8544a7b (diff)
MIPS32R2: Share address computation
For array accesses the element address has the following structure: Address = CONST_OFFSET + base_addr + index << ELEM_SHIFT The address part (index << ELEM_SHIFT) can be shared across array accesses with the same data type and index. For example, in the following loop 5 accesses can share address computation: void foo(int[] a, int[] b, int[] c) { for (i...) { a[i] = a[i] + 5; b[i] = b[i] + c[i]; } } Test: test-art-host, test-art-target Change-Id: Id09fa782934aad4ee47669275e7e1a4d7d23b0fa
Diffstat (limited to 'compiler/optimizing/code_generator_mips.cc')
-rw-r--r--compiler/optimizing/code_generator_mips.cc50
1 files changed, 50 insertions, 0 deletions
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index 70c8a5b523..3c592e7e37 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -2665,6 +2665,9 @@ void InstructionCodeGeneratorMIPS::VisitArrayGet(HArrayGet* instruction) {
__ ShiftAndAdd(TMP, index_reg, obj, TIMES_2, TMP);
__ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset);
__ Bind(&done);
+ } else if (instruction->InputAt(1)->IsIntermediateArrayAddressIndex()) {
+ __ Addu(TMP, index_reg, obj);
+ __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset, null_checker);
} else {
__ ShiftAndAdd(TMP, index_reg, obj, TIMES_2, TMP);
__ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset, null_checker);
@@ -2679,6 +2682,9 @@ void InstructionCodeGeneratorMIPS::VisitArrayGet(HArrayGet* instruction) {
size_t offset =
(index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset;
__ LoadFromOffset(kLoadSignedHalfword, out, obj, offset, null_checker);
+ } else if (instruction->InputAt(1)->IsIntermediateArrayAddressIndex()) {
+ __ Addu(TMP, index.AsRegister<Register>(), obj);
+ __ LoadFromOffset(kLoadSignedHalfword, out, TMP, data_offset, null_checker);
} else {
__ ShiftAndAdd(TMP, index.AsRegister<Register>(), obj, TIMES_2, TMP);
__ LoadFromOffset(kLoadSignedHalfword, out, TMP, data_offset, null_checker);
@@ -2693,6 +2699,9 @@ void InstructionCodeGeneratorMIPS::VisitArrayGet(HArrayGet* instruction) {
size_t offset =
(index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset;
__ LoadFromOffset(kLoadWord, out, obj, offset, null_checker);
+ } else if (instruction->InputAt(1)->IsIntermediateArrayAddressIndex()) {
+ __ Addu(TMP, index.AsRegister<Register>(), obj);
+ __ LoadFromOffset(kLoadWord, out, TMP, data_offset, null_checker);
} else {
__ ShiftAndAdd(TMP, index.AsRegister<Register>(), obj, TIMES_4, TMP);
__ LoadFromOffset(kLoadWord, out, TMP, data_offset, null_checker);
@@ -2766,6 +2775,9 @@ void InstructionCodeGeneratorMIPS::VisitArrayGet(HArrayGet* instruction) {
size_t offset =
(index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset;
__ LoadFromOffset(kLoadDoubleword, out, obj, offset, null_checker);
+ } else if (instruction->InputAt(1)->IsIntermediateArrayAddressIndex()) {
+ __ Addu(TMP, index.AsRegister<Register>(), obj);
+ __ LoadFromOffset(kLoadDoubleword, out, TMP, data_offset, null_checker);
} else {
__ ShiftAndAdd(TMP, index.AsRegister<Register>(), obj, TIMES_8, TMP);
__ LoadFromOffset(kLoadDoubleword, out, TMP, data_offset, null_checker);
@@ -2779,6 +2791,9 @@ void InstructionCodeGeneratorMIPS::VisitArrayGet(HArrayGet* instruction) {
size_t offset =
(index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset;
__ LoadSFromOffset(out, obj, offset, null_checker);
+ } else if (instruction->InputAt(1)->IsIntermediateArrayAddressIndex()) {
+ __ Addu(TMP, index.AsRegister<Register>(), obj);
+ __ LoadSFromOffset(out, TMP, data_offset, null_checker);
} else {
__ ShiftAndAdd(TMP, index.AsRegister<Register>(), obj, TIMES_4, TMP);
__ LoadSFromOffset(out, TMP, data_offset, null_checker);
@@ -2792,6 +2807,9 @@ void InstructionCodeGeneratorMIPS::VisitArrayGet(HArrayGet* instruction) {
size_t offset =
(index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset;
__ LoadDFromOffset(out, obj, offset, null_checker);
+ } else if (instruction->InputAt(1)->IsIntermediateArrayAddressIndex()) {
+ __ Addu(TMP, index.AsRegister<Register>(), obj);
+ __ LoadDFromOffset(out, TMP, data_offset, null_checker);
} else {
__ ShiftAndAdd(TMP, index.AsRegister<Register>(), obj, TIMES_8, TMP);
__ LoadDFromOffset(out, TMP, data_offset, null_checker);
@@ -2906,6 +2924,8 @@ void InstructionCodeGeneratorMIPS::VisitArraySet(HArraySet* instruction) {
uint32_t data_offset = mirror::Array::DataOffset(sizeof(uint16_t)).Uint32Value();
if (index.IsConstant()) {
data_offset += index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2;
+ } else if (instruction->InputAt(1)->IsIntermediateArrayAddressIndex()) {
+ __ Addu(base_reg, index.AsRegister<Register>(), obj);
} else {
__ ShiftAndAdd(base_reg, index.AsRegister<Register>(), obj, TIMES_2, base_reg);
}
@@ -2923,6 +2943,8 @@ void InstructionCodeGeneratorMIPS::VisitArraySet(HArraySet* instruction) {
uint32_t data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Uint32Value();
if (index.IsConstant()) {
data_offset += index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4;
+ } else if (instruction->InputAt(1)->IsIntermediateArrayAddressIndex()) {
+ __ Addu(base_reg, index.AsRegister<Register>(), obj);
} else {
__ ShiftAndAdd(base_reg, index.AsRegister<Register>(), obj, TIMES_4, base_reg);
}
@@ -2972,6 +2994,8 @@ void InstructionCodeGeneratorMIPS::VisitArraySet(HArraySet* instruction) {
uint32_t data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Uint32Value();
if (index.IsConstant()) {
data_offset += index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4;
+ } else if (instruction->InputAt(1)->IsIntermediateArrayAddressIndex()) {
+ __ Addu(base_reg, index.AsRegister<Register>(), obj);
} else {
__ ShiftAndAdd(base_reg, index.AsRegister<Register>(), obj, TIMES_4, base_reg);
}
@@ -3055,6 +3079,8 @@ void InstructionCodeGeneratorMIPS::VisitArraySet(HArraySet* instruction) {
uint32_t data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Uint32Value();
if (index.IsConstant()) {
data_offset += index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8;
+ } else if (instruction->InputAt(1)->IsIntermediateArrayAddressIndex()) {
+ __ Addu(base_reg, index.AsRegister<Register>(), obj);
} else {
__ ShiftAndAdd(base_reg, index.AsRegister<Register>(), obj, TIMES_8, base_reg);
}
@@ -3072,6 +3098,8 @@ void InstructionCodeGeneratorMIPS::VisitArraySet(HArraySet* instruction) {
uint32_t data_offset = mirror::Array::DataOffset(sizeof(float)).Uint32Value();
if (index.IsConstant()) {
data_offset += index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4;
+ } else if (instruction->InputAt(1)->IsIntermediateArrayAddressIndex()) {
+ __ Addu(base_reg, index.AsRegister<Register>(), obj);
} else {
__ ShiftAndAdd(base_reg, index.AsRegister<Register>(), obj, TIMES_4, base_reg);
}
@@ -3089,6 +3117,8 @@ void InstructionCodeGeneratorMIPS::VisitArraySet(HArraySet* instruction) {
uint32_t data_offset = mirror::Array::DataOffset(sizeof(double)).Uint32Value();
if (index.IsConstant()) {
data_offset += index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8;
+ } else if (instruction->InputAt(1)->IsIntermediateArrayAddressIndex()) {
+ __ Addu(base_reg, index.AsRegister<Register>(), obj);
} else {
__ ShiftAndAdd(base_reg, index.AsRegister<Register>(), obj, TIMES_8, base_reg);
}
@@ -3108,6 +3138,26 @@ void InstructionCodeGeneratorMIPS::VisitArraySet(HArraySet* instruction) {
}
}
+void LocationsBuilderMIPS::VisitIntermediateArrayAddressIndex(
+ HIntermediateArrayAddressIndex* instruction) {
+ LocationSummary* locations =
+ new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
+
+ HIntConstant* shift = instruction->GetShift()->AsIntConstant();
+
+ locations->SetInAt(0, Location::RequiresRegister());
+ locations->SetInAt(1, Location::ConstantLocation(shift));
+ locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+}
+
+void InstructionCodeGeneratorMIPS::VisitIntermediateArrayAddressIndex(
+ HIntermediateArrayAddressIndex* instruction) {
+ LocationSummary* locations = instruction->GetLocations();
+ Register index_reg = locations->InAt(0).AsRegister<Register>();
+ uint32_t shift = instruction->GetShift()->AsIntConstant()->GetValue();
+ __ Sll(locations->Out().AsRegister<Register>(), index_reg, shift);
+}
+
void LocationsBuilderMIPS::VisitBoundsCheck(HBoundsCheck* instruction) {
RegisterSet caller_saves = RegisterSet::Empty();
InvokeRuntimeCallingConvention calling_convention;