mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
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:
commit
a77206fa4a
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user