From a290160f74ee53c0ffb51c7b3ac916d239c9556a Mon Sep 17 00:00:00 2001 From: Lena Djokic Date: Thu, 21 Sep 2017 13:50:52 +0200 Subject: 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 --- compiler/optimizing/nodes_mips.h | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'compiler/optimizing/nodes_mips.h') diff --git a/compiler/optimizing/nodes_mips.h b/compiler/optimizing/nodes_mips.h index 80e652eaa7..ef388c30d5 100644 --- a/compiler/optimizing/nodes_mips.h +++ b/compiler/optimizing/nodes_mips.h @@ -69,6 +69,46 @@ class HMipsPackedSwitch FINAL : public HTemplateInstruction<2> { DISALLOW_COPY_AND_ASSIGN(HMipsPackedSwitch); }; +// This instruction computes part of the array access offset (index offset). +// +// 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]; +// } +// } +// +// Note: as the instruction doesn't involve base array address into computations it has no side +// effects. +class HIntermediateArrayAddressIndex FINAL : public HExpression<2> { + public: + HIntermediateArrayAddressIndex(HInstruction* index, HInstruction* shift, uint32_t dex_pc) + : HExpression(DataType::Type::kInt32, SideEffects::None(), dex_pc) { + SetRawInputAt(0, index); + SetRawInputAt(1, shift); + } + + bool CanBeMoved() const OVERRIDE { return true; } + bool InstructionDataEquals(const HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { + return true; + } + bool IsActualObject() const OVERRIDE { return false; } + + HInstruction* GetIndex() const { return InputAt(0); } + HInstruction* GetShift() const { return InputAt(1); } + + DECLARE_INSTRUCTION(IntermediateArrayAddressIndex); + + private: + DISALLOW_COPY_AND_ASSIGN(HIntermediateArrayAddressIndex); +}; + } // namespace art #endif // ART_COMPILER_OPTIMIZING_NODES_MIPS_H_ -- cgit v1.2.3-59-g8ed1b