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 #ifndef V8_COMPILER_COMMON_OPERATOR_H_ | 5 #ifndef V8_COMPILER_COMMON_OPERATOR_H_ |
6 #define V8_COMPILER_COMMON_OPERATOR_H_ | 6 #define V8_COMPILER_COMMON_OPERATOR_H_ |
7 | 7 |
8 #include "src/assembler.h" | 8 #include "src/assembler.h" |
9 #include "src/base/compiler-specific.h" | 9 #include "src/base/compiler-specific.h" |
10 #include "src/compiler/frame-states.h" | 10 #include "src/compiler/frame-states.h" |
11 #include "src/deoptimize-reason.h" | 11 #include "src/deoptimize-reason.h" |
12 #include "src/globals.h" | 12 #include "src/globals.h" |
13 #include "src/machine-type.h" | 13 #include "src/machine-type.h" |
14 #include "src/zone/zone-containers.h" | 14 #include "src/zone/zone-containers.h" |
15 | 15 |
16 namespace v8 { | 16 namespace v8 { |
17 namespace internal { | 17 namespace internal { |
18 namespace compiler { | 18 namespace compiler { |
19 | 19 |
20 // Forward declarations. | 20 // Forward declarations. |
21 class CallDescriptor; | 21 class CallDescriptor; |
22 struct CommonOperatorGlobalCache; | 22 struct CommonOperatorGlobalCache; |
23 class Operator; | 23 class Operator; |
24 class Type; | 24 class Type; |
25 class Node; | |
25 | 26 |
26 // Prediction hint for branches. | 27 // Prediction hint for branches. |
27 enum class BranchHint : uint8_t { kNone, kTrue, kFalse }; | 28 enum class BranchHint : uint8_t { kNone, kTrue, kFalse }; |
28 | 29 |
29 inline BranchHint NegateBranchHint(BranchHint hint) { | 30 inline BranchHint NegateBranchHint(BranchHint hint) { |
30 switch (hint) { | 31 switch (hint) { |
31 case BranchHint::kNone: | 32 case BranchHint::kNone: |
32 return hint; | 33 return hint; |
33 case BranchHint::kTrue: | 34 case BranchHint::kTrue: |
34 return BranchHint::kFalse; | 35 return BranchHint::kFalse; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
151 | 152 |
152 bool operator==(RelocatablePtrConstantInfo const& lhs, | 153 bool operator==(RelocatablePtrConstantInfo const& lhs, |
153 RelocatablePtrConstantInfo const& rhs); | 154 RelocatablePtrConstantInfo const& rhs); |
154 bool operator!=(RelocatablePtrConstantInfo const& lhs, | 155 bool operator!=(RelocatablePtrConstantInfo const& lhs, |
155 RelocatablePtrConstantInfo const& rhs); | 156 RelocatablePtrConstantInfo const& rhs); |
156 | 157 |
157 std::ostream& operator<<(std::ostream&, RelocatablePtrConstantInfo const&); | 158 std::ostream& operator<<(std::ostream&, RelocatablePtrConstantInfo const&); |
158 | 159 |
159 size_t hash_value(RelocatablePtrConstantInfo const& p); | 160 size_t hash_value(RelocatablePtrConstantInfo const& p); |
160 | 161 |
162 // Used to define a sparse set of inputs. This can be used to efficiently encode | |
163 // nodes that can have a lot of inputs, but where many inputs can have the same | |
164 // value. | |
165 // | |
166 // The sparse input mask has a bitmask specifying if the node's inputs are | |
167 // represented sparsely. If the bitmask value is 0, then the inputs are dense; | |
168 // otherwise, they should be interpreted as follows: | |
169 // | |
170 // * The bitmask represents which values are real, with 1 for real values | |
171 // and 0 for empty values. | |
172 // * The inputs to the node are the real values, in the order of the 1s from | |
173 // least- to most-significant. | |
174 // * The top bit of the bitmask is a guard indicating the end of the values, | |
175 // whether real or empty (and is not representative of a real input itself). | |
176 // This is used so that we don't have to additionally store a value count. | |
177 // | |
178 // So, for N 1s in the bitmask, there are N - 1 inputs into the node. | |
Jarin
2016/12/10 10:15:06
Perhaps move lines 166-178 to the actual mask fiel
Leszek Swirski
2016/12/13 14:35:16
Good idea, done.
| |
179 class SparseInputMask final { | |
180 public: | |
181 typedef uint32_t BitMaskType; | |
182 | |
183 // The mask representing a dense input set. | |
184 static const BitMaskType kDenseBitMask = 0x0; | |
185 // The bits representing the end of a sparse input set. | |
186 static const BitMaskType kEndMarker = 0x1; | |
187 // The mask for accessing a sparse input entry in the bitmask. | |
188 static const BitMaskType kEntryMask = 0x1; | |
189 | |
190 // The number of bits in the mask, minus one for the end marker. | |
191 static const int kMaxSparseInputs = (sizeof(BitMaskType) * kBitsPerByte - 1); | |
192 | |
193 // An iterator over a node's sparse inputs. | |
194 class InputIterator final { | |
195 public: | |
196 InputIterator() {} | |
197 InputIterator(BitMaskType bit_mask, Node* parent); | |
198 | |
199 Node* parent() const { return parent_; } | |
200 int real_index() const { return real_index_; } | |
201 | |
202 // Advance the iterator to the next sparse input. Only valid if the iterator | |
203 // has not reached the end. | |
204 void Advance(); | |
205 | |
206 // Get the current sparse input's real node value. Only valid if the | |
207 // current sparse input is real. | |
208 Node* GetReal() const; | |
209 | |
210 // Get the current sparse input, returning either a real input node if | |
211 // the current sparse input is real, or the given {empty_value} if the | |
212 // current sparse input is empty. | |
213 Node* Get(Node* empty_value) const { | |
214 return IsReal() ? GetReal() : empty_value; | |
215 } | |
216 | |
217 // True if the current sparse input is a real input node. | |
218 bool IsReal() const; | |
219 | |
220 // True if the current sparse input is an empty value. | |
221 bool IsEmpty() const { return !IsReal(); } | |
222 | |
223 // True if the iterator has reached the end of the sparse inputs. | |
224 bool IsEnd() const; | |
225 | |
226 private: | |
227 BitMaskType bit_mask_; | |
228 Node* parent_; | |
229 int real_index_; | |
230 }; | |
231 | |
232 explicit SparseInputMask(BitMaskType bit_mask) : bit_mask_(bit_mask) {} | |
233 | |
234 // Provides a SparseInputMask representing a dense input set. | |
235 static SparseInputMask Dense() { return SparseInputMask(kDenseBitMask); } | |
236 | |
237 BitMaskType mask() const { return bit_mask_; } | |
238 | |
239 bool IsDense() const { return bit_mask_ == SparseInputMask::kDenseBitMask; } | |
240 | |
241 // Counts how many real values are in the sparse array. Only valid for | |
242 // non-dense masks. | |
243 int CountReal() const; | |
244 | |
245 // Returns an iterator over the sparse inputs of {node}. | |
246 InputIterator IterateOverInputs(Node* node); | |
247 | |
248 private: | |
249 BitMaskType bit_mask_; | |
250 }; | |
251 | |
252 bool operator==(SparseInputMask const& lhs, SparseInputMask const& rhs); | |
253 bool operator!=(SparseInputMask const& lhs, SparseInputMask const& rhs); | |
254 | |
255 class TypedStateValueInfo final { | |
256 public: | |
257 TypedStateValueInfo(ZoneVector<MachineType> const* machine_types, | |
258 SparseInputMask sparse_input_mask) | |
259 : machine_types_(machine_types), sparse_input_mask_(sparse_input_mask) {} | |
260 | |
261 ZoneVector<MachineType> const* machine_types() const { | |
262 return machine_types_; | |
263 } | |
264 SparseInputMask sparse_input_mask() const { return sparse_input_mask_; } | |
265 | |
266 private: | |
267 ZoneVector<MachineType> const* machine_types_; | |
268 SparseInputMask sparse_input_mask_; | |
269 }; | |
270 | |
271 bool operator==(TypedStateValueInfo const& lhs, TypedStateValueInfo const& rhs); | |
272 bool operator!=(TypedStateValueInfo const& lhs, TypedStateValueInfo const& rhs); | |
273 | |
274 std::ostream& operator<<(std::ostream&, TypedStateValueInfo const&); | |
275 | |
276 size_t hash_value(TypedStateValueInfo const& p); | |
277 | |
161 // Used to mark a region (as identified by BeginRegion/FinishRegion) as either | 278 // Used to mark a region (as identified by BeginRegion/FinishRegion) as either |
162 // JavaScript-observable or not (i.e. allocations are not JavaScript observable | 279 // JavaScript-observable or not (i.e. allocations are not JavaScript observable |
163 // themselves, but transitioning stores are). | 280 // themselves, but transitioning stores are). |
164 enum class RegionObservability : uint8_t { kObservable, kNotObservable }; | 281 enum class RegionObservability : uint8_t { kObservable, kNotObservable }; |
165 | 282 |
166 size_t hash_value(RegionObservability); | 283 size_t hash_value(RegionObservability); |
167 | 284 |
168 std::ostream& operator<<(std::ostream&, RegionObservability); | 285 std::ostream& operator<<(std::ostream&, RegionObservability); |
169 | 286 |
170 RegionObservability RegionObservabilityOf(Operator const*) WARN_UNUSED_RESULT; | 287 RegionObservability RegionObservabilityOf(Operator const*) WARN_UNUSED_RESULT; |
171 | 288 |
172 std::ostream& operator<<(std::ostream& os, | 289 std::ostream& operator<<(std::ostream& os, |
173 const ZoneVector<MachineType>* types); | 290 const ZoneVector<MachineType>* types); |
174 | 291 |
175 Type* TypeGuardTypeOf(Operator const*) WARN_UNUSED_RESULT; | 292 Type* TypeGuardTypeOf(Operator const*) WARN_UNUSED_RESULT; |
176 | 293 |
177 int OsrValueIndexOf(Operator const*); | 294 int OsrValueIndexOf(Operator const*); |
178 | 295 |
179 enum class OsrGuardType { kUninitialized, kSignedSmall, kAny }; | 296 enum class OsrGuardType { kUninitialized, kSignedSmall, kAny }; |
180 size_t hash_value(OsrGuardType type); | 297 size_t hash_value(OsrGuardType type); |
181 std::ostream& operator<<(std::ostream&, OsrGuardType); | 298 std::ostream& operator<<(std::ostream&, OsrGuardType); |
182 OsrGuardType OsrGuardTypeOf(Operator const*); | 299 OsrGuardType OsrGuardTypeOf(Operator const*); |
183 | 300 |
301 SparseInputMask SparseInputMaskOf(Operator const*); | |
302 | |
184 ZoneVector<MachineType> const* MachineTypesOf(Operator const*) | 303 ZoneVector<MachineType> const* MachineTypesOf(Operator const*) |
185 WARN_UNUSED_RESULT; | 304 WARN_UNUSED_RESULT; |
186 | 305 |
187 // Interface for building common operators that can be used at any level of IR, | 306 // Interface for building common operators that can be used at any level of IR, |
188 // including JavaScript, mid-level, and low-level. | 307 // including JavaScript, mid-level, and low-level. |
189 class V8_EXPORT_PRIVATE CommonOperatorBuilder final | 308 class V8_EXPORT_PRIVATE CommonOperatorBuilder final |
190 : public NON_EXPORTED_BASE(ZoneObject) { | 309 : public NON_EXPORTED_BASE(ZoneObject) { |
191 public: | 310 public: |
192 explicit CommonOperatorBuilder(Zone* zone); | 311 explicit CommonOperatorBuilder(Zone* zone); |
193 | 312 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
236 const Operator* Phi(MachineRepresentation representation, | 355 const Operator* Phi(MachineRepresentation representation, |
237 int value_input_count); | 356 int value_input_count); |
238 const Operator* EffectPhi(int effect_input_count); | 357 const Operator* EffectPhi(int effect_input_count); |
239 const Operator* InductionVariablePhi(int value_input_count); | 358 const Operator* InductionVariablePhi(int value_input_count); |
240 const Operator* LoopExit(); | 359 const Operator* LoopExit(); |
241 const Operator* LoopExitValue(); | 360 const Operator* LoopExitValue(); |
242 const Operator* LoopExitEffect(); | 361 const Operator* LoopExitEffect(); |
243 const Operator* Checkpoint(); | 362 const Operator* Checkpoint(); |
244 const Operator* BeginRegion(RegionObservability); | 363 const Operator* BeginRegion(RegionObservability); |
245 const Operator* FinishRegion(); | 364 const Operator* FinishRegion(); |
246 const Operator* StateValues(int arguments); | 365 const Operator* StateValues(int arguments, SparseInputMask bitmask); |
247 const Operator* TypedStateValues(const ZoneVector<MachineType>* types); | 366 const Operator* TypedStateValues(const ZoneVector<MachineType>* types, |
367 SparseInputMask bitmask); | |
248 const Operator* ObjectState(int pointer_slots); | 368 const Operator* ObjectState(int pointer_slots); |
249 const Operator* TypedObjectState(const ZoneVector<MachineType>* types); | 369 const Operator* TypedObjectState(const ZoneVector<MachineType>* types); |
250 const Operator* FrameState(BailoutId bailout_id, | 370 const Operator* FrameState(BailoutId bailout_id, |
251 OutputFrameStateCombine state_combine, | 371 OutputFrameStateCombine state_combine, |
252 const FrameStateFunctionInfo* function_info); | 372 const FrameStateFunctionInfo* function_info); |
253 const Operator* Call(const CallDescriptor* descriptor); | 373 const Operator* Call(const CallDescriptor* descriptor); |
254 const Operator* TailCall(const CallDescriptor* descriptor); | 374 const Operator* TailCall(const CallDescriptor* descriptor); |
255 const Operator* Projection(size_t index); | 375 const Operator* Projection(size_t index); |
256 const Operator* Retain(); | 376 const Operator* Retain(); |
257 const Operator* TypeGuard(Type* type); | 377 const Operator* TypeGuard(Type* type); |
(...skipping 20 matching lines...) Expand all Loading... | |
278 Zone* const zone_; | 398 Zone* const zone_; |
279 | 399 |
280 DISALLOW_COPY_AND_ASSIGN(CommonOperatorBuilder); | 400 DISALLOW_COPY_AND_ASSIGN(CommonOperatorBuilder); |
281 }; | 401 }; |
282 | 402 |
283 } // namespace compiler | 403 } // namespace compiler |
284 } // namespace internal | 404 } // namespace internal |
285 } // namespace v8 | 405 } // namespace v8 |
286 | 406 |
287 #endif // V8_COMPILER_COMMON_OPERATOR_H_ | 407 #endif // V8_COMPILER_COMMON_OPERATOR_H_ |
OLD | NEW |