diff options
Diffstat (limited to 'compiler/optimizing/nodes.h')
| -rw-r--r-- | compiler/optimizing/nodes.h | 191 |
1 files changed, 104 insertions, 87 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 88d39d16e5..e9a42cb0ce 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -72,8 +72,10 @@ static const int kDefaultNumberOfExceptionalPredecessors = 0; static const int kDefaultNumberOfDominatedBlocks = 1; static const int kDefaultNumberOfBackEdges = 1; -static constexpr uint32_t kMaxIntShiftValue = 0x1f; -static constexpr uint64_t kMaxLongShiftValue = 0x3f; +// The maximum (meaningful) distance (31) that can be used in an integer shift/rotate operation. +static constexpr int32_t kMaxIntShiftDistance = 0x1f; +// The maximum (meaningful) distance (63) that can be used in a long shift/rotate operation. +static constexpr int32_t kMaxLongShiftDistance = 0x3f; static constexpr uint32_t kUnknownFieldIndex = static_cast<uint32_t>(-1); static constexpr uint16_t kUnknownClassDefIndex = static_cast<uint16_t>(-1); @@ -645,7 +647,7 @@ class HLoopInformation : public ArenaObject<kArenaAllocLoopInfo> { irreducible_(false), back_edges_(graph->GetArena()->Adapter(kArenaAllocLoopInfoBackEdges)), // Make bit vector growable, as the number of blocks may change. - blocks_(graph->GetArena(), graph->GetBlocks().size(), true) { + blocks_(graph->GetArena(), graph->GetBlocks().size(), true, kArenaAllocLoopInfoBackEdges) { back_edges_.reserve(kDefaultNumberOfBackEdges); } @@ -3461,7 +3463,10 @@ class HAboveOrEqual : public HCondition { // Result is 0 if input0 == input1, 1 if input0 > input1, or -1 if input0 < input1. class HCompare : public HBinaryOperation { public: - HCompare(Primitive::Type type, + // Note that `comparison_type` is the type of comparison performed + // between the comparison's inputs, not the type of the instantiated + // HCompare instruction (which is always Primitive::kPrimInt). + HCompare(Primitive::Type comparison_type, HInstruction* first, HInstruction* second, ComparisonBias bias, @@ -3469,11 +3474,11 @@ class HCompare : public HBinaryOperation { : HBinaryOperation(Primitive::kPrimInt, first, second, - SideEffectsForArchRuntimeCalls(type), + SideEffectsForArchRuntimeCalls(comparison_type), dex_pc) { SetPackedField<ComparisonBiasField>(bias); - DCHECK_EQ(type, first->GetType()); - DCHECK_EQ(type, second->GetType()); + DCHECK_EQ(comparison_type, Primitive::PrimitiveKind(first->GetType())); + DCHECK_EQ(comparison_type, Primitive::PrimitiveKind(second->GetType())); } template <typename T> @@ -4176,7 +4181,9 @@ class HInvokeInterface : public HInvoke { class HNeg : public HUnaryOperation { public: HNeg(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc) - : HUnaryOperation(result_type, input, dex_pc) {} + : HUnaryOperation(result_type, input, dex_pc) { + DCHECK_EQ(result_type, Primitive::PrimitiveKind(input->GetType())); + } template <typename T> T Compute(T x) const { return -x; } @@ -4473,37 +4480,39 @@ class HDivZeroCheck : public HExpression<1> { class HShl : public HBinaryOperation { public: HShl(Primitive::Type result_type, - HInstruction* left, - HInstruction* right, + HInstruction* value, + HInstruction* distance, uint32_t dex_pc = kNoDexPc) - : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} + : HBinaryOperation(result_type, value, distance, SideEffects::None(), dex_pc) { + DCHECK_EQ(result_type, Primitive::PrimitiveKind(value->GetType())); + DCHECK_EQ(Primitive::kPrimInt, Primitive::PrimitiveKind(distance->GetType())); + } - template <typename T, typename U, typename V> - T Compute(T x, U y, V max_shift_value) const { - static_assert(std::is_same<V, typename std::make_unsigned<T>::type>::value, - "V is not the unsigned integer type corresponding to T"); - return x << (y & max_shift_value); + template <typename T> + T Compute(T value, int32_t distance, int32_t max_shift_distance) const { + return value << (distance & max_shift_distance); } - HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { + HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const OVERRIDE { return GetBlock()->GetGraph()->GetIntConstant( - Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue), GetDexPc()); + Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc()); } - HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE { + HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const OVERRIDE { return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); + Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc()); } - HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); + HConstant* Evaluate(HLongConstant* value ATTRIBUTE_UNUSED, + HLongConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { + LOG(FATAL) << DebugName() << " is not defined for the (long, long) case."; + UNREACHABLE(); } - HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED, - HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { + HConstant* Evaluate(HFloatConstant* value ATTRIBUTE_UNUSED, + HFloatConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { LOG(FATAL) << DebugName() << " is not defined for float values"; UNREACHABLE(); } - HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED, - HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { + HConstant* Evaluate(HDoubleConstant* value ATTRIBUTE_UNUSED, + HDoubleConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { LOG(FATAL) << DebugName() << " is not defined for double values"; UNREACHABLE(); } @@ -4517,37 +4526,39 @@ class HShl : public HBinaryOperation { class HShr : public HBinaryOperation { public: HShr(Primitive::Type result_type, - HInstruction* left, - HInstruction* right, + HInstruction* value, + HInstruction* distance, uint32_t dex_pc = kNoDexPc) - : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} + : HBinaryOperation(result_type, value, distance, SideEffects::None(), dex_pc) { + DCHECK_EQ(result_type, Primitive::PrimitiveKind(value->GetType())); + DCHECK_EQ(Primitive::kPrimInt, Primitive::PrimitiveKind(distance->GetType())); + } - template <typename T, typename U, typename V> - T Compute(T x, U y, V max_shift_value) const { - static_assert(std::is_same<V, typename std::make_unsigned<T>::type>::value, - "V is not the unsigned integer type corresponding to T"); - return x >> (y & max_shift_value); + template <typename T> + T Compute(T value, int32_t distance, int32_t max_shift_distance) const { + return value >> (distance & max_shift_distance); } - HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { + HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const OVERRIDE { return GetBlock()->GetGraph()->GetIntConstant( - Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue), GetDexPc()); + Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc()); } - HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE { + HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const OVERRIDE { return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); + Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc()); } - HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); + HConstant* Evaluate(HLongConstant* value ATTRIBUTE_UNUSED, + HLongConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { + LOG(FATAL) << DebugName() << " is not defined for the (long, long) case."; + UNREACHABLE(); } - HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED, - HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { + HConstant* Evaluate(HFloatConstant* value ATTRIBUTE_UNUSED, + HFloatConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { LOG(FATAL) << DebugName() << " is not defined for float values"; UNREACHABLE(); } - HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED, - HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { + HConstant* Evaluate(HDoubleConstant* value ATTRIBUTE_UNUSED, + HDoubleConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { LOG(FATAL) << DebugName() << " is not defined for double values"; UNREACHABLE(); } @@ -4561,38 +4572,41 @@ class HShr : public HBinaryOperation { class HUShr : public HBinaryOperation { public: HUShr(Primitive::Type result_type, - HInstruction* left, - HInstruction* right, + HInstruction* value, + HInstruction* distance, uint32_t dex_pc = kNoDexPc) - : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} + : HBinaryOperation(result_type, value, distance, SideEffects::None(), dex_pc) { + DCHECK_EQ(result_type, Primitive::PrimitiveKind(value->GetType())); + DCHECK_EQ(Primitive::kPrimInt, Primitive::PrimitiveKind(distance->GetType())); + } - template <typename T, typename U, typename V> - T Compute(T x, U y, V max_shift_value) const { - static_assert(std::is_same<V, typename std::make_unsigned<T>::type>::value, - "V is not the unsigned integer type corresponding to T"); - V ux = static_cast<V>(x); - return static_cast<T>(ux >> (y & max_shift_value)); + template <typename T> + T Compute(T value, int32_t distance, int32_t max_shift_distance) const { + typedef typename std::make_unsigned<T>::type V; + V ux = static_cast<V>(value); + return static_cast<T>(ux >> (distance & max_shift_distance)); } - HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { + HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const OVERRIDE { return GetBlock()->GetGraph()->GetIntConstant( - Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue), GetDexPc()); + Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc()); } - HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE { + HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const OVERRIDE { return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); + Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc()); } - HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); + HConstant* Evaluate(HLongConstant* value ATTRIBUTE_UNUSED, + HLongConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { + LOG(FATAL) << DebugName() << " is not defined for the (long, long) case."; + UNREACHABLE(); } - HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED, - HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { + HConstant* Evaluate(HFloatConstant* value ATTRIBUTE_UNUSED, + HFloatConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { LOG(FATAL) << DebugName() << " is not defined for float values"; UNREACHABLE(); } - HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED, - HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { + HConstant* Evaluate(HDoubleConstant* value ATTRIBUTE_UNUSED, + HDoubleConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { LOG(FATAL) << DebugName() << " is not defined for double values"; UNREACHABLE(); } @@ -4717,41 +4731,44 @@ class HXor : public HBinaryOperation { class HRor : public HBinaryOperation { public: HRor(Primitive::Type result_type, HInstruction* value, HInstruction* distance) - : HBinaryOperation(result_type, value, distance) {} - - template <typename T, typename U, typename V> - T Compute(T x, U y, V max_shift_value) const { - static_assert(std::is_same<V, typename std::make_unsigned<T>::type>::value, - "V is not the unsigned integer type corresponding to T"); - V ux = static_cast<V>(x); - if ((y & max_shift_value) == 0) { + : HBinaryOperation(result_type, value, distance) { + DCHECK_EQ(result_type, Primitive::PrimitiveKind(value->GetType())); + DCHECK_EQ(Primitive::kPrimInt, Primitive::PrimitiveKind(distance->GetType())); + } + + template <typename T> + T Compute(T value, int32_t distance, int32_t max_shift_value) const { + typedef typename std::make_unsigned<T>::type V; + V ux = static_cast<V>(value); + if ((distance & max_shift_value) == 0) { return static_cast<T>(ux); } else { const V reg_bits = sizeof(T) * 8; - return static_cast<T>(ux >> (y & max_shift_value)) | - (x << (reg_bits - (y & max_shift_value))); + return static_cast<T>(ux >> (distance & max_shift_value)) | + (value << (reg_bits - (distance & max_shift_value))); } } - HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { + HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const OVERRIDE { return GetBlock()->GetGraph()->GetIntConstant( - Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue), GetDexPc()); + Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc()); } - HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE { + HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const OVERRIDE { return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); + Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc()); } - HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { - return GetBlock()->GetGraph()->GetLongConstant( - Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); + HConstant* Evaluate(HLongConstant* value ATTRIBUTE_UNUSED, + HLongConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { + LOG(FATAL) << DebugName() << " is not defined for the (long, long) case."; + UNREACHABLE(); } - HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED, - HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { + HConstant* Evaluate(HFloatConstant* value ATTRIBUTE_UNUSED, + HFloatConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { LOG(FATAL) << DebugName() << " is not defined for float values"; UNREACHABLE(); } - HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED, - HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { + HConstant* Evaluate(HDoubleConstant* value ATTRIBUTE_UNUSED, + HDoubleConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { LOG(FATAL) << DebugName() << " is not defined for double values"; UNREACHABLE(); } |