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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 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/flow_graph_range_analysis_test.cc ('k') | runtime/vm/freelist.h » ('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_type_propagator.h" 5 #include "vm/flow_graph_type_propagator.h"
6 6
7 #include "vm/bit_vector.h"
7 #include "vm/cha.h" 8 #include "vm/cha.h"
8 #include "vm/bit_vector.h"
9 #include "vm/il_printer.h" 9 #include "vm/il_printer.h"
10 #include "vm/object_store.h" 10 #include "vm/object_store.h"
11 #include "vm/regexp_assembler.h" 11 #include "vm/regexp_assembler.h"
12 #include "vm/resolver.h" 12 #include "vm/resolver.h"
13 #include "vm/timeline.h" 13 #include "vm/timeline.h"
14 14
15 namespace dart { 15 namespace dart {
16 16
17 DEFINE_FLAG(bool, 17 DEFINE_FLAG(bool,
18 trace_type_propagation, 18 trace_type_propagation,
19 false, 19 false,
20 "Trace flow graph type propagation"); 20 "Trace flow graph type propagation");
21 21
22 DECLARE_FLAG(bool, propagate_types); 22 DECLARE_FLAG(bool, propagate_types);
23 23
24
25 void FlowGraphTypePropagator::Propagate(FlowGraph* flow_graph) { 24 void FlowGraphTypePropagator::Propagate(FlowGraph* flow_graph) {
26 #ifndef PRODUCT 25 #ifndef PRODUCT
27 Thread* thread = flow_graph->thread(); 26 Thread* thread = flow_graph->thread();
28 TimelineStream* compiler_timeline = Timeline::GetCompilerStream(); 27 TimelineStream* compiler_timeline = Timeline::GetCompilerStream();
29 TimelineDurationScope tds2(thread, compiler_timeline, 28 TimelineDurationScope tds2(thread, compiler_timeline,
30 "FlowGraphTypePropagator"); 29 "FlowGraphTypePropagator");
31 #endif // !PRODUCT 30 #endif // !PRODUCT
32 FlowGraphTypePropagator propagator(flow_graph); 31 FlowGraphTypePropagator propagator(flow_graph);
33 propagator.Propagate(); 32 propagator.Propagate();
34 } 33 }
35 34
36
37 FlowGraphTypePropagator::FlowGraphTypePropagator(FlowGraph* flow_graph) 35 FlowGraphTypePropagator::FlowGraphTypePropagator(FlowGraph* flow_graph)
38 : FlowGraphVisitor(flow_graph->reverse_postorder()), 36 : FlowGraphVisitor(flow_graph->reverse_postorder()),
39 flow_graph_(flow_graph), 37 flow_graph_(flow_graph),
40 visited_blocks_(new (flow_graph->zone()) 38 visited_blocks_(new (flow_graph->zone())
41 BitVector(flow_graph->zone(), 39 BitVector(flow_graph->zone(),
42 flow_graph->reverse_postorder().length())), 40 flow_graph->reverse_postorder().length())),
43 types_(flow_graph->current_ssa_temp_index()), 41 types_(flow_graph->current_ssa_temp_index()),
44 in_worklist_(NULL), 42 in_worklist_(NULL),
45 asserts_(NULL), 43 asserts_(NULL),
46 collected_asserts_(NULL) { 44 collected_asserts_(NULL) {
47 for (intptr_t i = 0; i < flow_graph->current_ssa_temp_index(); i++) { 45 for (intptr_t i = 0; i < flow_graph->current_ssa_temp_index(); i++) {
48 types_.Add(NULL); 46 types_.Add(NULL);
49 } 47 }
50 48
51 if (Isolate::Current()->type_checks()) { 49 if (Isolate::Current()->type_checks()) {
52 asserts_ = new ZoneGrowableArray<AssertAssignableInstr*>( 50 asserts_ = new ZoneGrowableArray<AssertAssignableInstr*>(
53 flow_graph->current_ssa_temp_index()); 51 flow_graph->current_ssa_temp_index());
54 for (intptr_t i = 0; i < flow_graph->current_ssa_temp_index(); i++) { 52 for (intptr_t i = 0; i < flow_graph->current_ssa_temp_index(); i++) {
55 asserts_->Add(NULL); 53 asserts_->Add(NULL);
56 } 54 }
57 55
58 collected_asserts_ = new ZoneGrowableArray<intptr_t>(10); 56 collected_asserts_ = new ZoneGrowableArray<intptr_t>(10);
59 } 57 }
60 } 58 }
61 59
62
63 void FlowGraphTypePropagator::Propagate() { 60 void FlowGraphTypePropagator::Propagate() {
64 if (FLAG_support_il_printer && FLAG_trace_type_propagation && 61 if (FLAG_support_il_printer && FLAG_trace_type_propagation &&
65 FlowGraphPrinter::ShouldPrint(flow_graph_->function())) { 62 FlowGraphPrinter::ShouldPrint(flow_graph_->function())) {
66 FlowGraphPrinter::PrintGraph("Before type propagation", flow_graph_); 63 FlowGraphPrinter::PrintGraph("Before type propagation", flow_graph_);
67 } 64 }
68 65
69 // Walk the dominator tree and propagate reaching types to all Values. 66 // Walk the dominator tree and propagate reaching types to all Values.
70 // Collect all phis for a fixed point iteration. 67 // Collect all phis for a fixed point iteration.
71 PropagateRecursive(flow_graph_->graph_entry()); 68 PropagateRecursive(flow_graph_->graph_entry());
72 69
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 } 103 }
107 } 104 }
108 } 105 }
109 106
110 if (FLAG_support_il_printer && FLAG_trace_type_propagation && 107 if (FLAG_support_il_printer && FLAG_trace_type_propagation &&
111 FlowGraphPrinter::ShouldPrint(flow_graph_->function())) { 108 FlowGraphPrinter::ShouldPrint(flow_graph_->function())) {
112 FlowGraphPrinter::PrintGraph("After type propagation", flow_graph_); 109 FlowGraphPrinter::PrintGraph("After type propagation", flow_graph_);
113 } 110 }
114 } 111 }
115 112
116
117 void FlowGraphTypePropagator::PropagateRecursive(BlockEntryInstr* block) { 113 void FlowGraphTypePropagator::PropagateRecursive(BlockEntryInstr* block) {
118 if (visited_blocks_->Contains(block->postorder_number())) { 114 if (visited_blocks_->Contains(block->postorder_number())) {
119 return; 115 return;
120 } 116 }
121 visited_blocks_->Add(block->postorder_number()); 117 visited_blocks_->Add(block->postorder_number());
122 118
123 const intptr_t rollback_point = rollback_.length(); 119 const intptr_t rollback_point = rollback_.length();
124 120
125 if (Isolate::Current()->type_checks()) { 121 if (Isolate::Current()->type_checks()) {
126 StrengthenAsserts(block); 122 StrengthenAsserts(block);
(...skipping 23 matching lines...) Expand all
150 } 146 }
151 } 147 }
152 148
153 for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) { 149 for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) {
154 PropagateRecursive(block->dominated_blocks()[i]); 150 PropagateRecursive(block->dominated_blocks()[i]);
155 } 151 }
156 152
157 RollbackTo(rollback_point); 153 RollbackTo(rollback_point);
158 } 154 }
159 155
160
161 void FlowGraphTypePropagator::RollbackTo(intptr_t rollback_point) { 156 void FlowGraphTypePropagator::RollbackTo(intptr_t rollback_point) {
162 for (intptr_t i = rollback_.length() - 1; i >= rollback_point; i--) { 157 for (intptr_t i = rollback_.length() - 1; i >= rollback_point; i--) {
163 types_[rollback_[i].index()] = rollback_[i].type(); 158 types_[rollback_[i].index()] = rollback_[i].type();
164 } 159 }
165 rollback_.TruncateTo(rollback_point); 160 rollback_.TruncateTo(rollback_point);
166 } 161 }
167 162
168
169 CompileType* FlowGraphTypePropagator::TypeOf(Definition* def) { 163 CompileType* FlowGraphTypePropagator::TypeOf(Definition* def) {
170 const intptr_t index = def->ssa_temp_index(); 164 const intptr_t index = def->ssa_temp_index();
171 165
172 CompileType* type = types_[index]; 166 CompileType* type = types_[index];
173 if (type == NULL) { 167 if (type == NULL) {
174 type = types_[index] = def->Type(); 168 type = types_[index] = def->Type();
175 ASSERT(type != NULL); 169 ASSERT(type != NULL);
176 } 170 }
177 return type; 171 return type;
178 } 172 }
179 173
180
181 void FlowGraphTypePropagator::SetTypeOf(Definition* def, CompileType* type) { 174 void FlowGraphTypePropagator::SetTypeOf(Definition* def, CompileType* type) {
182 const intptr_t index = def->ssa_temp_index(); 175 const intptr_t index = def->ssa_temp_index();
183 rollback_.Add(RollbackEntry(index, types_[index])); 176 rollback_.Add(RollbackEntry(index, types_[index]));
184 types_[index] = type; 177 types_[index] = type;
185 } 178 }
186 179
187
188 void FlowGraphTypePropagator::SetCid(Definition* def, intptr_t cid) { 180 void FlowGraphTypePropagator::SetCid(Definition* def, intptr_t cid) {
189 CompileType* current = TypeOf(def); 181 CompileType* current = TypeOf(def);
190 if (current->IsNone() || (current->ToCid() != cid)) { 182 if (current->IsNone() || (current->ToCid() != cid)) {
191 SetTypeOf(def, new CompileType(CompileType::FromCid(cid))); 183 SetTypeOf(def, new CompileType(CompileType::FromCid(cid)));
192 } 184 }
193 } 185 }
194 186
195
196 void FlowGraphTypePropagator::VisitValue(Value* value) { 187 void FlowGraphTypePropagator::VisitValue(Value* value) {
197 CompileType* type = TypeOf(value->definition()); 188 CompileType* type = TypeOf(value->definition());
198 value->SetReachingType(type); 189 value->SetReachingType(type);
199 190
200 if (FLAG_support_il_printer && FLAG_trace_type_propagation && 191 if (FLAG_support_il_printer && FLAG_trace_type_propagation &&
201 FlowGraphPrinter::ShouldPrint(flow_graph_->function())) { 192 FlowGraphPrinter::ShouldPrint(flow_graph_->function())) {
202 THR_Print("reaching type to %s for v%" Pd " is %s\n", 193 THR_Print("reaching type to %s for v%" Pd " is %s\n",
203 value->instruction()->ToCString(), 194 value->instruction()->ToCString(),
204 value->definition()->ssa_temp_index(), type->ToCString()); 195 value->definition()->ssa_temp_index(), type->ToCString());
205 } 196 }
206 } 197 }
207 198
208
209 void FlowGraphTypePropagator::VisitJoinEntry(JoinEntryInstr* join) { 199 void FlowGraphTypePropagator::VisitJoinEntry(JoinEntryInstr* join) {
210 for (PhiIterator it(join); !it.Done(); it.Advance()) { 200 for (PhiIterator it(join); !it.Done(); it.Advance()) {
211 worklist_.Add(it.Current()); 201 worklist_.Add(it.Current());
212 } 202 }
213 } 203 }
214 204
215
216 void FlowGraphTypePropagator::VisitCheckSmi(CheckSmiInstr* check) { 205 void FlowGraphTypePropagator::VisitCheckSmi(CheckSmiInstr* check) {
217 SetCid(check->value()->definition(), kSmiCid); 206 SetCid(check->value()->definition(), kSmiCid);
218 } 207 }
219 208
220
221 void FlowGraphTypePropagator::VisitCheckArrayBound( 209 void FlowGraphTypePropagator::VisitCheckArrayBound(
222 CheckArrayBoundInstr* check) { 210 CheckArrayBoundInstr* check) {
223 // Array bounds checks also test index for smi. 211 // Array bounds checks also test index for smi.
224 SetCid(check->index()->definition(), kSmiCid); 212 SetCid(check->index()->definition(), kSmiCid);
225 } 213 }
226 214
227
228 void FlowGraphTypePropagator::VisitCheckClass(CheckClassInstr* check) { 215 void FlowGraphTypePropagator::VisitCheckClass(CheckClassInstr* check) {
229 if (!check->cids().IsMonomorphic()) { 216 if (!check->cids().IsMonomorphic()) {
230 return; 217 return;
231 } 218 }
232 219
233 if (!check->Dependencies().IsNone()) { 220 if (!check->Dependencies().IsNone()) {
234 // TODO(vegorov): If check is affected by side-effect we can still propagate 221 // TODO(vegorov): If check is affected by side-effect we can still propagate
235 // the type further but not the cid. 222 // the type further but not the cid.
236 return; 223 return;
237 } 224 }
238 225
239 SetCid(check->value()->definition(), check->cids().MonomorphicReceiverCid()); 226 SetCid(check->value()->definition(), check->cids().MonomorphicReceiverCid());
240 } 227 }
241 228
242
243 void FlowGraphTypePropagator::VisitCheckClassId(CheckClassIdInstr* check) { 229 void FlowGraphTypePropagator::VisitCheckClassId(CheckClassIdInstr* check) {
244 if (!check->Dependencies().IsNone()) { 230 if (!check->Dependencies().IsNone()) {
245 // TODO(vegorov): If check is affected by side-effect we can still propagate 231 // TODO(vegorov): If check is affected by side-effect we can still propagate
246 // the type further but not the cid. 232 // the type further but not the cid.
247 return; 233 return;
248 } 234 }
249 235
250 LoadClassIdInstr* load_cid = 236 LoadClassIdInstr* load_cid =
251 check->value()->definition()->OriginalDefinition()->AsLoadClassId(); 237 check->value()->definition()->OriginalDefinition()->AsLoadClassId();
252 if (load_cid != NULL && check->cids().IsSingleCid()) { 238 if (load_cid != NULL && check->cids().IsSingleCid()) {
253 SetCid(load_cid->object()->definition(), check->cids().cid_start); 239 SetCid(load_cid->object()->definition(), check->cids().cid_start);
254 } 240 }
255 } 241 }
256 242
257
258 void FlowGraphTypePropagator::CheckNonNullSelector( 243 void FlowGraphTypePropagator::CheckNonNullSelector(
259 Instruction* call, 244 Instruction* call,
260 Definition* receiver, 245 Definition* receiver,
261 const String& function_name) { 246 const String& function_name) {
262 if (!receiver->Type()->is_nullable()) { 247 if (!receiver->Type()->is_nullable()) {
263 // Nothing to do if type is already non-nullable. 248 // Nothing to do if type is already non-nullable.
264 return; 249 return;
265 } 250 }
266 const Class& null_class = 251 const Class& null_class =
267 Class::Handle(Isolate::Current()->object_store()->null_class()); 252 Class::Handle(Isolate::Current()->object_store()->null_class());
(...skipping 11 matching lines...) Expand all
279 if (redef != NULL) { 264 if (redef != NULL) {
280 for (intptr_t i = types_.length(); i <= redef->ssa_temp_index() + 1; 265 for (intptr_t i = types_.length(); i <= redef->ssa_temp_index() + 1;
281 ++i) { 266 ++i) {
282 types_.Add(NULL); 267 types_.Add(NULL);
283 } 268 }
284 } 269 }
285 } 270 }
286 } 271 }
287 } 272 }
288 273
289
290 void FlowGraphTypePropagator::VisitInstanceCall(InstanceCallInstr* instr) { 274 void FlowGraphTypePropagator::VisitInstanceCall(InstanceCallInstr* instr) {
291 if (instr->has_unique_selector()) { 275 if (instr->has_unique_selector()) {
292 SetCid(instr->ArgumentAt(0), instr->ic_data()->GetReceiverClassIdAt(0)); 276 SetCid(instr->ArgumentAt(0), instr->ic_data()->GetReceiverClassIdAt(0));
293 return; 277 return;
294 } 278 }
295 CheckNonNullSelector(instr, instr->ArgumentAt(0), instr->function_name()); 279 CheckNonNullSelector(instr, instr->ArgumentAt(0), instr->function_name());
296 } 280 }
297 281
298
299 void FlowGraphTypePropagator::VisitPolymorphicInstanceCall( 282 void FlowGraphTypePropagator::VisitPolymorphicInstanceCall(
300 PolymorphicInstanceCallInstr* instr) { 283 PolymorphicInstanceCallInstr* instr) {
301 if (instr->instance_call()->has_unique_selector()) { 284 if (instr->instance_call()->has_unique_selector()) {
302 SetCid(instr->ArgumentAt(0), instr->targets().MonomorphicReceiverCid()); 285 SetCid(instr->ArgumentAt(0), instr->targets().MonomorphicReceiverCid());
303 return; 286 return;
304 } 287 }
305 CheckNonNullSelector(instr, instr->ArgumentAt(0), 288 CheckNonNullSelector(instr, instr->ArgumentAt(0),
306 instr->instance_call()->function_name()); 289 instr->instance_call()->function_name());
307 } 290 }
308 291
309
310 void FlowGraphTypePropagator::VisitGuardFieldClass( 292 void FlowGraphTypePropagator::VisitGuardFieldClass(
311 GuardFieldClassInstr* guard) { 293 GuardFieldClassInstr* guard) {
312 const intptr_t cid = guard->field().guarded_cid(); 294 const intptr_t cid = guard->field().guarded_cid();
313 if ((cid == kIllegalCid) || (cid == kDynamicCid) || 295 if ((cid == kIllegalCid) || (cid == kDynamicCid) ||
314 Field::IsExternalizableCid(cid)) { 296 Field::IsExternalizableCid(cid)) {
315 return; 297 return;
316 } 298 }
317 299
318 Definition* def = guard->value()->definition(); 300 Definition* def = guard->value()->definition();
319 CompileType* current = TypeOf(def); 301 CompileType* current = TypeOf(def);
320 if (current->IsNone() || (current->ToCid() != cid) || 302 if (current->IsNone() || (current->ToCid() != cid) ||
321 (current->is_nullable() && !guard->field().is_nullable())) { 303 (current->is_nullable() && !guard->field().is_nullable())) {
322 const bool is_nullable = 304 const bool is_nullable =
323 guard->field().is_nullable() && current->is_nullable(); 305 guard->field().is_nullable() && current->is_nullable();
324 SetTypeOf(def, new CompileType(is_nullable, cid, NULL)); 306 SetTypeOf(def, new CompileType(is_nullable, cid, NULL));
325 } 307 }
326 } 308 }
327 309
328
329 void FlowGraphTypePropagator::VisitAssertAssignable( 310 void FlowGraphTypePropagator::VisitAssertAssignable(
330 AssertAssignableInstr* instr) { 311 AssertAssignableInstr* instr) {
331 SetTypeOf(instr->value()->definition(), 312 SetTypeOf(instr->value()->definition(),
332 new CompileType(instr->ComputeType())); 313 new CompileType(instr->ComputeType()));
333 } 314 }
334 315
335
336 void FlowGraphTypePropagator::VisitBranch(BranchInstr* instr) { 316 void FlowGraphTypePropagator::VisitBranch(BranchInstr* instr) {
337 StrictCompareInstr* comparison = instr->comparison()->AsStrictCompare(); 317 StrictCompareInstr* comparison = instr->comparison()->AsStrictCompare();
338 if (comparison == NULL) return; 318 if (comparison == NULL) return;
339 bool negated = comparison->kind() == Token::kNE_STRICT; 319 bool negated = comparison->kind() == Token::kNE_STRICT;
340 LoadClassIdInstr* load_cid = 320 LoadClassIdInstr* load_cid =
341 comparison->InputAt(0)->definition()->AsLoadClassId(); 321 comparison->InputAt(0)->definition()->AsLoadClassId();
342 InstanceCallInstr* call = 322 InstanceCallInstr* call =
343 comparison->InputAt(0)->definition()->AsInstanceCall(); 323 comparison->InputAt(0)->definition()->AsInstanceCall();
344 RedefinitionInstr* redef = NULL; 324 RedefinitionInstr* redef = NULL;
345 if (load_cid != NULL && comparison->InputAt(1)->BindsToConstant()) { 325 if (load_cid != NULL && comparison->InputAt(1)->BindsToConstant()) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 // TODO(fschneider): Add propagation for generic is-tests. 370 // TODO(fschneider): Add propagation for generic is-tests.
391 371
392 // Grow types array if a new redefinition was inserted. 372 // Grow types array if a new redefinition was inserted.
393 if (redef != NULL) { 373 if (redef != NULL) {
394 for (intptr_t i = types_.length(); i <= redef->ssa_temp_index() + 1; ++i) { 374 for (intptr_t i = types_.length(); i <= redef->ssa_temp_index() + 1; ++i) {
395 types_.Add(NULL); 375 types_.Add(NULL);
396 } 376 }
397 } 377 }
398 } 378 }
399 379
400
401 void FlowGraphTypePropagator::AddToWorklist(Definition* defn) { 380 void FlowGraphTypePropagator::AddToWorklist(Definition* defn) {
402 if (defn->ssa_temp_index() == -1) { 381 if (defn->ssa_temp_index() == -1) {
403 return; 382 return;
404 } 383 }
405 384
406 const intptr_t index = defn->ssa_temp_index(); 385 const intptr_t index = defn->ssa_temp_index();
407 if (!in_worklist_->Contains(index)) { 386 if (!in_worklist_->Contains(index)) {
408 worklist_.Add(defn); 387 worklist_.Add(defn);
409 in_worklist_->Add(index); 388 in_worklist_->Add(index);
410 } 389 }
411 } 390 }
412 391
413
414 Definition* FlowGraphTypePropagator::RemoveLastFromWorklist() { 392 Definition* FlowGraphTypePropagator::RemoveLastFromWorklist() {
415 Definition* defn = worklist_.RemoveLast(); 393 Definition* defn = worklist_.RemoveLast();
416 ASSERT(defn->ssa_temp_index() != -1); 394 ASSERT(defn->ssa_temp_index() != -1);
417 in_worklist_->Remove(defn->ssa_temp_index()); 395 in_worklist_->Remove(defn->ssa_temp_index());
418 return defn; 396 return defn;
419 } 397 }
420 398
421
422 // In the given block strengthen type assertions by hoisting first class or smi 399 // In the given block strengthen type assertions by hoisting first class or smi
423 // check over the same value up to the point before the assertion. This allows 400 // check over the same value up to the point before the assertion. This allows
424 // to eliminate type assertions that are postdominated by class or smi checks as 401 // to eliminate type assertions that are postdominated by class or smi checks as
425 // these checks are strongly stricter than type assertions. 402 // these checks are strongly stricter than type assertions.
426 void FlowGraphTypePropagator::StrengthenAsserts(BlockEntryInstr* block) { 403 void FlowGraphTypePropagator::StrengthenAsserts(BlockEntryInstr* block) {
427 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 404 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
428 Instruction* instr = it.Current(); 405 Instruction* instr = it.Current();
429 406
430 if (instr->IsCheckSmi() || instr->IsCheckClass()) { 407 if (instr->IsCheckSmi() || instr->IsCheckClass()) {
431 StrengthenAssertWith(instr); 408 StrengthenAssertWith(instr);
(...skipping 10 matching lines...) Expand all
442 } 419 }
443 } 420 }
444 421
445 for (intptr_t i = 0; i < collected_asserts_->length(); i++) { 422 for (intptr_t i = 0; i < collected_asserts_->length(); i++) {
446 (*asserts_)[(*collected_asserts_)[i]] = NULL; 423 (*asserts_)[(*collected_asserts_)[i]] = NULL;
447 } 424 }
448 425
449 collected_asserts_->TruncateTo(0); 426 collected_asserts_->TruncateTo(0);
450 } 427 }
451 428
452
453 void FlowGraphTypePropagator::StrengthenAssertWith(Instruction* check) { 429 void FlowGraphTypePropagator::StrengthenAssertWith(Instruction* check) {
454 // Marker that is used to mark values that already had type assertion 430 // Marker that is used to mark values that already had type assertion
455 // strengthened. 431 // strengthened.
456 AssertAssignableInstr* kStrengthenedAssertMarker = 432 AssertAssignableInstr* kStrengthenedAssertMarker =
457 reinterpret_cast<AssertAssignableInstr*>(-1); 433 reinterpret_cast<AssertAssignableInstr*>(-1);
458 434
459 Definition* defn = check->InputAt(0)->definition()->OriginalDefinition(); 435 Definition* defn = check->InputAt(0)->definition()->OriginalDefinition();
460 436
461 AssertAssignableInstr* assert = (*asserts_)[defn->ssa_temp_index()]; 437 AssertAssignableInstr* assert = (*asserts_)[defn->ssa_temp_index()];
462 if ((assert == NULL) || (assert == kStrengthenedAssertMarker)) { 438 if ((assert == NULL) || (assert == kStrengthenedAssertMarker)) {
(...skipping 17 matching lines...) Expand all
480 check->AsCheckClass()->licm_hoisted()); 456 check->AsCheckClass()->licm_hoisted());
481 } 457 }
482 ASSERT(check_clone != NULL); 458 ASSERT(check_clone != NULL);
483 ASSERT(assert->deopt_id() == assert->env()->deopt_id()); 459 ASSERT(assert->deopt_id() == assert->env()->deopt_id());
484 check_clone->InsertBefore(assert); 460 check_clone->InsertBefore(assert);
485 assert->env()->DeepCopyTo(zone(), check_clone); 461 assert->env()->DeepCopyTo(zone(), check_clone);
486 462
487 (*asserts_)[defn->ssa_temp_index()] = kStrengthenedAssertMarker; 463 (*asserts_)[defn->ssa_temp_index()] = kStrengthenedAssertMarker;
488 } 464 }
489 465
490
491 void CompileType::Union(CompileType* other) { 466 void CompileType::Union(CompileType* other) {
492 if (other->IsNone()) { 467 if (other->IsNone()) {
493 return; 468 return;
494 } 469 }
495 470
496 if (IsNone()) { 471 if (IsNone()) {
497 *this = *other; 472 *this = *other;
498 return; 473 return;
499 } 474 }
500 475
(...skipping 21 matching lines...) Expand all
522 type_ = other_compile_type; 497 type_ = other_compile_type;
523 } else if (other_compile_type->IsMoreSpecificThan(*compile_type, NULL, NULL, 498 } else if (other_compile_type->IsMoreSpecificThan(*compile_type, NULL, NULL,
524 Heap::kOld)) { 499 Heap::kOld)) {
525 // Nothing to do. 500 // Nothing to do.
526 } else { 501 } else {
527 // Can't unify. 502 // Can't unify.
528 type_ = &Object::dynamic_type(); 503 type_ = &Object::dynamic_type();
529 } 504 }
530 } 505 }
531 506
532
533 static bool IsNullableCid(intptr_t cid) { 507 static bool IsNullableCid(intptr_t cid) {
534 ASSERT(cid != kIllegalCid); 508 ASSERT(cid != kIllegalCid);
535 return cid == kNullCid || cid == kDynamicCid; 509 return cid == kNullCid || cid == kDynamicCid;
536 } 510 }
537 511
538
539 CompileType CompileType::Create(intptr_t cid, const AbstractType& type) { 512 CompileType CompileType::Create(intptr_t cid, const AbstractType& type) {
540 return CompileType(IsNullableCid(cid), cid, &type); 513 return CompileType(IsNullableCid(cid), cid, &type);
541 } 514 }
542 515
543
544 CompileType CompileType::FromAbstractType(const AbstractType& type, 516 CompileType CompileType::FromAbstractType(const AbstractType& type,
545 bool is_nullable) { 517 bool is_nullable) {
546 return CompileType(is_nullable, kIllegalCid, &type); 518 return CompileType(is_nullable, kIllegalCid, &type);
547 } 519 }
548 520
549
550 CompileType CompileType::FromCid(intptr_t cid) { 521 CompileType CompileType::FromCid(intptr_t cid) {
551 return CompileType(IsNullableCid(cid), cid, NULL); 522 return CompileType(IsNullableCid(cid), cid, NULL);
552 } 523 }
553 524
554
555 CompileType CompileType::Dynamic() { 525 CompileType CompileType::Dynamic() {
556 return Create(kDynamicCid, Object::dynamic_type()); 526 return Create(kDynamicCid, Object::dynamic_type());
557 } 527 }
558 528
559
560 CompileType CompileType::Null() { 529 CompileType CompileType::Null() {
561 return Create(kNullCid, Type::ZoneHandle(Type::NullType())); 530 return Create(kNullCid, Type::ZoneHandle(Type::NullType()));
562 } 531 }
563 532
564
565 CompileType CompileType::Bool() { 533 CompileType CompileType::Bool() {
566 return Create(kBoolCid, Type::ZoneHandle(Type::BoolType())); 534 return Create(kBoolCid, Type::ZoneHandle(Type::BoolType()));
567 } 535 }
568 536
569
570 CompileType CompileType::Int() { 537 CompileType CompileType::Int() {
571 return FromAbstractType(Type::ZoneHandle(Type::Int64Type()), kNonNullable); 538 return FromAbstractType(Type::ZoneHandle(Type::Int64Type()), kNonNullable);
572 } 539 }
573 540
574
575 CompileType CompileType::Smi() { 541 CompileType CompileType::Smi() {
576 return Create(kSmiCid, Type::ZoneHandle(Type::SmiType())); 542 return Create(kSmiCid, Type::ZoneHandle(Type::SmiType()));
577 } 543 }
578 544
579
580 CompileType CompileType::String() { 545 CompileType CompileType::String() {
581 return FromAbstractType(Type::ZoneHandle(Type::StringType()), kNonNullable); 546 return FromAbstractType(Type::ZoneHandle(Type::StringType()), kNonNullable);
582 } 547 }
583 548
584
585 intptr_t CompileType::ToCid() { 549 intptr_t CompileType::ToCid() {
586 if ((cid_ == kNullCid) || (cid_ == kDynamicCid)) { 550 if ((cid_ == kNullCid) || (cid_ == kDynamicCid)) {
587 return cid_; 551 return cid_;
588 } 552 }
589 553
590 return is_nullable_ ? static_cast<intptr_t>(kDynamicCid) : ToNullableCid(); 554 return is_nullable_ ? static_cast<intptr_t>(kDynamicCid) : ToNullableCid();
591 } 555 }
592 556
593
594 intptr_t CompileType::ToNullableCid() { 557 intptr_t CompileType::ToNullableCid() {
595 if (cid_ == kIllegalCid) { 558 if (cid_ == kIllegalCid) {
596 if (type_ == NULL) { 559 if (type_ == NULL) {
597 // Type propagation is turned off or has not yet run. 560 // Type propagation is turned off or has not yet run.
598 return kDynamicCid; 561 return kDynamicCid;
599 } else if (type_->IsMalformed()) { 562 } else if (type_->IsMalformed()) {
600 cid_ = kDynamicCid; 563 cid_ = kDynamicCid;
601 } else if (type_->IsVoidType()) { 564 } else if (type_->IsVoidType()) {
602 cid_ = kDynamicCid; 565 cid_ = kDynamicCid;
603 } else if (type_->IsFunctionType() || type_->IsDartFunctionType()) { 566 } else if (type_->IsFunctionType() || type_->IsDartFunctionType()) {
(...skipping 25 matching lines...) Expand all
629 cid_ = kDynamicCid; 592 cid_ = kDynamicCid;
630 } 593 }
631 } else { 594 } else {
632 cid_ = kDynamicCid; 595 cid_ = kDynamicCid;
633 } 596 }
634 } 597 }
635 598
636 return cid_; 599 return cid_;
637 } 600 }
638 601
639
640 bool CompileType::HasDecidableNullability() { 602 bool CompileType::HasDecidableNullability() {
641 return !is_nullable_ || IsNull(); 603 return !is_nullable_ || IsNull();
642 } 604 }
643 605
644
645 bool CompileType::IsNull() { 606 bool CompileType::IsNull() {
646 return (ToCid() == kNullCid); 607 return (ToCid() == kNullCid);
647 } 608 }
648 609
649
650 const AbstractType* CompileType::ToAbstractType() { 610 const AbstractType* CompileType::ToAbstractType() {
651 if (type_ == NULL) { 611 if (type_ == NULL) {
652 // Type propagation has not run. Return dynamic-type. 612 // Type propagation has not run. Return dynamic-type.
653 if (cid_ == kIllegalCid) { 613 if (cid_ == kIllegalCid) {
654 type_ = &Object::dynamic_type(); 614 type_ = &Object::dynamic_type();
655 return type_; 615 return type_;
656 } 616 }
657 617
658 // VM-internal objects don't have a compile-type. Return dynamic-type 618 // VM-internal objects don't have a compile-type. Return dynamic-type
659 // in this case. 619 // in this case.
660 if (cid_ < kInstanceCid) { 620 if (cid_ < kInstanceCid) {
661 type_ = &Object::dynamic_type(); 621 type_ = &Object::dynamic_type();
662 return type_; 622 return type_;
663 } 623 }
664 624
665 const Class& type_class = 625 const Class& type_class =
666 Class::Handle(Isolate::Current()->class_table()->At(cid_)); 626 Class::Handle(Isolate::Current()->class_table()->At(cid_));
667 627
668 if (type_class.NumTypeArguments() > 0) { 628 if (type_class.NumTypeArguments() > 0) {
669 type_ = &Object::dynamic_type(); 629 type_ = &Object::dynamic_type();
670 return type_; 630 return type_;
671 } 631 }
672 632
673 type_ = &Type::ZoneHandle(Type::NewNonParameterizedType(type_class)); 633 type_ = &Type::ZoneHandle(Type::NewNonParameterizedType(type_class));
674 } 634 }
675 635
676 return type_; 636 return type_;
677 } 637 }
678 638
679
680 bool CompileType::CanComputeIsInstanceOf(const AbstractType& type, 639 bool CompileType::CanComputeIsInstanceOf(const AbstractType& type,
681 bool is_nullable, 640 bool is_nullable,
682 bool* is_instance) { 641 bool* is_instance) {
683 ASSERT(is_instance != NULL); 642 ASSERT(is_instance != NULL);
684 // We cannot give an answer if the given type is malformed or malbounded. 643 // We cannot give an answer if the given type is malformed or malbounded.
685 if (type.IsMalformedOrMalbounded()) { 644 if (type.IsMalformedOrMalbounded()) {
686 return false; 645 return false;
687 } 646 }
688 647
689 if (type.IsDynamicType() || type.IsObjectType() || type.IsVoidType()) { 648 if (type.IsDynamicType() || type.IsObjectType() || type.IsVoidType()) {
(...skipping 25 matching lines...) Expand all
715 // If the value can be null then we can't eliminate the 674 // If the value can be null then we can't eliminate the
716 // check unless null is allowed. 675 // check unless null is allowed.
717 if (is_nullable_ && !is_nullable) { 676 if (is_nullable_ && !is_nullable) {
718 return false; 677 return false;
719 } 678 }
720 679
721 *is_instance = compile_type.IsMoreSpecificThan(type, NULL, NULL, Heap::kOld); 680 *is_instance = compile_type.IsMoreSpecificThan(type, NULL, NULL, Heap::kOld);
722 return *is_instance; 681 return *is_instance;
723 } 682 }
724 683
725
726 bool CompileType::IsMoreSpecificThan(const AbstractType& other) { 684 bool CompileType::IsMoreSpecificThan(const AbstractType& other) {
727 if (IsNone()) { 685 if (IsNone()) {
728 return false; 686 return false;
729 } 687 }
730 688
731 return ToAbstractType()->IsMoreSpecificThan(other, NULL, NULL, Heap::kOld); 689 return ToAbstractType()->IsMoreSpecificThan(other, NULL, NULL, Heap::kOld);
732 } 690 }
733 691
734
735 CompileType* Value::Type() { 692 CompileType* Value::Type() {
736 if (reaching_type_ == NULL) { 693 if (reaching_type_ == NULL) {
737 reaching_type_ = definition()->Type(); 694 reaching_type_ = definition()->Type();
738 } 695 }
739 return reaching_type_; 696 return reaching_type_;
740 } 697 }
741 698
742
743 CompileType PhiInstr::ComputeType() const { 699 CompileType PhiInstr::ComputeType() const {
744 // Initially type of phis is unknown until type propagation is run 700 // Initially type of phis is unknown until type propagation is run
745 // for the first time. 701 // for the first time.
746 return CompileType::None(); 702 return CompileType::None();
747 } 703 }
748 704
749
750 bool PhiInstr::RecomputeType() { 705 bool PhiInstr::RecomputeType() {
751 CompileType result = CompileType::None(); 706 CompileType result = CompileType::None();
752 for (intptr_t i = 0; i < InputCount(); i++) { 707 for (intptr_t i = 0; i < InputCount(); i++) {
753 if (FLAG_support_il_printer && FLAG_trace_type_propagation) { 708 if (FLAG_support_il_printer && FLAG_trace_type_propagation) {
754 THR_Print(" phi %" Pd " input %" Pd ": v%" Pd " has reaching type %s\n", 709 THR_Print(" phi %" Pd " input %" Pd ": v%" Pd " has reaching type %s\n",
755 ssa_temp_index(), i, InputAt(i)->definition()->ssa_temp_index(), 710 ssa_temp_index(), i, InputAt(i)->definition()->ssa_temp_index(),
756 InputAt(i)->Type()->ToCString()); 711 InputAt(i)->Type()->ToCString());
757 } 712 }
758 result.Union(InputAt(i)->Type()); 713 result.Union(InputAt(i)->Type());
759 } 714 }
760 715
761 if (result.IsNone()) { 716 if (result.IsNone()) {
762 ASSERT(Type()->IsNone()); 717 ASSERT(Type()->IsNone());
763 return false; 718 return false;
764 } 719 }
765 720
766 return UpdateType(result); 721 return UpdateType(result);
767 } 722 }
768 723
769
770 CompileType RedefinitionInstr::ComputeType() const { 724 CompileType RedefinitionInstr::ComputeType() const {
771 if (constrained_type_ != NULL) { 725 if (constrained_type_ != NULL) {
772 // Check if the type associated with this redefinition is more specific 726 // Check if the type associated with this redefinition is more specific
773 // than the type of its input. If yes, return it. Otherwise, fall back 727 // than the type of its input. If yes, return it. Otherwise, fall back
774 // to the input's type. 728 // to the input's type.
775 729
776 // If either type is non-nullable, the resulting type is non-nullable. 730 // If either type is non-nullable, the resulting type is non-nullable.
777 const bool is_nullable = 731 const bool is_nullable =
778 value()->Type()->is_nullable() && constrained_type_->is_nullable(); 732 value()->Type()->is_nullable() && constrained_type_->is_nullable();
779 733
(...skipping 11 matching lines...) Expand all
791 return is_nullable ? *value()->Type() 745 return is_nullable ? *value()->Type()
792 : value()->Type()->CopyNonNullable(); 746 : value()->Type()->CopyNonNullable();
793 } else { 747 } else {
794 return is_nullable ? *constrained_type_ 748 return is_nullable ? *constrained_type_
795 : constrained_type_->CopyNonNullable(); 749 : constrained_type_->CopyNonNullable();
796 } 750 }
797 } 751 }
798 return *value()->Type(); 752 return *value()->Type();
799 } 753 }
800 754
801
802 bool RedefinitionInstr::RecomputeType() { 755 bool RedefinitionInstr::RecomputeType() {
803 return UpdateType(ComputeType()); 756 return UpdateType(ComputeType());
804 } 757 }
805 758
806
807 CompileType IfThenElseInstr::ComputeType() const { 759 CompileType IfThenElseInstr::ComputeType() const {
808 return CompileType::FromCid(kSmiCid); 760 return CompileType::FromCid(kSmiCid);
809 } 761 }
810 762
811
812 CompileType ParameterInstr::ComputeType() const { 763 CompileType ParameterInstr::ComputeType() const {
813 // Note that returning the declared type of the formal parameter would be 764 // Note that returning the declared type of the formal parameter would be
814 // incorrect, because ParameterInstr is used as input to the type check 765 // incorrect, because ParameterInstr is used as input to the type check
815 // verifying the run time type of the passed-in parameter and this check would 766 // verifying the run time type of the passed-in parameter and this check would
816 // always be wrongly eliminated. 767 // always be wrongly eliminated.
817 // However there are parameters that are known to match their declared type: 768 // However there are parameters that are known to match their declared type:
818 // for example receiver. 769 // for example receiver.
819 GraphEntryInstr* graph_entry = block_->AsGraphEntry(); 770 GraphEntryInstr* graph_entry = block_->AsGraphEntry();
820 if (graph_entry == NULL) { 771 if (graph_entry == NULL) {
821 graph_entry = block_->AsCatchBlockEntry()->graph_entry(); 772 graph_entry = block_->AsCatchBlockEntry()->graph_entry();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 } 837 }
887 } 838 }
888 } 839 }
889 840
890 return CompileType(CompileType::kNonNullable, cid, &type); 841 return CompileType(CompileType::kNonNullable, cid, &type);
891 } 842 }
892 843
893 return CompileType::Dynamic(); 844 return CompileType::Dynamic();
894 } 845 }
895 846
896
897 CompileType PushArgumentInstr::ComputeType() const { 847 CompileType PushArgumentInstr::ComputeType() const {
898 return CompileType::Dynamic(); 848 return CompileType::Dynamic();
899 } 849 }
900 850
901
902 CompileType ConstantInstr::ComputeType() const { 851 CompileType ConstantInstr::ComputeType() const {
903 if (value().IsNull()) { 852 if (value().IsNull()) {
904 return CompileType::Null(); 853 return CompileType::Null();
905 } 854 }
906 855
907 intptr_t cid = value().GetClassId(); 856 intptr_t cid = value().GetClassId();
908 if (Field::IsExternalizableCid(cid)) { 857 if (Field::IsExternalizableCid(cid)) {
909 cid = kDynamicCid; 858 cid = kDynamicCid;
910 } 859 }
911 860
912 if (value().IsInstance()) { 861 if (value().IsInstance()) {
913 // Allocate in old-space since this may be invoked from the 862 // Allocate in old-space since this may be invoked from the
914 // background compiler. 863 // background compiler.
915 return CompileType::Create( 864 return CompileType::Create(
916 cid, 865 cid,
917 AbstractType::ZoneHandle(Instance::Cast(value()).GetType(Heap::kOld))); 866 AbstractType::ZoneHandle(Instance::Cast(value()).GetType(Heap::kOld)));
918 } else { 867 } else {
919 // Type info for non-instance objects. 868 // Type info for non-instance objects.
920 return CompileType::FromCid(cid); 869 return CompileType::FromCid(cid);
921 } 870 }
922 } 871 }
923 872
924
925 CompileType AssertAssignableInstr::ComputeType() const { 873 CompileType AssertAssignableInstr::ComputeType() const {
926 CompileType* value_type = value()->Type(); 874 CompileType* value_type = value()->Type();
927 875
928 if (value_type->IsMoreSpecificThan(dst_type())) { 876 if (value_type->IsMoreSpecificThan(dst_type())) {
929 return *value_type; 877 return *value_type;
930 } 878 }
931 879
932 return CompileType::Create(value_type->ToCid(), dst_type()); 880 return CompileType::Create(value_type->ToCid(), dst_type());
933 } 881 }
934 882
935
936 bool AssertAssignableInstr::RecomputeType() { 883 bool AssertAssignableInstr::RecomputeType() {
937 return UpdateType(ComputeType()); 884 return UpdateType(ComputeType());
938 } 885 }
939 886
940
941 CompileType AssertBooleanInstr::ComputeType() const { 887 CompileType AssertBooleanInstr::ComputeType() const {
942 return CompileType::Bool(); 888 return CompileType::Bool();
943 } 889 }
944 890
945
946 CompileType BooleanNegateInstr::ComputeType() const { 891 CompileType BooleanNegateInstr::ComputeType() const {
947 return CompileType::Bool(); 892 return CompileType::Bool();
948 } 893 }
949 894
950
951 CompileType InstanceOfInstr::ComputeType() const { 895 CompileType InstanceOfInstr::ComputeType() const {
952 return CompileType::Bool(); 896 return CompileType::Bool();
953 } 897 }
954 898
955
956 CompileType StrictCompareInstr::ComputeType() const { 899 CompileType StrictCompareInstr::ComputeType() const {
957 return CompileType::Bool(); 900 return CompileType::Bool();
958 } 901 }
959 902
960
961 CompileType TestSmiInstr::ComputeType() const { 903 CompileType TestSmiInstr::ComputeType() const {
962 return CompileType::Bool(); 904 return CompileType::Bool();
963 } 905 }
964 906
965
966 CompileType TestCidsInstr::ComputeType() const { 907 CompileType TestCidsInstr::ComputeType() const {
967 return CompileType::Bool(); 908 return CompileType::Bool();
968 } 909 }
969 910
970
971 CompileType EqualityCompareInstr::ComputeType() const { 911 CompileType EqualityCompareInstr::ComputeType() const {
972 // Used for numeric comparisons only. 912 // Used for numeric comparisons only.
973 return CompileType::Bool(); 913 return CompileType::Bool();
974 } 914 }
975 915
976
977 CompileType RelationalOpInstr::ComputeType() const { 916 CompileType RelationalOpInstr::ComputeType() const {
978 // Used for numeric comparisons only. 917 // Used for numeric comparisons only.
979 return CompileType::Bool(); 918 return CompileType::Bool();
980 } 919 }
981 920
982
983 CompileType SpecialParameterInstr::ComputeType() const { 921 CompileType SpecialParameterInstr::ComputeType() const {
984 switch (kind()) { 922 switch (kind()) {
985 case kContext: 923 case kContext:
986 return CompileType::FromCid(kContextCid); 924 return CompileType::FromCid(kContextCid);
987 case kTypeArgs: 925 case kTypeArgs:
988 return CompileType::FromCid(kTypeArgumentsCid); 926 return CompileType::FromCid(kTypeArgumentsCid);
989 } 927 }
990 UNREACHABLE(); 928 UNREACHABLE();
991 return CompileType::Dynamic(); 929 return CompileType::Dynamic();
992 } 930 }
993 931
994
995 CompileType CloneContextInstr::ComputeType() const { 932 CompileType CloneContextInstr::ComputeType() const {
996 return CompileType(CompileType::kNonNullable, kContextCid, 933 return CompileType(CompileType::kNonNullable, kContextCid,
997 &Object::dynamic_type()); 934 &Object::dynamic_type());
998 } 935 }
999 936
1000
1001 CompileType AllocateContextInstr::ComputeType() const { 937 CompileType AllocateContextInstr::ComputeType() const {
1002 return CompileType(CompileType::kNonNullable, kContextCid, 938 return CompileType(CompileType::kNonNullable, kContextCid,
1003 &Object::dynamic_type()); 939 &Object::dynamic_type());
1004 } 940 }
1005 941
1006
1007 CompileType AllocateUninitializedContextInstr::ComputeType() const { 942 CompileType AllocateUninitializedContextInstr::ComputeType() const {
1008 return CompileType(CompileType::kNonNullable, kContextCid, 943 return CompileType(CompileType::kNonNullable, kContextCid,
1009 &Object::dynamic_type()); 944 &Object::dynamic_type());
1010 } 945 }
1011 946
1012
1013 CompileType PolymorphicInstanceCallInstr::ComputeType() const { 947 CompileType PolymorphicInstanceCallInstr::ComputeType() const {
1014 if (!IsSureToCallSingleRecognizedTarget()) return CompileType::Dynamic(); 948 if (!IsSureToCallSingleRecognizedTarget()) return CompileType::Dynamic();
1015 const Function& target = *targets_.TargetAt(0)->target; 949 const Function& target = *targets_.TargetAt(0)->target;
1016 return (target.recognized_kind() != MethodRecognizer::kUnknown) 950 return (target.recognized_kind() != MethodRecognizer::kUnknown)
1017 ? CompileType::FromCid(MethodRecognizer::ResultCid(target)) 951 ? CompileType::FromCid(MethodRecognizer::ResultCid(target))
1018 : CompileType::Dynamic(); 952 : CompileType::Dynamic();
1019 } 953 }
1020 954
1021
1022 CompileType StaticCallInstr::ComputeType() const { 955 CompileType StaticCallInstr::ComputeType() const {
1023 if (result_cid_ != kDynamicCid) { 956 if (result_cid_ != kDynamicCid) {
1024 return CompileType::FromCid(result_cid_); 957 return CompileType::FromCid(result_cid_);
1025 } 958 }
1026 959
1027 if (Isolate::Current()->type_checks()) { 960 if (Isolate::Current()->type_checks()) {
1028 const AbstractType& result_type = 961 const AbstractType& result_type =
1029 AbstractType::ZoneHandle(function().result_type()); 962 AbstractType::ZoneHandle(function().result_type());
1030 return CompileType::FromAbstractType(result_type); 963 return CompileType::FromAbstractType(result_type);
1031 } 964 }
1032 965
1033 return (function_.recognized_kind() != MethodRecognizer::kUnknown) 966 return (function_.recognized_kind() != MethodRecognizer::kUnknown)
1034 ? CompileType::FromCid(MethodRecognizer::ResultCid(function_)) 967 ? CompileType::FromCid(MethodRecognizer::ResultCid(function_))
1035 : CompileType::Dynamic(); 968 : CompileType::Dynamic();
1036 } 969 }
1037 970
1038
1039 CompileType LoadLocalInstr::ComputeType() const { 971 CompileType LoadLocalInstr::ComputeType() const {
1040 if (Isolate::Current()->type_checks()) { 972 if (Isolate::Current()->type_checks()) {
1041 return CompileType::FromAbstractType(local().type()); 973 return CompileType::FromAbstractType(local().type());
1042 } 974 }
1043 return CompileType::Dynamic(); 975 return CompileType::Dynamic();
1044 } 976 }
1045 977
1046
1047 CompileType DropTempsInstr::ComputeType() const { 978 CompileType DropTempsInstr::ComputeType() const {
1048 return *value()->Type(); 979 return *value()->Type();
1049 } 980 }
1050 981
1051
1052 CompileType StoreLocalInstr::ComputeType() const { 982 CompileType StoreLocalInstr::ComputeType() const {
1053 // Returns stored value. 983 // Returns stored value.
1054 return *value()->Type(); 984 return *value()->Type();
1055 } 985 }
1056 986
1057
1058 CompileType OneByteStringFromCharCodeInstr::ComputeType() const { 987 CompileType OneByteStringFromCharCodeInstr::ComputeType() const {
1059 return CompileType::FromCid(kOneByteStringCid); 988 return CompileType::FromCid(kOneByteStringCid);
1060 } 989 }
1061 990
1062
1063 CompileType StringToCharCodeInstr::ComputeType() const { 991 CompileType StringToCharCodeInstr::ComputeType() const {
1064 return CompileType::FromCid(kSmiCid); 992 return CompileType::FromCid(kSmiCid);
1065 } 993 }
1066 994
1067
1068 CompileType StringInterpolateInstr::ComputeType() const { 995 CompileType StringInterpolateInstr::ComputeType() const {
1069 // TODO(srdjan): Do better and determine if it is a one or two byte string. 996 // TODO(srdjan): Do better and determine if it is a one or two byte string.
1070 return CompileType::String(); 997 return CompileType::String();
1071 } 998 }
1072 999
1073
1074 CompileType LoadStaticFieldInstr::ComputeType() const { 1000 CompileType LoadStaticFieldInstr::ComputeType() const {
1075 bool is_nullable = CompileType::kNullable; 1001 bool is_nullable = CompileType::kNullable;
1076 intptr_t cid = kDynamicCid; 1002 intptr_t cid = kDynamicCid;
1077 AbstractType* abstract_type = NULL; 1003 AbstractType* abstract_type = NULL;
1078 const Field& field = this->StaticField(); 1004 const Field& field = this->StaticField();
1079 if (Isolate::Current()->type_checks()) { 1005 if (Isolate::Current()->type_checks()) {
1080 cid = kIllegalCid; 1006 cid = kIllegalCid;
1081 abstract_type = &AbstractType::ZoneHandle(field.type()); 1007 abstract_type = &AbstractType::ZoneHandle(field.type());
1082 } 1008 }
1083 ASSERT(field.is_static()); 1009 ASSERT(field.is_static());
1084 if (field.is_final()) { 1010 if (field.is_final()) {
1085 if (!FLAG_fields_may_be_reset) { 1011 if (!FLAG_fields_may_be_reset) {
1086 const Instance& obj = Instance::Handle(field.StaticValue()); 1012 const Instance& obj = Instance::Handle(field.StaticValue());
1087 if ((obj.raw() != Object::sentinel().raw()) && 1013 if ((obj.raw() != Object::sentinel().raw()) &&
1088 (obj.raw() != Object::transition_sentinel().raw()) && !obj.IsNull()) { 1014 (obj.raw() != Object::transition_sentinel().raw()) && !obj.IsNull()) {
1089 is_nullable = CompileType::kNonNullable; 1015 is_nullable = CompileType::kNonNullable;
1090 cid = obj.GetClassId(); 1016 cid = obj.GetClassId();
1091 } 1017 }
1092 } else if (field.guarded_cid() != kIllegalCid) { 1018 } else if (field.guarded_cid() != kIllegalCid) {
1093 cid = field.guarded_cid(); 1019 cid = field.guarded_cid();
1094 if (!IsNullableCid(cid)) is_nullable = CompileType::kNonNullable; 1020 if (!IsNullableCid(cid)) is_nullable = CompileType::kNonNullable;
1095 } 1021 }
1096 } 1022 }
1097 if (Field::IsExternalizableCid(cid)) { 1023 if (Field::IsExternalizableCid(cid)) {
1098 cid = kDynamicCid; 1024 cid = kDynamicCid;
1099 } 1025 }
1100 return CompileType(is_nullable, cid, abstract_type); 1026 return CompileType(is_nullable, cid, abstract_type);
1101 } 1027 }
1102 1028
1103
1104 CompileType CreateArrayInstr::ComputeType() const { 1029 CompileType CreateArrayInstr::ComputeType() const {
1105 // TODO(fschneider): Add abstract type and type arguments to the compile type. 1030 // TODO(fschneider): Add abstract type and type arguments to the compile type.
1106 return CompileType::FromCid(kArrayCid); 1031 return CompileType::FromCid(kArrayCid);
1107 } 1032 }
1108 1033
1109
1110 CompileType AllocateObjectInstr::ComputeType() const { 1034 CompileType AllocateObjectInstr::ComputeType() const {
1111 if (!closure_function().IsNull()) { 1035 if (!closure_function().IsNull()) {
1112 ASSERT(cls().id() == kClosureCid); 1036 ASSERT(cls().id() == kClosureCid);
1113 return CompileType(CompileType::kNonNullable, kClosureCid, 1037 return CompileType(CompileType::kNonNullable, kClosureCid,
1114 &Type::ZoneHandle(closure_function().SignatureType())); 1038 &Type::ZoneHandle(closure_function().SignatureType()));
1115 } 1039 }
1116 // TODO(vegorov): Incorporate type arguments into the returned type. 1040 // TODO(vegorov): Incorporate type arguments into the returned type.
1117 return CompileType::FromCid(cls().id()); 1041 return CompileType::FromCid(cls().id());
1118 } 1042 }
1119 1043
1120
1121 CompileType LoadUntaggedInstr::ComputeType() const { 1044 CompileType LoadUntaggedInstr::ComputeType() const {
1122 return CompileType::Dynamic(); 1045 return CompileType::Dynamic();
1123 } 1046 }
1124 1047
1125
1126 CompileType LoadClassIdInstr::ComputeType() const { 1048 CompileType LoadClassIdInstr::ComputeType() const {
1127 return CompileType::FromCid(kSmiCid); 1049 return CompileType::FromCid(kSmiCid);
1128 } 1050 }
1129 1051
1130
1131 CompileType LoadFieldInstr::ComputeType() const { 1052 CompileType LoadFieldInstr::ComputeType() const {
1132 // Type may be null if the field is a VM field, e.g. context parent. 1053 // Type may be null if the field is a VM field, e.g. context parent.
1133 // Keep it as null for debug purposes and do not return dynamic in production 1054 // Keep it as null for debug purposes and do not return dynamic in production
1134 // mode, since misuse of the type would remain undetected. 1055 // mode, since misuse of the type would remain undetected.
1135 if (type().IsNull()) { 1056 if (type().IsNull()) {
1136 return CompileType::Dynamic(); 1057 return CompileType::Dynamic();
1137 } 1058 }
1138 1059
1139 const AbstractType* abstract_type = NULL; 1060 const AbstractType* abstract_type = NULL;
1140 if (Isolate::Current()->type_checks() && 1061 if (Isolate::Current()->type_checks() &&
(...skipping 12 matching lines...) Expand all
1153 // changed on the fly. 1074 // changed on the fly.
1154 field_cid = kDynamicCid; 1075 field_cid = kDynamicCid;
1155 } 1076 }
1156 return CompileType(is_nullable, field_cid, abstract_type); 1077 return CompileType(is_nullable, field_cid, abstract_type);
1157 } 1078 }
1158 1079
1159 ASSERT(!Field::IsExternalizableCid(result_cid_)); 1080 ASSERT(!Field::IsExternalizableCid(result_cid_));
1160 return CompileType::Create(result_cid_, *abstract_type); 1081 return CompileType::Create(result_cid_, *abstract_type);
1161 } 1082 }
1162 1083
1163
1164 CompileType LoadCodeUnitsInstr::ComputeType() const { 1084 CompileType LoadCodeUnitsInstr::ComputeType() const {
1165 switch (class_id()) { 1085 switch (class_id()) {
1166 case kOneByteStringCid: 1086 case kOneByteStringCid:
1167 case kExternalOneByteStringCid: 1087 case kExternalOneByteStringCid:
1168 case kTwoByteStringCid: 1088 case kTwoByteStringCid:
1169 case kExternalTwoByteStringCid: 1089 case kExternalTwoByteStringCid:
1170 return can_pack_into_smi() ? CompileType::FromCid(kSmiCid) 1090 return can_pack_into_smi() ? CompileType::FromCid(kSmiCid)
1171 : CompileType::Int(); 1091 : CompileType::Int();
1172 default: 1092 default:
1173 UNIMPLEMENTED(); 1093 UNIMPLEMENTED();
1174 return CompileType::Dynamic(); 1094 return CompileType::Dynamic();
1175 } 1095 }
1176 } 1096 }
1177 1097
1178
1179 CompileType BinaryInt32OpInstr::ComputeType() const { 1098 CompileType BinaryInt32OpInstr::ComputeType() const {
1180 // TODO(vegorov): range analysis information shall be used here. 1099 // TODO(vegorov): range analysis information shall be used here.
1181 return CompileType::Int(); 1100 return CompileType::Int();
1182 } 1101 }
1183 1102
1184
1185 CompileType BinarySmiOpInstr::ComputeType() const { 1103 CompileType BinarySmiOpInstr::ComputeType() const {
1186 return CompileType::FromCid(kSmiCid); 1104 return CompileType::FromCid(kSmiCid);
1187 } 1105 }
1188 1106
1189
1190 CompileType UnarySmiOpInstr::ComputeType() const { 1107 CompileType UnarySmiOpInstr::ComputeType() const {
1191 return CompileType::FromCid(kSmiCid); 1108 return CompileType::FromCid(kSmiCid);
1192 } 1109 }
1193 1110
1194
1195 CompileType UnaryDoubleOpInstr::ComputeType() const { 1111 CompileType UnaryDoubleOpInstr::ComputeType() const {
1196 return CompileType::FromCid(kDoubleCid); 1112 return CompileType::FromCid(kDoubleCid);
1197 } 1113 }
1198 1114
1199
1200 CompileType DoubleToSmiInstr::ComputeType() const { 1115 CompileType DoubleToSmiInstr::ComputeType() const {
1201 return CompileType::FromCid(kSmiCid); 1116 return CompileType::FromCid(kSmiCid);
1202 } 1117 }
1203 1118
1204
1205 CompileType ConstraintInstr::ComputeType() const { 1119 CompileType ConstraintInstr::ComputeType() const {
1206 return CompileType::FromCid(kSmiCid); 1120 return CompileType::FromCid(kSmiCid);
1207 } 1121 }
1208 1122
1209 // Note that MintOp may produce Smi-s as result of an 1123 // Note that MintOp may produce Smi-s as result of an
1210 // appended BoxInt64Instr node. 1124 // appended BoxInt64Instr node.
1211 CompileType BinaryMintOpInstr::ComputeType() const { 1125 CompileType BinaryMintOpInstr::ComputeType() const {
1212 return CompileType::Int(); 1126 return CompileType::Int();
1213 } 1127 }
1214 1128
1215
1216 CompileType ShiftMintOpInstr::ComputeType() const { 1129 CompileType ShiftMintOpInstr::ComputeType() const {
1217 return CompileType::Int(); 1130 return CompileType::Int();
1218 } 1131 }
1219 1132
1220
1221 CompileType UnaryMintOpInstr::ComputeType() const { 1133 CompileType UnaryMintOpInstr::ComputeType() const {
1222 return CompileType::Int(); 1134 return CompileType::Int();
1223 } 1135 }
1224 1136
1225
1226 CompileType BoxIntegerInstr::ComputeType() const { 1137 CompileType BoxIntegerInstr::ComputeType() const {
1227 return ValueFitsSmi() ? CompileType::FromCid(kSmiCid) : CompileType::Int(); 1138 return ValueFitsSmi() ? CompileType::FromCid(kSmiCid) : CompileType::Int();
1228 } 1139 }
1229 1140
1230
1231 bool BoxIntegerInstr::RecomputeType() { 1141 bool BoxIntegerInstr::RecomputeType() {
1232 return UpdateType(ComputeType()); 1142 return UpdateType(ComputeType());
1233 } 1143 }
1234 1144
1235
1236 CompileType UnboxIntegerInstr::ComputeType() const { 1145 CompileType UnboxIntegerInstr::ComputeType() const {
1237 return CompileType::Int(); 1146 return CompileType::Int();
1238 } 1147 }
1239 1148
1240
1241 CompileType DoubleToIntegerInstr::ComputeType() const { 1149 CompileType DoubleToIntegerInstr::ComputeType() const {
1242 return CompileType::Int(); 1150 return CompileType::Int();
1243 } 1151 }
1244 1152
1245
1246 CompileType BinaryDoubleOpInstr::ComputeType() const { 1153 CompileType BinaryDoubleOpInstr::ComputeType() const {
1247 return CompileType::FromCid(kDoubleCid); 1154 return CompileType::FromCid(kDoubleCid);
1248 } 1155 }
1249 1156
1250
1251 CompileType DoubleTestOpInstr::ComputeType() const { 1157 CompileType DoubleTestOpInstr::ComputeType() const {
1252 return CompileType::FromCid(kBoolCid); 1158 return CompileType::FromCid(kBoolCid);
1253 } 1159 }
1254 1160
1255
1256 CompileType BinaryFloat32x4OpInstr::ComputeType() const { 1161 CompileType BinaryFloat32x4OpInstr::ComputeType() const {
1257 return CompileType::FromCid(kFloat32x4Cid); 1162 return CompileType::FromCid(kFloat32x4Cid);
1258 } 1163 }
1259 1164
1260
1261 CompileType Simd32x4ShuffleInstr::ComputeType() const { 1165 CompileType Simd32x4ShuffleInstr::ComputeType() const {
1262 if ((op_kind() == MethodRecognizer::kFloat32x4ShuffleX) || 1166 if ((op_kind() == MethodRecognizer::kFloat32x4ShuffleX) ||
1263 (op_kind() == MethodRecognizer::kFloat32x4ShuffleY) || 1167 (op_kind() == MethodRecognizer::kFloat32x4ShuffleY) ||
1264 (op_kind() == MethodRecognizer::kFloat32x4ShuffleZ) || 1168 (op_kind() == MethodRecognizer::kFloat32x4ShuffleZ) ||
1265 (op_kind() == MethodRecognizer::kFloat32x4ShuffleW)) { 1169 (op_kind() == MethodRecognizer::kFloat32x4ShuffleW)) {
1266 return CompileType::FromCid(kDoubleCid); 1170 return CompileType::FromCid(kDoubleCid);
1267 } 1171 }
1268 if ((op_kind() == MethodRecognizer::kInt32x4Shuffle)) { 1172 if ((op_kind() == MethodRecognizer::kInt32x4Shuffle)) {
1269 return CompileType::FromCid(kInt32x4Cid); 1173 return CompileType::FromCid(kInt32x4Cid);
1270 } 1174 }
1271 ASSERT((op_kind() == MethodRecognizer::kFloat32x4Shuffle)); 1175 ASSERT((op_kind() == MethodRecognizer::kFloat32x4Shuffle));
1272 return CompileType::FromCid(kFloat32x4Cid); 1176 return CompileType::FromCid(kFloat32x4Cid);
1273 } 1177 }
1274 1178
1275
1276 CompileType Simd32x4ShuffleMixInstr::ComputeType() const { 1179 CompileType Simd32x4ShuffleMixInstr::ComputeType() const {
1277 if (op_kind() == MethodRecognizer::kInt32x4ShuffleMix) { 1180 if (op_kind() == MethodRecognizer::kInt32x4ShuffleMix) {
1278 return CompileType::FromCid(kInt32x4Cid); 1181 return CompileType::FromCid(kInt32x4Cid);
1279 } 1182 }
1280 ASSERT((op_kind() == MethodRecognizer::kFloat32x4ShuffleMix)); 1183 ASSERT((op_kind() == MethodRecognizer::kFloat32x4ShuffleMix));
1281 return CompileType::FromCid(kFloat32x4Cid); 1184 return CompileType::FromCid(kFloat32x4Cid);
1282 } 1185 }
1283 1186
1284
1285 CompileType Simd32x4GetSignMaskInstr::ComputeType() const { 1187 CompileType Simd32x4GetSignMaskInstr::ComputeType() const {
1286 return CompileType::Int(); 1188 return CompileType::Int();
1287 } 1189 }
1288 1190
1289
1290 CompileType Float32x4ConstructorInstr::ComputeType() const { 1191 CompileType Float32x4ConstructorInstr::ComputeType() const {
1291 return CompileType::FromCid(kFloat32x4Cid); 1192 return CompileType::FromCid(kFloat32x4Cid);
1292 } 1193 }
1293 1194
1294
1295 CompileType Float32x4ZeroInstr::ComputeType() const { 1195 CompileType Float32x4ZeroInstr::ComputeType() const {
1296 return CompileType::FromCid(kFloat32x4Cid); 1196 return CompileType::FromCid(kFloat32x4Cid);
1297 } 1197 }
1298 1198
1299
1300 CompileType Float32x4SplatInstr::ComputeType() const { 1199 CompileType Float32x4SplatInstr::ComputeType() const {
1301 return CompileType::FromCid(kFloat32x4Cid); 1200 return CompileType::FromCid(kFloat32x4Cid);
1302 } 1201 }
1303 1202
1304
1305 CompileType Float32x4ComparisonInstr::ComputeType() const { 1203 CompileType Float32x4ComparisonInstr::ComputeType() const {
1306 return CompileType::FromCid(kInt32x4Cid); 1204 return CompileType::FromCid(kInt32x4Cid);
1307 } 1205 }
1308 1206
1309
1310 CompileType Float32x4MinMaxInstr::ComputeType() const { 1207 CompileType Float32x4MinMaxInstr::ComputeType() const {
1311 return CompileType::FromCid(kFloat32x4Cid); 1208 return CompileType::FromCid(kFloat32x4Cid);
1312 } 1209 }
1313 1210
1314
1315 CompileType Float32x4ScaleInstr::ComputeType() const { 1211 CompileType Float32x4ScaleInstr::ComputeType() const {
1316 return CompileType::FromCid(kFloat32x4Cid); 1212 return CompileType::FromCid(kFloat32x4Cid);
1317 } 1213 }
1318 1214
1319
1320 CompileType Float32x4SqrtInstr::ComputeType() const { 1215 CompileType Float32x4SqrtInstr::ComputeType() const {
1321 return CompileType::FromCid(kFloat32x4Cid); 1216 return CompileType::FromCid(kFloat32x4Cid);
1322 } 1217 }
1323 1218
1324
1325 CompileType Float32x4ZeroArgInstr::ComputeType() const { 1219 CompileType Float32x4ZeroArgInstr::ComputeType() const {
1326 return CompileType::FromCid(kFloat32x4Cid); 1220 return CompileType::FromCid(kFloat32x4Cid);
1327 } 1221 }
1328 1222
1329
1330 CompileType Float32x4ClampInstr::ComputeType() const { 1223 CompileType Float32x4ClampInstr::ComputeType() const {
1331 return CompileType::FromCid(kFloat32x4Cid); 1224 return CompileType::FromCid(kFloat32x4Cid);
1332 } 1225 }
1333 1226
1334
1335 CompileType Float32x4WithInstr::ComputeType() const { 1227 CompileType Float32x4WithInstr::ComputeType() const {
1336 return CompileType::FromCid(kFloat32x4Cid); 1228 return CompileType::FromCid(kFloat32x4Cid);
1337 } 1229 }
1338 1230
1339
1340 CompileType Float32x4ToInt32x4Instr::ComputeType() const { 1231 CompileType Float32x4ToInt32x4Instr::ComputeType() const {
1341 return CompileType::FromCid(kInt32x4Cid); 1232 return CompileType::FromCid(kInt32x4Cid);
1342 } 1233 }
1343 1234
1344
1345 CompileType Simd64x2ShuffleInstr::ComputeType() const { 1235 CompileType Simd64x2ShuffleInstr::ComputeType() const {
1346 if ((op_kind() == MethodRecognizer::kFloat64x2GetX) || 1236 if ((op_kind() == MethodRecognizer::kFloat64x2GetX) ||
1347 (op_kind() == MethodRecognizer::kFloat64x2GetY)) { 1237 (op_kind() == MethodRecognizer::kFloat64x2GetY)) {
1348 return CompileType::FromCid(kDoubleCid); 1238 return CompileType::FromCid(kDoubleCid);
1349 } 1239 }
1350 UNREACHABLE(); 1240 UNREACHABLE();
1351 return CompileType::FromCid(kDoubleCid); 1241 return CompileType::FromCid(kDoubleCid);
1352 } 1242 }
1353 1243
1354
1355 CompileType Float64x2ZeroInstr::ComputeType() const { 1244 CompileType Float64x2ZeroInstr::ComputeType() const {
1356 return CompileType::FromCid(kFloat64x2Cid); 1245 return CompileType::FromCid(kFloat64x2Cid);
1357 } 1246 }
1358 1247
1359
1360 CompileType Float64x2SplatInstr::ComputeType() const { 1248 CompileType Float64x2SplatInstr::ComputeType() const {
1361 return CompileType::FromCid(kFloat64x2Cid); 1249 return CompileType::FromCid(kFloat64x2Cid);
1362 } 1250 }
1363 1251
1364
1365 CompileType Float64x2ConstructorInstr::ComputeType() const { 1252 CompileType Float64x2ConstructorInstr::ComputeType() const {
1366 return CompileType::FromCid(kFloat64x2Cid); 1253 return CompileType::FromCid(kFloat64x2Cid);
1367 } 1254 }
1368 1255
1369
1370 CompileType Float32x4ToFloat64x2Instr::ComputeType() const { 1256 CompileType Float32x4ToFloat64x2Instr::ComputeType() const {
1371 return CompileType::FromCid(kFloat64x2Cid); 1257 return CompileType::FromCid(kFloat64x2Cid);
1372 } 1258 }
1373 1259
1374
1375 CompileType Float64x2ToFloat32x4Instr::ComputeType() const { 1260 CompileType Float64x2ToFloat32x4Instr::ComputeType() const {
1376 return CompileType::FromCid(kFloat32x4Cid); 1261 return CompileType::FromCid(kFloat32x4Cid);
1377 } 1262 }
1378 1263
1379
1380 CompileType Float64x2ZeroArgInstr::ComputeType() const { 1264 CompileType Float64x2ZeroArgInstr::ComputeType() const {
1381 if (op_kind() == MethodRecognizer::kFloat64x2GetSignMask) { 1265 if (op_kind() == MethodRecognizer::kFloat64x2GetSignMask) {
1382 return CompileType::Int(); 1266 return CompileType::Int();
1383 } 1267 }
1384 return CompileType::FromCid(kFloat64x2Cid); 1268 return CompileType::FromCid(kFloat64x2Cid);
1385 } 1269 }
1386 1270
1387
1388 CompileType Float64x2OneArgInstr::ComputeType() const { 1271 CompileType Float64x2OneArgInstr::ComputeType() const {
1389 return CompileType::FromCid(kFloat64x2Cid); 1272 return CompileType::FromCid(kFloat64x2Cid);
1390 } 1273 }
1391 1274
1392
1393 CompileType Int32x4ConstructorInstr::ComputeType() const { 1275 CompileType Int32x4ConstructorInstr::ComputeType() const {
1394 return CompileType::FromCid(kInt32x4Cid); 1276 return CompileType::FromCid(kInt32x4Cid);
1395 } 1277 }
1396 1278
1397
1398 CompileType Int32x4BoolConstructorInstr::ComputeType() const { 1279 CompileType Int32x4BoolConstructorInstr::ComputeType() const {
1399 return CompileType::FromCid(kInt32x4Cid); 1280 return CompileType::FromCid(kInt32x4Cid);
1400 } 1281 }
1401 1282
1402
1403 CompileType Int32x4GetFlagInstr::ComputeType() const { 1283 CompileType Int32x4GetFlagInstr::ComputeType() const {
1404 return CompileType::FromCid(kBoolCid); 1284 return CompileType::FromCid(kBoolCid);
1405 } 1285 }
1406 1286
1407
1408 CompileType Int32x4SelectInstr::ComputeType() const { 1287 CompileType Int32x4SelectInstr::ComputeType() const {
1409 return CompileType::FromCid(kFloat32x4Cid); 1288 return CompileType::FromCid(kFloat32x4Cid);
1410 } 1289 }
1411 1290
1412
1413 CompileType Int32x4SetFlagInstr::ComputeType() const { 1291 CompileType Int32x4SetFlagInstr::ComputeType() const {
1414 return CompileType::FromCid(kInt32x4Cid); 1292 return CompileType::FromCid(kInt32x4Cid);
1415 } 1293 }
1416 1294
1417
1418 CompileType Int32x4ToFloat32x4Instr::ComputeType() const { 1295 CompileType Int32x4ToFloat32x4Instr::ComputeType() const {
1419 return CompileType::FromCid(kFloat32x4Cid); 1296 return CompileType::FromCid(kFloat32x4Cid);
1420 } 1297 }
1421 1298
1422
1423 CompileType BinaryInt32x4OpInstr::ComputeType() const { 1299 CompileType BinaryInt32x4OpInstr::ComputeType() const {
1424 return CompileType::FromCid(kInt32x4Cid); 1300 return CompileType::FromCid(kInt32x4Cid);
1425 } 1301 }
1426 1302
1427
1428 CompileType BinaryFloat64x2OpInstr::ComputeType() const { 1303 CompileType BinaryFloat64x2OpInstr::ComputeType() const {
1429 return CompileType::FromCid(kFloat64x2Cid); 1304 return CompileType::FromCid(kFloat64x2Cid);
1430 } 1305 }
1431 1306
1432
1433 CompileType MathUnaryInstr::ComputeType() const { 1307 CompileType MathUnaryInstr::ComputeType() const {
1434 return CompileType::FromCid(kDoubleCid); 1308 return CompileType::FromCid(kDoubleCid);
1435 } 1309 }
1436 1310
1437
1438 CompileType MathMinMaxInstr::ComputeType() const { 1311 CompileType MathMinMaxInstr::ComputeType() const {
1439 return CompileType::FromCid(result_cid_); 1312 return CompileType::FromCid(result_cid_);
1440 } 1313 }
1441 1314
1442
1443 CompileType CaseInsensitiveCompareUC16Instr::ComputeType() const { 1315 CompileType CaseInsensitiveCompareUC16Instr::ComputeType() const {
1444 return CompileType::FromCid(kBoolCid); 1316 return CompileType::FromCid(kBoolCid);
1445 } 1317 }
1446 1318
1447
1448 CompileType UnboxInstr::ComputeType() const { 1319 CompileType UnboxInstr::ComputeType() const {
1449 switch (representation()) { 1320 switch (representation()) {
1450 case kUnboxedDouble: 1321 case kUnboxedDouble:
1451 return CompileType::FromCid(kDoubleCid); 1322 return CompileType::FromCid(kDoubleCid);
1452 1323
1453 case kUnboxedFloat32x4: 1324 case kUnboxedFloat32x4:
1454 return CompileType::FromCid(kFloat32x4Cid); 1325 return CompileType::FromCid(kFloat32x4Cid);
1455 1326
1456 case kUnboxedFloat64x2: 1327 case kUnboxedFloat64x2:
1457 return CompileType::FromCid(kFloat64x2Cid); 1328 return CompileType::FromCid(kFloat64x2Cid);
1458 1329
1459 case kUnboxedInt32x4: 1330 case kUnboxedInt32x4:
1460 return CompileType::FromCid(kInt32x4Cid); 1331 return CompileType::FromCid(kInt32x4Cid);
1461 1332
1462 case kUnboxedMint: 1333 case kUnboxedMint:
1463 return CompileType::Int(); 1334 return CompileType::Int();
1464 1335
1465 default: 1336 default:
1466 UNREACHABLE(); 1337 UNREACHABLE();
1467 return CompileType::Dynamic(); 1338 return CompileType::Dynamic();
1468 } 1339 }
1469 } 1340 }
1470 1341
1471
1472 CompileType BoxInstr::ComputeType() const { 1342 CompileType BoxInstr::ComputeType() const {
1473 switch (from_representation()) { 1343 switch (from_representation()) {
1474 case kUnboxedDouble: 1344 case kUnboxedDouble:
1475 return CompileType::FromCid(kDoubleCid); 1345 return CompileType::FromCid(kDoubleCid);
1476 1346
1477 case kUnboxedFloat32x4: 1347 case kUnboxedFloat32x4:
1478 return CompileType::FromCid(kFloat32x4Cid); 1348 return CompileType::FromCid(kFloat32x4Cid);
1479 1349
1480 case kUnboxedFloat64x2: 1350 case kUnboxedFloat64x2:
1481 return CompileType::FromCid(kFloat64x2Cid); 1351 return CompileType::FromCid(kFloat64x2Cid);
1482 1352
1483 case kUnboxedInt32x4: 1353 case kUnboxedInt32x4:
1484 return CompileType::FromCid(kInt32x4Cid); 1354 return CompileType::FromCid(kInt32x4Cid);
1485 1355
1486 default: 1356 default:
1487 UNREACHABLE(); 1357 UNREACHABLE();
1488 return CompileType::Dynamic(); 1358 return CompileType::Dynamic();
1489 } 1359 }
1490 } 1360 }
1491 1361
1492
1493 CompileType Int32ToDoubleInstr::ComputeType() const { 1362 CompileType Int32ToDoubleInstr::ComputeType() const {
1494 return CompileType::FromCid(kDoubleCid); 1363 return CompileType::FromCid(kDoubleCid);
1495 } 1364 }
1496 1365
1497
1498 CompileType SmiToDoubleInstr::ComputeType() const { 1366 CompileType SmiToDoubleInstr::ComputeType() const {
1499 return CompileType::FromCid(kDoubleCid); 1367 return CompileType::FromCid(kDoubleCid);
1500 } 1368 }
1501 1369
1502
1503 CompileType MintToDoubleInstr::ComputeType() const { 1370 CompileType MintToDoubleInstr::ComputeType() const {
1504 return CompileType::FromCid(kDoubleCid); 1371 return CompileType::FromCid(kDoubleCid);
1505 } 1372 }
1506 1373
1507
1508 CompileType DoubleToDoubleInstr::ComputeType() const { 1374 CompileType DoubleToDoubleInstr::ComputeType() const {
1509 return CompileType::FromCid(kDoubleCid); 1375 return CompileType::FromCid(kDoubleCid);
1510 } 1376 }
1511 1377
1512
1513 CompileType FloatToDoubleInstr::ComputeType() const { 1378 CompileType FloatToDoubleInstr::ComputeType() const {
1514 return CompileType::FromCid(kDoubleCid); 1379 return CompileType::FromCid(kDoubleCid);
1515 } 1380 }
1516 1381
1517
1518 CompileType DoubleToFloatInstr::ComputeType() const { 1382 CompileType DoubleToFloatInstr::ComputeType() const {
1519 // Type is double when converted back. 1383 // Type is double when converted back.
1520 return CompileType::FromCid(kDoubleCid); 1384 return CompileType::FromCid(kDoubleCid);
1521 } 1385 }
1522 1386
1523
1524 CompileType InvokeMathCFunctionInstr::ComputeType() const { 1387 CompileType InvokeMathCFunctionInstr::ComputeType() const {
1525 return CompileType::FromCid(kDoubleCid); 1388 return CompileType::FromCid(kDoubleCid);
1526 } 1389 }
1527 1390
1528
1529 CompileType TruncDivModInstr::ComputeType() const { 1391 CompileType TruncDivModInstr::ComputeType() const {
1530 return CompileType::Dynamic(); 1392 return CompileType::Dynamic();
1531 } 1393 }
1532 1394
1533
1534 CompileType ExtractNthOutputInstr::ComputeType() const { 1395 CompileType ExtractNthOutputInstr::ComputeType() const {
1535 return CompileType::FromCid(definition_cid_); 1396 return CompileType::FromCid(definition_cid_);
1536 } 1397 }
1537 1398
1538 } // namespace dart 1399 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_range_analysis_test.cc ('k') | runtime/vm/freelist.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698