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

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 10829270: Continue work on type propagation in optimizing compiler (still WIP). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/flow_graph_allocator.h" 9 #include "vm/flow_graph_allocator.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 for (intptr_t i = 0; i < block_order_.length(); ++i) { 110 for (intptr_t i = 0; i < block_order_.length(); ++i) {
111 BlockEntryInstr* entry = block_order_[i]; 111 BlockEntryInstr* entry = block_order_[i];
112 entry->Accept(this); 112 entry->Accept(this);
113 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 113 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
114 it.Current()->Accept(this); 114 it.Current()->Accept(this);
115 } 115 }
116 } 116 }
117 } 117 }
118 118
119 119
120 // Returns true if the static type of this value is more specific than the 120 // Returns true if the compile type of this value is more specific than the
121 // given dst_type. 121 // given dst_type.
122 // TODO(regis): Should we support a set of static types? 122 // TODO(regis): Support a set of compile types for the given value.
123 bool Value::StaticTypeIsMoreSpecificThan(const AbstractType& dst_type) const { 123 bool Value::CompileTypeIsMoreSpecificThan(const AbstractType& dst_type) const {
124 ASSERT(!dst_type.IsMalformed()); // Should be tested by caller. 124 ASSERT(!dst_type.IsMalformed()); // Should be tested by caller.
125 ASSERT(!dst_type.IsDynamicType()); // Should be tested by caller. 125 ASSERT(!dst_type.IsDynamicType()); // Should be tested by caller.
126 ASSERT(!dst_type.IsObjectType()); // Should be tested by caller. 126 ASSERT(!dst_type.IsObjectType()); // Should be tested by caller.
127 127
128 // If the value is the null constant, its type (NullType) is more specific 128 // If the value is the null constant, its type (NullType) is more specific
129 // than the destination type, even if the destination type is the void type, 129 // than the destination type, even if the destination type is the void type,
130 // since a void function is allowed to return null. 130 // since a void function is allowed to return null.
131 if (IsConstant() && AsConstant()->value().IsNull()) { 131 if (IsConstant() && AsConstant()->value().IsNull()) {
132 return true; 132 return true;
133 } 133 }
134 134
135 // Functions that do not explicitly return a value, implicitly return null, 135 // Functions that do not explicitly return a value, implicitly return null,
136 // except generative constructors, which return the object being constructed. 136 // except generative constructors, which return the object being constructed.
137 // It is therefore acceptable for void functions to return null. 137 // It is therefore acceptable for void functions to return null.
138 // In case of a null constant, we have already returned true above, else we 138 // In case of a null constant, we have already returned true above, else we
139 // return false here. 139 // return false here.
140 if (dst_type.IsVoidType()) { 140 if (dst_type.IsVoidType()) {
141 return false; 141 return false;
142 } 142 }
143 143
144 // Consider the static type of the value. 144 // Consider the compile type of the value.
145 const AbstractType& static_type = AbstractType::Handle(StaticType()); 145 const AbstractType& static_type = AbstractType::Handle(CompileType());
146 ASSERT(!static_type.IsMalformed()); 146 ASSERT(!static_type.IsMalformed());
147 147
148 // If the static type of the value is void, we are type checking the result of 148 // If the compile type of the value is void, we are type checking the result
149 // a void function, which was checked to be null at the return statement 149 // of a void function, which was checked to be null at the return statement
150 // inside the function. 150 // inside the function.
151 if (static_type.IsVoidType()) { 151 if (static_type.IsVoidType()) {
152 return true; 152 return true;
153 } 153 }
154 154
155 // If the static type of the value is NullType, the type test is eliminated. 155 // If the compile type of the value is NullType, the type test is eliminated.
156 // There are only three instances that can be of Class Null: 156 // There are only three instances that can be of Class Null:
157 // Object::null(), Object::sentinel(), and Object::transition_sentinel(). 157 // Object::null(), Object::sentinel(), and Object::transition_sentinel().
158 // The inline code and run time code performing the type check will never 158 // The inline code and run time code performing the type check will never
159 // encounter the 2 sentinel values. The type check of a sentinel value 159 // encounter the 2 sentinel values. The type check of a sentinel value
160 // will always be eliminated here, because these sentinel values can only 160 // will always be eliminated here, because these sentinel values can only
161 // be encountered as constants, never as actual value of a heap object 161 // be encountered as constants, never as actual value of a heap object
162 // being type checked. 162 // being type checked.
163 if (static_type.IsNullType()) { 163 if (static_type.IsNullType()) {
164 return true; 164 return true;
165 } 165 }
166 166
167 // The run time type of the value is guaranteed to be a subtype of the 167 // The run time type of the value is guaranteed to be a subtype of the
168 // compile time static type of the value. However, establishing here that 168 // compile time type of the value. However, establishing here that
169 // the static type is a subtype of the destination type does not guarantee 169 // the compile time type is a subtype of the destination type does not
170 // that the run time type will also be a subtype of the destination type, 170 // guarantee that the run time type will also be a subtype of the destination
171 // because the subtype relation is not transitive. 171 // type, because the subtype relation is not transitive.
172 // However, the 'more specific than' relation is transitive and is used 172 // However, the 'more specific than' relation is transitive and is used
173 // here. In other words, if the static type of the value is more specific 173 // here. In other words, if the compile type of the value is more specific
174 // than the destination type, the run time type of the value, which is 174 // than the destination type, the run time type of the value, which is
175 // guaranteed to be a subtype of the static type, is also guaranteed to be 175 // guaranteed to be a subtype of the compile type, is also guaranteed to be
176 // a subtype of the destination type and the type check can therefore be 176 // a subtype of the destination type and the type check can therefore be
177 // eliminated. 177 // eliminated.
178 return static_type.IsMoreSpecificThan(dst_type, NULL); 178 return static_type.IsMoreSpecificThan(dst_type, NULL);
179 } 179 }
180 180
181 181
182 RawAbstractType* PhiInstr::StaticType() const { 182 RawAbstractType* PhiInstr::CompileType() const {
183 // TODO(regis): Return the least upper bound of the input static types. 183 // Type propagation must have occured before requesting the compile type.
184 // It is much simpler to compute the least specific of the input static types, 184 // Since at least one input is on a forward edge, the propagated type is set.
185 // and it may be good enough in practice. 185 return PropagatedType();
srdjan 2012/08/09 22:20:53 As discussed in chat, check if you want to split C
regis 2012/08/09 23:51:37 I will keep that question in mind for the next ste
186 // Even better: we could keep the set of the input static types intact. 186 }
187 AbstractType& least_specific_type = 187
188 AbstractType::Handle(InputAt(0)->StaticType()); 188
189 RawAbstractType* PhiInstr::LeastSpecificInputType() const {
190 // To avoid cycles we consider only the propagated types of the inputs.
191 // During the first iteration of type propagation, the propagated type of
192 // inputs on back edges will not be set yet and will be ignored.
193 AbstractType& least_specific_type = AbstractType::Handle();
189 AbstractType& input_type = AbstractType::Handle(); 194 AbstractType& input_type = AbstractType::Handle();
190 for (intptr_t i = 1; i < InputCount(); i++) { 195 for (intptr_t i = 0; i < InputCount(); i++) {
191 input_type = InputAt(i)->StaticType(); 196 Value* input = InputAt(i);
192 if (input_type.IsMoreSpecificThan(least_specific_type, NULL)) { 197 if (input->IsUse()) {
193 // Type least_specific_type is less specific than input_type. No change. 198 if (!input->AsUse()->definition()->HasPropagatedType()) {
194 } else if (least_specific_type.IsMoreSpecificThan(input_type, NULL)) { 199 continue;
200 }
201 input_type = input->AsUse()->definition()->PropagatedType();
srdjan 2012/08/09 22:20:53 input_type = input->AsUse()->CompileType();, and f
regis 2012/08/09 23:51:37 Code and comment changed: input_type = InputAt
202 } else {
203 input_type = input->CompileType();
204 }
205 ASSERT(!input_type.IsNull());
206 if (least_specific_type.IsNull() ||
207 least_specific_type.IsMoreSpecificThan(input_type, NULL)) {
195 // Type input_type is less specific than the current least_specific_type. 208 // Type input_type is less specific than the current least_specific_type.
196 least_specific_type = input_type.raw(); 209 least_specific_type = input_type.raw();
210 } else if (input_type.IsMoreSpecificThan(least_specific_type, NULL)) {
211 // Type least_specific_type is less specific than input_type. No change.
197 } else { 212 } else {
198 // The types are unrelated. No need to continue. 213 // The types are unrelated. No need to continue.
199 least_specific_type = Type::ObjectType(); 214 least_specific_type = Type::ObjectType();
200 break; 215 break;
201 } 216 }
202 } 217 }
203 return least_specific_type.raw(); 218 return least_specific_type.raw();
204 } 219 }
205 220
206 221
207 RawAbstractType* ParameterInstr::StaticType() const { 222 RawAbstractType* ParameterInstr::CompileType() const {
208 // TODO(regis): Can type feedback provide information about the static type 223 // TODO(regis): Can type feedback provide information about the compile type
209 // of a passed-in parameter? 224 // of a passed-in parameter? In that case, it would be stored in the
210 // Note that in checked mode, we could return the static type of the formal 225 // propagated_type_ field.
211 // parameter. However, this would be wrong if ParameterInstr is used to type 226 if (HasPropagatedType()) {
212 // check the passed-in parameter, since the type check would then always be 227 return PropagatedType();
213 // wrongly eliminated. 228 }
srdjan 2012/08/09 22:20:53 How can a parameter instruction have a propagated_
regis 2012/08/09 23:51:37 As the TODO indicates, it would be the type obtain
229 // Note that returning the declared type of the formal parameter would be
230 // incorrect, because ParameterInstr is used as input to the type check
231 // verifying the run time type of the passed-in parameter and this check would
232 // always be wrongly eliminated.
214 return Type::DynamicType(); 233 return Type::DynamicType();
215 } 234 }
216 235
217 236
218 intptr_t JoinEntryInstr::IndexOfPredecessor(BlockEntryInstr* pred) const { 237 intptr_t JoinEntryInstr::IndexOfPredecessor(BlockEntryInstr* pred) const {
219 for (intptr_t i = 0; i < predecessors_.length(); ++i) { 238 for (intptr_t i = 0; i < predecessors_.length(); ++i) {
220 if (predecessors_[i] == pred) return i; 239 if (predecessors_[i] == pred) return i;
221 } 240 }
222 return -1; 241 return -1;
223 } 242 }
(...skipping 13 matching lines...) Expand all
237 } 256 }
238 } 257 }
239 258
240 259
241 void Instruction::RecordAssignedVars(BitVector* assigned_vars, 260 void Instruction::RecordAssignedVars(BitVector* assigned_vars,
242 intptr_t fixed_parameter_count) { 261 intptr_t fixed_parameter_count) {
243 // Nothing to do for the base class. 262 // Nothing to do for the base class.
244 } 263 }
245 264
246 265
266 RawAbstractType* BindInstr::CompileType() const {
267 if (HasPropagatedType()) {
268 return PropagatedType();
269 }
270 // The compile type may be requested when building the flow graph, i.e. before
271 // type propagation has occurred.
272 return computation()->CompileType();
273 }
274
275
247 void BindInstr::RecordAssignedVars(BitVector* assigned_vars, 276 void BindInstr::RecordAssignedVars(BitVector* assigned_vars,
248 intptr_t fixed_parameter_count) { 277 intptr_t fixed_parameter_count) {
249 computation()->RecordAssignedVars(assigned_vars, fixed_parameter_count); 278 computation()->RecordAssignedVars(assigned_vars, fixed_parameter_count);
250 } 279 }
251 280
252 281
253 // ==== Postorder graph traversal. 282 // ==== Postorder graph traversal.
254 void GraphEntryInstr::DiscoverBlocks( 283 void GraphEntryInstr::DiscoverBlocks(
255 BlockEntryInstr* current_block, 284 BlockEntryInstr* current_block,
256 GrowableArray<BlockEntryInstr*>* preorder, 285 GrowableArray<BlockEntryInstr*>* preorder,
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 ASSERT(index == 0); 492 ASSERT(index == 0);
464 return successor(); 493 return successor();
465 } 494 }
466 495
467 496
468 void Instruction::Goto(JoinEntryInstr* entry) { 497 void Instruction::Goto(JoinEntryInstr* entry) {
469 set_next(new GotoInstr(entry)); 498 set_next(new GotoInstr(entry));
470 } 499 }
471 500
472 501
473 // ==== Support for propagating static type. 502 RawAbstractType* ConstantVal::CompileType() const {
474 RawAbstractType* ConstantVal::StaticType() const { 503 if (value().IsNull()) {
504 return Type::NullType();
505 }
475 if (value().IsInstance()) { 506 if (value().IsInstance()) {
476 return Instance::Cast(value()).GetType(); 507 return Instance::Cast(value()).GetType();
477 } else { 508 } else {
478 UNREACHABLE(); 509 ASSERT(value().IsAbstractTypeArguments());
479 return AbstractType::null(); 510 return AbstractType::null();
480 } 511 }
481 } 512 }
482 513
483 514
484 RawAbstractType* UseVal::StaticType() const { 515 RawAbstractType* UseVal::CompileType() const {
485 return definition()->StaticType(); 516 return definition()->CompileType();
486 } 517 }
487 518
488 519
489 RawAbstractType* AssertAssignableComp::StaticType() const { 520 RawAbstractType* AssertAssignableComp::CompileType() const {
490 const AbstractType& value_static_type = 521 const AbstractType& value_static_type =
491 AbstractType::Handle(value()->StaticType()); 522 AbstractType::Handle(value()->CompileType());
492 if (value_static_type.IsMoreSpecificThan(dst_type(), NULL)) { 523 if (value_static_type.IsMoreSpecificThan(dst_type(), NULL)) {
493 return value_static_type.raw(); 524 return value_static_type.raw();
494 } 525 }
495 return dst_type().raw(); 526 return dst_type().raw();
496 } 527 }
497 528
498 529
499 RawAbstractType* AssertBooleanComp::StaticType() const { 530 RawAbstractType* AssertBooleanComp::CompileType() const {
500 return Type::BoolInterface(); 531 return Type::BoolInterface();
501 } 532 }
502 533
503 534
504 RawAbstractType* CurrentContextComp::StaticType() const { 535 RawAbstractType* CurrentContextComp::CompileType() const {
505 UNREACHABLE();
506 return AbstractType::null(); 536 return AbstractType::null();
507 } 537 }
508 538
509 539
510 RawAbstractType* StoreContextComp::StaticType() const { 540 RawAbstractType* StoreContextComp::CompileType() const {
511 UNREACHABLE();
512 return AbstractType::null(); 541 return AbstractType::null();
513 } 542 }
514 543
515 544
516 RawAbstractType* ClosureCallComp::StaticType() const { 545 RawAbstractType* ClosureCallComp::CompileType() const {
517 // Because of function subtyping rules, the static return type of a closure 546 // Because of function subtyping rules, the declared return type of a closure
518 // call cannot be relied upon for static type analysis. For example, a 547 // call cannot be relied upon for compile type analysis. For example, a
519 // function returning Dynamic can be assigned to a closure variable declared 548 // function returning Dynamic can be assigned to a closure variable declared
520 // to return int and may actually return a double at run-time. 549 // to return int and may actually return a double at run-time.
521 return Type::DynamicType(); 550 return Type::DynamicType();
522 } 551 }
523 552
524 553
525 RawAbstractType* InstanceCallComp::StaticType() const { 554 RawAbstractType* InstanceCallComp::CompileType() const {
526 // TODO(regis): Return a more specific type than Dynamic for recognized 555 // TODO(regis): Return a more specific type than Dynamic for recognized
527 // combinations of receiver static type and method name. 556 // combinations of receiver type and method name.
528 return Type::DynamicType(); 557 return Type::DynamicType();
529 } 558 }
530 559
531 560
532 RawAbstractType* PolymorphicInstanceCallComp::StaticType() const { 561 RawAbstractType* PolymorphicInstanceCallComp::CompileType() const {
533 return Type::DynamicType(); 562 return Type::DynamicType();
534 } 563 }
535 564
536 565
537 RawAbstractType* StaticCallComp::StaticType() const { 566 RawAbstractType* StaticCallComp::CompileType() const {
538 return function().result_type(); 567 return function().result_type();
539 } 568 }
540 569
541 570
542 RawAbstractType* LoadLocalComp::StaticType() const { 571 RawAbstractType* LoadLocalComp::CompileType() const {
543 // TODO(regis): Verify that the type of the receiver is properly set.
544 if (FLAG_enable_type_checks) { 572 if (FLAG_enable_type_checks) {
545 return local().type().raw(); 573 return local().type().raw();
546 } 574 }
547 return Type::DynamicType(); 575 return Type::DynamicType();
548 } 576 }
549 577
550 578
551 RawAbstractType* StoreLocalComp::StaticType() const { 579 RawAbstractType* StoreLocalComp::CompileType() const {
552 return value()->StaticType(); 580 return value()->CompileType();
553 } 581 }
554 582
555 583
556 RawAbstractType* StrictCompareComp::StaticType() const { 584 RawAbstractType* StrictCompareComp::CompileType() const {
557 return Type::BoolInterface(); 585 return Type::BoolInterface();
558 } 586 }
559 587
560 588
561 RawAbstractType* EqualityCompareComp::StaticType() const { 589 RawAbstractType* EqualityCompareComp::CompileType() const {
562 return Type::BoolInterface(); 590 return Type::BoolInterface();
563 } 591 }
564 592
565 593
566 RawAbstractType* RelationalOpComp::StaticType() const { 594 RawAbstractType* RelationalOpComp::CompileType() const {
567 return Type::BoolInterface(); 595 return Type::BoolInterface();
568 } 596 }
569 597
570 598
571 RawAbstractType* NativeCallComp::StaticType() const { 599 RawAbstractType* NativeCallComp::CompileType() const {
572 // The result type of the native function is identical to the result type of 600 // The result type of the native function is identical to the result type of
573 // the enclosing native Dart function. However, we prefer to check the type 601 // the enclosing native Dart function. However, we prefer to check the type
574 // of the value returned from the native call. 602 // of the value returned from the native call.
575 return Type::DynamicType(); 603 return Type::DynamicType();
576 } 604 }
577 605
578 606
579 RawAbstractType* LoadIndexedComp::StaticType() const { 607 RawAbstractType* LoadIndexedComp::CompileType() const {
580 return Type::DynamicType(); 608 return Type::DynamicType();
581 } 609 }
582 610
583 611
584 RawAbstractType* StoreIndexedComp::StaticType() const { 612 RawAbstractType* StoreIndexedComp::CompileType() const {
585 UNREACHABLE();
586 return AbstractType::null(); 613 return AbstractType::null();
587 } 614 }
588 615
589 616
590 RawAbstractType* LoadInstanceFieldComp::StaticType() const { 617 RawAbstractType* LoadInstanceFieldComp::CompileType() const {
591 if (FLAG_enable_type_checks) { 618 if (FLAG_enable_type_checks) {
592 return field().type(); 619 return field().type();
593 } 620 }
594 return Type::DynamicType(); 621 return Type::DynamicType();
595 } 622 }
596 623
597 624
598 RawAbstractType* StoreInstanceFieldComp::StaticType() const { 625 RawAbstractType* StoreInstanceFieldComp::CompileType() const {
599 return value()->StaticType(); 626 return value()->CompileType();
600 } 627 }
601 628
602 629
603 RawAbstractType* LoadStaticFieldComp::StaticType() const { 630 RawAbstractType* LoadStaticFieldComp::CompileType() const {
604 if (FLAG_enable_type_checks) { 631 if (FLAG_enable_type_checks) {
605 return field().type(); 632 return field().type();
606 } 633 }
607 return Type::DynamicType(); 634 return Type::DynamicType();
608 } 635 }
609 636
610 637
611 RawAbstractType* StoreStaticFieldComp::StaticType() const { 638 RawAbstractType* StoreStaticFieldComp::CompileType() const {
612 return value()->StaticType(); 639 return value()->CompileType();
613 } 640 }
614 641
615 642
616 RawAbstractType* BooleanNegateComp::StaticType() const { 643 RawAbstractType* BooleanNegateComp::CompileType() const {
617 return Type::BoolInterface(); 644 return Type::BoolInterface();
618 } 645 }
619 646
620 647
621 RawAbstractType* InstanceOfComp::StaticType() const { 648 RawAbstractType* InstanceOfComp::CompileType() const {
622 return Type::BoolInterface(); 649 return Type::BoolInterface();
623 } 650 }
624 651
625 652
626 RawAbstractType* CreateArrayComp::StaticType() const { 653 RawAbstractType* CreateArrayComp::CompileType() const {
627 UNREACHABLE(); 654 // TODO(regis): Be more specific.
628 return AbstractType::null(); 655 return Type::DynamicType();
629 } 656 }
630 657
631 658
632 RawAbstractType* CreateClosureComp::StaticType() const { 659 RawAbstractType* CreateClosureComp::CompileType() const {
633 const Function& fun = function(); 660 const Function& fun = function();
634 const Class& signature_class = Class::Handle(fun.signature_class()); 661 const Class& signature_class = Class::Handle(fun.signature_class());
635 return signature_class.SignatureType(); 662 return signature_class.SignatureType();
636 } 663 }
637 664
638 665
639 RawAbstractType* AllocateObjectComp::StaticType() const { 666 RawAbstractType* AllocateObjectComp::CompileType() const {
640 // TODO(regis): Be more specific. 667 // TODO(regis): Be more specific.
641 return Type::DynamicType(); 668 return Type::DynamicType();
642 } 669 }
643 670
644 671
645 RawAbstractType* AllocateObjectWithBoundsCheckComp::StaticType() const { 672 RawAbstractType* AllocateObjectWithBoundsCheckComp::CompileType() const {
646 UNREACHABLE(); 673 // TODO(regis): Be more specific.
674 return Type::DynamicType();
675 }
676
677
678 RawAbstractType* LoadVMFieldComp::CompileType() const {
679 // Type may be null if the field is a VM field, e.g. context parent.
680 return type().raw();
681 }
682
683
684 RawAbstractType* StoreVMFieldComp::CompileType() const {
685 return value()->CompileType();
686 }
687
688
689 RawAbstractType* InstantiateTypeArgumentsComp::CompileType() const {
647 return AbstractType::null(); 690 return AbstractType::null();
648 } 691 }
649 692
650 693
651 RawAbstractType* LoadVMFieldComp::StaticType() const { 694 RawAbstractType* ExtractConstructorTypeArgumentsComp::CompileType() const {
652 ASSERT(!type().IsNull());
653 return type().raw();
654 }
655
656
657 RawAbstractType* StoreVMFieldComp::StaticType() const {
658 return value()->StaticType();
659 }
660
661
662 RawAbstractType* InstantiateTypeArgumentsComp::StaticType() const {
663 UNREACHABLE();
664 return AbstractType::null(); 695 return AbstractType::null();
665 } 696 }
666 697
667 698
668 RawAbstractType* ExtractConstructorTypeArgumentsComp::StaticType() const { 699 RawAbstractType* ExtractConstructorInstantiatorComp::CompileType() const {
669 UNREACHABLE();
670 return AbstractType::null(); 700 return AbstractType::null();
671 } 701 }
672 702
673 703
674 RawAbstractType* ExtractConstructorInstantiatorComp::StaticType() const { 704 RawAbstractType* AllocateContextComp::CompileType() const {
675 UNREACHABLE();
676 return AbstractType::null(); 705 return AbstractType::null();
677 } 706 }
678 707
679 708
680 RawAbstractType* AllocateContextComp::StaticType() const { 709 RawAbstractType* ChainContextComp::CompileType() const {
681 UNREACHABLE();
682 return AbstractType::null(); 710 return AbstractType::null();
683 } 711 }
684 712
685 713
686 RawAbstractType* ChainContextComp::StaticType() const { 714 RawAbstractType* CloneContextComp::CompileType() const {
687 UNREACHABLE();
688 return AbstractType::null(); 715 return AbstractType::null();
689 } 716 }
690 717
691 718
692 RawAbstractType* CloneContextComp::StaticType() const { 719 RawAbstractType* CatchEntryComp::CompileType() const {
693 UNREACHABLE();
694 return AbstractType::null(); 720 return AbstractType::null();
695 } 721 }
696 722
697 723
698 RawAbstractType* CatchEntryComp::StaticType() const { 724 RawAbstractType* CheckStackOverflowComp::CompileType() const {
699 UNREACHABLE(); 725 return Type::VoidType();
700 return AbstractType::null();
701 } 726 }
702 727
703 728
704 RawAbstractType* CheckStackOverflowComp::StaticType() const { 729 RawAbstractType* BinaryOpComp::CompileType() const {
705 UNREACHABLE();
706 return AbstractType::null();
707 }
708
709
710 RawAbstractType* BinaryOpComp::StaticType() const {
711 // TODO(srdjan): Compute based on input types (ICData). 730 // TODO(srdjan): Compute based on input types (ICData).
712 return Type::DynamicType(); 731 return Type::DynamicType();
713 } 732 }
714 733
715 734
716 RawAbstractType* DoubleBinaryOpComp::StaticType() const { 735 RawAbstractType* DoubleBinaryOpComp::CompileType() const {
717 return Type::DoubleInterface(); 736 return Type::DoubleInterface();
718 } 737 }
719 738
720 739
721 RawAbstractType* UnarySmiOpComp::StaticType() const { 740 RawAbstractType* UnarySmiOpComp::CompileType() const {
722 return Type::IntInterface(); 741 return Type::IntInterface();
723 } 742 }
724 743
725 744
726 RawAbstractType* NumberNegateComp::StaticType() const { 745 RawAbstractType* NumberNegateComp::CompileType() const {
727 return Type::NumberInterface(); 746 return Type::NumberInterface();
728 } 747 }
729 748
730 749
731 RawAbstractType* ToDoubleComp::StaticType() const { 750 RawAbstractType* ToDoubleComp::CompileType() const {
732 return Type::DoubleInterface(); 751 return Type::DoubleInterface();
733 } 752 }
734 753
735 754
736 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and 755 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and
737 // PrepareEntry). Only assembly code that can be shared across all architectures 756 // PrepareEntry). Only assembly code that can be shared across all architectures
738 // can be used. Machine specific register allocation and code generation 757 // can be used. Machine specific register allocation and code generation
739 // is located in intermediate_language_<arch>.cc 758 // is located in intermediate_language_<arch>.cc
740 759
741 760
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 return NULL; 1043 return NULL;
1025 } 1044 }
1026 1045
1027 1046
1028 void UseVal::EmitNativeCode(FlowGraphCompiler* compiler) { 1047 void UseVal::EmitNativeCode(FlowGraphCompiler* compiler) {
1029 UNIMPLEMENTED(); 1048 UNIMPLEMENTED();
1030 } 1049 }
1031 1050
1032 1051
1033 void AssertAssignableComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1052 void AssertAssignableComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1034 compiler->GenerateAssertAssignable(deopt_id(), 1053 if (!IsEliminated()) {
regis 2012/08/09 23:51:37 This makes sure eliminated type checks are not emi
1035 token_pos(), 1054 compiler->GenerateAssertAssignable(deopt_id(),
1036 try_index(), 1055 token_pos(),
1037 dst_type(), 1056 try_index(),
1038 dst_name()); 1057 dst_type(),
1058 dst_name());
1059 }
1039 ASSERT(locs()->in(0).reg() == locs()->out().reg()); 1060 ASSERT(locs()->in(0).reg() == locs()->out().reg());
1040 } 1061 }
1041 1062
1042 1063
1043 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const { 1064 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const {
1044 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); 1065 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall);
1045 locs->set_in(0, Location::RequiresRegister()); 1066 locs->set_in(0, Location::RequiresRegister());
1046 locs->set_temp(0, Location::RequiresRegister()); 1067 locs->set_temp(0, Location::RequiresRegister());
1047 locs->set_out(Location::SameAsFirstInput()); 1068 locs->set_out(Location::SameAsFirstInput());
1048 return locs; 1069 return locs;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 locations_[i] = Location::NoLocation(); 1221 locations_[i] = Location::NoLocation();
1201 } 1222 }
1202 } 1223 }
1203 } 1224 }
1204 } 1225 }
1205 1226
1206 1227
1207 #undef __ 1228 #undef __
1208 1229
1209 } // namespace dart 1230 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698