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/compiler/node.h" |
10 #include "src/compiler/opcodes.h" | 11 #include "src/compiler/opcodes.h" |
11 #include "src/compiler/operator.h" | 12 #include "src/compiler/operator.h" |
12 #include "src/handles-inl.h" | 13 #include "src/handles-inl.h" |
13 #include "src/zone/zone.h" | 14 #include "src/zone/zone.h" |
14 | 15 |
15 namespace v8 { | 16 namespace v8 { |
16 namespace internal { | 17 namespace internal { |
17 namespace compiler { | 18 namespace compiler { |
18 | 19 |
19 std::ostream& operator<<(std::ostream& os, BranchHint hint) { | 20 std::ostream& operator<<(std::ostream& os, BranchHint hint) { |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 | 165 |
165 size_t hash_value(RelocatablePtrConstantInfo const& p) { | 166 size_t hash_value(RelocatablePtrConstantInfo const& p) { |
166 return base::hash_combine(p.value(), p.rmode(), p.type()); | 167 return base::hash_combine(p.value(), p.rmode(), p.type()); |
167 } | 168 } |
168 | 169 |
169 std::ostream& operator<<(std::ostream& os, | 170 std::ostream& operator<<(std::ostream& os, |
170 RelocatablePtrConstantInfo const& p) { | 171 RelocatablePtrConstantInfo const& p) { |
171 return os << p.value() << "|" << p.rmode() << "|" << p.type(); | 172 return os << p.value() << "|" << p.rmode() << "|" << p.type(); |
172 } | 173 } |
173 | 174 |
| 175 SparseInputMask::InputIterator::InputIterator( |
| 176 SparseInputMask::BitMaskType bit_mask, Node* parent) |
| 177 : bit_mask_(bit_mask), parent_(parent), real_index_(0) { |
| 178 #if DEBUG |
| 179 if (bit_mask_ != SparseInputMask::kDenseBitMask) { |
| 180 DCHECK_EQ(base::bits::CountPopulation(bit_mask_) - |
| 181 base::bits::CountPopulation(kEndMarker), |
| 182 parent->InputCount()); |
| 183 } |
| 184 #endif |
| 185 } |
| 186 |
| 187 void SparseInputMask::InputIterator::Advance() { |
| 188 DCHECK(!IsEnd()); |
| 189 |
| 190 if (IsReal()) { |
| 191 ++real_index_; |
| 192 } |
| 193 bit_mask_ >>= 1; |
| 194 } |
| 195 |
| 196 Node* SparseInputMask::InputIterator::GetReal() const { |
| 197 DCHECK(IsReal()); |
| 198 return parent_->InputAt(real_index_); |
| 199 } |
| 200 |
| 201 bool SparseInputMask::InputIterator::IsReal() const { |
| 202 return bit_mask_ == SparseInputMask::kDenseBitMask || |
| 203 (bit_mask_ & kEntryMask); |
| 204 } |
| 205 |
| 206 bool SparseInputMask::InputIterator::IsEnd() const { |
| 207 return (bit_mask_ == kEndMarker) || |
| 208 (bit_mask_ == SparseInputMask::kDenseBitMask && |
| 209 real_index_ >= parent_->InputCount()); |
| 210 } |
| 211 |
| 212 int SparseInputMask::CountReal() const { |
| 213 DCHECK(!IsDense()); |
| 214 return base::bits::CountPopulation(bit_mask_) - |
| 215 base::bits::CountPopulation(kEndMarker); |
| 216 } |
| 217 |
| 218 SparseInputMask::InputIterator SparseInputMask::IterateOverInputs(Node* node) { |
| 219 DCHECK(IsDense() || CountReal() == node->InputCount()); |
| 220 return InputIterator(bit_mask_, node); |
| 221 } |
| 222 |
| 223 bool operator==(SparseInputMask const& lhs, SparseInputMask const& rhs) { |
| 224 return lhs.mask() == rhs.mask(); |
| 225 } |
| 226 |
| 227 bool operator!=(SparseInputMask const& lhs, SparseInputMask const& rhs) { |
| 228 return !(lhs == rhs); |
| 229 } |
| 230 |
| 231 size_t hash_value(SparseInputMask const& p) { |
| 232 return base::hash_value(p.mask()); |
| 233 } |
| 234 |
| 235 std::ostream& operator<<(std::ostream& os, SparseInputMask const& p) { |
| 236 if (p.IsDense()) { |
| 237 return os << "dense"; |
| 238 } else { |
| 239 SparseInputMask::BitMaskType mask = p.mask(); |
| 240 DCHECK_NE(mask, SparseInputMask::kDenseBitMask); |
| 241 |
| 242 os << "sparse:"; |
| 243 |
| 244 while (mask != SparseInputMask::kEndMarker) { |
| 245 if (mask & SparseInputMask::kEntryMask) { |
| 246 os << "^"; |
| 247 } else { |
| 248 os << "."; |
| 249 } |
| 250 mask >>= 1; |
| 251 } |
| 252 return os; |
| 253 } |
| 254 } |
| 255 |
| 256 bool operator==(TypedStateValueInfo const& lhs, |
| 257 TypedStateValueInfo const& rhs) { |
| 258 return lhs.machine_types() == rhs.machine_types() && |
| 259 lhs.sparse_input_mask() == rhs.sparse_input_mask(); |
| 260 } |
| 261 |
| 262 bool operator!=(TypedStateValueInfo const& lhs, |
| 263 TypedStateValueInfo const& rhs) { |
| 264 return !(lhs == rhs); |
| 265 } |
| 266 |
| 267 size_t hash_value(TypedStateValueInfo const& p) { |
| 268 return base::hash_combine(p.machine_types(), p.sparse_input_mask()); |
| 269 } |
| 270 |
| 271 std::ostream& operator<<(std::ostream& os, TypedStateValueInfo const& p) { |
| 272 return os << p.machine_types() << "|" << p.sparse_input_mask(); |
| 273 } |
| 274 |
174 size_t hash_value(RegionObservability observability) { | 275 size_t hash_value(RegionObservability observability) { |
175 return static_cast<size_t>(observability); | 276 return static_cast<size_t>(observability); |
176 } | 277 } |
177 | 278 |
178 std::ostream& operator<<(std::ostream& os, RegionObservability observability) { | 279 std::ostream& operator<<(std::ostream& os, RegionObservability observability) { |
179 switch (observability) { | 280 switch (observability) { |
180 case RegionObservability::kObservable: | 281 case RegionObservability::kObservable: |
181 return os << "observable"; | 282 return os << "observable"; |
182 case RegionObservability::kNotObservable: | 283 case RegionObservability::kNotObservable: |
183 return os << "not-observable"; | 284 return os << "not-observable"; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 } | 329 } |
229 UNREACHABLE(); | 330 UNREACHABLE(); |
230 return os; | 331 return os; |
231 } | 332 } |
232 | 333 |
233 OsrGuardType OsrGuardTypeOf(Operator const* op) { | 334 OsrGuardType OsrGuardTypeOf(Operator const* op) { |
234 DCHECK_EQ(IrOpcode::kOsrGuard, op->opcode()); | 335 DCHECK_EQ(IrOpcode::kOsrGuard, op->opcode()); |
235 return OpParameter<OsrGuardType>(op); | 336 return OpParameter<OsrGuardType>(op); |
236 } | 337 } |
237 | 338 |
| 339 SparseInputMask SparseInputMaskOf(Operator const* op) { |
| 340 DCHECK(op->opcode() == IrOpcode::kStateValues || |
| 341 op->opcode() == IrOpcode::kTypedStateValues); |
| 342 |
| 343 if (op->opcode() == IrOpcode::kTypedStateValues) { |
| 344 return OpParameter<TypedStateValueInfo>(op).sparse_input_mask(); |
| 345 } |
| 346 return OpParameter<SparseInputMask>(op); |
| 347 } |
| 348 |
238 ZoneVector<MachineType> const* MachineTypesOf(Operator const* op) { | 349 ZoneVector<MachineType> const* MachineTypesOf(Operator const* op) { |
239 DCHECK(op->opcode() == IrOpcode::kTypedObjectState || | 350 DCHECK(op->opcode() == IrOpcode::kTypedObjectState || |
240 op->opcode() == IrOpcode::kTypedStateValues); | 351 op->opcode() == IrOpcode::kTypedStateValues); |
| 352 |
| 353 if (op->opcode() == IrOpcode::kTypedStateValues) { |
| 354 return OpParameter<TypedStateValueInfo>(op).machine_types(); |
| 355 } |
241 return OpParameter<const ZoneVector<MachineType>*>(op); | 356 return OpParameter<const ZoneVector<MachineType>*>(op); |
242 } | 357 } |
243 | 358 |
244 #define CACHED_OP_LIST(V) \ | 359 #define CACHED_OP_LIST(V) \ |
245 V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \ | 360 V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \ |
246 V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ | 361 V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ |
247 V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ | 362 V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ |
248 V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ | 363 V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ |
249 V(IfException, Operator::kKontrol, 0, 1, 1, 1, 1, 1) \ | 364 V(IfException, Operator::kKontrol, 0, 1, 1, 1, 1, 1) \ |
250 V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ | 365 V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 "Projection", // name | 696 "Projection", // name |
582 1, 0, 1, 1, 0, 0, // counts, | 697 1, 0, 1, 1, 0, 0, // counts, |
583 kIndex) {} // parameter | 698 kIndex) {} // parameter |
584 }; | 699 }; |
585 #define CACHED_PROJECTION(index) \ | 700 #define CACHED_PROJECTION(index) \ |
586 ProjectionOperator<index> kProjection##index##Operator; | 701 ProjectionOperator<index> kProjection##index##Operator; |
587 CACHED_PROJECTION_LIST(CACHED_PROJECTION) | 702 CACHED_PROJECTION_LIST(CACHED_PROJECTION) |
588 #undef CACHED_PROJECTION | 703 #undef CACHED_PROJECTION |
589 | 704 |
590 template <int kInputCount> | 705 template <int kInputCount> |
591 struct StateValuesOperator final : public Operator { | 706 struct StateValuesOperator final : public Operator1<SparseInputMask> { |
592 StateValuesOperator() | 707 StateValuesOperator() |
593 : Operator( // -- | 708 : Operator1<SparseInputMask>( // -- |
594 IrOpcode::kStateValues, // opcode | 709 IrOpcode::kStateValues, // opcode |
595 Operator::kPure, // flags | 710 Operator::kPure, // flags |
596 "StateValues", // name | 711 "StateValues", // name |
597 kInputCount, 0, 0, 1, 0, 0) {} // counts | 712 kInputCount, 0, 0, 1, 0, 0, // counts |
| 713 SparseInputMask::Dense()) {} // parameter |
598 }; | 714 }; |
599 #define CACHED_STATE_VALUES(input_count) \ | 715 #define CACHED_STATE_VALUES(input_count) \ |
600 StateValuesOperator<input_count> kStateValues##input_count##Operator; | 716 StateValuesOperator<input_count> kStateValues##input_count##Operator; |
601 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES) | 717 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES) |
602 #undef CACHED_STATE_VALUES | 718 #undef CACHED_STATE_VALUES |
603 }; | 719 }; |
604 | 720 |
605 | 721 |
606 static base::LazyInstance<CommonOperatorGlobalCache>::type kCache = | 722 static base::LazyInstance<CommonOperatorGlobalCache>::type kCache = |
607 LAZY_INSTANCE_INITIALIZER; | 723 LAZY_INSTANCE_INITIALIZER; |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 switch (region_observability) { | 1109 switch (region_observability) { |
994 case RegionObservability::kObservable: | 1110 case RegionObservability::kObservable: |
995 return &cache_.kBeginRegionObservableOperator; | 1111 return &cache_.kBeginRegionObservableOperator; |
996 case RegionObservability::kNotObservable: | 1112 case RegionObservability::kNotObservable: |
997 return &cache_.kBeginRegionNotObservableOperator; | 1113 return &cache_.kBeginRegionNotObservableOperator; |
998 } | 1114 } |
999 UNREACHABLE(); | 1115 UNREACHABLE(); |
1000 return nullptr; | 1116 return nullptr; |
1001 } | 1117 } |
1002 | 1118 |
1003 const Operator* CommonOperatorBuilder::StateValues(int arguments) { | 1119 const Operator* CommonOperatorBuilder::StateValues(int arguments, |
1004 switch (arguments) { | 1120 SparseInputMask bitmask) { |
| 1121 if (bitmask.IsDense()) { |
| 1122 switch (arguments) { |
1005 #define CACHED_STATE_VALUES(arguments) \ | 1123 #define CACHED_STATE_VALUES(arguments) \ |
1006 case arguments: \ | 1124 case arguments: \ |
1007 return &cache_.kStateValues##arguments##Operator; | 1125 return &cache_.kStateValues##arguments##Operator; |
1008 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES) | 1126 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES) |
1009 #undef CACHED_STATE_VALUES | 1127 #undef CACHED_STATE_VALUES |
1010 default: | 1128 default: |
1011 break; | 1129 break; |
| 1130 } |
1012 } | 1131 } |
| 1132 |
| 1133 #if DEBUG |
| 1134 DCHECK(bitmask.IsDense() || bitmask.CountReal() == arguments); |
| 1135 #endif |
| 1136 |
1013 // Uncached. | 1137 // Uncached. |
1014 return new (zone()) Operator( // -- | 1138 return new (zone()) Operator1<SparseInputMask>( // -- |
1015 IrOpcode::kStateValues, Operator::kPure, // opcode | 1139 IrOpcode::kStateValues, Operator::kPure, // opcode |
1016 "StateValues", // name | 1140 "StateValues", // name |
1017 arguments, 0, 0, 1, 0, 0); // counts | 1141 arguments, 0, 0, 1, 0, 0, // counts |
| 1142 bitmask); // parameter |
1018 } | 1143 } |
1019 | 1144 |
1020 const Operator* CommonOperatorBuilder::TypedStateValues( | 1145 const Operator* CommonOperatorBuilder::TypedStateValues( |
1021 const ZoneVector<MachineType>* types) { | 1146 const ZoneVector<MachineType>* types, SparseInputMask bitmask) { |
1022 return new (zone()) Operator1<const ZoneVector<MachineType>*>( // -- | 1147 #if DEBUG |
1023 IrOpcode::kTypedStateValues, Operator::kPure, // opcode | 1148 DCHECK(bitmask.IsDense() || |
1024 "TypedStateValues", // name | 1149 bitmask.CountReal() == static_cast<int>(types->size())); |
1025 static_cast<int>(types->size()), 0, 0, 1, 0, 0, // counts | 1150 #endif |
1026 types); // parameter | 1151 |
| 1152 return new (zone()) Operator1<TypedStateValueInfo>( // -- |
| 1153 IrOpcode::kTypedStateValues, Operator::kPure, // opcode |
| 1154 "TypedStateValues", // name |
| 1155 static_cast<int>(types->size()), 0, 0, 1, 0, 0, // counts |
| 1156 TypedStateValueInfo(types, bitmask)); // parameters |
1027 } | 1157 } |
1028 | 1158 |
1029 const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots) { | 1159 const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots) { |
1030 return new (zone()) Operator1<int>( // -- | 1160 return new (zone()) Operator1<int>( // -- |
1031 IrOpcode::kObjectState, Operator::kPure, // opcode | 1161 IrOpcode::kObjectState, Operator::kPure, // opcode |
1032 "ObjectState", // name | 1162 "ObjectState", // name |
1033 pointer_slots, 0, 0, 1, 0, 0, // counts | 1163 pointer_slots, 0, 0, 1, 0, 0, // counts |
1034 pointer_slots); // parameter | 1164 pointer_slots); // parameter |
1035 } | 1165 } |
1036 | 1166 |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1173 CommonOperatorBuilder::CreateFrameStateFunctionInfo( | 1303 CommonOperatorBuilder::CreateFrameStateFunctionInfo( |
1174 FrameStateType type, int parameter_count, int local_count, | 1304 FrameStateType type, int parameter_count, int local_count, |
1175 Handle<SharedFunctionInfo> shared_info) { | 1305 Handle<SharedFunctionInfo> shared_info) { |
1176 return new (zone()->New(sizeof(FrameStateFunctionInfo))) | 1306 return new (zone()->New(sizeof(FrameStateFunctionInfo))) |
1177 FrameStateFunctionInfo(type, parameter_count, local_count, shared_info); | 1307 FrameStateFunctionInfo(type, parameter_count, local_count, shared_info); |
1178 } | 1308 } |
1179 | 1309 |
1180 } // namespace compiler | 1310 } // namespace compiler |
1181 } // namespace internal | 1311 } // namespace internal |
1182 } // namespace v8 | 1312 } // namespace v8 |
OLD | NEW |