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

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: Missed a TODO. 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
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 4587 matching lines...) Expand 10 before | Expand all | Expand 10 after
7634 } 7696 }
7635 7697
7636 7698
7637 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) { 7699 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) {
7638 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 7700 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
7639 it.Current()->Accept(this); 7701 it.Current()->Accept(this);
7640 } 7702 }
7641 } 7703 }
7642 7704
7643 7705
7706 void ConstantPropagator::VisitIndirectEntry(IndirectEntryInstr* block) {
7707 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
7708 it.Current()->Accept(this);
7709 }
7710 }
7711
7712
7644 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) { 7713 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) {
7645 const GrowableArray<Definition*>& defs = *block->initial_definitions(); 7714 const GrowableArray<Definition*>& defs = *block->initial_definitions();
7646 for (intptr_t i = 0; i < defs.length(); ++i) { 7715 for (intptr_t i = 0; i < defs.length(); ++i) {
7647 defs[i]->Accept(this); 7716 defs[i]->Accept(this);
7648 } 7717 }
7649 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 7718 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
7650 it.Current()->Accept(this); 7719 it.Current()->Accept(this);
7651 } 7720 }
7652 } 7721 }
7653 7722
(...skipping 27 matching lines...) Expand all
7681 SetReachable(instr->successor()); 7750 SetReachable(instr->successor());
7682 7751
7683 // Phi value depends on the reachability of a predecessor. We have 7752 // Phi value depends on the reachability of a predecessor. We have
7684 // to revisit phis every time a predecessor becomes reachable. 7753 // to revisit phis every time a predecessor becomes reachable.
7685 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) { 7754 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) {
7686 it.Current()->Accept(this); 7755 it.Current()->Accept(this);
7687 } 7756 }
7688 } 7757 }
7689 7758
7690 7759
7760 void ConstantPropagator::VisitIndirectGoto(IndirectGotoInstr* instr) {
7761 for (intptr_t i = 0; i < instr->SuccessorCount(); i++) {
7762 SetReachable(instr->SuccessorAt(i));
7763 }
7764 }
7765
7766
7691 void ConstantPropagator::VisitBranch(BranchInstr* instr) { 7767 void ConstantPropagator::VisitBranch(BranchInstr* instr) {
7692 instr->comparison()->Accept(this); 7768 instr->comparison()->Accept(this);
7693 7769
7694 // The successors may be reachable, but only if this instruction is. (We 7770 // The successors may be reachable, but only if this instruction is. (We
7695 // might be analyzing it because the constant value of one of its inputs 7771 // might be analyzing it because the constant value of one of its inputs
7696 // has changed.) 7772 // has changed.)
7697 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { 7773 if (reachable_->Contains(instr->GetBlock()->preorder_number())) {
7698 if (instr->constant_target() != NULL) { 7774 if (instr->constant_target() != NULL) {
7699 ASSERT((instr->constant_target() == instr->true_successor()) || 7775 ASSERT((instr->constant_target() == instr->true_successor()) ||
7700 (instr->constant_target() == instr->false_successor())); 7776 (instr->constant_target() == instr->false_successor()));
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
8092 SetValue(instr, result); 8168 SetValue(instr, result);
8093 return; 8169 return;
8094 } 8170 }
8095 } 8171 }
8096 } 8172 }
8097 SetValue(instr, non_constant_); 8173 SetValue(instr, non_constant_);
8098 } 8174 }
8099 } 8175 }
8100 8176
8101 8177
8178 void ConstantPropagator::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) {
8179 // TODO(jgruber): Implement constant propagation.
8180 SetValue(instr, non_constant_);
8181 }
8182
8183
8102 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { 8184 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) {
8103 SetValue(instr, instr->value()->definition()->constant_value()); 8185 SetValue(instr, instr->value()->definition()->constant_value());
8104 } 8186 }
8105 8187
8106 8188
8107 void ConstantPropagator::VisitStoreInstanceField( 8189 void ConstantPropagator::VisitStoreInstanceField(
8108 StoreInstanceFieldInstr* instr) { 8190 StoreInstanceFieldInstr* instr) {
8109 SetValue(instr, instr->value()->definition()->constant_value()); 8191 SetValue(instr, instr->value()->definition()->constant_value());
8110 } 8192 }
8111 8193
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
8734 const Object& right = instr->right()->definition()->constant_value(); 8816 const Object& right = instr->right()->definition()->constant_value();
8735 if (IsNonConstant(left) || IsNonConstant(right)) { 8817 if (IsNonConstant(left) || IsNonConstant(right)) {
8736 SetValue(instr, non_constant_); 8818 SetValue(instr, non_constant_);
8737 } else if (IsConstant(left) && IsConstant(right)) { 8819 } else if (IsConstant(left) && IsConstant(right)) {
8738 // TODO(srdjan): Handle min and max. 8820 // TODO(srdjan): Handle min and max.
8739 SetValue(instr, non_constant_); 8821 SetValue(instr, non_constant_);
8740 } 8822 }
8741 } 8823 }
8742 8824
8743 8825
8826 void ConstantPropagator::VisitCaseInsensitiveCompareUC16(
8827 CaseInsensitiveCompareUC16Instr *instr) {
8828 SetValue(instr, non_constant_);
8829 }
8830
8831
8744 void ConstantPropagator::VisitUnboxDouble(UnboxDoubleInstr* instr) { 8832 void ConstantPropagator::VisitUnboxDouble(UnboxDoubleInstr* instr) {
8745 const Object& value = instr->value()->definition()->constant_value(); 8833 const Object& value = instr->value()->definition()->constant_value();
8746 if (IsNonConstant(value)) { 8834 if (IsNonConstant(value)) {
8747 SetValue(instr, non_constant_); 8835 SetValue(instr, non_constant_);
8748 } else if (IsConstant(value)) { 8836 } else if (IsConstant(value)) {
8749 // TODO(kmillikin): Handle conversion. 8837 // TODO(kmillikin): Handle conversion.
8750 SetValue(instr, non_constant_); 8838 SetValue(instr, non_constant_);
8751 } 8839 }
8752 } 8840 }
8753 8841
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
8883 } else { 8971 } else {
8884 BlockEntryInstr* block = block_worklist_.RemoveLast(); 8972 BlockEntryInstr* block = block_worklist_.RemoveLast();
8885 block->Accept(this); 8973 block->Accept(this);
8886 } 8974 }
8887 } 8975 }
8888 } 8976 }
8889 8977
8890 8978
8891 static bool IsEmptyBlock(BlockEntryInstr* block) { 8979 static bool IsEmptyBlock(BlockEntryInstr* block) {
8892 return block->next()->IsGoto() && 8980 return block->next()->IsGoto() &&
8893 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)); 8981 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)) &&
8982 !block->IsIndirectEntry();
8894 } 8983 }
8895 8984
8896 8985
8897 // Traverses a chain of empty blocks and returns the first reachable non-empty 8986 // Traverses a chain of empty blocks and returns the first reachable non-empty
8898 // block that is not dominated by the start block. The empty blocks are added 8987 // block that is not dominated by the start block. The empty blocks are added
8899 // to the supplied bit vector. 8988 // to the supplied bit vector.
8900 static BlockEntryInstr* FindFirstNonEmptySuccessor( 8989 static BlockEntryInstr* FindFirstNonEmptySuccessor(
8901 TargetEntryInstr* block, 8990 TargetEntryInstr* block,
8902 BitVector* empty_blocks) { 8991 BitVector* empty_blocks) {
8903 BlockEntryInstr* current = block; 8992 BlockEntryInstr* current = block;
(...skipping 1170 matching lines...) Expand 10 before | Expand all | Expand 10 after
10074 10163
10075 // Insert materializations at environment uses. 10164 // Insert materializations at environment uses.
10076 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 10165 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
10077 CreateMaterializationAt( 10166 CreateMaterializationAt(
10078 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); 10167 exits_collector_.exits()[i], alloc, alloc->cls(), *slots);
10079 } 10168 }
10080 } 10169 }
10081 10170
10082 10171
10083 } // namespace dart 10172 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698