From 5bce12c95f05cc28b2ab3755432c65db8d7b10f2 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Fri, 18 Nov 2016 11:11:18 -0500 Subject: [LLVM 4.0] Move debuginfo alignment argument Alignment was removed from createBasicType and moved to - createGlobalVariable - createAutoVariable - createStaticMemberType (unused in Rust) - createTempGlobalVariableFwdDecl (unused in Rust) https://github.com/llvm-mirror/llvm/commit/e69c459a6e9756ca1ff3acb1dcfc434843aee80f --- src/rustllvm/RustWrapper.cpp | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index ae2ab932a61..85749d883d2 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -552,8 +552,13 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateBasicType( uint64_t AlignInBits, unsigned Encoding) { return wrap(Builder->createBasicType( - Name, SizeInBits, - AlignInBits, Encoding)); + Name, + SizeInBits, +#if LLVM_VERSION_LE(3, 9) + AlignInBits, +#endif + Encoding + )); } extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreatePointerType( @@ -645,8 +650,11 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable( LLVMRustMetadataRef Ty, bool isLocalToUnit, LLVMValueRef Val, - LLVMRustMetadataRef Decl = NULL) { - return wrap(Builder->createGlobalVariable(unwrapDI(Context), + LLVMRustMetadataRef Decl = NULL, + uint64_t AlignInBits = 0) +{ + return wrap(Builder->createGlobalVariable( + unwrapDI(Context), Name, LinkageName, unwrapDI(File), @@ -654,7 +662,11 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable( unwrapDI(Ty), isLocalToUnit, cast(unwrap(Val)), - unwrapDIptr(Decl))); + unwrapDIptr(Decl) +#if LLVM_VERSION_GE(4, 0) + , AlignInBits +#endif + )); } extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable( @@ -667,14 +679,23 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable( LLVMRustMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags, - unsigned ArgNo) { + unsigned ArgNo, + uint64_t AlignInBits) +{ #if LLVM_VERSION_GE(3, 8) if (Tag == 0x100) { // DW_TAG_auto_variable return wrap(Builder->createAutoVariable( - unwrapDI(Scope), Name, + unwrapDI(Scope), + Name, unwrapDI(File), LineNo, - unwrapDI(Ty), AlwaysPreserve, from_rust(Flags))); + unwrapDI(Ty), + AlwaysPreserve, + from_rust(Flags) +#if LLVM_VERSION_GE(4,0) + , AlignInBits +#endif + )); } else { return wrap(Builder->createParameterVariable( unwrapDI(Scope), Name, ArgNo, -- cgit 1.4.1-3-g733a5 From e080804f72fe937ed36cd6656f5f119959529945 Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Sun, 11 Dec 2016 22:08:20 +1300 Subject: Update LLVM global variable debug info API for 4.0 This teaches Rust about an LLVM 4.0 API change for creating debug info for global variables. This change was made in upstream LLVM patch https://reviews.llvm.org/D20147 This is almost 1:1 copy of how clang did it in http://reviews.llvm.org/D20415 --- src/rustllvm/RustWrapper.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 85749d883d2..f5fa66f1b0e 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -651,17 +651,32 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable( bool isLocalToUnit, LLVMValueRef Val, LLVMRustMetadataRef Decl = NULL, - uint64_t AlignInBits = 0) -{ - return wrap(Builder->createGlobalVariable( - unwrapDI(Context), + uint64_t AlignInBits = 0) { + Constant *InitVal = cast(unwrap(Val)); + +#if LLVM_VERSION_GE(4, 0) + llvm::DIExpression *InitExpr = nullptr; + if (llvm::ConstantInt *IntVal = llvm::dyn_cast(InitVal)) { + InitExpr = Builder->createConstantValueExpression( + IntVal->getValue().getSExtValue()); + } else if (llvm::ConstantFP *FPVal = llvm::dyn_cast(InitVal)) { + InitExpr = Builder->createConstantValueExpression( + FPVal->getValueAPF().bitcastToAPInt().getZExtValue()); + } +#endif + + return wrap(Builder->createGlobalVariable(unwrapDI(Context), Name, LinkageName, unwrapDI(File), LineNo, unwrapDI(Ty), isLocalToUnit, - cast(unwrap(Val)), +#if LLVM_VERSION_GE(4, 0) + InitExpr, +#else + InitVal, +#endif unwrapDIptr(Decl) #if LLVM_VERSION_GE(4, 0) , AlignInBits -- cgit 1.4.1-3-g733a5 From c461cdfdf686caec2b93fe9e41efaa79b7a5c292 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Wed, 21 Dec 2016 21:42:10 +0300 Subject: Fixed fastcall not applying inreg attributes to arguments like the C/C++ fastcall. --- src/librustc_llvm/ffi.rs | 1 + src/librustc_trans/abi.rs | 14 ++++++++--- src/librustc_trans/cabi_x86.rs | 55 +++++++++++++++++++++++++++++++++++++++++- src/rustllvm/RustWrapper.cpp | 2 ++ src/rustllvm/rustllvm.h | 1 + 5 files changed, 69 insertions(+), 4 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index d2b86ade7a2..f3dbac7ce68 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -117,6 +117,7 @@ pub enum Attribute { StructRet = 16, UWTable = 17, ZExt = 18, + InReg = 19, } /// LLVMIntPredicate diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 8b4343af199..f0f25118990 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -58,7 +58,7 @@ mod attr_impl { // The subset of llvm::Attribute needed for arguments, packed into a bitfield. bitflags! { #[derive(Default, Debug)] - flags ArgAttribute : u8 { + flags ArgAttribute : u16 { const ByVal = 1 << 0, const NoAlias = 1 << 1, const NoCapture = 1 << 2, @@ -67,6 +67,7 @@ mod attr_impl { const SExt = 1 << 5, const StructRet = 1 << 6, const ZExt = 1 << 7, + const InReg = 1 << 8, } } } @@ -80,7 +81,7 @@ macro_rules! for_each_kind { impl ArgAttribute { fn for_each_kind(&self, mut f: F) where F: FnMut(llvm::Attribute) { for_each_kind!(self, f, - ByVal, NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt) + ByVal, NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg) } } @@ -573,7 +574,14 @@ impl FnType { } match &ccx.sess().target.target.arch[..] { - "x86" => cabi_x86::compute_abi_info(ccx, self), + "x86" => { + let flavor = if abi == Abi::Fastcall { + cabi_x86::Flavor::Fastcall + } else { + cabi_x86::Flavor::General + }; + cabi_x86::compute_abi_info(ccx, self, flavor); + }, "x86_64" => if abi == Abi::SysV64 { cabi_x86_64::compute_abi_info(ccx, self); } else if abi == Abi::Win64 || ccx.sess().target.target.options.is_like_windows { diff --git a/src/librustc_trans/cabi_x86.rs b/src/librustc_trans/cabi_x86.rs index ce85234f203..ae8b610882b 100644 --- a/src/librustc_trans/cabi_x86.rs +++ b/src/librustc_trans/cabi_x86.rs @@ -14,7 +14,13 @@ use type_::Type; use super::common::*; use super::machine::*; -pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { +#[derive(PartialEq)] +pub enum Flavor { + General, + Fastcall +} + +pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType, flavor: Flavor) { if !fty.ret.is_ignore() { if fty.ret.ty.kind() == Struct { // Returning a structure. Most often, this will use @@ -51,4 +57,51 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { arg.extend_integer_width_to(32); } } + + if flavor == Flavor::Fastcall { + // Mark arguments as InReg like clang does it, + // so our fastcall is compatible with C/C++ fastcall. + // Clang reference: ib/CodeGen/TargetInfo.cpp + let is_mcu_abi = ccx.sess().target.target.target_os.eq("elfiamcu"); + let is_soft_float_abi = ccx.sess().target.target.options.features.contains("+soft-float"); + + let mut free_regs = 2; + + for arg in &mut fty.args { + if !arg.is_ignore() && !arg.is_indirect() { + if !is_soft_float_abi { + if arg.ty.kind() == Float { + continue; + } + } + + let size = llbitsize_of_real(ccx, arg.ty); + let size_in_regs = (size + 31) / 32; + + if size_in_regs == 0 { + continue; + } + + if !is_mcu_abi { + if size_in_regs > free_regs { + break; + } + } else { + if size_in_regs > free_regs || size_in_regs > 2 { + continue; + } + } + + free_regs -= size_in_regs; + + if !is_mcu_abi && size <= 32 && (arg.ty.kind() == Pointer || arg.ty.kind() == Integer) { + arg.attrs.set(ArgAttribute::InReg); + } + + if free_regs == 0 { + break; + } + } + } + } } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index f5fa66f1b0e..5d5845213e2 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -150,6 +150,8 @@ from_rust(LLVMRustAttribute kind) { return Attribute::UWTable; case ZExt: return Attribute::ZExt; + case InReg: + return Attribute::InReg; default: llvm_unreachable("bad AttributeKind"); } diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index b8c4076f4ce..8f7e0e3d918 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -98,6 +98,7 @@ enum LLVMRustAttribute { StructRet = 16, UWTable = 17, ZExt = 18, + InReg = 19, }; typedef struct OpaqueRustString *RustStringRef; -- cgit 1.4.1-3-g733a5