cretonne-faerie: add a translation mechanism for LibCalls (#321)
* cretonne-faerie: add a translation mechanism for LibCalls * cretonne-faerie: docs for libcall_names, rustfmt * cretonne-faerie: switch libcall naming to use a closure * travis: debug mypy version * travis: pin mypy to 0.521 mypy released 0.600 today and even with `--no-strict-optional` flag passed to it (in lib/codegen/meta/check.sh) it fails to infer the type of values that did not need type annotations in the past * faerie-backend: fix swapped nearbyint functions * cretonne-faerie: move boxing out of FaerieBuilder
This commit is contained in:
@@ -17,7 +17,7 @@ before_install:
|
|||||||
- wget https://storage.googleapis.com/wasm-llvm/builds/linux/26619/wasm-toolchain_0.1.26619_amd64.deb
|
- wget https://storage.googleapis.com/wasm-llvm/builds/linux/26619/wasm-toolchain_0.1.26619_amd64.deb
|
||||||
- sudo dpkg -i wasm-toolchain_0.1.26619_amd64.deb
|
- sudo dpkg -i wasm-toolchain_0.1.26619_amd64.deb
|
||||||
install:
|
install:
|
||||||
- pip3 install --user --upgrade mypy flake8
|
- pip3 install --user --upgrade mypy==0.521 flake8
|
||||||
- travis_wait ./check-rustfmt.sh --install
|
- travis_wait ./check-rustfmt.sh --install
|
||||||
script: ./test-all.sh
|
script: ./test-all.sh
|
||||||
cache:
|
cache:
|
||||||
|
|||||||
@@ -30,8 +30,10 @@ pub struct FaerieBuilder {
|
|||||||
format: container::Format,
|
format: container::Format,
|
||||||
faerie_target: faerie::Target,
|
faerie_target: faerie::Target,
|
||||||
collect_traps: FaerieTrapCollection,
|
collect_traps: FaerieTrapCollection,
|
||||||
|
libcall_names: Box<Fn(ir::LibCall) -> String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl FaerieBuilder {
|
impl FaerieBuilder {
|
||||||
/// Create a new `FaerieBuilder` using the given Cretonne target, that
|
/// Create a new `FaerieBuilder` using the given Cretonne target, that
|
||||||
/// can be passed to
|
/// can be passed to
|
||||||
@@ -41,11 +43,17 @@ impl FaerieBuilder {
|
|||||||
///
|
///
|
||||||
/// `collect_traps` setting determines whether trap information is collected in a
|
/// `collect_traps` setting determines whether trap information is collected in a
|
||||||
/// `FaerieTrapManifest` available in the `FaerieProduct`.
|
/// `FaerieTrapManifest` available in the `FaerieProduct`.
|
||||||
|
///
|
||||||
|
/// The `libcall_names` function provides a way to translate `cretonne_codegen`'s `ir::LibCall`
|
||||||
|
/// enum to symbols. LibCalls are inserted in the IR as part of the legalization for certain
|
||||||
|
/// floating point instructions, and for stack probes. If you don't know what to use for this
|
||||||
|
/// argument, use `FaerieBuilder::default_libcall_names()`.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
isa: Box<TargetIsa>,
|
isa: Box<TargetIsa>,
|
||||||
name: String,
|
name: String,
|
||||||
format: container::Format,
|
format: container::Format,
|
||||||
collect_traps: FaerieTrapCollection,
|
collect_traps: FaerieTrapCollection,
|
||||||
|
libcall_names: Box<Fn(ir::LibCall) -> String>,
|
||||||
) -> Result<Self, ModuleError> {
|
) -> Result<Self, ModuleError> {
|
||||||
if !isa.flags().is_pic() {
|
if !isa.flags().is_pic() {
|
||||||
return Err(ModuleError::Backend(
|
return Err(ModuleError::Backend(
|
||||||
@@ -59,16 +67,36 @@ impl FaerieBuilder {
|
|||||||
format,
|
format,
|
||||||
faerie_target,
|
faerie_target,
|
||||||
collect_traps,
|
collect_traps,
|
||||||
|
libcall_names,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Default names for `ir::LibCall`s. A function by this name is imported into the object as
|
||||||
|
/// part of the translation of a `ir::ExternalName::LibCall` variant. Calls to a LibCall should
|
||||||
|
/// only be inserted into the IR by the `cretonne_codegen` legalizer pass.
|
||||||
|
pub fn default_libcall_names() -> Box<Fn(ir::LibCall) -> String> {
|
||||||
|
Box::new(move |libcall| match libcall {
|
||||||
|
ir::LibCall::Probestack => "__cretonne_probestack".to_owned(),
|
||||||
|
ir::LibCall::CeilF32 => "ceilf".to_owned(),
|
||||||
|
ir::LibCall::CeilF64 => "ceil".to_owned(),
|
||||||
|
ir::LibCall::FloorF32 => "floorf".to_owned(),
|
||||||
|
ir::LibCall::FloorF64 => "floor".to_owned(),
|
||||||
|
ir::LibCall::TruncF32 => "truncf".to_owned(),
|
||||||
|
ir::LibCall::TruncF64 => "trunc".to_owned(),
|
||||||
|
ir::LibCall::NearestF32 => "nearbyintf".to_owned(),
|
||||||
|
ir::LibCall::NearestF64 => "nearbyint".to_owned(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// A `FaerieBackend` implements `Backend` and emits ".o" files using the `faerie` library.
|
/// A `FaerieBackend` implements `Backend` and emits ".o" files using the `faerie` library.
|
||||||
pub struct FaerieBackend {
|
pub struct FaerieBackend {
|
||||||
isa: Box<TargetIsa>,
|
isa: Box<TargetIsa>,
|
||||||
artifact: faerie::Artifact,
|
artifact: faerie::Artifact,
|
||||||
format: container::Format,
|
format: container::Format,
|
||||||
trap_manifest: Option<FaerieTrapManifest>,
|
trap_manifest: Option<FaerieTrapManifest>,
|
||||||
|
libcall_names: Box<Fn(ir::LibCall) -> String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FaerieCompiledFunction {}
|
pub struct FaerieCompiledFunction {}
|
||||||
@@ -100,6 +128,7 @@ impl Backend for FaerieBackend {
|
|||||||
FaerieTrapCollection::Enabled => Some(FaerieTrapManifest::new()),
|
FaerieTrapCollection::Enabled => Some(FaerieTrapManifest::new()),
|
||||||
FaerieTrapCollection::Disabled => None,
|
FaerieTrapCollection::Disabled => None,
|
||||||
},
|
},
|
||||||
|
libcall_names: builder.libcall_names,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,6 +165,7 @@ impl Backend for FaerieBackend {
|
|||||||
artifact: &mut self.artifact,
|
artifact: &mut self.artifact,
|
||||||
name,
|
name,
|
||||||
namespace,
|
namespace,
|
||||||
|
libcall_names: &self.libcall_names,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(ref mut trap_manifest) = self.trap_manifest {
|
if let Some(ref mut trap_manifest) = self.trap_manifest {
|
||||||
@@ -334,11 +364,13 @@ fn translate_data_linkage(linkage: Linkage, writable: bool) -> faerie::Decl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct FaerieRelocSink<'a> {
|
struct FaerieRelocSink<'a> {
|
||||||
format: container::Format,
|
format: container::Format,
|
||||||
artifact: &'a mut faerie::Artifact,
|
artifact: &'a mut faerie::Artifact,
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
namespace: &'a ModuleNamespace<'a, FaerieBackend>,
|
namespace: &'a ModuleNamespace<'a, FaerieBackend>,
|
||||||
|
libcall_names: &'a Box<Fn(ir::LibCall) -> String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RelocSink for FaerieRelocSink<'a> {
|
impl<'a> RelocSink for FaerieRelocSink<'a> {
|
||||||
@@ -353,10 +385,22 @@ impl<'a> RelocSink for FaerieRelocSink<'a> {
|
|||||||
name: &ir::ExternalName,
|
name: &ir::ExternalName,
|
||||||
addend: Addend,
|
addend: Addend,
|
||||||
) {
|
) {
|
||||||
let ref_name = if self.namespace.is_function(name) {
|
let ref_name: String = match name {
|
||||||
&self.namespace.get_function_decl(name).name
|
&ir::ExternalName::User { .. } => {
|
||||||
} else {
|
if self.namespace.is_function(name) {
|
||||||
&self.namespace.get_data_decl(name).name
|
self.namespace.get_function_decl(name).name.clone()
|
||||||
|
} else {
|
||||||
|
self.namespace.get_data_decl(name).name.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&ir::ExternalName::LibCall(ref libcall) => {
|
||||||
|
let sym = (self.libcall_names)(*libcall);
|
||||||
|
self.artifact
|
||||||
|
.declare(sym.clone(), faerie::Decl::FunctionImport)
|
||||||
|
.expect("faerie declaration of libcall");
|
||||||
|
sym
|
||||||
|
}
|
||||||
|
_ => panic!("invalid ExternalName {}", name),
|
||||||
};
|
};
|
||||||
let addend_i32 = addend as i32;
|
let addend_i32 = addend as i32;
|
||||||
debug_assert!(i64::from(addend_i32) == addend);
|
debug_assert!(i64::from(addend_i32) == addend);
|
||||||
@@ -365,7 +409,7 @@ impl<'a> RelocSink for FaerieRelocSink<'a> {
|
|||||||
.link_with(
|
.link_with(
|
||||||
faerie::Link {
|
faerie::Link {
|
||||||
from: self.name,
|
from: self.name,
|
||||||
to: ref_name,
|
to: &ref_name,
|
||||||
at: offset as usize,
|
at: offset as usize,
|
||||||
},
|
},
|
||||||
faerie::RelocOverride {
|
faerie::RelocOverride {
|
||||||
|
|||||||
Reference in New Issue
Block a user