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 libc::c_uint;
use rustc::bug;
@ -50,8 +48,8 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut ModuleLlvm, kind: Alloc
args.len() as c_uint,
False,
);
let name = CString::new(format!("__rust_{}", method.name)).unwrap();
let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr(), ty);
let name = format!("__rust_{}", method.name);
let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
if tcx.sess.target.target.options.default_hidden_visibility {
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);
}
let callee = CString::new(kind.fn_name(method.name)).unwrap();
let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr(), ty);
let callee = kind.fn_name(method.name);
let callee =
llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
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()
.map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
.collect::<Vec<_>>();
let ret = llvm::LLVMRustBuildCall(
llbuilder,
callee,
args.as_ptr(),
args.len() as c_uint,
None,
"\0".as_ptr().cast(),
);
let ret =
llvm::LLVMRustBuildCall(llbuilder, callee, args.as_ptr(), args.len() as c_uint, None);
llvm::LLVMSetTailCall(ret, True);
if output.is_some() {
llvm::LLVMBuildRet(llbuilder, ret);

View File

@ -12,7 +12,6 @@ use rustc_span::Span;
use libc::{c_char, c_uint};
use log::debug;
use std::ffi::{CStr, CString};
impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
fn codegen_inline_asm(
@ -80,12 +79,11 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
_ => self.type_struct(&output_types, false),
};
let asm = CString::new(ia.asm.as_str().as_bytes()).unwrap();
let constraint_cstr = CString::new(all_constraints).unwrap();
let asm = ia.asm.as_str();
let r = inline_asm_call(
self,
&asm,
&constraint_cstr,
&all_constraints,
&inputs,
output_type,
ia.volatile,
@ -125,17 +123,17 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
impl AsmMethods for CodegenCx<'ll, 'tcx> {
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 {
llvm::LLVMRustAppendModuleInlineAsm(self.llmod, asm.as_ptr());
llvm::LLVMRustAppendModuleInlineAsm(self.llmod, asm.as_ptr().cast(), asm.len());
}
}
}
fn inline_asm_call(
bx: &mut Builder<'a, 'll, 'tcx>,
asm: &CStr,
cons: &CStr,
asm: &str,
cons: &str,
inputs: &[&'ll Value],
output: &'ll llvm::Type,
volatile: bool,
@ -157,13 +155,15 @@ fn inline_asm_call(
let fty = bx.cx.type_func(&argtys[..], output);
unsafe {
// 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);
if constraints_ok {
let v = llvm::LLVMRustInlineAsm(
fty,
asm.as_ptr(),
cons.as_ptr(),
asm.as_ptr().cast(),
asm.len(),
cons.as_ptr().cast(),
cons.len(),
volatile,
alignstack,
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.len() as c_uint,
bundle,
UNNAMED,
)
}
}

View File

@ -21,7 +21,6 @@ use crate::value::Value;
use log::debug;
use rustc::ty::Ty;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::small_c_str::SmallCStr;
/// Declare a function.
///
@ -34,8 +33,9 @@ fn declare_raw_fn(
ty: &'ll Type,
) -> &'ll Value {
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
let namebuf = SmallCStr::new(name);
let llfn = unsafe { llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty) };
let llfn = unsafe {
llvm::LLVMRustGetOrInsertFunction(cx.llmod, name.as_ptr().cast(), name.len(), ty)
};
llvm::SetFunctionCallConv(llfn, callconv);
// 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> {
debug!("get_declared_value(name={:?})", name);
let namebuf = SmallCStr::new(name);
unsafe { llvm::LLVMRustGetNamedValue(self.llmod, namebuf.as_ptr()) }
unsafe { llvm::LLVMRustGetNamedValue(self.llmod, name.as_ptr().cast(), name.len()) }
}
fn get_defined_value(&self, name: &str) -> Option<&'ll Value> {

View File

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

View File

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