intrinsics.h revision 2f9fcc999fab4ba6cd86c30e664325b47b9618e5
171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe/*
271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * Copyright (C) 2015 The Android Open Source Project
371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe *
471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * Licensed under the Apache License, Version 2.0 (the "License");
571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * you may not use this file except in compliance with the License.
671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * You may obtain a copy of the License at
771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe *
871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe *      http://www.apache.org/licenses/LICENSE-2.0
971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe *
1071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * Unless required by applicable law or agreed to in writing, software
1171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * distributed under the License is distributed on an "AS IS" BASIS,
1271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * See the License for the specific language governing permissions and
1471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * limitations under the License.
1571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe */
1671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
1771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#ifndef ART_COMPILER_OPTIMIZING_INTRINSICS_H_
1871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#define ART_COMPILER_OPTIMIZING_INTRINSICS_H_
1971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
20ec525fc30848189051b888da53ba051bc0878b78Roland Levillain#include "code_generator.h"
2171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "nodes.h"
2271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "optimization.h"
23ec525fc30848189051b888da53ba051bc0878b78Roland Levillain#include "parallel_move_resolver.h"
2471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
2571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampenamespace art {
2671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
2771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampeclass CompilerDriver;
2871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampeclass DexFile;
2971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
30e6d0d8de85f79c8702ee722a04cd89ee7e89aeb7Andreas Gampe// Temporary measure until we have caught up with the Java 7 definition of Math.round. b/26327751
31e6d0d8de85f79c8702ee722a04cd89ee7e89aeb7Andreas Gampestatic constexpr bool kRoundIsPlusPointFive = false;
32e6d0d8de85f79c8702ee722a04cd89ee7e89aeb7Andreas Gampe
3371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe// Recognize intrinsics from HInvoke nodes.
3471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampeclass IntrinsicsRecognizer : public HOptimization {
3571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe public:
3638e9e8046ea2196284bdb4638771c31108a30a4aJean-Philippe Halimi  IntrinsicsRecognizer(HGraph* graph, CompilerDriver* driver, OptimizingCompilerStats* stats)
3738e9e8046ea2196284bdb4638771c31108a30a4aJean-Philippe Halimi      : HOptimization(graph, kIntrinsicsRecognizerPassName, stats),
38d5111bf05fc0a9974280a80eeb43db6d5227a81eNicolas Geoffray        driver_(driver) {}
3971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
4071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  void Run() OVERRIDE;
4171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
427c3952f423b8213083d60596a5f0bf4237ca3f7bAndreas Gampe  static constexpr const char* kIntrinsicsRecognizerPassName = "intrinsics_recognition";
437c3952f423b8213083d60596a5f0bf4237ca3f7bAndreas Gampe
4471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe private:
4571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  CompilerDriver* driver_;
4671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
4771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  DISALLOW_COPY_AND_ASSIGN(IntrinsicsRecognizer);
4871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe};
4971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
5071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampeclass IntrinsicVisitor : public ValueObject {
5171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe public:
5271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  virtual ~IntrinsicVisitor() {}
5371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
5471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  // Dispatch logic.
5571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
5671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  void Dispatch(HInvoke* invoke) {
5771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    switch (invoke->GetIntrinsic()) {
5871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      case Intrinsics::kNone:
5971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        return;
605d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment, SideEffects, Exceptions) \
615d75afe333f57546786686d9bee16b52f1bbe971Aart Bik      case Intrinsics::k ## Name: \
625d75afe333f57546786686d9bee16b52f1bbe971Aart Bik        Visit ## Name(invoke);    \
6371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe        return;
6471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "intrinsics_list.h"
6571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas GampeINTRINSICS_LIST(OPTIMIZING_INTRINSICS)
6671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef INTRINSICS_LIST
6771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef OPTIMIZING_INTRINSICS
6871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
6971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe      // Do not put a default case. That way the compiler will complain if we missed a case.
7071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe    }
7171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  }
7271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
7371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  // Define visitor methods.
7471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
755d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment, SideEffects, Exceptions) \
7671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  virtual void Visit ## Name(HInvoke* invoke ATTRIBUTE_UNUSED) { \
7771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  }
7871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "intrinsics_list.h"
7971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas GampeINTRINSICS_LIST(OPTIMIZING_INTRINSICS)
8071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef INTRINSICS_LIST
8171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef OPTIMIZING_INTRINSICS
8271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
83ec525fc30848189051b888da53ba051bc0878b78Roland Levillain  static void MoveArguments(HInvoke* invoke,
84ec525fc30848189051b888da53ba051bc0878b78Roland Levillain                            CodeGenerator* codegen,
85ec525fc30848189051b888da53ba051bc0878b78Roland Levillain                            InvokeDexCallingConventionVisitor* calling_convention_visitor) {
86ec525fc30848189051b888da53ba051bc0878b78Roland Levillain    if (kIsDebugBuild && invoke->IsInvokeStaticOrDirect()) {
87ec525fc30848189051b888da53ba051bc0878b78Roland Levillain      HInvokeStaticOrDirect* invoke_static_or_direct = invoke->AsInvokeStaticOrDirect();
8858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil      // Explicit clinit checks triggered by static invokes must have been
8958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil      // pruned by art::PrepareForRegisterAllocation.
9058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil      DCHECK(!invoke_static_or_direct->IsStaticWithExplicitClinitCheck());
91ec525fc30848189051b888da53ba051bc0878b78Roland Levillain    }
92ec525fc30848189051b888da53ba051bc0878b78Roland Levillain
93ec525fc30848189051b888da53ba051bc0878b78Roland Levillain    if (invoke->GetNumberOfArguments() == 0) {
94ec525fc30848189051b888da53ba051bc0878b78Roland Levillain      // No argument to move.
95ec525fc30848189051b888da53ba051bc0878b78Roland Levillain      return;
96ec525fc30848189051b888da53ba051bc0878b78Roland Levillain    }
97ec525fc30848189051b888da53ba051bc0878b78Roland Levillain
98ec525fc30848189051b888da53ba051bc0878b78Roland Levillain    LocationSummary* locations = invoke->GetLocations();
99ec525fc30848189051b888da53ba051bc0878b78Roland Levillain
100ec525fc30848189051b888da53ba051bc0878b78Roland Levillain    // We're moving potentially two or more locations to locations that could overlap, so we need
101ec525fc30848189051b888da53ba051bc0878b78Roland Levillain    // a parallel move resolver.
102ec525fc30848189051b888da53ba051bc0878b78Roland Levillain    HParallelMove parallel_move(codegen->GetGraph()->GetArena());
103ec525fc30848189051b888da53ba051bc0878b78Roland Levillain
104ec525fc30848189051b888da53ba051bc0878b78Roland Levillain    for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) {
105ec525fc30848189051b888da53ba051bc0878b78Roland Levillain      HInstruction* input = invoke->InputAt(i);
106ec525fc30848189051b888da53ba051bc0878b78Roland Levillain      Location cc_loc = calling_convention_visitor->GetNextLocation(input->GetType());
107ec525fc30848189051b888da53ba051bc0878b78Roland Levillain      Location actual_loc = locations->InAt(i);
108ec525fc30848189051b888da53ba051bc0878b78Roland Levillain
109ec525fc30848189051b888da53ba051bc0878b78Roland Levillain      parallel_move.AddMove(actual_loc, cc_loc, input->GetType(), nullptr);
110ec525fc30848189051b888da53ba051bc0878b78Roland Levillain    }
111ec525fc30848189051b888da53ba051bc0878b78Roland Levillain
112ec525fc30848189051b888da53ba051bc0878b78Roland Levillain    codegen->GetMoveResolver()->EmitNativeCode(&parallel_move);
113ec525fc30848189051b888da53ba051bc0878b78Roland Levillain  }
114ec525fc30848189051b888da53ba051bc0878b78Roland Levillain
11571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe protected:
11671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  IntrinsicVisitor() {}
11771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
11871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe private:
11971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe  DISALLOW_COPY_AND_ASSIGN(IntrinsicVisitor);
12071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe};
12171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
122a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray#define GENERIC_OPTIMIZATION(name, bit)                \
12312be662a580278edc37a52087255d87935660869Nicolas Geoffraypublic:                                                \
12412be662a580278edc37a52087255d87935660869Nicolas Geoffrayvoid Set##name() { SetBit(k##name); }                  \
12512be662a580278edc37a52087255d87935660869Nicolas Geoffraybool Get##name() const { return IsBitSet(k##name); }   \
12612be662a580278edc37a52087255d87935660869Nicolas Geoffrayprivate:                                               \
12712be662a580278edc37a52087255d87935660869Nicolas Geoffraystatic constexpr int k##name = bit
128a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
129a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffrayclass IntrinsicOptimizations : public ValueObject {
130a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray public:
13112be662a580278edc37a52087255d87935660869Nicolas Geoffray  explicit IntrinsicOptimizations(HInvoke* invoke) : value_(invoke->GetIntrinsicOptimizations()) {}
13212be662a580278edc37a52087255d87935660869Nicolas Geoffray  explicit IntrinsicOptimizations(const HInvoke& invoke)
13312be662a580278edc37a52087255d87935660869Nicolas Geoffray      : value_(invoke.GetIntrinsicOptimizations()) {}
134a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
135a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  static constexpr int kNumberOfGenericOptimizations = 2;
136a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  GENERIC_OPTIMIZATION(DoesNotNeedDexCache, 0);
137a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  GENERIC_OPTIMIZATION(DoesNotNeedEnvironment, 1);
138a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
139a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray protected:
140a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  bool IsBitSet(uint32_t bit) const {
141a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray    return (*value_ & (1 << bit)) != 0u;
142a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  }
143a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
144a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  void SetBit(uint32_t bit) {
145a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray    *(const_cast<uint32_t*>(value_)) |= (1 << bit);
146a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  }
147a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
148a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray private:
149a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  const uint32_t *value_;
150a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
151a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(IntrinsicOptimizations);
152a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray};
153a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
154a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray#undef GENERIC_OPTIMIZATION
155a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
156a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray#define INTRINSIC_OPTIMIZATION(name, bit)                             \
15712be662a580278edc37a52087255d87935660869Nicolas Geoffraypublic:                                                               \
15812be662a580278edc37a52087255d87935660869Nicolas Geoffrayvoid Set##name() { SetBit(k##name); }                                 \
15912be662a580278edc37a52087255d87935660869Nicolas Geoffraybool Get##name() const { return IsBitSet(k##name); }                  \
16012be662a580278edc37a52087255d87935660869Nicolas Geoffrayprivate:                                                              \
16112be662a580278edc37a52087255d87935660869Nicolas Geoffraystatic constexpr int k##name = bit + kNumberOfGenericOptimizations
162a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
163a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffrayclass StringEqualsOptimizations : public IntrinsicOptimizations {
164a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray public:
16512be662a580278edc37a52087255d87935660869Nicolas Geoffray  explicit StringEqualsOptimizations(HInvoke* invoke) : IntrinsicOptimizations(invoke) {}
166a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
167a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  INTRINSIC_OPTIMIZATION(ArgumentNotNull, 0);
168a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  INTRINSIC_OPTIMIZATION(ArgumentIsString, 1);
169a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
170a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray private:
171a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(StringEqualsOptimizations);
172a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray};
173a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
174ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffrayclass SystemArrayCopyOptimizations : public IntrinsicOptimizations {
175ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray public:
176ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray  explicit SystemArrayCopyOptimizations(HInvoke* invoke) : IntrinsicOptimizations(invoke) {}
177ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray
178ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray  INTRINSIC_OPTIMIZATION(SourceIsNotNull, 0);
179ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray  INTRINSIC_OPTIMIZATION(DestinationIsNotNull, 1);
180ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray  INTRINSIC_OPTIMIZATION(DestinationIsSource, 2);
181ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray  INTRINSIC_OPTIMIZATION(CountIsSourceLength, 3);
182ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray  INTRINSIC_OPTIMIZATION(CountIsDestinationLength, 4);
183ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray  INTRINSIC_OPTIMIZATION(DoesNotNeedTypeCheck, 5);
184ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray  INTRINSIC_OPTIMIZATION(DestinationIsTypedObjectArray, 6);
185ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray  INTRINSIC_OPTIMIZATION(DestinationIsNonPrimitiveArray, 7);
186ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray  INTRINSIC_OPTIMIZATION(DestinationIsPrimitiveArray, 8);
187ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray  INTRINSIC_OPTIMIZATION(SourceIsNonPrimitiveArray, 9);
188ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray  INTRINSIC_OPTIMIZATION(SourceIsPrimitiveArray, 10);
189ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray
190ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray private:
191ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(SystemArrayCopyOptimizations);
192ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray};
193ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray
194a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray#undef INTRISIC_OPTIMIZATION
195a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
1962f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik//
1972f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik// Macros for use in the intrinsics code generators.
1982f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik//
1992f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik
2002f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik// Defines an unimplemented intrinsic: that is, a method call that is recognized as an
2012f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik// intrinsic to exploit e.g. no side-effects or exceptions, but otherwise not handled
2022f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik// by this architecture-specific intrinsics code generator. Eventually it is implemented
2032f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik// as a true method call.
2042f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik#define UNIMPLEMENTED_INTRINSIC(Arch, Name)                                               \
2052f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bikvoid IntrinsicLocationsBuilder ## Arch::Visit ## Name(HInvoke* invoke ATTRIBUTE_UNUSED) { \
2062f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik}                                                                                         \
2072f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bikvoid IntrinsicCodeGenerator ## Arch::Visit ## Name(HInvoke* invoke ATTRIBUTE_UNUSED) {    \
2082f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik}
2092f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik
2102f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik// Defines a list of unreached intrinsics: that is, method calls that are recognized as
2112f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik// an intrinsic, and then always converted into HIR instructions before they reach any
2122f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik// architecture-specific intrinsics code generator.
2132f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik#define UNREACHABLE_INTRINSIC(Arch, Name)                                \
2142f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bikvoid IntrinsicLocationsBuilder ## Arch::Visit ## Name(HInvoke* invoke) { \
2152f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik  LOG(FATAL) << "Unreachable: intrinsic " << invoke->GetIntrinsic()      \
2162f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik             << " should have been converted to HIR";                    \
2172f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik}                                                                        \
2182f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bikvoid IntrinsicCodeGenerator ## Arch::Visit ## Name(HInvoke* invoke) {    \
2192f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik  LOG(FATAL) << "Unreachable: intrinsic " << invoke->GetIntrinsic()      \
2202f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik             << " should have been converted to HIR";                    \
2212f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik}
2222f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik#define UNREACHABLE_INTRINSICS(Arch)                \
2232f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart BikUNREACHABLE_INTRINSIC(Arch, FloatFloatToIntBits)    \
2242f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart BikUNREACHABLE_INTRINSIC(Arch, DoubleDoubleToLongBits) \
2252f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart BikUNREACHABLE_INTRINSIC(Arch, FloatIsNaN)             \
2262f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart BikUNREACHABLE_INTRINSIC(Arch, DoubleIsNaN)            \
2272f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart BikUNREACHABLE_INTRINSIC(Arch, IntegerRotateLeft)      \
2282f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart BikUNREACHABLE_INTRINSIC(Arch, LongRotateLeft)         \
2292f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart BikUNREACHABLE_INTRINSIC(Arch, IntegerRotateRight)     \
2302f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart BikUNREACHABLE_INTRINSIC(Arch, LongRotateRight)        \
2312f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart BikUNREACHABLE_INTRINSIC(Arch, IntegerCompare)         \
2322f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart BikUNREACHABLE_INTRINSIC(Arch, LongCompare)            \
2332f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart BikUNREACHABLE_INTRINSIC(Arch, IntegerSignum)          \
2342f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart BikUNREACHABLE_INTRINSIC(Arch, LongSignum)
2352f9fcc999fab4ba6cd86c30e664325b47b9618e5Aart Bik
23671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe}  // namespace art
23771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe
23871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#endif  // ART_COMPILER_OPTIMIZING_INTRINSICS_H_
239