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