Moved structs/enums with repr(C) to LLVM types into ffi.rs crates

Some were in librustc_codegen_llvm, but others are not tied to LLVM, so
I put them in a new crate: librustc_codegen_ssa/coverageinfo/ffi.rs
This commit is contained in:
Rich Kadel 2020-07-28 23:09:16 -07:00
parent b58afc088f
commit 5b2e2b25e4
6 changed files with 227 additions and 214 deletions

View File

@ -2,8 +2,9 @@ use crate::common::CodegenCx;
use crate::coverageinfo;
use crate::llvm;
use llvm::coverageinfo::CounterMappingRegion;
use log::debug;
use rustc_codegen_ssa::coverageinfo::map::*;
use rustc_codegen_ssa::coverageinfo::map::{Counter, CounterExpression, Region};
use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods};
use rustc_data_structures::fx::FxHashMap;
use rustc_llvm::RustString;
@ -132,7 +133,7 @@ impl CoverageMapGenerator {
};
virtual_file_mapping.push(filenames_index);
}
mapping_regions.push(coverageinfo::CounterMappingRegion::code_region(
mapping_regions.push(CounterMappingRegion::code_region(
counter,
current_file_id,
start_line,

View File

@ -4,8 +4,9 @@ use crate::builder::Builder;
use crate::common::CodegenCx;
use libc::c_uint;
use llvm::coverageinfo::CounterMappingRegion;
use log::debug;
use rustc_codegen_ssa::coverageinfo::map::*;
use rustc_codegen_ssa::coverageinfo::map::{CounterExpression, ExprKind, FunctionCoverage};
use rustc_codegen_ssa::traits::{
BaseTypeMethods, CoverageInfoBuilderMethods, CoverageInfoMethods, StaticMethods,
};
@ -110,150 +111,6 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
}
}
/// Aligns with [llvm::coverage::CounterMappingRegion::RegionKind](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L205-L221)
#[derive(Copy, Clone, Debug)]
#[repr(C)]
enum RegionKind {
/// A CodeRegion associates some code with a counter
CodeRegion = 0,
/// An ExpansionRegion represents a file expansion region that associates
/// a source range with the expansion of a virtual source file, such as
/// for a macro instantiation or #include file.
ExpansionRegion = 1,
/// A SkippedRegion represents a source range with code that was skipped
/// by a preprocessor or similar means.
SkippedRegion = 2,
/// A GapRegion is like a CodeRegion, but its count is only set as the
/// line execution count when its the only region in the line.
GapRegion = 3,
}
/// This struct provides LLVM's representation of a "CoverageMappingRegion", encoded into the
/// coverage map, in accordance with the
/// [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format).
/// The struct composes fields representing the `Counter` type and value(s) (injected counter ID,
/// or expression type and operands), the source file (an indirect index into a "filenames array",
/// encoded separately), and source location (start and end positions of the represented code
/// region).
///
/// Aligns with [llvm::coverage::CounterMappingRegion](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L223-L226)
/// Important: The Rust struct layout (order and types of fields) must match its C++ counterpart.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct CounterMappingRegion {
/// The counter type and type-dependent counter data, if any.
counter: Counter,
/// An indirect reference to the source filename. In the LLVM Coverage Mapping Format, the
/// file_id is an index into a function-specific `virtual_file_mapping` array of indexes that,
/// in turn, are used to look up the filename for this region.
file_id: u32,
/// If the `RegionKind` is an `ExpansionRegion`, the `expanded_file_id` can be used to find the
/// mapping regions created as a result of macro expansion, by checking if their file id matches
/// the expanded file id.
expanded_file_id: u32,
/// 1-based starting line of the mapping region.
start_line: u32,
/// 1-based starting column of the mapping region.
start_col: u32,
/// 1-based ending line of the mapping region.
end_line: u32,
/// 1-based ending column of the mapping region. If the high bit is set, the current mapping
/// region is a gap area.
end_col: u32,
kind: RegionKind,
}
impl CounterMappingRegion {
pub fn code_region(
counter: Counter,
file_id: u32,
start_line: u32,
start_col: u32,
end_line: u32,
end_col: u32,
) -> Self {
Self {
counter,
file_id,
expanded_file_id: 0,
start_line,
start_col,
end_line,
end_col,
kind: RegionKind::CodeRegion,
}
}
pub fn expansion_region(
file_id: u32,
expanded_file_id: u32,
start_line: u32,
start_col: u32,
end_line: u32,
end_col: u32,
) -> Self {
Self {
counter: Counter::zero(),
file_id,
expanded_file_id,
start_line,
start_col,
end_line,
end_col,
kind: RegionKind::ExpansionRegion,
}
}
pub fn skipped_region(
file_id: u32,
start_line: u32,
start_col: u32,
end_line: u32,
end_col: u32,
) -> Self {
Self {
counter: Counter::zero(),
file_id,
expanded_file_id: 0,
start_line,
start_col,
end_line,
end_col,
kind: RegionKind::SkippedRegion,
}
}
pub fn gap_region(
counter: Counter,
file_id: u32,
start_line: u32,
start_col: u32,
end_line: u32,
end_col: u32,
) -> Self {
Self {
counter,
file_id,
expanded_file_id: 0,
start_line,
start_col,
end_line,
end_col: ((1 as u32) << 31) | end_col,
kind: RegionKind::GapRegion,
}
}
}
pub(crate) fn write_filenames_section_to_buffer(filenames: &Vec<CString>, buffer: &RustString) {
let c_str_vec = filenames.iter().map(|cstring| cstring.as_ptr()).collect::<Vec<_>>();
unsafe {

View File

@ -1,7 +1,7 @@
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
use crate::coverageinfo::CounterMappingRegion;
use rustc_codegen_ssa::coverageinfo::map as coverage_map;
use super::debuginfo::{
DIArray, DIBasicType, DIBuilder, DICompositeType, DIDerivedType, DIDescriptor, DIEnumerator,
@ -652,6 +652,155 @@ pub struct Linker<'a>(InvariantOpaque<'a>);
pub type DiagnosticHandler = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void);
pub type InlineAsmDiagHandler = unsafe extern "C" fn(&SMDiagnostic, *const c_void, c_uint);
pub mod coverageinfo {
use super::coverage_map;
/// Aligns with [llvm::coverage::CounterMappingRegion::RegionKind](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L205-L221)
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum RegionKind {
/// A CodeRegion associates some code with a counter
CodeRegion = 0,
/// An ExpansionRegion represents a file expansion region that associates
/// a source range with the expansion of a virtual source file, such as
/// for a macro instantiation or #include file.
ExpansionRegion = 1,
/// A SkippedRegion represents a source range with code that was skipped
/// by a preprocessor or similar means.
SkippedRegion = 2,
/// A GapRegion is like a CodeRegion, but its count is only set as the
/// line execution count when its the only region in the line.
GapRegion = 3,
}
/// This struct provides LLVM's representation of a "CoverageMappingRegion", encoded into the
/// coverage map, in accordance with the
/// [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format).
/// The struct composes fields representing the `Counter` type and value(s) (injected counter
/// ID, or expression type and operands), the source file (an indirect index into a "filenames
/// array", encoded separately), and source location (start and end positions of the represented
/// code region).
///
/// Aligns with [llvm::coverage::CounterMappingRegion](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L223-L226)
/// Important: The Rust struct layout (order and types of fields) must match its C++
/// counterpart.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct CounterMappingRegion {
/// The counter type and type-dependent counter data, if any.
counter: coverage_map::Counter,
/// An indirect reference to the source filename. In the LLVM Coverage Mapping Format, the
/// file_id is an index into a function-specific `virtual_file_mapping` array of indexes
/// that, in turn, are used to look up the filename for this region.
file_id: u32,
/// If the `RegionKind` is an `ExpansionRegion`, the `expanded_file_id` can be used to find
/// the mapping regions created as a result of macro expansion, by checking if their file id
/// matches the expanded file id.
expanded_file_id: u32,
/// 1-based starting line of the mapping region.
start_line: u32,
/// 1-based starting column of the mapping region.
start_col: u32,
/// 1-based ending line of the mapping region.
end_line: u32,
/// 1-based ending column of the mapping region. If the high bit is set, the current
/// mapping region is a gap area.
end_col: u32,
kind: RegionKind,
}
impl CounterMappingRegion {
pub fn code_region(
counter: coverage_map::Counter,
file_id: u32,
start_line: u32,
start_col: u32,
end_line: u32,
end_col: u32,
) -> Self {
Self {
counter,
file_id,
expanded_file_id: 0,
start_line,
start_col,
end_line,
end_col,
kind: RegionKind::CodeRegion,
}
}
pub fn expansion_region(
file_id: u32,
expanded_file_id: u32,
start_line: u32,
start_col: u32,
end_line: u32,
end_col: u32,
) -> Self {
Self {
counter: coverage_map::Counter::zero(),
file_id,
expanded_file_id,
start_line,
start_col,
end_line,
end_col,
kind: RegionKind::ExpansionRegion,
}
}
pub fn skipped_region(
file_id: u32,
start_line: u32,
start_col: u32,
end_line: u32,
end_col: u32,
) -> Self {
Self {
counter: coverage_map::Counter::zero(),
file_id,
expanded_file_id: 0,
start_line,
start_col,
end_line,
end_col,
kind: RegionKind::SkippedRegion,
}
}
pub fn gap_region(
counter: coverage_map::Counter,
file_id: u32,
start_line: u32,
start_col: u32,
end_line: u32,
end_col: u32,
) -> Self {
Self {
counter,
file_id,
expanded_file_id: 0,
start_line,
start_col,
end_line,
end_col: ((1 as u32) << 31) | end_col,
kind: RegionKind::GapRegion,
}
}
}
}
pub mod debuginfo {
use super::{InvariantOpaque, Metadata};
use bitflags::bitflags;
@ -1646,9 +1795,9 @@ extern "C" {
pub fn LLVMRustCoverageWriteMappingToBuffer(
VirtualFileMappingIDs: *const c_uint,
NumVirtualFileMappingIDs: c_uint,
Expressions: *const rustc_codegen_ssa::coverageinfo::map::CounterExpression,
Expressions: *const coverage_map::CounterExpression,
NumExpressions: c_uint,
MappingRegions: *mut CounterMappingRegion,
MappingRegions: *mut coverageinfo::CounterMappingRegion,
NumMappingRegions: c_uint,
BufferOut: &RustString,
);

View File

@ -0,0 +1,67 @@
use super::map::{CounterValueReference, MappedExpressionIndex};
/// Aligns with [llvm::coverage::Counter::CounterKind](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L91)
#[derive(Copy, Clone, Debug)]
#[repr(C)]
enum CounterKind {
Zero = 0,
CounterValueReference = 1,
Expression = 2,
}
/// A reference to an instance of an abstract "counter" that will yield a value in a coverage
/// report. Note that `id` has different interpretations, depending on the `kind`:
/// * For `CounterKind::Zero`, `id` is assumed to be `0`
/// * For `CounterKind::CounterValueReference`, `id` matches the `counter_id` of the injected
/// instrumentation counter (the `index` argument to the LLVM intrinsic
/// `instrprof.increment()`)
/// * For `CounterKind::Expression`, `id` is the index into the coverage map's array of
/// counter expressions.
/// Aligns with [llvm::coverage::Counter](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L98-L99)
/// Important: The Rust struct layout (order and types of fields) must match its C++ counterpart.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct Counter {
// Important: The layout (order and types of fields) must match its C++ counterpart.
kind: CounterKind,
id: u32,
}
impl Counter {
pub fn zero() -> Self {
Self { kind: CounterKind::Zero, id: 0 }
}
pub fn counter_value_reference(counter_id: CounterValueReference) -> Self {
Self { kind: CounterKind::CounterValueReference, id: counter_id.into() }
}
pub fn expression(mapped_expression_index: MappedExpressionIndex) -> Self {
Self { kind: CounterKind::Expression, id: mapped_expression_index.into() }
}
}
/// Aligns with [llvm::coverage::CounterExpression::ExprKind](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L146)
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum ExprKind {
Subtract = 0,
Add = 1,
}
/// Aligns with [llvm::coverage::CounterExpression](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L147-L148)
/// Important: The Rust struct layout (order and types of fields) must match its C++
/// counterpart.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct CounterExpression {
kind: ExprKind,
lhs: Counter,
rhs: Counter,
}
impl CounterExpression {
pub fn new(lhs: Counter, kind: ExprKind, rhs: Counter) -> Self {
Self { kind, lhs, rhs }
}
}

View File

@ -1,3 +1,5 @@
pub use super::ffi::*;
use rustc_index::vec::IndexVec;
use rustc_middle::ty::Instance;
use rustc_middle::ty::TyCtxt;
@ -36,70 +38,6 @@ rustc_index::newtype_index! {
}
}
/// Aligns with [llvm::coverage::Counter::CounterKind](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L91)
#[derive(Copy, Clone, Debug)]
#[repr(C)]
enum CounterKind {
Zero = 0,
CounterValueReference = 1,
Expression = 2,
}
/// A reference to an instance of an abstract "counter" that will yield a value in a coverage
/// report. Note that `id` has different interpretations, depending on the `kind`:
/// * For `CounterKind::Zero`, `id` is assumed to be `0`
/// * For `CounterKind::CounterValueReference`, `id` matches the `counter_id` of the injected
/// instrumentation counter (the `index` argument to the LLVM intrinsic `instrprof.increment()`)
/// * For `CounterKind::Expression`, `id` is the index into the coverage map's array of counter
/// expressions.
/// Aligns with [llvm::coverage::Counter](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L98-L99)
/// Important: The Rust struct layout (order and types of fields) must match its C++ counterpart.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct Counter {
// Important: The layout (order and types of fields) must match its C++ counterpart.
kind: CounterKind,
id: u32,
}
impl Counter {
pub fn zero() -> Self {
Self { kind: CounterKind::Zero, id: 0 }
}
pub fn counter_value_reference(counter_id: CounterValueReference) -> Self {
Self { kind: CounterKind::CounterValueReference, id: counter_id.into() }
}
pub fn expression(mapped_expression_index: MappedExpressionIndex) -> Self {
Self { kind: CounterKind::Expression, id: mapped_expression_index.into() }
}
}
/// Aligns with [llvm::coverage::CounterExpression::ExprKind](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L146)
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum ExprKind {
Subtract = 0,
Add = 1,
}
/// Aligns with [llvm::coverage::CounterExpression](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L147-L148)
/// Important: The Rust struct layout (order and types of fields) must match its C++ counterpart.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct CounterExpression {
kind: ExprKind,
lhs: Counter,
rhs: Counter,
}
impl CounterExpression {
pub fn new(lhs: Counter, kind: ExprKind, rhs: Counter) -> Self {
Self { kind, lhs, rhs }
}
}
#[derive(Clone, Debug)]
pub struct Region {
start: Loc,

View File

@ -1,3 +1,4 @@
pub mod ffi;
pub mod map;
pub use map::ExprKind;