[codegen] Allow using the pinned register as the heap base via a setting;
This commit is contained in:
@@ -95,6 +95,21 @@ pub fn define() -> SettingGroup {
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
settings.add_bool(
|
||||||
|
"use_pinned_reg_as_heap_base",
|
||||||
|
r#"Use the pinned register as the heap base.
|
||||||
|
|
||||||
|
Enabling this requires the enable_pinned_reg setting to be set to true. It enables a custom
|
||||||
|
legalization of the `heap_addr` instruction so it will use the pinned register as the heap
|
||||||
|
base, instead of fetching it from a global value.
|
||||||
|
|
||||||
|
Warning! Enabling this means that the pinned register *must* be maintained to contain the
|
||||||
|
heap base address at all times, during the lifetime of a function. Using the pinned
|
||||||
|
register for other purposes when this is set is very likely to cause crashes.
|
||||||
|
"#,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
settings.add_bool("enable_simd", "Enable the use of SIMD instructions.", false);
|
settings.add_bool("enable_simd", "Enable the use of SIMD instructions.", false);
|
||||||
|
|
||||||
settings.add_bool(
|
settings.add_bool(
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ pub fn expand_heap_addr(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
_isa: &dyn TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
// Unpack the instruction.
|
// Unpack the instruction.
|
||||||
let (heap, offset, access_size) = match func.dfg[inst] {
|
let (heap, offset, access_size) = match func.dfg[inst] {
|
||||||
@@ -32,16 +32,24 @@ pub fn expand_heap_addr(
|
|||||||
|
|
||||||
match func.heaps[heap].style {
|
match func.heaps[heap].style {
|
||||||
ir::HeapStyle::Dynamic { bound_gv } => {
|
ir::HeapStyle::Dynamic { bound_gv } => {
|
||||||
dynamic_addr(inst, heap, offset, access_size, bound_gv, func)
|
dynamic_addr(isa, inst, heap, offset, access_size, bound_gv, func)
|
||||||
}
|
|
||||||
ir::HeapStyle::Static { bound } => {
|
|
||||||
static_addr(inst, heap, offset, access_size, bound.into(), func, cfg)
|
|
||||||
}
|
}
|
||||||
|
ir::HeapStyle::Static { bound } => static_addr(
|
||||||
|
isa,
|
||||||
|
inst,
|
||||||
|
heap,
|
||||||
|
offset,
|
||||||
|
access_size,
|
||||||
|
bound.into(),
|
||||||
|
func,
|
||||||
|
cfg,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Expand a `heap_addr` for a dynamic heap.
|
/// Expand a `heap_addr` for a dynamic heap.
|
||||||
fn dynamic_addr(
|
fn dynamic_addr(
|
||||||
|
isa: &dyn TargetIsa,
|
||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
heap: ir::Heap,
|
heap: ir::Heap,
|
||||||
offset: ir::Value,
|
offset: ir::Value,
|
||||||
@@ -82,11 +90,12 @@ fn dynamic_addr(
|
|||||||
}
|
}
|
||||||
pos.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds);
|
pos.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds);
|
||||||
|
|
||||||
compute_addr(inst, heap, addr_ty, offset, offset_ty, pos.func);
|
compute_addr(isa, inst, heap, addr_ty, offset, offset_ty, pos.func);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Expand a `heap_addr` for a static heap.
|
/// Expand a `heap_addr` for a static heap.
|
||||||
fn static_addr(
|
fn static_addr(
|
||||||
|
isa: &dyn TargetIsa,
|
||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
heap: ir::Heap,
|
heap: ir::Heap,
|
||||||
offset: ir::Value,
|
offset: ir::Value,
|
||||||
@@ -134,11 +143,12 @@ fn static_addr(
|
|||||||
pos.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds);
|
pos.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
compute_addr(inst, heap, addr_ty, offset, offset_ty, pos.func);
|
compute_addr(isa, inst, heap, addr_ty, offset, offset_ty, pos.func);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emit code for the base address computation of a `heap_addr` instruction.
|
/// Emit code for the base address computation of a `heap_addr` instruction.
|
||||||
fn compute_addr(
|
fn compute_addr(
|
||||||
|
isa: &dyn TargetIsa,
|
||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
heap: ir::Heap,
|
heap: ir::Heap,
|
||||||
addr_ty: ir::Type,
|
addr_ty: ir::Type,
|
||||||
@@ -165,7 +175,12 @@ fn compute_addr(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the heap base address base
|
// Add the heap base address base
|
||||||
let base_gv = pos.func.heaps[heap].base;
|
let base = if isa.flags().enable_pinned_reg() && isa.flags().use_pinned_reg_as_heap_base() {
|
||||||
let base = pos.ins().global_value(addr_ty, base_gv);
|
pos.ins().get_pinned_reg(isa.pointer_type())
|
||||||
|
} else {
|
||||||
|
let base_gv = pos.func.heaps[heap].base;
|
||||||
|
pos.ins().global_value(addr_ty, base_gv)
|
||||||
|
};
|
||||||
|
|
||||||
pos.func.dfg.replace(inst).iadd(base, offset);
|
pos.func.dfg.replace(inst).iadd(base, offset);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -389,6 +389,7 @@ mod tests {
|
|||||||
enable_float = true\n\
|
enable_float = true\n\
|
||||||
enable_nan_canonicalization = false\n\
|
enable_nan_canonicalization = false\n\
|
||||||
enable_pinned_reg = false\n\
|
enable_pinned_reg = false\n\
|
||||||
|
use_pinned_reg_as_heap_base = false\n\
|
||||||
enable_simd = false\n\
|
enable_simd = false\n\
|
||||||
enable_atomics = true\n\
|
enable_atomics = true\n\
|
||||||
enable_safepoints = false\n\
|
enable_safepoints = false\n\
|
||||||
|
|||||||
Reference in New Issue
Block a user