blob: e1a80ec6fbc809f920e65a631931c9a9206d7714 [file] [log] [blame]
Alexandre Rames22aa54b2016-10-18 09:32:29 +01001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_COMPILER_OPTIMIZING_SCHEDULER_ARM64_H_
18#define ART_COMPILER_OPTIMIZING_SCHEDULER_ARM64_H_
19
20#include "scheduler.h"
21
22namespace art {
23namespace arm64 {
24
25static constexpr uint32_t kArm64MemoryLoadLatency = 5;
26static constexpr uint32_t kArm64MemoryStoreLatency = 3;
27
28static constexpr uint32_t kArm64CallInternalLatency = 10;
29static constexpr uint32_t kArm64CallLatency = 5;
30
31// AArch64 instruction latency.
32// We currently assume that all arm64 CPUs share the same instruction latency list.
33static constexpr uint32_t kArm64IntegerOpLatency = 2;
34static constexpr uint32_t kArm64FloatingPointOpLatency = 5;
35
36
37static constexpr uint32_t kArm64DataProcWithShifterOpLatency = 3;
38static constexpr uint32_t kArm64DivDoubleLatency = 30;
39static constexpr uint32_t kArm64DivFloatLatency = 15;
40static constexpr uint32_t kArm64DivIntegerLatency = 5;
41static constexpr uint32_t kArm64LoadStringInternalLatency = 7;
42static constexpr uint32_t kArm64MulFloatingPointLatency = 6;
43static constexpr uint32_t kArm64MulIntegerLatency = 6;
44static constexpr uint32_t kArm64TypeConversionFloatingPointIntegerLatency = 5;
Artem Serovf0fc4c62017-05-03 15:07:15 +010045static constexpr uint32_t kArm64BranchLatency = kArm64IntegerOpLatency;
46
47static constexpr uint32_t kArm64SIMDFloatingPointOpLatency = 10;
48static constexpr uint32_t kArm64SIMDIntegerOpLatency = 6;
49static constexpr uint32_t kArm64SIMDMemoryLoadLatency = 10;
50static constexpr uint32_t kArm64SIMDMemoryStoreLatency = 6;
51static constexpr uint32_t kArm64SIMDMulFloatingPointLatency = 12;
52static constexpr uint32_t kArm64SIMDMulIntegerLatency = 12;
53static constexpr uint32_t kArm64SIMDReplicateOpLatency = 16;
54static constexpr uint32_t kArm64SIMDDivDoubleLatency = 60;
55static constexpr uint32_t kArm64SIMDDivFloatLatency = 30;
56static constexpr uint32_t kArm64SIMDTypeConversionInt2FPLatency = 10;
Alexandre Rames22aa54b2016-10-18 09:32:29 +010057
58class SchedulingLatencyVisitorARM64 : public SchedulingLatencyVisitor {
59 public:
60 // Default visitor for instructions not handled specifically below.
61 void VisitInstruction(HInstruction* ATTRIBUTE_UNUSED) {
62 last_visited_latency_ = kArm64IntegerOpLatency;
63 }
64
65// We add a second unused parameter to be able to use this macro like the others
66// defined in `nodes.h`.
Artem Serovf0fc4c62017-05-03 15:07:15 +010067#define FOR_EACH_SCHEDULED_COMMON_INSTRUCTION(M) \
68 M(ArrayGet , unused) \
69 M(ArrayLength , unused) \
70 M(ArraySet , unused) \
71 M(BinaryOperation , unused) \
72 M(BoundsCheck , unused) \
73 M(Div , unused) \
74 M(InstanceFieldGet , unused) \
75 M(InstanceOf , unused) \
76 M(Invoke , unused) \
77 M(LoadString , unused) \
78 M(Mul , unused) \
79 M(NewArray , unused) \
80 M(NewInstance , unused) \
81 M(Rem , unused) \
82 M(StaticFieldGet , unused) \
83 M(SuspendCheck , unused) \
84 M(TypeConversion , unused) \
85 M(VecReplicateScalar , unused) \
Aart Bik0148de42017-09-05 09:25:01 -070086 M(VecExtractScalar , unused) \
87 M(VecReduce , unused) \
Artem Serovf0fc4c62017-05-03 15:07:15 +010088 M(VecCnv , unused) \
89 M(VecNeg , unused) \
90 M(VecAbs , unused) \
91 M(VecNot , unused) \
92 M(VecAdd , unused) \
93 M(VecHalvingAdd , unused) \
94 M(VecSub , unused) \
95 M(VecMul , unused) \
96 M(VecDiv , unused) \
97 M(VecMin , unused) \
98 M(VecMax , unused) \
99 M(VecAnd , unused) \
100 M(VecAndNot , unused) \
101 M(VecOr , unused) \
102 M(VecXor , unused) \
103 M(VecShl , unused) \
104 M(VecShr , unused) \
105 M(VecUShr , unused) \
Aart Bik0148de42017-09-05 09:25:01 -0700106 M(VecSetScalars , unused) \
Artem Serovf0fc4c62017-05-03 15:07:15 +0100107 M(VecMultiplyAccumulate, unused) \
108 M(VecLoad , unused) \
109 M(VecStore , unused)
Alexandre Rames22aa54b2016-10-18 09:32:29 +0100110
111#define FOR_EACH_SCHEDULED_SHARED_INSTRUCTION(M) \
112 M(BitwiseNegatedRight, unused) \
113 M(MultiplyAccumulate, unused) \
Anton Kirilov74234da2017-01-13 14:42:47 +0000114 M(IntermediateAddress, unused) \
Artem Serovf0fc4c62017-05-03 15:07:15 +0100115 M(IntermediateAddressIndex, unused) \
Anton Kirilov74234da2017-01-13 14:42:47 +0000116 M(DataProcWithShifterOp, unused)
Alexandre Rames22aa54b2016-10-18 09:32:29 +0100117
118#define DECLARE_VISIT_INSTRUCTION(type, unused) \
119 void Visit##type(H##type* instruction) OVERRIDE;
120
121 FOR_EACH_SCHEDULED_COMMON_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
122 FOR_EACH_SCHEDULED_SHARED_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
123 FOR_EACH_CONCRETE_INSTRUCTION_ARM64(DECLARE_VISIT_INSTRUCTION)
124
125#undef DECLARE_VISIT_INSTRUCTION
Artem Serovf0fc4c62017-05-03 15:07:15 +0100126
127 private:
128 void HandleSimpleArithmeticSIMD(HVecOperation *instr);
129 void HandleVecAddress(HVecMemoryOperation* instruction, size_t size);
Alexandre Rames22aa54b2016-10-18 09:32:29 +0100130};
131
132class HSchedulerARM64 : public HScheduler {
133 public:
134 HSchedulerARM64(ArenaAllocator* arena, SchedulingNodeSelector* selector)
135 : HScheduler(arena, &arm64_latency_visitor_, selector) {}
136 ~HSchedulerARM64() OVERRIDE {}
137
138 bool IsSchedulable(const HInstruction* instruction) const OVERRIDE {
139#define CASE_INSTRUCTION_KIND(type, unused) case \
140 HInstruction::InstructionKind::k##type:
141 switch (instruction->GetKind()) {
142 FOR_EACH_SCHEDULED_SHARED_INSTRUCTION(CASE_INSTRUCTION_KIND)
143 return true;
144 FOR_EACH_CONCRETE_INSTRUCTION_ARM64(CASE_INSTRUCTION_KIND)
145 return true;
Artem Serovf0fc4c62017-05-03 15:07:15 +0100146 FOR_EACH_SCHEDULED_COMMON_INSTRUCTION(CASE_INSTRUCTION_KIND)
147 return true;
Alexandre Rames22aa54b2016-10-18 09:32:29 +0100148 default:
149 return HScheduler::IsSchedulable(instruction);
150 }
151#undef CASE_INSTRUCTION_KIND
152 }
153
154 private:
155 SchedulingLatencyVisitorARM64 arm64_latency_visitor_;
156 DISALLOW_COPY_AND_ASSIGN(HSchedulerARM64);
157};
158
159} // namespace arm64
160} // namespace art
161
162#endif // ART_COMPILER_OPTIMIZING_SCHEDULER_ARM64_H_