From 90eeb92e10d3a1ca058aa1fed24721aa3b7553cb Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Tue, 20 May 2014 17:42:20 -0400 Subject: [PATCH] Update to LLVM head and mark various ptrs as nonnull. --- src/librustc/lib/llvm.rs | 3 +++ src/librustc/middle/trans/base.rs | 22 +++++++++++++++++++++- src/llvm | 2 +- src/rustllvm/PassWrapper.cpp | 1 + src/rustllvm/RustWrapper.cpp | 12 ++++++++++++ src/rustllvm/llvm-auto-clean-trigger | 2 +- 6 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 711081f46d6..0e7a904c967 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -716,6 +716,9 @@ pub fn LLVMGetOrInsertFunction(M: ModuleRef, pub fn LLVMAddColdAttribute(Fn: ValueRef); + pub fn LLVMAddNonNullAttribute(Arg: ValueRef); + pub fn LLVMAddNonNullReturnAttribute(Fn: ValueRef); + pub fn LLVMRemoveFunctionAttr(Fn: ValueRef, PA: c_ulonglong, HighPA: c_ulonglong); diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index e208097e99b..6413d798e0e 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -259,12 +259,14 @@ pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool, ty::ty_uniq(..) => { unsafe { llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint); + llvm::LLVMAddNonNullAttribute(llarg); } } // `&mut` pointer parameters never alias other parameters, or mutable global data ty::ty_rptr(_, mt) if mt.mutbl == ast::MutMutable => { unsafe { llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint); + llvm::LLVMAddNonNullAttribute(llarg); } } // When a reference in an argument has no named lifetime, it's impossible for that @@ -273,6 +275,13 @@ pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool, debug!("marking argument of {} as nocapture because of anonymous lifetime", name); unsafe { llvm::LLVMAddAttribute(llarg, lib::llvm::NoCaptureAttribute as c_uint); + llvm::LLVMAddNonNullAttribute(llarg); + } + } + // `&` pointer parameters are never null + ty::ty_rptr(..) => { + unsafe { + llvm::LLVMAddNonNullAttribute(llarg); } } _ => { @@ -290,12 +299,23 @@ pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool, // The out pointer will never alias with any other pointers, as the object only exists at a // language level after the call. It can also be tagged with SRet to indicate that it is - // guaranteed to point to a usable block of memory for the type. + // guaranteed to point to a usable block of memory for the type. We also know that it's + // never null if uses_outptr { unsafe { let outptr = llvm::LLVMGetParam(llfn, 0); llvm::LLVMAddAttribute(outptr, lib::llvm::StructRetAttribute as c_uint); llvm::LLVMAddAttribute(outptr, lib::llvm::NoAliasAttribute as c_uint); + llvm::LLVMAddNonNullAttribute(outptr); + } + } else { + match ty::get(output).sty { + ty::ty_uniq(..) | ty::ty_rptr(..) => { + unsafe { + llvm::LLVMAddNonNullReturnAttribute(llfn); + } + } + _ => {} } } diff --git a/src/llvm b/src/llvm index 4b4d0533b4f..0a894645cf1 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 4b4d0533b4f76cc3fbba31bd9e7ac02e0c738b1d +Subproject commit 0a894645cf120539876e9eb4eb0d7b572dfa9d14 diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 64776421fa1..195b044ccdc 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -13,6 +13,7 @@ #include "rustllvm.h" #include "llvm/Support/CBindingWrapping.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Target/TargetLibraryInfo.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 717cd333a79..3661d152d59 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -119,8 +119,20 @@ extern "C" void LLVMAddColdAttribute(LLVMValueRef Fn) { Function *A = unwrap(Fn); A->addAttribute(AttributeSet::FunctionIndex, Attribute::Cold); } + +extern "C" void LLVMAddNonNullAttribute(LLVMValueRef Arg) { + Argument *A = unwrap(Arg); + A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, Attribute::NonNull)); +} + +extern "C" void LLVMAddNonNullReturnAttribute(LLVMValueRef Fn) { + Function *A = unwrap(Fn); + A->addAttribute(AttributeSet::ReturnIndex, Attribute::NonNull); +} #else extern "C" void LLVMAddColdAttribute(LLVMValueRef Fn) {} +extern "C" void LLVMAddNonNullAttribute(LLVMValueRef Arg) {} +extern "C" void LLVMAddNonNullReturnAttribute(LLVMValueRef Fn) {} #endif extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B, diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index 340a4915277..4e599ad115d 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2014-04-14 +2014-05-20 -- 2.44.0