diff options
Diffstat (limited to 'compiler/optimizing/intrinsics.cc')
| -rw-r--r-- | compiler/optimizing/intrinsics.cc | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc index 8ef13e125e..3db9816173 100644 --- a/compiler/optimizing/intrinsics.cc +++ b/compiler/optimizing/intrinsics.cc @@ -31,7 +31,7 @@ static inline InvokeType GetIntrinsicInvokeType(Intrinsics i) { switch (i) { case Intrinsics::kNone: return kInterface; // Non-sensical for intrinsic. -#define OPTIMIZING_INTRINSICS(Name, IsStatic) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment) \ case Intrinsics::k ## Name: \ return IsStatic; #include "intrinsics_list.h" @@ -42,7 +42,21 @@ INTRINSICS_LIST(OPTIMIZING_INTRINSICS) return kInterface; } - +// Function that returns whether an intrinsic needs an environment or not. +static inline IntrinsicNeedsEnvironment IntrinsicNeedsEnvironment(Intrinsics i) { + switch (i) { + case Intrinsics::kNone: + return kNeedsEnvironment; // Non-sensical for intrinsic. +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment) \ + case Intrinsics::k ## Name: \ + return NeedsEnvironment; +#include "intrinsics_list.h" +INTRINSICS_LIST(OPTIMIZING_INTRINSICS) +#undef INTRINSICS_LIST +#undef OPTIMIZING_INTRINSICS + } + return kNeedsEnvironment; +} static Primitive::Type GetType(uint64_t data, bool is_op_size) { if (is_op_size) { @@ -70,7 +84,10 @@ static Primitive::Type GetType(uint64_t data, bool is_op_size) { } } -static Intrinsics GetIntrinsic(InlineMethod method) { +static Intrinsics GetIntrinsic(InlineMethod method, InstructionSet instruction_set) { + if (instruction_set == kMips || instruction_set == kMips64) { + return Intrinsics::kNone; + } switch (method.opcode) { // Floating-point conversions. case kIntrinsicDoubleCvt: @@ -103,6 +120,16 @@ static Intrinsics GetIntrinsic(InlineMethod method) { LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; UNREACHABLE(); } + case kIntrinsicNumberOfLeadingZeros: + switch (GetType(method.d.data, true)) { + case Primitive::kPrimInt: + return Intrinsics::kIntegerNumberOfLeadingZeros; + case Primitive::kPrimLong: + return Intrinsics::kLongNumberOfLeadingZeros; + default: + LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; + UNREACHABLE(); + } // Abs. case kIntrinsicAbsDouble: @@ -187,6 +214,8 @@ static Intrinsics GetIntrinsic(InlineMethod method) { return Intrinsics::kStringCharAt; case kIntrinsicCompareTo: return Intrinsics::kStringCompareTo; + case kIntrinsicEquals: + return Intrinsics::kStringEquals; case kIntrinsicGetCharsNoCheck: return Intrinsics::kStringGetCharsNoCheck; case kIntrinsicIsEmptyOrLength: @@ -339,7 +368,7 @@ void IntrinsicsRecognizer::Run() { driver_->GetMethodInlinerMap()->GetMethodInliner(&invoke->GetDexFile()); DCHECK(inliner != nullptr); if (inliner->IsIntrinsic(invoke->GetDexMethodIndex(), &method)) { - Intrinsics intrinsic = GetIntrinsic(method); + Intrinsics intrinsic = GetIntrinsic(method, graph_->GetInstructionSet()); if (intrinsic != Intrinsics::kNone) { if (!CheckInvokeType(intrinsic, invoke)) { @@ -347,7 +376,7 @@ void IntrinsicsRecognizer::Run() { << intrinsic << " for " << PrettyMethod(invoke->GetDexMethodIndex(), invoke->GetDexFile()); } else { - invoke->SetIntrinsic(intrinsic); + invoke->SetIntrinsic(intrinsic, IntrinsicNeedsEnvironment(intrinsic)); } } } @@ -359,9 +388,9 @@ void IntrinsicsRecognizer::Run() { std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic) { switch (intrinsic) { case Intrinsics::kNone: - os << "No intrinsic."; + os << "None"; break; -#define OPTIMIZING_INTRINSICS(Name, IsStatic) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment) \ case Intrinsics::k ## Name: \ os << # Name; \ break; |