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 |