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

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: 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 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..76e9b63e3837d2e84946d741a7591e7ede01bdb0 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -211,6 +211,19 @@ void Intrinsifier::Intrinsify(const ParsedFunction& parsed_function,
}
+static intptr_t CidForRepresentation(Representation rep) {
+ switch (rep) {
+ case kUnboxedDouble:
+ return kDoubleCid;
+ case kUnboxedFloat32x4:
+ return kFloat32x4Cid;
+ default:
+ UNREACHABLE();
+ return kIllegalCid;
+ }
+}
+
+
class BlockBuilder : public ValueObject {
public:
BlockBuilder(FlowGraph* flow_graph, TargetEntryInstr* entry)
@@ -256,6 +269,16 @@ class BlockBuilder : public ValueObject {
new ConstantInstr(Object::ZoneHandle(Object::null())));
}
+ Definition* AddUnboxInstr(Representation rep, Value* value) {
+ Definition* unboxed_value = AddDefinition(
+ UnboxInstr::Create(rep, value, Isolate::kNoDeoptId));
+ // Manually adjust reaching type because there is no type propagation
+ // when building intrinsics.
+ unboxed_value->AsUnbox()->value()->SetReachingType(ZoneCompileType::Wrap(
+ CompileType::FromCid(CidForRepresentation(rep))));
+ return unboxed_value;
+ }
+
private:
FlowGraph* flow_graph_;
BlockEntryInstr* entry_;
@@ -450,14 +473,8 @@ bool Intrinsifier::Build_Float64ArraySetIndexed(FlowGraph* flow_graph) {
Isolate::kNoDeoptId,
value_check,
builder.TokenPos()));
- Definition* double_value = builder.AddDefinition(
- UnboxInstr::Create(kUnboxedDouble,
- new Value(value),
- Isolate::kNoDeoptId));
- // Manually adjust reaching type because there is no type propagation
- // when building intrinsics.
- double_value->AsUnbox()->value()->SetReachingType(
- ZoneCompileType::Wrap(CompileType::FromCid(kDoubleCid)));
+ Definition* double_value =
+ builder.AddUnboxInstr(kUnboxedDouble, new Value(value));
builder.AddInstruction(
new StoreIndexedInstr(new Value(array),
@@ -501,6 +518,111 @@ 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.AddUnboxInstr(kUnboxedFloat32x4, new Value(left));
+
+ Definition* right_simd =
+ builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(right));
+
+ 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.AddUnboxInstr(kUnboxedFloat32x4, new Value(receiver));
+
+ 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