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

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

Issue 683433003: Integrate the Irregexp Regular Expression Engine. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase 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
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 1641 matching lines...) Expand 10 before | Expand all | Expand 10 after
1652 if (!ShouldInlineSimd()) { 1652 if (!ShouldInlineSimd()) {
1653 return false; 1653 return false;
1654 } 1654 }
1655 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, 1655 return InlineByteArrayViewStore(target, call, receiver, receiver_cid,
1656 kTypedDataInt32x4ArrayCid, 1656 kTypedDataInt32x4ArrayCid,
1657 ic_data, entry, last); 1657 ic_data, entry, last);
1658 case MethodRecognizer::kStringBaseCodeUnitAt: 1658 case MethodRecognizer::kStringBaseCodeUnitAt:
1659 return InlineStringCodeUnitAt(call, receiver_cid, entry, last); 1659 return InlineStringCodeUnitAt(call, receiver_cid, entry, last);
1660 case MethodRecognizer::kStringBaseCharAt: 1660 case MethodRecognizer::kStringBaseCharAt:
1661 return InlineStringBaseCharAt(call, receiver_cid, entry, last); 1661 return InlineStringBaseCharAt(call, receiver_cid, entry, last);
1662 case MethodRecognizer::kOneByteString_oneCodeUnitAt:
1663 case MethodRecognizer::kTwoByteString_oneCodeUnitAt:
1664 return InlineStringCodeUnitsAt(call, receiver_cid, 1, entry, last);
1665 case MethodRecognizer::kOneByteString_twoCodeUnitsAt:
1666 case MethodRecognizer::kTwoByteString_twoCodeUnitsAt:
1667 return InlineStringCodeUnitsAt(call, receiver_cid, 2, entry, last);
1668 case MethodRecognizer::kOneByteString_fourCodeUnitsAt:
1669 return InlineStringCodeUnitsAt(call, receiver_cid, 4, entry, last);
1662 case MethodRecognizer::kDoubleAdd: 1670 case MethodRecognizer::kDoubleAdd:
1663 return InlineDoubleOp(Token::kADD, call, entry, last); 1671 return InlineDoubleOp(Token::kADD, call, entry, last);
1664 case MethodRecognizer::kDoubleSub: 1672 case MethodRecognizer::kDoubleSub:
1665 return InlineDoubleOp(Token::kSUB, call, entry, last); 1673 return InlineDoubleOp(Token::kSUB, call, entry, last);
1666 case MethodRecognizer::kDoubleMul: 1674 case MethodRecognizer::kDoubleMul:
1667 return InlineDoubleOp(Token::kMUL, call, entry, last); 1675 return InlineDoubleOp(Token::kMUL, call, entry, last);
1668 case MethodRecognizer::kDoubleDiv: 1676 case MethodRecognizer::kDoubleDiv:
1669 return InlineDoubleOp(Token::kDIV, call, entry, last); 1677 return InlineDoubleOp(Token::kDIV, call, entry, last);
1670 default: 1678 default:
1671 return false; 1679 return false;
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after
2862 *entry = new(I) TargetEntryInstr(flow_graph()->allocate_block_id(), 2870 *entry = new(I) TargetEntryInstr(flow_graph()->allocate_block_id(),
2863 call->GetBlock()->try_index()); 2871 call->GetBlock()->try_index());
2864 (*entry)->InheritDeoptTarget(I, call); 2872 (*entry)->InheritDeoptTarget(I, call);
2865 2873
2866 *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry); 2874 *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry);
2867 2875
2868 return true; 2876 return true;
2869 } 2877 }
2870 2878
2871 2879
2880 Definition* FlowGraphOptimizer::PrepareInlineStringIndexOpUnchecked(
2881 Instruction* call,
2882 intptr_t cid,
2883 intptr_t count,
2884 Definition* str,
2885 Definition* index,
2886 Instruction* cursor) {
2887 LoadCodeUnitsInstr* load = new(I) LoadCodeUnitsInstr(
2888 new(I) Value(str),
2889 new(I) Value(index),
2890 count,
2891 cid,
2892 call->token_pos());
2893
2894 cursor = flow_graph()->AppendTo(cursor,
2895 load,
2896 NULL,
2897 FlowGraph::kValue);
2898 ASSERT(cursor == load);
2899 return load;
2900 }
2901
2902
2903 bool FlowGraphOptimizer::InlineStringCodeUnitsAt(
2904 Instruction* call,
2905 intptr_t cid,
2906 intptr_t count,
2907 TargetEntryInstr** entry,
2908 Definition** last) {
2909 // TODO(jgruber): Handle external strings in
2910 // PrepareInlineStringIndexOpUnchecked.
2911 if (RawObject::IsExternalStringClassId(cid)) {
2912 return false;
2913 }
2914
2915 Definition* str = call->ArgumentAt(0);
2916 Definition* index = call->ArgumentAt(1);
2917
2918 *entry = new(I) TargetEntryInstr(flow_graph()->allocate_block_id(),
2919 call->GetBlock()->try_index());
2920 (*entry)->InheritDeoptTarget(I, call);
2921
2922 *last = PrepareInlineStringIndexOpUnchecked(
2923 call, cid, count, str, index, *entry);
2924
2925 return true;
2926 }
2927
2928
2872 bool FlowGraphOptimizer::InlineStringBaseCharAt( 2929 bool FlowGraphOptimizer::InlineStringBaseCharAt(
2873 Instruction* call, 2930 Instruction* call,
2874 intptr_t cid, 2931 intptr_t cid,
2875 TargetEntryInstr** entry, 2932 TargetEntryInstr** entry,
2876 Definition** last) { 2933 Definition** last) {
2877 // TODO(johnmccutchan): Handle external strings in PrepareInlineStringIndexOp. 2934 // TODO(johnmccutchan): Handle external strings in PrepareInlineStringIndexOp.
2878 if (RawObject::IsExternalStringClassId(cid) || cid != kOneByteStringCid) { 2935 if (RawObject::IsExternalStringClassId(cid) || cid != kOneByteStringCid) {
2879 return false; 2936 return false;
2880 } 2937 }
2881 Definition* str = call->ArgumentAt(0); 2938 Definition* str = call->ArgumentAt(0);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
3054 Bigint::neg_offset(), 3111 Bigint::neg_offset(),
3055 new(I) Value(bigint), 3112 new(I) Value(bigint),
3056 new(I) Value(value), 3113 new(I) Value(value),
3057 kEmitStoreBarrier, 3114 kEmitStoreBarrier,
3058 call->token_pos()); 3115 call->token_pos());
3059 ReplaceCall(call, store); 3116 ReplaceCall(call, store);
3060 return true; 3117 return true;
3061 } 3118 }
3062 3119
3063 if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) || 3120 if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) ||
3064 (recognized_kind == MethodRecognizer::kStringBaseCharAt)) && 3121 (recognized_kind == MethodRecognizer::kStringBaseCharAt) ||
3122 (recognized_kind == MethodRecognizer::kOneByteString_oneCodeUnitAt) ||
3123 (recognized_kind == MethodRecognizer::kOneByteString_twoCodeUnitsAt) ||
3124 (recognized_kind == MethodRecognizer::kOneByteString_fourCodeUnitsAt) ||
3125 (recognized_kind == MethodRecognizer::kTwoByteString_oneCodeUnitAt) ||
3126 (recognized_kind == MethodRecognizer::kTwoByteString_twoCodeUnitsAt)) &&
3065 (ic_data.NumberOfChecks() == 1) && 3127 (ic_data.NumberOfChecks() == 1) &&
3066 ((class_ids[0] == kOneByteStringCid) || 3128 ((class_ids[0] == kOneByteStringCid) ||
3067 (class_ids[0] == kTwoByteStringCid))) { 3129 (class_ids[0] == kTwoByteStringCid))) {
3068 return TryReplaceInstanceCallWithInline(call); 3130 return TryReplaceInstanceCallWithInline(call);
3069 } 3131 }
3070 3132
3071 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) { 3133 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) {
3072 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) { 3134 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) {
3073 // This is an internal method, no need to check argument types nor 3135 // This is an internal method, no need to check argument types nor
3074 // range. 3136 // range.
(...skipping 4607 matching lines...) Expand 10 before | Expand all | Expand 10 after
7682 } 7744 }
7683 7745
7684 7746
7685 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) { 7747 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) {
7686 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 7748 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
7687 it.Current()->Accept(this); 7749 it.Current()->Accept(this);
7688 } 7750 }
7689 } 7751 }
7690 7752
7691 7753
7754 void ConstantPropagator::VisitIndirectEntry(IndirectEntryInstr* block) {
7755 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
7756 it.Current()->Accept(this);
7757 }
7758 }
7759
7760
7692 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) { 7761 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) {
7693 const GrowableArray<Definition*>& defs = *block->initial_definitions(); 7762 const GrowableArray<Definition*>& defs = *block->initial_definitions();
7694 for (intptr_t i = 0; i < defs.length(); ++i) { 7763 for (intptr_t i = 0; i < defs.length(); ++i) {
7695 defs[i]->Accept(this); 7764 defs[i]->Accept(this);
7696 } 7765 }
7697 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 7766 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
7698 it.Current()->Accept(this); 7767 it.Current()->Accept(this);
7699 } 7768 }
7700 } 7769 }
7701 7770
(...skipping 27 matching lines...) Expand all
7729 SetReachable(instr->successor()); 7798 SetReachable(instr->successor());
7730 7799
7731 // Phi value depends on the reachability of a predecessor. We have 7800 // Phi value depends on the reachability of a predecessor. We have
7732 // to revisit phis every time a predecessor becomes reachable. 7801 // to revisit phis every time a predecessor becomes reachable.
7733 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) { 7802 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) {
7734 it.Current()->Accept(this); 7803 it.Current()->Accept(this);
7735 } 7804 }
7736 } 7805 }
7737 7806
7738 7807
7808 void ConstantPropagator::VisitIndirectGoto(IndirectGotoInstr* instr) {
7809 for (intptr_t i = 0; i < instr->SuccessorCount(); i++) {
7810 SetReachable(instr->SuccessorAt(i));
7811 }
7812 }
7813
7814
7739 void ConstantPropagator::VisitBranch(BranchInstr* instr) { 7815 void ConstantPropagator::VisitBranch(BranchInstr* instr) {
7740 instr->comparison()->Accept(this); 7816 instr->comparison()->Accept(this);
7741 7817
7742 // The successors may be reachable, but only if this instruction is. (We 7818 // The successors may be reachable, but only if this instruction is. (We
7743 // might be analyzing it because the constant value of one of its inputs 7819 // might be analyzing it because the constant value of one of its inputs
7744 // has changed.) 7820 // has changed.)
7745 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { 7821 if (reachable_->Contains(instr->GetBlock()->preorder_number())) {
7746 if (instr->constant_target() != NULL) { 7822 if (instr->constant_target() != NULL) {
7747 ASSERT((instr->constant_target() == instr->true_successor()) || 7823 ASSERT((instr->constant_target() == instr->true_successor()) ||
7748 (instr->constant_target() == instr->false_successor())); 7824 (instr->constant_target() == instr->false_successor()));
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
8140 SetValue(instr, result); 8216 SetValue(instr, result);
8141 return; 8217 return;
8142 } 8218 }
8143 } 8219 }
8144 } 8220 }
8145 SetValue(instr, non_constant_); 8221 SetValue(instr, non_constant_);
8146 } 8222 }
8147 } 8223 }
8148 8224
8149 8225
8226 void ConstantPropagator::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) {
8227 // TODO(jgruber): Implement constant propagation.
8228 SetValue(instr, non_constant_);
8229 }
8230
8231
8150 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { 8232 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) {
8151 SetValue(instr, instr->value()->definition()->constant_value()); 8233 SetValue(instr, instr->value()->definition()->constant_value());
8152 } 8234 }
8153 8235
8154 8236
8155 void ConstantPropagator::VisitStoreInstanceField( 8237 void ConstantPropagator::VisitStoreInstanceField(
8156 StoreInstanceFieldInstr* instr) { 8238 StoreInstanceFieldInstr* instr) {
8157 SetValue(instr, instr->value()->definition()->constant_value()); 8239 SetValue(instr, instr->value()->definition()->constant_value());
8158 } 8240 }
8159 8241
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
8782 const Object& right = instr->right()->definition()->constant_value(); 8864 const Object& right = instr->right()->definition()->constant_value();
8783 if (IsNonConstant(left) || IsNonConstant(right)) { 8865 if (IsNonConstant(left) || IsNonConstant(right)) {
8784 SetValue(instr, non_constant_); 8866 SetValue(instr, non_constant_);
8785 } else if (IsConstant(left) && IsConstant(right)) { 8867 } else if (IsConstant(left) && IsConstant(right)) {
8786 // TODO(srdjan): Handle min and max. 8868 // TODO(srdjan): Handle min and max.
8787 SetValue(instr, non_constant_); 8869 SetValue(instr, non_constant_);
8788 } 8870 }
8789 } 8871 }
8790 8872
8791 8873
8874 void ConstantPropagator::VisitCaseInsensitiveCompareUC16(
8875 CaseInsensitiveCompareUC16Instr *instr) {
8876 SetValue(instr, non_constant_);
8877 }
8878
8879
8792 void ConstantPropagator::VisitUnboxDouble(UnboxDoubleInstr* instr) { 8880 void ConstantPropagator::VisitUnboxDouble(UnboxDoubleInstr* instr) {
8793 const Object& value = instr->value()->definition()->constant_value(); 8881 const Object& value = instr->value()->definition()->constant_value();
8794 if (IsNonConstant(value)) { 8882 if (IsNonConstant(value)) {
8795 SetValue(instr, non_constant_); 8883 SetValue(instr, non_constant_);
8796 } else if (IsConstant(value)) { 8884 } else if (IsConstant(value)) {
8797 // TODO(kmillikin): Handle conversion. 8885 // TODO(kmillikin): Handle conversion.
8798 SetValue(instr, non_constant_); 8886 SetValue(instr, non_constant_);
8799 } 8887 }
8800 } 8888 }
8801 8889
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
8931 } else { 9019 } else {
8932 BlockEntryInstr* block = block_worklist_.RemoveLast(); 9020 BlockEntryInstr* block = block_worklist_.RemoveLast();
8933 block->Accept(this); 9021 block->Accept(this);
8934 } 9022 }
8935 } 9023 }
8936 } 9024 }
8937 9025
8938 9026
8939 static bool IsEmptyBlock(BlockEntryInstr* block) { 9027 static bool IsEmptyBlock(BlockEntryInstr* block) {
8940 return block->next()->IsGoto() && 9028 return block->next()->IsGoto() &&
8941 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)); 9029 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)) &&
9030 !block->IsIndirectEntry();
8942 } 9031 }
8943 9032
8944 9033
8945 // Traverses a chain of empty blocks and returns the first reachable non-empty 9034 // Traverses a chain of empty blocks and returns the first reachable non-empty
8946 // block that is not dominated by the start block. The empty blocks are added 9035 // block that is not dominated by the start block. The empty blocks are added
8947 // to the supplied bit vector. 9036 // to the supplied bit vector.
8948 static BlockEntryInstr* FindFirstNonEmptySuccessor( 9037 static BlockEntryInstr* FindFirstNonEmptySuccessor(
8949 TargetEntryInstr* block, 9038 TargetEntryInstr* block,
8950 BitVector* empty_blocks) { 9039 BitVector* empty_blocks) {
8951 BlockEntryInstr* current = block; 9040 BlockEntryInstr* current = block;
(...skipping 1170 matching lines...) Expand 10 before | Expand all | Expand 10 after
10122 10211
10123 // Insert materializations at environment uses. 10212 // Insert materializations at environment uses.
10124 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 10213 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
10125 CreateMaterializationAt( 10214 CreateMaterializationAt(
10126 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); 10215 exits_collector_.exits()[i], alloc, alloc->cls(), *slots);
10127 } 10216 }
10128 } 10217 }
10129 10218
10130 10219
10131 } // namespace dart 10220 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698