about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniel Micay <danielmicay@gmail.com>2013-09-13 00:14:17 -0400
committerDaniel Micay <danielmicay@gmail.com>2013-09-15 23:34:11 -0400
commit6d0a847c3a03d7920f64526f1776e572d86b2777 (patch)
treea70432c3030b5036f2664bdb374cb5991c9c8f61
parent137eb346f69501c0f67fe43dfcddb01669ba2734 (diff)
downloadrust-6d0a847c3a03d7920f64526f1776e572d86b2777.tar.gz
rust-6d0a847c3a03d7920f64526f1776e572d86b2777.zip
teach Call/CallWithConv to set attributes
-rw-r--r--src/librustc/middle/trans/base.rs17
-rw-r--r--src/librustc/middle/trans/build.rs11
-rw-r--r--src/librustc/middle/trans/builder.rs32
-rw-r--r--src/librustc/middle/trans/callee.rs2
-rw-r--r--src/librustc/middle/trans/foreign.rs10
-rw-r--r--src/librustc/middle/trans/glue.rs6
-rw-r--r--src/librustc/middle/trans/intrinsic.rs12
7 files changed, 47 insertions, 43 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index a79063c9c9a..4d1ea783c39 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -825,7 +825,8 @@ pub fn trans_external_path(ccx: &mut CrateContext, did: ast::DefId, t: ty::t)
     };
 }
 
-pub fn invoke(bcx: @mut Block, llfn: ValueRef, llargs: ~[ValueRef])
+pub fn invoke(bcx: @mut Block, llfn: ValueRef, llargs: ~[ValueRef],
+              attributes: &[(uint, lib::llvm::Attribute)])
            -> (ValueRef, @mut Block) {
     let _icx = push_ctxt("invoke_");
     if bcx.unreachable {
@@ -865,7 +866,7 @@ pub fn invoke(bcx: @mut Block, llfn: ValueRef, llargs: ~[ValueRef])
                 debug!("arg: %x", ::std::cast::transmute(llarg));
             }
         }
-        let llresult = Call(bcx, llfn, llargs);
+        let llresult = Call(bcx, llfn, llargs, attributes);
         return (llresult, bcx);
     }
 }
@@ -976,7 +977,7 @@ pub fn get_landing_pad(bcx: @mut Block) -> BasicBlockRef {
     // Because we may have unwound across a stack boundary, we must call into
     // the runtime to figure out which stack segment we are on and place the
     // stack limit back into the TLS.
-    Call(pad_bcx, bcx.ccx().upcalls.reset_stack_limit, []);
+    Call(pad_bcx, bcx.ccx().upcalls.reset_stack_limit, [], []);
 
     // We store the retval in a function-central alloca, so that calls to
     // Resume can find it.
@@ -1071,7 +1072,7 @@ pub fn trans_trace(bcx: @mut Block, sp_opt: Option<Span>, trace_str: @str) {
     let V_trace_str = PointerCast(bcx, V_trace_str, Type::i8p());
     let V_filename = PointerCast(bcx, V_filename, Type::i8p());
     let args = ~[V_trace_str, V_filename, C_int(ccx, V_line)];
-    Call(bcx, ccx.upcalls.trace, args);
+    Call(bcx, ccx.upcalls.trace, args, []);
 }
 
 pub fn ignore_lhs(_bcx: @mut Block, local: &ast::Local) -> bool {
@@ -1465,7 +1466,7 @@ pub fn call_memcpy(cx: @mut Block, dst: ValueRef, src: ValueRef, n_bytes: ValueR
     let size = IntCast(cx, n_bytes, ccx.int_type);
     let align = C_i32(align as i32);
     let volatile = C_i1(false);
-    Call(cx, memcpy, [dst_ptr, src_ptr, size, align, volatile]);
+    Call(cx, memcpy, [dst_ptr, src_ptr, size, align, volatile], []);
 }
 
 pub fn memcpy_ty(bcx: @mut Block, dst: ValueRef, src: ValueRef, t: ty::t) {
@@ -1510,7 +1511,7 @@ pub fn memzero(b: &Builder, llptr: ValueRef, ty: Type) {
     let size = machine::llsize_of(ccx, ty);
     let align = C_i32(llalign_of_min(ccx, ty) as i32);
     let volatile = C_i1(false);
-    b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile]);
+    b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile], []);
 }
 
 pub fn alloc_ty(bcx: @mut Block, t: ty::t, name: &str) -> ValueRef {
@@ -2353,7 +2354,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
             llvm::LLVMGetParam(llfdecl, env_arg as c_uint)
         };
         let args = ~[llenvarg];
-        Call(bcx, main_llfn, args);
+        Call(bcx, main_llfn, args, []);
 
         finish_fn(fcx, bcx);
         return llfdecl;
