Transform ranges and simple expressions (#63)

This commit is contained in:
Yury Delendik
2019-08-08 22:44:45 -05:00
committed by Dan Gohman
parent 36b4ff8031
commit 4f04d7d873
20 changed files with 2701 additions and 867 deletions

View File

@@ -27,6 +27,12 @@ pub struct FunctionAddressMap {
/// The array is sorted by the InstructionAddressMap::code_offset field.
pub instructions: Vec<InstructionAddressMap>,
/// Function start source location (normally declaration).
pub start_srcloc: ir::SourceLoc,
/// Function end source location.
pub end_srcloc: ir::SourceLoc,
/// Generated function body offset if applicable, otherwise 0.
pub body_offset: usize,
@@ -36,3 +42,18 @@ pub struct FunctionAddressMap {
/// Module functions addresses mappings.
pub type ModuleAddressMap = PrimaryMap<DefinedFuncIndex, FunctionAddressMap>;
/// Value ranges for functions.
pub type ValueLabelsRanges = PrimaryMap<DefinedFuncIndex, cranelift_codegen::ValueLabelsRanges>;
/// Stack slots for functions.
pub type StackSlots = PrimaryMap<DefinedFuncIndex, ir::StackSlots>;
/// Module `vmctx` related info.
pub struct ModuleVmctxInfo {
/// The memory definition offset in the VMContext structure.
pub memory_offset: i64,
/// The functions stack slots.
pub stack_slots: StackSlots,
}

View File

@@ -1,4 +1,4 @@
use crate::address_map::ModuleAddressMap;
use crate::address_map::{ModuleAddressMap, ValueLabelsRanges};
use crate::compilation::{CodeAndJTOffsets, Compilation, Relocations};
use crate::module::Module;
use crate::module_environ::FunctionBodyData;
@@ -102,9 +102,17 @@ pub struct ModuleCacheData {
compilation: Compilation,
relocations: Relocations,
address_transforms: ModuleAddressMap,
value_ranges: ValueLabelsRanges,
stack_slots: PrimaryMap<DefinedFuncIndex, ir::StackSlots>,
}
type ModuleCacheDataTupleType = (Compilation, Relocations, ModuleAddressMap);
type ModuleCacheDataTupleType = (
Compilation,
Relocations,
ModuleAddressMap,
ValueLabelsRanges,
PrimaryMap<DefinedFuncIndex, ir::StackSlots>,
);
struct Sha256Hasher(Sha256);
@@ -225,11 +233,19 @@ impl ModuleCacheData {
compilation: data.0,
relocations: data.1,
address_transforms: data.2,
value_ranges: data.3,
stack_slots: data.4,
}
}
pub fn to_tuple(self) -> ModuleCacheDataTupleType {
(self.compilation, self.relocations, self.address_transforms)
(
self.compilation,
self.relocations,
self.address_transforms,
self.value_ranges,
self.stack_slots,
)
}
}

View File

@@ -1,7 +1,7 @@
//! A `Compilation` contains the compiled function bodies for a WebAssembly
//! module.
use crate::address_map::ModuleAddressMap;
use crate::address_map::{ModuleAddressMap, ValueLabelsRanges};
use crate::module;
use crate::module_environ::FunctionBodyData;
use cranelift_codegen::{binemit, ir, isa, CodegenError};
@@ -149,5 +149,14 @@ pub trait Compiler {
function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>,
isa: &dyn isa::TargetIsa,
generate_debug_info: bool,
) -> Result<(Compilation, Relocations, ModuleAddressMap), CompileError>;
) -> Result<
(
Compilation,
Relocations,
ModuleAddressMap,
ValueLabelsRanges,
PrimaryMap<DefinedFuncIndex, ir::StackSlots>,
),
CompileError,
>;
}

View File

