mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:37:12 +00:00
VM: Intrinsify some common SIMD methods to speed up precompiled SIMD code.
This speeds up precompiled code using SIMD (around 2x on Tracer). Also fix printing of recognized methods which was off-by-one. BUG= R=johnmccutchan@google.com Review URL: https://codereview.chromium.org//1347203005 .
This commit is contained in:
parent
847847dd95
commit
60b4e00770
|
@ -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();
|
||||
|
|
|
@ -28,6 +28,7 @@ bool MethodRecognizer::PolymorphicTarget(const Function& function) {
|
|||
#define KIND_TO_STRING(class_name, function_name, enum_name, fp) \
|
||||
#enum_name,
|
||||
static const char* recognized_list_method_name[] = {
|
||||
"Unknown",
|
||||
RECOGNIZED_LIST(KIND_TO_STRING)
|
||||
};
|
||||
#undef KIND_TO_STRING
|
||||
|
|
|
@ -64,10 +64,6 @@ namespace dart {
|
|||
V(Float32x4, Float32x4.fromFloat64x2, Float32x4FromFloat64x2, 1327692716) \
|
||||
V(_Float32x4, shuffle, Float32x4Shuffle, 1636488139) \
|
||||
V(_Float32x4, shuffleMix, Float32x4ShuffleMix, 654814229) \
|
||||
V(_Float32x4, get:x, Float32x4ShuffleX, 384969722) \
|
||||
V(_Float32x4, get:y, Float32x4ShuffleY, 1398121942) \
|
||||
V(_Float32x4, get:z, Float32x4ShuffleZ, 1178175605) \
|
||||
V(_Float32x4, get:w, Float32x4ShuffleW, 480951003) \
|
||||
V(_Float32x4, get:signMask, Float32x4GetSignMask, 630880675) \
|
||||
V(_Float32x4, _cmpequal, Float32x4Equal, 571062952) \
|
||||
V(_Float32x4, _cmpgt, Float32x4GreaterThan, 1613543295) \
|
||||
|
@ -285,6 +281,13 @@ namespace dart {
|
|||
V(_Float64Array, []=, Float64ArraySetIndexed, 887301703) \
|
||||
V(_Float64Array, [], Float64ArrayGetIndexed, 1959896670) \
|
||||
V(_TypedList, get:length, TypedDataLength, 522684521) \
|
||||
V(_Float32x4, get:x, Float32x4ShuffleX, 384969722) \
|
||||
V(_Float32x4, get:y, Float32x4ShuffleY, 1398121942) \
|
||||
V(_Float32x4, get:z, Float32x4ShuffleZ, 1178175605) \
|
||||
V(_Float32x4, get:w, Float32x4ShuffleW, 480951003) \
|
||||
V(_Float32x4, _mul, Float32x4Mul, 1703784673) \
|
||||
V(_Float32x4, _sub, Float32x4Sub, 1302598822) \
|
||||
V(_Float32x4, _add, Float32x4Add, 182344215) \
|
||||
|
||||
#define GRAPH_CORE_INTRINSICS_LIST(V) \
|
||||
V(_List, get:length, ObjectArrayLength, 1181471893) \
|
||||
|
|
Loading…
Reference in a new issue