blob: eb034e92e3736837e4120bf67226290a9f14c8b7 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/compiler/machine-operator.h"
6
7#include "src/base/lazy-instance.h"
8#include "src/compiler/opcodes.h"
9#include "src/compiler/operator.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010#include "src/v8.h"
11#include "src/zone-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012
13namespace v8 {
14namespace internal {
15namespace compiler {
16
Emily Bernierd0a1eb72015-03-24 16:35:39 -040017std::ostream& operator<<(std::ostream& os, WriteBarrierKind kind) {
18 switch (kind) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000019 case kNoWriteBarrier:
20 return os << "NoWriteBarrier";
21 case kFullWriteBarrier:
22 return os << "FullWriteBarrier";
23 }
24 UNREACHABLE();
25 return os;
26}
27
28
Emily Bernierd0a1eb72015-03-24 16:35:39 -040029bool operator==(StoreRepresentation lhs, StoreRepresentation rhs) {
30 return lhs.machine_type() == rhs.machine_type() &&
31 lhs.write_barrier_kind() == rhs.write_barrier_kind();
32}
33
34
35bool operator!=(StoreRepresentation lhs, StoreRepresentation rhs) {
36 return !(lhs == rhs);
37}
38
39
40size_t hash_value(StoreRepresentation rep) {
41 return base::hash_combine(rep.machine_type(), rep.write_barrier_kind());
42}
43
44
45std::ostream& operator<<(std::ostream& os, StoreRepresentation rep) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000046 return os << "(" << rep.machine_type() << " : " << rep.write_barrier_kind()
47 << ")";
48}
49
50
Emily Bernierd0a1eb72015-03-24 16:35:39 -040051StoreRepresentation const& StoreRepresentationOf(Operator const* op) {
52 DCHECK_EQ(IrOpcode::kStore, op->opcode());
53 return OpParameter<StoreRepresentation>(op);
54}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000055
56
Emily Bernierd0a1eb72015-03-24 16:35:39 -040057CheckedLoadRepresentation CheckedLoadRepresentationOf(Operator const* op) {
58 DCHECK_EQ(IrOpcode::kCheckedLoad, op->opcode());
59 return OpParameter<CheckedLoadRepresentation>(op);
60}
61
62
63CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
64 DCHECK_EQ(IrOpcode::kCheckedStore, op->opcode());
65 return OpParameter<CheckedStoreRepresentation>(op);
66}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000067
68
69#define PURE_OP_LIST(V) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -040070 V(Word32And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
71 V(Word32Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
72 V(Word32Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
73 V(Word32Shl, Operator::kNoProperties, 2, 0, 1) \
74 V(Word32Shr, Operator::kNoProperties, 2, 0, 1) \
75 V(Word32Sar, Operator::kNoProperties, 2, 0, 1) \
76 V(Word32Ror, Operator::kNoProperties, 2, 0, 1) \
77 V(Word32Equal, Operator::kCommutative, 2, 0, 1) \
78 V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
79 V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
80 V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
81 V(Word64Shl, Operator::kNoProperties, 2, 0, 1) \
82 V(Word64Shr, Operator::kNoProperties, 2, 0, 1) \
83 V(Word64Sar, Operator::kNoProperties, 2, 0, 1) \
84 V(Word64Ror, Operator::kNoProperties, 2, 0, 1) \
85 V(Word64Equal, Operator::kCommutative, 2, 0, 1) \
86 V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000087 V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative, 2, \
Emily Bernierd0a1eb72015-03-24 16:35:39 -040088 0, 2) \
89 V(Int32Sub, Operator::kNoProperties, 2, 0, 1) \
90 V(Int32SubWithOverflow, Operator::kNoProperties, 2, 0, 2) \
91 V(Int32Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
92 V(Int32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
93 V(Int32Div, Operator::kNoProperties, 2, 1, 1) \
94 V(Int32Mod, Operator::kNoProperties, 2, 1, 1) \
95 V(Int32LessThan, Operator::kNoProperties, 2, 0, 1) \
96 V(Int32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
97 V(Uint32Div, Operator::kNoProperties, 2, 1, 1) \
98 V(Uint32LessThan, Operator::kNoProperties, 2, 0, 1) \
99 V(Uint32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
100 V(Uint32Mod, Operator::kNoProperties, 2, 1, 1) \
101 V(Uint32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
102 V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
103 V(Int64Sub, Operator::kNoProperties, 2, 0, 1) \
104 V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
105 V(Int64Div, Operator::kNoProperties, 2, 0, 1) \
106 V(Int64Mod, Operator::kNoProperties, 2, 0, 1) \
107 V(Int64LessThan, Operator::kNoProperties, 2, 0, 1) \
108 V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
109 V(Uint64Div, Operator::kNoProperties, 2, 0, 1) \
110 V(Uint64LessThan, Operator::kNoProperties, 2, 0, 1) \
111 V(Uint64Mod, Operator::kNoProperties, 2, 0, 1) \
112 V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
113 V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \
114 V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 0, 1) \
115 V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
116 V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1) \
117 V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
118 V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1) \
119 V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
120 V(TruncateFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \
121 V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1) \
122 V(Float64Add, Operator::kCommutative, 2, 0, 1) \
123 V(Float64Sub, Operator::kNoProperties, 2, 0, 1) \
124 V(Float64Mul, Operator::kCommutative, 2, 0, 1) \
125 V(Float64Div, Operator::kNoProperties, 2, 0, 1) \
126 V(Float64Mod, Operator::kNoProperties, 2, 0, 1) \
127 V(Float64Sqrt, Operator::kNoProperties, 1, 0, 1) \
128 V(Float64Ceil, Operator::kNoProperties, 1, 0, 1) \
129 V(Float64Floor, Operator::kNoProperties, 1, 0, 1) \
130 V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
131 V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1) \
132 V(Float64Equal, Operator::kCommutative, 2, 0, 1) \
133 V(Float64LessThan, Operator::kNoProperties, 2, 0, 1) \
134 V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
135 V(LoadStackPointer, Operator::kNoProperties, 0, 0, 1)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136
137
138#define MACHINE_TYPE_LIST(V) \
139 V(MachFloat32) \
140 V(MachFloat64) \
141 V(MachInt8) \
142 V(MachUint8) \
143 V(MachInt16) \
144 V(MachUint16) \
145 V(MachInt32) \
146 V(MachUint32) \
147 V(MachInt64) \
148 V(MachUint64) \
149 V(MachAnyTagged) \
150 V(RepBit) \
151 V(RepWord8) \
152 V(RepWord16) \
153 V(RepWord32) \
154 V(RepWord64) \
155 V(RepFloat32) \
156 V(RepFloat64) \
157 V(RepTagged)
158
159
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400160struct MachineOperatorGlobalCache {
161#define PURE(Name, properties, value_input_count, control_input_count, \
162 output_count) \
163 struct Name##Operator FINAL : public Operator { \
164 Name##Operator() \
165 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
166 value_input_count, 0, control_input_count, output_count, 0, \
167 0) {} \
168 }; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000169 Name##Operator k##Name;
170 PURE_OP_LIST(PURE)
171#undef PURE
172
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400173#define LOAD(Type) \
174 struct Load##Type##Operator FINAL : public Operator1<LoadRepresentation> { \
175 Load##Type##Operator() \
176 : Operator1<LoadRepresentation>( \
177 IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, \
178 "Load", 2, 1, 1, 1, 1, 0, k##Type) {} \
179 }; \
180 struct CheckedLoad##Type##Operator FINAL \
181 : public Operator1<CheckedLoadRepresentation> { \
182 CheckedLoad##Type##Operator() \
183 : Operator1<CheckedLoadRepresentation>( \
184 IrOpcode::kCheckedLoad, Operator::kNoThrow | Operator::kNoWrite, \
185 "CheckedLoad", 3, 1, 1, 1, 1, 0, k##Type) {} \
186 }; \
187 Load##Type##Operator kLoad##Type; \
188 CheckedLoad##Type##Operator kCheckedLoad##Type;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000189 MACHINE_TYPE_LIST(LOAD)
190#undef LOAD
191
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400192#define STORE(Type) \
193 struct Store##Type##Operator : public Operator1<StoreRepresentation> { \
194 explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind) \
195 : Operator1<StoreRepresentation>( \
196 IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, \
197 "Store", 3, 1, 1, 0, 1, 0, \
198 StoreRepresentation(k##Type, write_barrier_kind)) {} \
199 }; \
200 struct Store##Type##NoWriteBarrier##Operator FINAL \
201 : public Store##Type##Operator { \
202 Store##Type##NoWriteBarrier##Operator() \
203 : Store##Type##Operator(kNoWriteBarrier) {} \
204 }; \
205 struct Store##Type##FullWriteBarrier##Operator FINAL \
206 : public Store##Type##Operator { \
207 Store##Type##FullWriteBarrier##Operator() \
208 : Store##Type##Operator(kFullWriteBarrier) {} \
209 }; \
210 struct CheckedStore##Type##Operator FINAL \
211 : public Operator1<CheckedStoreRepresentation> { \
212 CheckedStore##Type##Operator() \
213 : Operator1<CheckedStoreRepresentation>( \
214 IrOpcode::kCheckedStore, Operator::kNoRead | Operator::kNoThrow, \
215 "CheckedStore", 4, 1, 1, 0, 1, 0, k##Type) {} \
216 }; \
217 Store##Type##NoWriteBarrier##Operator kStore##Type##NoWriteBarrier; \
218 Store##Type##FullWriteBarrier##Operator kStore##Type##FullWriteBarrier; \
219 CheckedStore##Type##Operator kCheckedStore##Type;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000220 MACHINE_TYPE_LIST(STORE)
221#undef STORE
222};
223
224
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400225static base::LazyInstance<MachineOperatorGlobalCache>::type kCache =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000226 LAZY_INSTANCE_INITIALIZER;
227
228
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400229MachineOperatorBuilder::MachineOperatorBuilder(Zone* zone, MachineType word,
230 Flags flags)
231 : zone_(zone), cache_(kCache.Get()), word_(word), flags_(flags) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000232 DCHECK(word == kRepWord32 || word == kRepWord64);
233}
234
235
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400236#define PURE(Name, properties, value_input_count, control_input_count, \
237 output_count) \
238 const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000239PURE_OP_LIST(PURE)
240#undef PURE
241
242
243const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
244 switch (rep) {
245#define LOAD(Type) \
246 case k##Type: \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400247 return &cache_.kLoad##Type;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000248 MACHINE_TYPE_LIST(LOAD)
249#undef LOAD
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000250 default:
251 break;
252 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400253 // Uncached.
254 return new (zone_) Operator1<LoadRepresentation>( // --
255 IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, "Load", 2, 1, 1,
256 1, 1, 0, rep);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000257}
258
259
260const Operator* MachineOperatorBuilder::Store(StoreRepresentation rep) {
261 switch (rep.machine_type()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400262#define STORE(Type) \
263 case k##Type: \
264 switch (rep.write_barrier_kind()) { \
265 case kNoWriteBarrier: \
266 return &cache_.k##Store##Type##NoWriteBarrier; \
267 case kFullWriteBarrier: \
268 return &cache_.k##Store##Type##FullWriteBarrier; \
269 } \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000270 break;
271 MACHINE_TYPE_LIST(STORE)
272#undef STORE
273
274 default:
275 break;
276 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400277 // Uncached.
278 return new (zone_) Operator1<StoreRepresentation>( // --
279 IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, "Store", 3, 1,
280 1, 0, 1, 0, rep);
281}
282
283
284const Operator* MachineOperatorBuilder::CheckedLoad(
285 CheckedLoadRepresentation rep) {
286 switch (rep) {
287#define LOAD(Type) \
288 case k##Type: \
289 return &cache_.kCheckedLoad##Type;
290 MACHINE_TYPE_LIST(LOAD)
291#undef LOAD
292 default:
293 break;
294 }
295 // Uncached.
296 return new (zone_) Operator1<CheckedLoadRepresentation>(
297 IrOpcode::kCheckedLoad, Operator::kNoThrow | Operator::kNoWrite,
298 "CheckedLoad", 3, 1, 1, 1, 1, 0, rep);
299}
300
301
302const Operator* MachineOperatorBuilder::CheckedStore(
303 CheckedStoreRepresentation rep) {
304 switch (rep) {
305#define STORE(Type) \
306 case k##Type: \
307 return &cache_.kCheckedStore##Type;
308 MACHINE_TYPE_LIST(STORE)
309#undef STORE
310 default:
311 break;
312 }
313 // Uncached.
314 return new (zone_) Operator1<CheckedStoreRepresentation>(
315 IrOpcode::kCheckedStore, Operator::kNoRead | Operator::kNoThrow,
316 "CheckedStore", 4, 1, 1, 0, 1, 0, rep);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000317}
318
319} // namespace compiler
320} // namespace internal
321} // namespace v8