@@ -1,6 +1,8 @@
//! Support for compiling with Cranelift.
use crate::address_map::{FunctionAddressMap, InstructionAddressMap, ModuleAddressMap};
use crate::address_map::{
FunctionAddressMap, InstructionAddressMap, ModuleAddressMap, ValueLabelsRanges,
};
use crate::cache::{ModuleCacheData, ModuleCacheEntry};
use crate::compilation::{
CodeAndJTOffsets, Compilation, CompileError, Relocation, RelocationTarget, Relocations,
@@ -90,8 +92,13 @@ impl RelocSink {
}
}
fn get_address_transform(context: &Context, isa: &isa::TargetIsa) -> Vec<InstructionAddressMap> {
let mut result = Vec::new();
fn get_function_address_map<'data>(
context: &Context,
data: &FunctionBodyData<'data>,
body_len: usize,
isa: &isa::TargetIsa,
) -> FunctionAddressMap {
let mut instructions = Vec::new();
let func = &context.func;
let mut ebbs = func.layout.ebbs().collect::<Vec<_>>();
@@ -101,14 +108,27 @@ fn get_address_transform(context: &Context, isa: &isa::TargetIsa) -> Vec<Instruc
for ebb in ebbs {
for (offset, inst, size) in func.inst_offsets(ebb, &encinfo) {
let srcloc = func.srclocs[inst];
result.push(InstructionAddressMap {
instructions.push(InstructionAddressMap {
srcloc,
code_offset: offset as usize,
code_len: size as usize,
});
}
}
result
// Generate artificial srcloc for function start/end to identify boundary
// within module. Similar to FuncTranslator::cur_srcloc(): it will wrap around
// if byte code is larger than 4 GB.
let start_srcloc = ir::SourceLoc::new(data.module_offset as u32);
let end_srcloc = ir::SourceLoc::new((data.module_offset + data.data.len()) as u32);
FunctionAddressMap {
instructions,
start_srcloc,
end_srcloc,
body_offset: 0,
body_len,
}
}
/// A compiler that compiles a WebAssembly module with Cranelift, translating the Wasm to Cranelift IR,
@@ -123,7 +143,16 @@ impl crate::compilation::Compiler for Cranelift {
function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>,
isa: &dyn isa::TargetIsa,
generate_debug_info: bool,
) -> Result<(Compilation, Relocations, ModuleAddressMap), CompileError> {
) -> Result<
(
Compilation,
Relocations,
ModuleAddressMap,
ValueLabelsRanges,
PrimaryMap<DefinedFuncIndex, ir::StackSlots>,
),
CompileError,
> {
let cache_entry = ModuleCacheEntry::new(
module,
&function_body_inputs,
@@ -138,6 +167,8 @@ impl crate::compilation::Compiler for Cranelift {
let mut functions = PrimaryMap::with_capacity(function_body_inputs.len());
let mut relocations = PrimaryMap::with_capacity(function_body_inputs.len());
let mut address_transforms = PrimaryMap::with_capacity(function_body_inputs.len());
let mut value_ranges = PrimaryMap::with_capacity(function_body_inputs.len());
let mut stack_slots = PrimaryMap::with_capacity(function_body_inputs.len());
function_body_inputs
.into_iter()
@@ -149,6 +180,9 @@ impl crate::compilation::Compiler for Cranelift {
context.func.name = get_func_name(func_index);
context.func.signature =
module.signatures[module.functions[func_index]].clone();
if generate_debug_info {
context.func.collect_debug_info();
}
let mut trans = FuncTranslator::new();
trans
@@ -171,36 +205,48 @@ impl crate::compilation::Compiler for Cranelift {
let address_transform = if generate_debug_info {
let body_len = code_buf.len();
let at = get_address_transform(&context, isa);
Some(FunctionAddressMap {
instructions: at,
body_offset: 0,
body_len,
})
Some(get_function_address_map(&context, input, body_len, isa))
} else {
None
};
let ranges = if generate_debug_info {
Some(
context
.build_value_labels_ranges(isa)
.map_err(CompileError::Codegen)?,
)
} else {
None
};
let stack_slots = context.func.stack_slots.clone();
Ok((
code_buf,
jt_offsets,
reloc_sink.func_relocs,
address_transform,
ranges,
stack_slots,
))
})
.collect::<Result<Vec<_>, CompileError>>()?
.into_iter()
.for_each(|(function, func_jt_offsets, relocs, address_transform)| {
functions.push(CodeAndJTOffsets {
body: function,
jt_offsets: func_jt_offsets,
});
relocations.push(relocs);
if let Some(address_transform) = address_transform {
address_transforms.push(address_transform);
}
});
.for_each(
|(function, func_jt_offsets, relocs, address_transform, ranges, sss)| {
functions.push(CodeAndJTOffsets {
body: function,
jt_offsets: func_jt_offsets,
});
relocations.push(relocs);
if let Some(address_transform) = address_transform {
address_transforms.push(address_transform);
}
value_ranges.push(ranges.unwrap_or(std::collections::HashMap::new()));
stack_slots.push(sss);
},
);
// TODO: Reorganize where we create the Vec for the resolved imports.
@@ -208,6 +254,8 @@ impl crate::compilation::Compiler for Cranelift {
Compilation::new(functions),
relocations,
address_transforms,
value_ranges,
stack_slots,
));
cache_entry.update_data(&data);
data

View File

@@ -51,7 +51,9 @@ pub mod cranelift;
#[cfg(feature = "lightbeam")]
pub mod lightbeam;
pub use crate::address_map::{FunctionAddressMap, InstructionAddressMap, ModuleAddressMap};
pub use crate::address_map::{
FunctionAddressMap, InstructionAddressMap, ModuleAddressMap, ModuleVmctxInfo, ValueLabelsRanges,
};
pub use crate::cache::conf as cache_conf;
pub use crate::compilation::{
Compilation, CompileError, Compiler, Relocation, RelocationTarget, Relocations,