From 800cf25bb586bef6e9f0dd8b7dd82ab8f57a7625 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Mon, 24 May 2021 11:16:57 -0700 Subject: [PATCH] Make the CFG metadata computation conditional on a flag. --- cranelift/codegen/meta/src/shared/settings.rs | 15 ++++++ cranelift/codegen/src/machinst/mod.rs | 6 +++ cranelift/codegen/src/machinst/vcode.rs | 49 ++++++++++--------- cranelift/codegen/src/settings.rs | 1 + 4 files changed, 49 insertions(+), 22 deletions(-) diff --git a/cranelift/codegen/meta/src/shared/settings.rs b/cranelift/codegen/meta/src/shared/settings.rs index 2233e85dbc..b9fa89587a 100644 --- a/cranelift/codegen/meta/src/shared/settings.rs +++ b/cranelift/codegen/meta/src/shared/settings.rs @@ -245,6 +245,21 @@ pub(crate) fn define() -> SettingGroup { 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 // as all-ones bitpatterns. settings.add_bool( diff --git a/cranelift/codegen/src/machinst/mod.rs b/cranelift/codegen/src/machinst/mod.rs index 0c2376ce66..41d6e05bed 100644 --- a/cranelift/codegen/src/machinst/mod.rs +++ b/cranelift/codegen/src/machinst/mod.rs @@ -341,10 +341,16 @@ pub struct MachCompileResult { /// Debug info: stackslots to stack pointer offsets. pub stackslot_offsets: PrimaryMap, /// 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, /// Basic-block layout info: block edges. Each edge is `(from, /// to)`, where `from` and `to` are basic-block start offsets of /// the respective blocks. + /// + /// This info is generated only if the `machine_code_cfg_info` + /// flag is set. pub bb_edges: Vec<(CodeOffset, CodeOffset)>, } diff --git a/cranelift/codegen/src/machinst/vcode.rs b/cranelift/codegen/src/machinst/vcode.rs index bf1b2e0698..c27f1e00ee 100644 --- a/cranelift/codegen/src/machinst/vcode.rs +++ b/cranelift/codegen/src/machinst/vcode.rs @@ -486,6 +486,7 @@ impl VCode { let _tt = timing::vcode_emit(); let mut buffer = MachBuffer::new(); let mut state = I::State::new(&*self.abi); + let cfg_metadata = self.flags().machine_code_cfg_info(); let mut bb_starts: Vec> = vec![]; // The first M MachLabels are reserved for block indices, the next N MachLabels for @@ -513,19 +514,21 @@ impl VCode { buffer.bind_label(MachLabel::from_block(block)); label_insn_iix[block as usize] = start; - // Track BB starts. If we have backed up due to MachBuffer - // branch opts, note that the removed blocks were removed. - let cur_offset = buffer.cur_offset(); - if last_offset.is_some() && cur_offset <= last_offset.unwrap() { - for i in (0..bb_starts.len()).rev() { - if bb_starts[i].is_some() && cur_offset > bb_starts[i].unwrap() { - break; + if cfg_metadata { + // Track BB starts. If we have backed up due to MachBuffer + // branch opts, note that the removed blocks were removed. + let cur_offset = buffer.cur_offset(); + if last_offset.is_some() && cur_offset <= last_offset.unwrap() { + for i in (0..bb_starts.len()).rev() { + 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 { let srcloc = self.srclocs[iix as usize]; @@ -606,19 +609,21 @@ impl VCode { // Create `bb_edges` and final (filtered) `bb_starts`. let mut final_bb_starts = vec![]; let mut bb_edges = vec![]; - for block in 0..self.num_blocks() { - if bb_starts[block].is_none() { - // Block was deleted by MachBuffer; skip. - continue; - } - let from = bb_starts[block].unwrap(); + if cfg_metadata { + for block in 0..self.num_blocks() { + if bb_starts[block].is_none() { + // Block was deleted by MachBuffer; skip. + continue; + } + let from = bb_starts[block].unwrap(); - final_bb_starts.push(from); - // Resolve each `succ` label and add edges. - let succs = self.block_succs(BlockIx::new(block as u32)); - for succ in succs.iter() { - let to = buffer.resolve_label_offset(MachLabel::from_block(succ.get())); - bb_edges.push((from, to)); + final_bb_starts.push(from); + // Resolve each `succ` label and add edges. + let succs = self.block_succs(BlockIx::new(block as u32)); + for succ in succs.iter() { + let to = buffer.resolve_label_offset(MachLabel::from_block(succ.get())); + bb_edges.push((from, to)); + } } } diff --git a/cranelift/codegen/src/settings.rs b/cranelift/codegen/src/settings.rs index 0f36db82a9..09db7f55e5 100644 --- a/cranelift/codegen/src/settings.rs +++ b/cranelift/codegen/src/settings.rs @@ -511,6 +511,7 @@ enable_atomics = true enable_safepoints = false enable_llvm_abi_extensions = false unwind_info = true +machine_code_cfg_info = false emit_all_ones_funcaddrs = false enable_probestack = true probestack_func_adjusts_sp = false