diff options
author | 2017-10-03 11:37:37 -0700 | |
---|---|---|
committer | 2017-10-05 10:42:13 -0700 | |
commit | 46b6dbcd18df0cb5915ca906fefd9f0b0a1af6a2 (patch) | |
tree | 723856081b9d0abcc017b323672e4b1cc99cad16 /compiler/optimizing/nodes_vector.h | |
parent | 844a4edc7f72e33a3b328c3d53ef710909d2273d (diff) |
Try to preserve dex pc better in vector code.
Also improves a few comment and uses new data
type method to test type consistency.
Test: test-art-host
Change-Id: I4a17f9d5bc458a091a259dd45ebcdc6531abbf84
Diffstat (limited to 'compiler/optimizing/nodes_vector.h')
-rw-r--r-- | compiler/optimizing/nodes_vector.h | 116 |
1 files changed, 64 insertions, 52 deletions
diff --git a/compiler/optimizing/nodes_vector.h b/compiler/optimizing/nodes_vector.h index d01f8c0289..8f3ab11d00 100644 --- a/compiler/optimizing/nodes_vector.h +++ b/compiler/optimizing/nodes_vector.h @@ -34,7 +34,7 @@ class Alignment { DCHECK(IsPowerOfTwo(base)); } - // Returns true if memory is "at least" aligned at the given boundary. + // Returns true if memory is at least aligned at the given boundary. // Assumes requested base is power of two. bool IsAlignedAt(size_t base) const { DCHECK_NE(0u, base); @@ -42,6 +42,10 @@ class Alignment { return ((offset_ | base_) & (base - 1u)) == 0; } + size_t Base() const { return base_; } + + size_t Offset() const { return offset_; } + std::string ToString() const { return "ALIGN(" + std::to_string(base_) + "," + std::to_string(offset_) + ")"; } @@ -116,6 +120,22 @@ class HVecOperation : public HVariableInputSizeInstruction { return GetVectorLength() == o->GetVectorLength() && GetPackedType() == o->GetPackedType(); } + // Maps an integral type to the same-size signed type and leaves other types alone. + // Can be used to test relaxed type consistency in which packed same-size integral + // types can co-exist, but other type mixes are an error. + static DataType::Type ToSignedType(DataType::Type type) { + switch (type) { + case DataType::Type::kBool: // 1-byte storage unit + case DataType::Type::kUint8: + return DataType::Type::kInt8; + case DataType::Type::kUint16: + return DataType::Type::kInt16; + default: + DCHECK(type != DataType::Type::kVoid && type != DataType::Type::kReference) << type; + return type; + } + } + DECLARE_ABSTRACT_INSTRUCTION(VecOperation); protected: @@ -187,8 +207,7 @@ class HVecBinaryOperation : public HVecOperation { }; // Abstraction of a vector operation that references memory, with an alignment. -// The Android runtime guarantees at least "component size" alignment for array -// elements and, thus, vectors. +// The Android runtime guarantees elements have at least natural alignment. class HVecMemoryOperation : public HVecOperation { public: HVecMemoryOperation(ArenaAllocator* arena, @@ -230,20 +249,7 @@ inline static bool HasConsistentPackedTypes(HInstruction* input, DataType::Type } DCHECK(input->IsVecOperation()); DataType::Type input_type = input->AsVecOperation()->GetPackedType(); - switch (input_type) { - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - return type == DataType::Type::kBool || - type == DataType::Type::kUint8 || - type == DataType::Type::kInt8; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - return type == DataType::Type::kUint16 || - type == DataType::Type::kInt16; - default: - return type == input_type; - } + return HVecOperation::ToSignedType(input_type) == HVecOperation::ToSignedType(type); } // @@ -258,7 +264,7 @@ class HVecReplicateScalar FINAL : public HVecUnaryOperation { HInstruction* scalar, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecUnaryOperation(arena, scalar, packed_type, vector_length, dex_pc) { DCHECK(!scalar->IsVecOperation()); } @@ -284,7 +290,7 @@ class HVecExtractScalar FINAL : public HVecUnaryOperation { DataType::Type packed_type, size_t vector_length, size_t index, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecUnaryOperation(arena, input, packed_type, vector_length, dex_pc) { DCHECK(HasConsistentPackedTypes(input, packed_type)); DCHECK_LT(index, vector_length); @@ -322,7 +328,7 @@ class HVecReduce FINAL : public HVecUnaryOperation { DataType::Type packed_type, size_t vector_length, ReductionKind kind, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecUnaryOperation(arena, input, packed_type, vector_length, dex_pc), kind_(kind) { DCHECK(HasConsistentPackedTypes(input, packed_type)); @@ -354,7 +360,7 @@ class HVecCnv FINAL : public HVecUnaryOperation { HInstruction* input, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecUnaryOperation(arena, input, packed_type, vector_length, dex_pc) { DCHECK(input->IsVecOperation()); DCHECK_NE(GetInputType(), GetResultType()); // actual convert @@ -379,7 +385,7 @@ class HVecNeg FINAL : public HVecUnaryOperation { HInstruction* input, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecUnaryOperation(arena, input, packed_type, vector_length, dex_pc) { DCHECK(HasConsistentPackedTypes(input, packed_type)); } @@ -393,14 +399,15 @@ class HVecNeg FINAL : public HVecUnaryOperation { }; // Takes absolute value of every component in the vector, -// viz. abs[ x1, .. , xn ] = [ |x1|, .. , |xn| ]. +// viz. abs[ x1, .. , xn ] = [ |x1|, .. , |xn| ] +// for signed operand x. class HVecAbs FINAL : public HVecUnaryOperation { public: HVecAbs(ArenaAllocator* arena, HInstruction* input, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecUnaryOperation(arena, input, packed_type, vector_length, dex_pc) { DCHECK(HasConsistentPackedTypes(input, packed_type)); } @@ -422,7 +429,7 @@ class HVecNot FINAL : public HVecUnaryOperation { HInstruction* input, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecUnaryOperation(arena, input, packed_type, vector_length, dex_pc) { DCHECK(input->IsVecOperation()); } @@ -448,7 +455,7 @@ class HVecAdd FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { DCHECK(HasConsistentPackedTypes(left, packed_type)); DCHECK(HasConsistentPackedTypes(right, packed_type)); @@ -465,7 +472,7 @@ class HVecAdd FINAL : public HVecBinaryOperation { // 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 ] // truncated [ 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). +// for either both signed or both unsigned operands x, y. class HVecHalvingAdd FINAL : public HVecBinaryOperation { public: HVecHalvingAdd(ArenaAllocator* arena, @@ -474,8 +481,9 @@ class HVecHalvingAdd FINAL : public HVecBinaryOperation { DataType::Type packed_type, size_t vector_length, bool is_rounded, - bool is_unsigned = false) - : HVecBinaryOperation(arena, left, right, packed_type, vector_length, kNoDexPc) { + bool is_unsigned, + uint32_t dex_pc) + : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { // The `is_unsigned` flag should be used exclusively with the Int32 or Int64. // This flag is a temporary measure while we do not have the Uint32 and Uint64 data types. DCHECK(!is_unsigned || @@ -521,7 +529,7 @@ class HVecSub FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { DCHECK(HasConsistentPackedTypes(left, packed_type)); DCHECK(HasConsistentPackedTypes(right, packed_type)); @@ -544,7 +552,7 @@ class HVecMul FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { DCHECK(HasConsistentPackedTypes(left, packed_type)); DCHECK(HasConsistentPackedTypes(right, packed_type)); @@ -567,7 +575,7 @@ class HVecDiv FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { DCHECK(HasConsistentPackedTypes(left, packed_type)); DCHECK(HasConsistentPackedTypes(right, packed_type)); @@ -582,7 +590,8 @@ class HVecDiv FINAL : public HVecBinaryOperation { }; // Takes minimum of every component in the two vectors, -// viz. MIN( [ x1, .. , xn ] , [ y1, .. , yn ]) = [ min(x1, y1), .. , min(xn, yn) ]. +// viz. MIN( [ x1, .. , xn ] , [ y1, .. , yn ]) = [ min(x1, y1), .. , min(xn, yn) ] +// for either both signed or both unsigned operands x, y. class HVecMin FINAL : public HVecBinaryOperation { public: HVecMin(ArenaAllocator* arena, @@ -590,8 +599,9 @@ class HVecMin FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - bool is_unsigned = false) - : HVecBinaryOperation(arena, left, right, packed_type, vector_length, kNoDexPc) { + bool is_unsigned, + uint32_t dex_pc) + : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { // The `is_unsigned` flag should be used exclusively with the Int32 or Int64. // This flag is a temporary measure while we do not have the Uint32 and Uint64 data types. DCHECK(!is_unsigned || @@ -624,7 +634,8 @@ class HVecMin FINAL : public HVecBinaryOperation { }; // Takes maximum of every component in the two vectors, -// viz. MAX( [ x1, .. , xn ] , [ y1, .. , yn ]) = [ max(x1, y1), .. , max(xn, yn) ]. +// viz. MAX( [ x1, .. , xn ] , [ y1, .. , yn ]) = [ max(x1, y1), .. , max(xn, yn) ] +// for either both signed or both unsigned operands x, y. class HVecMax FINAL : public HVecBinaryOperation { public: HVecMax(ArenaAllocator* arena, @@ -632,8 +643,9 @@ class HVecMax FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - bool is_unsigned = false) - : HVecBinaryOperation(arena, left, right, packed_type, vector_length, kNoDexPc) { + bool is_unsigned, + uint32_t dex_pc) + : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { // The `is_unsigned` flag should be used exclusively with the Int32 or Int64. // This flag is a temporary measure while we do not have the Uint32 and Uint64 data types. DCHECK(!is_unsigned || @@ -674,7 +686,7 @@ class HVecAnd FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { DCHECK(left->IsVecOperation() && right->IsVecOperation()); } @@ -696,7 +708,7 @@ class HVecAndNot FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { DCHECK(left->IsVecOperation() && right->IsVecOperation()); } @@ -718,7 +730,7 @@ class HVecOr FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { DCHECK(left->IsVecOperation() && right->IsVecOperation()); } @@ -740,7 +752,7 @@ class HVecXor FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { DCHECK(left->IsVecOperation() && right->IsVecOperation()); } @@ -762,7 +774,7 @@ class HVecShl FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { DCHECK(HasConsistentPackedTypes(left, packed_type)); } @@ -784,7 +796,7 @@ class HVecShr FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { DCHECK(HasConsistentPackedTypes(left, packed_type)); } @@ -806,7 +818,7 @@ class HVecUShr FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { DCHECK(HasConsistentPackedTypes(left, packed_type)); } @@ -833,7 +845,7 @@ class HVecSetScalars FINAL : public HVecOperation { DataType::Type packed_type, size_t vector_length, size_t number_of_scalars, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecOperation(arena, packed_type, SideEffects::None(), @@ -867,7 +879,7 @@ class HVecMultiplyAccumulate FINAL : public HVecOperation { HInstruction* mul_right, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecOperation(arena, packed_type, SideEffects::None(), @@ -905,9 +917,9 @@ class HVecMultiplyAccumulate FINAL : public HVecOperation { // Takes the absolute difference of two vectors, and adds the results to // same-precision or wider-precision components in the accumulator, -// viz. SAD([ a1, .. , am ], [ x1, .. , xn ], [ y1, .. , yn ] = +// viz. SAD([ a1, .. , am ], [ x1, .. , xn ], [ y1, .. , yn ]) = // [ a1 + sum abs(xi-yi), .. , am + sum abs(xj-yj) ], -// for m <= n and non-overlapping sums. +// for m <= n, non-overlapping sums, and signed operands x, y. class HVecSADAccumulate FINAL : public HVecOperation { public: HVecSADAccumulate(ArenaAllocator* arena, @@ -916,7 +928,7 @@ class HVecSADAccumulate FINAL : public HVecOperation { HInstruction* sad_right, DataType::Type packed_type, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecOperation(arena, packed_type, SideEffects::None(), @@ -950,7 +962,7 @@ class HVecLoad FINAL : public HVecMemoryOperation { SideEffects side_effects, size_t vector_length, bool is_string_char_at, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecMemoryOperation(arena, packed_type, side_effects, @@ -994,7 +1006,7 @@ class HVecStore FINAL : public HVecMemoryOperation { DataType::Type packed_type, SideEffects side_effects, size_t vector_length, - uint32_t dex_pc = kNoDexPc) + uint32_t dex_pc) : HVecMemoryOperation(arena, packed_type, side_effects, |