Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(279)

Side by Side Diff: src/hydrogen-instructions.h

Issue 6881044: Change the Hydrogen representation of uses. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698