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

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

Issue 2122363002: DBC: Implement TestCids instruction. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: sync, review Created 4 years, 5 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
« no previous file with comments | « runtime/vm/constants_dbc.h ('k') | runtime/vm/simulator_dbc.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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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/globals.h" // Needed here to get TARGET_ARCH_DBC. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC.
6 #if defined(TARGET_ARCH_DBC) 6 #if defined(TARGET_ARCH_DBC)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 12 matching lines...) Expand all
23 23
24 #define __ compiler->assembler()-> 24 #define __ compiler->assembler()->
25 25
26 namespace dart { 26 namespace dart {
27 27
28 DECLARE_FLAG(bool, emit_edge_counters); 28 DECLARE_FLAG(bool, emit_edge_counters);
29 DECLARE_FLAG(int, optimization_counter_threshold); 29 DECLARE_FLAG(int, optimization_counter_threshold);
30 30
31 // List of instructions that are still unimplemented by DBC backend. 31 // List of instructions that are still unimplemented by DBC backend.
32 #define FOR_EACH_UNIMPLEMENTED_INSTRUCTION(M) \ 32 #define FOR_EACH_UNIMPLEMENTED_INSTRUCTION(M) \
33 M(IndirectGoto) \
34 M(LoadCodeUnits) \ 33 M(LoadCodeUnits) \
35 M(LoadUntagged) \ 34 M(LoadUntagged) \
36 M(AllocateUninitializedContext) \ 35 M(AllocateUninitializedContext) \
37 M(BinaryInt32Op) \ 36 M(BinaryInt32Op) \
38 M(UnaryDoubleOp) \ 37 M(UnaryDoubleOp) \
39 M(SmiToDouble) \ 38 M(SmiToDouble) \
40 M(Int32ToDouble) \ 39 M(Int32ToDouble) \
41 M(MintToDouble) \ 40 M(MintToDouble) \
42 M(DoubleToInteger) \ 41 M(DoubleToInteger) \
43 M(DoubleToSmi) \ 42 M(DoubleToSmi) \
44 M(DoubleToDouble) \ 43 M(DoubleToDouble) \
45 M(DoubleToFloat) \ 44 M(DoubleToFloat) \
46 M(FloatToDouble) \ 45 M(FloatToDouble) \
47 M(UnboxedConstant) \ 46 M(UnboxedConstant) \
48 M(BinaryDoubleOp) \ 47 M(BinaryDoubleOp) \
49 M(MathUnary) \ 48 M(MathUnary) \
50 M(MathMinMax) \ 49 M(MathMinMax) \
51 M(Box) \ 50 M(Box) \
52 M(Unbox) \ 51 M(Unbox) \
53 M(BoxInt64) \ 52 M(BoxInt64) \
54 M(CaseInsensitiveCompareUC16) \
55 M(BinaryMintOp) \ 53 M(BinaryMintOp) \
56 M(ShiftMintOp) \ 54 M(ShiftMintOp) \
57 M(UnaryMintOp) \ 55 M(UnaryMintOp) \
58 M(InvokeMathCFunction) \ 56 M(InvokeMathCFunction) \
59 M(MergedMath) \ 57 M(MergedMath) \
60 M(GuardFieldClass) \ 58 M(GuardFieldClass) \
61 M(GuardFieldLength) \ 59 M(GuardFieldLength) \
62 M(IfThenElse) \ 60 M(IfThenElse) \
63 M(BinaryFloat32x4Op) \ 61 M(BinaryFloat32x4Op) \
64 M(Simd32x4Shuffle) \ 62 M(Simd32x4Shuffle) \
(...skipping 10 matching lines...) Expand all
75 M(Float32x4Clamp) \ 73 M(Float32x4Clamp) \
76 M(Float32x4With) \ 74 M(Float32x4With) \
77 M(Float32x4ToInt32x4) \ 75 M(Float32x4ToInt32x4) \
78 M(Int32x4Constructor) \ 76 M(Int32x4Constructor) \
79 M(Int32x4BoolConstructor) \ 77 M(Int32x4BoolConstructor) \
80 M(Int32x4GetFlag) \ 78 M(Int32x4GetFlag) \
81 M(Int32x4Select) \ 79 M(Int32x4Select) \
82 M(Int32x4SetFlag) \ 80 M(Int32x4SetFlag) \
83 M(Int32x4ToFloat32x4) \ 81 M(Int32x4ToFloat32x4) \
84 M(BinaryInt32x4Op) \ 82 M(BinaryInt32x4Op) \
85 M(TestCids) \
86 M(BinaryFloat64x2Op) \ 83 M(BinaryFloat64x2Op) \
87 M(Float64x2Zero) \ 84 M(Float64x2Zero) \
88 M(Float64x2Constructor) \ 85 M(Float64x2Constructor) \
89 M(Float64x2Splat) \ 86 M(Float64x2Splat) \
90 M(Float32x4ToFloat64x2) \ 87 M(Float32x4ToFloat64x2) \
91 M(Float64x2ToFloat32x4) \ 88 M(Float64x2ToFloat32x4) \
92 M(Simd64x2Shuffle) \ 89 M(Simd64x2Shuffle) \
93 M(Float64x2ZeroArg) \ 90 M(Float64x2ZeroArg) \
94 M(Float64x2OneArg) \ 91 M(Float64x2OneArg) \
95 M(ExtractNthOutput) \ 92 M(ExtractNthOutput) \
96 M(BinaryUint32Op) \ 93 M(BinaryUint32Op) \
97 M(ShiftUint32Op) \ 94 M(ShiftUint32Op) \
98 M(UnaryUint32Op) \ 95 M(UnaryUint32Op) \
99 M(UnboxedIntConverter) \ 96 M(UnboxedIntConverter) \
100 M(GrowRegExpStack) \
101 M(BoxInteger32) \ 97 M(BoxInteger32) \
102 M(UnboxInteger32) \ 98 M(UnboxInteger32) \
103 M(CheckedSmiOp) \ 99 M(CheckedSmiOp) \
104 M(CheckArrayBound) \ 100 M(CheckArrayBound) \
105 M(RelationalOp) \ 101 M(RelationalOp) \
106 M(EqualityCompare) \ 102 M(EqualityCompare) \
107 M(LoadIndexed) 103 M(LoadIndexed)
108 104
105 // List of instructions that are not used by DBC.
106 #define FOR_EACH_UNREACHABLE_INSTRUCTION(M) \
107 M(CaseInsensitiveCompareUC16) \
108 M(GrowRegExpStack) \
109 M(IndirectGoto)
110
109 // Location summaries actually are not used by the unoptimizing DBC compiler 111 // Location summaries actually are not used by the unoptimizing DBC compiler
110 // because we don't allocate any registers. 112 // because we don't allocate any registers.
111 static LocationSummary* CreateLocationSummary( 113 static LocationSummary* CreateLocationSummary(
112 Zone* zone, 114 Zone* zone,
113 intptr_t num_inputs, 115 intptr_t num_inputs,
114 Location output = Location::NoLocation(), 116 Location output = Location::NoLocation(),
115 LocationSummary::ContainsCall contains_call = LocationSummary::kNoCall) { 117 LocationSummary::ContainsCall contains_call = LocationSummary::kNoCall) {
116 const intptr_t kNumTemps = 0; 118 const intptr_t kNumTemps = 0;
117 LocationSummary* locs = new(zone) LocationSummary( 119 LocationSummary* locs = new(zone) LocationSummary(
118 zone, num_inputs, kNumTemps, contains_call); 120 zone, num_inputs, kNumTemps, contains_call);
(...skipping 19 matching lines...) Expand all
138 DEFINE_MAKE_LOCATION_SUMMARY(Name, __VA_ARGS__); \ 140 DEFINE_MAKE_LOCATION_SUMMARY(Name, __VA_ARGS__); \
139 void Name##Instr::EmitNativeCode(FlowGraphCompiler* compiler) \ 141 void Name##Instr::EmitNativeCode(FlowGraphCompiler* compiler) \
140 142
141 #define DEFINE_UNIMPLEMENTED_MAKE_LOCATION_SUMMARY(Name) \ 143 #define DEFINE_UNIMPLEMENTED_MAKE_LOCATION_SUMMARY(Name) \
142 LocationSummary* Name##Instr::MakeLocationSummary(Zone* zone, bool opt) \ 144 LocationSummary* Name##Instr::MakeLocationSummary(Zone* zone, bool opt) \
143 const { \ 145 const { \
144 if (!opt) UNIMPLEMENTED(); \ 146 if (!opt) UNIMPLEMENTED(); \
145 return NULL; \ 147 return NULL; \
146 } \ 148 } \
147 149
150 #define DEFINE_UNREACHABLE_MAKE_LOCATION_SUMMARY(Name) \
151 LocationSummary* Name##Instr::MakeLocationSummary(Zone* zone, bool opt) \
152 const { \
153 UNREACHABLE(); \
154 return NULL; \
155 } \
156
148 #define DEFINE_UNIMPLEMENTED_EMIT_NATIVE_CODE(Name) \ 157 #define DEFINE_UNIMPLEMENTED_EMIT_NATIVE_CODE(Name) \
149 void Name##Instr::EmitNativeCode(FlowGraphCompiler* compiler) { \ 158 void Name##Instr::EmitNativeCode(FlowGraphCompiler* compiler) { \
150 UNIMPLEMENTED(); \ 159 UNIMPLEMENTED(); \
151 } 160 }
152 161
162 #define DEFINE_UNREACHABLE_EMIT_NATIVE_CODE(Name) \
163 void Name##Instr::EmitNativeCode(FlowGraphCompiler* compiler) { \
164 UNREACHABLE(); \
165 }
166
153 #define DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(Name) \ 167 #define DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(Name) \
154 void Name##Instr::EmitBranchCode(FlowGraphCompiler*, BranchInstr*) { \ 168 void Name##Instr::EmitBranchCode(FlowGraphCompiler*, BranchInstr*) { \
155 UNIMPLEMENTED(); \ 169 UNIMPLEMENTED(); \
156 } \ 170 } \
157 Condition Name##Instr::EmitComparisonCode(FlowGraphCompiler*, \ 171 Condition Name##Instr::EmitComparisonCode(FlowGraphCompiler*, \
158 BranchLabels) { \ 172 BranchLabels) { \
159 UNIMPLEMENTED(); \ 173 UNIMPLEMENTED(); \
160 return NEXT_IS_TRUE; \ 174 return NEXT_IS_TRUE; \
161 } 175 }
162 176
163 #define DEFINE_UNIMPLEMENTED(Name) \ 177 #define DEFINE_UNIMPLEMENTED(Name) \
164 DEFINE_UNIMPLEMENTED_MAKE_LOCATION_SUMMARY(Name) \ 178 DEFINE_UNIMPLEMENTED_MAKE_LOCATION_SUMMARY(Name) \
165 DEFINE_UNIMPLEMENTED_EMIT_NATIVE_CODE(Name) \ 179 DEFINE_UNIMPLEMENTED_EMIT_NATIVE_CODE(Name) \
166 180
167 FOR_EACH_UNIMPLEMENTED_INSTRUCTION(DEFINE_UNIMPLEMENTED) 181 FOR_EACH_UNIMPLEMENTED_INSTRUCTION(DEFINE_UNIMPLEMENTED)
168 182
169 #undef DEFINE_UNIMPLEMENTED 183 #undef DEFINE_UNIMPLEMENTED
170 184
171 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(TestCids) 185 #define DEFINE_UNREACHABLE(Name) \
186 DEFINE_UNREACHABLE_MAKE_LOCATION_SUMMARY(Name) \
187 DEFINE_UNREACHABLE_EMIT_NATIVE_CODE(Name) \
188
189 FOR_EACH_UNREACHABLE_INSTRUCTION(DEFINE_UNREACHABLE)
190
191 #undef DEFINE_UNREACHABLE
192
172 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(RelationalOp) 193 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(RelationalOp)
173 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(EqualityCompare) 194 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(EqualityCompare)
174 195
175 196
176 EMIT_NATIVE_CODE(InstanceOf, 2, Location::SameAsFirstInput(), 197 EMIT_NATIVE_CODE(InstanceOf, 2, Location::SameAsFirstInput(),
177 LocationSummary::kCall) { 198 LocationSummary::kCall) {
178 SubtypeTestCache& test_cache = SubtypeTestCache::Handle(); 199 SubtypeTestCache& test_cache = SubtypeTestCache::Handle();
179 if (!type().IsVoidType() && type().IsInstantiated()) { 200 if (!type().IsVoidType() && type().IsInstantiated()) {
180 test_cache = SubtypeTestCache::New(); 201 test_cache = SubtypeTestCache::New();
181 } 202 }
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 558
538 EMIT_NATIVE_CODE(TestSmi, 559 EMIT_NATIVE_CODE(TestSmi,
539 2, 560 2,
540 Location::RequiresRegister(), 561 Location::RequiresRegister(),
541 LocationSummary::kNoCall) { 562 LocationSummary::kNoCall) {
542 // Never emitted outside of the BranchInstr. 563 // Never emitted outside of the BranchInstr.
543 UNREACHABLE(); 564 UNREACHABLE();
544 } 565 }
545 566
546 567
568 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
569 BranchLabels labels) {
570 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT));
571 const Register value = locs()->in(0).reg();
572 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0;
573
574 const ZoneGrowableArray<intptr_t>& data = cid_results();
575 const intptr_t num_cases = data.length() / 2;
576 ASSERT(num_cases <= 255);
577 __ TestCids(value, num_cases);
578
579 bool result = false;
580 for (intptr_t i = 0; i < data.length(); i += 2) {
581 const intptr_t test_cid = data[i];
582 result = data[i + 1] == true_result;
583 __ Nop(result ? 1 : 0, compiler->ToEmbeddableCid(test_cid, this));
584 }
585
586 // No match found, deoptimize or false.
587 if (CanDeoptimize()) {
588 compiler->EmitDeopt(deopt_id(),
589 ICData::kDeoptTestCids,
590 licm_hoisted_ ? ICData::kHoisted : 0);
591 } else {
592 Label* target = result ? labels.false_label : labels.true_label;
593 __ Jump(target);
594 }
595
596 return NEXT_IS_TRUE;
597 }
598
599
600 void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler,
601 BranchInstr* branch) {
602 BranchLabels labels = compiler->CreateBranchLabels(branch);
603 Condition true_condition = EmitComparisonCode(compiler, labels);
604 EmitBranchOnCondition(compiler, true_condition, labels);
605 }
606
607
608 EMIT_NATIVE_CODE(TestCids, 1, Location::RequiresRegister(),
609 LocationSummary::kNoCall) {
610 Register result_reg = locs()->out(0).reg();
611 Label is_true, is_false, done;
612 BranchLabels labels = { &is_true, &is_false, &is_false };
613 EmitComparisonCode(compiler, labels);
614 __ Jump(&is_true);
615 __ Bind(&is_false);
616 __ LoadConstant(result_reg, Bool::False());
617 __ Jump(&done);
618 __ Bind(&is_true);
619 __ LoadConstant(result_reg, Bool::True());
620 __ Bind(&done);
621 }
622
623
547 EMIT_NATIVE_CODE(CreateArray, 624 EMIT_NATIVE_CODE(CreateArray,
548 2, Location::RequiresRegister(), 625 2, Location::RequiresRegister(),
549 LocationSummary::kCall) { 626 LocationSummary::kCall) {
550 if (compiler->is_optimizing()) { 627 if (compiler->is_optimizing()) {
551 __ Push(locs()->in(0).reg()); 628 __ Push(locs()->in(0).reg());
552 __ Push(locs()->in(1).reg()); 629 __ Push(locs()->in(1).reg());
553 } 630 }
554 __ CreateArrayTOS(); 631 __ CreateArrayTOS();
555 compiler->RecordSafepoint(locs()); 632 compiler->RecordSafepoint(locs());
556 if (compiler->is_optimizing()) { 633 if (compiler->is_optimizing()) {
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 __ BitNot(locs()->out(0).reg(), locs()->in(0).reg()); 1203 __ BitNot(locs()->out(0).reg(), locs()->in(0).reg());
1127 break; 1204 break;
1128 default: 1205 default:
1129 UNREACHABLE(); 1206 UNREACHABLE();
1130 } 1207 }
1131 } 1208 }
1132 1209
1133 } // namespace dart 1210 } // namespace dart
1134 1211
1135 #endif // defined TARGET_ARCH_DBC 1212 #endif // defined TARGET_ARCH_DBC
OLDNEW
« no previous file with comments | « runtime/vm/constants_dbc.h ('k') | runtime/vm/simulator_dbc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698