summaryrefslogtreecommitdiff
path: root/compiler/optimizing/nodes.h
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r--compiler/optimizing/nodes.h191
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();
}