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:
Remo Senekowitsch
2023-04-05 21:28:46 +02:00
committed by GitHub
parent 064968b01d
commit 7eb8914090
61 changed files with 815 additions and 245 deletions

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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 {

View File

@@ -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())