mirror of
https://github.com/dart-lang/sdk
synced 2024-10-04 15:51:41 +00:00
[vm] Introduce --target-unknown-cpu option and use it for app-jit snapshots
App-jit and core-jit snapshots generated on one machine can be copied to another machine with different CPU family/model, so it is incorrect to use CPU features of the host machine to generate code for snapshots. This change adds --target-unknown-cpu option and enables it when generating app-jit and core-jit snapshots in standalone Dart VM and gen_snapshot. Currently, this flag disables SSE4.1, popcnt and ABM on ia32 and x64, and integer division instruction on ARM. Also, new flag enables testing of roundsd instruction availability at run time on x64 (similarly to AOT). TEST=ci Fixes https://github.com/dart-lang/sdk/issues/47907 Fixes https://github.com/flutter/flutter/issues/94181 Change-Id: Id28448052a21df4bae30b39e62b8532e55d4c901 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/223960 Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
parent
8784f9682d
commit
b80e682cbf
|
@ -879,6 +879,10 @@ int main(int argc, char** argv) {
|
|||
if (IsSnapshottingForPrecompilation()) {
|
||||
vm_options.AddArgument("--precompilation");
|
||||
} else if ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT)) {
|
||||
// Core-jit and app-jit snapshot can be deployed to another machine,
|
||||
// so generated code should not depend on the CPU features
|
||||
// of the system where snapshot was generated.
|
||||
vm_options.AddArgument("--target-unknown-cpu");
|
||||
#if !defined(TARGET_ARCH_IA32)
|
||||
vm_options.AddArgument("--link_natives_lazily");
|
||||
#endif
|
||||
|
|
|
@ -1242,6 +1242,12 @@ void main(int argc, char** argv) {
|
|||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
vm_options.AddArgument("--precompilation");
|
||||
#endif
|
||||
if (Options::gen_snapshot_kind() == kAppJIT) {
|
||||
// App-jit snapshot can be deployed to another machine,
|
||||
// so generated code should not depend on the CPU features
|
||||
// of the system where snapshot was generated.
|
||||
vm_options.AddArgument("--target-unknown-cpu");
|
||||
}
|
||||
// If we need to write an app-jit snapshot or a depfile, then add an exit
|
||||
// hook that writes the snapshot and/or depfile as appropriate.
|
||||
if ((Options::gen_snapshot_kind() == kAppJIT) ||
|
||||
|
|
|
@ -223,16 +223,14 @@ void FlowGraphCompiler::InitCompiler() {
|
|||
BlockEntryInstr* entry = block_order_[i];
|
||||
for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
|
||||
Instruction* current = it.Current();
|
||||
if (current->IsBranch()) {
|
||||
current = current->AsBranch()->comparison();
|
||||
if (auto* branch = current->AsBranch()) {
|
||||
current = branch->comparison();
|
||||
}
|
||||
// In optimized code, ICData is always set in the instructions.
|
||||
const ICData* ic_data = NULL;
|
||||
if (current->IsInstanceCall()) {
|
||||
ic_data = current->AsInstanceCall()->ic_data();
|
||||
}
|
||||
if ((ic_data != NULL) && (ic_data->NumberOfUsedChecks() == 0)) {
|
||||
may_reoptimize_ = true;
|
||||
if (auto* instance_call = current->AsInstanceCall()) {
|
||||
const ICData* ic_data = instance_call->ic_data();
|
||||
if ((ic_data == nullptr) || (ic_data->NumberOfUsedChecks() == 0)) {
|
||||
may_reoptimize_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5241,11 +5241,12 @@ void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
|||
compiler->AddSlowPathCode(slow_path);
|
||||
|
||||
if (recognized_kind() != MethodRecognizer::kDoubleToInteger) {
|
||||
// In JIT mode VM knows target CPU features at compile time
|
||||
// and can pick more optimal representation for DoubleToDouble
|
||||
// conversion. In AOT mode we test if roundsd instruction is
|
||||
// available at run time and fall back to stub if it isn't.
|
||||
ASSERT(CompilerState::Current().is_aot());
|
||||
// In JIT mode without --target-unknown-cpu VM knows target CPU features
|
||||
// at compile time and can pick more optimal representation
|
||||
// for DoubleToDouble conversion. In AOT mode and with
|
||||
// --target-unknown-cpu we test if roundsd instruction is available
|
||||
// at run time and fall back to stub if it isn't.
|
||||
ASSERT(CompilerState::Current().is_aot() || FLAG_target_unknown_cpu);
|
||||
if (FLAG_use_slow_path) {
|
||||
__ jmp(slow_path->entry_label());
|
||||
__ Bind(slow_path->exit_label());
|
||||
|
|
|
@ -940,7 +940,7 @@ bool FlowGraphBuilder::IsRecognizedMethodForFlowGraph(
|
|||
case MethodRecognizer::kDoubleFloorToInt:
|
||||
if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
|
||||
#if defined(TARGET_ARCH_X64)
|
||||
return CompilerState::Current().is_aot();
|
||||
return CompilerState::Current().is_aot() || FLAG_target_unknown_cpu;
|
||||
#elif defined(TARGET_ARCH_ARM64)
|
||||
return true;
|
||||
#else
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#endif
|
||||
|
||||
#include "vm/allocation.h"
|
||||
#include "vm/flags.h"
|
||||
#include "vm/simulator.h"
|
||||
|
||||
namespace dart {
|
||||
|
@ -32,7 +33,7 @@ class HostCPUFeatures : public AllStatic {
|
|||
}
|
||||
static bool integer_division_supported() {
|
||||
DEBUG_ASSERT(initialized_);
|
||||
return integer_division_supported_;
|
||||
return integer_division_supported_ && !FLAG_target_unknown_cpu;
|
||||
}
|
||||
static bool neon_supported() {
|
||||
DEBUG_ASSERT(initialized_);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#endif
|
||||
|
||||
#include "vm/allocation.h"
|
||||
#include "vm/flags.h"
|
||||
#include "vm/simulator.h"
|
||||
|
||||
namespace dart {
|
||||
|
|
|
@ -30,15 +30,15 @@ class HostCPUFeatures : public AllStatic {
|
|||
}
|
||||
static bool sse4_1_supported() {
|
||||
DEBUG_ASSERT(initialized_);
|
||||
return sse4_1_supported_ && FLAG_use_sse41;
|
||||
return sse4_1_supported_ && FLAG_use_sse41 && !FLAG_target_unknown_cpu;
|
||||
}
|
||||
static bool popcnt_supported() {
|
||||
DEBUG_ASSERT(initialized_);
|
||||
return popcnt_supported_;
|
||||
return popcnt_supported_ && !FLAG_target_unknown_cpu;
|
||||
}
|
||||
static bool abm_supported() {
|
||||
DEBUG_ASSERT(initialized_);
|
||||
return abm_supported_;
|
||||
return abm_supported_ && !FLAG_target_unknown_cpu;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -30,15 +30,15 @@ class HostCPUFeatures : public AllStatic {
|
|||
}
|
||||
static bool sse4_1_supported() {
|
||||
DEBUG_ASSERT(initialized_);
|
||||
return sse4_1_supported_ && FLAG_use_sse41;
|
||||
return sse4_1_supported_ && FLAG_use_sse41 && !FLAG_target_unknown_cpu;
|
||||
}
|
||||
static bool popcnt_supported() {
|
||||
DEBUG_ASSERT(initialized_);
|
||||
return popcnt_supported_;
|
||||
return popcnt_supported_ && !FLAG_target_unknown_cpu;
|
||||
}
|
||||
static bool abm_supported() {
|
||||
DEBUG_ASSERT(initialized_);
|
||||
return abm_supported_;
|
||||
return abm_supported_ && !FLAG_target_unknown_cpu;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -193,6 +193,8 @@ constexpr bool FLAG_support_il_printer = false;
|
|||
"needed in the precompiled runtime.") \
|
||||
P(show_invisible_frames, bool, false, \
|
||||
"Show invisible frames in stack traces.") \
|
||||
P(target_unknown_cpu, bool, false, \
|
||||
"Generate code for a generic CPU, unknown at compile time") \
|
||||
D(trace_cha, bool, false, "Trace CHA operations") \
|
||||
R(trace_field_guards, false, bool, false, "Trace changes in field's cids.") \
|
||||
D(trace_ic, bool, false, "Trace IC handling") \
|
||||
|
|
Loading…
Reference in a new issue