diff options
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 84 | ||||
| -rw-r--r-- | compiler/optimizing/intrinsics.cc | 4 | ||||
| -rw-r--r-- | compiler/optimizing/intrinsics_arm.cc | 2 | ||||
| -rw-r--r-- | compiler/optimizing/intrinsics_arm64.cc | 2 | ||||
| -rw-r--r-- | compiler/optimizing/intrinsics_list.h | 2 | ||||
| -rw-r--r-- | compiler/optimizing/intrinsics_mips.cc | 2 | ||||
| -rw-r--r-- | compiler/optimizing/intrinsics_mips64.cc | 2 | ||||
| -rw-r--r-- | compiler/optimizing/intrinsics_x86.cc | 2 | ||||
| -rw-r--r-- | compiler/optimizing/intrinsics_x86_64.cc | 2 |
9 files changed, 83 insertions, 19 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index 13d3f752c3..f8a9a94e62 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -93,6 +93,7 @@ class InstructionSimplifierVisitor : public HGraphDelegateVisitor { void SimplifyStringEquals(HInvoke* invoke); void SimplifyCompare(HInvoke* invoke, bool has_zero_op); void SimplifyIsNaN(HInvoke* invoke); + void SimplifyFP2Int(HInvoke* invoke); OptimizingCompilerStats* stats_; bool simplification_occurred_ = false; @@ -1562,26 +1563,71 @@ void InstructionSimplifierVisitor::SimplifyIsNaN(HInvoke* invoke) { invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, condition); } +void InstructionSimplifierVisitor::SimplifyFP2Int(HInvoke* invoke) { + DCHECK(invoke->IsInvokeStaticOrDirect()); + uint32_t dex_pc = invoke->GetDexPc(); + HInstruction* x = invoke->InputAt(0); + Primitive::Type type = x->GetType(); + // Set proper bit pattern for NaN and replace intrinsic with raw version. + HInstruction* nan; + if (type == Primitive::kPrimDouble) { + nan = GetGraph()->GetLongConstant(0x7ff8000000000000L); + invoke->SetIntrinsic(Intrinsics::kDoubleDoubleToRawLongBits, + kNeedsEnvironmentOrCache, + kNoSideEffects, + kNoThrow); + } else { + DCHECK_EQ(type, Primitive::kPrimFloat); + nan = GetGraph()->GetIntConstant(0x7fc00000); + invoke->SetIntrinsic(Intrinsics::kFloatFloatToRawIntBits, + kNeedsEnvironmentOrCache, + kNoSideEffects, + kNoThrow); + } + // Test IsNaN(x), which is the same as x != x. + HCondition* condition = new (GetGraph()->GetArena()) HNotEqual(x, x, dex_pc); + condition->SetBias(ComparisonBias::kLtBias); + invoke->GetBlock()->InsertInstructionBefore(condition, invoke->GetNext()); + // Select between the two. + HInstruction* select = new (GetGraph()->GetArena()) HSelect(condition, nan, invoke, dex_pc); + invoke->GetBlock()->InsertInstructionBefore(select, condition->GetNext()); + invoke->ReplaceWithExceptInReplacementAtIndex(select, 0); // false at index 0 +} + void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) { - if (instruction->GetIntrinsic() == Intrinsics::kStringEquals) { - SimplifyStringEquals(instruction); - } else if (instruction->GetIntrinsic() == Intrinsics::kSystemArrayCopy) { - SimplifySystemArrayCopy(instruction); - } else if (instruction->GetIntrinsic() == Intrinsics::kIntegerRotateRight || - instruction->GetIntrinsic() == Intrinsics::kLongRotateRight) { - SimplifyRotate(instruction, false); - } else if (instruction->GetIntrinsic() == Intrinsics::kIntegerRotateLeft || - instruction->GetIntrinsic() == Intrinsics::kLongRotateLeft) { - SimplifyRotate(instruction, true); - } else if (instruction->GetIntrinsic() == Intrinsics::kIntegerCompare || - instruction->GetIntrinsic() == Intrinsics::kLongCompare) { - SimplifyCompare(instruction, /* is_signum */ false); - } else if (instruction->GetIntrinsic() == Intrinsics::kIntegerSignum || - instruction->GetIntrinsic() == Intrinsics::kLongSignum) { - SimplifyCompare(instruction, /* is_signum */ true); - } else if (instruction->GetIntrinsic() == Intrinsics::kFloatIsNaN || - instruction->GetIntrinsic() == Intrinsics::kDoubleIsNaN) { - SimplifyIsNaN(instruction); + switch (instruction->GetIntrinsic()) { + case Intrinsics::kStringEquals: + SimplifyStringEquals(instruction); + break; + case Intrinsics::kSystemArrayCopy: + SimplifySystemArrayCopy(instruction); + break; + case Intrinsics::kIntegerRotateRight: + case Intrinsics::kLongRotateRight: + SimplifyRotate(instruction, false); + break; + case Intrinsics::kIntegerRotateLeft: + case Intrinsics::kLongRotateLeft: + SimplifyRotate(instruction, true); + break; + case Intrinsics::kIntegerCompare: + case Intrinsics::kLongCompare: + SimplifyCompare(instruction, /* is_signum */ false); + break; + case Intrinsics::kIntegerSignum: + case Intrinsics::kLongSignum: + SimplifyCompare(instruction, /* is_signum */ true); + break; + case Intrinsics::kFloatIsNaN: + case Intrinsics::kDoubleIsNaN: + SimplifyIsNaN(instruction); + break; + case Intrinsics::kFloatFloatToIntBits: + case Intrinsics::kDoubleDoubleToLongBits: + SimplifyFP2Int(instruction); + break; + default: + break; } } diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc index 316e86b4c9..3ed0278871 100644 --- a/compiler/optimizing/intrinsics.cc +++ b/compiler/optimizing/intrinsics.cc @@ -130,6 +130,10 @@ static Intrinsics GetIntrinsic(InlineMethod method) { case kIntrinsicFloatCvt: return ((method.d.data & kIntrinsicFlagToFloatingPoint) == 0) ? Intrinsics::kFloatFloatToRawIntBits : Intrinsics::kFloatIntBitsToFloat; + case kIntrinsicFloat2Int: + return Intrinsics::kFloatFloatToIntBits; + case kIntrinsicDouble2Long: + return Intrinsics::kDoubleDoubleToLongBits; // Floating-point tests. case kIntrinsicFloatIsInfinite: diff --git a/compiler/optimizing/intrinsics_arm.cc b/compiler/optimizing/intrinsics_arm.cc index 8e22f8677d..4ce919ee39 100644 --- a/compiler/optimizing/intrinsics_arm.cc +++ b/compiler/optimizing/intrinsics_arm.cc @@ -2006,6 +2006,8 @@ UNIMPLEMENTED_INTRINSIC(IntegerLowestOneBit) UNIMPLEMENTED_INTRINSIC(LongLowestOneBit) // Handled as HIR instructions. +UNIMPLEMENTED_INTRINSIC(FloatFloatToIntBits) +UNIMPLEMENTED_INTRINSIC(DoubleDoubleToLongBits) UNIMPLEMENTED_INTRINSIC(FloatIsNaN) UNIMPLEMENTED_INTRINSIC(DoubleIsNaN) UNIMPLEMENTED_INTRINSIC(IntegerRotateLeft) diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc index 19ccb3d568..4be1695a94 100644 --- a/compiler/optimizing/intrinsics_arm64.cc +++ b/compiler/optimizing/intrinsics_arm64.cc @@ -1688,6 +1688,8 @@ UNIMPLEMENTED_INTRINSIC(IntegerLowestOneBit) UNIMPLEMENTED_INTRINSIC(LongLowestOneBit) // Handled as HIR instructions. +UNIMPLEMENTED_INTRINSIC(FloatFloatToIntBits) +UNIMPLEMENTED_INTRINSIC(DoubleDoubleToLongBits) UNIMPLEMENTED_INTRINSIC(FloatIsNaN) UNIMPLEMENTED_INTRINSIC(DoubleIsNaN) UNIMPLEMENTED_INTRINSIC(IntegerRotateLeft) diff --git a/compiler/optimizing/intrinsics_list.h b/compiler/optimizing/intrinsics_list.h index 88217b308e..e1aea924cf 100644 --- a/compiler/optimizing/intrinsics_list.h +++ b/compiler/optimizing/intrinsics_list.h @@ -23,10 +23,12 @@ #define INTRINSICS_LIST(V) \ V(DoubleDoubleToRawLongBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ + V(DoubleDoubleToLongBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ V(DoubleIsInfinite, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ V(DoubleIsNaN, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ V(DoubleLongBitsToDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ V(FloatFloatToRawIntBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ + V(FloatFloatToIntBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ V(FloatIsInfinite, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ V(FloatIsNaN, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ V(FloatIntBitsToFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ diff --git a/compiler/optimizing/intrinsics_mips.cc b/compiler/optimizing/intrinsics_mips.cc index 2f183c3a62..a737d8100a 100644 --- a/compiler/optimizing/intrinsics_mips.cc +++ b/compiler/optimizing/intrinsics_mips.cc @@ -1772,6 +1772,8 @@ UNIMPLEMENTED_INTRINSIC(IntegerLowestOneBit) UNIMPLEMENTED_INTRINSIC(LongLowestOneBit) // Handled as HIR instructions. +UNIMPLEMENTED_INTRINSIC(FloatFloatToIntBits) +UNIMPLEMENTED_INTRINSIC(DoubleDoubleToLongBits) UNIMPLEMENTED_INTRINSIC(FloatIsNaN) UNIMPLEMENTED_INTRINSIC(DoubleIsNaN) UNIMPLEMENTED_INTRINSIC(IntegerCompare) diff --git a/compiler/optimizing/intrinsics_mips64.cc b/compiler/optimizing/intrinsics_mips64.cc index bd4f5329da..ca2652b74a 100644 --- a/compiler/optimizing/intrinsics_mips64.cc +++ b/compiler/optimizing/intrinsics_mips64.cc @@ -1824,6 +1824,8 @@ UNIMPLEMENTED_INTRINSIC(IntegerLowestOneBit) UNIMPLEMENTED_INTRINSIC(LongLowestOneBit) // Handled as HIR instructions. +UNIMPLEMENTED_INTRINSIC(FloatFloatToIntBits) +UNIMPLEMENTED_INTRINSIC(DoubleDoubleToLongBits) UNIMPLEMENTED_INTRINSIC(FloatIsNaN) UNIMPLEMENTED_INTRINSIC(DoubleIsNaN) UNIMPLEMENTED_INTRINSIC(IntegerCompare) diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc index 260a8773fb..0df4553f56 100644 --- a/compiler/optimizing/intrinsics_x86.cc +++ b/compiler/optimizing/intrinsics_x86.cc @@ -2642,6 +2642,8 @@ UNIMPLEMENTED_INTRINSIC(IntegerLowestOneBit) UNIMPLEMENTED_INTRINSIC(LongLowestOneBit) // Handled as HIR instructions. +UNIMPLEMENTED_INTRINSIC(FloatFloatToIntBits) +UNIMPLEMENTED_INTRINSIC(DoubleDoubleToLongBits) UNIMPLEMENTED_INTRINSIC(FloatIsNaN) UNIMPLEMENTED_INTRINSIC(DoubleIsNaN) UNIMPLEMENTED_INTRINSIC(IntegerRotateLeft) diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc index 93e8c00e5a..2a9e684d11 100644 --- a/compiler/optimizing/intrinsics_x86_64.cc +++ b/compiler/optimizing/intrinsics_x86_64.cc @@ -2719,6 +2719,8 @@ UNIMPLEMENTED_INTRINSIC(FloatIsInfinite) UNIMPLEMENTED_INTRINSIC(DoubleIsInfinite) // Handled as HIR instructions. +UNIMPLEMENTED_INTRINSIC(FloatFloatToIntBits) +UNIMPLEMENTED_INTRINSIC(DoubleDoubleToLongBits) UNIMPLEMENTED_INTRINSIC(FloatIsNaN) UNIMPLEMENTED_INTRINSIC(DoubleIsNaN) UNIMPLEMENTED_INTRINSIC(IntegerRotateLeft) |