diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 10e717e550d1f..9e652536f6d21 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -709,6 +709,7 @@ pub mod llvm { pub fn LLVMSetGC(Fn: ValueRef, Name: *c_char); pub fn LLVMAddFunctionAttr(Fn: ValueRef, PA: c_uint); pub fn LLVMAddFunctionAttrString(Fn: ValueRef, Name: *c_char); + pub fn LLVMRemoveFunctionAttrString(Fn: ValueRef, Name: *c_char); pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong; pub fn LLVMAddReturnAttribute(Fn: ValueRef, PA: c_uint); diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 95ba619e40103..735b60622ed62 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -199,6 +199,7 @@ fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, lib::llvm::SetFunctionCallConv(llfn, cc); // Function addresses in Rust are never significant, allowing functions to be merged. lib::llvm::SetUnnamedAddr(llfn, true); + set_split_stack(llfn); llfn } @@ -445,8 +446,8 @@ pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) { } // Add the no-split-stack attribute if requested - if !contains_name(attrs, "no_split_stack") { - set_split_stack(llfn); + if contains_name(attrs, "no_split_stack") { + unset_split_stack(llfn); } if contains_name(attrs, "cold") { @@ -464,6 +465,12 @@ pub fn set_split_stack(f: ValueRef) { }) } +pub fn unset_split_stack(f: ValueRef) { + "split-stack".with_c_str(|buf| { + unsafe { llvm::LLVMRemoveFunctionAttrString(f, buf); } + }) +} + // Double-check that we never ask LLVM to declare the same symbol twice. It // silently mangles such symbols, breaking our linkage model. pub fn note_unique_llvm_symbol(ccx: &CrateContext, sym: ~str) { diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 035a39669de8d..3fe1b1380da01 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -77,6 +77,18 @@ extern "C" void LLVMAddFunctionAttrString(LLVMValueRef fn, const char *Name) { unwrap(fn)->addFnAttr(Name); } +extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, const char *Name) { + Function *f = unwrap(fn); + LLVMContext &C = f->getContext(); + AttrBuilder B; + B.addAttribute(Name); + AttributeSet to_remove = AttributeSet::get(C, AttributeSet::FunctionIndex, B); + + AttributeSet attrs = f->getAttributes(); + f->setAttributes(attrs.removeAttributes(f->getContext(), + AttributeSet::FunctionIndex, + to_remove)); +} extern "C" void LLVMAddReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) { Function *A = unwrap(Fn);