Compress in-memory representation of FunctionAddressMap (#2321)
This commit compresses `FunctionAddressMap` by performing a simple coalescing of adjacent `InstructionAddressMap` descriptors if they describe the same source location. This is intended to handle the common case where a sequene of machine instructions describes a high-level wasm instruction. For the module on #2318 this reduces the cache entry size from 306MB to 161MB.
This commit is contained in:
@@ -233,18 +233,16 @@ fn get_function_address_map<'data>(
|
|||||||
body_len: usize,
|
body_len: usize,
|
||||||
isa: &dyn isa::TargetIsa,
|
isa: &dyn isa::TargetIsa,
|
||||||
) -> FunctionAddressMap {
|
) -> FunctionAddressMap {
|
||||||
let mut instructions = Vec::new();
|
let instructions = if let Some(ref mcr) = &context.mach_compile_result {
|
||||||
|
|
||||||
if let Some(ref mcr) = &context.mach_compile_result {
|
|
||||||
// New-style backend: we have a `MachCompileResult` that will give us `MachSrcLoc` mapping
|
// New-style backend: we have a `MachCompileResult` that will give us `MachSrcLoc` mapping
|
||||||
// tuples.
|
// tuples.
|
||||||
for &MachSrcLoc { start, end, loc } in mcr.buffer.get_srclocs_sorted() {
|
collect_address_maps(mcr.buffer.get_srclocs_sorted().into_iter().map(
|
||||||
instructions.push(InstructionAddressMap {
|
|&MachSrcLoc { start, end, loc }| InstructionAddressMap {
|
||||||
srcloc: loc,
|
srcloc: loc,
|
||||||
code_offset: start as usize,
|
code_offset: start as usize,
|
||||||
code_len: (end - start) as usize,
|
code_len: (end - start) as usize,
|
||||||
});
|
},
|
||||||
}
|
))
|
||||||
} else {
|
} else {
|
||||||
// Old-style backend: we need to traverse the instruction/encoding info in the function.
|
// Old-style backend: we need to traverse the instruction/encoding info in the function.
|
||||||
let func = &context.func;
|
let func = &context.func;
|
||||||
@@ -252,17 +250,17 @@ fn get_function_address_map<'data>(
|
|||||||
blocks.sort_by_key(|block| func.offsets[*block]); // Ensure inst offsets always increase
|
blocks.sort_by_key(|block| func.offsets[*block]); // Ensure inst offsets always increase
|
||||||
|
|
||||||
let encinfo = isa.encoding_info();
|
let encinfo = isa.encoding_info();
|
||||||
for block in blocks {
|
collect_address_maps(
|
||||||
for (offset, inst, size) in func.inst_offsets(block, &encinfo) {
|
blocks
|
||||||
let srcloc = func.srclocs[inst];
|
.into_iter()
|
||||||
instructions.push(InstructionAddressMap {
|
.flat_map(|block| func.inst_offsets(block, &encinfo))
|
||||||
srcloc,
|
.map(|(offset, inst, size)| InstructionAddressMap {
|
||||||
|
srcloc: func.srclocs[inst],
|
||||||
code_offset: offset as usize,
|
code_offset: offset as usize,
|
||||||
code_len: size as usize,
|
code_len: size as usize,
|
||||||
});
|
}),
|
||||||
}
|
)
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// Generate artificial srcloc for function start/end to identify boundary
|
// Generate artificial srcloc for function start/end to identify boundary
|
||||||
// within module. Similar to FuncTranslator::cur_srcloc(): it will wrap around
|
// within module. Similar to FuncTranslator::cur_srcloc(): it will wrap around
|
||||||
@@ -282,6 +280,30 @@ fn get_function_address_map<'data>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Collects an iterator of `InstructionAddressMap` into a `Vec` for insertion
|
||||||
|
// into a `FunctionAddressMap`. This will automatically coalesce adjacent
|
||||||
|
// instructions which map to the same original source position.
|
||||||
|
fn collect_address_maps(
|
||||||
|
iter: impl IntoIterator<Item = InstructionAddressMap>,
|
||||||
|
) -> Vec<InstructionAddressMap> {
|
||||||
|
let mut iter = iter.into_iter();
|
||||||
|
let mut cur = match iter.next() {
|
||||||
|
Some(i) => i,
|
||||||
|
None => return Vec::new(),
|
||||||
|
};
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
for item in iter {
|
||||||
|
if cur.code_offset + cur.code_len == item.code_offset && item.srcloc == cur.srcloc {
|
||||||
|
cur.code_len += item.code_len;
|
||||||
|
} else {
|
||||||
|
ret.push(cur);
|
||||||
|
cur = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret.push(cur);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/// A compiler that compiles a WebAssembly module with Cranelift, translating the Wasm to Cranelift IR,
|
/// A compiler that compiles a WebAssembly module with Cranelift, translating the Wasm to Cranelift IR,
|
||||||
/// optimizing it and then translating to assembly.
|
/// optimizing it and then translating to assembly.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|||||||
Reference in New Issue
Block a user