diff options
Diffstat (limited to 'compiler/optimizing/intrinsics.cc')
-rw-r--r-- | compiler/optimizing/intrinsics.cc | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc index 8357e57c1f..d84e1cbc97 100644 --- a/compiler/optimizing/intrinsics.cc +++ b/compiler/optimizing/intrinsics.cc @@ -32,6 +32,7 @@ #include "obj_ptr-inl.h" #include "scoped_thread_state_change-inl.h" #include "thread-current-inl.h" +#include "well_known_classes.h" namespace art HIDDEN { @@ -412,4 +413,54 @@ void IntrinsicVisitor::AssertNonMovableStringClass() { } } +void InsertFpToIntegralIntrinsic(HInvokeStaticOrDirect* invoke, size_t input_index) { + DCHECK_EQ(invoke->GetCodePtrLocation(), CodePtrLocation::kCallCriticalNative); + DCHECK(!invoke->GetBlock()->GetGraph()->IsDebuggable()) + << "Unexpected direct @CriticalNative call in a debuggable graph!"; + DCHECK_LT(input_index, invoke->GetNumberOfArguments()); + HInstruction* input = invoke->InputAt(input_index); + DataType::Type input_type = input->GetType(); + DCHECK(DataType::IsFloatingPointType(input_type)); + bool is_double = (input_type == DataType::Type::kFloat64); + DataType::Type converted_type = is_double ? DataType::Type::kInt64 : DataType::Type::kInt32; + ArtMethod* resolved_method = is_double + ? WellKnownClasses::java_lang_Double_doubleToRawLongBits + : WellKnownClasses::java_lang_Float_floatToRawIntBits; + DCHECK(resolved_method != nullptr); + DCHECK(resolved_method->IsIntrinsic()); + MethodReference target_method(nullptr, 0); + { + ScopedObjectAccess soa(Thread::Current()); + target_method = + MethodReference(resolved_method->GetDexFile(), resolved_method->GetDexMethodIndex()); + } + // Use arbitrary dispatch info that does not require the method argument. + HInvokeStaticOrDirect::DispatchInfo dispatch_info = { + MethodLoadKind::kBssEntry, + CodePtrLocation::kCallArtMethod, + /*method_load_data=*/ 0u + }; + HBasicBlock* block = invoke->GetBlock(); + ArenaAllocator* allocator = block->GetGraph()->GetAllocator(); + HInvokeStaticOrDirect* new_input = new (allocator) HInvokeStaticOrDirect( + allocator, + /*number_of_arguments=*/ 1u, + converted_type, + invoke->GetDexPc(), + /*method_reference=*/ MethodReference(nullptr, dex::kDexNoIndex), + resolved_method, + dispatch_info, + kStatic, + target_method, + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + /*enable_intrinsic_opt=*/ true); + // The intrinsic has no side effects and does not need the environment. + new_input->SetSideEffects(SideEffects::None()); + IntrinsicOptimizations opt(new_input); + opt.SetDoesNotNeedEnvironment(); + new_input->SetRawInputAt(0u, input); + block->InsertInstructionBefore(new_input, invoke); + invoke->ReplaceInput(new_input, input_index); +} + } // namespace art |