From 137eb346f69501c0f67fe43dfcddb01669ba2734 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Thu, 12 Sep 2013 23:41:01 -0400 Subject: [PATCH 1/2] remove unused `FastCall` wrapper this can just be done using CallWithConv --- src/librustc/middle/trans/build.rs | 5 ----- src/librustc/middle/trans/builder.rs | 10 ---------- 2 files changed, 15 deletions(-) diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 11458eda585..f31e0f8b602 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -649,11 +649,6 @@ pub fn Call(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef { B(cx).call(Fn, Args) } -pub fn FastCall(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef { - if cx.unreachable { return _UndefReturn(cx, Fn); } - B(cx).call(Fn, Args) -} - pub fn CallWithConv(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef], Conv: CallConv, sret: bool) -> ValueRef { if cx.unreachable { return _UndefReturn(cx, Fn); } diff --git a/src/librustc/middle/trans/builder.rs b/src/librustc/middle/trans/builder.rs index 349f14aefbc..ee2363dbec9 100644 --- a/src/librustc/middle/trans/builder.rs +++ b/src/librustc/middle/trans/builder.rs @@ -786,16 +786,6 @@ impl Builder { } } - pub fn fastcall(&self, llfn: ValueRef, args: &[ValueRef]) -> ValueRef { - self.count_insn("fastcall"); - unsafe { - let v = llvm::LLVMBuildCall(self.llbuilder, llfn, vec::raw::to_ptr(args), - args.len() as c_uint, noname()); - lib::llvm::SetInstructionCallConv(v, lib::llvm::FastCallConv); - v - } - } - pub fn call_with_conv(&self, llfn: ValueRef, args: &[ValueRef], conv: CallConv, sret: bool) -> ValueRef { self.count_insn("callwithconv"); From 6d0a847c3a03d7920f64526f1776e572d86b2777 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 13 Sep 2013 00:14:17 -0400 Subject: [PATCH 2/2] teach Call/CallWithConv to set attributes --- src/librustc/middle/trans/base.rs | 17 +++++++------- src/librustc/middle/trans/build.rs | 11 +++++---- src/librustc/middle/trans/builder.rs | 32 +++++++++++--------------- src/librustc/middle/trans/callee.rs | 2 +- src/librustc/middle/trans/foreign.rs | 10 ++++++-- src/librustc/middle/trans/glue.rs | 6 ++--- src/librustc/middle/trans/intrinsic.rs | 12 +++++----- 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, 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,32 +772,29 @@ 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()) + unsafe { + let v = llvm::LLVMBuildCall(self.llbuilder, llfn, vec::raw::to_ptr(args), + args.len() as c_uint, noname()); + 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, sret: bool) -> ValueRef { + conv: CallConv, attributes: &[(uint, lib::llvm::Attribute)]) -> 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); - } - v - } + 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 { 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));