Rollup merge of #69893 - tmiasko:cstr, r=petrochenkov

librustc_codegen_llvm: Use slices instead of 0-terminated strings

Changed functions:
* LLVMRustGetOrInsertFunction
* LLVMRustGetNamedValue
* LLVMRustBuildCall (removed unused name argument)
* LLVMRustInlineAsm
* LLVMRustInlineAsmVerify
* LLVMRustAppendModuleInlineAsm
This commit is contained in:
Mazdak Farrokhzad 2020-03-11 14:03:54 +01:00 committed by GitHub
commit a77206fa4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 62 additions and 56 deletions

View File

@ -1,5 +1,3 @@
use std::ffi::CString;
use crate::attributes; use crate::attributes;
use libc::c_uint; use libc::c_uint;
use rustc::bug; use rustc::bug;
@ -50,8 +48,8 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut ModuleLlvm, kind: Alloc
args.len() as c_uint, args.len() as c_uint,
False, False,
); );
let name = CString::new(format!("__rust_{}", method.name)).unwrap(); let name = format!("__rust_{}", method.name);
let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr(), ty); let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
if tcx.sess.target.target.options.default_hidden_visibility { if tcx.sess.target.target.options.default_hidden_visibility {
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
@ -60,8 +58,9 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut ModuleLlvm, kind: Alloc
attributes::emit_uwtable(llfn, true); attributes::emit_uwtable(llfn, true);
} }
let callee = CString::new(kind.fn_name(method.name)).unwrap(); let callee = kind.fn_name(method.name);
let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr(), ty); let callee =
llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden); llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast()); let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
@ -73,14 +72,8 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut ModuleLlvm, kind: Alloc
.enumerate() .enumerate()
.map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint)) .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let ret = llvm::LLVMRustBuildCall( let ret =
llbuilder, llvm::LLVMRustBuildCall(llbuilder, callee, args.as_ptr(), args.len() as c_uint, None);
callee,
args.as_ptr(),
args.len() as c_uint,
None,
"\0".as_ptr().cast(),
);
llvm::LLVMSetTailCall(ret, True); llvm::LLVMSetTailCall(ret, True);
if output.is_some() { if output.is_some() {
llvm::LLVMBuildRet(llbuilder, ret); llvm::LLVMBuildRet(llbuilder, ret);

View File

@ -12,7 +12,6 @@ use rustc_span::Span;
use libc::{c_char, c_uint}; use libc::{c_char, c_uint};
use log::debug; use log::debug;
use std::ffi::{CStr, CString};
impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
fn codegen_inline_asm( fn codegen_inline_asm(
@ -80,12 +79,11 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
_ => self.type_struct(&output_types, false), _ => self.type_struct(&output_types, false),
}; };
let asm = CString::new(ia.asm.as_str().as_bytes()).unwrap(); let asm = ia.asm.as_str();
let constraint_cstr = CString::new(all_constraints).unwrap();
let r = inline_asm_call( let r = inline_asm_call(
self, self,
&asm, &asm,
&constraint_cstr, &all_constraints,
&inputs, &inputs,
output_type, output_type,
ia.volatile, ia.volatile,
@ -125,17 +123,17 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
impl AsmMethods for CodegenCx<'ll, 'tcx> { impl AsmMethods for CodegenCx<'ll, 'tcx> {
fn codegen_global_asm(&self, ga: &hir::GlobalAsm) { fn codegen_global_asm(&self, ga: &hir::GlobalAsm) {
let asm = CString::new(ga.asm.as_str().as_bytes()).unwrap(); let asm = ga.asm.as_str();
unsafe { unsafe {
llvm::LLVMRustAppendModuleInlineAsm(self.llmod, asm.as_ptr()); llvm::LLVMRustAppendModuleInlineAsm(self.llmod, asm.as_ptr().cast(), asm.len());
} }
} }
} }
fn inline_asm_call( fn inline_asm_call(
bx: &mut Builder<'a, 'll, 'tcx>, bx: &mut Builder<'a, 'll, 'tcx>,
asm: &CStr, asm: &str,
cons: &CStr, cons: &str,
inputs: &[&'ll Value], inputs: &[&'ll Value],
output: &'ll llvm::Type, output: &'ll llvm::Type,
volatile: bool, volatile: bool,
@ -157,13 +155,15 @@ fn inline_asm_call(
let fty = bx.cx.type_func(&argtys[..], output); let fty = bx.cx.type_func(&argtys[..], output);
unsafe { unsafe {
// Ask LLVM to verify that the constraints are well-formed. // Ask LLVM to verify that the constraints are well-formed.
let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr()); let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr().cast(), cons.len());
debug!("constraint verification result: {:?}", constraints_ok); debug!("constraint verification result: {:?}", constraints_ok);
if constraints_ok { if constraints_ok {
let v = llvm::LLVMRustInlineAsm( let v = llvm::LLVMRustInlineAsm(
fty, fty,
asm.as_ptr(), asm.as_ptr().cast(),
cons.as_ptr(), asm.len(),
cons.as_ptr().cast(),
cons.len(),
volatile, volatile,
alignstack, alignstack,
llvm::AsmDialect::from_generic(dia), llvm::AsmDialect::from_generic(dia),

View File

@ -1016,7 +1016,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
args.as_ptr() as *const &llvm::Value, args.as_ptr() as *const &llvm::Value,
args.len() as c_uint, args.len() as c_uint,
bundle, bundle,
UNNAMED,
) )
} }
} }

View File

@ -21,7 +21,6 @@ use crate::value::Value;
use log::debug; use log::debug;
use rustc::ty::Ty; use rustc::ty::Ty;
use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::traits::*;
use rustc_data_structures::small_c_str::SmallCStr;
/// Declare a function. /// Declare a function.
/// ///
@ -34,8 +33,9 @@ fn declare_raw_fn(
ty: &'ll Type, ty: &'ll Type,
) -> &'ll Value { ) -> &'ll Value {
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty); debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
let namebuf = SmallCStr::new(name); let llfn = unsafe {
let llfn = unsafe { llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty) }; llvm::LLVMRustGetOrInsertFunction(cx.llmod, name.as_ptr().cast(), name.len(), ty)
};
llvm::SetFunctionCallConv(llfn, callconv); llvm::SetFunctionCallConv(llfn, callconv);
// Function addresses in Rust are never significant, allowing functions to // Function addresses in Rust are never significant, allowing functions to
@ -83,8 +83,7 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn get_declared_value(&self, name: &str) -> Option<&'ll Value> { fn get_declared_value(&self, name: &str) -> Option<&'ll Value> {
debug!("get_declared_value(name={:?})", name); debug!("get_declared_value(name={:?})", name);
let namebuf = SmallCStr::new(name); unsafe { llvm::LLVMRustGetNamedValue(self.llmod, name.as_ptr().cast(), name.len()) }
unsafe { llvm::LLVMRustGetNamedValue(self.llmod, namebuf.as_ptr()) }
} }
fn get_defined_value(&self, name: &str) -> Option<&'ll Value> { fn get_defined_value(&self, name: &str) -> Option<&'ll Value> {

View File

@ -732,7 +732,7 @@ extern "C" {
/// See Module::setModuleInlineAsm. /// See Module::setModuleInlineAsm.
pub fn LLVMSetModuleInlineAsm(M: &Module, Asm: *const c_char); pub fn LLVMSetModuleInlineAsm(M: &Module, Asm: *const c_char);
pub fn LLVMRustAppendModuleInlineAsm(M: &Module, Asm: *const c_char); pub fn LLVMRustAppendModuleInlineAsm(M: &Module, Asm: *const c_char, AsmLen: size_t);
/// See llvm::LLVMTypeKind::getTypeID. /// See llvm::LLVMTypeKind::getTypeID.
pub fn LLVMRustGetTypeKind(Ty: &Type) -> TypeKind; pub fn LLVMRustGetTypeKind(Ty: &Type) -> TypeKind;
@ -879,13 +879,18 @@ extern "C" {
pub fn LLVMSetThreadLocalMode(GlobalVar: &Value, Mode: ThreadLocalMode); pub fn LLVMSetThreadLocalMode(GlobalVar: &Value, Mode: ThreadLocalMode);
pub fn LLVMIsGlobalConstant(GlobalVar: &Value) -> Bool; pub fn LLVMIsGlobalConstant(GlobalVar: &Value) -> Bool;
pub fn LLVMSetGlobalConstant(GlobalVar: &Value, IsConstant: Bool); pub fn LLVMSetGlobalConstant(GlobalVar: &Value, IsConstant: Bool);
pub fn LLVMRustGetNamedValue(M: &Module, Name: *const c_char) -> Option<&Value>; pub fn LLVMRustGetNamedValue(
M: &Module,
Name: *const c_char,
NameLen: size_t,
) -> Option<&Value>;
pub fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool); pub fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool);
// Operations on functions // Operations on functions
pub fn LLVMRustGetOrInsertFunction( pub fn LLVMRustGetOrInsertFunction(
M: &'a Module, M: &'a Module,
Name: *const c_char, Name: *const c_char,
NameLen: size_t,
FunctionTy: &'a Type, FunctionTy: &'a Type,
) -> &'a Value; ) -> &'a Value;
pub fn LLVMSetFunctionCallConv(Fn: &Value, CC: c_uint); pub fn LLVMSetFunctionCallConv(Fn: &Value, CC: c_uint);
@ -1332,7 +1337,6 @@ extern "C" {
Args: *const &'a Value, Args: *const &'a Value,
NumArgs: c_uint, NumArgs: c_uint,
Bundle: Option<&OperandBundleDef<'a>>, Bundle: Option<&OperandBundleDef<'a>>,
Name: *const c_char,
) -> &'a Value; ) -> &'a Value;
pub fn LLVMRustBuildMemCpy( pub fn LLVMRustBuildMemCpy(
B: &Builder<'a>, B: &Builder<'a>,
@ -1581,12 +1585,18 @@ extern "C" {
pub fn LLVMRustInlineAsm( pub fn LLVMRustInlineAsm(
Ty: &Type, Ty: &Type,
AsmString: *const c_char, AsmString: *const c_char,
AsmStringLen: size_t,
Constraints: *const c_char, Constraints: *const c_char,
ConstraintsLen: size_t,
SideEffects: Bool, SideEffects: Bool,
AlignStack: Bool, AlignStack: Bool,
Dialect: AsmDialect, Dialect: AsmDialect,
) -> &Value; ) -> &Value;
pub fn LLVMRustInlineAsmVerify(Ty: &Type, Constraints: *const c_char) -> bool; pub fn LLVMRustInlineAsmVerify(
Ty: &Type,
Constraints: *const c_char,
ConstraintsLen: size_t,
) -> bool;
pub fn LLVMRustDebugMetadataVersion() -> u32; pub fn LLVMRustDebugMetadataVersion() -> u32;
pub fn LLVMRustVersionMajor() -> u32; pub fn LLVMRustVersionMajor() -> u32;

View File

@ -112,20 +112,22 @@ extern "C" void LLVMRustPrintPassTimings() {
TimerGroup::printAll(OS); TimerGroup::printAll(OS);
} }
extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name,
const char *Name) { size_t NameLen) {
return wrap(unwrap(M)->getNamedValue(Name)); return wrap(unwrap(M)->getNamedValue(StringRef(Name, NameLen)));
} }
extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M, extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
const char *Name, const char *Name,
size_t NameLen,
LLVMTypeRef FunctionTy) { LLVMTypeRef FunctionTy) {
return wrap( return wrap(unwrap(M)
unwrap(M)->getOrInsertFunction(Name, unwrap<FunctionType>(FunctionTy)) ->getOrInsertFunction(StringRef(Name, NameLen),
unwrap<FunctionType>(FunctionTy))
#if LLVM_VERSION_GE(9, 0) #if LLVM_VERSION_GE(9, 0)
.getCallee() .getCallee()
#endif #endif
); );
} }
extern "C" LLVMValueRef extern "C" LLVMValueRef
@ -395,22 +397,26 @@ static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
} }
} }
extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, extern "C" LLVMValueRef
char *Constraints, LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
LLVMBool HasSideEffects, char *Constraints, size_t ConstraintsLen,
LLVMBool IsAlignStack, LLVMBool HasSideEffects, LLVMBool IsAlignStack,
LLVMRustAsmDialect Dialect) { LLVMRustAsmDialect Dialect) {
return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString, Constraints, return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
StringRef(AsmString, AsmStringLen),
StringRef(Constraints, ConstraintsLen),
HasSideEffects, IsAlignStack, fromRust(Dialect))); HasSideEffects, IsAlignStack, fromRust(Dialect)));
} }
extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
char *Constraints) { size_t ConstraintsLen) {
return InlineAsm::Verify(unwrap<FunctionType>(Ty), Constraints); return InlineAsm::Verify(unwrap<FunctionType>(Ty),
StringRef(Constraints, ConstraintsLen));
} }
extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm) { extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
unwrap(M)->appendModuleInlineAsm(StringRef(Asm)); size_t AsmLen) {
unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen));
} }
typedef DIBuilder *LLVMRustDIBuilderRef; typedef DIBuilder *LLVMRustDIBuilderRef;
@ -1282,12 +1288,11 @@ extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs, LLVMValueRef *Args, unsigned NumArgs,
OperandBundleDef *Bundle, OperandBundleDef *Bundle) {
const char *Name) {
unsigned Len = Bundle ? 1 : 0; unsigned Len = Bundle ? 1 : 0;
ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len); ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
return wrap(unwrap(B)->CreateCall( return wrap(unwrap(B)->CreateCall(
unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Bundles, Name)); unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Bundles));
} }
extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B, extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,