Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NaN canonicalization for singlepass backend. #1303

Merged
merged 23 commits into from
Mar 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8ea7bfd
NaN canonicalization by tracking values.
losfair Mar 15, 2020
5d26d92
Add switch to turn on/off NaN canonicalization.
losfair Mar 16, 2020
da07ed5
Add clif/llvm NaN spectest failure excludes.
losfair Mar 16, 2020
ae9b321
Update changelog.
losfair Mar 16, 2020
29b5223
Canonicalize NANs produced by f.trunc and f.nearby.
nlewycky Mar 16, 2020
8f2bb84
Merge pull request #1308 from wasmerio/nlewycky/llvm-nan-cncl
syrusakbary Mar 16, 2020
3ee7f43
Enable nan canonicalization for cranelift backend.
losfair Mar 17, 2020
4357c15
Fix missing canonicalizations.
losfair Mar 17, 2020
e0538d3
Remove clif spectest excludes.
losfair Mar 17, 2020
1ddf3a1
Add mem/local NaN tests.
losfair Mar 17, 2020
1d9f0c5
Style fixes and fix missing canonicalization at function call.
losfair Mar 17, 2020
72bc9f6
Add call canonicalization tests.
losfair Mar 17, 2020
5e40be4
Merge remote-tracking branch 'origin/master' into feature/singlepass-…
losfair Mar 17, 2020
8e92e32
Disable canonicalization for aarch64.
losfair Mar 17, 2020
bfc3b82
Apply suggestions from code review
losfair Mar 17, 2020
86dde8c
Add missing movs.
losfair Mar 17, 2020
3a18b70
Merge remote-tracking branch 'origin/feature/singlepass-nan-cncl' int…
losfair Mar 17, 2020
ea0cd72
Cargo fmt
losfair Mar 17, 2020
a9cd6d6
Add aarch64 NaN canonicalization spectest excludes.
losfair Mar 17, 2020
29a431c
Remove 4 spectest excludes that are no longer needed.
losfair Mar 17, 2020
8485ccc
Update comment for `nan_canonicalization`.
losfair Mar 17, 2020
c25ba62
Add comment for call argument list preprocessing.
losfair Mar 18, 2020
d1e8674
Merge branch 'master' into feature/singlepass-nan-cncl
losfair Mar 19, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## **[Unreleased]**

