Remove code offsets from Function (#3412)
* Remove code offsets from Function * Remove reloc_jt and fix wasmtime-cranelift
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
//! `CodeSink::put*` methods, so the performance impact of the virtual callbacks is less severe.
|
||||
use super::{Addend, CodeInfo, CodeOffset, CodeSink, Reloc};
|
||||
use crate::binemit::stack_map::StackMap;
|
||||
use crate::ir::{ConstantOffset, ExternalName, JumpTable, Opcode, SourceLoc, TrapCode};
|
||||
use crate::ir::{ConstantOffset, ExternalName, Opcode, SourceLoc, TrapCode};
|
||||
use core::ptr::write_unaligned;
|
||||
|
||||
/// A `CodeSink` that writes binary machine code directly into memory.
|
||||
@@ -82,9 +82,6 @@ pub trait RelocSink {
|
||||
/// Add a relocation referencing a constant.
|
||||
fn reloc_constant(&mut self, _: CodeOffset, _: Reloc, _: ConstantOffset);
|
||||
|
||||
/// Add a relocation referencing a jump table.
|
||||
fn reloc_jt(&mut self, _: CodeOffset, _: Reloc, _: JumpTable);
|
||||
|
||||
/// Track a call site whose return address is the given CodeOffset, for the given opcode. Does
|
||||
/// nothing in general, only useful for certain embedders (SpiderMonkey).
|
||||
fn add_call_site(&mut self, _: Opcode, _: CodeOffset, _: SourceLoc) {}
|
||||
@@ -146,11 +143,6 @@ impl<'a> CodeSink for MemoryCodeSink<'a> {
|
||||
self.relocs.reloc_constant(ofs, rel, constant_offset);
|
||||
}
|
||||
|
||||
fn reloc_jt(&mut self, rel: Reloc, jt: JumpTable) {
|
||||
let ofs = self.offset();
|
||||
self.relocs.reloc_jt(ofs, rel, jt);
|
||||
}
|
||||
|
||||
fn trap(&mut self, code: TrapCode, srcloc: SourceLoc) {
|
||||
let ofs = self.offset();
|
||||
self.traps.trap(ofs, srcloc, code);
|
||||
@@ -195,7 +187,6 @@ impl RelocSink for NullRelocSink {
|
||||
) {
|
||||
}
|
||||
fn reloc_constant(&mut self, _: CodeOffset, _: Reloc, _: ConstantOffset) {}
|
||||
fn reloc_jt(&mut self, _: CodeOffset, _: Reloc, _: JumpTable) {}
|
||||
}
|
||||
|
||||
/// A `TrapSink` implementation that does nothing, which is convenient when
|
||||
|
||||
@@ -11,10 +11,7 @@ pub use self::memorysink::{
|
||||
TrapSink,
|
||||
};
|
||||
pub use self::stack_map::StackMap;
|
||||
use crate::ir::{
|
||||
ConstantOffset, ExternalName, Function, Inst, JumpTable, Opcode, SourceLoc, TrapCode,
|
||||
};
|
||||
use crate::isa::TargetIsa;
|
||||
use crate::ir::{ConstantOffset, ExternalName, Opcode, SourceLoc, TrapCode};
|
||||
use core::fmt;
|
||||
#[cfg(feature = "enable-serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -153,9 +150,6 @@ pub trait CodeSink {
|
||||
/// Add a relocation referencing a constant.
|
||||
fn reloc_constant(&mut self, _: Reloc, _: ConstantOffset);
|
||||
|
||||
/// Add a relocation referencing a jump table.
|
||||
fn reloc_jt(&mut self, _: Reloc, _: JumpTable);
|
||||
|
||||
/// Add trap information for the current offset.
|
||||
fn trap(&mut self, _: TrapCode, _: SourceLoc);
|
||||
|
||||
@@ -173,42 +167,3 @@ pub trait CodeSink {
|
||||
// Default implementation doesn't need to do anything.
|
||||
}
|
||||
}
|
||||
|
||||
/// Emit a function to `sink`, given an instruction emitter function.
|
||||
///
|
||||
/// This function is called from the `TargetIsa::emit_function()` implementations with the
|
||||
/// appropriate instruction emitter.
|
||||
pub fn emit_function<CS, EI>(func: &Function, emit_inst: EI, sink: &mut CS, isa: &dyn TargetIsa)
|
||||
where
|
||||
CS: CodeSink,
|
||||
EI: Fn(&Function, Inst, &mut CS, &dyn TargetIsa),
|
||||
{
|
||||
for block in func.layout.blocks() {
|
||||
debug_assert_eq!(func.offsets[block], sink.offset());
|
||||
for inst in func.layout.block_insts(block) {
|
||||
emit_inst(func, inst, sink, isa);
|
||||
}
|
||||
}
|
||||
|
||||
sink.begin_jumptables();
|
||||
|
||||
// Output jump tables.
|
||||
for (jt, jt_data) in func.jump_tables.iter() {
|
||||
let jt_offset = func.jt_offsets[jt];
|
||||
for block in jt_data.iter() {
|
||||
let rel_offset: i32 = func.offsets[*block] as i32 - jt_offset as i32;
|
||||
sink.put4(rel_offset as u32)
|
||||
}
|
||||
}
|
||||
|
||||
sink.begin_rodata();
|
||||
|
||||
// Output constants.
|
||||
for (_, constant_data) in func.dfg.constants.iter() {
|
||||
for byte in constant_data.iter() {
|
||||
sink.put1(*byte)
|
||||
}
|
||||
}
|
||||
|
||||
sink.end_codegen();
|
||||
}
|
||||
|
||||
@@ -5,20 +5,19 @@
|
||||
|
||||
use crate::entity::{PrimaryMap, SecondaryMap};
|
||||
use crate::ir;
|
||||
use crate::ir::JumpTables;
|
||||
use crate::ir::{
|
||||
instructions::BranchInfo, Block, ExtFuncData, FuncRef, GlobalValue, GlobalValueData, Heap,
|
||||
HeapData, Inst, InstructionData, JumpTable, JumpTableData, Opcode, SigRef, StackSlot,
|
||||
StackSlotData, Table, TableData,
|
||||
};
|
||||
use crate::ir::{BlockOffsets, SourceLocs, StackSlots};
|
||||
use crate::ir::{DataFlowGraph, ExternalName, Layout, Signature};
|
||||
use crate::ir::{JumpTableOffsets, JumpTables};
|
||||
use crate::ir::{SourceLocs, StackSlots};
|
||||
use crate::isa::CallConv;
|
||||
use crate::value_label::ValueLabelsRanges;
|
||||
use crate::write::write_function;
|
||||
#[cfg(feature = "enable-serde")]
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use core::fmt;
|
||||
|
||||
#[cfg(feature = "enable-serde")]
|
||||
@@ -100,32 +99,12 @@ pub struct Function {
|
||||
/// Layout of blocks and instructions in the function body.
|
||||
pub layout: Layout,
|
||||
|
||||
/// Code offsets of the block headers.
|
||||
///
|
||||
/// This information is only transiently available after the `binemit::relax_branches` function
|
||||
/// computes it, and it can easily be recomputed by calling that function. It is not included
|
||||
/// in the textual IR format.
|
||||
pub offsets: BlockOffsets,
|
||||
|
||||
/// Code offsets of Jump Table headers.
|
||||
pub jt_offsets: JumpTableOffsets,
|
||||
|
||||
/// Source locations.
|
||||
///
|
||||
/// Track the original source location for each instruction. The source locations are not
|
||||
/// interpreted by Cranelift, only preserved.
|
||||
pub srclocs: SourceLocs,
|
||||
|
||||
/// Instruction that marks the end (inclusive) of the function's prologue.
|
||||
///
|
||||
/// This is used for some ABIs to generate unwind information.
|
||||
pub prologue_end: Option<Inst>,
|
||||
|
||||
/// The instructions that mark the start (inclusive) of an epilogue in the function.
|
||||
///
|
||||
/// This is used for some ABIs to generate unwind information.
|
||||
pub epilogues_start: Vec<(Inst, Block)>,
|
||||
|
||||
/// An optional global value which represents an expression evaluating to
|
||||
/// the stack limit for this function. This `GlobalValue` will be
|
||||
/// interpreted in the prologue, if necessary, to insert a stack check to
|
||||
@@ -148,11 +127,7 @@ impl Function {
|
||||
jump_tables: PrimaryMap::new(),
|
||||
dfg: DataFlowGraph::new(),
|
||||
layout: Layout::new(),
|
||||
offsets: SecondaryMap::new(),
|
||||
jt_offsets: SecondaryMap::new(),
|
||||
srclocs: SecondaryMap::new(),
|
||||
prologue_end: None,
|
||||
epilogues_start: Vec::new(),
|
||||
stack_limit: None,
|
||||
}
|
||||
}
|
||||
@@ -167,11 +142,7 @@ impl Function {
|
||||
self.jump_tables.clear();
|
||||
self.dfg.clear();
|
||||
self.layout.clear();
|
||||
self.offsets.clear();
|
||||
self.jt_offsets.clear();
|
||||
self.srclocs.clear();
|
||||
self.prologue_end = None;
|
||||
self.epilogues_start.clear();
|
||||
self.stack_limit = None;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,18 +59,11 @@ pub use crate::ir::types::Type;
|
||||
pub use crate::value_label::LabelValueLoc;
|
||||
pub use cranelift_codegen_shared::condcodes;
|
||||
|
||||
use crate::binemit;
|
||||
use crate::entity::{entity_impl, PrimaryMap, SecondaryMap};
|
||||
|
||||
/// Map of jump tables.
|
||||
pub type JumpTables = PrimaryMap<JumpTable, JumpTableData>;
|
||||
|
||||
/// Code offsets for blocks.
|
||||
pub type BlockOffsets = SecondaryMap<Block, binemit::CodeOffset>;
|
||||
|
||||
/// Code offsets for Jump Tables.
|
||||
pub type JumpTableOffsets = SecondaryMap<JumpTable, binemit::CodeOffset>;
|
||||
|
||||
/// Source locations for instructions.
|
||||
pub type SourceLocs = SecondaryMap<Inst, SourceLoc>;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use crate::binemit::{Addend, CodeOffset, CodeSink, Reloc};
|
||||
use crate::ir::{ConstantOffset, ExternalName, JumpTable, Opcode, SourceLoc, TrapCode};
|
||||
use crate::ir::{ConstantOffset, ExternalName, Opcode, SourceLoc, TrapCode};
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use std::string::String;
|
||||
@@ -68,8 +68,6 @@ impl CodeSink for TestCodeSink {
|
||||
|
||||
fn reloc_constant(&mut self, _rel: Reloc, _constant_offset: ConstantOffset) {}
|
||||
|
||||
fn reloc_jt(&mut self, _rel: Reloc, _jt: JumpTable) {}
|
||||
|
||||
fn trap(&mut self, _code: TrapCode, _srcloc: SourceLoc) {}
|
||||
|
||||
fn begin_jumptables(&mut self) {}
|
||||
|
||||
@@ -1641,7 +1641,7 @@ impl<I: VCodeInst> TextSectionBuilder for MachTextSectionBuilder<I> {
|
||||
#[cfg(all(test, feature = "arm64"))]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::ir::{ConstantOffset, JumpTable};
|
||||
use crate::ir::ConstantOffset;
|
||||
use crate::isa::aarch64::inst::xreg;
|
||||
use crate::isa::aarch64::inst::{BranchTarget, CondBrKind, EmitInfo, Inst};
|
||||
use crate::machinst::MachInstEmit;
|
||||
@@ -2068,7 +2068,6 @@ mod test {
|
||||
self.relocs.push((self.offset, r));
|
||||
}
|
||||
fn reloc_constant(&mut self, _: Reloc, _: ConstantOffset) {}
|
||||
fn reloc_jt(&mut self, _: Reloc, _: JumpTable) {}
|
||||
fn trap(&mut self, t: TrapCode, _: SourceLoc) {
|
||||
self.traps.push((self.offset, t));
|
||||
}
|
||||
|
||||
@@ -96,7 +96,6 @@ impl binemit::CodeSink for SizeSink {
|
||||
) {
|
||||
}
|
||||
fn reloc_constant(&mut self, _: binemit::Reloc, _: ir::ConstantOffset) {}
|
||||
fn reloc_jt(&mut self, _reloc: binemit::Reloc, _jt: ir::JumpTable) {}
|
||||
fn trap(&mut self, _code: ir::TrapCode, _srcloc: ir::SourceLoc) {}
|
||||
fn begin_jumptables(&mut self) {}
|
||||
fn begin_rodata(&mut self) {}
|
||||
|
||||
@@ -894,18 +894,6 @@ impl RelocSink for JITRelocSink {
|
||||
});
|
||||
}
|
||||
|
||||
fn reloc_jt(&mut self, _offset: CodeOffset, reloc: Reloc, _jt: ir::JumpTable) {
|
||||
match reloc {
|
||||
Reloc::X86PCRelRodata4 => {
|
||||
// Not necessary to record this unless we are going to split apart code and its
|
||||
// jumptbl/rodata.
|
||||
}
|
||||
_ => {
|
||||
panic!("Unhandled reloc");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn reloc_constant(&mut self, _offset: CodeOffset, reloc: Reloc, _constant: ir::ConstantOffset) {
|
||||
match reloc {
|
||||
Reloc::X86PCRelRodata4 => {
|
||||
|
||||
@@ -735,18 +735,6 @@ impl RelocSink for ObjectRelocSink {
|
||||
})
|
||||
}
|
||||
|
||||
fn reloc_jt(&mut self, _offset: CodeOffset, reloc: Reloc, _jt: ir::JumpTable) {
|
||||
match reloc {
|
||||
Reloc::X86PCRelRodata4 => {
|
||||
// Not necessary to record this unless we are going to split apart code and its
|
||||
// jumptbl/rodata.
|
||||
}
|
||||
_ => {
|
||||
panic!("Unhandled reloc");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn reloc_constant(&mut self, _offset: CodeOffset, reloc: Reloc, _jt: ir::ConstantOffset) {
|
||||
match reloc {
|
||||
Reloc::X86PCRelRodata4 => {
|
||||
|
||||
@@ -37,12 +37,6 @@ impl binemit::RelocSink for PrintRelocs {
|
||||
}
|
||||
}
|
||||
|
||||
fn reloc_jt(&mut self, where_: binemit::CodeOffset, r: binemit::Reloc, jt: ir::JumpTable) {
|
||||
if self.flag_print {
|
||||
writeln!(&mut self.text, "reloc_jt: {} {} at {}", r, jt, where_).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn reloc_constant(
|
||||
&mut self,
|
||||
code_offset: binemit::CodeOffset,
|
||||
|
||||
@@ -197,7 +197,6 @@ impl wasmtime_environ::Compiler for Compiler {
|
||||
let length = u32::try_from(code_buf.len()).unwrap();
|
||||
Ok(Box::new(CompiledFunction {
|
||||
body: code_buf,
|
||||
jt_offsets: context.func.jt_offsets,
|
||||
relocations: reloc_sink.func_relocs,
|
||||
value_labels_ranges: ranges.unwrap_or(Default::default()),
|
||||
stack_slots: context.func.stack_slots,
|
||||
@@ -540,7 +539,6 @@ impl Compiler {
|
||||
|
||||
Ok(CompiledFunction {
|
||||
body: code_buf,
|
||||
jt_offsets: context.func.jt_offsets,
|
||||
unwind_info,
|
||||
relocations: reloc_sink.relocs,
|
||||
stack_slots: Default::default(),
|
||||
@@ -655,15 +653,6 @@ impl binemit::RelocSink for RelocSink {
|
||||
// Do nothing for now: cranelift emits constant data after the function code and also emits
|
||||
// function code with correct relative offsets to the constant data.
|
||||
}
|
||||
|
||||
fn reloc_jt(&mut self, offset: binemit::CodeOffset, reloc: binemit::Reloc, jt: ir::JumpTable) {
|
||||
self.func_relocs.push(Relocation {
|
||||
reloc,
|
||||
reloc_target: RelocationTarget::JumpTable(jt),
|
||||
offset,
|
||||
addend: 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl RelocSink {
|
||||
@@ -783,12 +772,4 @@ impl binemit::RelocSink for TrampolineRelocSink {
|
||||
) {
|
||||
panic!("trampoline compilation should not produce constant relocs");
|
||||
}
|
||||
fn reloc_jt(
|
||||
&mut self,
|
||||
_offset: binemit::CodeOffset,
|
||||
_reloc: binemit::Reloc,
|
||||
_jt: ir::JumpTable,
|
||||
) {
|
||||
panic!("trampoline compilation should not produce jump table relocs");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,9 +114,6 @@ pub struct CompiledFunction {
|
||||
/// The machine code for this function.
|
||||
body: Vec<u8>,
|
||||
|
||||
/// The jump tables offsets (in the body).
|
||||
jt_offsets: ir::JumpTableOffsets,
|
||||
|
||||
/// The unwind information.
|
||||
unwind_info: Option<UnwindInfo>,
|
||||
|
||||
@@ -181,8 +178,6 @@ enum RelocationTarget {
|
||||
UserFunc(FuncIndex),
|
||||
/// A compiler-generated libcall.
|
||||
LibCall(ir::LibCall),
|
||||
/// Jump table index.
|
||||
JumpTable(ir::JumpTable),
|
||||
}
|
||||
|
||||
/// Creates a new cranelift `Signature` with no wasm params/results for the
|
||||
|
||||
@@ -305,7 +305,6 @@ impl<'a> ObjectBuilder<'a> {
|
||||
// seem too common though so aren't necessarily that important
|
||||
// to optimize.
|
||||
RelocationTarget::LibCall(call) => (self.libcalls[&call], 0),
|
||||
RelocationTarget::JumpTable(jt) => (symbol_id, func.jt_offsets[jt]),
|
||||
};
|
||||
let (kind, encoding, size) = match r.reloc {
|
||||
Reloc::Abs4 => (RelocationKind::Absolute, RelocationEncoding::Generic, 32),
|
||||
|
||||
Reference in New Issue
Block a user