Chaos mode MVP: Skip branch optimization in MachBuffer (#6039)
* fuzz: Add chaos mode control plane Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Moritz Waser <mzrw.dev@pm.me> * fuzz: Skip branch optimization with chaos mode Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Moritz Waser <mzrw.dev@pm.me> * fuzz: Rename chaos engine -> control plane Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Moritz Waser <mzrw.dev@pm.me> * chaos mode: refactoring ControlPlane to be passed through the call stack by reference Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Remo Senekowitsch <contact@remsle.dev> * fuzz: annotate chaos todos Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Moritz Waser <mzrw.dev@pm.me> * fuzz: cleanup control plane Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Moritz Waser <mzrw.dev@pm.me> * fuzz: remove control plane from compiler context Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Moritz Waser <mzrw.dev@pm.me> * fuzz: move control plane into emit state Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Moritz Waser <mzrw.dev@pm.me> * fuzz: fix remaining compiler errors Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Moritz Waser <mzrw.dev@pm.me> * fix tests * refactor emission state ctrl plane accessors Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Moritz Waser <mzrw.dev@pm.me> * centralize conditional compilation of chaos mode Also cleanup a few straggling dependencies on cranelift-control that aren't needed anymore. Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Moritz Waser <mzrw.dev@pm.me> * add cranelift-control to published crates prtest:full Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Moritz Waser <mzrw.dev@pm.me> * add cranelift-control to public crates Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Moritz Waser <mzrw.dev@pm.me> --------- Co-authored-by: Falk Zwimpfer <24669719+FalkZ@users.noreply.github.com> Co-authored-by: Moritz Waser <mzrw.dev@pm.me> Co-authored-by: Remo Senekowitsch <contact@remsle.dev>
This commit is contained in:
committed by
GitHub
parent
064968b01d
commit
7eb8914090
@@ -620,7 +620,7 @@ pub(crate) fn emit(
|
||||
|
||||
// Here the `idiv` is executed, which is different depending on the
|
||||
// size
|
||||
sink.bind_label(do_op);
|
||||
sink.bind_label(do_op, &mut state.ctrl_plane);
|
||||
let inst = match size {
|
||||
OperandSize::Size8 => Inst::div8(
|
||||
DivSignedness::Signed,
|
||||
@@ -642,7 +642,7 @@ pub(crate) fn emit(
|
||||
};
|
||||
inst.emit(&[], sink, info, state);
|
||||
|
||||
sink.bind_label(done_label);
|
||||
sink.bind_label(done_label, &mut state.ctrl_plane);
|
||||
}
|
||||
|
||||
Inst::Imm {
|
||||
@@ -1291,7 +1291,7 @@ pub(crate) fn emit(
|
||||
let inst = Inst::xmm_unary_rm_r(op, consequent, Writable::from_reg(dst));
|
||||
inst.emit(&[], sink, info, state);
|
||||
|
||||
sink.bind_label(next);
|
||||
sink.bind_label(next, &mut state.ctrl_plane);
|
||||
}
|
||||
|
||||
Inst::Push64 { src } => {
|
||||
@@ -1395,7 +1395,7 @@ pub(crate) fn emit(
|
||||
|
||||
// Emit the main loop!
|
||||
let loop_start = sink.get_label();
|
||||
sink.bind_label(loop_start);
|
||||
sink.bind_label(loop_start, &mut state.ctrl_plane);
|
||||
|
||||
// sub rsp, GUARD_SIZE
|
||||
let inst = Inst::alu_rmi_r(
|
||||
@@ -1666,7 +1666,7 @@ pub(crate) fn emit(
|
||||
inst.emit(&[], sink, info, state);
|
||||
|
||||
// Emit jump table (table of 32-bit offsets).
|
||||
sink.bind_label(start_of_jumptable);
|
||||
sink.bind_label(start_of_jumptable, &mut state.ctrl_plane);
|
||||
let jt_off = sink.cur_offset();
|
||||
for &target in targets.iter().chain(std::iter::once(default_target)) {
|
||||
let word_off = sink.cur_offset();
|
||||
@@ -1698,7 +1698,7 @@ pub(crate) fn emit(
|
||||
one_way_jmp(sink, cc1.invert(), else_label);
|
||||
one_way_jmp(sink, *cc2, trap_label);
|
||||
|
||||
sink.bind_label(else_label);
|
||||
sink.bind_label(else_label, &mut state.ctrl_plane);
|
||||
}
|
||||
|
||||
Inst::TrapIfOr {
|
||||
@@ -2750,18 +2750,18 @@ pub(crate) fn emit(
|
||||
// x86's min/max are not symmetric; if either operand is a NaN, they return the
|
||||
// read-only operand: perform an addition between the two operands, which has the
|
||||
// desired NaN propagation effects.
|
||||
sink.bind_label(propagate_nan);
|
||||
sink.bind_label(propagate_nan, &mut state.ctrl_plane);
|
||||
let inst = Inst::xmm_rm_r(add_op, RegMem::reg(lhs), Writable::from_reg(dst));
|
||||
inst.emit(&[], sink, info, state);
|
||||
|
||||
one_way_jmp(sink, CC::P, done);
|
||||
|
||||
sink.bind_label(do_min_max);
|
||||
sink.bind_label(do_min_max, &mut state.ctrl_plane);
|
||||
|
||||
let inst = Inst::xmm_rm_r(min_max_op, RegMem::reg(lhs), Writable::from_reg(dst));
|
||||
inst.emit(&[], sink, info, state);
|
||||
|
||||
sink.bind_label(done);
|
||||
sink.bind_label(done, &mut state.ctrl_plane);
|
||||
}
|
||||
|
||||
Inst::XmmRmRImm {
|
||||
@@ -3028,7 +3028,7 @@ pub(crate) fn emit(
|
||||
let inst = Inst::jmp_known(done);
|
||||
inst.emit(&[], sink, info, state);
|
||||
|
||||
sink.bind_label(handle_negative);
|
||||
sink.bind_label(handle_negative, &mut state.ctrl_plane);
|
||||
|
||||
// Divide x by two to get it in range for the signed conversion, keep the LSB, and
|
||||
// scale it back up on the FP side.
|
||||
@@ -3081,7 +3081,7 @@ pub(crate) fn emit(
|
||||
let inst = Inst::xmm_rm_r(add_op, RegMem::reg(dst), Writable::from_reg(dst));
|
||||
inst.emit(&[], sink, info, state);
|
||||
|
||||
sink.bind_label(done);
|
||||
sink.bind_label(done, &mut state.ctrl_plane);
|
||||
}
|
||||
|
||||
Inst::CvtFloatToSintSeq {
|
||||
@@ -3183,7 +3183,7 @@ pub(crate) fn emit(
|
||||
let inst = Inst::jmp_known(done);
|
||||
inst.emit(&[], sink, info, state);
|
||||
|
||||
sink.bind_label(not_nan);
|
||||
sink.bind_label(not_nan, &mut state.ctrl_plane);
|
||||
|
||||
// If the input was positive, saturate to INT_MAX.
|
||||
|
||||
@@ -3281,7 +3281,7 @@ pub(crate) fn emit(
|
||||
inst.emit(&[], sink, info, state);
|
||||
}
|
||||
|
||||
sink.bind_label(done);
|
||||
sink.bind_label(done, &mut state.ctrl_plane);
|
||||
}
|
||||
|
||||
Inst::CvtFloatToUintSeq {
|
||||
@@ -3391,7 +3391,7 @@ pub(crate) fn emit(
|
||||
|
||||
let inst = Inst::jmp_known(done);
|
||||
inst.emit(&[], sink, info, state);
|
||||
sink.bind_label(not_nan);
|
||||
sink.bind_label(not_nan, &mut state.ctrl_plane);
|
||||
} else {
|
||||
// Trap.
|
||||
let inst = Inst::trap_if(CC::P, TrapCode::BadConversionToInteger);
|
||||
@@ -3430,7 +3430,7 @@ pub(crate) fn emit(
|
||||
|
||||
// Now handle large inputs.
|
||||
|
||||
sink.bind_label(handle_large);
|
||||
sink.bind_label(handle_large, &mut state.ctrl_plane);
|
||||
|
||||
let inst = Inst::gen_move(Writable::from_reg(tmp_xmm2), src, types::F64);
|
||||
inst.emit(&[], sink, info, state);
|
||||
@@ -3463,7 +3463,7 @@ pub(crate) fn emit(
|
||||
|
||||
let inst = Inst::jmp_known(done);
|
||||
inst.emit(&[], sink, info, state);
|
||||
sink.bind_label(next_is_large);
|
||||
sink.bind_label(next_is_large, &mut state.ctrl_plane);
|
||||
} else {
|
||||
let inst = Inst::trap_if(CC::L, TrapCode::IntegerOverflow);
|
||||
inst.emit(&[], sink, info, state);
|
||||
@@ -3490,7 +3490,7 @@ pub(crate) fn emit(
|
||||
inst.emit(&[], sink, info, state);
|
||||
}
|
||||
|
||||
sink.bind_label(done);
|
||||
sink.bind_label(done, &mut state.ctrl_plane);
|
||||
}
|
||||
|
||||
Inst::LoadExtName { dst, name, offset } => {
|
||||
@@ -3600,7 +3600,7 @@ pub(crate) fn emit(
|
||||
i1.emit(&[], sink, info, state);
|
||||
|
||||
// again:
|
||||
sink.bind_label(again_label);
|
||||
sink.bind_label(again_label, &mut state.ctrl_plane);
|
||||
|
||||
// movq %rax, %r_temp
|
||||
let i2 = Inst::mov_r_r(OperandSize::Size64, dst_old.to_reg(), temp);
|
||||
|
||||
@@ -5098,6 +5098,7 @@ fn test_x64_emit() {
|
||||
|
||||
// ========================================================
|
||||
// Actually run the tests!
|
||||
let ctrl_plane = &mut Default::default();
|
||||
let mut flag_builder = settings::builder();
|
||||
flag_builder.enable("is_pic").unwrap();
|
||||
let flags = settings::Flags::new(flag_builder);
|
||||
@@ -5126,9 +5127,9 @@ fn test_x64_emit() {
|
||||
|
||||
// Allow one label just after the instruction (so the offset is 0).
|
||||
let label = buffer.get_label();
|
||||
buffer.bind_label(label);
|
||||
buffer.bind_label(label, ctrl_plane);
|
||||
|
||||
let buffer = buffer.finish();
|
||||
let buffer = buffer.finish(ctrl_plane);
|
||||
let actual_encoding = &buffer.stringify_code_bytes();
|
||||
assert_eq!(expected_encoding, actual_encoding, "{}", expected_printing);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::{machinst::*, trace};
|
||||
use crate::{settings, CodegenError, CodegenResult};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use cranelift_control::ControlPlane;
|
||||
use regalloc2::{Allocation, PRegSet, VReg};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::fmt;
|
||||
@@ -2547,6 +2548,9 @@ pub struct EmitState {
|
||||
stack_map: Option<StackMap>,
|
||||
/// Current source location.
|
||||
cur_srcloc: RelSourceLoc,
|
||||
/// Only used during fuzz-testing. Otherwise, it is a zero-sized struct and
|
||||
/// optimized away at compiletime. See [cranelift_control].
|
||||
ctrl_plane: ControlPlane,
|
||||
}
|
||||
|
||||
/// Constant state used during emissions of a sequence of instructions.
|
||||
@@ -2583,12 +2587,13 @@ impl MachInstEmit for Inst {
|
||||
}
|
||||
|
||||
impl MachInstEmitState<Inst> for EmitState {
|
||||
fn new(abi: &Callee<X64ABIMachineSpec>) -> Self {
|
||||
fn new(abi: &Callee<X64ABIMachineSpec>, ctrl_plane: ControlPlane) -> Self {
|
||||
EmitState {
|
||||
virtual_sp_offset: 0,
|
||||
nominal_sp_to_fp: abi.frame_size() as i64,
|
||||
stack_map: None,
|
||||
cur_srcloc: Default::default(),
|
||||
ctrl_plane,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2599,6 +2604,14 @@ impl MachInstEmitState<Inst> for EmitState {
|
||||
fn pre_sourceloc(&mut self, srcloc: RelSourceLoc) {
|
||||
self.cur_srcloc = srcloc;
|
||||
}
|
||||
|
||||
fn ctrl_plane_mut(&mut self) -> &mut ControlPlane {
|
||||
&mut self.ctrl_plane
|
||||
}
|
||||
|
||||
fn take_ctrl_plane(self) -> ControlPlane {
|
||||
self.ctrl_plane
|
||||
}
|
||||
}
|
||||
|
||||
impl EmitState {
|
||||
|
||||
@@ -118,7 +118,9 @@ mod tests {
|
||||
Some(StackSlotData::new(StackSlotKind::ExplicitSlot, 64)),
|
||||
));
|
||||
|
||||
let code = context.compile(&*isa).expect("expected compilation");
|
||||
let code = context
|
||||
.compile(&*isa, &mut Default::default())
|
||||
.expect("expected compilation");
|
||||
|
||||
let fde = match code
|
||||
.create_unwind_info(isa.as_ref())
|
||||
@@ -157,7 +159,9 @@ mod tests {
|
||||
|
||||
let mut context = Context::for_function(create_multi_return_function(CallConv::SystemV));
|
||||
|
||||
let code = context.compile(&*isa).expect("expected compilation");
|
||||
let code = context
|
||||
.compile(&*isa, &mut Default::default())
|
||||
.expect("expected compilation");
|
||||
|
||||
let fde = match code
|
||||
.create_unwind_info(isa.as_ref())
|
||||
|
||||
Reference in New Issue
Block a user