diff options
author | 2017-04-12 17:09:20 -0700 | |
---|---|---|
committer | 2017-04-19 10:30:57 -0700 | |
commit | f3e61ee363fe7f82ef56704f06d753e2034a67dd (patch) | |
tree | a00f1fce4a2e284b0a03f941f530afc5b5c56b59 /compiler/optimizing/nodes_vector.h | |
parent | 741a81af441cbcb7255229bf250bc009d2894e92 (diff) |
Implement halving add idiom (with checker tests).
Rationale:
First of several idioms that map to very efficient SIMD instructions.
Note that the is-zero-ext and is-sign-ext are general-purpose utilities
that will be widely used in the vectorizer to detect low precision
idioms, so expect that code to be shared with many CLs to come.
Test: test-art-host, test-art-target
Change-Id: If7dc2926c72a2e4b5cea15c44ef68cf5503e9be9
Diffstat (limited to 'compiler/optimizing/nodes_vector.h')
-rw-r--r-- | compiler/optimizing/nodes_vector.h | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/compiler/optimizing/nodes_vector.h b/compiler/optimizing/nodes_vector.h index 0cbbf2a215..bff58d0910 100644 --- a/compiler/optimizing/nodes_vector.h +++ b/compiler/optimizing/nodes_vector.h @@ -338,6 +338,42 @@ class HVecAdd FINAL : public HVecBinaryOperation { DISALLOW_COPY_AND_ASSIGN(HVecAdd); }; +// Performs halving add on every component in the two vectors, viz. +// rounded [ x1, .. , xn ] hradd [ y1, .. , yn ] = [ (x1 + y1 + 1) >> 1, .. , (xn + yn + 1) >> 1 ] +// or [ x1, .. , xn ] hadd [ y1, .. , yn ] = [ (x1 + y1) >> 1, .. , (xn + yn ) >> 1 ] +// for signed operands x, y (sign extension) or unsigned operands x, y (zero extension). +class HVecHalvingAdd FINAL : public HVecBinaryOperation { + public: + HVecHalvingAdd(ArenaAllocator* arena, + HInstruction* left, + HInstruction* right, + Primitive::Type packed_type, + size_t vector_length, + bool is_unsigned, + bool is_rounded, + uint32_t dex_pc = kNoDexPc) + : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc), + is_unsigned_(is_unsigned), + is_rounded_(is_rounded) { + DCHECK(left->IsVecOperation() && right->IsVecOperation()); + DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type); + DCHECK_EQ(right->AsVecOperation()->GetPackedType(), packed_type); + SetRawInputAt(0, left); + SetRawInputAt(1, right); + } + + bool IsUnsigned() const { return is_unsigned_; } + bool IsRounded() const { return is_rounded_; } + + DECLARE_INSTRUCTION(VecHalvingAdd); + + private: + bool is_unsigned_; + bool is_rounded_; + + DISALLOW_COPY_AND_ASSIGN(HVecHalvingAdd); +}; + // Subtracts every component in the two vectors, // viz. [ x1, .. , xn ] - [ y1, .. , yn ] = [ x1 - y1, .. , xn - yn ]. class HVecSub FINAL : public HVecBinaryOperation { @@ -404,6 +440,50 @@ class HVecDiv FINAL : public HVecBinaryOperation { DISALLOW_COPY_AND_ASSIGN(HVecDiv); }; +// Takes minimum of every component in the two vectors, +// viz. MIN( [ x1, .. , xn ] , [ y1, .. , yn ]) = [ min(x1, y1), .. , min(xn, yn) ]. +class HVecMin FINAL : public HVecBinaryOperation { + public: + HVecMin(ArenaAllocator* arena, + HInstruction* left, + HInstruction* right, + Primitive::Type packed_type, + size_t vector_length, + uint32_t dex_pc = kNoDexPc) + : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) { + DCHECK(left->IsVecOperation() && right->IsVecOperation()); + DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type); + DCHECK_EQ(right->AsVecOperation()->GetPackedType(), packed_type); + SetRawInputAt(0, left); + SetRawInputAt(1, right); + } + DECLARE_INSTRUCTION(VecMin); + private: + DISALLOW_COPY_AND_ASSIGN(HVecMin); +}; + +// Takes maximum of every component in the two vectors, +// viz. MAX( [ x1, .. , xn ] , [ y1, .. , yn ]) = [ max(x1, y1), .. , max(xn, yn) ]. +class HVecMax FINAL : public HVecBinaryOperation { + public: + HVecMax(ArenaAllocator* arena, + HInstruction* left, + HInstruction* right, + Primitive::Type packed_type, + size_t vector_length, + uint32_t dex_pc = kNoDexPc) + : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) { + DCHECK(left->IsVecOperation() && right->IsVecOperation()); + DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type); + DCHECK_EQ(right->AsVecOperation()->GetPackedType(), packed_type); + SetRawInputAt(0, left); + SetRawInputAt(1, right); + } + DECLARE_INSTRUCTION(VecMax); + private: + DISALLOW_COPY_AND_ASSIGN(HVecMax); +}; + // Bitwise-ands every component in the two vectors, // viz. [ x1, .. , xn ] & [ y1, .. , yn ] = [ x1 & y1, .. , xn & yn ]. class HVecAnd FINAL : public HVecBinaryOperation { |