| Index: runtime/vm/intrinsifier.cc
|
| diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
|
| index 51d0e29ba441f56b28610f1a815e059a6f298b99..8eb5fabd52e4c6daf5d70446df3f0a0881bc37cd 100644
|
| --- a/runtime/vm/intrinsifier.cc
|
| +++ b/runtime/vm/intrinsifier.cc
|
| @@ -3,22 +3,21 @@
|
| // BSD-style license that can be found in the LICENSE file.
|
| // Class for intrinsifying functions.
|
|
|
| +#include "vm/intrinsifier.h"
|
| #include "vm/assembler.h"
|
| #include "vm/compiler.h"
|
| #include "vm/cpu.h"
|
| #include "vm/flags.h"
|
| #include "vm/flow_graph.h"
|
| -#include "vm/flow_graph_compiler.h"
|
| #include "vm/flow_graph_allocator.h"
|
| #include "vm/flow_graph_builder.h"
|
| +#include "vm/flow_graph_compiler.h"
|
| #include "vm/il_printer.h"
|
| #include "vm/intermediate_language.h"
|
| -#include "vm/intrinsifier.h"
|
| #include "vm/object.h"
|
| #include "vm/parser.h"
|
| #include "vm/symbols.h"
|
|
|
| -
|
| namespace dart {
|
|
|
| DEFINE_FLAG(bool, intrinsify, true, "Instrinsify when possible");
|
| @@ -59,7 +58,6 @@ bool Intrinsifier::CanIntrinsify(const Function& function) {
|
| return true;
|
| }
|
|
|
| -
|
| #if !defined(DART_PRECOMPILED_RUNTIME)
|
| void Intrinsifier::InitializeState() {
|
| Thread* thread = Thread::Current();
|
| @@ -121,7 +119,6 @@ void Intrinsifier::InitializeState() {
|
| }
|
| #endif // !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
| -
|
| // DBC does not use graph intrinsics.
|
| #if !defined(TARGET_ARCH_DBC)
|
| static void EmitCodeFor(FlowGraphCompiler* compiler, FlowGraph* graph) {
|
| @@ -160,7 +157,6 @@ static void EmitCodeFor(FlowGraphCompiler* compiler, FlowGraph* graph) {
|
| }
|
| #endif
|
|
|
| -
|
| bool Intrinsifier::GraphIntrinsify(const ParsedFunction& parsed_function,
|
| FlowGraphCompiler* compiler) {
|
| #if !defined(TARGET_ARCH_DBC)
|
| @@ -214,7 +210,6 @@ bool Intrinsifier::GraphIntrinsify(const ParsedFunction& parsed_function,
|
| #endif // !defined(TARGET_ARCH_DBC)
|
| }
|
|
|
| -
|
| // Returns true if fall-through code can be omitted.
|
| bool Intrinsifier::Intrinsify(const ParsedFunction& parsed_function,
|
| FlowGraphCompiler* compiler) {
|
| @@ -270,7 +265,6 @@ bool Intrinsifier::Intrinsify(const ParsedFunction& parsed_function,
|
| return false;
|
| }
|
|
|
| -
|
| #if !defined(TARGET_ARCH_DBC)
|
| static intptr_t CidForRepresentation(Representation rep) {
|
| switch (rep) {
|
| @@ -290,7 +284,6 @@ static intptr_t CidForRepresentation(Representation rep) {
|
| }
|
| }
|
|
|
| -
|
| // Notes about the graph intrinsics:
|
| //
|
| // IR instructions which would jump to a deoptimization sequence on failure
|
| @@ -384,14 +377,12 @@ class BlockBuilder : public ValueObject {
|
| return invoke_math_c_function;
|
| }
|
|
|
| -
|
| FlowGraph* flow_graph_;
|
| BlockEntryInstr* entry_;
|
| Instruction* current_;
|
| Environment* fall_through_env_;
|
| };
|
|
|
| -
|
| static void PrepareIndexedOp(BlockBuilder* builder,
|
| Definition* array,
|
| Definition* index,
|
| @@ -481,7 +472,6 @@ static bool IntrinsifyArrayGetIndexed(FlowGraph* flow_graph,
|
| return true;
|
| }
|
|
|
| -
|
| static bool IntrinsifyArraySetIndexed(FlowGraph* flow_graph,
|
| intptr_t array_cid) {
|
| GraphEntryInstr* graph_entry = flow_graph->graph_entry();
|
| @@ -581,7 +571,6 @@ static bool IntrinsifyArraySetIndexed(FlowGraph* flow_graph,
|
| return true;
|
| }
|
|
|
| -
|
| #define DEFINE_ARRAY_GETTER_INTRINSIC(enum_name) \
|
| bool Intrinsifier::Build_##enum_name##GetIndexed(FlowGraph* flow_graph) { \
|
| return IntrinsifyArrayGetIndexed( \
|
| @@ -589,7 +578,6 @@ static bool IntrinsifyArraySetIndexed(FlowGraph* flow_graph,
|
| MethodRecognizer::k##enum_name##GetIndexed)); \
|
| }
|
|
|
| -
|
| #define DEFINE_ARRAY_SETTER_INTRINSIC(enum_name) \
|
| bool Intrinsifier::Build_##enum_name##SetIndexed(FlowGraph* flow_graph) { \
|
| return IntrinsifyArraySetIndexed( \
|
| @@ -618,7 +606,6 @@ DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint32Array)
|
| #undef DEFINE_ARRAY_GETTER_INTRINSIC
|
| #undef DEFINE_ARRAY_SETTER_INTRINSIC
|
|
|
| -
|
| #define DEFINE_FLOAT_ARRAY_GETTER_INTRINSIC(enum_name) \
|
| bool Intrinsifier::Build_##enum_name##GetIndexed(FlowGraph* flow_graph) { \
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) { \
|
| @@ -629,7 +616,6 @@ DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint32Array)
|
| MethodRecognizer::k##enum_name##GetIndexed)); \
|
| }
|
|
|
| -
|
| #define DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC(enum_name) \
|
| bool Intrinsifier::Build_##enum_name##SetIndexed(FlowGraph* flow_graph) { \
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) { \
|
| @@ -651,7 +637,6 @@ DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(Float32Array)
|
| #undef DEFINE_FLOAT_ARRAY_GETTER_INTRINSIC
|
| #undef DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC
|
|
|
| -
|
| #define DEFINE_SIMD_ARRAY_GETTER_INTRINSIC(enum_name) \
|
| bool Intrinsifier::Build_##enum_name##GetIndexed(FlowGraph* flow_graph) { \
|
| if (!FlowGraphCompiler::SupportsUnboxedSimd128()) { \
|
| @@ -662,7 +647,6 @@ DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(Float32Array)
|
| MethodRecognizer::k##enum_name##GetIndexed)); \
|
| }
|
|
|
| -
|
| #define DEFINE_SIMD_ARRAY_SETTER_INTRINSIC(enum_name) \
|
| bool Intrinsifier::Build_##enum_name##SetIndexed(FlowGraph* flow_graph) { \
|
| if (!FlowGraphCompiler::SupportsUnboxedSimd128()) { \
|
| @@ -685,7 +669,6 @@ DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(Float64x2Array)
|
| #undef DEFINE_SIMD_ARRAY_GETTER_INTRINSIC
|
| #undef DEFINE_SIMD_ARRAY_SETTER_INTRINSIC
|
|
|
| -
|
| static bool BuildCodeUnitAt(FlowGraph* flow_graph, intptr_t cid) {
|
| GraphEntryInstr* graph_entry = flow_graph->graph_entry();
|
| TargetEntryInstr* normal_entry = graph_entry->normal_entry();
|
| @@ -715,29 +698,24 @@ static bool BuildCodeUnitAt(FlowGraph* flow_graph, intptr_t cid) {
|
| return true;
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_OneByteStringCodeUnitAt(FlowGraph* flow_graph) {
|
| return BuildCodeUnitAt(flow_graph, kOneByteStringCid);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_TwoByteStringCodeUnitAt(FlowGraph* flow_graph) {
|
| return BuildCodeUnitAt(flow_graph, kTwoByteStringCid);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_ExternalOneByteStringCodeUnitAt(
|
| FlowGraph* flow_graph) {
|
| return BuildCodeUnitAt(flow_graph, kExternalOneByteStringCid);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_ExternalTwoByteStringCodeUnitAt(
|
| FlowGraph* flow_graph) {
|
| return BuildCodeUnitAt(flow_graph, kExternalTwoByteStringCid);
|
| }
|
|
|
| -
|
| static bool BuildBinaryFloat32x4Op(FlowGraph* flow_graph, Token::Kind kind) {
|
| if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false;
|
|
|
| @@ -769,22 +747,18 @@ static bool BuildBinaryFloat32x4Op(FlowGraph* flow_graph, Token::Kind kind) {
|
| 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::SupportsUnboxedDoubles() ||
|
| @@ -810,31 +784,26 @@ static bool BuildFloat32x4Shuffle(FlowGraph* flow_graph,
|
| 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();
|
| @@ -848,32 +817,26 @@ static bool BuildLoadField(FlowGraph* flow_graph, intptr_t offset) {
|
| return true;
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_ObjectArrayLength(FlowGraph* flow_graph) {
|
| return BuildLoadField(flow_graph, Array::length_offset());
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_ImmutableArrayLength(FlowGraph* flow_graph) {
|
| return BuildLoadField(flow_graph, Array::length_offset());
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_GrowableArrayLength(FlowGraph* flow_graph) {
|
| return BuildLoadField(flow_graph, GrowableObjectArray::length_offset());
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_StringBaseLength(FlowGraph* flow_graph) {
|
| return BuildLoadField(flow_graph, String::length_offset());
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_TypedDataLength(FlowGraph* flow_graph) {
|
| return BuildLoadField(flow_graph, TypedData::length_offset());
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_GrowableArrayCapacity(FlowGraph* flow_graph) {
|
| GraphEntryInstr* graph_entry = flow_graph->graph_entry();
|
| TargetEntryInstr* normal_entry = graph_entry->normal_entry();
|
| @@ -891,7 +854,6 @@ bool Intrinsifier::Build_GrowableArrayCapacity(FlowGraph* flow_graph) {
|
| return true;
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_GrowableArrayGetIndexed(FlowGraph* flow_graph) {
|
| GraphEntryInstr* graph_entry = flow_graph->graph_entry();
|
| TargetEntryInstr* normal_entry = graph_entry->normal_entry();
|
| @@ -914,7 +876,6 @@ bool Intrinsifier::Build_GrowableArrayGetIndexed(FlowGraph* flow_graph) {
|
| return true;
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_GrowableArraySetIndexed(FlowGraph* flow_graph) {
|
| if (Isolate::Current()->type_checks()) {
|
| return false;
|
| @@ -946,7 +907,6 @@ bool Intrinsifier::Build_GrowableArraySetIndexed(FlowGraph* flow_graph) {
|
| return true;
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_GrowableArraySetData(FlowGraph* flow_graph) {
|
| GraphEntryInstr* graph_entry = flow_graph->graph_entry();
|
| TargetEntryInstr* normal_entry = graph_entry->normal_entry();
|
| @@ -969,7 +929,6 @@ bool Intrinsifier::Build_GrowableArraySetData(FlowGraph* flow_graph) {
|
| return true;
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_GrowableArraySetLength(FlowGraph* flow_graph) {
|
| GraphEntryInstr* graph_entry = flow_graph->graph_entry();
|
| TargetEntryInstr* normal_entry = graph_entry->normal_entry();
|
| @@ -988,7 +947,6 @@ bool Intrinsifier::Build_GrowableArraySetLength(FlowGraph* flow_graph) {
|
| return true;
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_DoubleFlipSignBit(FlowGraph* flow_graph) {
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
|
| return false;
|
| @@ -1009,7 +967,6 @@ bool Intrinsifier::Build_DoubleFlipSignBit(FlowGraph* flow_graph) {
|
| return true;
|
| }
|
|
|
| -
|
| static bool BuildInvokeMathCFunction(BlockBuilder* builder,
|
| MethodRecognizer::Kind kind,
|
| intptr_t num_parameters = 1) {
|
| @@ -1037,7 +994,6 @@ static bool BuildInvokeMathCFunction(BlockBuilder* builder,
|
| return true;
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_MathSin(FlowGraph* flow_graph) {
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
|
|
|
| @@ -1048,7 +1004,6 @@ bool Intrinsifier::Build_MathSin(FlowGraph* flow_graph) {
|
| return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathSin);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_MathCos(FlowGraph* flow_graph) {
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
|
|
|
| @@ -1059,7 +1014,6 @@ bool Intrinsifier::Build_MathCos(FlowGraph* flow_graph) {
|
| return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathCos);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_MathTan(FlowGraph* flow_graph) {
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
|
|
|
| @@ -1070,7 +1024,6 @@ bool Intrinsifier::Build_MathTan(FlowGraph* flow_graph) {
|
| return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathTan);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_MathAsin(FlowGraph* flow_graph) {
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
|
|
|
| @@ -1081,7 +1034,6 @@ bool Intrinsifier::Build_MathAsin(FlowGraph* flow_graph) {
|
| return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAsin);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_MathAcos(FlowGraph* flow_graph) {
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
|
|
|
| @@ -1092,7 +1044,6 @@ bool Intrinsifier::Build_MathAcos(FlowGraph* flow_graph) {
|
| return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAcos);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_MathAtan(FlowGraph* flow_graph) {
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
|
|
|
| @@ -1103,7 +1054,6 @@ bool Intrinsifier::Build_MathAtan(FlowGraph* flow_graph) {
|
| return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAtan);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_MathAtan2(FlowGraph* flow_graph) {
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
|
|
|
| @@ -1115,7 +1065,6 @@ bool Intrinsifier::Build_MathAtan2(FlowGraph* flow_graph) {
|
| /* num_parameters = */ 2);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_DoubleMod(FlowGraph* flow_graph) {
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
|
|
|
| @@ -1127,7 +1076,6 @@ bool Intrinsifier::Build_DoubleMod(FlowGraph* flow_graph) {
|
| /* num_parameters = */ 2);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_DoubleCeil(FlowGraph* flow_graph) {
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
|
| // TODO(johnmccutchan): On X86 this intrinsic can be written in a different
|
| @@ -1141,7 +1089,6 @@ bool Intrinsifier::Build_DoubleCeil(FlowGraph* flow_graph) {
|
| return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleCeil);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_DoubleFloor(FlowGraph* flow_graph) {
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
|
| // TODO(johnmccutchan): On X86 this intrinsic can be written in a different
|
| @@ -1155,7 +1102,6 @@ bool Intrinsifier::Build_DoubleFloor(FlowGraph* flow_graph) {
|
| return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleFloor);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_DoubleTruncate(FlowGraph* flow_graph) {
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
|
| // TODO(johnmccutchan): On X86 this intrinsic can be written in a different
|
| @@ -1169,7 +1115,6 @@ bool Intrinsifier::Build_DoubleTruncate(FlowGraph* flow_graph) {
|
| return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleTruncate);
|
| }
|
|
|
| -
|
| bool Intrinsifier::Build_DoubleRound(FlowGraph* flow_graph) {
|
| if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
|
|
|
| @@ -1180,16 +1125,13 @@ bool Intrinsifier::Build_DoubleRound(FlowGraph* flow_graph) {
|
| return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleRound);
|
| }
|
|
|
| -
|
| void Intrinsifier::RegExp_ExecuteMatch(Assembler* assembler) {
|
| IntrinsifyRegExpExecuteMatch(assembler, /*sticky=*/false);
|
| }
|
|
|
| -
|
| void Intrinsifier::RegExp_ExecuteMatchSticky(Assembler* assembler) {
|
| IntrinsifyRegExpExecuteMatch(assembler, /*sticky=*/true);
|
| }
|
| #endif // !defined(TARGET_ARCH_DBC)
|
|
|
| -
|
| } // namespace dart
|
|
|