1
Fork 0

Auto merge of #94539 - tmiasko:string-attributes, r=nikic

Pass LLVM string attributes as string slices
This commit is contained in:
bors 2022-03-04 10:38:11 +00:00
commit 047f9c4bc4
5 changed files with 47 additions and 43 deletions

View file

@ -561,8 +561,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
if self.conv == Conv::CCmseNonSecureCall { if self.conv == Conv::CCmseNonSecureCall {
// This will probably get ignored on all targets but those supporting the TrustZone-M // This will probably get ignored on all targets but those supporting the TrustZone-M
// extension (thumbv8m targets). // extension (thumbv8m targets).
let cmse_nonsecure_call = let cmse_nonsecure_call = llvm::CreateAttrString(bx.cx.llcx, "cmse_nonsecure_call");
llvm::CreateAttrString(bx.cx.llcx, cstr::cstr!("cmse_nonsecure_call"));
attributes::apply_to_callsite( attributes::apply_to_callsite(
callsite, callsite,
llvm::AttributePlace::Function, llvm::AttributePlace::Function,

View file

@ -1,10 +1,6 @@
//! Set and unset common attributes on LLVM values. //! Set and unset common attributes on LLVM values.
use std::ffi::CString;
use cstr::cstr;
use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::traits::*;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
@ -103,11 +99,11 @@ pub fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attr
fp = FramePointer::Always; fp = FramePointer::Always;
} }
let attr_value = match fp { let attr_value = match fp {
FramePointer::Always => cstr!("all"), FramePointer::Always => "all",
FramePointer::NonLeaf => cstr!("non-leaf"), FramePointer::NonLeaf => "non-leaf",
FramePointer::MayOmit => return None, FramePointer::MayOmit => return None,
}; };
Some(llvm::CreateAttrStringValue(cx.llcx, cstr!("frame-pointer"), attr_value)) Some(llvm::CreateAttrStringValue(cx.llcx, "frame-pointer", attr_value))
} }
/// Tell LLVM what instrument function to insert. /// Tell LLVM what instrument function to insert.
@ -119,11 +115,11 @@ fn instrument_function_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribu
// The function name varies on platforms. // The function name varies on platforms.
// See test/CodeGen/mcount.c in clang. // See test/CodeGen/mcount.c in clang.
let mcount_name = CString::new(cx.sess().target.mcount.as_str().as_bytes()).unwrap(); let mcount_name = cx.sess().target.mcount.as_str();
Some(llvm::CreateAttrStringValue( Some(llvm::CreateAttrStringValue(
cx.llcx, cx.llcx,
cstr!("instrument-function-entry-inlined"), "instrument-function-entry-inlined",
&mcount_name, &mcount_name,
)) ))
} else { } else {
@ -159,20 +155,20 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
StackProbeType::None => return None, StackProbeType::None => return None,
// Request LLVM to generate the probes inline. If the given LLVM version does not support // Request LLVM to generate the probes inline. If the given LLVM version does not support
// this, no probe is generated at all (even if the attribute is specified). // this, no probe is generated at all (even if the attribute is specified).
StackProbeType::Inline => cstr!("inline-asm"), StackProbeType::Inline => "inline-asm",
// Flag our internal `__rust_probestack` function as the stack probe symbol. // Flag our internal `__rust_probestack` function as the stack probe symbol.
// This is defined in the `compiler-builtins` crate for each architecture. // This is defined in the `compiler-builtins` crate for each architecture.
StackProbeType::Call => cstr!("__rust_probestack"), StackProbeType::Call => "__rust_probestack",
// Pick from the two above based on the LLVM version. // Pick from the two above based on the LLVM version.
StackProbeType::InlineOrCall { min_llvm_version_for_inline } => { StackProbeType::InlineOrCall { min_llvm_version_for_inline } => {
if llvm_util::get_version() < min_llvm_version_for_inline { if llvm_util::get_version() < min_llvm_version_for_inline {
cstr!("__rust_probestack") "__rust_probestack"
} else { } else {
cstr!("inline-asm") "inline-asm"
} }
} }
}; };
Some(llvm::CreateAttrStringValue(cx.llcx, cstr!("probe-stack"), attr_value)) Some(llvm::CreateAttrStringValue(cx.llcx, "probe-stack", attr_value))
} }
fn stackprotector_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { fn stackprotector_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
@ -187,15 +183,13 @@ fn stackprotector_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
} }
pub fn target_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Attribute { pub fn target_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Attribute {
let target_cpu = SmallCStr::new(llvm_util::target_cpu(cx.tcx.sess)); let target_cpu = llvm_util::target_cpu(cx.tcx.sess);
llvm::CreateAttrStringValue(cx.llcx, cstr!("target-cpu"), target_cpu.as_c_str()) llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu)
} }
pub fn tune_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { pub fn tune_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
llvm_util::tune_cpu(cx.tcx.sess).map(|tune| { llvm_util::tune_cpu(cx.tcx.sess)
let tune_cpu = SmallCStr::new(tune); .map(|tune_cpu| llvm::CreateAttrStringValue(cx.llcx, "tune-cpu", tune_cpu))
llvm::CreateAttrStringValue(cx.llcx, cstr!("tune-cpu"), tune_cpu.as_c_str())
})
} }
/// Get the `NonLazyBind` LLVM attribute, /// Get the `NonLazyBind` LLVM attribute,
@ -280,7 +274,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
} }
if cx.sess().opts.debugging_opts.profile_sample_use.is_some() { if cx.sess().opts.debugging_opts.profile_sample_use.is_some() {
to_add.push(llvm::CreateAttrString(cx.llcx, cstr!("use-sample-profile"))); to_add.push(llvm::CreateAttrString(cx.llcx, "use-sample-profile"));
} }
// FIXME: none of these three functions interact with source level attributes. // FIXME: none of these three functions interact with source level attributes.
@ -310,7 +304,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]); attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]);
} }
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY) { if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY) {
to_add.push(llvm::CreateAttrString(cx.llcx, cstr!("cmse_nonsecure_entry"))); to_add.push(llvm::CreateAttrString(cx.llcx, "cmse_nonsecure_entry"));
} }
if let Some(align) = codegen_fn_attrs.alignment { if let Some(align) = codegen_fn_attrs.alignment {
llvm::set_alignment(llfn, align as usize); llvm::set_alignment(llfn, align as usize);
@ -363,12 +357,12 @@ pub fn from_fn_attrs<'ll, 'tcx>(
// If this function is an import from the environment but the wasm // If this function is an import from the environment but the wasm
// import has a specific module/name, apply them here. // import has a specific module/name, apply them here.
if let Some(module) = wasm_import_module(cx.tcx, instance.def_id()) { if let Some(module) = wasm_import_module(cx.tcx, instance.def_id()) {
to_add.push(llvm::CreateAttrStringValue(cx.llcx, cstr!("wasm-import-module"), &module)); to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-module", &module));
let name = let name =
codegen_fn_attrs.link_name.unwrap_or_else(|| cx.tcx.item_name(instance.def_id())); codegen_fn_attrs.link_name.unwrap_or_else(|| cx.tcx.item_name(instance.def_id()));
let name = CString::new(name.as_str()).unwrap(); let name = name.as_str();
to_add.push(llvm::CreateAttrStringValue(cx.llcx, cstr!("wasm-import-name"), &name)); to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-name", name));
} }
// The `"wasm"` abi on wasm targets automatically enables the // The `"wasm"` abi on wasm targets automatically enables the
@ -388,13 +382,13 @@ pub fn from_fn_attrs<'ll, 'tcx>(
let val = global_features let val = global_features
.chain(function_features.iter().map(|s| &s[..])) .chain(function_features.iter().map(|s| &s[..]))
.intersperse(",") .intersperse(",")
.collect::<SmallCStr>(); .collect::<String>();
to_add.push(llvm::CreateAttrStringValue(cx.llcx, cstr!("target-features"), &val)); to_add.push(llvm::CreateAttrStringValue(cx.llcx, "target-features", &val));
} }
attributes::apply_to_llfn(llfn, Function, &to_add); attributes::apply_to_llfn(llfn, Function, &to_add);
} }
fn wasm_import_module(tcx: TyCtxt<'_>, id: DefId) -> Option<CString> { fn wasm_import_module(tcx: TyCtxt<'_>, id: DefId) -> Option<&String> {
tcx.wasm_import_module_map(id.krate).get(&id).map(|s| CString::new(&s[..]).unwrap()) tcx.wasm_import_module_map(id.krate).get(&id)
} }

