summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/optimizing/graph_checker.cc60
-rw-r--r--compiler/optimizing/instruction_builder.cc1
-rw-r--r--compiler/optimizing/intrinsics.h72
-rw-r--r--compiler/optimizing/intrinsics_arm64.h4
-rw-r--r--compiler/optimizing/intrinsics_arm_vixl.h4
-rw-r--r--compiler/optimizing/intrinsics_riscv64.h4
-rw-r--r--compiler/optimizing/intrinsics_x86.h4
-rw-r--r--compiler/optimizing/intrinsics_x86_64.h4
8 files changed, 57 insertions, 96 deletions
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index e8c94dd6b4..8f2f25355d 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -27,6 +27,7 @@
#include "base/scoped_arena_containers.h"
#include "code_generator.h"
#include "handle.h"
+#include "intrinsics.h"
#include "mirror/class.h"
#include "nodes.h"
#include "obj_ptr-inl.h"
@@ -738,50 +739,21 @@ void GraphChecker::VisitInvoke(HInvoke* invoke) {
// Check for intrinsics which should have been replaced by intermediate representation in the
// instruction builder.
- switch (invoke->GetIntrinsic()) {
- case Intrinsics::kIntegerRotateRight:
- case Intrinsics::kLongRotateRight:
- case Intrinsics::kIntegerRotateLeft:
- case Intrinsics::kLongRotateLeft:
- case Intrinsics::kIntegerCompare:
- case Intrinsics::kLongCompare:
- case Intrinsics::kIntegerSignum:
- case Intrinsics::kLongSignum:
- case Intrinsics::kFloatIsNaN:
- case Intrinsics::kDoubleIsNaN:
- case Intrinsics::kStringIsEmpty:
- case Intrinsics::kUnsafeLoadFence:
- case Intrinsics::kUnsafeStoreFence:
- case Intrinsics::kUnsafeFullFence:
- case Intrinsics::kJdkUnsafeLoadFence:
- case Intrinsics::kJdkUnsafeStoreFence:
- case Intrinsics::kJdkUnsafeFullFence:
- case Intrinsics::kVarHandleFullFence:
- case Intrinsics::kVarHandleAcquireFence:
- case Intrinsics::kVarHandleReleaseFence:
- case Intrinsics::kVarHandleLoadLoadFence:
- case Intrinsics::kVarHandleStoreStoreFence:
- case Intrinsics::kMathMinIntInt:
- case Intrinsics::kMathMinLongLong:
- case Intrinsics::kMathMinFloatFloat:
- case Intrinsics::kMathMinDoubleDouble:
- case Intrinsics::kMathMaxIntInt:
- case Intrinsics::kMathMaxLongLong:
- case Intrinsics::kMathMaxFloatFloat:
- case Intrinsics::kMathMaxDoubleDouble:
- case Intrinsics::kMathAbsInt:
- case Intrinsics::kMathAbsLong:
- case Intrinsics::kMathAbsFloat:
- case Intrinsics::kMathAbsDouble:
- AddError(
- StringPrintf("The graph contains an instrinsic which should have been replaced in the "
- "instruction builder: %s:%d in block %d.",
- invoke->DebugName(),
- invoke->GetId(),
- invoke->GetBlock()->GetBlockId()));
- break;
- default:
- break;
+ if (IsIntrinsicWithSpecializedHir(invoke->GetIntrinsic()) &&
+ // FIXME: The inliner can currently create graphs with any of the intrinsics with HIR.
+ // However, we are able to compensate for `StringCharAt` and `StringLength` in the
+ // `HInstructionSimplifier`, so we're allowing these two intrinsics for now, preserving
+ // the old behavior. Besides fixing the bug, we should also clean up the simplifier
+ // and remove `SimplifyStringCharAt` and `SimplifyStringLength`. Bug: 319045458
+ invoke->GetIntrinsic() != Intrinsics::kStringCharAt &&
+ invoke->GetIntrinsic() != Intrinsics::kStringLength) {
+ AddError(
+ StringPrintf("The graph contains the instrinsic %d which should have been replaced in the "
+ "instruction builder: %s:%d in block %d.",
+ enum_cast<int>(invoke->GetIntrinsic()),
+ invoke->DebugName(),
+ invoke->GetId(),
+ invoke->GetBlock()->GetBlockId()));
}
}
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index 23d47c3857..ca0a8e81af 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -2009,6 +2009,7 @@ bool HInstructionBuilder::BuildSimpleIntrinsic(ArtMethod* method,
break;
default:
// We do not have intermediate representation for other intrinsics.
+ DCHECK(!IsIntrinsicWithSpecializedHir(intrinsic));
return false;
}
DCHECK(instruction != nullptr);
diff --git a/compiler/optimizing/intrinsics.h b/compiler/optimizing/intrinsics.h
index d74d5d2a40..d14d264204 100644
--- a/compiler/optimizing/intrinsics.h
+++ b/compiler/optimizing/intrinsics.h
@@ -45,11 +45,23 @@ class IntrinsicVisitor : public ValueObject {
switch (invoke->GetIntrinsic()) {
case Intrinsics::kNone:
return;
+
+#define OPTIMIZING_INTRINSICS_WITH_SPECIALIZED_HIR(Name, ...) \
+ case Intrinsics::k ## Name:
+ ART_INTRINSICS_WITH_SPECIALIZED_HIR_LIST(OPTIMIZING_INTRINSICS_WITH_SPECIALIZED_HIR)
+#undef OPTIMIZING_INTRINSICS_WITH_SPECIALIZED_HIR
+ // Note: clang++ can optimize this `switch` to a range check and a virtual dispatch
+ // with indexed load from the vtable using an adjusted `invoke->GetIntrinsic()`
+ // as the index. However, a non-empty `case` causes clang++ to produce much worse
+ // code, so we want to limit this check to debug builds only.
+ DCHECK(false) << "Unexpected intrinsic with HIR: " << invoke->GetIntrinsic();
+ return;
+
#define OPTIMIZING_INTRINSICS(Name, ...) \
case Intrinsics::k ## Name: \
Visit ## Name(invoke); \
return;
- ART_INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
+ ART_INTRINSICS_WITH_HINVOKE_LIST(OPTIMIZING_INTRINSICS)
#undef OPTIMIZING_INTRINSICS
// Do not put a default case. That way the compiler will complain if we missed a case.
@@ -58,10 +70,10 @@ class IntrinsicVisitor : public ValueObject {
// Define visitor methods.
-#define OPTIMIZING_INTRINSICS(Name, ...) \
- virtual void Visit##Name([[maybe_unused]] HInvoke* invoke) {}
- ART_INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
-#undef OPTIMIZING_INTRINSICS
+#define DECLARE_VISIT_INTRINSIC(Name, ...) \
+ virtual void Visit##Name([[maybe_unused]] HInvoke* invoke) = 0;
+ ART_INTRINSICS_WITH_HINVOKE_LIST(DECLARE_VISIT_INTRINSIC)
+#undef DECLARE_VISIT_INTRINSIC
static void MoveArguments(HInvoke* invoke,
CodeGenerator* codegen,
@@ -153,6 +165,18 @@ class IntrinsicVisitor : public ValueObject {
DISALLOW_COPY_AND_ASSIGN(IntrinsicVisitor);
};
+static inline bool IsIntrinsicWithSpecializedHir(Intrinsics intrinsic) {
+ switch (intrinsic) {
+#define OPTIMIZING_INTRINSICS_WITH_SPECIALIZED_HIR(Name, ...) \
+ case Intrinsics::k ## Name:
+ ART_INTRINSICS_WITH_SPECIALIZED_HIR_LIST(OPTIMIZING_INTRINSICS_WITH_SPECIALIZED_HIR)
+#undef OPTIMIZING_INTRINSICS_WITH_SPECIALIZED_HIR
+ return true;
+ default:
+ return false;
+ }
+}
+
#define GENERIC_OPTIMIZATION(name, bit) \
public: \
void Set##name() { SetBit(k##name); } \
@@ -278,44 +302,8 @@ void IntrinsicCodeGenerator ## Arch::Visit ## Name(HInvoke* invoke) { \
<< " should have been converted to HIR"; \
}
#define UNREACHABLE_INTRINSICS(Arch) \
-UNREACHABLE_INTRINSIC(Arch, MathMinIntInt) \
-UNREACHABLE_INTRINSIC(Arch, MathMinLongLong) \
-UNREACHABLE_INTRINSIC(Arch, MathMinFloatFloat) \
-UNREACHABLE_INTRINSIC(Arch, MathMinDoubleDouble) \
-UNREACHABLE_INTRINSIC(Arch, MathMaxIntInt) \
-UNREACHABLE_INTRINSIC(Arch, MathMaxLongLong) \
-UNREACHABLE_INTRINSIC(Arch, MathMaxFloatFloat) \
-UNREACHABLE_INTRINSIC(Arch, MathMaxDoubleDouble) \
-UNREACHABLE_INTRINSIC(Arch, MathAbsInt) \
-UNREACHABLE_INTRINSIC(Arch, MathAbsLong) \
-UNREACHABLE_INTRINSIC(Arch, MathAbsFloat) \
-UNREACHABLE_INTRINSIC(Arch, MathAbsDouble) \
UNREACHABLE_INTRINSIC(Arch, FloatFloatToIntBits) \
-UNREACHABLE_INTRINSIC(Arch, DoubleDoubleToLongBits) \
-UNREACHABLE_INTRINSIC(Arch, FloatIsNaN) \
-UNREACHABLE_INTRINSIC(Arch, DoubleIsNaN) \
-UNREACHABLE_INTRINSIC(Arch, IntegerRotateLeft) \
-UNREACHABLE_INTRINSIC(Arch, LongRotateLeft) \
-UNREACHABLE_INTRINSIC(Arch, IntegerRotateRight) \
-UNREACHABLE_INTRINSIC(Arch, LongRotateRight) \
-UNREACHABLE_INTRINSIC(Arch, IntegerCompare) \
-UNREACHABLE_INTRINSIC(Arch, LongCompare) \
-UNREACHABLE_INTRINSIC(Arch, IntegerSignum) \
-UNREACHABLE_INTRINSIC(Arch, LongSignum) \
-UNREACHABLE_INTRINSIC(Arch, StringCharAt) \
-UNREACHABLE_INTRINSIC(Arch, StringIsEmpty) \
-UNREACHABLE_INTRINSIC(Arch, StringLength) \
-UNREACHABLE_INTRINSIC(Arch, UnsafeLoadFence) \
-UNREACHABLE_INTRINSIC(Arch, UnsafeStoreFence) \
-UNREACHABLE_INTRINSIC(Arch, UnsafeFullFence) \
-UNREACHABLE_INTRINSIC(Arch, JdkUnsafeLoadFence) \
-UNREACHABLE_INTRINSIC(Arch, JdkUnsafeStoreFence) \
-UNREACHABLE_INTRINSIC(Arch, JdkUnsafeFullFence) \
-UNREACHABLE_INTRINSIC(Arch, VarHandleFullFence) \
-UNREACHABLE_INTRINSIC(Arch, VarHandleAcquireFence) \
-UNREACHABLE_INTRINSIC(Arch, VarHandleReleaseFence) \
-UNREACHABLE_INTRINSIC(Arch, VarHandleLoadLoadFence) \
-UNREACHABLE_INTRINSIC(Arch, VarHandleStoreStoreFence)
+UNREACHABLE_INTRINSIC(Arch, DoubleDoubleToLongBits)
template <typename IntrinsicLocationsBuilder, typename Codegenerator>
bool IsCallFreeIntrinsic(HInvoke* invoke, Codegenerator* codegen) {
diff --git a/compiler/optimizing/intrinsics_arm64.h b/compiler/optimizing/intrinsics_arm64.h
index 50e2e43f5f..d103cafdf7 100644
--- a/compiler/optimizing/intrinsics_arm64.h
+++ b/compiler/optimizing/intrinsics_arm64.h
@@ -48,7 +48,7 @@ class IntrinsicLocationsBuilderARM64 final : public IntrinsicVisitor {
#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \
void Visit ## Name(HInvoke* invoke) override;
- ART_INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
+ ART_INTRINSICS_WITH_HINVOKE_LIST(OPTIMIZING_INTRINSICS)
#undef OPTIMIZING_INTRINSICS
// Check whether an invoke is an intrinsic, and if so, create a location summary. Returns whether
@@ -71,7 +71,7 @@ class IntrinsicCodeGeneratorARM64 final : public IntrinsicVisitor {
#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \
void Visit ## Name(HInvoke* invoke) override;
- ART_INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
+ ART_INTRINSICS_WITH_HINVOKE_LIST(OPTIMIZING_INTRINSICS)
#undef OPTIMIZING_INTRINSICS
private:
diff --git a/compiler/optimizing/intrinsics_arm_vixl.h b/compiler/optimizing/intrinsics_arm_vixl.h
index fd86866d4e..7dcb52403b 100644
--- a/compiler/optimizing/intrinsics_arm_vixl.h
+++ b/compiler/optimizing/intrinsics_arm_vixl.h
@@ -37,7 +37,7 @@ class IntrinsicLocationsBuilderARMVIXL final : public IntrinsicVisitor {
#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \
void Visit ## Name(HInvoke* invoke) override;
- ART_INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
+ ART_INTRINSICS_WITH_HINVOKE_LIST(OPTIMIZING_INTRINSICS)
#undef OPTIMIZING_INTRINSICS
// Check whether an invoke is an intrinsic, and if so, create a location summary. Returns whether
@@ -62,7 +62,7 @@ class IntrinsicCodeGeneratorARMVIXL final : public IntrinsicVisitor {
#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \
void Visit ## Name(HInvoke* invoke) override;
- ART_INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
+ ART_INTRINSICS_WITH_HINVOKE_LIST(OPTIMIZING_INTRINSICS)
#undef OPTIMIZING_INTRINSICS
private:
diff --git a/compiler/optimizing/intrinsics_riscv64.h b/compiler/optimizing/intrinsics_riscv64.h
index 8160c054ee..43068c04c2 100644
--- a/compiler/optimizing/intrinsics_riscv64.h
+++ b/compiler/optimizing/intrinsics_riscv64.h
@@ -42,7 +42,7 @@ class IntrinsicLocationsBuilderRISCV64 final : public IntrinsicVisitor {
#define OPTIMIZING_INTRINSICS(Name, ...) \
void Visit##Name(HInvoke* invoke) override;
- ART_INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
+ ART_INTRINSICS_WITH_HINVOKE_LIST(OPTIMIZING_INTRINSICS)
#undef OPTIMIZING_INTRINSICS
// Check whether an invoke is an intrinsic, and if so, create a location summary. Returns whether
@@ -65,7 +65,7 @@ class IntrinsicCodeGeneratorRISCV64 final : public IntrinsicVisitor {
#define OPTIMIZING_INTRINSICS(Name, ...) \
void Visit##Name(HInvoke* invoke);
- ART_INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
+ ART_INTRINSICS_WITH_HINVOKE_LIST(OPTIMIZING_INTRINSICS)
#undef OPTIMIZING_INTRINSICS
private:
diff --git a/compiler/optimizing/intrinsics_x86.h b/compiler/optimizing/intrinsics_x86.h
index 289a3c342c..565a92a11b 100644
--- a/compiler/optimizing/intrinsics_x86.h
+++ b/compiler/optimizing/intrinsics_x86.h
@@ -40,7 +40,7 @@ class IntrinsicLocationsBuilderX86 final : public IntrinsicVisitor {
#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \
void Visit ## Name(HInvoke* invoke) override;
- ART_INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
+ ART_INTRINSICS_WITH_HINVOKE_LIST(OPTIMIZING_INTRINSICS)
#undef OPTIMIZING_INTRINSICS
// Check whether an invoke is an intrinsic, and if so, create a location summary. Returns whether
@@ -63,7 +63,7 @@ class IntrinsicCodeGeneratorX86 final : public IntrinsicVisitor {
#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \
void Visit ## Name(HInvoke* invoke) override;
- ART_INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
+ ART_INTRINSICS_WITH_HINVOKE_LIST(OPTIMIZING_INTRINSICS)
#undef OPTIMIZING_INTRINSICS
private:
diff --git a/compiler/optimizing/intrinsics_x86_64.h b/compiler/optimizing/intrinsics_x86_64.h
index 4a76c5c8ec..704fa9be0d 100644
--- a/compiler/optimizing/intrinsics_x86_64.h
+++ b/compiler/optimizing/intrinsics_x86_64.h
@@ -40,7 +40,7 @@ class IntrinsicLocationsBuilderX86_64 final : public IntrinsicVisitor {
#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \
void Visit ## Name(HInvoke* invoke) override;
- ART_INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
+ ART_INTRINSICS_WITH_HINVOKE_LIST(OPTIMIZING_INTRINSICS)
#undef OPTIMIZING_INTRINSICS
// Check whether an invoke is an intrinsic, and if so, create a location summary. Returns whether
@@ -63,7 +63,7 @@ class IntrinsicCodeGeneratorX86_64 final : public IntrinsicVisitor {
#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \
void Visit ## Name(HInvoke* invoke) override;
- ART_INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
+ ART_INTRINSICS_WITH_HINVOKE_LIST(OPTIMIZING_INTRINSICS)
#undef OPTIMIZING_INTRINSICS
private: