| 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/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 // 1. During propagation, the use info is used to inform the input node | 66 // 1. During propagation, the use info is used to inform the input node |
| 67 // about what part of the input is used (we call this truncation) and what | 67 // about what part of the input is used (we call this truncation) and what |
| 68 // is the preferred representation. | 68 // is the preferred representation. |
| 69 // | 69 // |
| 70 // 2. During lowering, the use info is used to properly convert the input | 70 // 2. During lowering, the use info is used to properly convert the input |
| 71 // to the preferred representation. The preferred representation might be | 71 // to the preferred representation. The preferred representation might be |
| 72 // insufficient to do the conversion (e.g. word32->float64 conv), so we also | 72 // insufficient to do the conversion (e.g. word32->float64 conv), so we also |
| 73 // need the signedness information to produce the correct value. | 73 // need the signedness information to produce the correct value. |
| 74 class UseInfo { | 74 class UseInfo { |
| 75 public: | 75 public: |
| 76 UseInfo(MachineType preferred, Truncation truncation) | 76 UseInfo(MachineRepresentation preferred, Truncation truncation) |
| 77 : preferred_(preferred), truncation_(truncation) { | 77 : preferred_(preferred), truncation_(truncation) {} |
| 78 DCHECK(preferred == (preferred & kRepMask)); | |
| 79 } | |
| 80 static UseInfo TruncatingWord32() { | 78 static UseInfo TruncatingWord32() { |
| 81 return UseInfo(kRepWord32, Truncation::Word32()); | 79 return UseInfo(MachineRepresentation::kWord32, Truncation::Word32()); |
| 82 } | 80 } |
| 83 static UseInfo TruncatingWord64() { | 81 static UseInfo TruncatingWord64() { |
| 84 return UseInfo(kRepWord64, Truncation::Word64()); | 82 return UseInfo(MachineRepresentation::kWord64, Truncation::Word64()); |
| 85 } | 83 } |
| 86 static UseInfo Bool() { return UseInfo(kRepBit, Truncation::Bool()); } | 84 static UseInfo Bool() { |
| 85 return UseInfo(MachineRepresentation::kBit, Truncation::Bool()); |
| 86 } |
| 87 static UseInfo Float32() { | 87 static UseInfo Float32() { |
| 88 return UseInfo(kRepFloat32, Truncation::Float32()); | 88 return UseInfo(MachineRepresentation::kFloat32, Truncation::Float32()); |
| 89 } | 89 } |
| 90 static UseInfo Float64() { | 90 static UseInfo Float64() { |
| 91 return UseInfo(kRepFloat64, Truncation::Float64()); | 91 return UseInfo(MachineRepresentation::kFloat64, Truncation::Float64()); |
| 92 } | 92 } |
| 93 static UseInfo PointerInt() { | 93 static UseInfo PointerInt() { |
| 94 return kPointerSize == 4 ? TruncatingWord32() : TruncatingWord64(); | 94 return kPointerSize == 4 ? TruncatingWord32() : TruncatingWord64(); |
| 95 } | 95 } |
| 96 static UseInfo AnyTagged() { return UseInfo(kRepTagged, Truncation::Any()); } | 96 static UseInfo AnyTagged() { |
| 97 return UseInfo(MachineRepresentation::kTagged, Truncation::Any()); |
| 98 } |
| 97 | 99 |
| 98 // Undetermined representation. | 100 // Undetermined representation. |
| 99 static UseInfo Any() { return UseInfo(kMachNone, Truncation::Any()); } | 101 static UseInfo Any() { |
| 100 static UseInfo None() { return UseInfo(kMachNone, Truncation::None()); } | 102 return UseInfo(MachineRepresentation::kNone, Truncation::Any()); |
| 103 } |
| 104 static UseInfo None() { |
| 105 return UseInfo(MachineRepresentation::kNone, Truncation::None()); |
| 106 } |
| 101 | 107 |
| 102 // Truncation to a representation that is smaller than the preferred | 108 // Truncation to a representation that is smaller than the preferred |
| 103 // one. | 109 // one. |
| 104 static UseInfo Float64TruncatingToWord32() { | 110 static UseInfo Float64TruncatingToWord32() { |
| 105 return UseInfo(kRepFloat64, Truncation::Word32()); | 111 return UseInfo(MachineRepresentation::kFloat64, Truncation::Word32()); |
| 106 } | 112 } |
| 107 static UseInfo Word64TruncatingToWord32() { | 113 static UseInfo Word64TruncatingToWord32() { |
| 108 return UseInfo(kRepWord64, Truncation::Word32()); | 114 return UseInfo(MachineRepresentation::kWord64, Truncation::Word32()); |
| 109 } | 115 } |
| 110 static UseInfo AnyTruncatingToBool() { | 116 static UseInfo AnyTruncatingToBool() { |
| 111 return UseInfo(kMachNone, Truncation::Bool()); | 117 return UseInfo(MachineRepresentation::kNone, Truncation::Bool()); |
| 112 } | 118 } |
| 113 | 119 |
| 114 MachineType preferred() const { return preferred_; } | 120 MachineRepresentation preferred() const { return preferred_; } |
| 115 Truncation truncation() const { return truncation_; } | 121 Truncation truncation() const { return truncation_; } |
| 116 | 122 |
| 117 private: | 123 private: |
| 118 MachineType preferred_; | 124 MachineRepresentation preferred_; |
| 119 Truncation truncation_; | 125 Truncation truncation_; |
| 120 }; | 126 }; |
| 121 | 127 |
| 122 | 128 |
| 123 UseInfo UseInfoFromMachineType(MachineType type) { | 129 UseInfo TruncatingUseInfoFromRepresentation(MachineRepresentation rep) { |
| 124 MachineTypeUnion rep = RepresentationOf(type); | 130 switch (rep) { |
| 125 DCHECK((rep & kTypeMask) == 0); | 131 case MachineRepresentation::kTagged: |
| 126 | 132 return UseInfo::AnyTagged(); |
| 127 if (rep & kRepTagged) return UseInfo::AnyTagged(); | 133 case MachineRepresentation::kFloat64: |
| 128 if (rep & kRepFloat64) { | |
| 129 DCHECK((rep & kRepWord64) == 0); | |
| 130 return UseInfo::Float64(); | 134 return UseInfo::Float64(); |
| 135 case MachineRepresentation::kFloat32: |
| 136 return UseInfo::Float32(); |
| 137 case MachineRepresentation::kWord64: |
| 138 return UseInfo::TruncatingWord64(); |
| 139 case MachineRepresentation::kWord8: |
| 140 case MachineRepresentation::kWord16: |
| 141 case MachineRepresentation::kWord32: |
| 142 return UseInfo::TruncatingWord32(); |
| 143 case MachineRepresentation::kBit: |
| 144 return UseInfo::Bool(); |
| 145 case MachineRepresentation::kNone: |
| 146 break; |
| 131 } | 147 } |
| 132 if (rep & kRepFloat32) { | 148 UNREACHABLE(); |
| 133 if (rep == kRepFloat32) return UseInfo::Float32(); | 149 return UseInfo::None(); |
| 134 return UseInfo::AnyTagged(); | |
| 135 } | |
| 136 if (rep & kRepWord64) { | |
| 137 return UseInfo::TruncatingWord64(); | |
| 138 } | |
| 139 if (rep & (kRepWord32 | kRepWord16 | kRepWord8)) { | |
| 140 CHECK(!(rep & kRepBit)); | |
| 141 return UseInfo::TruncatingWord32(); | |
| 142 } | |
| 143 DCHECK(rep & kRepBit); | |
| 144 return UseInfo::Bool(); | |
| 145 } | 150 } |
| 146 | 151 |
| 147 | 152 |
| 148 UseInfo UseInfoForBasePointer(const FieldAccess& access) { | 153 UseInfo UseInfoForBasePointer(const FieldAccess& access) { |
| 149 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); | 154 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); |
| 150 } | 155 } |
| 151 | 156 |
| 152 | 157 |
| 153 UseInfo UseInfoForBasePointer(const ElementAccess& access) { | 158 UseInfo UseInfoForBasePointer(const ElementAccess& access) { |
| 154 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); | 159 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); |
| 155 } | 160 } |
| 156 | 161 |
| 157 | 162 |
| 158 #ifdef DEBUG | 163 #ifdef DEBUG |
| 159 // Helpers for monotonicity checking. | 164 // Helpers for monotonicity checking. |
| 160 | 165 |
| 161 bool MachineTypeIsSubtype(MachineType t1, MachineType t2) { | 166 bool MachineTypeIsSubtype(MachineSemantic t1, MachineSemantic t2) { |
| 162 switch (t1) { | 167 switch (t1) { |
| 163 case kMachNone: | 168 case MachineSemantic::kNone: |
| 164 return true; | 169 return true; |
| 165 case kTypeBool: | 170 case MachineSemantic::kBool: |
| 166 return t2 == kTypeBool || t2 == kTypeNumber || t2 == kTypeAny; | 171 return t2 == MachineSemantic::kBool || t2 == MachineSemantic::kNumber || |
| 167 case kTypeInt32: | 172 t2 == MachineSemantic::kAny; |
| 168 return t2 == kTypeInt32 || t2 == kTypeNumber || t2 == kTypeAny; | 173 case MachineSemantic::kInt32: |
| 169 case kTypeUint32: | 174 return t2 == MachineSemantic::kInt32 || t2 == MachineSemantic::kNumber || |
| 170 return t2 == kTypeUint32 || t2 == kTypeNumber || t2 == kTypeAny; | 175 t2 == MachineSemantic::kAny; |
| 171 case kTypeInt64: | 176 case MachineSemantic::kUint32: |
| 172 return t2 == kTypeInt64; | 177 return t2 == MachineSemantic::kUint32 || t2 == MachineSemantic::kNumber || |
| 173 case kTypeUint64: | 178 t2 == MachineSemantic::kAny; |
| 174 return t2 == kTypeUint64; | 179 case MachineSemantic::kInt64: |
| 175 case kTypeNumber: | 180 return t2 == MachineSemantic::kInt64; |
| 176 return t2 == kTypeNumber || t2 == kTypeAny; | 181 case MachineSemantic::kUint64: |
| 177 case kTypeAny: | 182 return t2 == MachineSemantic::kUint64; |
| 178 return t2 == kTypeAny; | 183 case MachineSemantic::kNumber: |
| 184 return t2 == MachineSemantic::kNumber || t2 == MachineSemantic::kAny; |
| 185 case MachineSemantic::kAny: |
| 186 return t2 == MachineSemantic::kAny; |
| 179 default: | 187 default: |
| 180 break; | 188 break; |
| 181 } | 189 } |
| 182 UNREACHABLE(); | 190 UNREACHABLE(); |
| 183 return false; | 191 return false; |
| 184 } | 192 } |
| 185 | 193 |
| 186 | 194 |
| 187 bool MachineRepresentationIsSubtype(MachineType r1, MachineType r2) { | 195 bool MachineRepresentationIsSubtype(MachineRepresentation r1, |
| 196 MachineRepresentation r2) { |
| 188 switch (r1) { | 197 switch (r1) { |
| 189 case kMachNone: | 198 case MachineRepresentation::kNone: |
| 190 return true; | 199 return true; |
| 191 case kRepBit: | 200 case MachineRepresentation::kBit: |
| 192 return r2 == kRepBit || r2 == kRepTagged; | 201 return r2 == MachineRepresentation::kBit || |
| 193 case kRepWord8: | 202 r2 == MachineRepresentation::kTagged; |
| 194 return r2 == kRepWord8 || r2 == kRepWord16 || r2 == kRepWord32 || | 203 case MachineRepresentation::kWord8: |
| 195 r2 == kRepWord64 || r2 == kRepFloat32 || r2 == kRepFloat64 || | 204 return r2 == MachineRepresentation::kWord8 || |
| 196 r2 == kRepTagged; | 205 r2 == MachineRepresentation::kWord16 || |
| 197 case kRepWord16: | 206 r2 == MachineRepresentation::kWord32 || |
| 198 return r2 == kRepWord16 || r2 == kRepWord32 || r2 == kRepWord64 || | 207 r2 == MachineRepresentation::kWord64 || |
| 199 r2 == kRepFloat32 || r2 == kRepFloat64 || r2 == kRepTagged; | 208 r2 == MachineRepresentation::kFloat32 || |
| 200 case kRepWord32: | 209 r2 == MachineRepresentation::kFloat64 || |
| 201 return r2 == kRepWord32 || r2 == kRepWord64 || r2 == kRepFloat64 || | 210 r2 == MachineRepresentation::kTagged; |
| 202 r2 == kRepTagged; | 211 case MachineRepresentation::kWord16: |
| 203 case kRepWord64: | 212 return r2 == MachineRepresentation::kWord16 || |
| 204 return r2 == kRepWord64; | 213 r2 == MachineRepresentation::kWord32 || |
| 205 case kRepFloat32: | 214 r2 == MachineRepresentation::kWord64 || |
| 206 return r2 == kRepFloat32 || r2 == kRepFloat64 || r2 == kRepTagged; | 215 r2 == MachineRepresentation::kFloat32 || |
| 207 case kRepFloat64: | 216 r2 == MachineRepresentation::kFloat64 || |
| 208 return r2 == kRepFloat64 || r2 == kRepTagged; | 217 r2 == MachineRepresentation::kTagged; |
| 209 case kRepTagged: | 218 case MachineRepresentation::kWord32: |
| 210 return r2 == kRepTagged; | 219 return r2 == MachineRepresentation::kWord32 || |
| 220 r2 == MachineRepresentation::kWord64 || |
| 221 r2 == MachineRepresentation::kFloat64 || |
| 222 r2 == MachineRepresentation::kTagged; |
| 223 case MachineRepresentation::kWord64: |
| 224 return r2 == MachineRepresentation::kWord64; |
| 225 case MachineRepresentation::kFloat32: |
| 226 return r2 == MachineRepresentation::kFloat32 || |
| 227 r2 == MachineRepresentation::kFloat64 || |
| 228 r2 == MachineRepresentation::kTagged; |
| 229 case MachineRepresentation::kFloat64: |
| 230 return r2 == MachineRepresentation::kFloat64 || |
| 231 r2 == MachineRepresentation::kTagged; |
| 232 case MachineRepresentation::kTagged: |
| 233 return r2 == MachineRepresentation::kTagged; |
| 211 default: | 234 default: |
| 212 break; | 235 break; |
| 213 } | 236 } |
| 214 UNREACHABLE(); | 237 UNREACHABLE(); |
| 215 return false; | 238 return false; |
| 216 } | 239 } |
| 217 | 240 |
| 218 | 241 |
| 219 bool MachineTypeRepIsSubtype(MachineTypeUnion m1, MachineTypeUnion m2) { | 242 bool MachineTypeRepIsSubtype(MachineType m1, MachineType m2) { |
| 220 return MachineTypeIsSubtype(static_cast<MachineType>(m1 & kTypeMask), | 243 return MachineTypeIsSubtype(m1.semantic(), m2.semantic()) && |
| 221 static_cast<MachineType>(m2 & kTypeMask)) && | 244 MachineRepresentationIsSubtype(m1.representation(), |
| 222 MachineRepresentationIsSubtype( | 245 m2.representation()); |
| 223 static_cast<MachineType>(m1 & kRepMask), | |
| 224 static_cast<MachineType>(m2 & kRepMask)); | |
| 225 } | 246 } |
| 226 | 247 |
| 227 | 248 |
| 228 class InputUseInfos { | 249 class InputUseInfos { |
| 229 public: | 250 public: |
| 230 explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {} | 251 explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {} |
| 231 | 252 |
| 232 void SetAndCheckInput(Node* node, int index, UseInfo use_info) { | 253 void SetAndCheckInput(Node* node, int index, UseInfo use_info) { |
| 233 if (input_use_infos_.empty()) { | 254 if (input_use_infos_.empty()) { |
| 234 input_use_infos_.resize(node->InputCount(), UseInfo::None()); | 255 input_use_infos_.resize(node->InputCount(), UseInfo::None()); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 264 Truncation old_truncation = truncation_; | 285 Truncation old_truncation = truncation_; |
| 265 truncation_ = Truncation::Generalize(truncation_, info.truncation()); | 286 truncation_ = Truncation::Generalize(truncation_, info.truncation()); |
| 266 return truncation_ != old_truncation; | 287 return truncation_ != old_truncation; |
| 267 } | 288 } |
| 268 | 289 |
| 269 void set_queued(bool value) { queued_ = value; } | 290 void set_queued(bool value) { queued_ = value; } |
| 270 bool queued() const { return queued_; } | 291 bool queued() const { return queued_; } |
| 271 void set_visited() { visited_ = true; } | 292 void set_visited() { visited_ = true; } |
| 272 bool visited() const { return visited_; } | 293 bool visited() const { return visited_; } |
| 273 Truncation truncation() const { return truncation_; } | 294 Truncation truncation() const { return truncation_; } |
| 274 void set_output_type(MachineTypeUnion type) { output_ = type; } | 295 void set_output_type(MachineType type) { output_ = type; } |
| 275 MachineTypeUnion output_type() const { return output_; } | 296 MachineType output_type() const { return output_; } |
| 276 | 297 |
| 277 private: | 298 private: |
| 278 bool queued_ = false; // Bookkeeping for the traversal. | 299 bool queued_ = false; // Bookkeeping for the traversal. |
| 279 bool visited_ = false; // Bookkeeping for the traversal. | 300 bool visited_ = false; // Bookkeeping for the traversal. |
| 280 MachineTypeUnion output_ = kMachNone; // Output type of the node. | 301 MachineType output_ = MachineType::None(); // Output type of the node. |
| 281 Truncation truncation_ = Truncation::None(); // Information about uses. | 302 Truncation truncation_ = Truncation::None(); // Information about uses. |
| 282 }; | 303 }; |
| 283 | 304 |
| 284 RepresentationSelector(JSGraph* jsgraph, Zone* zone, | 305 RepresentationSelector(JSGraph* jsgraph, Zone* zone, |
| 285 RepresentationChanger* changer, | 306 RepresentationChanger* changer, |
| 286 SourcePositionTable* source_positions) | 307 SourcePositionTable* source_positions) |
| 287 : jsgraph_(jsgraph), | 308 : jsgraph_(jsgraph), |
| 288 count_(jsgraph->graph()->NodeCount()), | 309 count_(jsgraph->graph()->NodeCount()), |
| 289 info_(count_, zone), | 310 info_(count_, zone), |
| 290 #ifdef DEBUG | 311 #ifdef DEBUG |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 TRACE(" added: "); | 408 TRACE(" added: "); |
| 388 } else { | 409 } else { |
| 389 TRACE(" inqueue: "); | 410 TRACE(" inqueue: "); |
| 390 } | 411 } |
| 391 PrintTruncation(info->truncation()); | 412 PrintTruncation(info->truncation()); |
| 392 } | 413 } |
| 393 } | 414 } |
| 394 | 415 |
| 395 bool lower() { return phase_ == LOWER; } | 416 bool lower() { return phase_ == LOWER; } |
| 396 | 417 |
| 397 void SetOutput(Node* node, MachineTypeUnion output) { | 418 void SetOutput(Node* node, MachineType output) { |
| 398 // Every node should have at most one output representation. Note that | 419 // Every node should have at most one output representation. Note that |
| 399 // phis can have 0, if they have not been used in a representation-inducing | 420 // phis can have 0, if they have not been used in a representation-inducing |
| 400 // instruction. | 421 // instruction. |
| 401 DCHECK((output & kRepMask) == 0 || | |
| 402 base::bits::IsPowerOfTwo32(output & kRepMask)); | |
| 403 NodeInfo* info = GetInfo(node); | 422 NodeInfo* info = GetInfo(node); |
| 404 DCHECK(MachineTypeRepIsSubtype(info->output_type(), output)); | 423 DCHECK(MachineTypeRepIsSubtype(info->output_type(), output)); |
| 405 info->set_output_type(output); | 424 info->set_output_type(output); |
| 406 } | 425 } |
| 407 | 426 |
| 408 bool BothInputsAre(Node* node, Type* type) { | 427 bool BothInputsAre(Node* node, Type* type) { |
| 409 DCHECK_EQ(2, node->InputCount()); | 428 DCHECK_EQ(2, node->InputCount()); |
| 410 return NodeProperties::GetType(node->InputAt(0))->Is(type) && | 429 return NodeProperties::GetType(node->InputAt(0))->Is(type) && |
| 411 NodeProperties::GetType(node->InputAt(1))->Is(type); | 430 NodeProperties::GetType(node->InputAt(1))->Is(type); |
| 412 } | 431 } |
| 413 | 432 |
| 414 void ConvertInput(Node* node, int index, UseInfo use) { | 433 void ConvertInput(Node* node, int index, UseInfo use) { |
| 415 Node* input = node->InputAt(index); | 434 Node* input = node->InputAt(index); |
| 416 // In the change phase, insert a change before the use if necessary. | 435 // In the change phase, insert a change before the use if necessary. |
| 417 if (use.preferred() == kMachNone) | 436 if (use.preferred() == MachineRepresentation::kNone) |
| 418 return; // No input requirement on the use. | 437 return; // No input requirement on the use. |
| 419 MachineTypeUnion output = GetInfo(input)->output_type(); | 438 MachineType output = GetInfo(input)->output_type(); |
| 420 if ((output & kRepMask) != use.preferred()) { | 439 if (output.representation() != use.preferred()) { |
| 421 // Output representation doesn't match usage. | 440 // Output representation doesn't match usage. |
| 422 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), | 441 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), |
| 423 index, input->id(), input->op()->mnemonic()); | 442 index, input->id(), input->op()->mnemonic()); |
| 424 TRACE(" from "); | 443 TRACE(" from "); |
| 425 PrintInfo(output); | 444 PrintInfo(output); |
| 426 TRACE(" to "); | 445 TRACE(" to "); |
| 427 PrintUseInfo(use); | 446 PrintUseInfo(use); |
| 428 TRACE("\n"); | 447 TRACE("\n"); |
| 429 Node* n = changer_->GetRepresentationFor(input, output, use.preferred(), | 448 Node* n = changer_->GetRepresentationFor(input, output, use.preferred(), |
| 430 use.truncation()); | 449 use.truncation()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 ProcessInput(node, i, UseInfo::AnyTagged()); | 484 ProcessInput(node, i, UseInfo::AnyTagged()); |
| 466 } | 485 } |
| 467 // Only enqueue other inputs (framestates, effects, control). | 486 // Only enqueue other inputs (framestates, effects, control). |
| 468 for (int i = tagged_count; i < node->InputCount(); i++) { | 487 for (int i = tagged_count; i < node->InputCount(); i++) { |
| 469 EnqueueInput(node, i); | 488 EnqueueInput(node, i); |
| 470 } | 489 } |
| 471 } | 490 } |
| 472 | 491 |
| 473 // Helper for binops of the R x L -> O variety. | 492 // Helper for binops of the R x L -> O variety. |
| 474 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, | 493 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, |
| 475 MachineTypeUnion output) { | 494 MachineType output) { |
| 476 DCHECK_EQ(2, node->op()->ValueInputCount()); | 495 DCHECK_EQ(2, node->op()->ValueInputCount()); |
| 477 ProcessInput(node, 0, left_use); | 496 ProcessInput(node, 0, left_use); |
| 478 ProcessInput(node, 1, right_use); | 497 ProcessInput(node, 1, right_use); |
| 479 for (int i = 2; i < node->InputCount(); i++) { | 498 for (int i = 2; i < node->InputCount(); i++) { |
| 480 EnqueueInput(node, i); | 499 EnqueueInput(node, i); |
| 481 } | 500 } |
| 482 SetOutput(node, output); | 501 SetOutput(node, output); |
| 483 } | 502 } |
| 484 | 503 |
| 485 // Helper for binops of the I x I -> O variety. | 504 // Helper for binops of the I x I -> O variety. |
| 486 void VisitBinop(Node* node, UseInfo input_use, MachineTypeUnion output) { | 505 void VisitBinop(Node* node, UseInfo input_use, MachineType output) { |
| 487 VisitBinop(node, input_use, input_use, output); | 506 VisitBinop(node, input_use, input_use, output); |
| 488 } | 507 } |
| 489 | 508 |
| 490 // Helper for unops of the I -> O variety. | 509 // Helper for unops of the I -> O variety. |
| 491 void VisitUnop(Node* node, UseInfo input_use, MachineTypeUnion output) { | 510 void VisitUnop(Node* node, UseInfo input_use, MachineType output) { |
| 492 DCHECK_EQ(1, node->InputCount()); | 511 DCHECK_EQ(1, node->InputCount()); |
| 493 ProcessInput(node, 0, input_use); | 512 ProcessInput(node, 0, input_use); |
| 494 SetOutput(node, output); | 513 SetOutput(node, output); |
| 495 } | 514 } |
| 496 | 515 |
| 497 // Helper for leaf nodes. | 516 // Helper for leaf nodes. |
| 498 void VisitLeaf(Node* node, MachineTypeUnion output) { | 517 void VisitLeaf(Node* node, MachineType output) { |
| 499 DCHECK_EQ(0, node->InputCount()); | 518 DCHECK_EQ(0, node->InputCount()); |
| 500 SetOutput(node, output); | 519 SetOutput(node, output); |
| 501 } | 520 } |
| 502 | 521 |
| 503 // Helpers for specific types of binops. | 522 // Helpers for specific types of binops. |
| 504 void VisitFloat64Binop(Node* node) { | 523 void VisitFloat64Binop(Node* node) { |
| 505 VisitBinop(node, UseInfo::Float64(), kMachFloat64); | 524 VisitBinop(node, UseInfo::Float64(), MachineType::Float64()); |
| 506 } | 525 } |
| 507 void VisitInt32Binop(Node* node) { | 526 void VisitInt32Binop(Node* node) { |
| 508 VisitBinop(node, UseInfo::TruncatingWord32(), kMachInt32); | 527 VisitBinop(node, UseInfo::TruncatingWord32(), MachineType::Int32()); |
| 509 } | 528 } |
| 510 void VisitUint32Binop(Node* node) { | 529 void VisitUint32Binop(Node* node) { |
| 511 VisitBinop(node, UseInfo::TruncatingWord32(), kMachUint32); | 530 VisitBinop(node, UseInfo::TruncatingWord32(), MachineType::Uint32()); |
| 512 } | 531 } |
| 513 void VisitInt64Binop(Node* node) { | 532 void VisitInt64Binop(Node* node) { |
| 514 VisitBinop(node, UseInfo::TruncatingWord64(), kMachInt64); | 533 VisitBinop(node, UseInfo::TruncatingWord64(), MachineType::Int64()); |
| 515 } | 534 } |
| 516 void VisitUint64Binop(Node* node) { | 535 void VisitUint64Binop(Node* node) { |
| 517 VisitBinop(node, UseInfo::TruncatingWord64(), kMachUint64); | 536 VisitBinop(node, UseInfo::TruncatingWord64(), MachineType::Uint64()); |
| 518 } | 537 } |
| 519 void VisitFloat64Cmp(Node* node) { | 538 void VisitFloat64Cmp(Node* node) { |
| 520 VisitBinop(node, UseInfo::Float64(), kMachBool); | 539 VisitBinop(node, UseInfo::Float64(), MachineType::Bool()); |
| 521 } | 540 } |
| 522 void VisitInt32Cmp(Node* node) { | 541 void VisitInt32Cmp(Node* node) { |
| 523 VisitBinop(node, UseInfo::TruncatingWord32(), kMachBool); | 542 VisitBinop(node, UseInfo::TruncatingWord32(), MachineType::Bool()); |
| 524 } | 543 } |
| 525 void VisitUint32Cmp(Node* node) { | 544 void VisitUint32Cmp(Node* node) { |
| 526 VisitBinop(node, UseInfo::TruncatingWord32(), kMachBool); | 545 VisitBinop(node, UseInfo::TruncatingWord32(), MachineType::Bool()); |
| 527 } | 546 } |
| 528 void VisitInt64Cmp(Node* node) { | 547 void VisitInt64Cmp(Node* node) { |
| 529 VisitBinop(node, UseInfo::TruncatingWord64(), kMachBool); | 548 VisitBinop(node, UseInfo::TruncatingWord64(), MachineType::Bool()); |
| 530 } | 549 } |
| 531 void VisitUint64Cmp(Node* node) { | 550 void VisitUint64Cmp(Node* node) { |
| 532 VisitBinop(node, UseInfo::TruncatingWord64(), kMachBool); | 551 VisitBinop(node, UseInfo::TruncatingWord64(), MachineType::Bool()); |
| 533 } | 552 } |
| 534 | 553 |
| 535 // Infer representation for phi-like nodes. | 554 // Infer representation for phi-like nodes. |
| 536 static MachineType GetRepresentationForPhi(Node* node, Truncation use) { | 555 static MachineRepresentation GetRepresentationForPhi(Node* node, |
| 556 Truncation use) { |
| 537 // Phis adapt to the output representation their uses demand. | 557 // Phis adapt to the output representation their uses demand. |
| 538 Type* upper = NodeProperties::GetType(node); | 558 Type* upper = NodeProperties::GetType(node); |
| 539 if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) { | 559 if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) { |
| 540 // We are within 32 bits range => pick kRepWord32. | 560 // We are within 32 bits range => pick kRepWord32. |
| 541 return kRepWord32; | 561 return MachineRepresentation::kWord32; |
| 542 } else if (use.TruncatesToWord32()) { | 562 } else if (use.TruncatesToWord32()) { |
| 543 // We only use 32 bits. | 563 // We only use 32 bits. |
| 544 return kRepWord32; | 564 return MachineRepresentation::kWord32; |
| 545 } else if (upper->Is(Type::Boolean())) { | 565 } else if (upper->Is(Type::Boolean())) { |
| 546 // multiple uses => pick kRepBit. | 566 // multiple uses => pick kRepBit. |
| 547 return kRepBit; | 567 return MachineRepresentation::kBit; |
| 548 } else if (upper->Is(Type::Number())) { | 568 } else if (upper->Is(Type::Number())) { |
| 549 // multiple uses => pick kRepFloat64. | 569 // multiple uses => pick kRepFloat64. |
| 550 return kRepFloat64; | 570 return MachineRepresentation::kFloat64; |
| 551 } else if (upper->Is(Type::Internal())) { | 571 } else if (upper->Is(Type::Internal())) { |
| 552 return kMachPtr; | 572 return MachineType::PointerRepresentation(); |
| 553 } | 573 } |
| 554 return kRepTagged; | 574 return MachineRepresentation::kTagged; |
| 555 } | 575 } |
| 556 | 576 |
| 557 // Helper for handling selects. | 577 // Helper for handling selects. |
| 558 void VisitSelect(Node* node, Truncation truncation, | 578 void VisitSelect(Node* node, Truncation truncation, |
| 559 SimplifiedLowering* lowering) { | 579 SimplifiedLowering* lowering) { |
| 560 ProcessInput(node, 0, UseInfo::Bool()); | 580 ProcessInput(node, 0, UseInfo::Bool()); |
| 561 MachineType output = GetRepresentationForPhi(node, truncation); | 581 MachineRepresentation output = GetRepresentationForPhi(node, truncation); |
| 562 | 582 |
| 563 Type* upper = NodeProperties::GetType(node); | 583 Type* upper = NodeProperties::GetType(node); |
| 564 MachineType output_type = | 584 MachineType output_type = |
| 565 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); | 585 MachineType(output, changer_->TypeFromUpperBound(upper)); |
| 566 SetOutput(node, output_type); | 586 SetOutput(node, output_type); |
| 567 | 587 |
| 568 if (lower()) { | 588 if (lower()) { |
| 569 // Update the select operator. | 589 // Update the select operator. |
| 570 SelectParameters p = SelectParametersOf(node->op()); | 590 SelectParameters p = SelectParametersOf(node->op()); |
| 571 MachineType type = static_cast<MachineType>(output_type); | 591 if (output != p.representation()) { |
| 572 if (type != p.type()) { | |
| 573 NodeProperties::ChangeOp(node, | 592 NodeProperties::ChangeOp(node, |
| 574 lowering->common()->Select(type, p.hint())); | 593 lowering->common()->Select(output, p.hint())); |
| 575 } | 594 } |
| 576 } | 595 } |
| 577 // Convert inputs to the output representation of this phi, pass the | 596 // Convert inputs to the output representation of this phi, pass the |
| 578 // truncation truncation along. | 597 // truncation truncation along. |
| 579 UseInfo input_use(output, truncation); | 598 UseInfo input_use(output, truncation); |
| 580 ProcessInput(node, 1, input_use); | 599 ProcessInput(node, 1, input_use); |
| 581 ProcessInput(node, 2, input_use); | 600 ProcessInput(node, 2, input_use); |
| 582 } | 601 } |
| 583 | 602 |
| 584 // Helper for handling phis. | 603 // Helper for handling phis. |
| 585 void VisitPhi(Node* node, Truncation truncation, | 604 void VisitPhi(Node* node, Truncation truncation, |
| 586 SimplifiedLowering* lowering) { | 605 SimplifiedLowering* lowering) { |
| 587 MachineType output = GetRepresentationForPhi(node, truncation); | 606 MachineRepresentation output = GetRepresentationForPhi(node, truncation); |
| 588 | 607 |
| 589 Type* upper = NodeProperties::GetType(node); | 608 Type* upper = NodeProperties::GetType(node); |
| 590 MachineType output_type = | 609 MachineType output_type = |
| 591 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); | 610 MachineType(output, changer_->TypeFromUpperBound(upper)); |
| 592 SetOutput(node, output_type); | 611 SetOutput(node, output_type); |
| 593 | 612 |
| 594 int values = node->op()->ValueInputCount(); | 613 int values = node->op()->ValueInputCount(); |
| 595 | 614 |
| 596 if (lower()) { | 615 if (lower()) { |
| 597 // Update the phi operator. | 616 // Update the phi operator. |
| 598 MachineType type = static_cast<MachineType>(output_type); | 617 if (output != PhiRepresentationOf(node->op())) { |
| 599 if (type != OpParameter<MachineType>(node)) { | 618 NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values)); |
| 600 NodeProperties::ChangeOp(node, lowering->common()->Phi(type, values)); | |
| 601 } | 619 } |
| 602 } | 620 } |
| 603 | 621 |
| 604 // Convert inputs to the output representation of this phi, pass the | 622 // Convert inputs to the output representation of this phi, pass the |
| 605 // truncation truncation along. | 623 // truncation truncation along. |
| 606 UseInfo input_use(output, truncation); | 624 UseInfo input_use(output, truncation); |
| 607 for (int i = 0; i < node->InputCount(); i++) { | 625 for (int i = 0; i < node->InputCount(); i++) { |
| 608 ProcessInput(node, i, i < values ? input_use : UseInfo::None()); | 626 ProcessInput(node, i, i < values ? input_use : UseInfo::None()); |
| 609 } | 627 } |
| 610 } | 628 } |
| 611 | 629 |
| 612 void VisitCall(Node* node, SimplifiedLowering* lowering) { | 630 void VisitCall(Node* node, SimplifiedLowering* lowering) { |
| 613 const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op()); | 631 const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op()); |
| 614 const MachineSignature* sig = desc->GetMachineSignature(); | 632 const MachineSignature* sig = desc->GetMachineSignature(); |
| 615 int params = static_cast<int>(sig->parameter_count()); | 633 int params = static_cast<int>(sig->parameter_count()); |
| 616 // Propagate representation information from call descriptor. | 634 // Propagate representation information from call descriptor. |
| 617 for (int i = 0; i < node->InputCount(); i++) { | 635 for (int i = 0; i < node->InputCount(); i++) { |
| 618 if (i == 0) { | 636 if (i == 0) { |
| 619 // The target of the call. | 637 // The target of the call. |
| 620 ProcessInput(node, i, UseInfo::None()); | 638 ProcessInput(node, i, UseInfo::None()); |
| 621 } else if ((i - 1) < params) { | 639 } else if ((i - 1) < params) { |
| 622 ProcessInput(node, i, UseInfoFromMachineType(sig->GetParam(i - 1))); | 640 ProcessInput(node, i, TruncatingUseInfoFromRepresentation( |
| 641 sig->GetParam(i - 1).representation())); |
| 623 } else { | 642 } else { |
| 624 ProcessInput(node, i, UseInfo::None()); | 643 ProcessInput(node, i, UseInfo::None()); |
| 625 } | 644 } |
| 626 } | 645 } |
| 627 | 646 |
| 628 if (sig->return_count() > 0) { | 647 if (sig->return_count() > 0) { |
| 629 SetOutput(node, desc->GetMachineSignature()->GetReturn()); | 648 SetOutput(node, desc->GetMachineSignature()->GetReturn()); |
| 630 } else { | 649 } else { |
| 631 SetOutput(node, kMachAnyTagged); | 650 SetOutput(node, MachineType::AnyTagged()); |
| 632 } | 651 } |
| 633 } | 652 } |
| 634 | 653 |
| 635 void VisitStateValues(Node* node) { | 654 void VisitStateValues(Node* node) { |
| 636 if (phase_ == PROPAGATE) { | 655 if (phase_ == PROPAGATE) { |
| 637 for (int i = 0; i < node->InputCount(); i++) { | 656 for (int i = 0; i < node->InputCount(); i++) { |
| 638 EnqueueInput(node, i, UseInfo::Any()); | 657 EnqueueInput(node, i, UseInfo::Any()); |
| 639 } | 658 } |
| 640 } else { | 659 } else { |
| 641 Zone* zone = jsgraph_->zone(); | 660 Zone* zone = jsgraph_->zone(); |
| 642 ZoneVector<MachineType>* types = | 661 ZoneVector<MachineType>* types = |
| 643 new (zone->New(sizeof(ZoneVector<MachineType>))) | 662 new (zone->New(sizeof(ZoneVector<MachineType>))) |
| 644 ZoneVector<MachineType>(node->InputCount(), zone); | 663 ZoneVector<MachineType>(node->InputCount(), zone); |
| 645 for (int i = 0; i < node->InputCount(); i++) { | 664 for (int i = 0; i < node->InputCount(); i++) { |
| 646 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output_type(); | 665 MachineType input_type = GetInfo(node->InputAt(i))->output_type(); |
| 647 (*types)[i] = static_cast<MachineType>(input_type); | 666 (*types)[i] = input_type; |
| 648 } | 667 } |
| 649 NodeProperties::ChangeOp(node, | 668 NodeProperties::ChangeOp(node, |
| 650 jsgraph_->common()->TypedStateValues(types)); | 669 jsgraph_->common()->TypedStateValues(types)); |
| 651 } | 670 } |
| 652 SetOutput(node, kMachAnyTagged); | 671 SetOutput(node, MachineType::AnyTagged()); |
| 653 } | 672 } |
| 654 | 673 |
| 655 const Operator* Int32Op(Node* node) { | 674 const Operator* Int32Op(Node* node) { |
| 656 return changer_->Int32OperatorFor(node->opcode()); | 675 return changer_->Int32OperatorFor(node->opcode()); |
| 657 } | 676 } |
| 658 | 677 |
| 659 const Operator* Uint32Op(Node* node) { | 678 const Operator* Uint32Op(Node* node) { |
| 660 return changer_->Uint32OperatorFor(node->opcode()); | 679 return changer_->Uint32OperatorFor(node->opcode()); |
| 661 } | 680 } |
| 662 | 681 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 693 // Dispatching routine for visiting the node {node} with the usage {use}. | 712 // Dispatching routine for visiting the node {node} with the usage {use}. |
| 694 // Depending on the operator, propagate new usage info to the inputs. | 713 // Depending on the operator, propagate new usage info to the inputs. |
| 695 void VisitNode(Node* node, Truncation truncation, | 714 void VisitNode(Node* node, Truncation truncation, |
| 696 SimplifiedLowering* lowering) { | 715 SimplifiedLowering* lowering) { |
| 697 switch (node->opcode()) { | 716 switch (node->opcode()) { |
| 698 //------------------------------------------------------------------ | 717 //------------------------------------------------------------------ |
| 699 // Common operators. | 718 // Common operators. |
| 700 //------------------------------------------------------------------ | 719 //------------------------------------------------------------------ |
| 701 case IrOpcode::kStart: | 720 case IrOpcode::kStart: |
| 702 case IrOpcode::kDead: | 721 case IrOpcode::kDead: |
| 703 return VisitLeaf(node, 0); | 722 return VisitLeaf(node, MachineType::None()); |
| 704 case IrOpcode::kParameter: { | 723 case IrOpcode::kParameter: { |
| 705 // TODO(titzer): use representation from linkage. | 724 // TODO(titzer): use representation from linkage. |
| 706 Type* upper = NodeProperties::GetType(node); | 725 Type* upper = NodeProperties::GetType(node); |
| 707 ProcessInput(node, 0, UseInfo::None()); | 726 ProcessInput(node, 0, UseInfo::None()); |
| 708 SetOutput(node, kRepTagged | changer_->TypeFromUpperBound(upper)); | 727 SetOutput(node, MachineType(MachineRepresentation::kTagged, |
| 728 changer_->TypeFromUpperBound(upper))); |
| 709 return; | 729 return; |
| 710 } | 730 } |
| 711 case IrOpcode::kInt32Constant: | 731 case IrOpcode::kInt32Constant: |
| 712 return VisitLeaf(node, kRepWord32); | 732 return VisitLeaf(node, MachineType::RepWord32()); |
| 713 case IrOpcode::kInt64Constant: | 733 case IrOpcode::kInt64Constant: |
| 714 return VisitLeaf(node, kRepWord64); | 734 return VisitLeaf(node, MachineType::RepWord64()); |
| 715 case IrOpcode::kFloat32Constant: | 735 case IrOpcode::kFloat32Constant: |
| 716 return VisitLeaf(node, kRepFloat32); | 736 return VisitLeaf(node, MachineType::RepFloat32()); |
| 717 case IrOpcode::kFloat64Constant: | 737 case IrOpcode::kFloat64Constant: |
| 718 return VisitLeaf(node, kRepFloat64); | 738 return VisitLeaf(node, MachineType::RepFloat64()); |
| 719 case IrOpcode::kExternalConstant: | 739 case IrOpcode::kExternalConstant: |
| 720 return VisitLeaf(node, kMachPtr); | 740 return VisitLeaf(node, MachineType::Pointer()); |
| 721 case IrOpcode::kNumberConstant: | 741 case IrOpcode::kNumberConstant: |
| 722 return VisitLeaf(node, kRepTagged); | 742 return VisitLeaf(node, MachineType::RepTagged()); |
| 723 case IrOpcode::kHeapConstant: | 743 case IrOpcode::kHeapConstant: |
| 724 return VisitLeaf(node, kRepTagged); | 744 return VisitLeaf(node, MachineType::RepTagged()); |
| 725 | 745 |
| 726 case IrOpcode::kBranch: | 746 case IrOpcode::kBranch: |
| 727 ProcessInput(node, 0, UseInfo::Bool()); | 747 ProcessInput(node, 0, UseInfo::Bool()); |
| 728 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); | 748 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); |
| 729 break; | 749 break; |
| 730 case IrOpcode::kSwitch: | 750 case IrOpcode::kSwitch: |
| 731 ProcessInput(node, 0, UseInfo::TruncatingWord32()); | 751 ProcessInput(node, 0, UseInfo::TruncatingWord32()); |
| 732 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); | 752 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); |
| 733 break; | 753 break; |
| 734 case IrOpcode::kSelect: | 754 case IrOpcode::kSelect: |
| 735 return VisitSelect(node, truncation, lowering); | 755 return VisitSelect(node, truncation, lowering); |
| 736 case IrOpcode::kPhi: | 756 case IrOpcode::kPhi: |
| 737 return VisitPhi(node, truncation, lowering); | 757 return VisitPhi(node, truncation, lowering); |
| 738 case IrOpcode::kCall: | 758 case IrOpcode::kCall: |
| 739 return VisitCall(node, lowering); | 759 return VisitCall(node, lowering); |
| 740 | 760 |
| 741 //------------------------------------------------------------------ | 761 //------------------------------------------------------------------ |
| 742 // JavaScript operators. | 762 // JavaScript operators. |
| 743 //------------------------------------------------------------------ | 763 //------------------------------------------------------------------ |
| 744 // For now, we assume that all JS operators were too complex to lower | 764 // For now, we assume that all JS operators were too complex to lower |
| 745 // to Simplified and that they will always require tagged value inputs | 765 // to Simplified and that they will always require tagged value inputs |
| 746 // and produce tagged value outputs. | 766 // and produce tagged value outputs. |
| 747 // TODO(turbofan): it might be possible to lower some JSOperators here, | 767 // TODO(turbofan): it might be possible to lower some JSOperators here, |
| 748 // but that responsibility really lies in the typed lowering phase. | 768 // but that responsibility really lies in the typed lowering phase. |
| 749 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: | 769 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: |
| 750 JS_OP_LIST(DEFINE_JS_CASE) | 770 JS_OP_LIST(DEFINE_JS_CASE) |
| 751 #undef DEFINE_JS_CASE | 771 #undef DEFINE_JS_CASE |
| 752 VisitInputs(node); | 772 VisitInputs(node); |
| 753 return SetOutput(node, kRepTagged); | 773 return SetOutput(node, MachineType::RepTagged()); |
| 754 | 774 |
| 755 //------------------------------------------------------------------ | 775 //------------------------------------------------------------------ |
| 756 // Simplified operators. | 776 // Simplified operators. |
| 757 //------------------------------------------------------------------ | 777 //------------------------------------------------------------------ |
| 758 case IrOpcode::kBooleanNot: { | 778 case IrOpcode::kBooleanNot: { |
| 759 if (lower()) { | 779 if (lower()) { |
| 760 MachineTypeUnion input = GetInfo(node->InputAt(0))->output_type(); | 780 MachineType input = GetInfo(node->InputAt(0))->output_type(); |
| 761 if (input & kRepBit) { | 781 if (input.representation() == MachineRepresentation::kBit) { |
| 762 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) | 782 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) |
| 763 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); | 783 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); |
| 764 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal()); | 784 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal()); |
| 765 } else { | 785 } else { |
| 766 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) | 786 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) |
| 767 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); | 787 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); |
| 768 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); | 788 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
| 769 } | 789 } |
| 770 } else { | 790 } else { |
| 771 // No input representation requirement; adapt during lowering. | 791 // No input representation requirement; adapt during lowering. |
| 772 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); | 792 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); |
| 773 SetOutput(node, kRepBit); | 793 SetOutput(node, MachineType::RepBit()); |
| 774 } | 794 } |
| 775 break; | 795 break; |
| 776 } | 796 } |
| 777 case IrOpcode::kBooleanToNumber: { | 797 case IrOpcode::kBooleanToNumber: { |
| 778 if (lower()) { | 798 if (lower()) { |
| 779 MachineTypeUnion input = GetInfo(node->InputAt(0))->output_type(); | 799 MachineType input = GetInfo(node->InputAt(0))->output_type(); |
| 780 if (input & kRepBit) { | 800 if (input.representation() == MachineRepresentation::kBit) { |
| 781 // BooleanToNumber(x: kRepBit) => x | 801 // BooleanToNumber(x: kRepBit) => x |
| 782 DeferReplacement(node, node->InputAt(0)); | 802 DeferReplacement(node, node->InputAt(0)); |
| 783 } else { | 803 } else { |
| 784 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) | 804 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) |
| 785 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); | 805 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); |
| 786 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); | 806 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
| 787 } | 807 } |
| 788 } else { | 808 } else { |
| 789 // No input representation requirement; adapt during lowering. | 809 // No input representation requirement; adapt during lowering. |
| 790 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); | 810 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); |
| 791 SetOutput(node, kMachInt32); | 811 SetOutput(node, MachineType::Int32()); |
| 792 } | 812 } |
| 793 break; | 813 break; |
| 794 } | 814 } |
| 795 case IrOpcode::kNumberEqual: | 815 case IrOpcode::kNumberEqual: |
| 796 case IrOpcode::kNumberLessThan: | 816 case IrOpcode::kNumberLessThan: |
| 797 case IrOpcode::kNumberLessThanOrEqual: { | 817 case IrOpcode::kNumberLessThanOrEqual: { |
| 798 // Number comparisons reduce to integer comparisons for integer inputs. | 818 // Number comparisons reduce to integer comparisons for integer inputs. |
| 799 if (BothInputsAre(node, Type::Signed32())) { | 819 if (BothInputsAre(node, Type::Signed32())) { |
| 800 // => signed Int32Cmp | 820 // => signed Int32Cmp |
| 801 VisitInt32Cmp(node); | 821 VisitInt32Cmp(node); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 880 } | 900 } |
| 881 case IrOpcode::kNumberBitwiseOr: | 901 case IrOpcode::kNumberBitwiseOr: |
| 882 case IrOpcode::kNumberBitwiseXor: | 902 case IrOpcode::kNumberBitwiseXor: |
| 883 case IrOpcode::kNumberBitwiseAnd: { | 903 case IrOpcode::kNumberBitwiseAnd: { |
| 884 VisitInt32Binop(node); | 904 VisitInt32Binop(node); |
| 885 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 905 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
| 886 break; | 906 break; |
| 887 } | 907 } |
| 888 case IrOpcode::kNumberShiftLeft: { | 908 case IrOpcode::kNumberShiftLeft: { |
| 889 VisitBinop(node, UseInfo::TruncatingWord32(), | 909 VisitBinop(node, UseInfo::TruncatingWord32(), |
| 890 UseInfo::TruncatingWord32(), kMachInt32); | 910 UseInfo::TruncatingWord32(), MachineType::Int32()); |
| 891 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shl()); | 911 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shl()); |
| 892 break; | 912 break; |
| 893 } | 913 } |
| 894 case IrOpcode::kNumberShiftRight: { | 914 case IrOpcode::kNumberShiftRight: { |
| 895 VisitBinop(node, UseInfo::TruncatingWord32(), | 915 VisitBinop(node, UseInfo::TruncatingWord32(), |
| 896 UseInfo::TruncatingWord32(), kMachInt32); | 916 UseInfo::TruncatingWord32(), MachineType::Int32()); |
| 897 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Sar()); | 917 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Sar()); |
| 898 break; | 918 break; |
| 899 } | 919 } |
| 900 case IrOpcode::kNumberShiftRightLogical: { | 920 case IrOpcode::kNumberShiftRightLogical: { |
| 901 VisitBinop(node, UseInfo::TruncatingWord32(), | 921 VisitBinop(node, UseInfo::TruncatingWord32(), |
| 902 UseInfo::TruncatingWord32(), kMachUint32); | 922 UseInfo::TruncatingWord32(), MachineType::Uint32()); |
| 903 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shr()); | 923 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shr()); |
| 904 break; | 924 break; |
| 905 } | 925 } |
| 906 case IrOpcode::kNumberToInt32: { | 926 case IrOpcode::kNumberToInt32: { |
| 907 // Just change representation if necessary. | 927 // Just change representation if necessary. |
| 908 VisitUnop(node, UseInfo::TruncatingWord32(), kMachInt32); | 928 VisitUnop(node, UseInfo::TruncatingWord32(), MachineType::Int32()); |
| 909 if (lower()) DeferReplacement(node, node->InputAt(0)); | 929 if (lower()) DeferReplacement(node, node->InputAt(0)); |
| 910 break; | 930 break; |
| 911 } | 931 } |
| 912 case IrOpcode::kNumberToUint32: { | 932 case IrOpcode::kNumberToUint32: { |
| 913 // Just change representation if necessary. | 933 // Just change representation if necessary. |
| 914 VisitUnop(node, UseInfo::TruncatingWord32(), kMachUint32); | 934 VisitUnop(node, UseInfo::TruncatingWord32(), MachineType::Uint32()); |
| 915 if (lower()) DeferReplacement(node, node->InputAt(0)); | 935 if (lower()) DeferReplacement(node, node->InputAt(0)); |
| 916 break; | 936 break; |
| 917 } | 937 } |
| 918 case IrOpcode::kNumberIsHoleNaN: { | 938 case IrOpcode::kNumberIsHoleNaN: { |
| 919 VisitUnop(node, UseInfo::Float64(), kMachBool); | 939 VisitUnop(node, UseInfo::Float64(), MachineType::Bool()); |
| 920 if (lower()) { | 940 if (lower()) { |
| 921 // NumberIsHoleNaN(x) => Word32Equal(Float64ExtractLowWord32(x), | 941 // NumberIsHoleNaN(x) => Word32Equal(Float64ExtractLowWord32(x), |
| 922 // #HoleNaNLower32) | 942 // #HoleNaNLower32) |
| 923 node->ReplaceInput(0, | 943 node->ReplaceInput(0, |
| 924 jsgraph_->graph()->NewNode( | 944 jsgraph_->graph()->NewNode( |
| 925 lowering->machine()->Float64ExtractLowWord32(), | 945 lowering->machine()->Float64ExtractLowWord32(), |
| 926 node->InputAt(0))); | 946 node->InputAt(0))); |
| 927 node->AppendInput(jsgraph_->zone(), | 947 node->AppendInput(jsgraph_->zone(), |
| 928 jsgraph_->Int32Constant(kHoleNanLower32)); | 948 jsgraph_->Int32Constant(kHoleNanLower32)); |
| 929 NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal()); | 949 NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal()); |
| 930 } | 950 } |
| 931 break; | 951 break; |
| 932 } | 952 } |
| 933 case IrOpcode::kPlainPrimitiveToNumber: { | 953 case IrOpcode::kPlainPrimitiveToNumber: { |
| 934 VisitUnop(node, UseInfo::AnyTagged(), kTypeNumber | kRepTagged); | 954 VisitUnop(node, UseInfo::AnyTagged(), |
| 955 MachineType(MachineRepresentation::kTagged, |
| 956 MachineSemantic::kNumber)); |
| 935 if (lower()) { | 957 if (lower()) { |
| 936 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) | 958 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) |
| 937 Operator::Properties properties = node->op()->properties(); | 959 Operator::Properties properties = node->op()->properties(); |
| 938 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); | 960 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); |
| 939 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 961 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
| 940 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 962 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 941 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, | 963 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, |
| 942 flags, properties); | 964 flags, properties); |
| 943 node->InsertInput(jsgraph_->zone(), 0, | 965 node->InsertInput(jsgraph_->zone(), 0, |
| 944 jsgraph_->HeapConstant(callable.code())); | 966 jsgraph_->HeapConstant(callable.code())); |
| 945 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); | 967 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); |
| 946 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); | 968 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); |
| 947 } | 969 } |
| 948 break; | 970 break; |
| 949 } | 971 } |
| 950 case IrOpcode::kReferenceEqual: { | 972 case IrOpcode::kReferenceEqual: { |
| 951 VisitBinop(node, UseInfo::AnyTagged(), kMachBool); | 973 VisitBinop(node, UseInfo::AnyTagged(), MachineType::Bool()); |
| 952 if (lower()) { | 974 if (lower()) { |
| 953 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); | 975 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
| 954 } | 976 } |
| 955 break; | 977 break; |
| 956 } | 978 } |
| 957 case IrOpcode::kStringEqual: { | 979 case IrOpcode::kStringEqual: { |
| 958 VisitBinop(node, UseInfo::AnyTagged(), kMachBool); | 980 VisitBinop(node, UseInfo::AnyTagged(), MachineType::Bool()); |
| 959 if (lower()) lowering->DoStringEqual(node); | 981 if (lower()) lowering->DoStringEqual(node); |
| 960 break; | 982 break; |
| 961 } | 983 } |
| 962 case IrOpcode::kStringLessThan: { | 984 case IrOpcode::kStringLessThan: { |
| 963 VisitBinop(node, UseInfo::AnyTagged(), kMachBool); | 985 VisitBinop(node, UseInfo::AnyTagged(), MachineType::Bool()); |
| 964 if (lower()) lowering->DoStringLessThan(node); | 986 if (lower()) lowering->DoStringLessThan(node); |
| 965 break; | 987 break; |
| 966 } | 988 } |
| 967 case IrOpcode::kStringLessThanOrEqual: { | 989 case IrOpcode::kStringLessThanOrEqual: { |
| 968 VisitBinop(node, UseInfo::AnyTagged(), kMachBool); | 990 VisitBinop(node, UseInfo::AnyTagged(), MachineType::Bool()); |
| 969 if (lower()) lowering->DoStringLessThanOrEqual(node); | 991 if (lower()) lowering->DoStringLessThanOrEqual(node); |
| 970 break; | 992 break; |
| 971 } | 993 } |
| 972 case IrOpcode::kAllocate: { | 994 case IrOpcode::kAllocate: { |
| 973 ProcessInput(node, 0, UseInfo::AnyTagged()); | 995 ProcessInput(node, 0, UseInfo::AnyTagged()); |
| 974 ProcessRemainingInputs(node, 1); | 996 ProcessRemainingInputs(node, 1); |
| 975 SetOutput(node, kMachAnyTagged); | 997 SetOutput(node, MachineType::AnyTagged()); |
| 976 break; | 998 break; |
| 977 } | 999 } |
| 978 case IrOpcode::kLoadField: { | 1000 case IrOpcode::kLoadField: { |
| 979 FieldAccess access = FieldAccessOf(node->op()); | 1001 FieldAccess access = FieldAccessOf(node->op()); |
| 980 ProcessInput(node, 0, UseInfoForBasePointer(access)); | 1002 ProcessInput(node, 0, UseInfoForBasePointer(access)); |
| 981 ProcessRemainingInputs(node, 1); | 1003 ProcessRemainingInputs(node, 1); |
| 982 SetOutput(node, access.machine_type); | 1004 SetOutput(node, access.machine_type); |
| 983 break; | 1005 break; |
| 984 } | 1006 } |
| 985 case IrOpcode::kStoreField: { | 1007 case IrOpcode::kStoreField: { |
| 986 FieldAccess access = FieldAccessOf(node->op()); | 1008 FieldAccess access = FieldAccessOf(node->op()); |
| 987 ProcessInput(node, 0, UseInfoForBasePointer(access)); | 1009 ProcessInput(node, 0, UseInfoForBasePointer(access)); |
| 988 ProcessInput(node, 1, UseInfoFromMachineType(access.machine_type)); | 1010 ProcessInput(node, 1, TruncatingUseInfoFromRepresentation( |
| 1011 access.machine_type.representation())); |
| 989 ProcessRemainingInputs(node, 2); | 1012 ProcessRemainingInputs(node, 2); |
| 990 SetOutput(node, 0); | 1013 SetOutput(node, MachineType::None()); |
| 991 break; | 1014 break; |
| 992 } | 1015 } |
| 993 case IrOpcode::kLoadBuffer: { | 1016 case IrOpcode::kLoadBuffer: { |
| 994 BufferAccess access = BufferAccessOf(node->op()); | 1017 BufferAccess access = BufferAccessOf(node->op()); |
| 995 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer | 1018 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer |
| 996 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset | 1019 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset |
| 997 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length | 1020 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length |
| 998 ProcessRemainingInputs(node, 3); | 1021 ProcessRemainingInputs(node, 3); |
| 999 | 1022 |
| 1000 MachineType output_type; | 1023 MachineType output_type; |
| 1001 if (truncation.TruncatesUndefinedToZeroOrNaN()) { | 1024 if (truncation.TruncatesUndefinedToZeroOrNaN()) { |
| 1002 if (truncation.TruncatesNaNToZero()) { | 1025 if (truncation.TruncatesNaNToZero()) { |
| 1003 // If undefined is truncated to a non-NaN number, we can use | 1026 // If undefined is truncated to a non-NaN number, we can use |
| 1004 // the load's representation. | 1027 // the load's representation. |
| 1005 output_type = access.machine_type(); | 1028 output_type = access.machine_type(); |
| 1006 } else { | 1029 } else { |
| 1007 // If undefined is truncated to a number, but the use can | 1030 // If undefined is truncated to a number, but the use can |
| 1008 // observe NaN, we need to output at least the float32 | 1031 // observe NaN, we need to output at least the float32 |
| 1009 // representation. | 1032 // representation. |
| 1010 if (access.machine_type() & kRepFloat32) { | 1033 if (access.machine_type().representation() == |
| 1034 MachineRepresentation::kFloat32) { |
| 1011 output_type = access.machine_type(); | 1035 output_type = access.machine_type(); |
| 1012 } else { | 1036 } else { |
| 1013 output_type = kMachFloat64; | 1037 output_type = MachineType::Float64(); |
| 1014 } | 1038 } |
| 1015 } | 1039 } |
| 1016 } else { | 1040 } else { |
| 1017 // If undefined is not truncated away, we need to have the tagged | 1041 // If undefined is not truncated away, we need to have the tagged |
| 1018 // representation. | 1042 // representation. |
| 1019 output_type = kMachAnyTagged; | 1043 output_type = MachineType::AnyTagged(); |
| 1020 } | 1044 } |
| 1021 SetOutput(node, output_type); | 1045 SetOutput(node, output_type); |
| 1022 if (lower()) lowering->DoLoadBuffer(node, output_type, changer_); | 1046 if (lower()) lowering->DoLoadBuffer(node, output_type, changer_); |
| 1023 break; | 1047 break; |
| 1024 } | 1048 } |
| 1025 case IrOpcode::kStoreBuffer: { | 1049 case IrOpcode::kStoreBuffer: { |
| 1026 BufferAccess access = BufferAccessOf(node->op()); | 1050 BufferAccess access = BufferAccessOf(node->op()); |
| 1027 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer | 1051 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer |
| 1028 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset | 1052 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset |
| 1029 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length | 1053 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length |
| 1030 ProcessInput(node, 3, | 1054 ProcessInput(node, 3, |
| 1031 UseInfoFromMachineType(access.machine_type())); // value | 1055 TruncatingUseInfoFromRepresentation( |
| 1056 access.machine_type().representation())); // value |
| 1032 ProcessRemainingInputs(node, 4); | 1057 ProcessRemainingInputs(node, 4); |
| 1033 SetOutput(node, 0); | 1058 SetOutput(node, MachineType::None()); |
| 1034 if (lower()) lowering->DoStoreBuffer(node); | 1059 if (lower()) lowering->DoStoreBuffer(node); |
| 1035 break; | 1060 break; |
| 1036 } | 1061 } |
| 1037 case IrOpcode::kLoadElement: { | 1062 case IrOpcode::kLoadElement: { |
| 1038 ElementAccess access = ElementAccessOf(node->op()); | 1063 ElementAccess access = ElementAccessOf(node->op()); |
| 1039 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base | 1064 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base |
| 1040 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index | 1065 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index |
| 1041 ProcessRemainingInputs(node, 2); | 1066 ProcessRemainingInputs(node, 2); |
| 1042 SetOutput(node, access.machine_type); | 1067 SetOutput(node, access.machine_type); |
| 1043 break; | 1068 break; |
| 1044 } | 1069 } |
| 1045 case IrOpcode::kStoreElement: { | 1070 case IrOpcode::kStoreElement: { |
| 1046 ElementAccess access = ElementAccessOf(node->op()); | 1071 ElementAccess access = ElementAccessOf(node->op()); |
| 1047 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base | 1072 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base |
| 1048 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index | 1073 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index |
| 1049 ProcessInput(node, 2, | 1074 ProcessInput(node, 2, |
| 1050 UseInfoFromMachineType(access.machine_type)); // value | 1075 TruncatingUseInfoFromRepresentation( |
| 1076 access.machine_type.representation())); // value |
| 1051 ProcessRemainingInputs(node, 3); | 1077 ProcessRemainingInputs(node, 3); |
| 1052 SetOutput(node, 0); | 1078 SetOutput(node, MachineType::None()); |
| 1053 break; | 1079 break; |
| 1054 } | 1080 } |
| 1055 case IrOpcode::kObjectIsNumber: { | 1081 case IrOpcode::kObjectIsNumber: { |
| 1056 ProcessInput(node, 0, UseInfo::AnyTagged()); | 1082 ProcessInput(node, 0, UseInfo::AnyTagged()); |
| 1057 SetOutput(node, kMachBool); | 1083 SetOutput(node, MachineType::Bool()); |
| 1058 if (lower()) lowering->DoObjectIsNumber(node); | 1084 if (lower()) lowering->DoObjectIsNumber(node); |
| 1059 break; | 1085 break; |
| 1060 } | 1086 } |
| 1061 case IrOpcode::kObjectIsSmi: { | 1087 case IrOpcode::kObjectIsSmi: { |
| 1062 ProcessInput(node, 0, UseInfo::AnyTagged()); | 1088 ProcessInput(node, 0, UseInfo::AnyTagged()); |
| 1063 SetOutput(node, kMachBool); | 1089 SetOutput(node, MachineType::Bool()); |
| 1064 if (lower()) lowering->DoObjectIsSmi(node); | 1090 if (lower()) lowering->DoObjectIsSmi(node); |
| 1065 break; | 1091 break; |
| 1066 } | 1092 } |
| 1067 | 1093 |
| 1068 //------------------------------------------------------------------ | 1094 //------------------------------------------------------------------ |
| 1069 // Machine-level operators. | 1095 // Machine-level operators. |
| 1070 //------------------------------------------------------------------ | 1096 //------------------------------------------------------------------ |
| 1071 case IrOpcode::kLoad: { | 1097 case IrOpcode::kLoad: { |
| 1072 // TODO(jarin) Eventually, we should get rid of all machine stores | 1098 // TODO(jarin) Eventually, we should get rid of all machine stores |
| 1073 // from the high-level phases, then this becomes UNREACHABLE. | 1099 // from the high-level phases, then this becomes UNREACHABLE. |
| 1074 LoadRepresentation rep = OpParameter<LoadRepresentation>(node); | 1100 LoadRepresentation rep = LoadRepresentationOf(node->op()); |
| 1075 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer | 1101 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer |
| 1076 ProcessInput(node, 1, UseInfo::PointerInt()); // index | 1102 ProcessInput(node, 1, UseInfo::PointerInt()); // index |
| 1077 ProcessRemainingInputs(node, 2); | 1103 ProcessRemainingInputs(node, 2); |
| 1078 SetOutput(node, rep); | 1104 SetOutput(node, rep); |
| 1079 break; | 1105 break; |
| 1080 } | 1106 } |
| 1081 case IrOpcode::kStore: { | 1107 case IrOpcode::kStore: { |
| 1082 // TODO(jarin) Eventually, we should get rid of all machine stores | 1108 // TODO(jarin) Eventually, we should get rid of all machine stores |
| 1083 // from the high-level phases, then this becomes UNREACHABLE. | 1109 // from the high-level phases, then this becomes UNREACHABLE. |
| 1084 StoreRepresentation rep = OpParameter<StoreRepresentation>(node); | 1110 StoreRepresentation rep = StoreRepresentationOf(node->op()); |
| 1085 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer | 1111 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer |
| 1086 ProcessInput(node, 1, UseInfo::PointerInt()); // index | 1112 ProcessInput(node, 1, UseInfo::PointerInt()); // index |
| 1087 ProcessInput(node, 2, UseInfoFromMachineType(rep.machine_type())); | 1113 ProcessInput(node, 2, TruncatingUseInfoFromRepresentation( |
| 1114 rep.machine_type().representation())); |
| 1088 ProcessRemainingInputs(node, 3); | 1115 ProcessRemainingInputs(node, 3); |
| 1089 SetOutput(node, 0); | 1116 SetOutput(node, MachineType::None()); |
| 1090 break; | 1117 break; |
| 1091 } | 1118 } |
| 1092 case IrOpcode::kWord32Shr: | 1119 case IrOpcode::kWord32Shr: |
| 1093 // We output unsigned int32 for shift right because JavaScript. | 1120 // We output unsigned int32 for shift right because JavaScript. |
| 1094 return VisitBinop(node, UseInfo::TruncatingWord32(), kMachUint32); | 1121 return VisitBinop(node, UseInfo::TruncatingWord32(), |
| 1122 MachineType::Uint32()); |
| 1095 case IrOpcode::kWord32And: | 1123 case IrOpcode::kWord32And: |
| 1096 case IrOpcode::kWord32Or: | 1124 case IrOpcode::kWord32Or: |
| 1097 case IrOpcode::kWord32Xor: | 1125 case IrOpcode::kWord32Xor: |
| 1098 case IrOpcode::kWord32Shl: | 1126 case IrOpcode::kWord32Shl: |
| 1099 case IrOpcode::kWord32Sar: | 1127 case IrOpcode::kWord32Sar: |
| 1100 // We use signed int32 as the output type for these word32 operations, | 1128 // We use signed int32 as the output type for these word32 operations, |
| 1101 // though the machine bits are the same for either signed or unsigned, | 1129 // though the machine bits are the same for either signed or unsigned, |
| 1102 // because JavaScript considers the result from these operations signed. | 1130 // because JavaScript considers the result from these operations signed. |
| 1103 return VisitBinop(node, UseInfo::TruncatingWord32(), | 1131 return VisitBinop(node, UseInfo::TruncatingWord32(), |
| 1104 kRepWord32 | kTypeInt32); | 1132 MachineType::Int32()); |
| 1105 case IrOpcode::kWord32Equal: | 1133 case IrOpcode::kWord32Equal: |
| 1106 return VisitBinop(node, UseInfo::TruncatingWord32(), kMachBool); | 1134 return VisitBinop(node, UseInfo::TruncatingWord32(), |
| 1135 MachineType::Bool()); |
| 1107 | 1136 |
| 1108 case IrOpcode::kWord32Clz: | 1137 case IrOpcode::kWord32Clz: |
| 1109 return VisitUnop(node, UseInfo::TruncatingWord32(), kMachUint32); | 1138 return VisitUnop(node, UseInfo::TruncatingWord32(), |
| 1139 MachineType::Uint32()); |
| 1110 | 1140 |
| 1111 case IrOpcode::kInt32Add: | 1141 case IrOpcode::kInt32Add: |
| 1112 case IrOpcode::kInt32Sub: | 1142 case IrOpcode::kInt32Sub: |
| 1113 case IrOpcode::kInt32Mul: | 1143 case IrOpcode::kInt32Mul: |
| 1114 case IrOpcode::kInt32MulHigh: | 1144 case IrOpcode::kInt32MulHigh: |
| 1115 case IrOpcode::kInt32Div: | 1145 case IrOpcode::kInt32Div: |
| 1116 case IrOpcode::kInt32Mod: | 1146 case IrOpcode::kInt32Mod: |
| 1117 return VisitInt32Binop(node); | 1147 return VisitInt32Binop(node); |
| 1118 case IrOpcode::kUint32Div: | 1148 case IrOpcode::kUint32Div: |
| 1119 case IrOpcode::kUint32Mod: | 1149 case IrOpcode::kUint32Mod: |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1143 case IrOpcode::kUint64Div: | 1173 case IrOpcode::kUint64Div: |
| 1144 case IrOpcode::kUint64Mod: | 1174 case IrOpcode::kUint64Mod: |
| 1145 return VisitUint64Binop(node); | 1175 return VisitUint64Binop(node); |
| 1146 | 1176 |
| 1147 case IrOpcode::kWord64And: | 1177 case IrOpcode::kWord64And: |
| 1148 case IrOpcode::kWord64Or: | 1178 case IrOpcode::kWord64Or: |
| 1149 case IrOpcode::kWord64Xor: | 1179 case IrOpcode::kWord64Xor: |
| 1150 case IrOpcode::kWord64Shl: | 1180 case IrOpcode::kWord64Shl: |
| 1151 case IrOpcode::kWord64Shr: | 1181 case IrOpcode::kWord64Shr: |
| 1152 case IrOpcode::kWord64Sar: | 1182 case IrOpcode::kWord64Sar: |
| 1153 return VisitBinop(node, UseInfo::TruncatingWord64(), kRepWord64); | 1183 return VisitBinop(node, UseInfo::TruncatingWord64(), |
| 1184 MachineType(MachineRepresentation::kWord64, |
| 1185 MachineSemantic::kNone)); |
| 1154 case IrOpcode::kWord64Equal: | 1186 case IrOpcode::kWord64Equal: |
| 1155 return VisitBinop(node, UseInfo::TruncatingWord64(), kMachBool); | 1187 return VisitBinop(node, UseInfo::TruncatingWord64(), |
| 1188 MachineType::Bool()); |
| 1156 | 1189 |
| 1157 case IrOpcode::kChangeInt32ToInt64: | 1190 case IrOpcode::kChangeInt32ToInt64: |
| 1158 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1191 return VisitUnop(node, UseInfo::TruncatingWord32(), |
| 1159 kTypeInt32 | kRepWord64); | 1192 MachineType(MachineRepresentation::kWord64, |
| 1193 MachineSemantic::kInt32)); |
| 1160 case IrOpcode::kChangeUint32ToUint64: | 1194 case IrOpcode::kChangeUint32ToUint64: |
| 1161 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1195 return VisitUnop(node, UseInfo::TruncatingWord32(), |
| 1162 kTypeUint32 | kRepWord64); | 1196 MachineType(MachineRepresentation::kWord64, |
| 1197 MachineSemantic::kUint32)); |
| 1163 case IrOpcode::kTruncateFloat64ToFloat32: | 1198 case IrOpcode::kTruncateFloat64ToFloat32: |
| 1164 return VisitUnop(node, UseInfo::Float64(), kTypeNumber | kRepFloat32); | 1199 return VisitUnop(node, UseInfo::Float64(), MachineType::Float32()); |
| 1165 case IrOpcode::kTruncateFloat64ToInt32: | 1200 case IrOpcode::kTruncateFloat64ToInt32: |
| 1166 return VisitUnop(node, UseInfo::Float64(), kTypeInt32 | kRepWord32); | 1201 return VisitUnop(node, UseInfo::Float64(), MachineType::Int32()); |
| 1167 case IrOpcode::kTruncateInt64ToInt32: | 1202 case IrOpcode::kTruncateInt64ToInt32: |
| 1168 // TODO(titzer): Is kTypeInt32 correct here? | 1203 // TODO(titzer): Is kTypeInt32 correct here? |
| 1169 return VisitUnop(node, UseInfo::Word64TruncatingToWord32(), | 1204 return VisitUnop(node, UseInfo::Word64TruncatingToWord32(), |
| 1170 kTypeInt32 | kRepWord32); | 1205 MachineType::Int32()); |
| 1171 | 1206 |
| 1172 case IrOpcode::kChangeFloat32ToFloat64: | 1207 case IrOpcode::kChangeFloat32ToFloat64: |
| 1173 return VisitUnop(node, UseInfo::Float32(), kTypeNumber | kRepFloat64); | 1208 return VisitUnop(node, UseInfo::Float32(), MachineType::Float64()); |
| 1174 case IrOpcode::kChangeInt32ToFloat64: | 1209 case IrOpcode::kChangeInt32ToFloat64: |
| 1175 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1210 return VisitUnop(node, UseInfo::TruncatingWord32(), |
| 1176 kTypeInt32 | kRepFloat64); | 1211 MachineType(MachineRepresentation::kFloat64, |
| 1212 MachineSemantic::kInt32)); |
| 1177 case IrOpcode::kChangeUint32ToFloat64: | 1213 case IrOpcode::kChangeUint32ToFloat64: |
| 1178 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1214 return VisitUnop(node, UseInfo::TruncatingWord32(), |
| 1179 kTypeUint32 | kRepFloat64); | 1215 MachineType(MachineRepresentation::kFloat64, |
| 1216 MachineSemantic::kUint32)); |
| 1180 case IrOpcode::kChangeFloat64ToInt32: | 1217 case IrOpcode::kChangeFloat64ToInt32: |
| 1181 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), | 1218 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), |
| 1182 kTypeInt32 | kRepWord32); | 1219 MachineType::Int32()); |
| 1183 case IrOpcode::kChangeFloat64ToUint32: | 1220 case IrOpcode::kChangeFloat64ToUint32: |
| 1184 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), | 1221 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), |
| 1185 kTypeUint32 | kRepWord32); | 1222 MachineType::Uint32()); |
| 1186 | 1223 |
| 1187 case IrOpcode::kFloat64Add: | 1224 case IrOpcode::kFloat64Add: |
| 1188 case IrOpcode::kFloat64Sub: | 1225 case IrOpcode::kFloat64Sub: |
| 1189 case IrOpcode::kFloat64Mul: | 1226 case IrOpcode::kFloat64Mul: |
| 1190 case IrOpcode::kFloat64Div: | 1227 case IrOpcode::kFloat64Div: |
| 1191 case IrOpcode::kFloat64Mod: | 1228 case IrOpcode::kFloat64Mod: |
| 1192 case IrOpcode::kFloat64Min: | 1229 case IrOpcode::kFloat64Min: |
| 1193 return VisitFloat64Binop(node); | 1230 return VisitFloat64Binop(node); |
| 1194 case IrOpcode::kFloat64Abs: | 1231 case IrOpcode::kFloat64Abs: |
| 1195 case IrOpcode::kFloat64Sqrt: | 1232 case IrOpcode::kFloat64Sqrt: |
| 1196 case IrOpcode::kFloat64RoundDown: | 1233 case IrOpcode::kFloat64RoundDown: |
| 1197 case IrOpcode::kFloat64RoundTruncate: | 1234 case IrOpcode::kFloat64RoundTruncate: |
| 1198 case IrOpcode::kFloat64RoundTiesAway: | 1235 case IrOpcode::kFloat64RoundTiesAway: |
| 1199 return VisitUnop(node, UseInfo::Float64(), kMachFloat64); | 1236 return VisitUnop(node, UseInfo::Float64(), MachineType::Float64()); |
| 1200 case IrOpcode::kFloat64Equal: | 1237 case IrOpcode::kFloat64Equal: |
| 1201 case IrOpcode::kFloat64LessThan: | 1238 case IrOpcode::kFloat64LessThan: |
| 1202 case IrOpcode::kFloat64LessThanOrEqual: | 1239 case IrOpcode::kFloat64LessThanOrEqual: |
| 1203 return VisitFloat64Cmp(node); | 1240 return VisitFloat64Cmp(node); |
| 1204 case IrOpcode::kFloat64ExtractLowWord32: | 1241 case IrOpcode::kFloat64ExtractLowWord32: |
| 1205 case IrOpcode::kFloat64ExtractHighWord32: | 1242 case IrOpcode::kFloat64ExtractHighWord32: |
| 1206 return VisitUnop(node, UseInfo::Float64(), kMachInt32); | 1243 return VisitUnop(node, UseInfo::Float64(), MachineType::Int32()); |
| 1207 case IrOpcode::kFloat64InsertLowWord32: | 1244 case IrOpcode::kFloat64InsertLowWord32: |
| 1208 case IrOpcode::kFloat64InsertHighWord32: | 1245 case IrOpcode::kFloat64InsertHighWord32: |
| 1209 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(), | 1246 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(), |
| 1210 kMachFloat64); | 1247 MachineType::Float64()); |
| 1211 case IrOpcode::kLoadStackPointer: | 1248 case IrOpcode::kLoadStackPointer: |
| 1212 case IrOpcode::kLoadFramePointer: | 1249 case IrOpcode::kLoadFramePointer: |
| 1213 return VisitLeaf(node, kMachPtr); | 1250 return VisitLeaf(node, MachineType::Pointer()); |
| 1214 case IrOpcode::kStateValues: | 1251 case IrOpcode::kStateValues: |
| 1215 VisitStateValues(node); | 1252 VisitStateValues(node); |
| 1216 break; | 1253 break; |
| 1217 default: | 1254 default: |
| 1218 VisitInputs(node); | 1255 VisitInputs(node); |
| 1219 // Assume the output is tagged. | 1256 // Assume the output is tagged. |
| 1220 SetOutput(node, kMachAnyTagged); | 1257 SetOutput(node, MachineType::AnyTagged()); |
| 1221 break; | 1258 break; |
| 1222 } | 1259 } |
| 1223 } | 1260 } |
| 1224 | 1261 |
| 1225 void DeferReplacement(Node* node, Node* replacement) { | 1262 void DeferReplacement(Node* node, Node* replacement) { |
| 1226 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), | 1263 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), |
| 1227 node->op()->mnemonic(), replacement->id(), | 1264 node->op()->mnemonic(), replacement->id(), |
| 1228 replacement->op()->mnemonic()); | 1265 replacement->op()->mnemonic()); |
| 1229 | 1266 |
| 1230 if (replacement->id() < count_ && | 1267 if (replacement->id() < count_ && |
| 1231 GetInfo(replacement)->output_type() == GetInfo(node)->output_type()) { | 1268 GetInfo(replacement)->output_type() == GetInfo(node)->output_type()) { |
| 1232 // Replace with a previously existing node eagerly only if the type is the | 1269 // Replace with a previously existing node eagerly only if the type is the |
| 1233 // same. | 1270 // same. |
| 1234 node->ReplaceUses(replacement); | 1271 node->ReplaceUses(replacement); |
| 1235 } else { | 1272 } else { |
| 1236 // Otherwise, we are replacing a node with a representation change. | 1273 // Otherwise, we are replacing a node with a representation change. |
| 1237 // Such a substitution must be done after all lowering is done, because | 1274 // Such a substitution must be done after all lowering is done, because |
| 1238 // changing the type could confuse the representation change | 1275 // changing the type could confuse the representation change |
| 1239 // insertion for uses of the node. | 1276 // insertion for uses of the node. |
| 1240 replacements_.push_back(node); | 1277 replacements_.push_back(node); |
| 1241 replacements_.push_back(replacement); | 1278 replacements_.push_back(replacement); |
| 1242 } | 1279 } |
| 1243 node->NullAllInputs(); // Node is now dead. | 1280 node->NullAllInputs(); // Node is now dead. |
| 1244 } | 1281 } |
| 1245 | 1282 |
| 1246 void PrintInfo(MachineTypeUnion info) { | 1283 void PrintInfo(MachineType info) { |
| 1247 if (FLAG_trace_representation) { | 1284 if (FLAG_trace_representation) { |
| 1248 OFStream os(stdout); | 1285 OFStream os(stdout); |
| 1249 os << static_cast<MachineType>(info); | 1286 os << info; |
| 1250 } | 1287 } |
| 1251 } | 1288 } |
| 1252 | 1289 |
| 1253 void PrintTruncation(Truncation truncation) { | 1290 void PrintTruncation(Truncation truncation) { |
| 1254 if (FLAG_trace_representation) { | 1291 if (FLAG_trace_representation) { |
| 1255 OFStream os(stdout); | 1292 OFStream os(stdout); |
| 1256 os << truncation.description(); | 1293 os << truncation.description(); |
| 1257 } | 1294 } |
| 1258 } | 1295 } |
| 1259 | 1296 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 RepresentationChanger changer(jsgraph(), jsgraph()->isolate()); | 1342 RepresentationChanger changer(jsgraph(), jsgraph()->isolate()); |
| 1306 RepresentationSelector selector(jsgraph(), zone_, &changer, | 1343 RepresentationSelector selector(jsgraph(), zone_, &changer, |
| 1307 source_positions_); | 1344 source_positions_); |
| 1308 selector.Run(this); | 1345 selector.Run(this); |
| 1309 } | 1346 } |
| 1310 | 1347 |
| 1311 | 1348 |
| 1312 void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type, | 1349 void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type, |
| 1313 RepresentationChanger* changer) { | 1350 RepresentationChanger* changer) { |
| 1314 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode()); | 1351 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode()); |
| 1315 DCHECK_NE(kMachNone, RepresentationOf(output_type)); | 1352 DCHECK_NE(MachineRepresentation::kNone, output_type.representation()); |
| 1316 MachineType const type = BufferAccessOf(node->op()).machine_type(); | 1353 MachineType const type = BufferAccessOf(node->op()).machine_type(); |
| 1317 if (output_type != type) { | 1354 if (output_type != type) { |
| 1318 Node* const buffer = node->InputAt(0); | 1355 Node* const buffer = node->InputAt(0); |
| 1319 Node* const offset = node->InputAt(1); | 1356 Node* const offset = node->InputAt(1); |
| 1320 Node* const length = node->InputAt(2); | 1357 Node* const length = node->InputAt(2); |
| 1321 Node* const effect = node->InputAt(3); | 1358 Node* const effect = node->InputAt(3); |
| 1322 Node* const control = node->InputAt(4); | 1359 Node* const control = node->InputAt(4); |
| 1323 Node* const index = | 1360 Node* const index = |
| 1324 machine()->Is64() | 1361 machine()->Is64() |
| 1325 ? graph()->NewNode(machine()->ChangeUint32ToUint64(), offset) | 1362 ? graph()->NewNode(machine()->ChangeUint32ToUint64(), offset) |
| 1326 : offset; | 1363 : offset; |
| 1327 | 1364 |
| 1328 Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length); | 1365 Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length); |
| 1329 Node* branch = | 1366 Node* branch = |
| 1330 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 1367 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| 1331 | 1368 |
| 1332 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 1369 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 1333 Node* etrue = | 1370 Node* etrue = |
| 1334 graph()->NewNode(machine()->Load(type), buffer, index, effect, if_true); | 1371 graph()->NewNode(machine()->Load(type), buffer, index, effect, if_true); |
| 1335 Node* vtrue = changer->GetRepresentationFor( | 1372 Node* vtrue = changer->GetRepresentationFor( |
| 1336 etrue, type, RepresentationOf(output_type), Truncation::None()); | 1373 etrue, type, output_type.representation(), Truncation::None()); |
| 1337 | 1374 |
| 1338 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 1375 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 1339 Node* efalse = effect; | 1376 Node* efalse = effect; |
| 1340 Node* vfalse; | 1377 Node* vfalse; |
| 1341 if (output_type & kRepTagged) { | 1378 if (output_type.representation() == MachineRepresentation::kTagged) { |
| 1342 vfalse = jsgraph()->UndefinedConstant(); | 1379 vfalse = jsgraph()->UndefinedConstant(); |
| 1343 } else if (output_type & kRepFloat64) { | 1380 } else if (output_type.representation() == |
| 1381 MachineRepresentation::kFloat64) { |
| 1344 vfalse = | 1382 vfalse = |
| 1345 jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN()); | 1383 jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN()); |
| 1346 } else if (output_type & kRepFloat32) { | 1384 } else if (output_type.representation() == |
| 1385 MachineRepresentation::kFloat32) { |
| 1347 vfalse = | 1386 vfalse = |
| 1348 jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN()); | 1387 jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN()); |
| 1349 } else { | 1388 } else { |
| 1350 vfalse = jsgraph()->Int32Constant(0); | 1389 vfalse = jsgraph()->Int32Constant(0); |
| 1351 } | 1390 } |
| 1352 | 1391 |
| 1353 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | 1392 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 1354 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); | 1393 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); |
| 1355 | 1394 |
| 1356 // Replace effect uses of {node} with the {ephi}. | 1395 // Replace effect uses of {node} with the {ephi}. |
| 1357 NodeProperties::ReplaceUses(node, node, ephi); | 1396 NodeProperties::ReplaceUses(node, node, ephi); |
| 1358 | 1397 |
| 1359 // Turn the {node} into a Phi. | 1398 // Turn the {node} into a Phi. |
| 1360 node->ReplaceInput(0, vtrue); | 1399 node->ReplaceInput(0, vtrue); |
| 1361 node->ReplaceInput(1, vfalse); | 1400 node->ReplaceInput(1, vfalse); |
| 1362 node->ReplaceInput(2, merge); | 1401 node->ReplaceInput(2, merge); |
| 1363 node->TrimInputCount(3); | 1402 node->TrimInputCount(3); |
| 1364 NodeProperties::ChangeOp(node, common()->Phi(output_type, 2)); | 1403 NodeProperties::ChangeOp(node, |
| 1404 common()->Phi(output_type.representation(), 2)); |
| 1365 } else { | 1405 } else { |
| 1366 NodeProperties::ChangeOp(node, machine()->CheckedLoad(type)); | 1406 NodeProperties::ChangeOp(node, machine()->CheckedLoad(type)); |
| 1367 } | 1407 } |
| 1368 } | 1408 } |
| 1369 | 1409 |
| 1370 | 1410 |
| 1371 void SimplifiedLowering::DoStoreBuffer(Node* node) { | 1411 void SimplifiedLowering::DoStoreBuffer(Node* node) { |
| 1372 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); | 1412 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); |
| 1373 MachineType const type = BufferAccessOf(node->op()).machine_type(); | 1413 MachineType const type = BufferAccessOf(node->op()).machine_type(); |
| 1374 NodeProperties::ChangeOp(node, machine()->CheckedStore(type)); | 1414 NodeProperties::ChangeOp(node, machine()->CheckedStore(type)); |
| 1375 } | 1415 } |
| 1376 | 1416 |
| 1377 | 1417 |
| 1378 void SimplifiedLowering::DoObjectIsNumber(Node* node) { | 1418 void SimplifiedLowering::DoObjectIsNumber(Node* node) { |
| 1379 Node* input = NodeProperties::GetValueInput(node, 0); | 1419 Node* input = NodeProperties::GetValueInput(node, 0); |
| 1380 // TODO(bmeurer): Optimize somewhat based on input type. | 1420 // TODO(bmeurer): Optimize somewhat based on input type. |
| 1381 Node* check = | 1421 Node* check = |
| 1382 graph()->NewNode(machine()->WordEqual(), | 1422 graph()->NewNode(machine()->WordEqual(), |
| 1383 graph()->NewNode(machine()->WordAnd(), input, | 1423 graph()->NewNode(machine()->WordAnd(), input, |
| 1384 jsgraph()->IntPtrConstant(kSmiTagMask)), | 1424 jsgraph()->IntPtrConstant(kSmiTagMask)), |
| 1385 jsgraph()->IntPtrConstant(kSmiTag)); | 1425 jsgraph()->IntPtrConstant(kSmiTag)); |
| 1386 Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start()); | 1426 Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start()); |
| 1387 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 1427 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 1388 Node* vtrue = jsgraph()->Int32Constant(1); | 1428 Node* vtrue = jsgraph()->Int32Constant(1); |
| 1389 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 1429 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 1390 Node* vfalse = graph()->NewNode( | 1430 Node* vfalse = graph()->NewNode( |
| 1391 machine()->WordEqual(), | 1431 machine()->WordEqual(), |
| 1392 graph()->NewNode( | 1432 graph()->NewNode( |
| 1393 machine()->Load(kMachAnyTagged), input, | 1433 machine()->Load(MachineType::AnyTagged()), input, |
| 1394 jsgraph()->IntPtrConstant(HeapObject::kMapOffset - kHeapObjectTag), | 1434 jsgraph()->IntPtrConstant(HeapObject::kMapOffset - kHeapObjectTag), |
| 1395 graph()->start(), if_false), | 1435 graph()->start(), if_false), |
| 1396 jsgraph()->HeapConstant(isolate()->factory()->heap_number_map())); | 1436 jsgraph()->HeapConstant(isolate()->factory()->heap_number_map())); |
| 1397 Node* control = graph()->NewNode(common()->Merge(2), if_true, if_false); | 1437 Node* control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 1398 node->ReplaceInput(0, vtrue); | 1438 node->ReplaceInput(0, vtrue); |
| 1399 node->AppendInput(graph()->zone(), vfalse); | 1439 node->AppendInput(graph()->zone(), vfalse); |
| 1400 node->AppendInput(graph()->zone(), control); | 1440 node->AppendInput(graph()->zone(), control); |
| 1401 NodeProperties::ChangeOp(node, common()->Phi(kMachBool, 2)); | 1441 NodeProperties::ChangeOp(node, common()->Phi(MachineRepresentation::kBit, 2)); |
| 1402 } | 1442 } |
| 1403 | 1443 |
| 1404 | 1444 |
| 1405 void SimplifiedLowering::DoObjectIsSmi(Node* node) { | 1445 void SimplifiedLowering::DoObjectIsSmi(Node* node) { |
| 1406 node->ReplaceInput(0, | 1446 node->ReplaceInput(0, |
| 1407 graph()->NewNode(machine()->WordAnd(), node->InputAt(0), | 1447 graph()->NewNode(machine()->WordAnd(), node->InputAt(0), |
| 1408 jsgraph()->IntPtrConstant(kSmiTagMask))); | 1448 jsgraph()->IntPtrConstant(kSmiTagMask))); |
| 1409 node->AppendInput(graph()->zone(), jsgraph()->IntPtrConstant(kSmiTag)); | 1449 node->AppendInput(graph()->zone(), jsgraph()->IntPtrConstant(kSmiTag)); |
| 1410 NodeProperties::ChangeOp(node, machine()->WordEqual()); | 1450 NodeProperties::ChangeOp(node, machine()->WordEqual()); |
| 1411 } | 1451 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1449 // if rhs < -1 then | 1489 // if rhs < -1 then |
| 1450 // lhs / rhs | 1490 // lhs / rhs |
| 1451 // else if rhs == 0 then | 1491 // else if rhs == 0 then |
| 1452 // 0 | 1492 // 0 |
| 1453 // else | 1493 // else |
| 1454 // 0 - lhs | 1494 // 0 - lhs |
| 1455 // | 1495 // |
| 1456 // Note: We do not use the Diamond helper class here, because it really hurts | 1496 // Note: We do not use the Diamond helper class here, because it really hurts |
| 1457 // readability with nested diamonds. | 1497 // readability with nested diamonds. |
| 1458 const Operator* const merge_op = common()->Merge(2); | 1498 const Operator* const merge_op = common()->Merge(2); |
| 1459 const Operator* const phi_op = common()->Phi(kMachInt32, 2); | 1499 const Operator* const phi_op = |
| 1500 common()->Phi(MachineRepresentation::kWord32, 2); |
| 1460 | 1501 |
| 1461 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs); | 1502 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs); |
| 1462 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, | 1503 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, |
| 1463 graph()->start()); | 1504 graph()->start()); |
| 1464 | 1505 |
| 1465 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 1506 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| 1466 Node* true0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0); | 1507 Node* true0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0); |
| 1467 | 1508 |
| 1468 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | 1509 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
| 1469 Node* false0; | 1510 Node* false0; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1526 // lhs & msk | 1567 // lhs & msk |
| 1527 // else | 1568 // else |
| 1528 // if rhs < -1 then | 1569 // if rhs < -1 then |
| 1529 // lhs % rhs | 1570 // lhs % rhs |
| 1530 // else | 1571 // else |
| 1531 // zero | 1572 // zero |
| 1532 // | 1573 // |
| 1533 // Note: We do not use the Diamond helper class here, because it really hurts | 1574 // Note: We do not use the Diamond helper class here, because it really hurts |
| 1534 // readability with nested diamonds. | 1575 // readability with nested diamonds. |
| 1535 const Operator* const merge_op = common()->Merge(2); | 1576 const Operator* const merge_op = common()->Merge(2); |
| 1536 const Operator* const phi_op = common()->Phi(kMachInt32, 2); | 1577 const Operator* const phi_op = |
| 1578 common()->Phi(MachineRepresentation::kWord32, 2); |
| 1537 | 1579 |
| 1538 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs); | 1580 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs); |
| 1539 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, | 1581 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, |
| 1540 graph()->start()); | 1582 graph()->start()); |
| 1541 | 1583 |
| 1542 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 1584 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| 1543 Node* true0; | 1585 Node* true0; |
| 1544 { | 1586 { |
| 1545 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one); | 1587 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one); |
| 1546 | 1588 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1605 | 1647 |
| 1606 if (m.right().Is(0)) { | 1648 if (m.right().Is(0)) { |
| 1607 return zero; | 1649 return zero; |
| 1608 } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) { | 1650 } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) { |
| 1609 return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start()); | 1651 return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start()); |
| 1610 } | 1652 } |
| 1611 | 1653 |
| 1612 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); | 1654 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); |
| 1613 Diamond d(graph(), common(), check, BranchHint::kFalse); | 1655 Diamond d(graph(), common(), check, BranchHint::kFalse); |
| 1614 Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false); | 1656 Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false); |
| 1615 return d.Phi(kMachUint32, zero, div); | 1657 return d.Phi(MachineRepresentation::kWord32, zero, div); |
| 1616 } | 1658 } |
| 1617 | 1659 |
| 1618 | 1660 |
| 1619 Node* SimplifiedLowering::Uint32Mod(Node* const node) { | 1661 Node* SimplifiedLowering::Uint32Mod(Node* const node) { |
| 1620 Uint32BinopMatcher m(node); | 1662 Uint32BinopMatcher m(node); |
| 1621 Node* const minus_one = jsgraph()->Int32Constant(-1); | 1663 Node* const minus_one = jsgraph()->Int32Constant(-1); |
| 1622 Node* const zero = jsgraph()->Uint32Constant(0); | 1664 Node* const zero = jsgraph()->Uint32Constant(0); |
| 1623 Node* const lhs = m.left().node(); | 1665 Node* const lhs = m.left().node(); |
| 1624 Node* const rhs = m.right().node(); | 1666 Node* const rhs = m.right().node(); |
| 1625 | 1667 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1637 // if rhs & msk != 0 then | 1679 // if rhs & msk != 0 then |
| 1638 // lhs % rhs | 1680 // lhs % rhs |
| 1639 // else | 1681 // else |
| 1640 // lhs & msk | 1682 // lhs & msk |
| 1641 // else | 1683 // else |
| 1642 // zero | 1684 // zero |
| 1643 // | 1685 // |
| 1644 // Note: We do not use the Diamond helper class here, because it really hurts | 1686 // Note: We do not use the Diamond helper class here, because it really hurts |
| 1645 // readability with nested diamonds. | 1687 // readability with nested diamonds. |
| 1646 const Operator* const merge_op = common()->Merge(2); | 1688 const Operator* const merge_op = common()->Merge(2); |
| 1647 const Operator* const phi_op = common()->Phi(kMachInt32, 2); | 1689 const Operator* const phi_op = |
| 1690 common()->Phi(MachineRepresentation::kWord32, 2); |
| 1648 | 1691 |
| 1649 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), rhs, | 1692 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), rhs, |
| 1650 graph()->start()); | 1693 graph()->start()); |
| 1651 | 1694 |
| 1652 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 1695 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| 1653 Node* true0; | 1696 Node* true0; |
| 1654 { | 1697 { |
| 1655 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one); | 1698 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one); |
| 1656 | 1699 |
| 1657 Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk); | 1700 Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1728 ReplaceEffectUses(node, comparison); | 1771 ReplaceEffectUses(node, comparison); |
| 1729 node->ReplaceInput(0, comparison); | 1772 node->ReplaceInput(0, comparison); |
| 1730 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1773 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
| 1731 node->TrimInputCount(2); | 1774 node->TrimInputCount(2); |
| 1732 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); | 1775 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); |
| 1733 } | 1776 } |
| 1734 | 1777 |
| 1735 } // namespace compiler | 1778 } // namespace compiler |
| 1736 } // namespace internal | 1779 } // namespace internal |
| 1737 } // namespace v8 | 1780 } // namespace v8 |
| OLD | NEW |