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

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
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/object.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 (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& compile_type = AbstractType::Handle(CompileType());
146 ASSERT(!static_type.IsMalformed()); 146 ASSERT(!compile_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 (compile_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 (compile_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 compile_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 if (HasPropagatedType()) {
184 // It is much simpler to compute the least specific of the input static types, 184 return PropagatedType();
185 // and it may be good enough in practice. 185 }
186 // Even better: we could keep the set of the input static types intact. 186 // If type propagation has not yet occured, we are reaching this phi via a
187 AbstractType& least_specific_type = 187 // back edge phi input. Return null as compile type so that this input is
188 AbstractType::Handle(InputAt(0)->StaticType()); 188 // ignored in the first iteration of type propagation.
189 return AbstractType::null();
190 }
191
192
193 RawAbstractType* PhiInstr::LeastSpecificInputType() const {
194 AbstractType& least_specific_type = AbstractType::Handle();
189 AbstractType& input_type = AbstractType::Handle(); 195 AbstractType& input_type = AbstractType::Handle();
190 for (intptr_t i = 1; i < InputCount(); i++) { 196 for (intptr_t i = 0; i < InputCount(); i++) {
191 input_type = InputAt(i)->StaticType(); 197 input_type = InputAt(i)->CompileType();
192 if (input_type.IsMoreSpecificThan(least_specific_type, NULL)) { 198 if (input_type.IsNull()) {
193 // Type least_specific_type is less specific than input_type. No change. 199 // This input is on a back edge and we are in the first iteration of type
194 } else if (least_specific_type.IsMoreSpecificThan(input_type, NULL)) { 200 // propagation. Ignore it.
201 continue;
202 }
203 ASSERT(!input_type.IsNull());
204 if (least_specific_type.IsNull() ||
205 least_specific_type.IsMoreSpecificThan(input_type, NULL)) {
195 // Type input_type is less specific than the current least_specific_type. 206 // Type input_type is less specific than the current least_specific_type.
196 least_specific_type = input_type.raw(); 207 least_specific_type = input_type.raw();
208 } else if (input_type.IsMoreSpecificThan(least_specific_type, NULL)) {
209 // Type least_specific_type is less specific than input_type. No change.
197 } else { 210 } else {
198 // The types are unrelated. No need to continue. 211 // The types are unrelated. No need to continue.
199 least_specific_type = Type::ObjectType(); 212 least_specific_type = Type::ObjectType();
200 break; 213 break;
201 } 214 }
202 } 215 }
203 return least_specific_type.raw(); 216 return least_specific_type.raw();
204 } 217 }
205 218
206 219
207 RawAbstractType* ParameterInstr::StaticType() const { 220 RawAbstractType* ParameterInstr::CompileType() const {
208 // TODO(regis): Can type feedback provide information about the static type 221 // TODO(regis): Can type feedback provide information about the compile type
209 // of a passed-in parameter? 222 // 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 223 // propagated_type_ field.
211 // parameter. However, this would be wrong if ParameterInstr is used to type 224 if (HasPropagatedType()) {
212 // check the passed-in parameter, since the type check would then always be 225 return PropagatedType();
213 // wrongly eliminated. 226 }
227 // Note that returning the declared type of the formal parameter would be
228 // incorrect, because ParameterInstr is used as input to the type check
229 // verifying the run time type of the passed-in parameter and this check would
230 // always be wrongly eliminated.
214 return Type::DynamicType(); 231 return Type::DynamicType();
215 } 232 }
216 233
217 234
218 intptr_t JoinEntryInstr::IndexOfPredecessor(BlockEntryInstr* pred) const { 235 intptr_t JoinEntryInstr::IndexOfPredecessor(BlockEntryInstr* pred) const {
219 for (intptr_t i = 0; i < predecessors_.length(); ++i) { 236 for (intptr_t i = 0; i < predecessors_.length(); ++i) {
220 if (predecessors_[i] == pred) return i; 237 if (predecessors_[i] == pred) return i;
221 } 238 }
222 return -1; 239 return -1;
223 } 240 }
(...skipping 13 matching lines...) Expand all
237 } 254 }
238 } 255 }
239 256
240 257
241 void Instruction::RecordAssignedVars(BitVector* assigned_vars, 258 void Instruction::RecordAssignedVars(BitVector* assigned_vars,
242 intptr_t fixed_parameter_count) { 259 intptr_t fixed_parameter_count) {
243 // Nothing to do for the base class. 260 // Nothing to do for the base class.
244 } 261 }
245 262
246 263
264 RawAbstractType* BindInstr::CompileType() const {
265 if (HasPropagatedType()) {
266 return PropagatedType();
267 }
268 // The compile type may be requested when building the flow graph, i.e. before
269 // type propagation has occurred.
270 return computation()->CompileType();
271 }
272
273
247 void BindInstr::RecordAssignedVars(BitVector* assigned_vars, 274 void BindInstr::RecordAssignedVars(BitVector* assigned_vars,
248 intptr_t fixed_parameter_count) { 275 intptr_t fixed_parameter_count) {
249 computation()->RecordAssignedVars(assigned_vars, fixed_parameter_count); 276 computation()->RecordAssignedVars(assigned_vars, fixed_parameter_count);
250 } 277 }
251 278
252 279
253 // ==== Postorder graph traversal. 280 // ==== Postorder graph traversal.
254 void GraphEntryInstr::DiscoverBlocks( 281 void GraphEntryInstr::DiscoverBlocks(
255 BlockEntryInstr* current_block, 282 BlockEntryInstr* current_block,
256 GrowableArray<BlockEntryInstr*>* preorder, 283 GrowableArray<BlockEntryInstr*>* preorder,
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 ASSERT(index == 0); 490 ASSERT(index == 0);
464 return successor(); 491 return successor();
465 } 492 }
466 493
467 494
468 void Instruction::Goto(JoinEntryInstr* entry) { 495 void Instruction::Goto(JoinEntryInstr* entry) {
469 set_next(new GotoInstr(entry)); 496 set_next(new GotoInstr(entry));
470 } 497 }
471 498
472 499
473 // ==== Support for propagating static type. 500 RawAbstractType* ConstantVal::CompileType() const {
474 RawAbstractType* ConstantVal::StaticType() const { 501 if (value().IsNull()) {
502 return Type::NullType();
503 }
475 if (value().IsInstance()) { 504 if (value().IsInstance()) {
476 return Instance::Cast(value()).GetType(); 505 return Instance::Cast(value()).GetType();
477 } else { 506 } else {
478 UNREACHABLE(); 507 ASSERT(value().IsAbstractTypeArguments());
479 return AbstractType::null(); 508 return AbstractType::null();
480 } 509 }
481 } 510 }
482 511
483 512
484 RawAbstractType* UseVal::StaticType() const { 513 RawAbstractType* UseVal::CompileType() const {
485 return definition()->StaticType(); 514 return definition()->CompileType();
486 } 515 }
487 516
488 517
489 RawAbstractType* AssertAssignableComp::StaticType() const { 518 RawAbstractType* AssertAssignableComp::CompileType() const {
490 const AbstractType& value_static_type = 519 const AbstractType& value_compile_type =
491 AbstractType::Handle(value()->StaticType()); 520 AbstractType::Handle(value()->CompileType());
492 if (value_static_type.IsMoreSpecificThan(dst_type(), NULL)) { 521 if (value_compile_type.IsMoreSpecificThan(dst_type(), NULL)) {
493 return value_static_type.raw(); 522 return value_compile_type.raw();
494 } 523 }
495 return dst_type().raw(); 524 return dst_type().raw();
496 } 525 }
497 526
498 527
499 RawAbstractType* AssertBooleanComp::StaticType() const { 528 RawAbstractType* AssertBooleanComp::CompileType() const {
500 return Type::BoolInterface(); 529 return Type::BoolInterface();
501 } 530 }
502 531
503 532
504 RawAbstractType* CurrentContextComp::StaticType() const { 533 RawAbstractType* CurrentContextComp::CompileType() const {
505 UNREACHABLE();
506 return AbstractType::null(); 534 return AbstractType::null();
507 } 535 }
508 536
509 537
510 RawAbstractType* StoreContextComp::StaticType() const { 538 RawAbstractType* StoreContextComp::CompileType() const {
511 UNREACHABLE();
512 return AbstractType::null(); 539 return AbstractType::null();
513 } 540 }
514 541
515 542
516 RawAbstractType* ClosureCallComp::StaticType() const { 543 RawAbstractType* ClosureCallComp::CompileType() const {
517 // Because of function subtyping rules, the static return type of a closure 544 // 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 545 // call cannot be relied upon for compile type analysis. For example, a
519 // function returning Dynamic can be assigned to a closure variable declared 546 // function returning Dynamic can be assigned to a closure variable declared
520 // to return int and may actually return a double at run-time. 547 // to return int and may actually return a double at run-time.
521 return Type::DynamicType(); 548 return Type::DynamicType();
522 } 549 }
523 550
524 551
525 RawAbstractType* InstanceCallComp::StaticType() const { 552 RawAbstractType* InstanceCallComp::CompileType() const {
526 // TODO(regis): Return a more specific type than Dynamic for recognized 553 // TODO(regis): Return a more specific type than Dynamic for recognized
527 // combinations of receiver static type and method name. 554 // combinations of receiver type and method name.
528 return Type::DynamicType(); 555 return Type::DynamicType();
529 } 556 }
530 557
531 558
532 RawAbstractType* PolymorphicInstanceCallComp::StaticType() const { 559 RawAbstractType* PolymorphicInstanceCallComp::CompileType() const {
533 return Type::DynamicType(); 560 return Type::DynamicType();
534 } 561 }
535 562
536 563
537 RawAbstractType* StaticCallComp::StaticType() const { 564 RawAbstractType* StaticCallComp::CompileType() const {
538 return function().result_type(); 565 return function().result_type();
539 } 566 }
540 567
541 568
542 RawAbstractType* LoadLocalComp::StaticType() const { 569 RawAbstractType* LoadLocalComp::CompileType() const {
543 // TODO(regis): Verify that the type of the receiver is properly set.
544 if (FLAG_enable_type_checks) { 570 if (FLAG_enable_type_checks) {
545 return local().type().raw(); 571 return local().type().raw();
546 } 572 }
547 return Type::DynamicType(); 573 return Type::DynamicType();
548 } 574 }
549 575
550 576
551 RawAbstractType* StoreLocalComp::StaticType() const { 577 RawAbstractType* StoreLocalComp::CompileType() const {
552 return value()->StaticType(); 578 return value()->CompileType();
553 } 579 }
554 580
555 581
556 RawAbstractType* StrictCompareComp::StaticType() const { 582 RawAbstractType* StrictCompareComp::CompileType() const {
557 return Type::BoolInterface(); 583 return Type::BoolInterface();
558 } 584 }
559 585
560 586
561 RawAbstractType* EqualityCompareComp::StaticType() const { 587 RawAbstractType* EqualityCompareComp::CompileType() const {
562 return Type::BoolInterface(); 588 return Type::BoolInterface();
563 } 589 }
564 590
565 591
566 RawAbstractType* RelationalOpComp::StaticType() const { 592 RawAbstractType* RelationalOpComp::CompileType() const {
567 return Type::BoolInterface(); 593 return Type::BoolInterface();
568 } 594 }
569 595
570 596
571 RawAbstractType* NativeCallComp::StaticType() const { 597 RawAbstractType* NativeCallComp::CompileType() const {
572 // The result type of the native function is identical to the result type of 598 // 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 599 // the enclosing native Dart function. However, we prefer to check the type
574 // of the value returned from the native call. 600 // of the value returned from the native call.
575 return Type::DynamicType(); 601 return Type::DynamicType();
576 } 602 }
577 603
578 604
579 RawAbstractType* LoadIndexedComp::StaticType() const { 605 RawAbstractType* LoadIndexedComp::CompileType() const {
580 return Type::DynamicType(); 606 return Type::DynamicType();
581 } 607 }
582 608
583 609
584 RawAbstractType* StoreIndexedComp::StaticType() const { 610 RawAbstractType* StoreIndexedComp::CompileType() const {
585 UNREACHABLE();
586 return AbstractType::null(); 611 return AbstractType::null();
587 } 612 }
588 613
589 614
590 RawAbstractType* LoadInstanceFieldComp::StaticType() const { 615 RawAbstractType* LoadInstanceFieldComp::CompileType() const {
591 if (FLAG_enable_type_checks) { 616 if (FLAG_enable_type_checks) {
592 return field().type(); 617 return field().type();
593 } 618 }
594 return Type::DynamicType(); 619 return Type::DynamicType();
595 } 620 }
596 621
597 622
598 RawAbstractType* StoreInstanceFieldComp::StaticType() const { 623 RawAbstractType* StoreInstanceFieldComp::CompileType() const {
599 return value()->StaticType(); 624 return value()->CompileType();
600 } 625 }
601 626
602 627
603 RawAbstractType* LoadStaticFieldComp::StaticType() const { 628 RawAbstractType* LoadStaticFieldComp::CompileType() const {
604 if (FLAG_enable_type_checks) { 629 if (FLAG_enable_type_checks) {
605 return field().type(); 630 return field().type();
606 } 631 }
607 return Type::DynamicType(); 632 return Type::DynamicType();
608 } 633 }
609 634
610 635
611 RawAbstractType* StoreStaticFieldComp::StaticType() const { 636 RawAbstractType* StoreStaticFieldComp::CompileType() const {
612 return value()->StaticType(); 637 return value()->CompileType();
613 } 638 }
614 639
615 640
616 RawAbstractType* BooleanNegateComp::StaticType() const { 641 RawAbstractType* BooleanNegateComp::CompileType() const {
617 return Type::BoolInterface(); 642 return Type::BoolInterface();
618 } 643 }
619 644
620 645
621 RawAbstractType* InstanceOfComp::StaticType() const { 646 RawAbstractType* InstanceOfComp::CompileType() const {
622 return Type::BoolInterface(); 647 return Type::BoolInterface();
623 } 648 }
624 649
625 650
626 RawAbstractType* CreateArrayComp::StaticType() const { 651 RawAbstractType* CreateArrayComp::CompileType() const {
627 UNREACHABLE(); 652 // TODO(regis): Be more specific.
628 return AbstractType::null(); 653 return Type::DynamicType();
629 } 654 }
630 655
631 656
632 RawAbstractType* CreateClosureComp::StaticType() const { 657 RawAbstractType* CreateClosureComp::CompileType() const {
633 const Function& fun = function(); 658 const Function& fun = function();
634 const Class& signature_class = Class::Handle(fun.signature_class()); 659 const Class& signature_class = Class::Handle(fun.signature_class());
635 return signature_class.SignatureType(); 660 return signature_class.SignatureType();
636 } 661 }
637 662
638 663
639 RawAbstractType* AllocateObjectComp::StaticType() const { 664 RawAbstractType* AllocateObjectComp::CompileType() const {
640 // TODO(regis): Be more specific. 665 // TODO(regis): Be more specific.
641 return Type::DynamicType(); 666 return Type::DynamicType();
642 } 667 }
643 668
644 669
645 RawAbstractType* AllocateObjectWithBoundsCheckComp::StaticType() const { 670 RawAbstractType* AllocateObjectWithBoundsCheckComp::CompileType() const {
646 UNREACHABLE(); 671 // TODO(regis): Be more specific.
672 return Type::DynamicType();
673 }
674
675
676 RawAbstractType* LoadVMFieldComp::CompileType() const {
677 // Type may be null if the field is a VM field, e.g. context parent.
678 return type().raw();
679 }
680
681
682 RawAbstractType* StoreVMFieldComp::CompileType() const {
683 return value()->CompileType();
684 }
685
686
687 RawAbstractType* InstantiateTypeArgumentsComp::CompileType() const {
647 return AbstractType::null(); 688 return AbstractType::null();
648 } 689 }
649 690
650 691
651 RawAbstractType* LoadVMFieldComp::StaticType() const { 692 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(); 693 return AbstractType::null();
665 } 694 }
666 695
667 696
668 RawAbstractType* ExtractConstructorTypeArgumentsComp::StaticType() const { 697 RawAbstractType* ExtractConstructorInstantiatorComp::CompileType() const {
669 UNREACHABLE();
670 return AbstractType::null(); 698 return AbstractType::null();
671 } 699 }
672 700
673 701
674 RawAbstractType* ExtractConstructorInstantiatorComp::StaticType() const { 702 RawAbstractType* AllocateContextComp::CompileType() const {
675 UNREACHABLE();
676 return AbstractType::null(); 703 return AbstractType::null();
677 } 704 }
678 705
679 706
680 RawAbstractType* AllocateContextComp::StaticType() const { 707 RawAbstractType* ChainContextComp::CompileType() const {
681 UNREACHABLE();
682 return AbstractType::null(); 708 return AbstractType::null();
683 } 709 }
684 710
685 711
686 RawAbstractType* ChainContextComp::StaticType() const { 712 RawAbstractType* CloneContextComp::CompileType() const {
687 UNREACHABLE();
688 return AbstractType::null(); 713 return AbstractType::null();
689 } 714 }
690 715
691 716
692 RawAbstractType* CloneContextComp::StaticType() const { 717 RawAbstractType* CatchEntryComp::CompileType() const {
693 UNREACHABLE();
694 return AbstractType::null(); 718 return AbstractType::null();
695 } 719 }
696 720
697 721
698 RawAbstractType* CatchEntryComp::StaticType() const { 722 RawAbstractType* CheckStackOverflowComp::CompileType() const {
699 UNREACHABLE(); 723 return Type::VoidType();
700 return AbstractType::null();
701 } 724 }
702 725
703 726
704 RawAbstractType* CheckStackOverflowComp::StaticType() const { 727 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). 728 // TODO(srdjan): Compute based on input types (ICData).
712 return Type::DynamicType(); 729 return Type::DynamicType();
713 } 730 }
714 731
715 732
716 RawAbstractType* DoubleBinaryOpComp::StaticType() const { 733 RawAbstractType* DoubleBinaryOpComp::CompileType() const {
717 return Type::DoubleInterface(); 734 return Type::DoubleInterface();
718 } 735 }
719 736
720 737
721 RawAbstractType* UnarySmiOpComp::StaticType() const { 738 RawAbstractType* UnarySmiOpComp::CompileType() const {
722 return Type::IntInterface(); 739 return Type::IntInterface();
723 } 740 }
724 741
725 742
726 RawAbstractType* NumberNegateComp::StaticType() const { 743 RawAbstractType* NumberNegateComp::CompileType() const {
727 return Type::NumberInterface(); 744 return Type::NumberInterface();
728 } 745 }
729 746
730 747
731 RawAbstractType* ToDoubleComp::StaticType() const { 748 RawAbstractType* ToDoubleComp::CompileType() const {
732 return Type::DoubleInterface(); 749 return Type::DoubleInterface();
733 } 750 }
734 751
735 752
736 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and 753 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and
737 // PrepareEntry). Only assembly code that can be shared across all architectures 754 // PrepareEntry). Only assembly code that can be shared across all architectures
738 // can be used. Machine specific register allocation and code generation 755 // can be used. Machine specific register allocation and code generation
739 // is located in intermediate_language_<arch>.cc 756 // is located in intermediate_language_<arch>.cc
740 757
741 758
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 return NULL; 1041 return NULL;
1025 } 1042 }
1026 1043
1027 1044
1028 void UseVal::EmitNativeCode(FlowGraphCompiler* compiler) { 1045 void UseVal::EmitNativeCode(FlowGraphCompiler* compiler) {
1029 UNIMPLEMENTED(); 1046 UNIMPLEMENTED();
1030 } 1047 }
1031 1048
1032 1049
1033 void AssertAssignableComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1050 void AssertAssignableComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1034 compiler->GenerateAssertAssignable(deopt_id(), 1051 if (!IsEliminated()) {
1035 token_pos(), 1052 compiler->GenerateAssertAssignable(deopt_id(),
1036 try_index(), 1053 token_pos(),
1037 dst_type(), 1054 try_index(),
1038 dst_name()); 1055 dst_type(),
1056 dst_name());
1057 }
1039 ASSERT(locs()->in(0).reg() == locs()->out().reg()); 1058 ASSERT(locs()->in(0).reg() == locs()->out().reg());
1040 } 1059 }
1041 1060
1042 1061
1043 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const { 1062 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const {
1044 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); 1063 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall);
1045 locs->set_in(0, Location::RequiresRegister()); 1064 locs->set_in(0, Location::RequiresRegister());
1046 locs->set_temp(0, Location::RequiresRegister()); 1065 locs->set_temp(0, Location::RequiresRegister());
1047 locs->set_out(Location::SameAsFirstInput()); 1066 locs->set_out(Location::SameAsFirstInput());
1048 return locs; 1067 return locs;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 locations_[i] = Location::NoLocation(); 1219 locations_[i] = Location::NoLocation();
1201 } 1220 }
1202 } 1221 }
1203 } 1222 }
1204 } 1223 }
1205 1224
1206 1225
1207 #undef __ 1226 #undef __
1208 1227
1209 } // namespace dart 1228 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698