From e36e97ba51f512de2fd05e3250db4a7b72caae04 Mon Sep 17 00:00:00 2001 From: David Voit Date: Sat, 23 May 2015 23:33:37 +0200 Subject: [PATCH] rustc_trans: 'assume' intrinsic is only available on LLVM >= 3.6 Based on the patch from Luca Bruno. Instead of creating an empty C function in the rt, this version creates an shim noop function using llvm. This function is declared as internal, and the unsupported assume intrinsic and the shim gets completly removed by the optimizer. --- src/librustc_trans/trans/context.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs index f2de949ccd53..42e2efa90625 100644 --- a/src/librustc_trans/trans/context.rs +++ b/src/librustc_trans/trans/context.rs @@ -933,11 +933,33 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option void); ifn!("llvm.expect.i1", fn(i1, i1) -> i1); - ifn!("llvm.assume", fn(i1) -> void); // Some intrinsics were introduced in later versions of LLVM, but they have // fallbacks in libc or libm and such. macro_rules! compatible_ifn { + ($name:expr, noop($cname:ident ($($arg:expr),*) -> void), $llvm_version:expr) => ( + if unsafe { llvm::LLVMVersionMinor() >= $llvm_version } { + // The `if key == $name` is already in ifn! + ifn!($name, fn($($arg),*) -> void); + } else if *key == $name { + let f = declare::declare_cfn(ccx, stringify!($cname), + Type::func(&[$($arg),*], &void), + ty::mk_nil(ccx.tcx())); + llvm::SetLinkage(f, llvm::InternalLinkage); + + let bld = ccx.builder(); + let llbb = unsafe { + llvm::LLVMAppendBasicBlockInContext(ccx.llcx(), f, + "entry-block\0".as_ptr() as *const _) + }; + + bld.position_at_end(llbb); + bld.ret_void(); + + ccx.intrinsics().borrow_mut().insert($name, f.clone()); + return Some(f); + } + ); ($name:expr, $cname:ident ($($arg:expr),*) -> $ret:expr, $llvm_version:expr) => ( if unsafe { llvm::LLVMVersionMinor() >= $llvm_version } { // The `if key == $name` is already in ifn! @@ -952,6 +974,8 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option void), 6); + if ccx.sess().opts.debuginfo != NoDebugInfo { ifn!("llvm.dbg.declare", fn(Type::metadata(ccx), Type::metadata(ccx)) -> void); ifn!("llvm.dbg.value", fn(Type::metadata(ccx), t_i64, Type::metadata(ccx)) -> void);