diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc index 00cf48285d4..6a2413919c0 100644 --- a/runtime/bin/gen_snapshot.cc +++ b/runtime/bin/gen_snapshot.cc @@ -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 diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc index 88e7c9e9bc6..d03555a9531 100644 --- a/runtime/bin/main.cc +++ b/runtime/bin/main.cc @@ -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) || diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc index 9e560490794..a6d54180856 100644 --- a/runtime/vm/compiler/backend/flow_graph_compiler.cc +++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc @@ -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; + } } } } diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc index 1e568f2793b..378537a351c 100644 --- a/runtime/vm/compiler/backend/il_x64.cc +++ b/runtime/vm/compiler/backend/il_x64.cc @@ -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()); diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc index 2b7346a014e..07a2898984e 100644 --- a/runtime/vm/compiler/frontend/kernel_to_il.cc +++ b/runtime/vm/compiler/frontend/kernel_to_il.cc @@ -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 diff --git a/runtime/vm/cpu_arm.h b/runtime/vm/cpu_arm.h index 0729a028309..a6cb9d7675d 100644 --- a/runtime/vm/cpu_arm.h +++ b/runtime/vm/cpu_arm.h @@ -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_); diff --git a/runtime/vm/cpu_arm64.h b/runtime/vm/cpu_arm64.h index 5fa7b2e5e89..3e793ef6471 100644 --- a/runtime/vm/cpu_arm64.h +++ b/runtime/vm/cpu_arm64.h @@ -10,6 +10,7 @@ #endif #include "vm/allocation.h" +#include "vm/flags.h" #include "vm/simulator.h" namespace dart { diff --git a/runtime/vm/cpu_ia32.h b/runtime/vm/cpu_ia32.h index f622c1f5e97..0fe8ba02e1c 100644 --- a/runtime/vm/cpu_ia32.h +++ b/runtime/vm/cpu_ia32.h @@ -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: diff --git a/runtime/vm/cpu_x64.h b/runtime/vm/cpu_x64.h index d0d1a14bbf2..c444be87c2f 100644 --- a/runtime/vm/cpu_x64.h +++ b/runtime/vm/cpu_x64.h @@ -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: diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h index 8af317ada07..cccfdfb40b8 100644 --- a/runtime/vm/flag_list.h +++ b/runtime/vm/flag_list.h @@ -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") \