gave unused_fn WeakAnyLinkage; moved create_pgo_func_name_var
The sample json5format tests produce coverage results again (and work with opt-level 3!)
This commit is contained in:
parent
bcf755562a
commit
5a484a1aed
@ -67,25 +67,12 @@ impl CoverageInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||||||
let mut pgo_func_name_var_map = coverage_context.pgo_func_name_var_map.borrow_mut();
|
let mut pgo_func_name_var_map = coverage_context.pgo_func_name_var_map.borrow_mut();
|
||||||
pgo_func_name_var_map
|
pgo_func_name_var_map
|
||||||
.entry(instance)
|
.entry(instance)
|
||||||
.or_insert_with(|| self.create_pgo_func_name_var(instance))
|
.or_insert_with(|| create_pgo_func_name_var(self, instance))
|
||||||
} else {
|
} else {
|
||||||
bug!("Could not get the `coverage_context`");
|
bug!("Could not get the `coverage_context`");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls llvm::createPGOFuncNameVar() with the given function instance's
|
|
||||||
/// mangled function name. The LLVM API returns an llvm::GlobalVariable
|
|
||||||
/// containing the function name, with the specific variable name and
|
|
||||||
/// linkage required by LLVM InstrProf source-based coverage
|
|
||||||
/// instrumentation. Use `bx.get_pgo_func_name_var()` to ensure the variable
|
|
||||||
/// is only created once per `Instance`.
|
|
||||||
fn create_pgo_func_name_var(&self, instance: Instance<'tcx>) -> &'ll llvm::Value {
|
|
||||||
let mangled_fn_name = CString::new(self.tcx.symbol_name(instance).name)
|
|
||||||
.expect("error converting function name to C string");
|
|
||||||
let llfn = self.get_fn(instance);
|
|
||||||
unsafe { llvm::LLVMRustCoverageCreatePGOFuncNameVar(llfn, mangled_fn_name.as_ptr()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn define_unused_fn(&self, def_id: DefId) {
|
fn define_unused_fn(&self, def_id: DefId) {
|
||||||
let instance = declare_unused_fn(self, &def_id);
|
let instance = declare_unused_fn(self, &def_id);
|
||||||
codegen_unused_fn_and_counter(self, instance);
|
codegen_unused_fn_and_counter(self, instance);
|
||||||
@ -210,10 +197,8 @@ fn declare_unused_fn(cx: &CodegenCx<'ll, 'tcx>, def_id: &DefId) -> Instance<'tcx
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
unsafe {
|
llvm::set_linkage(llfn, llvm::Linkage::WeakAnyLinkage);
|
||||||
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
|
llvm::set_visibility(llfn, llvm::Visibility::Hidden);
|
||||||
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
|
|
||||||
}
|
|
||||||
|
|
||||||
cx.instances.borrow_mut().insert(instance, llfn);
|
cx.instances.borrow_mut().insert(instance, llfn);
|
||||||
|
|
||||||
@ -261,6 +246,22 @@ fn add_function_coverage(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>, de
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calls llvm::createPGOFuncNameVar() with the given function instance's
|
||||||
|
/// mangled function name. The LLVM API returns an llvm::GlobalVariable
|
||||||
|
/// containing the function name, with the specific variable name and linkage
|
||||||
|
/// required by LLVM InstrProf source-based coverage instrumentation. Use
|
||||||
|
/// `bx.get_pgo_func_name_var()` to ensure the variable is only created once per
|
||||||
|
/// `Instance`.
|
||||||
|
fn create_pgo_func_name_var(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
|
instance: Instance<'tcx>,
|
||||||
|
) -> &'ll llvm::Value {
|
||||||
|
let mangled_fn_name = CString::new(cx.tcx.symbol_name(instance).name)
|
||||||
|
.expect("error converting function name to C string");
|
||||||
|
let llfn = cx.get_fn(instance);
|
||||||
|
unsafe { llvm::LLVMRustCoverageCreatePGOFuncNameVar(llfn, mangled_fn_name.as_ptr()) }
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn write_filenames_section_to_buffer<'a>(
|
pub(crate) fn write_filenames_section_to_buffer<'a>(
|
||||||
filenames: impl IntoIterator<Item = &'a CString>,
|
filenames: impl IntoIterator<Item = &'a CString>,
|
||||||
buffer: &RustString,
|
buffer: &RustString,
|
||||||
|
@ -29,10 +29,6 @@ pub trait CoverageInfoMethods<'tcx>: BackendTypes {
|
|||||||
/// `instrprof.increment()`. The `Value` is only created once per instance.
|
/// `instrprof.increment()`. The `Value` is only created once per instance.
|
||||||
/// Multiple invocations with the same instance return the same `Value`.
|
/// Multiple invocations with the same instance return the same `Value`.
|
||||||
fn get_pgo_func_name_var(&self, instance: Instance<'tcx>) -> Self::Value;
|
fn get_pgo_func_name_var(&self, instance: Instance<'tcx>) -> Self::Value;
|
||||||
|
|
||||||
/// Creates a new PGO function name variable. This should only be called
|
|
||||||
/// to fill in the unused function names array.
|
|
||||||
fn create_pgo_func_name_var(&self, instance: Instance<'tcx>) -> Self::Value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
|
pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user