X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=src%2Flibrustc_trans%2Ftrans%2Fbuilder.rs;h=434fca4168858421bb2b5e220e6a303294886614;hb=7453a54e5240c53c1674e3dda6cc681179b9c8f2;hp=be4028e37d7182a52e85f47abba5bb443741302f;hpb=9cc50fc6f5a9de25b3f33673e9f1b960df866413;p=rustc.git diff --git a/src/librustc_trans/trans/builder.rs b/src/librustc_trans/trans/builder.rs index be4028e37d..434fca4168 100644 --- a/src/librustc_trans/trans/builder.rs +++ b/src/librustc_trans/trans/builder.rs @@ -12,7 +12,7 @@ use llvm; use llvm::{CallConv, AtomicBinOp, AtomicOrdering, SynchronizationScope, AsmDialect, AttrBuilder}; -use llvm::{Opcode, IntPredicate, RealPredicate, False}; +use llvm::{Opcode, IntPredicate, RealPredicate, False, OperandBundleDef}; use llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef}; use trans::base; use trans::common::*; @@ -158,6 +158,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { args: &[ValueRef], then: BasicBlockRef, catch: BasicBlockRef, + bundle: Option<&OperandBundleDef>, attributes: Option) -> ValueRef { self.count_insn("invoke"); @@ -169,17 +170,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .collect::>() .join(", ")); + let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(0 as *mut _); + unsafe { - let v = llvm::LLVMBuildInvoke(self.llbuilder, - llfn, - args.as_ptr(), - args.len() as c_uint, - then, - catch, - noname()); - match attributes { - Some(a) => a.apply_callsite(v), - None => {} + let v = llvm::LLVMRustBuildInvoke(self.llbuilder, + llfn, + args.as_ptr(), + args.len() as c_uint, + then, + catch, + bundle, + noname()); + if let Some(a) = attributes { + a.apply_callsite(v); } v } @@ -771,7 +774,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { comment_text.as_ptr(), noname(), False, False) }; - self.call(asm, &[], None); + self.call(asm, &[], None, None); } } @@ -796,11 +799,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { unsafe { let v = llvm::LLVMInlineAsm( fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint); - self.call(v, inputs, None) + self.call(v, inputs, None, None) } } pub fn call(&self, llfn: ValueRef, args: &[ValueRef], + bundle: Option<&OperandBundleDef>, attributes: Option) -> ValueRef { self.count_insn("call"); @@ -837,21 +841,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } + let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(0 as *mut _); + unsafe { - let v = llvm::LLVMBuildCall(self.llbuilder, llfn, args.as_ptr(), - args.len() as c_uint, noname()); - match attributes { - Some(a) => a.apply_callsite(v), - None => {} + let v = llvm::LLVMRustBuildCall(self.llbuilder, llfn, args.as_ptr(), + args.len() as c_uint, bundle, + noname()); + if let Some(a) = attributes { + a.apply_callsite(v); } v } } pub fn call_with_conv(&self, llfn: ValueRef, args: &[ValueRef], - conv: CallConv, attributes: Option) -> ValueRef { + conv: CallConv, + bundle: Option<&OperandBundleDef>, + attributes: Option) -> ValueRef { self.count_insn("callwithconv"); - let v = self.call(llfn, args, attributes); + let v = self.call(llfn, args, bundle, attributes); llvm::SetInstructionCallConv(v, conv); v } @@ -948,8 +956,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { assert!((t as isize != 0)); let args: &[ValueRef] = &[]; self.count_insn("trap"); - llvm::LLVMBuildCall( - self.llbuilder, t, args.as_ptr(), args.len() as c_uint, noname()); + llvm::LLVMRustBuildCall(self.llbuilder, t, + args.as_ptr(), args.len() as c_uint, + 0 as *mut _, + noname()); } } @@ -983,14 +993,95 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } + pub fn cleanup_pad(&self, + parent: Option, + args: &[ValueRef]) -> ValueRef { + self.count_insn("cleanuppad"); + let parent = parent.unwrap_or(0 as *mut _); + let name = CString::new("cleanuppad").unwrap(); + let ret = unsafe { + llvm::LLVMRustBuildCleanupPad(self.llbuilder, + parent, + args.len() as c_uint, + args.as_ptr(), + name.as_ptr()) + }; + assert!(!ret.is_null(), "LLVM does not have support for cleanuppad"); + return ret + } + + pub fn cleanup_ret(&self, cleanup: ValueRef, + unwind: Option) -> ValueRef { + self.count_insn("cleanupret"); + let unwind = unwind.unwrap_or(0 as *mut _); + let ret = unsafe { + llvm::LLVMRustBuildCleanupRet(self.llbuilder, cleanup, unwind) + }; + assert!(!ret.is_null(), "LLVM does not have support for cleanupret"); + return ret + } + + pub fn catch_pad(&self, + parent: ValueRef, + args: &[ValueRef]) -> ValueRef { + self.count_insn("catchpad"); + let name = CString::new("catchpad").unwrap(); + let ret = unsafe { + llvm::LLVMRustBuildCatchPad(self.llbuilder, parent, + args.len() as c_uint, args.as_ptr(), + name.as_ptr()) + }; + assert!(!ret.is_null(), "LLVM does not have support for catchpad"); + return ret + } + + pub fn catch_ret(&self, pad: ValueRef, unwind: BasicBlockRef) -> ValueRef { + self.count_insn("catchret"); + let ret = unsafe { + llvm::LLVMRustBuildCatchRet(self.llbuilder, pad, unwind) + }; + assert!(!ret.is_null(), "LLVM does not have support for catchret"); + return ret + } + + pub fn catch_switch(&self, + parent: Option, + unwind: Option, + num_handlers: usize) -> ValueRef { + self.count_insn("catchswitch"); + let parent = parent.unwrap_or(0 as *mut _); + let unwind = unwind.unwrap_or(0 as *mut _); + let name = CString::new("catchswitch").unwrap(); + let ret = unsafe { + llvm::LLVMRustBuildCatchSwitch(self.llbuilder, parent, unwind, + num_handlers as c_uint, + name.as_ptr()) + }; + assert!(!ret.is_null(), "LLVM does not have support for catchswitch"); + return ret + } + + pub fn add_handler(&self, catch_switch: ValueRef, handler: BasicBlockRef) { + unsafe { + llvm::LLVMRustAddHandler(catch_switch, handler); + } + } + + pub fn set_personality_fn(&self, personality: ValueRef) { + unsafe { + llvm::LLVMRustSetPersonalityFn(self.llbuilder, personality); + } + } + // Atomic Operations pub fn atomic_cmpxchg(&self, dst: ValueRef, cmp: ValueRef, src: ValueRef, order: AtomicOrdering, - failure_order: AtomicOrdering) -> ValueRef { + failure_order: AtomicOrdering, + weak: llvm::Bool) -> ValueRef { unsafe { llvm::LLVMBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src, - order, failure_order) + order, failure_order, weak) } } pub fn atomic_rmw(&self, op: AtomicBinOp,