Make the CFG metadata computation conditional on a flag.
This commit is contained in:
@@ -245,6 +245,21 @@ pub(crate) fn define() -> SettingGroup {
|
|||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
settings.add_bool(
|
||||||
|
"machine_code_cfg_info",
|
||||||
|
"Generate CFG metadata for machine code.",
|
||||||
|
r#"
|
||||||
|
This increases metadata size and compile time, but allows for the
|
||||||
|
embedder to more easily post-process or analyze the generated
|
||||||
|
machine code. It provides code offsets for the start of each
|
||||||
|
basic block in the generated machine code, and a list of CFG
|
||||||
|
edges (with blocks identified by start offsets) between them.
|
||||||
|
This is useful for, e.g., machine-code analyses that verify certain
|
||||||
|
properties of the generated code.
|
||||||
|
"#,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
// BaldrMonkey requires that not-yet-relocated function addresses be encoded
|
// BaldrMonkey requires that not-yet-relocated function addresses be encoded
|
||||||
// as all-ones bitpatterns.
|
// as all-ones bitpatterns.
|
||||||
settings.add_bool(
|
settings.add_bool(
|
||||||
|
|||||||
@@ -341,10 +341,16 @@ pub struct MachCompileResult {
|
|||||||
/// Debug info: stackslots to stack pointer offsets.
|
/// Debug info: stackslots to stack pointer offsets.
|
||||||
pub stackslot_offsets: PrimaryMap<StackSlot, u32>,
|
pub stackslot_offsets: PrimaryMap<StackSlot, u32>,
|
||||||
/// Basic-block layout info: block start offsets.
|
/// Basic-block layout info: block start offsets.
|
||||||
|
///
|
||||||
|
/// This info is generated only if the `machine_code_cfg_info`
|
||||||
|
/// flag is set.
|
||||||
pub bb_starts: Vec<CodeOffset>,
|
pub bb_starts: Vec<CodeOffset>,
|
||||||
/// Basic-block layout info: block edges. Each edge is `(from,
|
/// Basic-block layout info: block edges. Each edge is `(from,
|
||||||
/// to)`, where `from` and `to` are basic-block start offsets of
|
/// to)`, where `from` and `to` are basic-block start offsets of
|
||||||
/// the respective blocks.
|
/// the respective blocks.
|
||||||
|
///
|
||||||
|
/// This info is generated only if the `machine_code_cfg_info`
|
||||||
|
/// flag is set.
|
||||||
pub bb_edges: Vec<(CodeOffset, CodeOffset)>,
|
pub bb_edges: Vec<(CodeOffset, CodeOffset)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -486,6 +486,7 @@ impl<I: VCodeInst> VCode<I> {
|
|||||||
let _tt = timing::vcode_emit();
|
let _tt = timing::vcode_emit();
|
||||||
let mut buffer = MachBuffer::new();
|
let mut buffer = MachBuffer::new();
|
||||||
let mut state = I::State::new(&*self.abi);
|
let mut state = I::State::new(&*self.abi);
|
||||||
|
let cfg_metadata = self.flags().machine_code_cfg_info();
|
||||||
let mut bb_starts: Vec<Option<CodeOffset>> = vec![];
|
let mut bb_starts: Vec<Option<CodeOffset>> = vec![];
|
||||||
|
|
||||||
// The first M MachLabels are reserved for block indices, the next N MachLabels for
|
// The first M MachLabels are reserved for block indices, the next N MachLabels for
|
||||||
@@ -513,19 +514,21 @@ impl<I: VCodeInst> VCode<I> {
|
|||||||
buffer.bind_label(MachLabel::from_block(block));
|
buffer.bind_label(MachLabel::from_block(block));
|
||||||
label_insn_iix[block as usize] = start;
|
label_insn_iix[block as usize] = start;
|
||||||
|
|
||||||
// Track BB starts. If we have backed up due to MachBuffer
|
if cfg_metadata {
|
||||||
// branch opts, note that the removed blocks were removed.
|
// Track BB starts. If we have backed up due to MachBuffer
|
||||||
let cur_offset = buffer.cur_offset();
|
// branch opts, note that the removed blocks were removed.
|
||||||
if last_offset.is_some() && cur_offset <= last_offset.unwrap() {
|
let cur_offset = buffer.cur_offset();
|
||||||
for i in (0..bb_starts.len()).rev() {
|
if last_offset.is_some() && cur_offset <= last_offset.unwrap() {
|
||||||
if bb_starts[i].is_some() && cur_offset > bb_starts[i].unwrap() {
|
for i in (0..bb_starts.len()).rev() {
|
||||||
break;
|
if bb_starts[i].is_some() && cur_offset > bb_starts[i].unwrap() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bb_starts[i] = None;
|
||||||
}
|
}
|
||||||
bb_starts[i] = None;
|
|
||||||
}
|
}
|
||||||
|
bb_starts.push(Some(cur_offset));
|
||||||
|
last_offset = Some(cur_offset);
|
||||||
}
|
}
|
||||||
bb_starts.push(Some(cur_offset));
|
|
||||||
last_offset = Some(cur_offset);
|
|
||||||
|
|
||||||
for iix in start..end {
|
for iix in start..end {
|
||||||
let srcloc = self.srclocs[iix as usize];
|
let srcloc = self.srclocs[iix as usize];
|
||||||
@@ -606,19 +609,21 @@ impl<I: VCodeInst> VCode<I> {
|
|||||||
// Create `bb_edges` and final (filtered) `bb_starts`.
|
// Create `bb_edges` and final (filtered) `bb_starts`.
|
||||||
let mut final_bb_starts = vec![];
|
let mut final_bb_starts = vec![];
|
||||||
let mut bb_edges = vec![];
|
let mut bb_edges = vec![];
|
||||||
for block in 0..self.num_blocks() {
|
if cfg_metadata {
|
||||||
if bb_starts[block].is_none() {
|
for block in 0..self.num_blocks() {
|
||||||
// Block was deleted by MachBuffer; skip.
|
if bb_starts[block].is_none() {
|
||||||
continue;
|
// Block was deleted by MachBuffer; skip.
|
||||||
}
|
continue;
|
||||||
let from = bb_starts[block].unwrap();
|
}
|
||||||
|
let from = bb_starts[block].unwrap();
|
||||||
|
|
||||||
final_bb_starts.push(from);
|
final_bb_starts.push(from);
|
||||||
// Resolve each `succ` label and add edges.
|
// Resolve each `succ` label and add edges.
|
||||||
let succs = self.block_succs(BlockIx::new(block as u32));
|
let succs = self.block_succs(BlockIx::new(block as u32));
|
||||||
for succ in succs.iter() {
|
for succ in succs.iter() {
|
||||||
let to = buffer.resolve_label_offset(MachLabel::from_block(succ.get()));
|
let to = buffer.resolve_label_offset(MachLabel::from_block(succ.get()));
|
||||||
bb_edges.push((from, to));
|
bb_edges.push((from, to));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -511,6 +511,7 @@ enable_atomics = true
|
|||||||
enable_safepoints = false
|
enable_safepoints = false
|
||||||
enable_llvm_abi_extensions = false
|
enable_llvm_abi_extensions = false
|
||||||
unwind_info = true
|
unwind_info = true
|
||||||
|
machine_code_cfg_info = false
|
||||||
emit_all_ones_funcaddrs = false
|
emit_all_ones_funcaddrs = false
|
||||||
enable_probestack = true
|
enable_probestack = true
|
||||||
probestack_func_adjusts_sp = false
|
probestack_func_adjusts_sp = false
|
||||||
|
|||||||
Reference in New Issue
Block a user