Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 396 | 396 |
| 397 // Make sure type fits in int16. | 397 // Make sure type fits in int16. |
| 398 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte))); | 398 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte))); |
| 399 | 399 |
| 400 explicit HType(Type t) : type_(t) { } | 400 explicit HType(Type t) : type_(t) { } |
| 401 | 401 |
| 402 int16_t type_; | 402 int16_t type_; |
| 403 }; | 403 }; |
| 404 | 404 |
| 405 | 405 |
| 406 class HUseListNode: public ZoneObject { | |
| 407 public: | |
| 408 HUseListNode(HValue* value, int index, HUseListNode* tail) | |
| 409 : tail_(tail), value_(value), index_(index) { | |
| 410 } | |
| 411 | |
| 412 HUseListNode* tail() const { return tail_; } | |
| 413 HValue* value() const { return value_; } | |
| 414 int index() const { return index_; } | |
| 415 | |
| 416 void set_tail(HUseListNode* list) { tail_ = list; } | |
| 417 | |
| 418 #ifdef DEBUG | |
| 419 void Zap() { | |
| 420 tail_ = reinterpret_cast<HUseListNode*>(1); | |
| 421 value_ = NULL; | |
| 422 index_ = -1; | |
| 423 } | |
| 424 #endif | |
| 425 | |
| 426 private: | |
| 427 HUseListNode* tail_; | |
| 428 HValue* value_; | |
| 429 int index_; | |
| 430 }; | |
| 431 | |
| 432 | |
| 433 // We reuse use list nodes behind the scenes as uses are added and deleted. | |
| 434 // This class is the safe way to iterate uses while deleting them. | |
| 435 class HUseIterator BASE_EMBEDDED { | |
| 436 public: | |
| 437 bool Done() { return current_ == NULL; } | |
| 438 void Advance(); | |
| 439 | |
| 440 HValue* value() { | |
| 441 ASSERT(!Done()); | |
| 442 return value_; | |
| 443 } | |
| 444 | |
| 445 int index() { | |
| 446 ASSERT(!Done()); | |
| 447 return index_; | |
| 448 } | |
| 449 | |
| 450 private: | |
| 451 explicit HUseIterator(HUseListNode* head); | |
| 452 | |
| 453 HUseListNode* current_; | |
| 454 HUseListNode* next_; | |
| 455 HValue* value_; | |
| 456 int index_; | |
| 457 | |
| 458 friend class HValue; | |
| 459 }; | |
| 460 | |
| 461 | |
| 406 class HValue: public ZoneObject { | 462 class HValue: public ZoneObject { |
| 407 public: | 463 public: |
| 408 static const int kNoNumber = -1; | 464 static const int kNoNumber = -1; |
| 409 | 465 |
| 410 // There must be one corresponding kDepends flag for every kChanges flag and | 466 // There must be one corresponding kDepends flag for every kChanges flag and |
| 411 // the order of the kChanges flags must be exactly the same as of the kDepends | 467 // the order of the kChanges flags must be exactly the same as of the kDepends |
| 412 // flags. | 468 // flags. |
| 413 enum Flag { | 469 enum Flag { |
| 414 // Declare global value numbering flags. | 470 // Declare global value numbering flags. |
| 415 #define DECLARE_DO(type) kChanges##type, kDependsOn##type, | 471 #define DECLARE_DO(type) kChanges##type, kDependsOn##type, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 466 | 522 |
| 467 // Declare virtual predicates for abstract HInstruction or HValue | 523 // Declare virtual predicates for abstract HInstruction or HValue |
| 468 #define DECLARE_PREDICATE(type) \ | 524 #define DECLARE_PREDICATE(type) \ |
| 469 virtual bool Is##type() const { return false; } | 525 virtual bool Is##type() const { return false; } |
| 470 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE) | 526 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE) |
| 471 #undef DECLARE_PREDICATE | 527 #undef DECLARE_PREDICATE |
| 472 | 528 |
| 473 HValue() : block_(NULL), | 529 HValue() : block_(NULL), |
| 474 id_(kNoNumber), | 530 id_(kNoNumber), |
| 475 type_(HType::Tagged()), | 531 type_(HType::Tagged()), |
| 532 use_list_(NULL), | |
| 476 range_(NULL), | 533 range_(NULL), |
| 477 flags_(0) {} | 534 flags_(0) {} |
| 478 virtual ~HValue() {} | 535 virtual ~HValue() {} |
| 479 | 536 |
| 480 HBasicBlock* block() const { return block_; } | 537 HBasicBlock* block() const { return block_; } |
| 481 void SetBlock(HBasicBlock* block); | 538 void SetBlock(HBasicBlock* block); |
| 482 | 539 |
| 483 int id() const { return id_; } | 540 int id() const { return id_; } |
| 484 void set_id(int id) { id_ = id; } | 541 void set_id(int id) { id_ = id; } |
| 485 | 542 |
| 486 SmallPointerList<HValue>* uses() { return &uses_; } | 543 HUseIterator uses() const { return HUseIterator(use_list_); } |
| 487 | 544 |
| 488 virtual bool EmitAtUses() { return false; } | 545 virtual bool EmitAtUses() { return false; } |
| 489 Representation representation() const { return representation_; } | 546 Representation representation() const { return representation_; } |
| 490 void ChangeRepresentation(Representation r) { | 547 void ChangeRepresentation(Representation r) { |
| 491 // Representation was already set and is allowed to be changed. | 548 // Representation was already set and is allowed to be changed. |
| 492 ASSERT(!representation_.IsNone()); | 549 ASSERT(!representation_.IsNone()); |
| 493 ASSERT(!r.IsNone()); | 550 ASSERT(!r.IsNone()); |
| 494 ASSERT(CheckFlag(kFlexibleRepresentation)); | 551 ASSERT(CheckFlag(kFlexibleRepresentation)); |
| 495 RepresentationChanged(r); | 552 RepresentationChanged(r); |
| 496 representation_ = r; | 553 representation_ = r; |
| 497 } | 554 } |
| 498 | 555 |
| 499 HType type() const { return type_; } | 556 HType type() const { return type_; } |
| 500 void set_type(HType type) { | 557 void set_type(HType type) { |
| 501 ASSERT(uses_.length() == 0); | 558 ASSERT(HasNoUses()); |
| 502 type_ = type; | 559 type_ = type; |
| 503 } | 560 } |
| 504 | 561 |
| 505 // An operation needs to override this function iff: | 562 // An operation needs to override this function iff: |
| 506 // 1) it can produce an int32 output. | 563 // 1) it can produce an int32 output. |
| 507 // 2) the true value of its output can potentially be minus zero. | 564 // 2) the true value of its output can potentially be minus zero. |
| 508 // The implementation must set a flag so that it bails out in the case where | 565 // The implementation must set a flag so that it bails out in the case where |
| 509 // it would otherwise output what should be a minus zero as an int32 zero. | 566 // it would otherwise output what should be a minus zero as an int32 zero. |
| 510 // If the operation also exists in a form that takes int32 and outputs int32 | 567 // If the operation also exists in a form that takes int32 and outputs int32 |
| 511 // then the operation should return its input value so that we can propagate | 568 // then the operation should return its input value so that we can propagate |
| 512 // back. There are two operations that need to propagate back to more than | 569 // back. There are two operations that need to propagate back to more than |
| 513 // one input. They are phi and binary add. They always return NULL and | 570 // one input. They are phi and binary add. They always return NULL and |
| 514 // expect the caller to take care of things. | 571 // expect the caller to take care of things. |
| 515 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) { | 572 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) { |
| 516 visited->Add(id()); | 573 visited->Add(id()); |
| 517 return NULL; | 574 return NULL; |
| 518 } | 575 } |
| 519 | 576 |
| 520 bool IsDefinedAfter(HBasicBlock* other) const; | 577 bool IsDefinedAfter(HBasicBlock* other) const; |
| 521 | 578 |
| 522 // Operands. | 579 // Operands. |
| 523 virtual int OperandCount() = 0; | 580 virtual int OperandCount() = 0; |
| 524 virtual HValue* OperandAt(int index) = 0; | 581 virtual HValue* OperandAt(int index) = 0; |
| 525 void SetOperandAt(int index, HValue* value); | 582 void SetOperandAt(int index, HValue* value); |
| 526 | 583 |
| 527 int LookupOperandIndex(int occurrence_index, HValue* op); | 584 void DeleteAndReplaceWith(HValue* other); |
| 528 bool UsesMultipleTimes(HValue* op); | 585 bool HasNoUses() const { return use_list_ == NULL; } |
| 529 | 586 bool HasMultipleUses() const { |
| 530 void ReplaceAndDelete(HValue* other); | 587 return use_list_ != NULL && use_list_->tail() != NULL; |
| 531 void ReplaceValue(HValue* other); | 588 } |
| 532 void ReplaceAtUse(HValue* use, HValue* other); | 589 int UseCount() const; |
| 533 void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r); | |
| 534 bool HasNoUses() const { return uses_.is_empty(); } | |
| 535 void ClearOperands(); | 590 void ClearOperands(); |
| 536 void Delete(); | |
| 537 | 591 |
| 538 int flags() const { return flags_; } | 592 int flags() const { return flags_; } |
| 539 void SetFlag(Flag f) { flags_ |= (1 << f); } | 593 void SetFlag(Flag f) { flags_ |= (1 << f); } |
| 540 void ClearFlag(Flag f) { flags_ &= ~(1 << f); } | 594 void ClearFlag(Flag f) { flags_ &= ~(1 << f); } |
| 541 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; } | 595 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; } |
| 542 | 596 |
| 543 void SetAllSideEffects() { flags_ |= AllSideEffects(); } | 597 void SetAllSideEffects() { flags_ |= AllSideEffects(); } |
| 544 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); } | 598 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); } |
| 545 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; } | 599 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; } |
| 546 | 600 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 604 ASSERT(representation_.IsNone() && !r.IsNone()); | 658 ASSERT(representation_.IsNone() && !r.IsNone()); |
| 605 representation_ = r; | 659 representation_ = r; |
| 606 } | 660 } |
| 607 | 661 |
| 608 private: | 662 private: |
| 609 // A flag mask to mark an instruction as having arbitrary side effects. | 663 // A flag mask to mark an instruction as having arbitrary side effects. |
| 610 static int AllSideEffects() { | 664 static int AllSideEffects() { |
| 611 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries); | 665 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries); |
| 612 } | 666 } |
| 613 | 667 |
| 614 void InternalReplaceAtUse(HValue* use, HValue* other); | 668 // Remove the matching use from the use list if present. Returns the |
| 669 // removed list node or NULL. | |
| 670 HUseListNode* RemoveUse(HValue* value, int index); | |
|
danno
2011/04/20 04:25:12
How about wrapping HValue* and int in a HUse struc
| |
| 671 | |
| 672 void ReplaceAllUsesWith(HValue* other); | |
| 673 | |
| 615 void RegisterUse(int index, HValue* new_value); | 674 void RegisterUse(int index, HValue* new_value); |
| 616 | 675 |
| 617 HBasicBlock* block_; | 676 HBasicBlock* block_; |
| 618 | 677 |
| 619 // The id of this instruction in the hydrogen graph, assigned when first | 678 // The id of this instruction in the hydrogen graph, assigned when first |
| 620 // added to the graph. Reflects creation order. | 679 // added to the graph. Reflects creation order. |
| 621 int id_; | 680 int id_; |
| 622 | 681 |
| 623 Representation representation_; | 682 Representation representation_; |
| 624 HType type_; | 683 HType type_; |
| 625 SmallPointerList<HValue> uses_; | 684 HUseListNode* use_list_; |
| 626 Range* range_; | 685 Range* range_; |
| 627 int flags_; | 686 int flags_; |
| 628 | 687 |
| 629 DISALLOW_COPY_AND_ASSIGN(HValue); | 688 DISALLOW_COPY_AND_ASSIGN(HValue); |
| 630 }; | 689 }; |
| 631 | 690 |
| 632 | 691 |
| 633 class HInstruction: public HValue { | 692 class HInstruction: public HValue { |
| 634 public: | 693 public: |
| 635 HInstruction* next() const { return next_; } | 694 HInstruction* next() const { return next_; } |
| (...skipping 1614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2250 HCompare(HValue* left, HValue* right, Token::Value token) | 2309 HCompare(HValue* left, HValue* right, Token::Value token) |
| 2251 : HBinaryOperation(left, right), token_(token) { | 2310 : HBinaryOperation(left, right), token_(token) { |
| 2252 ASSERT(Token::IsCompareOp(token)); | 2311 ASSERT(Token::IsCompareOp(token)); |
| 2253 set_representation(Representation::Tagged()); | 2312 set_representation(Representation::Tagged()); |
| 2254 SetAllSideEffects(); | 2313 SetAllSideEffects(); |
| 2255 } | 2314 } |
| 2256 | 2315 |
| 2257 void SetInputRepresentation(Representation r); | 2316 void SetInputRepresentation(Representation r); |
| 2258 | 2317 |
| 2259 virtual bool EmitAtUses() { | 2318 virtual bool EmitAtUses() { |
| 2260 return !HasSideEffects() && (uses()->length() <= 1); | 2319 return !HasSideEffects() && !HasMultipleUses(); |
| 2261 } | 2320 } |
| 2262 | 2321 |
| 2263 virtual Representation RequiredInputRepresentation(int index) const { | 2322 virtual Representation RequiredInputRepresentation(int index) const { |
| 2264 return input_representation_; | 2323 return input_representation_; |
| 2265 } | 2324 } |
| 2266 Representation GetInputRepresentation() const { | 2325 Representation GetInputRepresentation() const { |
| 2267 return input_representation_; | 2326 return input_representation_; |
| 2268 } | 2327 } |
| 2269 Token::Value token() const { return token_; } | 2328 Token::Value token() const { return token_; } |
| 2270 virtual void PrintDataTo(StringStream* stream); | 2329 virtual void PrintDataTo(StringStream* stream); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 2292 class HCompareJSObjectEq: public HBinaryOperation { | 2351 class HCompareJSObjectEq: public HBinaryOperation { |
| 2293 public: | 2352 public: |
| 2294 HCompareJSObjectEq(HValue* left, HValue* right) | 2353 HCompareJSObjectEq(HValue* left, HValue* right) |
| 2295 : HBinaryOperation(left, right) { | 2354 : HBinaryOperation(left, right) { |
| 2296 set_representation(Representation::Tagged()); | 2355 set_representation(Representation::Tagged()); |
| 2297 SetFlag(kUseGVN); | 2356 SetFlag(kUseGVN); |
| 2298 SetFlag(kDependsOnMaps); | 2357 SetFlag(kDependsOnMaps); |
| 2299 } | 2358 } |
| 2300 | 2359 |
| 2301 virtual bool EmitAtUses() { | 2360 virtual bool EmitAtUses() { |
| 2302 return !HasSideEffects() && (uses()->length() <= 1); | 2361 return !HasSideEffects() && !HasMultipleUses(); |
| 2303 } | 2362 } |
| 2304 | 2363 |
| 2305 virtual Representation RequiredInputRepresentation(int index) const { | 2364 virtual Representation RequiredInputRepresentation(int index) const { |
| 2306 return Representation::Tagged(); | 2365 return Representation::Tagged(); |
| 2307 } | 2366 } |
| 2308 virtual HType CalculateInferredType(); | 2367 virtual HType CalculateInferredType(); |
| 2309 | 2368 |
| 2310 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq) | 2369 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq) |
| 2311 | 2370 |
| 2312 protected: | 2371 protected: |
| 2313 virtual bool DataEquals(HValue* other) { return true; } | 2372 virtual bool DataEquals(HValue* other) { return true; } |
| 2314 }; | 2373 }; |
| 2315 | 2374 |
| 2316 | 2375 |
| 2317 class HUnaryPredicate: public HUnaryOperation { | 2376 class HUnaryPredicate: public HUnaryOperation { |
| 2318 public: | 2377 public: |
| 2319 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) { | 2378 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) { |
| 2320 set_representation(Representation::Tagged()); | 2379 set_representation(Representation::Tagged()); |
| 2321 SetFlag(kUseGVN); | 2380 SetFlag(kUseGVN); |
| 2322 } | 2381 } |
| 2323 | 2382 |
| 2324 virtual bool EmitAtUses() { | 2383 virtual bool EmitAtUses() { |
| 2325 return !HasSideEffects() && (uses()->length() <= 1); | 2384 return !HasSideEffects() && !HasMultipleUses(); |
| 2326 } | 2385 } |
| 2327 | 2386 |
| 2328 virtual Representation RequiredInputRepresentation(int index) const { | 2387 virtual Representation RequiredInputRepresentation(int index) const { |
| 2329 return Representation::Tagged(); | 2388 return Representation::Tagged(); |
| 2330 } | 2389 } |
| 2331 virtual HType CalculateInferredType(); | 2390 virtual HType CalculateInferredType(); |
| 2332 }; | 2391 }; |
| 2333 | 2392 |
| 2334 | 2393 |
| 2335 class HIsNull: public HUnaryPredicate { | 2394 class HIsNull: public HUnaryPredicate { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2375 | 2434 |
| 2376 | 2435 |
| 2377 class HIsConstructCall: public HTemplateInstruction<0> { | 2436 class HIsConstructCall: public HTemplateInstruction<0> { |
| 2378 public: | 2437 public: |
| 2379 HIsConstructCall() { | 2438 HIsConstructCall() { |
| 2380 set_representation(Representation::Tagged()); | 2439 set_representation(Representation::Tagged()); |
| 2381 SetFlag(kUseGVN); | 2440 SetFlag(kUseGVN); |
| 2382 } | 2441 } |
| 2383 | 2442 |
| 2384 virtual bool EmitAtUses() { | 2443 virtual bool EmitAtUses() { |
| 2385 return !HasSideEffects() && (uses()->length() <= 1); | 2444 return !HasSideEffects() && !HasMultipleUses(); |
| 2386 } | 2445 } |
| 2387 | 2446 |
| 2388 virtual Representation RequiredInputRepresentation(int index) const { | 2447 virtual Representation RequiredInputRepresentation(int index) const { |
| 2389 return Representation::None(); | 2448 return Representation::None(); |
| 2390 } | 2449 } |
| 2391 | 2450 |
| 2392 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall) | 2451 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall) |
| 2393 | 2452 |
| 2394 protected: | 2453 protected: |
| 2395 virtual bool DataEquals(HValue* other) { return true; } | 2454 virtual bool DataEquals(HValue* other) { return true; } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2497 SetOperandAt(2, right); | 2556 SetOperandAt(2, right); |
| 2498 set_representation(Representation::Tagged()); | 2557 set_representation(Representation::Tagged()); |
| 2499 SetAllSideEffects(); | 2558 SetAllSideEffects(); |
| 2500 } | 2559 } |
| 2501 | 2560 |
| 2502 HValue* context() { return OperandAt(0); } | 2561 HValue* context() { return OperandAt(0); } |
| 2503 HValue* left() { return OperandAt(1); } | 2562 HValue* left() { return OperandAt(1); } |
| 2504 HValue* right() { return OperandAt(2); } | 2563 HValue* right() { return OperandAt(2); } |
| 2505 | 2564 |
| 2506 virtual bool EmitAtUses() { | 2565 virtual bool EmitAtUses() { |
| 2507 return !HasSideEffects() && (uses()->length() <= 1); | 2566 return !HasSideEffects() && !HasMultipleUses(); |
| 2508 } | 2567 } |
| 2509 | 2568 |
| 2510 virtual Representation RequiredInputRepresentation(int index) const { | 2569 virtual Representation RequiredInputRepresentation(int index) const { |
| 2511 return Representation::Tagged(); | 2570 return Representation::Tagged(); |
| 2512 } | 2571 } |
| 2513 | 2572 |
| 2514 virtual void PrintDataTo(StringStream* stream); | 2573 virtual void PrintDataTo(StringStream* stream); |
| 2515 | 2574 |
| 2516 DECLARE_CONCRETE_INSTRUCTION(InstanceOf) | 2575 DECLARE_CONCRETE_INSTRUCTION(InstanceOf) |
| 2517 }; | 2576 }; |
| (...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3718 HValue* object() { return left(); } | 3777 HValue* object() { return left(); } |
| 3719 HValue* key() { return right(); } | 3778 HValue* key() { return right(); } |
| 3720 }; | 3779 }; |
| 3721 | 3780 |
| 3722 #undef DECLARE_INSTRUCTION | 3781 #undef DECLARE_INSTRUCTION |
| 3723 #undef DECLARE_CONCRETE_INSTRUCTION | 3782 #undef DECLARE_CONCRETE_INSTRUCTION |
| 3724 | 3783 |
| 3725 } } // namespace v8::internal | 3784 } } // namespace v8::internal |
| 3726 | 3785 |
| 3727 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 3786 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |