Skip to content

Pass LLVM string attributes as string slices #94539

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,8 +561,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
if self.conv == Conv::CCmseNonSecureCall {
// This will probably get ignored on all targets but those supporting the TrustZone-M
// extension (thumbv8m targets).
let cmse_nonsecure_call =
llvm::CreateAttrString(bx.cx.llcx, cstr::cstr!("cmse_nonsecure_call"));
let cmse_nonsecure_call = llvm::CreateAttrString(bx.cx.llcx, "cmse_nonsecure_call");
attributes::apply_to_callsite(
callsite,
llvm::AttributePlace::Function,
Expand Down
52 changes: 23 additions & 29 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
//! Set and unset common attributes on LLVM values.

use std::ffi::CString;

use cstr::cstr;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty::{self, TyCtxt};
Expand Down Expand Up @@ -103,11 +99,11 @@ pub fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attr
fp = FramePointer::Always;
}
let attr_value = match fp {
FramePointer::Always => cstr!("all"),
FramePointer::NonLeaf => cstr!("non-leaf"),
FramePointer::Always => "all",
FramePointer::NonLeaf => "non-leaf",
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.
Expand All @@ -119,11 +115,11 @@ fn instrument_function_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribu

// The function name varies on platforms.
// 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(
cx.llcx,
cstr!("instrument-function-entry-inlined"),
"instrument-function-entry-inlined",
&mcount_name,
))
} else {
Expand Down Expand Up @@ -159,20 +155,20 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
StackProbeType::None => return None,
// 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).
StackProbeType::Inline => cstr!("inline-asm"),
StackProbeType::Inline => "inline-asm",
// Flag our internal `__rust_probestack` function as the stack probe symbol.
// 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.
StackProbeType::InlineOrCall { min_llvm_version_for_inline } => {
if llvm_util::get_version() < min_llvm_version_for_inline {
cstr!("__rust_probestack")
"__rust_probestack"
} 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> {
Expand All @@ -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 {
let target_cpu = SmallCStr::new(llvm_util::target_cpu(cx.tcx.sess));
llvm::CreateAttrStringValue(cx.llcx, cstr!("target-cpu"), target_cpu.as_c_str())
let target_cpu = llvm_util::target_cpu(cx.tcx.sess);
llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu)
}

pub fn tune_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
llvm_util::tune_cpu(cx.tcx.sess).map(|tune| {
let tune_cpu = SmallCStr::new(tune);
llvm::CreateAttrStringValue(cx.llcx, cstr!("tune-cpu"), tune_cpu.as_c_str())
})
llvm_util::tune_cpu(cx.tcx.sess)
.map(|tune_cpu| llvm::CreateAttrStringValue(cx.llcx, "tune-cpu", tune_cpu))
}

/// Get the `NonLazyBind` LLVM attribute,
Expand Down Expand Up @@ -280,7 +274,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
}

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.
Expand Down Expand Up @@ -310,7 +304,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]);
}
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 {
llvm::set_alignment(llfn, align as usize);
Expand Down Expand Up @@ -363,12 +357,12 @@ pub fn from_fn_attrs<'ll, 'tcx>(
// If this function is an import from the environment but the wasm
// import has a specific module/name, apply them here.
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 =
codegen_fn_attrs.link_name.unwrap_or_else(|| cx.tcx.item_name(instance.def_id()));
let name = CString::new(name.as_str()).unwrap();
to_add.push(llvm::CreateAttrStringValue(cx.llcx, cstr!("wasm-import-name"), &name));
let name = name.as_str();
to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-name", name));
}

// The `"wasm"` abi on wasm targets automatically enables the
Expand All @@ -388,13 +382,13 @@ pub fn from_fn_attrs<'ll, 'tcx>(
let val = global_features
.chain(function_features.iter().map(|s| &s[..]))
.intersperse(",")
.collect::<SmallCStr>();
to_add.push(llvm::CreateAttrStringValue(cx.llcx, cstr!("target-features"), &val));
.collect::<String>();
to_add.push(llvm::CreateAttrStringValue(cx.llcx, "target-features", &val));
}

attributes::apply_to_llfn(llfn, Function, &to_add);
}

fn wasm_import_module(tcx: TyCtxt<'_>, id: DefId) -> Option<CString> {
tcx.wasm_import_module_map(id.krate).get(&id).map(|s| CString::new(&s[..]).unwrap())
fn wasm_import_module(tcx: TyCtxt<'_>, id: DefId) -> Option<&String> {
tcx.wasm_import_module_map(id.krate).get(&id)
}
5 changes: 3 additions & 2 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1175,11 +1175,12 @@ extern "C" {

// Operations on attributes
pub fn LLVMRustCreateAttrNoValue(C: &Context, attr: AttributeKind) -> &Attribute;
pub fn LLVMRustCreateAttrString(C: &Context, Name: *const c_char) -> &Attribute;
pub fn LLVMRustCreateAttrStringValue(
pub fn LLVMCreateStringAttribute(
C: &Context,
Name: *const c_char,
NameLen: c_uint,
Value: *const c_char,
ValueLen: c_uint,
) -> &Attribute;
pub fn LLVMRustCreateAlignmentAttr(C: &Context, bytes: u64) -> &Attribute;
pub fn LLVMRustCreateDereferenceableAttr(C: &Context, bytes: u64) -> &Attribute;
Expand Down
24 changes: 20 additions & 4 deletions compiler/rustc_codegen_llvm/src/llvm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,28 @@ pub fn AddCallSiteAttributes<'ll>(
}
}

pub fn CreateAttrStringValue<'ll>(llcx: &'ll Context, attr: &CStr, value: &CStr) -> &'ll Attribute {
unsafe { LLVMRustCreateAttrStringValue(llcx, attr.as_ptr(), value.as_ptr()) }
pub fn CreateAttrStringValue<'ll>(llcx: &'ll Context, attr: &str, value: &str) -> &'ll Attribute {
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 {
unsafe { LLVMRustCreateAttrStringValue(llcx, attr.as_ptr(), std::ptr::null()) }
pub fn CreateAttrString<'ll>(llcx: &'ll Context, attr: &str) -> &'ll Attribute {
unsafe {
LLVMCreateStringAttribute(
llcx,
attr.as_ptr().cast(),
attr.len().try_into().unwrap(),
std::ptr::null(),
0,
)
}
}

pub fn CreateAlignmentAttr(llcx: &Context, bytes: u64) -> &Attribute {
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,12 +267,6 @@ extern "C" LLVMAttributeRef LLVMRustCreateAttrNoValue(LLVMContextRef C,
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,
uint64_t Bytes) {
return wrap(Attribute::getWithAlignment(*unwrap(C), llvm::Align(Bytes)));
Expand Down