[vm] Rewrite Intrinsifier::InitializeState to be data driven.
The expanded form takes long time to compile in release mode (>200s)
this reduces compilation time of intrinsifier.cc by a factor of 20x.
Bug: https://github.com/dart-lang/sdk/issues/33023
Change-Id: Idff9d8a46a5335eb7a722c3eee02dc2258b16283
Reviewed-on: https://dart-review.googlesource.com/53421
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index 654d33c..d7ffab5 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -61,6 +61,45 @@
}
#if !defined(DART_PRECOMPILED_RUNTIME)
+struct IntrinsicDesc {
+ const char* class_name;
+ const char* function_name;
+};
+
+struct LibraryInstrinsicsDesc {
+ Library& library;
+ IntrinsicDesc* intrinsics;
+};
+
+#define DEFINE_INTRINSIC(class_name, function_name, destination, type, fp) \
+ {#class_name, #function_name},
+
+// clang-format off
+static IntrinsicDesc core_intrinsics[] = {
+ CORE_LIB_INTRINSIC_LIST(DEFINE_INTRINSIC)
+ CORE_INTEGER_LIB_INTRINSIC_LIST(DEFINE_INTRINSIC)
+ GRAPH_CORE_INTRINSICS_LIST(DEFINE_INTRINSIC)
+ {nullptr, nullptr},
+};
+
+static IntrinsicDesc math_intrinsics[] = {
+ MATH_LIB_INTRINSIC_LIST(DEFINE_INTRINSIC)
+ GRAPH_MATH_LIB_INTRINSIC_LIST(DEFINE_INTRINSIC)
+ {nullptr, nullptr},
+};
+
+static IntrinsicDesc typed_data_intrinsics[] = {
+ TYPED_DATA_LIB_INTRINSIC_LIST(DEFINE_INTRINSIC)
+ GRAPH_TYPED_DATA_INTRINSICS_LIST(DEFINE_INTRINSIC)
+ {nullptr, nullptr},
+};
+
+static IntrinsicDesc developer_intrinsics[] = {
+ DEVELOPER_LIB_INTRINSIC_LIST(DEFINE_INTRINSIC)
+ {nullptr, nullptr},
+};
+// clang-format on
+
void Intrinsifier::InitializeState() {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -68,62 +107,53 @@
Class& cls = Class::Handle(zone);
Function& func = Function::Handle(zone);
String& str = String::Handle(zone);
+ String& str2 = String::Handle(zone);
Error& error = Error::Handle(zone);
-#define SETUP_FUNCTION(class_name, function_name, destination, type, fp) \
- func = Function::null(); \
- if (strcmp(#class_name, "::") == 0) { \
- str = String::New(#function_name); \
- func = lib.LookupFunctionAllowPrivate(str); \
- } else { \
- str = String::New(#class_name); \
- cls = lib.LookupClassAllowPrivate(str); \
- ASSERT(FLAG_precompiled_mode || !cls.IsNull()); \
- if (!cls.IsNull()) { \
- error = cls.EnsureIsFinalized(thread); \
- if (!error.IsNull()) { \
- OS::PrintErr("%s\n", error.ToErrorCString()); \
- } \
- ASSERT(error.IsNull()); \
- if (#function_name[0] == '.') { \
- str = String::New(#class_name #function_name); \
- } else { \
- str = String::New(#function_name); \
- } \
- func = cls.LookupFunctionAllowPrivate(str); \
- } \
- } \
- if (!func.IsNull()) { \
- func.set_is_intrinsic(true); \
- } else if (!FLAG_precompiled_mode) { \
- FATAL2("Intrinsifier failed to find method %s in class %s\n", \
- #function_name, #class_name); \
+ static const intptr_t kNumLibs = 4;
+ LibraryInstrinsicsDesc intrinsics[kNumLibs] = {
+ {Library::Handle(zone, Library::CoreLibrary()), core_intrinsics},
+ {Library::Handle(zone, Library::MathLibrary()), math_intrinsics},
+ {Library::Handle(zone, Library::TypedDataLibrary()),
+ typed_data_intrinsics},
+ {Library::Handle(zone, Library::DeveloperLibrary()),
+ developer_intrinsics},
+ };
+
+ for (intptr_t i = 0; i < kNumLibs; i++) {
+ lib = intrinsics[i].library.raw();
+ for (IntrinsicDesc* intrinsic = intrinsics[i].intrinsics;
+ intrinsic->class_name != nullptr; intrinsic++) {
+ func = Function::null();
+ if (strcmp(intrinsic->class_name, "::") == 0) {
+ str = String::New(intrinsic->function_name);
+ func = lib.LookupFunctionAllowPrivate(str);
+ } else {
+ str = String::New(intrinsic->class_name);
+ cls = lib.LookupClassAllowPrivate(str);
+ ASSERT(FLAG_precompiled_mode || !cls.IsNull());
+ if (!cls.IsNull()) {
+ error = cls.EnsureIsFinalized(thread);
+ if (!error.IsNull()) {
+ OS::PrintErr("%s\n", error.ToErrorCString());
+ }
+ ASSERT(error.IsNull());
+ str = String::New(intrinsic->function_name);
+ if (intrinsic->function_name[0] == '.') {
+ str2 = String::New(intrinsic->class_name);
+ str = String::Concat(str2, str);
+ }
+ func = cls.LookupFunctionAllowPrivate(str);
+ }
+ }
+ if (!func.IsNull()) {
+ func.set_is_intrinsic(true);
+ } else if (!FLAG_precompiled_mode) {
+ FATAL2("Intrinsifier failed to find method %s in class %s\n",
+ intrinsic->function_name, intrinsic->class_name);
+ }
+ }
}
-
- // Set up all core lib functions that can be intrinsified.
- lib = Library::CoreLibrary();
- ASSERT(!lib.IsNull());
- CORE_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
- CORE_INTEGER_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
- GRAPH_CORE_INTRINSICS_LIST(SETUP_FUNCTION);
-
- // Set up all math lib functions that can be intrinsified.
- lib = Library::MathLibrary();
- ASSERT(!lib.IsNull());
- MATH_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
- GRAPH_MATH_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
-
- // Set up all dart:typed_data lib functions that can be intrinsified.
- lib = Library::TypedDataLibrary();
- ASSERT(!lib.IsNull());
- TYPED_DATA_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
- GRAPH_TYPED_DATA_INTRINSICS_LIST(SETUP_FUNCTION);
-
- // Setup all dart:developer lib functions that can be intrinsified.
- lib = Library::DeveloperLibrary();
- ASSERT(!lib.IsNull());
- DEVELOPER_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
-
#undef SETUP_FUNCTION
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)