 Chromium Code Reviews
 Chromium Code Reviews Issue 2509623002:
  [turbofan] Sparse representation for state values  (Closed)
    
  
    Issue 2509623002:
  [turbofan] Sparse representation for state values  (Closed) 
  | 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 |