- [#1303](https://github.com/wasmerio/wasmer/pull/1303) NaN canonicalization for singlepass backend.
- [#1305](https://github.com/wasmerio/wasmer/pull/1305) Handle panics from DynamicFunc.
- [#1301](https://github.com/wasmerio/wasmer/pull/1301) Update supported stable Rust version to 1.41.1.
- [#1300](https://github.com/wasmerio/wasmer/pull/1300) Add support for multiple versions of WASI tests: wasitests now test all versions of WASI.
Expand Down
30 changes: 21 additions & 9 deletions lib/clif-backend/src/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use std::mem;
use std::sync::{Arc, RwLock};
use wasmer_runtime_core::error::CompileError;
use wasmer_runtime_core::{
backend::{CacheGen, Token},
backend::{CacheGen, CompilerConfig, Token},
cache::{Artifact, Error as CacheError},
codegen::*,
memory::MemoryType,
Expand All @@ -36,7 +36,7 @@ use wasmparser::Type as WpType;
static BACKEND_ID: &str = "cranelift";

pub struct CraneliftModuleCodeGenerator {
isa: Box<dyn isa::TargetIsa>,
isa: Option<Box<dyn isa::TargetIsa>>,
signatures: Option<Arc<Map<SigIndex, FuncSig>>>,
pub clif_signatures: Map<SigIndex, ir::Signature>,
function_signatures: Option<Arc<Map<FuncIndex, SigIndex>>>,
Expand All @@ -47,9 +47,8 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
for CraneliftModuleCodeGenerator
{
fn new() -> Self {
let isa = get_isa();
CraneliftModuleCodeGenerator {
isa,
isa: None,
clif_signatures: Map::new(),
functions: vec![],
function_signatures: None,
Expand Down Expand Up @@ -100,7 +99,7 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
position: Position::default(),
func_env: FunctionEnvironment {
module_info: Arc::clone(&module_info),
target_config: self.isa.frontend_config().clone(),
target_config: self.isa.as_ref().unwrap().frontend_config().clone(),
clif_signatures: self.clif_signatures.clone(),
},
loc,
Expand Down Expand Up @@ -162,9 +161,9 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
}

let (func_resolver_builder, debug_metadata, handler_data) =
FuncResolverBuilder::new(&*self.isa, func_bodies, module_info)?;
FuncResolverBuilder::new(&**self.isa.as_ref().unwrap(), func_bodies, module_info)?;

let trampolines = Arc::new(Trampolines::new(&*self.isa, module_info));
let trampolines = Arc::new(Trampolines::new(&**self.isa.as_ref().unwrap(), module_info));

let signatures_empty = Map::new();
let signatures = if self.signatures.is_some() {
Expand All @@ -191,9 +190,19 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
))
}

fn feed_compiler_config(&mut self, config: &CompilerConfig) -> Result<(), CodegenError> {
self.isa = Some(get_isa(Some(config)));
Ok(())
}

fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError> {
self.signatures = Some(Arc::new(signatures));
let call_conv = self.isa.frontend_config().default_call_conv;
let call_conv = self
.isa
.as_ref()
.unwrap()
.frontend_config()
.default_call_conv;
for (_sig_idx, func_sig) in self.signatures.as_ref().unwrap().iter() {
self.clif_signatures
.push(convert_func_sig(func_sig, call_conv));
Expand Down Expand Up @@ -1302,7 +1311,10 @@ fn generate_signature(
}

fn pointer_type(mcg: &CraneliftModuleCodeGenerator) -> ir::Type {
ir::Type::int(u16::from(mcg.isa.frontend_config().pointer_bits())).unwrap()
ir::Type::int(u16::from(
mcg.isa.as_ref().unwrap().frontend_config().pointer_bits(),
))
.unwrap()
}

/// Declare local variables for the signature parameters that correspond to WebAssembly locals.
Expand Down
11 changes: 8 additions & 3 deletions lib/clif-backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ use cranelift_codegen::{
settings::{self, Configurable},
};
use target_lexicon::Triple;
use wasmer_runtime_core::{backend::CompilerConfig, codegen::SimpleStreamingCompilerGen};

#[macro_use]
extern crate serde_derive;

extern crate rayon;
extern crate serde;

fn get_isa() -> Box<dyn isa::TargetIsa> {
fn get_isa(config: Option<&CompilerConfig>) -> Box<dyn isa::TargetIsa> {
let flags = {
let mut builder = settings::builder();
builder.set("opt_level", "speed_and_size").unwrap();
Expand All @@ -48,6 +49,12 @@ fn get_isa() -> Box<dyn isa::TargetIsa> {
builder.set("enable_verifier", "false").unwrap();
}

if let Some(config) = config {
if config.nan_canonicalization {
builder.set("enable_nan_canonicalization", "true").unwrap();
}
}

let flags = settings::Flags::new(builder);
debug_assert_eq!(flags.opt_level(), settings::OptLevel::SpeedAndSize);
flags
Expand All @@ -58,8 +65,6 @@ fn get_isa() -> Box<dyn isa::TargetIsa> {
/// The current version of this crate
pub const VERSION: &str = env!("CARGO_PKG_VERSION");

use wasmer_runtime_core::codegen::SimpleStreamingCompilerGen;

/// Streaming compiler implementation for the Cranelift backed. Compiles web assembly binary into
/// machine code.
pub type CraneliftCompiler = SimpleStreamingCompilerGen<
Expand Down
6 changes: 2 additions & 4 deletions lib/clif-backend/src/trampoline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,7 @@ fn wasm_ty_to_clif(ty: Type) -> ir::types::Type {
}

fn generate_trampoline_signature() -> ir::Signature {
let isa = super::get_isa();
let call_convention = isa.default_call_conv();
let call_convention = super::get_isa(None).default_call_conv();
let mut sig = ir::Signature::new(call_convention);

let ptr_param = ir::AbiParam {
Expand All @@ -229,8 +228,7 @@ fn generate_trampoline_signature() -> ir::Signature {
}

fn generate_export_signature(func_sig: &FuncSig) -> ir::Signature {
let isa = super::get_isa();
let call_convention = isa.default_call_conv();
let call_convention = super::get_isa(None).default_call_conv();
let mut export_clif_sig = ir::Signature::new(call_convention);

let func_sig_iter = func_sig.params().iter().map(|wasm_ty| ir::AbiParam {
Expand Down
8 changes: 4 additions & 4 deletions lib/llvm-backend/src/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3701,7 +3701,7 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
.try_as_basic_value()
.left()
.unwrap();
state.push1_extra(res, i);
state.push1_extra(res, i | ExtraInfo::pending_f32_nan());
}
Operator::F64Trunc => {
let (v, i) = state.pop1_extra()?;
Expand All @@ -3714,7 +3714,7 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
.try_as_basic_value()
.left()
.unwrap();
state.push1_extra(res, i);
state.push1_extra(res, i | ExtraInfo::pending_f64_nan());
}
Operator::F32Nearest => {
let (v, i) = state.pop1_extra()?;
Expand All @@ -3727,7 +3727,7 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
.try_as_basic_value()
.left()
.unwrap();
state.push1_extra(res, i);
state.push1_extra(res, i | ExtraInfo::pending_f32_nan());
}
Operator::F64Nearest => {
let (v, i) = state.pop1_extra()?;
Expand All @@ -3740,7 +3740,7 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
.try_as_basic_value()
.left()
.unwrap();
state.push1_extra(res, i);
state.push1_extra(res, i | ExtraInfo::pending_f64_nan());
}
Operator::F32Abs => {
let (v, i) = state.pop1_extra()?;
Expand Down
4 changes: 4 additions & 0 deletions lib/runtime-core/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ pub struct CompilerConfig {
/// When enabled there can be a small amount of runtime performance overhead.
pub full_preemption: bool,

/// Always choose a unique bit representation for NaN.
/// Enabling this makes execution deterministic but increases runtime overhead.
pub nan_canonicalization: bool,

pub features: Features,

// Target info. Presently only supported by LLVM.
Expand Down
Loading