@@ -2808,7 +2809,7 @@ pub fn declare_dbg_intrinsics(llmod: ModuleRef, intrinsics: &mut HashMap<&'stati
 
 pub fn trap(bcx: @mut Block) {
     match bcx.ccx().intrinsics.find_equiv(& &"llvm.trap") {
-      Some(&x) => { Call(bcx, x, []); },
+      Some(&x) => { Call(bcx, x, [], []); },
       _ => bcx.sess().bug("unbound llvm.trap in trap")
     }
 }
diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs
index f31e0f8b602..aabb389dde1 100644
--- a/src/librustc/middle/trans/build.rs
+++ b/src/librustc/middle/trans/build.rs
@@ -644,15 +644,16 @@ pub fn InlineAsmCall(cx: @mut Block, asm: *c_char, cons: *c_char,
     B(cx).inline_asm_call(asm, cons, inputs, output, volatile, alignstack, dia)
 }
 
-pub fn Call(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef {
+pub fn Call(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef],
+            attributes: &[(uint, lib::llvm::Attribute)]) -> ValueRef {
     if cx.unreachable { return _UndefReturn(cx, Fn); }
-    B(cx).call(Fn, Args)
+    B(cx).call(Fn, Args, attributes)
 }
 
-pub fn CallWithConv(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef],
-                    Conv: CallConv, sret: bool) -> ValueRef {
+pub fn CallWithConv(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef], Conv: CallConv,
+                    attributes: &[(uint, lib::llvm::Attribute)]) -> ValueRef {
     if cx.unreachable { return _UndefReturn(cx, Fn); }
-    B(cx).call_with_conv(Fn, Args, Conv, sret)
+    B(cx).call_with_conv(Fn, Args, Conv, attributes)
 }
 
 pub fn AtomicFence(cx: @mut Block, order: AtomicOrdering) {
diff --git a/src/librustc/middle/trans/builder.rs b/src/librustc/middle/trans/builder.rs
index ee2363dbec9..85e45942b79 100644
--- a/src/librustc/middle/trans/builder.rs
+++ b/src/librustc/middle/trans/builder.rs
@@ -13,7 +13,6 @@ use lib::llvm::llvm;
 use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
 use lib::llvm::{Opcode, IntPredicate, RealPredicate, False};
 use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
-use lib::llvm::{StructRetAttribute};
 use middle::trans::base;
 use middle::trans::common::*;
 use middle::trans::machine::llalign_of_min;
@@ -748,7 +747,7 @@ impl Builder {
                                              c, noname(), False, False)
                 }
             };
-            self.call(asm, []);
+            self.call(asm, [], []);
         }
     }
 
@@ -773,34 +772,31 @@ impl Builder {
         unsafe {
             let v = llvm::LLVMInlineAsm(
                 fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint);
-            self.call(v, inputs)
+            self.call(v, inputs, [])
         }
     }
 
