OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/common-operator.h" | 5 #include "src/compiler/common-operator.h" |
6 | 6 |
7 #include "src/assembler.h" | 7 #include "src/assembler.h" |
8 #include "src/base/lazy-instance.h" | 8 #include "src/base/lazy-instance.h" |
9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
10 #include "src/unique.h" | 10 #include "src/unique.h" |
11 #include "src/zone.h" | 11 #include "src/zone.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 namespace compiler { | 15 namespace compiler { |
16 | 16 |
17 namespace { | 17 namespace { |
18 | 18 |
19 // TODO(turbofan): Use size_t instead of int here. | 19 // TODO(turbofan): Use size_t instead of int here. |
20 class ControlOperator : public Operator1<int> { | 20 class ControlOperator : public Operator1<int> { |
21 public: | 21 public: |
22 ControlOperator(IrOpcode::Value opcode, Properties properties, int inputs, | 22 ControlOperator(IrOpcode::Value opcode, Properties properties, int inputs, |
23 int outputs, int controls, const char* mnemonic) | 23 int outputs, int controls, const char* mnemonic) |
24 : Operator1<int>(opcode, properties, inputs, outputs, mnemonic, | 24 : Operator1<int>(opcode, properties, inputs, outputs, mnemonic, |
25 controls) {} | 25 controls) {} |
26 | 26 |
27 virtual std::ostream& PrintParameter(std::ostream& os) const FINAL { | 27 virtual void PrintParameter(std::ostream& os) const FINAL {} |
28 return os; | |
29 } | |
30 }; | 28 }; |
31 | 29 |
32 } // namespace | 30 } // namespace |
33 | 31 |
34 | 32 |
35 // Specialization for static parameters of type {ExternalReference}. | 33 size_t hash_value(OutputFrameStateCombine const& sc) { |
36 template <> | 34 return base::hash_combine(sc.kind_, sc.parameter_); |
37 struct StaticParameterTraits<ExternalReference> { | 35 } |
38 static std::ostream& PrintTo(std::ostream& os, ExternalReference reference) { | 36 |
39 os << static_cast<const void*>(reference.address()); | 37 |
40 // TODO(bmeurer): Move to operator<<(os, ExternalReference) | 38 std::ostream& operator<<(std::ostream& os, OutputFrameStateCombine const& sc) { |
41 const Runtime::Function* function = | 39 switch (sc.kind_) { |
42 Runtime::FunctionForEntry(reference.address()); | 40 case OutputFrameStateCombine::kPushOutput: |
43 if (function) { | 41 if (sc.parameter_ == 0) return os << "Ignore"; |
44 os << " <" << function->name << ".entry>"; | 42 return os << "Push(" << sc.parameter_ << ")"; |
45 } | 43 case OutputFrameStateCombine::kPokeAt: |
46 return os; | 44 return os << "PokeAt(" << sc.parameter_ << ")"; |
47 } | 45 } |
48 static int HashCode(ExternalReference reference) { | 46 UNREACHABLE(); |
49 return bit_cast<int>(static_cast<uint32_t>( | 47 return os; |
50 reinterpret_cast<uintptr_t>(reference.address()))); | 48 } |
51 } | 49 |
52 static bool Equals(ExternalReference lhs, ExternalReference rhs) { | 50 |
53 return lhs == rhs; | 51 bool operator==(FrameStateCallInfo const& lhs, FrameStateCallInfo const& rhs) { |
54 } | 52 return lhs.type() == rhs.type() && lhs.bailout_id() == rhs.bailout_id() && |
55 }; | 53 lhs.state_combine() == rhs.state_combine(); |
| 54 } |
| 55 |
| 56 |
| 57 bool operator!=(FrameStateCallInfo const& lhs, FrameStateCallInfo const& rhs) { |
| 58 return !(lhs == rhs); |
| 59 } |
| 60 |
| 61 |
| 62 size_t hash_value(FrameStateCallInfo const& info) { |
| 63 return base::hash_combine(info.type(), info.bailout_id(), |
| 64 info.state_combine()); |
| 65 } |
| 66 |
| 67 |
| 68 std::ostream& operator<<(std::ostream& os, FrameStateCallInfo const& info) { |
| 69 return os << info.type() << ", " << info.bailout_id() << ", " |
| 70 << info.state_combine(); |
| 71 } |
56 | 72 |
57 | 73 |
58 #define SHARED_OP_LIST(V) \ | 74 #define SHARED_OP_LIST(V) \ |
59 V(Dead, Operator::kFoldable, 0, 0) \ | 75 V(Dead, Operator::kFoldable, 0, 0) \ |
60 V(End, Operator::kFoldable, 0, 1) \ | 76 V(End, Operator::kFoldable, 0, 1) \ |
61 V(Branch, Operator::kFoldable, 1, 1) \ | 77 V(Branch, Operator::kFoldable, 1, 1) \ |
62 V(IfTrue, Operator::kFoldable, 0, 1) \ | 78 V(IfTrue, Operator::kFoldable, 0, 1) \ |
63 V(IfFalse, Operator::kFoldable, 0, 1) \ | 79 V(IfFalse, Operator::kFoldable, 0, 1) \ |
64 V(Throw, Operator::kFoldable, 1, 1) \ | 80 V(Throw, Operator::kFoldable, 1, 1) \ |
65 V(Return, Operator::kNoProperties, 1, 1) | 81 V(Return, Operator::kNoProperties, 1, 1) |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 | 171 |
156 | 172 |
157 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) { | 173 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) { |
158 return new (zone()) | 174 return new (zone()) |
159 Operator1<double>(IrOpcode::kNumberConstant, Operator::kPure, 0, 1, | 175 Operator1<double>(IrOpcode::kNumberConstant, Operator::kPure, 0, 1, |
160 "NumberConstant", value); | 176 "NumberConstant", value); |
161 } | 177 } |
162 | 178 |
163 | 179 |
164 const Operator* CommonOperatorBuilder::HeapConstant( | 180 const Operator* CommonOperatorBuilder::HeapConstant( |
165 const Unique<Object>& value) { | 181 const Unique<HeapObject>& value) { |
166 return new (zone()) Operator1<Unique<Object> >( | 182 return new (zone()) Operator1<Unique<HeapObject>>( |
167 IrOpcode::kHeapConstant, Operator::kPure, 0, 1, "HeapConstant", value); | 183 IrOpcode::kHeapConstant, Operator::kPure, 0, 1, "HeapConstant", value); |
168 } | 184 } |
169 | 185 |
170 | 186 |
171 const Operator* CommonOperatorBuilder::Phi(MachineType type, int arguments) { | 187 const Operator* CommonOperatorBuilder::Phi(MachineType type, int arguments) { |
172 DCHECK(arguments > 0); // Disallow empty phis. | 188 DCHECK(arguments > 0); // Disallow empty phis. |
173 return new (zone()) Operator1<MachineType>(IrOpcode::kPhi, Operator::kPure, | 189 return new (zone()) Operator1<MachineType>(IrOpcode::kPhi, Operator::kPure, |
174 arguments, 1, "Phi", type); | 190 arguments, 1, "Phi", type); |
175 } | 191 } |
176 | 192 |
177 | 193 |
178 const Operator* CommonOperatorBuilder::EffectPhi(int arguments) { | 194 const Operator* CommonOperatorBuilder::EffectPhi(int arguments) { |
179 DCHECK(arguments > 0); // Disallow empty phis. | 195 DCHECK(arguments > 0); // Disallow empty phis. |
180 return new (zone()) Operator1<int>(IrOpcode::kEffectPhi, Operator::kPure, 0, | 196 return new (zone()) Operator1<int>(IrOpcode::kEffectPhi, Operator::kPure, 0, |
181 0, "EffectPhi", arguments); | 197 0, "EffectPhi", arguments); |
182 } | 198 } |
183 | 199 |
184 | 200 |
185 const Operator* CommonOperatorBuilder::ValueEffect(int arguments) { | 201 const Operator* CommonOperatorBuilder::ValueEffect(int arguments) { |
186 DCHECK(arguments > 0); // Disallow empty value effects. | 202 DCHECK(arguments > 0); // Disallow empty value effects. |
187 return new (zone()) SimpleOperator(IrOpcode::kValueEffect, Operator::kPure, | 203 return new (zone()) Operator1<int>(IrOpcode::kValueEffect, Operator::kPure, |
188 arguments, 0, "ValueEffect"); | 204 arguments, 0, "ValueEffect", arguments); |
189 } | 205 } |
190 | 206 |
191 | 207 |
192 const Operator* CommonOperatorBuilder::Finish(int arguments) { | 208 const Operator* CommonOperatorBuilder::Finish(int arguments) { |
193 DCHECK(arguments > 0); // Disallow empty finishes. | 209 DCHECK(arguments > 0); // Disallow empty finishes. |
194 return new (zone()) Operator1<int>(IrOpcode::kFinish, Operator::kPure, 1, 1, | 210 return new (zone()) Operator1<int>(IrOpcode::kFinish, Operator::kPure, 1, 1, |
195 "Finish", arguments); | 211 "Finish", arguments); |
196 } | 212 } |
197 | 213 |
198 | 214 |
(...skipping 18 matching lines...) Expand all Loading... |
217 // TODO(titzer): Operator still uses int, whereas CallDescriptor uses | 233 // TODO(titzer): Operator still uses int, whereas CallDescriptor uses |
218 // size_t. | 234 // size_t. |
219 CallOperator(const CallDescriptor* descriptor, const char* mnemonic) | 235 CallOperator(const CallDescriptor* descriptor, const char* mnemonic) |
220 : Operator1<const CallDescriptor*>( | 236 : Operator1<const CallDescriptor*>( |
221 IrOpcode::kCall, descriptor->properties(), | 237 IrOpcode::kCall, descriptor->properties(), |
222 static_cast<int>(descriptor->InputCount() + | 238 static_cast<int>(descriptor->InputCount() + |
223 descriptor->FrameStateCount()), | 239 descriptor->FrameStateCount()), |
224 static_cast<int>(descriptor->ReturnCount()), mnemonic, | 240 static_cast<int>(descriptor->ReturnCount()), mnemonic, |
225 descriptor) {} | 241 descriptor) {} |
226 | 242 |
227 virtual std::ostream& PrintParameter(std::ostream& os) const OVERRIDE { | 243 virtual void PrintParameter(std::ostream& os) const OVERRIDE { |
228 return os << "[" << *parameter() << "]"; | 244 os << "[" << *parameter() << "]"; |
229 } | 245 } |
230 }; | 246 }; |
231 return new (zone()) CallOperator(descriptor, "Call"); | 247 return new (zone()) CallOperator(descriptor, "Call"); |
232 } | 248 } |
233 | 249 |
234 | 250 |
235 const Operator* CommonOperatorBuilder::Projection(size_t index) { | 251 const Operator* CommonOperatorBuilder::Projection(size_t index) { |
236 return new (zone()) Operator1<size_t>(IrOpcode::kProjection, Operator::kPure, | 252 return new (zone()) Operator1<size_t>(IrOpcode::kProjection, Operator::kPure, |
237 1, 1, "Projection", index); | 253 1, 1, "Projection", index); |
238 } | 254 } |
239 | 255 |
240 | |
241 OutputFrameStateCombine::OutputFrameStateCombine(CombineKind kind, | |
242 size_t parameter) | |
243 : kind_(kind), parameter_(parameter) {} | |
244 | |
245 // static | |
246 OutputFrameStateCombine OutputFrameStateCombine::Ignore() { | |
247 return OutputFrameStateCombine(kPushOutput, 0); | |
248 } | |
249 | |
250 | |
251 // static | |
252 OutputFrameStateCombine OutputFrameStateCombine::Push(size_t count) { | |
253 return OutputFrameStateCombine(kPushOutput, count); | |
254 } | |
255 | |
256 | |
257 // static | |
258 OutputFrameStateCombine OutputFrameStateCombine::PokeAt(size_t index) { | |
259 return OutputFrameStateCombine(kPokeAt, index); | |
260 } | |
261 | |
262 | |
263 OutputFrameStateCombine::CombineKind OutputFrameStateCombine::kind() { | |
264 return kind_; | |
265 } | |
266 | |
267 | |
268 size_t OutputFrameStateCombine::GetPushCount() { | |
269 DCHECK(kind() == kPushOutput); | |
270 return parameter_; | |
271 } | |
272 | |
273 | |
274 size_t OutputFrameStateCombine::GetOffsetToPokeAt() { | |
275 DCHECK(kind() == kPokeAt); | |
276 return parameter_; | |
277 } | |
278 | |
279 | |
280 bool OutputFrameStateCombine::IsOutputIgnored() { | |
281 return kind() == kPushOutput && GetPushCount() == 0; | |
282 } | |
283 | |
284 } // namespace compiler | 256 } // namespace compiler |
285 } // namespace internal | 257 } // namespace internal |
286 } // namespace v8 | 258 } // namespace v8 |
OLD | NEW |