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

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

Issue 670263007: IR refactoring: consolidate all boxing and unboxing instructions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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/il_printer.cc ('k') | runtime/vm/intermediate_language.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_
6 #define VM_INTERMEDIATE_LANGUAGE_H_ 6 #define VM_INTERMEDIATE_LANGUAGE_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/ast.h" 9 #include "vm/ast.h"
10 #include "vm/growable_array.h" 10 #include "vm/growable_array.h"
11 #include "vm/handles_impl.h" 11 #include "vm/handles_impl.h"
12 #include "vm/locations.h" 12 #include "vm/locations.h"
13 #include "vm/method_recognizer.h" 13 #include "vm/method_recognizer.h"
14 #include "vm/object.h" 14 #include "vm/object.h"
15 #include "vm/parser.h" 15 #include "vm/parser.h"
16 16
17 namespace dart { 17 namespace dart {
18 18
19 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); 19 DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
20 20
21 class BitVector; 21 class BitVector;
22 class BlockEntryInstr; 22 class BlockEntryInstr;
23 class BoxIntNInstr; 23 class BoxIntegerInstr;
24 class BufferFormatter; 24 class BufferFormatter;
25 class CatchBlockEntryInstr; 25 class CatchBlockEntryInstr;
26 class ComparisonInstr; 26 class ComparisonInstr;
27 class Definition; 27 class Definition;
28 class Environment; 28 class Environment;
29 class FlowGraph; 29 class FlowGraph;
30 class FlowGraphBuilder; 30 class FlowGraphBuilder;
31 class FlowGraphCompiler; 31 class FlowGraphCompiler;
32 class FlowGraphVisitor; 32 class FlowGraphVisitor;
33 class Instruction; 33 class Instruction;
34 class LocalVariable; 34 class LocalVariable;
35 class ParsedFunction; 35 class ParsedFunction;
36 class Range; 36 class Range;
37 class RangeAnalysis; 37 class RangeAnalysis;
38 class RangeBoundary; 38 class RangeBoundary;
39 class UnboxIntNInstr; 39 class UnboxIntegerInstr;
40 40
41 // CompileType describes type of the value produced by the definition. 41 // CompileType describes type of the value produced by the definition.
42 // 42 //
43 // It captures the following properties: 43 // It captures the following properties:
44 // - whether value can potentially be null or it is definitely not null; 44 // - whether value can potentially be null or it is definitely not null;
45 // - concrete class id of the value or kDynamicCid if unknown statically; 45 // - concrete class id of the value or kDynamicCid if unknown statically;
46 // - abstract super type of the value, concrete type of the value in runtime 46 // - abstract super type of the value, concrete type of the value in runtime
47 // is guaranteed to be sub type of this type. 47 // is guaranteed to be sub type of this type.
48 // 48 //
49 // Values of CompileType form a lattice with a None type as a bottom and a 49 // Values of CompileType form a lattice with a None type as a bottom and a
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 M(FloatToDouble) \ 484 M(FloatToDouble) \
485 M(CheckClass) \ 485 M(CheckClass) \
486 M(CheckClassId) \ 486 M(CheckClassId) \
487 M(CheckSmi) \ 487 M(CheckSmi) \
488 M(Constant) \ 488 M(Constant) \
489 M(UnboxedConstant) \ 489 M(UnboxedConstant) \
490 M(CheckEitherNonSmi) \ 490 M(CheckEitherNonSmi) \
491 M(BinaryDoubleOp) \ 491 M(BinaryDoubleOp) \
492 M(MathUnary) \ 492 M(MathUnary) \
493 M(MathMinMax) \ 493 M(MathMinMax) \
494 M(UnboxDouble) \ 494 M(Box) \
495 M(BoxDouble) \ 495 M(Unbox) \
496 M(BoxFloat32x4) \ 496 M(BoxInt64) \
497 M(UnboxFloat32x4) \ 497 M(UnboxInt64) \
498 M(BoxInt32x4) \
499 M(UnboxInt32x4) \
500 M(UnboxInteger) \
501 M(BoxInteger) \
502 M(BinaryMintOp) \ 498 M(BinaryMintOp) \
503 M(ShiftMintOp) \ 499 M(ShiftMintOp) \
504 M(UnaryMintOp) \ 500 M(UnaryMintOp) \
505 M(CheckArrayBound) \ 501 M(CheckArrayBound) \
506 M(Constraint) \ 502 M(Constraint) \
507 M(StringToCharCode) \ 503 M(StringToCharCode) \
508 M(StringFromCharCode) \ 504 M(StringFromCharCode) \
509 M(StringInterpolate) \ 505 M(StringInterpolate) \
510 M(InvokeMathCFunction) \ 506 M(InvokeMathCFunction) \
511 M(MergedMath) \ 507 M(MergedMath) \
(...skipping 18 matching lines...) Expand all
530 M(MaterializeObject) \ 526 M(MaterializeObject) \
531 M(Int32x4Constructor) \ 527 M(Int32x4Constructor) \
532 M(Int32x4BoolConstructor) \ 528 M(Int32x4BoolConstructor) \
533 M(Int32x4GetFlag) \ 529 M(Int32x4GetFlag) \
534 M(Int32x4Select) \ 530 M(Int32x4Select) \
535 M(Int32x4SetFlag) \ 531 M(Int32x4SetFlag) \
536 M(Int32x4ToFloat32x4) \ 532 M(Int32x4ToFloat32x4) \
537 M(BinaryInt32x4Op) \ 533 M(BinaryInt32x4Op) \
538 M(TestSmi) \ 534 M(TestSmi) \
539 M(TestCids) \ 535 M(TestCids) \
540 M(BoxFloat64x2) \
541 M(UnboxFloat64x2) \
542 M(BinaryFloat64x2Op) \ 536 M(BinaryFloat64x2Op) \
543 M(Float64x2Zero) \ 537 M(Float64x2Zero) \
544 M(Float64x2Constructor) \ 538 M(Float64x2Constructor) \
545 M(Float64x2Splat) \ 539 M(Float64x2Splat) \
546 M(Float32x4ToFloat64x2) \ 540 M(Float32x4ToFloat64x2) \
547 M(Float64x2ToFloat32x4) \ 541 M(Float64x2ToFloat32x4) \
548 M(Simd64x2Shuffle) \ 542 M(Simd64x2Shuffle) \
549 M(Float64x2ZeroArg) \ 543 M(Float64x2ZeroArg) \
550 M(Float64x2OneArg) \ 544 M(Float64x2OneArg) \
551 M(ExtractNthOutput) \ 545 M(ExtractNthOutput) \
552 M(BinaryUint32Op) \ 546 M(BinaryUint32Op) \
553 M(ShiftUint32Op) \ 547 M(ShiftUint32Op) \
554 M(UnaryUint32Op) \ 548 M(UnaryUint32Op) \
555 M(BoxUint32) \ 549 M(BoxUint32) \
556 M(UnboxUint32) \ 550 M(UnboxUint32) \
557 M(BoxInt32) \ 551 M(BoxInt32) \
558 M(UnboxInt32) \ 552 M(UnboxInt32) \
559 M(UnboxedIntConverter) \ 553 M(UnboxedIntConverter) \
560 M(Deoptimize) 554 M(Deoptimize)
561 555
562 #define FOR_EACH_ABSTRACT_INSTRUCTION(M) \ 556 #define FOR_EACH_ABSTRACT_INSTRUCTION(M) \
563 M(BlockEntry) \ 557 M(BlockEntry) \
564 M(BoxIntN) \ 558 M(BoxInteger) \
565 M(UnboxIntN) \ 559 M(UnboxInteger) \
566 M(Comparison) \ 560 M(Comparison) \
567 M(UnaryIntegerOp) \ 561 M(UnaryIntegerOp) \
568 M(BinaryIntegerOp) \ 562 M(BinaryIntegerOp) \
569 563
570 #define FORWARD_DECLARATION(type) class type##Instr; 564 #define FORWARD_DECLARATION(type) class type##Instr;
571 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) 565 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
572 FOR_EACH_ABSTRACT_INSTRUCTION(FORWARD_DECLARATION) 566 FOR_EACH_ABSTRACT_INSTRUCTION(FORWARD_DECLARATION)
573 #undef FORWARD_DECLARATION 567 #undef FORWARD_DECLARATION
574 568
575 #define DEFINE_INSTRUCTION_TYPE_CHECK(type) \ 569 #define DEFINE_INSTRUCTION_TYPE_CHECK(type) \
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after
1614 type_ = ComputeInitialType(); 1608 type_ = ComputeInitialType();
1615 } 1609 }
1616 return type_; 1610 return type_;
1617 } 1611 }
1618 1612
1619 virtual CompileType* ComputeInitialType() const { 1613 virtual CompileType* ComputeInitialType() const {
1620 return ZoneCompileType::Wrap(ComputeType()); 1614 return ZoneCompileType::Wrap(ComputeType());
1621 } 1615 }
1622 1616
1623 // Does this define a mint? 1617 // Does this define a mint?
1624 bool IsMintDefinition() { 1618 inline bool IsMintDefinition();
1625 return (Type()->ToCid() == kMintCid) ||
1626 IsBinaryMintOp() ||
1627 IsUnaryMintOp() ||
1628 IsShiftMintOp() ||
1629 IsBoxInteger() ||
1630 IsUnboxInteger();
1631 }
1632 1619
1633 bool IsInt32Definition() { 1620 bool IsInt32Definition() {
1634 return IsBinaryInt32Op() || 1621 return IsBinaryInt32Op() ||
1635 IsBoxInt32() || 1622 IsBoxInt32() ||
1636 IsUnboxInt32() || 1623 IsUnboxInt32() ||
1637 IsUnboxedIntConverter(); 1624 IsUnboxedIntConverter();
1638 } 1625 }
1639 1626
1640 // Compute compile type for this definition. It is safe to use this 1627 // Compute compile type for this definition. It is safe to use this
1641 // approximation even before type propagator was run (e.g. during graph 1628 // approximation even before type propagator was run (e.g. during graph
(...skipping 2770 matching lines...) Expand 10 before | Expand all | Expand 10 after
4412 4399
4413 void set_licm_hoisted(bool value) { licm_hoisted_ = value; } 4400 void set_licm_hoisted(bool value) { licm_hoisted_ = value; }
4414 4401
4415 private: 4402 private:
4416 bool licm_hoisted_; 4403 bool licm_hoisted_;
4417 4404
4418 DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiInstr); 4405 DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiInstr);
4419 }; 4406 };
4420 4407
4421 4408
4422 class BoxDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> { 4409 class Boxing : public AllStatic {
4423 public: 4410 public:
4424 explicit BoxDoubleInstr(Value* value) { 4411 static bool Supports(Representation rep) {
4425 SetInputAt(0, value); 4412 switch (rep) {
4426 } 4413 case kUnboxedDouble:
4414 case kUnboxedFloat32x4:
4415 case kUnboxedFloat64x2:
4416 case kUnboxedInt32x4:
4417 case kUnboxedMint:
4418 case kUnboxedInt32:
4419 case kUnboxedUint32:
4420 return true;
4421 default:
4422 return false;
4423 }
4424 }
4425
4426 static intptr_t ValueOffset(Representation rep) {
4427 switch (rep) {
4428 case kUnboxedDouble:
4429 return Double::value_offset();
4430
4431 case kUnboxedFloat32x4:
4432 return Float32x4::value_offset();
4433
4434 case kUnboxedFloat64x2:
4435 return Float64x2::value_offset();
4436
4437 case kUnboxedInt32x4:
4438 return Int32x4::value_offset();
4439
4440 case kUnboxedMint:
4441 return Mint::value_offset();
4442
4443 default:
4444 UNREACHABLE();
4445 return 0;
4446 }
4447 }
4448
4449 static intptr_t BoxCid(Representation rep) {
4450 switch (rep) {
4451 case kUnboxedMint:
4452 return kMintCid;
4453 case kUnboxedDouble:
4454 return kDoubleCid;
4455 case kUnboxedFloat32x4:
4456 return kFloat32x4Cid;
4457 case kUnboxedFloat64x2:
4458 return kFloat64x2Cid;
4459 case kUnboxedInt32x4:
4460 return kInt32x4Cid;
4461 default:
4462 UNREACHABLE();
4463 return kIllegalCid;
4464 }
4465 }
4466 };
4467
4468
4469 class BoxInstr : public TemplateDefinition<1, NoThrow, Pure> {
4470 public:
4471 static BoxInstr* Create(Representation from, Value* value);
4427 4472
4428 Value* value() const { return inputs_[0]; } 4473 Value* value() const { return inputs_[0]; }
4429 4474 Representation from_representation() const { return from_representation_; }
4430 DECLARE_INSTRUCTION(BoxDouble) 4475
4476 DECLARE_INSTRUCTION(Box)
4431 virtual CompileType ComputeType() const; 4477 virtual CompileType ComputeType() const;
4432 4478
4433 virtual bool CanDeoptimize() const { return false; } 4479 virtual bool CanDeoptimize() const { return false; }
4434
4435 virtual intptr_t DeoptimizationTarget() const { 4480 virtual intptr_t DeoptimizationTarget() const {
4436 return Isolate::kNoDeoptId; 4481 return Isolate::kNoDeoptId;
4437 } 4482 }
4438 4483
4439 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4484 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4440 ASSERT(idx == 0); 4485 ASSERT(idx == 0);
4441 return kUnboxedDouble; 4486 return from_representation();
4442 } 4487 }
4443 4488
4444 virtual bool AttributesEqual(Instruction* other) const { return true; } 4489 virtual bool AttributesEqual(Instruction* other) const {
4490 return other->AsBox()->from_representation() == from_representation();
4491 }
4445 4492
4446 Definition* Canonicalize(FlowGraph* flow_graph); 4493 Definition* Canonicalize(FlowGraph* flow_graph);
4447 4494
4448 private: 4495 protected:
4449 DISALLOW_COPY_AND_ASSIGN(BoxDoubleInstr); 4496 BoxInstr(Representation from_representation, Value* value)
4450 }; 4497 : from_representation_(from_representation) {
4451
4452
4453 class BoxFloat32x4Instr : public TemplateDefinition<1, NoThrow, Pure> {
4454 public:
4455 explicit BoxFloat32x4Instr(Value* value) {
4456 SetInputAt(0, value); 4498 SetInputAt(0, value);
4457 } 4499 }
4458 4500
4459 Value* value() const { return inputs_[0]; } 4501 private:
4460 4502 intptr_t ValueOffset() const {
4461 virtual bool CanDeoptimize() const { return false; } 4503 return Boxing::ValueOffset(from_representation());
4462 4504 }
4463 virtual intptr_t DeoptimizationTarget() const { 4505
4464 return Isolate::kNoDeoptId; 4506 const Representation from_representation_;
4465 } 4507
4466 4508 DISALLOW_COPY_AND_ASSIGN(BoxInstr);
4467 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4509 };
4468 ASSERT(idx == 0); 4510
4469 return kUnboxedFloat32x4; 4511
4470 } 4512 class BoxIntegerInstr : public BoxInstr {
4471 4513 public:
4472 DECLARE_INSTRUCTION(BoxFloat32x4) 4514 BoxIntegerInstr(Representation representation, Value* value)
4473 virtual CompileType ComputeType() const; 4515 : BoxInstr(representation, value) { }
4474 4516
4475 virtual bool AttributesEqual(Instruction* other) const { return true; } 4517 virtual bool ValueFitsSmi() const;
4476 4518
4477 Definition* Canonicalize(FlowGraph* flow_graph); 4519 virtual void InferRange(RangeAnalysis* analysis, Range* range);
4478 4520
4479 private:
4480 DISALLOW_COPY_AND_ASSIGN(BoxFloat32x4Instr);
4481 };
4482
4483
4484 class BoxFloat64x2Instr : public TemplateDefinition<1, NoThrow, Pure> {
4485 public:
4486 explicit BoxFloat64x2Instr(Value* value) {
4487 SetInputAt(0, value);
4488 }
4489
4490 Value* value() const { return inputs_[0]; }
4491
4492 virtual bool CanDeoptimize() const { return false; }
4493
4494 virtual intptr_t DeoptimizationTarget() const {
4495 return Isolate::kNoDeoptId;
4496 }
4497
4498 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4499 ASSERT(idx == 0);
4500 return kUnboxedFloat64x2;
4501 }
4502
4503 DECLARE_INSTRUCTION(BoxFloat64x2)
4504 virtual CompileType ComputeType() const;
4505
4506 virtual bool AttributesEqual(Instruction* other) const { return true; }
4507
4508 Definition* Canonicalize(FlowGraph* flow_graph);
4509
4510 private:
4511 DISALLOW_COPY_AND_ASSIGN(BoxFloat64x2Instr);
4512 };
4513
4514
4515
4516 class BoxInt32x4Instr : public TemplateDefinition<1, NoThrow, Pure> {
4517 public:
4518 explicit BoxInt32x4Instr(Value* value) {
4519 SetInputAt(0, value);
4520 }
4521
4522 Value* value() const { return inputs_[0]; }
4523
4524 virtual bool CanDeoptimize() const { return false; }
4525
4526 virtual intptr_t DeoptimizationTarget() const {
4527 return Isolate::kNoDeoptId;
4528 }
4529
4530 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4531 ASSERT(idx == 0);
4532 return kUnboxedInt32x4;
4533 }
4534
4535 DECLARE_INSTRUCTION(BoxInt32x4)
4536 virtual CompileType ComputeType() const;
4537
4538 virtual bool AttributesEqual(Instruction* other) const { return true; }
4539
4540 Definition* Canonicalize(FlowGraph* flow_graph);
4541
4542 private:
4543 DISALLOW_COPY_AND_ASSIGN(BoxInt32x4Instr);
4544 };
4545
4546
4547 class BoxIntegerInstr : public TemplateDefinition<1, NoThrow, Pure> {
4548 public:
4549 explicit BoxIntegerInstr(Value* value) : is_smi_(false) {
4550 SetInputAt(0, value);
4551 }
4552
4553 Value* value() const { return inputs_[0]; }
4554
4555 bool is_smi() const { return is_smi_; }
4556 void set_is_smi(bool is_smi) { is_smi_ = is_smi; }
4557
4558 virtual bool CanDeoptimize() const { return false; }
4559
4560 virtual intptr_t DeoptimizationTarget() const {
4561 return Isolate::kNoDeoptId;
4562 }
4563
4564 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4565 ASSERT(idx == 0);
4566 return kUnboxedMint;
4567 }
4568
4569 DECLARE_INSTRUCTION(BoxInteger)
4570 virtual CompileType ComputeType() const; 4521 virtual CompileType ComputeType() const;
4571 virtual bool RecomputeType(); 4522 virtual bool RecomputeType();
4572 4523
4573 virtual void InferRange(RangeAnalysis* analysis, Range* range);
4574
4575 virtual bool AttributesEqual(Instruction* other) const { return true; }
4576
4577 virtual Definition* Canonicalize(FlowGraph* flow_graph); 4524 virtual Definition* Canonicalize(FlowGraph* flow_graph);
4578 4525
4579 private: 4526 DEFINE_INSTRUCTION_TYPE_CHECK(BoxInteger)
4580 bool is_smi_; 4527
4581 4528 private:
4582 DISALLOW_COPY_AND_ASSIGN(BoxIntegerInstr); 4529 DISALLOW_COPY_AND_ASSIGN(BoxIntegerInstr);
4583 }; 4530 };
4584 4531
4585 4532
4586 class UnboxDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> { 4533 class BoxInteger32Instr : public BoxIntegerInstr {
4587 public: 4534 public:
4588 UnboxDoubleInstr(Value* value, intptr_t deopt_id) 4535 BoxInteger32Instr(Representation representation, Value* value)
4589 : TemplateDefinition(deopt_id) { 4536 : BoxIntegerInstr(representation, value) { }
4537
4538 DECLARE_INSTRUCTION_BACKEND()
4539
4540 private:
4541 DISALLOW_COPY_AND_ASSIGN(BoxInteger32Instr);
4542 };
4543
4544
4545 class BoxInt32Instr : public BoxInteger32Instr {
4546 public:
4547 explicit BoxInt32Instr(Value* value)
4548 : BoxInteger32Instr(kUnboxedInt32, value) { }
4549
4550 DECLARE_INSTRUCTION_NO_BACKEND(BoxInt32)
4551
4552 private:
4553 DISALLOW_COPY_AND_ASSIGN(BoxInt32Instr);
4554 };
4555
4556
4557 class BoxUint32Instr : public BoxInteger32Instr {
4558 public:
4559 explicit BoxUint32Instr(Value* value)
4560 : BoxInteger32Instr(kUnboxedUint32, value) { }
4561
4562 DECLARE_INSTRUCTION_NO_BACKEND(BoxUint32)
4563
4564 private:
4565 DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr);
4566 };
4567
4568
4569 class BoxInt64Instr : public BoxIntegerInstr {
4570 public:
4571 explicit BoxInt64Instr(Value* value)
4572 : BoxIntegerInstr(kUnboxedMint, value) { }
4573
4574 virtual Definition* Canonicalize(FlowGraph* flow_graph);
4575
4576 DECLARE_INSTRUCTION(BoxInt64)
4577
4578 private:
4579 DISALLOW_COPY_AND_ASSIGN(BoxInt64Instr);
4580 };
4581
4582
4583 class UnboxInstr : public TemplateDefinition<1, NoThrow, Pure> {
4584 public:
4585 static UnboxInstr* Create(Representation to, Value* value, intptr_t deopt_id);
4586
4587 Value* value() const { return inputs_[0]; }
4588
4589 virtual bool CanDeoptimize() const {
4590 const intptr_t value_cid = value()->Type()->ToCid();
4591
4592 if (CanConvertSmi() &&
4593 (value()->Type()->ToCid() == kSmiCid)) {
4594 return false;
4595 }
4596
4597 return (value_cid != BoxCid());
4598 }
4599
4600 virtual Representation representation() const {
4601 return representation_;
4602 }
4603
4604 DECLARE_INSTRUCTION(Unbox)
4605 virtual CompileType ComputeType() const;
4606
4607 virtual bool AttributesEqual(Instruction* other) const {
4608 return representation() == other->AsUnbox()->representation();
4609 }
4610
4611 Definition* Canonicalize(FlowGraph* flow_graph);
4612
4613 virtual intptr_t DeoptimizationTarget() const {
4614 return GetDeoptId();
4615 }
4616
4617 protected:
4618 UnboxInstr(Representation representation,
4619 Value* value,
4620 intptr_t deopt_id)
4621 : TemplateDefinition(deopt_id),
4622 representation_(representation) {
4590 SetInputAt(0, value); 4623 SetInputAt(0, value);
4591 } 4624 }
4592 4625
4593 Value* value() const { return inputs_[0]; } 4626 private:
4627 bool CanConvertSmi() const;
4628 void EmitLoadFromBox(FlowGraphCompiler* compiler);
4629 void EmitSmiConversion(FlowGraphCompiler* compiler);
4630
4631 intptr_t BoxCid() const {
4632 return Boxing::BoxCid(representation_);
4633 }
4634
4635 intptr_t ValueOffset() const {
4636 return Boxing::ValueOffset(representation_);
4637 }
4638
4639 const Representation representation_;
4640
4641 DISALLOW_COPY_AND_ASSIGN(UnboxInstr);
4642 };
4643
4644
4645 class UnboxIntegerInstr : public UnboxInstr {
4646 public:
4647 enum TruncationMode { kTruncate, kNoTruncation };
4648
4649 UnboxIntegerInstr(Representation representation,
4650 TruncationMode truncation_mode,
4651 Value* value,
4652 intptr_t deopt_id)
4653 : UnboxInstr(representation, value, deopt_id),
4654 is_truncating_(truncation_mode == kTruncate) {
4655 }
4656
4657 bool is_truncating() const { return is_truncating_; }
4658
4659 virtual CompileType ComputeType() const;
4660
4661 virtual bool AttributesEqual(Instruction* other) const {
4662 UnboxIntegerInstr* other_unbox = other->AsUnboxInteger();
4663 return UnboxInstr::AttributesEqual(other) &&
4664 (other_unbox->is_truncating_ == is_truncating_);
4665 }
4666
4667 virtual Definition* Canonicalize(FlowGraph* flow_graph);
4668
4669 virtual void PrintOperandsTo(BufferFormatter* f) const;
4670
4671 DEFINE_INSTRUCTION_TYPE_CHECK(UnboxInteger)
4672
4673 private:
4674 bool is_truncating_;
4675
4676 DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr);
4677 };
4678
4679
4680 class UnboxInteger32Instr : public UnboxIntegerInstr {
4681 public:
4682 UnboxInteger32Instr(Representation representation,
4683 TruncationMode truncation_mode,
4684 Value* value,
4685 intptr_t deopt_id)
4686 : UnboxIntegerInstr(representation, truncation_mode, value, deopt_id) { }
4687
4688 DECLARE_INSTRUCTION_BACKEND()
4689
4690 private:
4691 DISALLOW_COPY_AND_ASSIGN(UnboxInteger32Instr);
4692 };
4693
4694
4695 class UnboxUint32Instr : public UnboxInteger32Instr {
4696 public:
4697 UnboxUint32Instr(Value* value, intptr_t deopt_id)
4698 : UnboxInteger32Instr(kUnboxedUint32, kTruncate, value, deopt_id) {
4699 ASSERT(is_truncating());
4700 }
4594 4701
4595 virtual bool CanDeoptimize() const { 4702 virtual bool CanDeoptimize() const {
4596 return (value()->Type()->ToCid() != kDoubleCid) 4703 ASSERT(is_truncating());
4597 && (value()->Type()->ToCid() != kSmiCid);
4598 }
4599
4600 virtual Representation representation() const {
4601 return kUnboxedDouble;
4602 }
4603
4604 DECLARE_INSTRUCTION(UnboxDouble)
4605 virtual CompileType ComputeType() const;
4606
4607 virtual bool AttributesEqual(Instruction* other) const { return true; }
4608
4609 Definition* Canonicalize(FlowGraph* flow_graph);
4610
4611 private:
4612 DISALLOW_COPY_AND_ASSIGN(UnboxDoubleInstr);
4613 };
4614
4615
4616 class UnboxFloat32x4Instr : public TemplateDefinition<1, NoThrow, Pure> {
4617 public:
4618 UnboxFloat32x4Instr(Value* value, intptr_t deopt_id)
4619 : TemplateDefinition(deopt_id) {
4620 SetInputAt(0, value);
4621 }
4622
4623 Value* value() const { return inputs_[0]; }
4624
4625 virtual bool CanDeoptimize() const {
4626 return (value()->Type()->ToCid() != kFloat32x4Cid);
4627 }
4628
4629 virtual Representation representation() const {
4630 return kUnboxedFloat32x4;
4631 }
4632
4633 DECLARE_INSTRUCTION(UnboxFloat32x4)
4634 virtual CompileType ComputeType() const;
4635
4636 virtual bool AttributesEqual(Instruction* other) const { return true; }
4637
4638 Definition* Canonicalize(FlowGraph* flow_graph);
4639
4640 private:
4641 DISALLOW_COPY_AND_ASSIGN(UnboxFloat32x4Instr);
4642 };
4643
4644
4645 class UnboxFloat64x2Instr : public TemplateDefinition<1, NoThrow, Pure> {
4646 public:
4647 UnboxFloat64x2Instr(Value* value, intptr_t deopt_id)
4648 : TemplateDefinition(deopt_id) {
4649 SetInputAt(0, value);
4650 }
4651
4652 Value* value() const { return inputs_[0]; }
4653
4654 virtual bool CanDeoptimize() const {
4655 return (value()->Type()->ToCid() != kFloat64x2Cid);
4656 }
4657
4658 virtual Representation representation() const {
4659 return kUnboxedFloat64x2;
4660 }
4661
4662 DECLARE_INSTRUCTION(UnboxFloat64x2)
4663 virtual CompileType ComputeType() const;
4664
4665 virtual bool AttributesEqual(Instruction* other) const { return true; }
4666
4667 Definition* Canonicalize(FlowGraph* flow_graph);
4668
4669 private:
4670 DISALLOW_COPY_AND_ASSIGN(UnboxFloat64x2Instr);
4671 };
4672
4673
4674 class UnboxInt32x4Instr : public TemplateDefinition<1, NoThrow, Pure> {
4675 public:
4676 UnboxInt32x4Instr(Value* value, intptr_t deopt_id)
4677 : TemplateDefinition(deopt_id) {
4678 SetInputAt(0, value);
4679 }
4680
4681 Value* value() const { return inputs_[0]; }
4682
4683 virtual bool CanDeoptimize() const {
4684 return (value()->Type()->ToCid() != kInt32x4Cid);
4685 }
4686
4687 virtual Representation representation() const {
4688 return kUnboxedInt32x4;
4689 }
4690
4691 virtual bool AttributesEqual(Instruction* other) const { return true; }
4692
4693 DECLARE_INSTRUCTION(UnboxInt32x4)
4694 virtual CompileType ComputeType() const;
4695
4696 Definition* Canonicalize(FlowGraph* flow_graph);
4697
4698 private:
4699 DISALLOW_COPY_AND_ASSIGN(UnboxInt32x4Instr);
4700 };
4701
4702
4703 class UnboxIntegerInstr : public TemplateDefinition<1, NoThrow, Pure> {
4704 public:
4705 UnboxIntegerInstr(Value* value, intptr_t deopt_id)
4706 : TemplateDefinition(deopt_id) {
4707 SetInputAt(0, value);
4708 }
4709
4710 Value* value() const { return inputs_[0]; }
4711
4712 virtual bool CanDeoptimize() const {
4713 return (value()->Type()->ToCid() != kSmiCid) 4704 return (value()->Type()->ToCid() != kSmiCid)
4714 && (value()->Type()->ToCid() != kMintCid); 4705 && (value()->Type()->ToCid() != kMintCid);
4715 } 4706 }
4716 4707
4717 virtual Representation representation() const { 4708 DECLARE_INSTRUCTION_NO_BACKEND(UnboxUint32)
4718 return kUnboxedMint; 4709
4719 } 4710 private:
4720 4711 DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr);
4721 intptr_t deopt_id() const { return GetDeoptId(); } 4712 };
4713
4714
4715 class UnboxInt32Instr : public UnboxInteger32Instr {
4716 public:
4717 UnboxInt32Instr(TruncationMode truncation_mode,
4718 Value* value,
4719 intptr_t deopt_id)
4720 : UnboxInteger32Instr(kUnboxedInt32, truncation_mode, value, deopt_id) {
4721 }
4722
4723 virtual bool CanDeoptimize() const;
4722 4724
4723 virtual void InferRange(RangeAnalysis* analysis, Range* range); 4725 virtual void InferRange(RangeAnalysis* analysis, Range* range);
4724 4726
4725 DECLARE_INSTRUCTION(UnboxInteger)
4726 virtual CompileType ComputeType() const;
4727
4728 virtual bool AttributesEqual(Instruction* other) const { return true; }
4729
4730 virtual Definition* Canonicalize(FlowGraph* flow_graph); 4727 virtual Definition* Canonicalize(FlowGraph* flow_graph);
4731 4728
4732 private: 4729 DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt32)
4733 DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr); 4730
4734 }; 4731 private:
4732 DISALLOW_COPY_AND_ASSIGN(UnboxInt32Instr);
4733 };
4734
4735
4736 class UnboxInt64Instr : public UnboxIntegerInstr {
4737 public:
4738 UnboxInt64Instr(Value* value, intptr_t deopt_id)
4739 : UnboxIntegerInstr(kUnboxedMint, kNoTruncation, value, deopt_id) {
4740 }
4741
4742 virtual void InferRange(RangeAnalysis* analysis, Range* range);
4743
4744 DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt64)
4745
4746 private:
4747 DISALLOW_COPY_AND_ASSIGN(UnboxInt64Instr);
4748 };
4749
4750
4751 bool Definition::IsMintDefinition() {
4752 return (Type()->ToCid() == kMintCid) ||
4753 IsBinaryMintOp() ||
4754 IsUnaryMintOp() ||
4755 IsShiftMintOp() ||
4756 IsBoxInt64() ||
4757 IsUnboxInt64();
4758 }
4735 4759
4736 4760
4737 class MathUnaryInstr : public TemplateDefinition<1, NoThrow, Pure> { 4761 class MathUnaryInstr : public TemplateDefinition<1, NoThrow, Pure> {
4738 public: 4762 public:
4739 enum MathUnaryKind { 4763 enum MathUnaryKind {
4740 kIllegal, 4764 kIllegal,
4741 kSin, 4765 kSin,
4742 kCos, 4766 kCos,
4743 kSqrt, 4767 kSqrt,
4744 kDoubleSquare, 4768 kDoubleSquare,
(...skipping 2718 matching lines...) Expand 10 before | Expand all | Expand 10 after
7463 }; 7487 };
7464 7488
7465 private: 7489 private:
7466 bool generalized_; 7490 bool generalized_;
7467 bool licm_hoisted_; 7491 bool licm_hoisted_;
7468 7492
7469 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr); 7493 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr);
7470 }; 7494 };
7471 7495
7472 7496
7473 class BoxIntNInstr : public TemplateDefinition<1, NoThrow, Pure> {
7474 public:
7475 BoxIntNInstr(Representation representation, Value* value)
7476 : from_representation_(representation) {
7477 SetInputAt(0, value);
7478 }
7479
7480 Representation from_representation() const { return from_representation_; }
7481
7482 Value* value() const { return inputs_[0]; }
7483 virtual bool ValueFitsSmi() const;
7484
7485 virtual CompileType ComputeType() const;
7486 virtual bool RecomputeType();
7487
7488 virtual bool CanDeoptimize() const { return false; }
7489
7490 virtual intptr_t DeoptimizationTarget() const {
7491 return Isolate::kNoDeoptId;
7492 }
7493
7494 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
7495 ASSERT(idx == 0);
7496 return from_representation_;
7497 }
7498
7499 virtual bool AttributesEqual(Instruction* other) const {
7500 return other->AsBoxIntN()->from_representation_ == from_representation_;
7501 }
7502
7503 virtual Definition* Canonicalize(FlowGraph* flow_graph);
7504
7505 DEFINE_INSTRUCTION_TYPE_CHECK(BoxIntN)
7506 DECLARE_INSTRUCTION_BACKEND()
7507
7508 private:
7509 const Representation from_representation_;
7510
7511 DISALLOW_COPY_AND_ASSIGN(BoxIntNInstr);
7512 };
7513
7514
7515 class BoxUint32Instr : public BoxIntNInstr {
7516 public:
7517 explicit BoxUint32Instr(Value* value)
7518 : BoxIntNInstr(kUnboxedUint32, value) { }
7519
7520 DECLARE_INSTRUCTION_NO_BACKEND(BoxUint32)
7521
7522 private:
7523 DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr);
7524 };
7525
7526
7527 class BoxInt32Instr : public BoxIntNInstr {
7528 public:
7529 explicit BoxInt32Instr(Value* value)
7530 : BoxIntNInstr(kUnboxedInt32, value) { }
7531
7532 virtual void InferRange(RangeAnalysis* analysis, Range* range);
7533
7534 DECLARE_INSTRUCTION_NO_BACKEND(BoxInt32)
7535
7536 private:
7537 DISALLOW_COPY_AND_ASSIGN(BoxInt32Instr);
7538 };
7539
7540
7541 class UnboxIntNInstr : public TemplateDefinition<1, NoThrow, Pure> {
7542 public:
7543 UnboxIntNInstr(Representation representation,
7544 Value* value,
7545 intptr_t deopt_id)
7546 : TemplateDefinition(deopt_id),
7547 representation_(representation),
7548 is_truncating_(representation == kUnboxedUint32) {
7549 SetInputAt(0, value);
7550 }
7551
7552 Value* value() const { return inputs_[0]; }
7553
7554 bool is_truncating() const { return is_truncating_; }
7555 void mark_truncating() { is_truncating_ = true; }
7556
7557 virtual Representation representation() const {
7558 return representation_;
7559 }
7560
7561 virtual CompileType ComputeType() const;
7562
7563 virtual bool AttributesEqual(Instruction* other) const {
7564 UnboxIntNInstr* other_unbox = other->AsUnboxIntN();
7565 return (other_unbox->representation_ == representation_) &&
7566 (other_unbox->is_truncating_ == is_truncating_);
7567 }
7568
7569 virtual Definition* Canonicalize(FlowGraph* flow_graph);
7570
7571 virtual void PrintOperandsTo(BufferFormatter* f) const;
7572
7573 DEFINE_INSTRUCTION_TYPE_CHECK(UnboxIntN)
7574 DECLARE_INSTRUCTION_BACKEND()
7575
7576 private:
7577 const Representation representation_;
7578 bool is_truncating_;
7579
7580 DISALLOW_COPY_AND_ASSIGN(UnboxIntNInstr);
7581 };
7582
7583
7584 class UnboxUint32Instr : public UnboxIntNInstr {
7585 public:
7586 UnboxUint32Instr(Value* value, intptr_t deopt_id)
7587 : UnboxIntNInstr(kUnboxedUint32, value, deopt_id) {
7588 ASSERT(is_truncating());
7589 }
7590
7591 virtual bool CanDeoptimize() const {
7592 return (value()->Type()->ToCid() != kSmiCid)
7593 && (value()->Type()->ToCid() != kMintCid);
7594 }
7595
7596 DECLARE_INSTRUCTION_NO_BACKEND(UnboxUint32)
7597
7598 private:
7599 DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr);
7600 };
7601
7602
7603 class UnboxInt32Instr : public UnboxIntNInstr {
7604 public:
7605 UnboxInt32Instr(Value* value, intptr_t deopt_id)
7606 : UnboxIntNInstr(kUnboxedInt32, value, deopt_id) {
7607 }
7608
7609 virtual bool CanDeoptimize() const;
7610
7611 virtual void InferRange(RangeAnalysis* analysis, Range* range);
7612
7613 virtual Definition* Canonicalize(FlowGraph* flow_graph);
7614
7615 DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt32)
7616
7617 private:
7618 DISALLOW_COPY_AND_ASSIGN(UnboxInt32Instr);
7619 };
7620
7621
7622 class UnboxedIntConverterInstr : public TemplateDefinition<1, NoThrow> { 7497 class UnboxedIntConverterInstr : public TemplateDefinition<1, NoThrow> {
7623 public: 7498 public:
7624 UnboxedIntConverterInstr(Representation from, 7499 UnboxedIntConverterInstr(Representation from,
7625 Representation to, 7500 Representation to,
7626 Value* value, 7501 Value* value,
7627 intptr_t deopt_id) 7502 intptr_t deopt_id)
7628 : TemplateDefinition(deopt_id), 7503 : TemplateDefinition(deopt_id),
7629 from_representation_(from), 7504 from_representation_(from),
7630 to_representation_(to), 7505 to_representation_(to),
7631 is_truncating_(to == kUnboxedUint32) { 7506 is_truncating_(to == kUnboxedUint32) {
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
7919 Isolate* isolate, bool opt) const { \ 7794 Isolate* isolate, bool opt) const { \
7920 UNIMPLEMENTED(); \ 7795 UNIMPLEMENTED(); \
7921 return NULL; \ 7796 return NULL; \
7922 } \ 7797 } \
7923 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } 7798 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
7924 7799
7925 7800
7926 } // namespace dart 7801 } // namespace dart
7927 7802
7928 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 7803 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698