diff options
author | 2016-03-18 14:04:28 +0000 | |
---|---|---|
committer | 2016-03-18 14:04:28 +0000 | |
commit | 22c4922c6b31e154a6814c4abe9015d9ba156911 (patch) | |
tree | 8e871f67e327322d24d0c2e4588b165005414077 /compiler/optimizing | |
parent | 0205b58a0d7a9ce5832393857c19c086c78996e9 (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.cc | 13 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 3 | ||||
-rw-r--r-- | compiler/optimizing/common_arm64.h | 6 | ||||
-rw-r--r-- | compiler/optimizing/graph_checker.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 24 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 7 |
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 { |