[vm] Don't emit graph body when intrinsification is complete.
Flutter Gallery:
Instructions(CodeSize): -1.36%
Total(CodeSize): -0.87%
Change-Id: I40b8e0a5a73373993961e357b4cab9a78936332a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99162
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Samir Jindel <sjindel@google.com>
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index b59a7fc..9e5377b 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -560,6 +560,14 @@
StatsEnd(entry);
pending_deoptimization_env_ = NULL;
EndCodeSourceRange(entry->token_pos());
+
+ // The function was fully intrinsified, so there's no need to generate any
+ // more code.
+ if (fully_intrinsified_) {
+ ASSERT(entry == flow_graph().graph_entry()->normal_entry());
+ break;
+ }
+
// Compile all successors until an exit, branch, or a block entry.
for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
Instruction* instr = it.Current();
@@ -1163,6 +1171,14 @@
// Returns 'true' if regular code generation should be skipped.
bool FlowGraphCompiler::TryIntrinsify() {
+ if (TryIntrinsifyHelper()) {
+ fully_intrinsified_ = true;
+ return true;
+ }
+ return false;
+}
+
+bool FlowGraphCompiler::TryIntrinsifyHelper() {
Label exit;
set_intrinsic_slow_path_label(&exit);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 435de9a..56046747 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -817,6 +817,7 @@
void EmitFrameEntry();
+ bool TryIntrinsifyHelper();
void AddPcRelativeCallTarget(const Function& function,
Code::EntryKind entry_kind);
void AddPcRelativeCallStubTarget(const Code& stub_code);
@@ -1030,6 +1031,7 @@
// True while emitting intrinsic code.
bool intrinsic_mode_;
Label* intrinsic_slow_path_label_ = nullptr;
+ bool fully_intrinsified_ = false;
CodeStatistics* stats_;
const Class& double_class_;
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 684ca5a..04a4a85 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -943,8 +943,11 @@
VisitBlocks();
__ bkpt(0);
- ASSERT(assembler()->constant_pool_allowed());
- GenerateDeferredCode();
+
+ if (!fully_intrinsified_) {
+ ASSERT(assembler()->constant_pool_allowed());
+ GenerateDeferredCode();
+ }
}
void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index 20c7f57..192a903 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -932,8 +932,11 @@
VisitBlocks();
__ int3();
- ASSERT(assembler()->constant_pool_allowed());
- GenerateDeferredCode();
+
+ if (!fully_intrinsified_) {
+ ASSERT(assembler()->constant_pool_allowed());
+ GenerateDeferredCode();
+ }
}
void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index c65e75e..4af0220 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -3766,14 +3766,11 @@
compiler->SpecialStatsEnd(CombinedCodeStatistics::kTagCheckedEntry);
}
}
- // NOTE: Because in JIT X64/ARM mode the graph can have multiple
- // entrypoints, so we generate several times the same intrinsification &
- // frame setup. That's why we cannot rely on the constant pool being
- // `false` when we come in here.
+ // NOTE: Because in X64/ARM mode the graph can have multiple entrypoints, we
+ // generate several times the same intrinsification & frame setup. That's why
+ // we cannot rely on the constant pool being `false` when we come in here.
__ set_constant_pool_allowed(false);
- // TODO(#34162): Don't emit more code if 'TryIntrinsify' returns 'true'
- // (meaning the function was fully intrinsified).
- compiler->TryIntrinsify();
+ if (compiler->TryIntrinsify()) return;
compiler->EmitPrologue();
ASSERT(__ constant_pool_allowed());
#endif