summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Roland Levillain <rpl@google.com> 2016-03-18 14:04:28 +0000
committer Roland Levillain <rpl@google.com> 2016-03-18 14:04:28 +0000
commit22c4922c6b31e154a6814c4abe9015d9ba156911 (patch)
tree8e871f67e327322d24d0c2e4588b165005414077 /compiler/optimizing
parent0205b58a0d7a9ce5832393857c19c086c78996e9 (diff)
Ensure art::HRor support boolean, byte, short and char inputs.
Also extend tests covering the IntegerRotateLeft, LongRotateLeft, IntegerRotateRight and LongRotateRight intrinsics and their translation into an art::HRor instruction. Bug: 27682579 Change-Id: I89f6ea6a7315659a172482bf09875cfb7e7422a1
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/code_generator_arm.cc13
-rw-r--r--compiler/optimizing/code_generator_arm.h2
-rw-r--r--compiler/optimizing/code_generator_x86.cc3
-rw-r--r--compiler/optimizing/common_arm64.h6
-rw-r--r--compiler/optimizing/graph_checker.cc2
-rw-r--r--compiler/optimizing/instruction_simplifier.cc24
-rw-r--r--compiler/optimizing/nodes.h7
7 files changed, 29 insertions, 28 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 34fd9ff2a5..c164f2b344 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -3273,7 +3273,8 @@ void InstructionCodeGeneratorARM::HandleLongRotate(LocationSummary* locations) {
__ Bind(&end);
}
}
-void LocationsBuilderARM::HandleRotate(HRor* ror) {
+
+void LocationsBuilderARM::VisitRor(HRor* ror) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(ror, LocationSummary::kNoCall);
switch (ror->GetResultType()) {
@@ -3300,7 +3301,7 @@ void LocationsBuilderARM::HandleRotate(HRor* ror) {
}
}
-void InstructionCodeGeneratorARM::HandleRotate(HRor* ror) {
+void InstructionCodeGeneratorARM::VisitRor(HRor* ror) {
LocationSummary* locations = ror->GetLocations();
Primitive::Type type = ror->GetResultType();
switch (type) {
@@ -3318,14 +3319,6 @@ void InstructionCodeGeneratorARM::HandleRotate(HRor* ror) {
}
}
-void LocationsBuilderARM::VisitRor(HRor* op) {
- HandleRotate(op);
-}
-
-void InstructionCodeGeneratorARM::VisitRor(HRor* op) {
- HandleRotate(op);
-}
-
void LocationsBuilderARM::HandleShift(HBinaryOperation* op) {
DCHECK(op->IsShl() || op->IsShr() || op->IsUShr());
diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h
index 5c0f31c0cb..cc4aa144c0 100644
--- a/compiler/optimizing/code_generator_arm.h
+++ b/compiler/optimizing/code_generator_arm.h
@@ -174,7 +174,6 @@ class LocationsBuilderARM : public HGraphVisitor {
void HandleCondition(HCondition* condition);
void HandleIntegerRotate(LocationSummary* locations);
void HandleLongRotate(LocationSummary* locations);
- void HandleRotate(HRor* ror);
void HandleShift(HBinaryOperation* operation);
void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info);
void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
@@ -222,7 +221,6 @@ class InstructionCodeGeneratorARM : public InstructionCodeGenerator {
void HandleCondition(HCondition* condition);
void HandleIntegerRotate(LocationSummary* locations);
void HandleLongRotate(LocationSummary* locations);
- void HandleRotate(HRor* ror);
void HandleShift(HBinaryOperation* operation);
void GenerateWideAtomicStore(Register addr, uint32_t offset,
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 9acaa1d000..68c10d4e98 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -3981,8 +3981,7 @@ void InstructionCodeGeneratorX86::VisitRor(HRor* ror) {
__ cmovl(kNotEqual, first_reg_hi, first_reg_lo);
__ cmovl(kNotEqual, first_reg_lo, temp_reg);
} else {
- int32_t shift_amt =
- CodeGenerator::GetInt64ValueOf(second.GetConstant()) & kMaxLongShiftValue;
+ int32_t shift_amt = CodeGenerator::GetInt64ValueOf(second.GetConstant()) & kMaxLongShiftValue;
if (shift_amt == 0) {
// Already fine.
return;
diff --git a/compiler/optimizing/common_arm64.h b/compiler/optimizing/common_arm64.h
index 10d83439fd..6c551945e9 100644
--- a/compiler/optimizing/common_arm64.h
+++ b/compiler/optimizing/common_arm64.h
@@ -194,7 +194,8 @@ static inline vixl::Operand OperandFromMemOperand(const vixl::MemOperand& mem_op
}
static bool CanEncodeConstantAsImmediate(HConstant* constant, HInstruction* instr) {
- DCHECK(constant->IsIntConstant() || constant->IsLongConstant() || constant->IsNullConstant());
+ DCHECK(constant->IsIntConstant() || constant->IsLongConstant() || constant->IsNullConstant())
+ << constant->DebugName();
// For single uses we let VIXL handle the constant generation since it will
// use registers that are not managed by the register allocator (wip0, wip1).
@@ -221,7 +222,8 @@ static bool CanEncodeConstantAsImmediate(HConstant* constant, HInstruction* inst
instr->IsBoundsCheck() ||
instr->IsCompare() ||
instr->IsCondition() ||
- instr->IsSub());
+ instr->IsSub())
+ << instr->DebugName();
// Uses aliases of ADD/SUB instructions.
// If `value` does not fit but `-value` does, VIXL will automatically use
// the 'opposite' instruction.
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index 1fbb2d5277..11e3689a82 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -945,7 +945,7 @@ void GraphChecker::VisitBinaryOperation(HBinaryOperation* op) {
Primitive::PrettyDescriptor(result_type)));
}
} else {
- // Use the first input, so that we can also make this check for shift operations.
+ // Use the first input, so that we can also make this check for shift and rotate operations.
if (Primitive::PrimitiveKind(result_type) != Primitive::PrimitiveKind(lhs_type)) {
AddError(StringPrintf("Binary operation %s %d has a result kind different "
"from its input kind: %s vs %s.",
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index dd2977f799..4a8186a659 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -96,7 +96,7 @@ class InstructionSimplifierVisitor : public HGraphDelegateVisitor {
bool CanEnsureNotNullAt(HInstruction* instr, HInstruction* at) const;
- void SimplifyRotate(HInvoke* invoke, bool is_left);
+ void SimplifyRotate(HInvoke* invoke, bool is_left, Primitive::Type type);
void SimplifySystemArrayCopy(HInvoke* invoke);
void SimplifyStringEquals(HInvoke* invoke);
void SimplifyCompare(HInvoke* invoke, bool is_signum, Primitive::Type type);
@@ -262,10 +262,8 @@ static bool IsSubRegBitsMinusOther(HSub* sub, size_t reg_bits, HInstruction* oth
bool InstructionSimplifierVisitor::ReplaceRotateWithRor(HBinaryOperation* op,
HUShr* ushr,
HShl* shl) {
- DCHECK(op->IsAdd() || op->IsXor() || op->IsOr());
- HRor* ror = new (GetGraph()->GetArena()) HRor(ushr->GetType(),
- ushr->GetLeft(),
- ushr->GetRight());
+ DCHECK(op->IsAdd() || op->IsXor() || op->IsOr()) << op->DebugName();
+ HRor* ror = new (GetGraph()->GetArena()) HRor(ushr->GetType(), ushr->GetLeft(), ushr->GetRight());
op->GetBlock()->ReplaceAndRemoveInstructionWith(op, ror);
if (!ushr->HasUses()) {
ushr->GetBlock()->RemoveInstruction(ushr);
@@ -1232,7 +1230,7 @@ void InstructionSimplifierVisitor::VisitMul(HMul* instruction) {
// with
// SHL dst, src, log2(pow_of_2)
HIntConstant* shift = GetGraph()->GetIntConstant(WhichPowerOf2(factor));
- HShl* shl = new(allocator) HShl(type, input_other, shift);
+ HShl* shl = new (allocator) HShl(type, input_other, shift);
block->ReplaceAndRemoveInstructionWith(instruction, shl);
RecordSimplification();
} else if (IsPowerOfTwo(factor - 1)) {
@@ -1531,7 +1529,9 @@ void InstructionSimplifierVisitor::SimplifyStringEquals(HInvoke* instruction) {
}
}
-void InstructionSimplifierVisitor::SimplifyRotate(HInvoke* invoke, bool is_left) {
+void InstructionSimplifierVisitor::SimplifyRotate(HInvoke* invoke,
+ bool is_left,
+ Primitive::Type type) {
DCHECK(invoke->IsInvokeStaticOrDirect());
DCHECK_EQ(invoke->GetOriginalInvokeType(), InvokeType::kStatic);
HInstruction* value = invoke->InputAt(0);
@@ -1541,7 +1541,7 @@ void InstructionSimplifierVisitor::SimplifyRotate(HInvoke* invoke, bool is_left)
distance = new (GetGraph()->GetArena()) HNeg(distance->GetType(), distance);
invoke->GetBlock()->InsertInstructionBefore(distance, invoke);
}
- HRor* ror = new (GetGraph()->GetArena()) HRor(value->GetType(), value, distance);
+ HRor* ror = new (GetGraph()->GetArena()) HRor(type, value, distance);
invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, ror);
// Remove ClinitCheck and LoadClass, if possible.
HInstruction* clinit = invoke->InputAt(invoke->InputCount() - 1);
@@ -1694,12 +1694,16 @@ void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
SimplifySystemArrayCopy(instruction);
break;
case Intrinsics::kIntegerRotateRight:
+ SimplifyRotate(instruction, /* is_left */ false, Primitive::kPrimInt);
+ break;
case Intrinsics::kLongRotateRight:
- SimplifyRotate(instruction, false);
+ SimplifyRotate(instruction, /* is_left */ false, Primitive::kPrimLong);
break;
case Intrinsics::kIntegerRotateLeft:
+ SimplifyRotate(instruction, /* is_left */ true, Primitive::kPrimInt);
+ break;
case Intrinsics::kLongRotateLeft:
- SimplifyRotate(instruction, true);
+ SimplifyRotate(instruction, /* is_left */ true, Primitive::kPrimLong);
break;
case Intrinsics::kIntegerCompare:
SimplifyCompare(instruction, /* is_signum */ false, Primitive::kPrimInt);
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index e2a54f42ce..46377ee503 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -4689,7 +4689,12 @@ class HXor : public HBinaryOperation {
class HRor : public HBinaryOperation {
public:
HRor(Primitive::Type result_type, HInstruction* value, HInstruction* distance)
- : HBinaryOperation(result_type, value, distance) {}
+ : HBinaryOperation(result_type, value, distance) {
+ if (kIsDebugBuild) {
+ 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 {