-    pub fn call(&self, llfn: ValueRef, args: &[ValueRef]) -> ValueRef {
+    pub fn call(&self, llfn: ValueRef, args: &[ValueRef],
+                attributes: &[(uint, lib::llvm::Attribute)]) -> ValueRef {
         self.count_insn("call");
-        do args.as_imm_buf |ptr, len| {
-            unsafe {
-                llvm::LLVMBuildCall(self.llbuilder, llfn, ptr, len as c_uint, noname())
-            }
-        }
-    }
-
-    pub fn call_with_conv(&self, llfn: ValueRef, args: &[ValueRef],
-                         conv: CallConv, sret: bool) -> ValueRef {
-        self.count_insn("callwithconv");
         unsafe {
             let v = llvm::LLVMBuildCall(self.llbuilder, llfn, vec::raw::to_ptr(args),
                                         args.len() as c_uint, noname());
-            lib::llvm::SetInstructionCallConv(v, conv);
-            if sret {
-                let return_slot = 1;
-                llvm::LLVMAddInstrAttribute(v, return_slot, StructRetAttribute as c_uint);
+            for &(idx, attr) in attributes.iter() {
+                llvm::LLVMAddInstrAttribute(v, idx as c_uint, attr as c_uint);
             }
             v
         }
     }
 
+    pub fn call_with_conv(&self, llfn: ValueRef, args: &[ValueRef],
+                          conv: CallConv, attributes: &[(uint, lib::llvm::Attribute)]) -> ValueRef {
+        self.count_insn("callwithconv");
+        let v = self.call(llfn, args, attributes);
+        lib::llvm::SetInstructionCallConv(v, conv);
+        v
+    }
+
     pub fn select(&self, cond: ValueRef, then_val: ValueRef, else_val: ValueRef) -> ValueRef {
         self.count_insn("select");
         unsafe {
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index aa6e10a4a0d..45da026afd0 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -707,7 +707,7 @@ pub fn trans_call_inner(in_cx: @mut Block,
             }
 
             // Invoke the actual rust fn and update bcx/llresult.
-            let (llret, b) = base::invoke(bcx, llfn, llargs);
+            let (llret, b) = base::invoke(bcx, llfn, llargs, []);
             bcx = b;
             llresult = llret;
 
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index 681852b3bf2..87755b4431c 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -11,7 +11,7 @@
 
 use back::{link};
 use std::libc::c_uint;
-use lib::llvm::{ValueRef, Attribute, CallConv};
+use lib::llvm::{ValueRef, Attribute, CallConv, StructRetAttribute};
 use lib::llvm::llvm;
 use lib;
 use middle::trans::machine;
@@ -266,7 +266,13 @@ pub fn trans_native_call(bcx: @mut Block,
         }
     };
 
-    let llforeign_retval = CallWithConv(bcx, llfn, llargs_foreign, cc, fn_type.sret);
+    let attrs;
+    if fn_type.sret {
+        attrs = &[(1, StructRetAttribute)];
+    } else {
+        attrs = &[];
+    }
+    let llforeign_retval = CallWithConv(bcx, llfn, llargs_foreign, cc, attrs);
 
     // If the function we just called does not use an outpointer,
     // store the result into the rust outpointer. Cast the outpointer
diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs
index 910d743d182..1958d3c9adb 100644
--- a/src/librustc/middle/trans/glue.rs
+++ b/src/librustc/middle/trans/glue.rs
@@ -332,7 +332,7 @@ pub fn call_tydesc_glue_full(bcx: @mut Block,
         }
     };
 
-    Call(bcx, llfn, [C_null(Type::nil().ptr_to()), llrawptr]);
+    Call(bcx, llfn, [C_null(Type::nil().ptr_to()), llrawptr], []);
 }
 
 // See [Note-arg-mode]
@@ -424,7 +424,7 @@ pub fn trans_struct_drop_flag(bcx: @mut Block, t: ty::t, v0: ValueRef, dtor_did:
         let self_arg = PointerCast(bcx, v0, params[0]);
         let args = ~[self_arg];
 
-        Call(bcx, dtor_addr, args);
+        Call(bcx, dtor_addr, args, []);
 
         // Drop the fields
         let field_tys = ty::struct_fields(bcx.tcx(), class_did, substs);
@@ -459,7 +459,7 @@ pub fn trans_struct_drop(mut bcx: @mut Block, t: ty::t, v0: ValueRef, dtor_did:
     let self_arg = PointerCast(bcx, v0, params[0]);
     let args = ~[self_arg];
 
-    Call(bcx, dtor_addr, args);
+    Call(bcx, dtor_addr, args, []);
 
     // Drop the fields
     let field_tys = ty::struct_fields(bcx.tcx(), class_did, substs);
diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs
index e81bc4a9196..d17773d3302 100644
--- a/src/librustc/middle/trans/intrinsic.rs
+++ b/src/librustc/middle/trans/intrinsic.rs
@@ -49,7 +49,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
             args[i] = get_param(bcx.fcx.llfn, first_real_arg + i);
         }
         let llfn = bcx.ccx().intrinsics.get_copy(&name);
-        Ret(bcx, Call(bcx, llfn, args.slice(0, num_args)));
+        Ret(bcx, Call(bcx, llfn, args.slice(0, num_args), []));
     }
 
     fn with_overflow_instrinsic(bcx: @mut Block, name: &'static str) {
@@ -59,7 +59,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
         let llfn = bcx.ccx().intrinsics.get_copy(&name);
 
         // convert `i1` to a `bool`, and write to the out parameter
-        let val = Call(bcx, llfn, [a, b]);
+        let val = Call(bcx, llfn, [a, b], []);
         let result = ExtractValue(bcx, val, 0);
         let overflow = ZExt(bcx, ExtractValue(bcx, val, 1), Type::bool());
         let retptr = get_param(bcx.fcx.llfn, bcx.fcx.out_arg_pos());
@@ -87,7 +87,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
         let count = get_param(decl, first_real_arg + 2);
         let volatile = C_i1(false);
         let llfn = bcx.ccx().intrinsics.get_copy(&name);
-        Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]);
+        Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile], []);
         RetVoid(bcx);
     }
 
@@ -108,7 +108,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
         let count = get_param(decl, first_real_arg + 2);
         let volatile = C_i1(false);
         let llfn = bcx.ccx().intrinsics.get_copy(&name);
-        Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]);
+        Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile], []);
         RetVoid(bcx);
     }
 
@@ -116,7 +116,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
         let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u));
         let y = C_i1(false);
         let llfn = bcx.ccx().intrinsics.get_copy(&name);
-        Ret(bcx, Call(bcx, llfn, [x, y]));
+        Ret(bcx, Call(bcx, llfn, [x, y], []));
     }
 
     let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, item.id));
@@ -366,7 +366,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
         }
         "frame_address" => {
             let frameaddress = ccx.intrinsics.get_copy(& &"llvm.frameaddress");
-            let frameaddress_val = Call(bcx, frameaddress, [C_i32(0i32)]);
+            let frameaddress_val = Call(bcx, frameaddress, [C_i32(0i32)], []);
             let star_u8 = ty::mk_imm_ptr(
                 bcx.tcx(),
                 ty::mk_mach_uint(ast::ty_u8));