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

Unified 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: 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/method_recognizer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intrinsifier.cc
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index 5e24dd35739cf3ef92ae6be446fe713656cb9c05..48498e10012f614d5f7712193614787b78fd9b43 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -501,6 +501,128 @@ bool Intrinsifier::Build_Float64ArrayGetIndexed(FlowGraph* flow_graph) {
}
+static bool BuildBinaryFloat32x4Op(FlowGraph* flow_graph, Token::Kind kind) {
+ if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false;
+
+ GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+ TargetEntryInstr* normal_entry = graph_entry->normal_entry();
+ BlockBuilder builder(flow_graph, normal_entry);
+
+ Definition* right = builder.AddParameter(1);
+ Definition* left = builder.AddParameter(2);
+
+ const ICData& value_check = ICData::ZoneHandle(ICData::New(
+ flow_graph->function(),
+ String::Handle(flow_graph->function().name()),
+ Object::empty_array(), // Dummy args. descr.
+ Isolate::kNoDeoptId,
+ 1));
+ value_check.AddReceiverCheck(kFloat32x4Cid, flow_graph->function());
+ // Check argument. Receiver (left) is known to be a Float32x4.
+ builder.AddInstruction(
+ new CheckClassInstr(new Value(right),
+ Isolate::kNoDeoptId,
+ value_check,
+ builder.TokenPos()));
+ Definition* left_simd = builder.AddDefinition(
+ UnboxInstr::Create(kUnboxedFloat32x4,
+ new Value(left),
Cutch 2015/09/22 15:48:05 What about creating a helper: Definition* Unbox(R
Florian Schneider 2015/09/22 16:13:38 Done.
+ Isolate::kNoDeoptId));
+ // Manually adjust reaching type because there is no type propagation
+ // when building intrinsics.
+ left_simd->AsUnbox()->value()->SetReachingType(
+ ZoneCompileType::Wrap(CompileType::FromCid(kFloat32x4Cid)));
+
+ Definition* right_simd = builder.AddDefinition(
+ UnboxInstr::Create(kUnboxedFloat32x4,
+ new Value(right),
+ Isolate::kNoDeoptId));
+ // Manually adjust reaching type because there is no type propagation
+ // when building intrinsics.
+ right_simd->AsUnbox()->value()->SetReachingType(
+ ZoneCompileType::Wrap(CompileType::FromCid(kFloat32x4Cid)));
+ Definition* unboxed_result = builder.AddDefinition(
+ new BinaryFloat32x4OpInstr(kind,
+ new Value(left_simd),
+ new Value(right_simd),
+ Isolate::kNoDeoptId));
+ Definition* result = builder.AddDefinition(
+ BoxInstr::Create(kUnboxedFloat32x4, new Value(unboxed_result)));
+ builder.AddIntrinsicReturn(new Value(result));
+ return true;
+}
+
+
+bool Intrinsifier::Build_Float32x4Mul(FlowGraph* flow_graph) {
+ return BuildBinaryFloat32x4Op(flow_graph, Token::kMUL);
+}
+
+
+bool Intrinsifier::Build_Float32x4Sub(FlowGraph* flow_graph) {
+ return BuildBinaryFloat32x4Op(flow_graph, Token::kSUB);
+}
+
+
+bool Intrinsifier::Build_Float32x4Add(FlowGraph* flow_graph) {
+ return BuildBinaryFloat32x4Op(flow_graph, Token::kADD);
+}
+
+
+static bool BuildFloat32x4Shuffle(FlowGraph* flow_graph,
+ MethodRecognizer::Kind kind) {
+ if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false;
+ GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+ TargetEntryInstr* normal_entry = graph_entry->normal_entry();
+ BlockBuilder builder(flow_graph, normal_entry);
+
+ Definition* receiver = builder.AddParameter(1);
+
+ Definition* unboxed_receiver = builder.AddDefinition(
+ UnboxInstr::Create(kUnboxedFloat32x4,
+ new Value(receiver),
+ Isolate::kNoDeoptId));
+ // Manually adjust reaching type because there is no type propagation
+ // when building intrinsics.
+ unboxed_receiver->AsUnbox()->value()->SetReachingType(
+ ZoneCompileType::Wrap(CompileType::FromCid(kFloat32x4Cid)));
Cutch 2015/09/22 15:48:05 Use helper here too
Florian Schneider 2015/09/22 16:13:38 Done.
+
+ Definition* unboxed_result = builder.AddDefinition(
+ new Simd32x4ShuffleInstr(kind,
+ new Value(unboxed_receiver),
+ 0,
+ Isolate::kNoDeoptId));
+
+ Definition* result = builder.AddDefinition(
+ BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
+ builder.AddIntrinsicReturn(new Value(result));
+ return true;
+}
+
+
+bool Intrinsifier::Build_Float32x4ShuffleX(FlowGraph* flow_graph) {
+ return BuildFloat32x4Shuffle(flow_graph,
+ MethodRecognizer::kFloat32x4ShuffleX);
+}
+
+
+bool Intrinsifier::Build_Float32x4ShuffleY(FlowGraph* flow_graph) {
+ return BuildFloat32x4Shuffle(flow_graph,
+ MethodRecognizer::kFloat32x4ShuffleY);
+}
+
+
+bool Intrinsifier::Build_Float32x4ShuffleZ(FlowGraph* flow_graph) {
+ return BuildFloat32x4Shuffle(flow_graph,
+ MethodRecognizer::kFloat32x4ShuffleZ);
+}
+
+
+bool Intrinsifier::Build_Float32x4ShuffleW(FlowGraph* flow_graph) {
+ return BuildFloat32x4Shuffle(flow_graph,
+ MethodRecognizer::kFloat32x4ShuffleW);
+}
+
+
static bool BuildLoadField(FlowGraph* flow_graph, intptr_t offset) {
GraphEntryInstr* graph_entry = flow_graph->graph_entry();
TargetEntryInstr* normal_entry = graph_entry->normal_entry();
« 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