View file

@ -1176,11 +1176,12 @@ extern "C" {
// Operations on attributes // Operations on attributes
pub fn LLVMRustCreateAttrNoValue(C: &Context, attr: AttributeKind) -> &Attribute; pub fn LLVMRustCreateAttrNoValue(C: &Context, attr: AttributeKind) -> &Attribute;
pub fn LLVMRustCreateAttrString(C: &Context, Name: *const c_char) -> &Attribute; pub fn LLVMCreateStringAttribute(
pub fn LLVMRustCreateAttrStringValue(
C: &Context, C: &Context,
Name: *const c_char, Name: *const c_char,
NameLen: c_uint,
Value: *const c_char, Value: *const c_char,
ValueLen: c_uint,
) -> &Attribute; ) -> &Attribute;
pub fn LLVMRustCreateAlignmentAttr(C: &Context, bytes: u64) -> &Attribute; pub fn LLVMRustCreateAlignmentAttr(C: &Context, bytes: u64) -> &Attribute;
pub fn LLVMRustCreateDereferenceableAttr(C: &Context, bytes: u64) -> &Attribute; pub fn LLVMRustCreateDereferenceableAttr(C: &Context, bytes: u64) -> &Attribute;

View file

@ -47,12 +47,28 @@ pub fn AddCallSiteAttributes<'ll>(
} }
} }
pub fn CreateAttrStringValue<'ll>(llcx: &'ll Context, attr: &CStr, value: &CStr) -> &'ll Attribute { pub fn CreateAttrStringValue<'ll>(llcx: &'ll Context, attr: &str, value: &str) -> &'ll Attribute {
unsafe { LLVMRustCreateAttrStringValue(llcx, attr.as_ptr(), value.as_ptr()) } unsafe {
LLVMCreateStringAttribute(
llcx,
attr.as_ptr().cast(),
attr.len().try_into().unwrap(),
value.as_ptr().cast(),
value.len().try_into().unwrap(),
)
}
} }
pub fn CreateAttrString<'ll>(llcx: &'ll Context, attr: &CStr) -> &'ll Attribute { pub fn CreateAttrString<'ll>(llcx: &'ll Context, attr: &str) -> &'ll Attribute {
unsafe { LLVMRustCreateAttrStringValue(llcx, attr.as_ptr(), std::ptr::null()) } unsafe {
LLVMCreateStringAttribute(
llcx,
attr.as_ptr().cast(),
attr.len().try_into().unwrap(),
std::ptr::null(),
0,
)
}
} }
pub fn CreateAlignmentAttr(llcx: &Context, bytes: u64) -> &Attribute { pub fn CreateAlignmentAttr(llcx: &Context, bytes: u64) -> &Attribute {

View file

@ -267,12 +267,6 @@ extern "C" LLVMAttributeRef LLVMRustCreateAttrNoValue(LLVMContextRef C,
return wrap(Attribute::get(*unwrap(C), fromRust(RustAttr))); return wrap(Attribute::get(*unwrap(C), fromRust(RustAttr)));
} }
extern "C" LLVMAttributeRef LLVMRustCreateAttrStringValue(LLVMContextRef C,
const char *Name,
const char *Value) {
return wrap(Attribute::get(*unwrap(C), StringRef(Name), StringRef(Value)));
}
extern "C" LLVMAttributeRef LLVMRustCreateAlignmentAttr(LLVMContextRef C, extern "C" LLVMAttributeRef LLVMRustCreateAlignmentAttr(LLVMContextRef C,
uint64_t Bytes) { uint64_t Bytes) {
return wrap(Attribute::getWithAlignment(*unwrap(C), llvm::Align(Bytes))); return wrap(Attribute::getWithAlignment(*unwrap(C), llvm::Align(Bytes)));