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

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

Issue 539153002: Port and integrate the irregexp engine from V8 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed Ivan's comments. Created 6 years, 2 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/flow_graph_optimizer.h ('k') | runtime/vm/flow_graph_range_analysis.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 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 1613 matching lines...) Expand 10 before | Expand all | Expand 10 after
1624 if (!ShouldInlineSimd()) { 1624 if (!ShouldInlineSimd()) {
1625 return false; 1625 return false;
1626 } 1626 }
1627 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, 1627 return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
1628 kTypedDataInt32x4ArrayCid, 1628 kTypedDataInt32x4ArrayCid,
1629 ic_data, entry, last); 1629 ic_data, entry, last);
1630 case MethodRecognizer::kStringBaseCodeUnitAt: 1630 case MethodRecognizer::kStringBaseCodeUnitAt:
1631 return InlineStringCodeUnitAt(call, receiver_cid, entry, last); 1631 return InlineStringCodeUnitAt(call, receiver_cid, entry, last);
1632 case MethodRecognizer::kStringBaseCharAt: 1632 case MethodRecognizer::kStringBaseCharAt:
1633 return InlineStringBaseCharAt(call, receiver_cid, entry, last); 1633 return InlineStringBaseCharAt(call, receiver_cid, entry, last);
1634 case MethodRecognizer::kOneByteString_oneCodeUnitAt:
1635 case MethodRecognizer::kTwoByteString_oneCodeUnitAt:
1636 return InlineStringCodeUnitsAt(call, receiver_cid, 1, entry, last);
1637 case MethodRecognizer::kOneByteString_twoCodeUnitsAt:
1638 case MethodRecognizer::kTwoByteString_twoCodeUnitsAt:
1639 return InlineStringCodeUnitsAt(call, receiver_cid, 2, entry, last);
1640 case MethodRecognizer::kOneByteString_fourCodeUnitsAt:
1641 return InlineStringCodeUnitsAt(call, receiver_cid, 4, entry, last);
1634 case MethodRecognizer::kDoubleAdd: 1642 case MethodRecognizer::kDoubleAdd:
1635 return InlineDoubleOp(Token::kADD, call, entry, last); 1643 return InlineDoubleOp(Token::kADD, call, entry, last);
1636 case MethodRecognizer::kDoubleSub: 1644 case MethodRecognizer::kDoubleSub:
1637 return InlineDoubleOp(Token::kSUB, call, entry, last); 1645 return InlineDoubleOp(Token::kSUB, call, entry, last);
1638 case MethodRecognizer::kDoubleMul: 1646 case MethodRecognizer::kDoubleMul:
1639 return InlineDoubleOp(Token::kMUL, call, entry, last); 1647 return InlineDoubleOp(Token::kMUL, call, entry, last);
1640 case MethodRecognizer::kDoubleDiv: 1648 case MethodRecognizer::kDoubleDiv:
1641 return InlineDoubleOp(Token::kDIV, call, entry, last); 1649 return InlineDoubleOp(Token::kDIV, call, entry, last);
1642 default: 1650 default:
1643 return false; 1651 return false;
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after
2834 *entry = new(I) TargetEntryInstr(flow_graph()->allocate_block_id(), 2842 *entry = new(I) TargetEntryInstr(flow_graph()->allocate_block_id(),
2835 call->GetBlock()->try_index()); 2843 call->GetBlock()->try_index());
2836 (*entry)->InheritDeoptTarget(I, call); 2844 (*entry)->InheritDeoptTarget(I, call);
2837 2845
2838 *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry); 2846 *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry);
2839 2847
2840 return true; 2848 return true;
2841 } 2849 }
2842 2850
2843 2851
2852 Definition* FlowGraphOptimizer::PrepareInlineStringIndexOpUnchecked(
2853 Instruction* call,
2854 intptr_t cid,
2855 intptr_t count,
2856 Definition* str,
2857 Definition* index,
2858 Instruction* cursor) {
2859 LoadCodeUnitsInstr* load = new(I) LoadCodeUnitsInstr(
2860 new(I) Value(str),
2861 new(I) Value(index),
2862 count,
2863 cid,
2864 call->token_pos());
2865
2866 cursor = flow_graph()->AppendTo(cursor,
2867 load,
2868 NULL,
2869 FlowGraph::kValue);
2870 ASSERT(cursor == load);
2871 return load;
2872 }
2873
2874
2875 bool FlowGraphOptimizer::InlineStringCodeUnitsAt(
2876 Instruction* call,
2877 intptr_t cid,
2878 intptr_t count,
2879 TargetEntryInstr** entry,
2880 Definition** last) {
2881 // TODO(jgruber): Handle external strings in
2882 // PrepareInlineStringIndexOpUnchecked.
2883 if (RawObject::IsExternalStringClassId(cid)) {
2884 return false;
2885 }
2886
2887 Definition* str = call->ArgumentAt(0);
2888 Definition* index = call->ArgumentAt(1);
2889
2890 *entry = new(I) TargetEntryInstr(flow_graph()->allocate_block_id(),
2891 call->GetBlock()->try_index());
2892 (*entry)->InheritDeoptTarget(I, call);
2893
2894 *last = PrepareInlineStringIndexOpUnchecked(
2895 call, cid, count, str, index, *entry);
2896
2897 return true;
2898 }
2899
2900
2844 bool FlowGraphOptimizer::InlineStringBaseCharAt( 2901 bool FlowGraphOptimizer::InlineStringBaseCharAt(
2845 Instruction* call, 2902 Instruction* call,
2846 intptr_t cid, 2903 intptr_t cid,
2847 TargetEntryInstr** entry, 2904 TargetEntryInstr** entry,
2848 Definition** last) { 2905 Definition** last) {
2849 // TODO(johnmccutchan): Handle external strings in PrepareInlineStringIndexOp. 2906 // TODO(johnmccutchan): Handle external strings in PrepareInlineStringIndexOp.
2850 if (RawObject::IsExternalStringClassId(cid) || cid != kOneByteStringCid) { 2907 if (RawObject::IsExternalStringClassId(cid) || cid != kOneByteStringCid) {
2851 return false; 2908 return false;
2852 } 2909 }
2853 Definition* str = call->ArgumentAt(0); 2910 Definition* str = call->ArgumentAt(0);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
3026 Bigint::neg_offset(), 3083 Bigint::neg_offset(),
3027 new(I) Value(bigint), 3084 new(I) Value(bigint),
3028 new(I) Value(value), 3085 new(I) Value(value),
3029 kEmitStoreBarrier, 3086 kEmitStoreBarrier,
3030 call->token_pos()); 3087 call->token_pos());
3031 ReplaceCall(call, store); 3088 ReplaceCall(call, store);
3032 return true; 3089 return true;
3033 } 3090 }
3034 3091
3035 if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) || 3092 if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) ||
3036 (recognized_kind == MethodRecognizer::kStringBaseCharAt)) && 3093 (recognized_kind == MethodRecognizer::kStringBaseCharAt) ||
3094 (recognized_kind == MethodRecognizer::kOneByteString_oneCodeUnitAt) ||
3095 (recognized_kind == MethodRecognizer::kOneByteString_twoCodeUnitsAt) ||
3096 (recognized_kind == MethodRecognizer::kOneByteString_fourCodeUnitsAt) ||
3097 (recognized_kind == MethodRecognizer::kTwoByteString_oneCodeUnitAt) ||
3098 (recognized_kind == MethodRecognizer::kTwoByteString_twoCodeUnitsAt)) &&
3037 (ic_data.NumberOfChecks() == 1) && 3099 (ic_data.NumberOfChecks() == 1) &&
3038 ((class_ids[0] == kOneByteStringCid) || 3100 ((class_ids[0] == kOneByteStringCid) ||
3039 (class_ids[0] == kTwoByteStringCid))) { 3101 (class_ids[0] == kTwoByteStringCid))) {
3040 return TryReplaceInstanceCallWithInline(call); 3102 return TryReplaceInstanceCallWithInline(call);
3041 } 3103 }
3042 3104
3043 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) { 3105 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) {
3044 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) { 3106 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) {
3045 // This is an internal method, no need to check argument types nor 3107 // This is an internal method, no need to check argument types nor
3046 // range. 3108 // range.
(...skipping 4608 matching lines...) Expand 10 before | Expand all | Expand 10 after
7655 } 7717 }
7656 7718
7657 7719
7658 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) { 7720 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) {
7659 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 7721 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
7660 it.Current()->Accept(this); 7722 it.Current()->Accept(this);
7661 } 7723 }
7662 } 7724 }
7663 7725
7664 7726
7727 void ConstantPropagator::VisitIndirectEntry(IndirectEntryInstr* block) {
7728 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
7729 it.Current()->Accept(this);
7730 }
7731 }
7732
7733
7665 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) { 7734 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) {
7666 const GrowableArray<Definition*>& defs = *block->initial_definitions(); 7735 const GrowableArray<Definition*>& defs = *block->initial_definitions();
7667 for (intptr_t i = 0; i < defs.length(); ++i) { 7736 for (intptr_t i = 0; i < defs.length(); ++i) {
7668 defs[i]->Accept(this); 7737 defs[i]->Accept(this);
7669 } 7738 }
7670 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 7739 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
7671 it.Current()->Accept(this); 7740 it.Current()->Accept(this);
7672 } 7741 }
7673 } 7742 }
7674 7743
(...skipping 27 matching lines...) Expand all
7702 SetReachable(instr->successor()); 7771 SetReachable(instr->successor());
7703 7772
7704 // Phi value depends on the reachability of a predecessor. We have 7773 // Phi value depends on the reachability of a predecessor. We have
7705 // to revisit phis every time a predecessor becomes reachable. 7774 // to revisit phis every time a predecessor becomes reachable.
7706 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) { 7775 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) {
7707 it.Current()->Accept(this); 7776 it.Current()->Accept(this);
7708 } 7777 }
7709 } 7778 }
7710 7779
7711 7780
7781 void ConstantPropagator::VisitIndirectGoto(IndirectGotoInstr* instr) {
7782 for (intptr_t i = 0; i < instr->SuccessorCount(); i++) {
7783 SetReachable(instr->SuccessorAt(i));
7784 }
7785 }
7786
7787
7712 void ConstantPropagator::VisitBranch(BranchInstr* instr) { 7788 void ConstantPropagator::VisitBranch(BranchInstr* instr) {
7713 instr->comparison()->Accept(this); 7789 instr->comparison()->Accept(this);
7714 7790
7715 // The successors may be reachable, but only if this instruction is. (We 7791 // The successors may be reachable, but only if this instruction is. (We
7716 // might be analyzing it because the constant value of one of its inputs 7792 // might be analyzing it because the constant value of one of its inputs
7717 // has changed.) 7793 // has changed.)
7718 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { 7794 if (reachable_->Contains(instr->GetBlock()->preorder_number())) {
7719 if (instr->constant_target() != NULL) { 7795 if (instr->constant_target() != NULL) {
7720 ASSERT((instr->constant_target() == instr->true_successor()) || 7796 ASSERT((instr->constant_target() == instr->true_successor()) ||
7721 (instr->constant_target() == instr->false_successor())); 7797 (instr->constant_target() == instr->false_successor()));
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
8113 SetValue(instr, result); 8189 SetValue(instr, result);
8114 return; 8190 return;
8115 } 8191 }
8116 } 8192 }
8117 } 8193 }
8118 SetValue(instr, non_constant_); 8194 SetValue(instr, non_constant_);
8119 } 8195 }
8120 } 8196 }
8121 8197
8122 8198
8199 void ConstantPropagator::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) {
8200 // TODO(jgruber): Implement constant propagation.
8201 SetValue(instr, non_constant_);
8202 }
8203
8204
8123 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { 8205 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) {
8124 SetValue(instr, instr->value()->definition()->constant_value()); 8206 SetValue(instr, instr->value()->definition()->constant_value());
8125 } 8207 }
8126 8208
8127 8209
8128 void ConstantPropagator::VisitStoreInstanceField( 8210 void ConstantPropagator::VisitStoreInstanceField(
8129 StoreInstanceFieldInstr* instr) { 8211 StoreInstanceFieldInstr* instr) {
8130 SetValue(instr, instr->value()->definition()->constant_value()); 8212 SetValue(instr, instr->value()->definition()->constant_value());
8131 } 8213 }
8132 8214
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
8755 const Object& right = instr->right()->definition()->constant_value(); 8837 const Object& right = instr->right()->definition()->constant_value();
8756 if (IsNonConstant(left) || IsNonConstant(right)) { 8838 if (IsNonConstant(left) || IsNonConstant(right)) {
8757 SetValue(instr, non_constant_); 8839 SetValue(instr, non_constant_);
8758 } else if (IsConstant(left) && IsConstant(right)) { 8840 } else if (IsConstant(left) && IsConstant(right)) {
8759 // TODO(srdjan): Handle min and max. 8841 // TODO(srdjan): Handle min and max.
8760 SetValue(instr, non_constant_); 8842 SetValue(instr, non_constant_);
8761 } 8843 }
8762 } 8844 }
8763 8845
8764 8846
8847 void ConstantPropagator::VisitCaseInsensitiveCompareUC16(
8848 CaseInsensitiveCompareUC16Instr *instr) {
8849 SetValue(instr, non_constant_);
8850 }
8851
8852
8765 void ConstantPropagator::VisitUnboxDouble(UnboxDoubleInstr* instr) { 8853 void ConstantPropagator::VisitUnboxDouble(UnboxDoubleInstr* instr) {
8766 const Object& value = instr->value()->definition()->constant_value(); 8854 const Object& value = instr->value()->definition()->constant_value();
8767 if (IsNonConstant(value)) { 8855 if (IsNonConstant(value)) {
8768 SetValue(instr, non_constant_); 8856 SetValue(instr, non_constant_);
8769 } else if (IsConstant(value)) { 8857 } else if (IsConstant(value)) {
8770 // TODO(kmillikin): Handle conversion. 8858 // TODO(kmillikin): Handle conversion.
8771 SetValue(instr, non_constant_); 8859 SetValue(instr, non_constant_);
8772 } 8860 }
8773 } 8861 }
8774 8862
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
8904 } else { 8992 } else {
8905 BlockEntryInstr* block = block_worklist_.RemoveLast(); 8993 BlockEntryInstr* block = block_worklist_.RemoveLast();
8906 block->Accept(this); 8994 block->Accept(this);
8907 } 8995 }
8908 } 8996 }
8909 } 8997 }
8910 8998
8911 8999
8912 static bool IsEmptyBlock(BlockEntryInstr* block) { 9000 static bool IsEmptyBlock(BlockEntryInstr* block) {
8913 return block->next()->IsGoto() && 9001 return block->next()->IsGoto() &&
8914 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)); 9002 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)) &&
9003 !block->IsIndirectEntry();
8915 } 9004 }
8916 9005
8917 9006
8918 // Traverses a chain of empty blocks and returns the first reachable non-empty 9007 // Traverses a chain of empty blocks and returns the first reachable non-empty
8919 // block that is not dominated by the start block. The empty blocks are added 9008 // block that is not dominated by the start block. The empty blocks are added
8920 // to the supplied bit vector. 9009 // to the supplied bit vector.
8921 static BlockEntryInstr* FindFirstNonEmptySuccessor( 9010 static BlockEntryInstr* FindFirstNonEmptySuccessor(
8922 TargetEntryInstr* block, 9011 TargetEntryInstr* block,
8923 BitVector* empty_blocks) { 9012 BitVector* empty_blocks) {
8924 BlockEntryInstr* current = block; 9013 BlockEntryInstr* current = block;
(...skipping 1170 matching lines...) Expand 10 before | Expand all | Expand 10 after
10095 10184
10096 // Insert materializations at environment uses. 10185 // Insert materializations at environment uses.
10097 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 10186 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
10098 CreateMaterializationAt( 10187 CreateMaterializationAt(
10099 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); 10188 exits_collector_.exits()[i], alloc, alloc->cls(), *slots);
10100 } 10189 }
10101 } 10190 }
10102 10191
10103 10192
10104 } // namespace dart 10193 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/flow_graph_range_analysis.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698