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

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

Issue 1347203005: VM: Intrinsify some common SIMD methods to speed up precompiled SIMD code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: added helper to create unboxing instructions Created 5 years, 3 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 | « no previous file | runtime/vm/method_recognizer.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 // Class for intrinsifying functions. 4 // Class for intrinsifying functions.
5 5
6 #include "vm/assembler.h" 6 #include "vm/assembler.h"
7 #include "vm/intrinsifier.h" 7 #include "vm/intrinsifier.h"
8 #include "vm/flags.h" 8 #include "vm/flags.h"
9 #include "vm/object.h" 9 #include "vm/object.h"
10 #include "vm/symbols.h" 10 #include "vm/symbols.h"
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 switch (function.recognized_kind()) { 204 switch (function.recognized_kind()) {
205 CORE_INTEGER_LIB_INTRINSIC_LIST(EMIT_CASE) 205 CORE_INTEGER_LIB_INTRINSIC_LIST(EMIT_CASE)
206 default: 206 default:
207 break; 207 break;
208 } 208 }
209 } 209 }
210 #undef EMIT_INTRINSIC 210 #undef EMIT_INTRINSIC
211 } 211 }
212 212
213 213
214 static intptr_t CidForRepresentation(Representation rep) {
215 switch (rep) {
216 case kUnboxedDouble:
217 return kDoubleCid;
218 case kUnboxedFloat32x4:
219 return kFloat32x4Cid;
220 default:
221 UNREACHABLE();
222 return kIllegalCid;
223 }
224 }
225
226
214 class BlockBuilder : public ValueObject { 227 class BlockBuilder : public ValueObject {
215 public: 228 public:
216 BlockBuilder(FlowGraph* flow_graph, TargetEntryInstr* entry) 229 BlockBuilder(FlowGraph* flow_graph, TargetEntryInstr* entry)
217 : flow_graph_(flow_graph), entry_(entry), current_(entry) { } 230 : flow_graph_(flow_graph), entry_(entry), current_(entry) { }
218 231
219 Definition* AddToInitialDefinitions(Definition* def) { 232 Definition* AddToInitialDefinitions(Definition* def) {
220 def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); 233 def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
221 flow_graph_->AddToInitialDefinitions(def); 234 flow_graph_->AddToInitialDefinitions(def);
222 return def; 235 return def;
223 } 236 }
(...skipping 25 matching lines...) Expand all
249 262
250 intptr_t TokenPos() { 263 intptr_t TokenPos() {
251 return flow_graph_->function().token_pos(); 264 return flow_graph_->function().token_pos();
252 } 265 }
253 266
254 Definition* AddNullDefinition() { 267 Definition* AddNullDefinition() {
255 return AddDefinition( 268 return AddDefinition(
256 new ConstantInstr(Object::ZoneHandle(Object::null()))); 269 new ConstantInstr(Object::ZoneHandle(Object::null())));
257 } 270 }
258 271
272 Definition* AddUnboxInstr(Representation rep, Value* value) {
273 Definition* unboxed_value = AddDefinition(
274 UnboxInstr::Create(rep, value, Isolate::kNoDeoptId));
275 // Manually adjust reaching type because there is no type propagation
276 // when building intrinsics.
277 unboxed_value->AsUnbox()->value()->SetReachingType(ZoneCompileType::Wrap(
278 CompileType::FromCid(CidForRepresentation(rep))));
279 return unboxed_value;
280 }
281
259 private: 282 private:
260 FlowGraph* flow_graph_; 283 FlowGraph* flow_graph_;
261 BlockEntryInstr* entry_; 284 BlockEntryInstr* entry_;
262 Instruction* current_; 285 Instruction* current_;
263 }; 286 };
264 287
265 288
266 static void PrepareIndexedOp(BlockBuilder* builder, 289 static void PrepareIndexedOp(BlockBuilder* builder,
267 Definition* array, 290 Definition* array,
268 Definition* index, 291 Definition* index,
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 String::Handle(flow_graph->function().name()), 466 String::Handle(flow_graph->function().name()),
444 Object::empty_array(), // Dummy args. descr. 467 Object::empty_array(), // Dummy args. descr.
445 Isolate::kNoDeoptId, 468 Isolate::kNoDeoptId,
446 1)); 469 1));
447 value_check.AddReceiverCheck(kDoubleCid, flow_graph->function()); 470 value_check.AddReceiverCheck(kDoubleCid, flow_graph->function());
448 builder.AddInstruction( 471 builder.AddInstruction(
449 new CheckClassInstr(new Value(value), 472 new CheckClassInstr(new Value(value),
450 Isolate::kNoDeoptId, 473 Isolate::kNoDeoptId,
451 value_check, 474 value_check,
452 builder.TokenPos())); 475 builder.TokenPos()));
453 Definition* double_value = builder.AddDefinition( 476 Definition* double_value =
454 UnboxInstr::Create(kUnboxedDouble, 477 builder.AddUnboxInstr(kUnboxedDouble, new Value(value));
455 new Value(value),
456 Isolate::kNoDeoptId));
457 // Manually adjust reaching type because there is no type propagation
458 // when building intrinsics.
459 double_value->AsUnbox()->value()->SetReachingType(
460 ZoneCompileType::Wrap(CompileType::FromCid(kDoubleCid)));
461 478
462 builder.AddInstruction( 479 builder.AddInstruction(
463 new StoreIndexedInstr(new Value(array), 480 new StoreIndexedInstr(new Value(array),
464 new Value(index), 481 new Value(index),
465 new Value(double_value), 482 new Value(double_value),
466 kNoStoreBarrier, 483 kNoStoreBarrier,
467 8, // index scale 484 8, // index scale
468 kTypedDataFloat64ArrayCid, 485 kTypedDataFloat64ArrayCid,
469 Isolate::kNoDeoptId, 486 Isolate::kNoDeoptId,
470 builder.TokenPos())); 487 builder.TokenPos()));
(...skipping 23 matching lines...) Expand all
494 kTypedDataFloat64ArrayCid, 511 kTypedDataFloat64ArrayCid,
495 Isolate::kNoDeoptId, 512 Isolate::kNoDeoptId,
496 builder.TokenPos())); 513 builder.TokenPos()));
497 Definition* result = builder.AddDefinition( 514 Definition* result = builder.AddDefinition(
498 BoxInstr::Create(kUnboxedDouble, new Value(unboxed_value))); 515 BoxInstr::Create(kUnboxedDouble, new Value(unboxed_value)));
499 builder.AddIntrinsicReturn(new Value(result)); 516 builder.AddIntrinsicReturn(new Value(result));
500 return true; 517 return true;
501 } 518 }
502 519
503 520
521 static bool BuildBinaryFloat32x4Op(FlowGraph* flow_graph, Token::Kind kind) {
522 if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false;
523
524 GraphEntryInstr* graph_entry = flow_graph->graph_entry();
525 TargetEntryInstr* normal_entry = graph_entry->normal_entry();
526 BlockBuilder builder(flow_graph, normal_entry);
527
528 Definition* right = builder.AddParameter(1);
529 Definition* left = builder.AddParameter(2);
530
531 const ICData& value_check = ICData::ZoneHandle(ICData::New(
532 flow_graph->function(),
533 String::Handle(flow_graph->function().name()),
534 Object::empty_array(), // Dummy args. descr.
535 Isolate::kNoDeoptId,
536 1));
537 value_check.AddReceiverCheck(kFloat32x4Cid, flow_graph->function());
538 // Check argument. Receiver (left) is known to be a Float32x4.
539 builder.AddInstruction(
540 new CheckClassInstr(new Value(right),
541 Isolate::kNoDeoptId,
542 value_check,
543 builder.TokenPos()));
544 Definition* left_simd =
545 builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(left));
546
547 Definition* right_simd =
548 builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(right));
549
550 Definition* unboxed_result = builder.AddDefinition(
551 new BinaryFloat32x4OpInstr(kind,
552 new Value(left_simd),
553 new Value(right_simd),
554 Isolate::kNoDeoptId));
555 Definition* result = builder.AddDefinition(
556 BoxInstr::Create(kUnboxedFloat32x4, new Value(unboxed_result)));
557 builder.AddIntrinsicReturn(new Value(result));
558 return true;
559 }
560
561
562 bool Intrinsifier::Build_Float32x4Mul(FlowGraph* flow_graph) {
563 return BuildBinaryFloat32x4Op(flow_graph, Token::kMUL);
564 }
565
566
567 bool Intrinsifier::Build_Float32x4Sub(FlowGraph* flow_graph) {
568 return BuildBinaryFloat32x4Op(flow_graph, Token::kSUB);
569 }
570
571
572 bool Intrinsifier::Build_Float32x4Add(FlowGraph* flow_graph) {
573 return BuildBinaryFloat32x4Op(flow_graph, Token::kADD);
574 }
575
576
577 static bool BuildFloat32x4Shuffle(FlowGraph* flow_graph,
578 MethodRecognizer::Kind kind) {
579 if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false;
580 GraphEntryInstr* graph_entry = flow_graph->graph_entry();
581 TargetEntryInstr* normal_entry = graph_entry->normal_entry();
582 BlockBuilder builder(flow_graph, normal_entry);
583
584 Definition* receiver = builder.AddParameter(1);
585
586 Definition* unboxed_receiver =
587 builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(receiver));
588
589 Definition* unboxed_result = builder.AddDefinition(
590 new Simd32x4ShuffleInstr(kind,
591 new Value(unboxed_receiver),
592 0,
593 Isolate::kNoDeoptId));
594
595 Definition* result = builder.AddDefinition(
596 BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
597 builder.AddIntrinsicReturn(new Value(result));
598 return true;
599 }
600
601
602 bool Intrinsifier::Build_Float32x4ShuffleX(FlowGraph* flow_graph) {
603 return BuildFloat32x4Shuffle(flow_graph,
604 MethodRecognizer::kFloat32x4ShuffleX);
605 }
606
607
608 bool Intrinsifier::Build_Float32x4ShuffleY(FlowGraph* flow_graph) {
609 return BuildFloat32x4Shuffle(flow_graph,
610 MethodRecognizer::kFloat32x4ShuffleY);
611 }
612
613
614 bool Intrinsifier::Build_Float32x4ShuffleZ(FlowGraph* flow_graph) {
615 return BuildFloat32x4Shuffle(flow_graph,
616 MethodRecognizer::kFloat32x4ShuffleZ);
617 }
618
619
620 bool Intrinsifier::Build_Float32x4ShuffleW(FlowGraph* flow_graph) {
621 return BuildFloat32x4Shuffle(flow_graph,
622 MethodRecognizer::kFloat32x4ShuffleW);
623 }
624
625
504 static bool BuildLoadField(FlowGraph* flow_graph, intptr_t offset) { 626 static bool BuildLoadField(FlowGraph* flow_graph, intptr_t offset) {
505 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); 627 GraphEntryInstr* graph_entry = flow_graph->graph_entry();
506 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); 628 TargetEntryInstr* normal_entry = graph_entry->normal_entry();
507 BlockBuilder builder(flow_graph, normal_entry); 629 BlockBuilder builder(flow_graph, normal_entry);
508 630
509 Definition* array = builder.AddParameter(1); 631 Definition* array = builder.AddParameter(1);
510 632
511 Definition* length = builder.AddDefinition( 633 Definition* length = builder.AddDefinition(
512 new LoadFieldInstr(new Value(array), 634 new LoadFieldInstr(new Value(array),
513 offset, 635 offset,
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 new Value(growable_array), 804 new Value(growable_array),
683 new Value(length), 805 new Value(length),
684 kNoStoreBarrier, 806 kNoStoreBarrier,
685 builder.TokenPos())); 807 builder.TokenPos()));
686 Definition* null_def = builder.AddNullDefinition(); 808 Definition* null_def = builder.AddNullDefinition();
687 builder.AddIntrinsicReturn(new Value(null_def)); 809 builder.AddIntrinsicReturn(new Value(null_def));
688 return true; 810 return true;
689 } 811 }
690 812
691 } // namespace dart 813 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/method_recognizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698