diff options
| author | Mark Simulacrum <mark.simulacrum@gmail.com> | 2016-12-18 09:42:50 -0700 |
|---|---|---|
| committer | Mark Simulacrum <mark.simulacrum@gmail.com> | 2016-12-20 20:03:31 -0700 |
| commit | 1173db00628882300c2651e6e5d8eb6ddbcb5057 (patch) | |
| tree | b8bdecf6284737e9c2d062654bc88774fa921c51 | |
| parent | 97a2096e5e779fe2473c77b051725bf9f0f8b01d (diff) | |
| download | rust-1173db00628882300c2651e6e5d8eb6ddbcb5057.tar.gz rust-1173db00628882300c2651e6e5d8eb6ddbcb5057.zip | |
Inline last remaining use of Callee::call and delete unused code
| -rw-r--r-- | src/librustc_trans/basic_block.rs | 49 | ||||
| -rw-r--r-- | src/librustc_trans/callee.rs | 94 | ||||
| -rw-r--r-- | src/librustc_trans/glue.rs | 15 | ||||
| -rw-r--r-- | src/librustc_trans/lib.rs | 1 | ||||
| -rw-r--r-- | src/librustc_trans/mir/mod.rs | 8 | ||||
| -rw-r--r-- | src/librustc_trans/value.rs | 156 |
6 files changed, 19 insertions, 304 deletions
diff --git a/src/librustc_trans/basic_block.rs b/src/librustc_trans/basic_block.rs deleted file mode 100644 index 50246a1c5b3..00000000000 --- a/src/librustc_trans/basic_block.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use llvm; -use llvm::BasicBlockRef; -use value::Value; - -#[derive(Copy, Clone)] -pub struct BasicBlock(pub BasicBlockRef); - -/// Wrapper for LLVM BasicBlockRef -impl BasicBlock { - pub fn get(&self) -> BasicBlockRef { - self.0 - } - - pub fn as_value(self) -> Value { - unsafe { - Value(llvm::LLVMBasicBlockAsValue(self.get())) - } - } - - pub fn pred_iter(self) -> impl Iterator<Item=BasicBlock> { - self.as_value().user_iter() - .filter(|user| user.is_a_terminator_inst()) - .map(|user| user.get_parent().unwrap()) - } - - pub fn get_single_predecessor(self) -> Option<BasicBlock> { - let mut iter = self.pred_iter(); - match (iter.next(), iter.next()) { - (Some(first), None) => Some(first), - _ => None - } - } - - pub fn delete(self) { - unsafe { - llvm::LLVMDeleteBasicBlock(self.0); - } - } -} diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index e0ecd1d8bf5..4dbfdc9d499 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -25,7 +25,7 @@ use attributes; use base; use base::*; use common::{ - self, BlockAndBuilder, CrateContext, FunctionContext, SharedCrateContext + self, CrateContext, FunctionContext, SharedCrateContext }; use consts; use declare; @@ -178,26 +178,6 @@ impl<'tcx> Callee<'tcx> { fn_ty } - /// This behemoth of a function translates function calls. Unfortunately, in - /// order to generate more efficient LLVM output at -O0, it has quite a complex - /// signature (refactoring this into two functions seems like a good idea). - /// - /// In particular, for lang items, it is invoked with a dest of None, and in - /// that case the return value contains the result of the fn. The lang item must - /// not return a structural type or else all heck breaks loose. - /// - /// For non-lang items, `dest` is always Some, and hence the result is written - /// into memory somewhere. Nonetheless we return the actual return value of the - /// function. - pub fn call<'a>(self, - bcx: &BlockAndBuilder<'a, 'tcx>, - args: &[ValueRef], - dest: Option<ValueRef>, - lpad: Option<&'a llvm::OperandBundleDef> - ) { - trans_call_inner(bcx, self, args, dest, lpad) - } - /// Turn the callee into a function pointer. pub fn reify<'a>(self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef { match self.data { @@ -666,75 +646,3 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, (llfn, fn_ty) } - -// ______________________________________________________________________ -// Translating calls - -fn trans_call_inner<'a, 'tcx>( - bcx: &BlockAndBuilder<'a, 'tcx>, - callee: Callee<'tcx>, - args: &[ValueRef], - dest: Option<ValueRef>, - lpad: Option<&'a llvm::OperandBundleDef> -) { - // Introduce a temporary cleanup scope that will contain cleanups - // for the arguments while they are being evaluated. The purpose - // this cleanup is to ensure that, should a panic occur while - // evaluating argument N, the values for arguments 0...N-1 are all - // cleaned up. If no panic occurs, the values are handed off to - // the callee, and hence none of the cleanups in this temporary - // scope will ever execute. - let ccx = bcx.ccx(); - let fn_ret = callee.ty.fn_ret(); - let fn_ty = callee.direct_fn_type(ccx, &[]); - - // If there no destination, return must be direct, with no cast. - if dest.is_none() { - assert!(!fn_ty.ret.is_indirect() && fn_ty.ret.cast.is_none()); - } - - let mut llargs = Vec::new(); - - if fn_ty.ret.is_indirect() { - let dest = dest.unwrap(); - let llretslot = if let Some(ty) = fn_ty.ret.cast { - bcx.pointercast(dest, ty.ptr_to()) - } else { - dest - }; - llargs.push(llretslot); - } - - let llfn = match callee.data { - NamedTupleConstructor(_) | Intrinsic => { - bug!("{:?} calls should not go through Callee::call", callee); - } - Virtual(idx) => { - llargs.push(args[0]); - - let fn_ptr = meth::get_virtual_method(&bcx, args[1], idx); - let llty = fn_ty.llvm_type(&bcx.ccx()).ptr_to(); - llargs.extend_from_slice(&args[2..]); - bcx.pointercast(fn_ptr, llty) - } - Fn(f) => { - llargs.extend_from_slice(args); - f - } - }; - - let llret = bcx.call(llfn, &llargs[..], lpad); - fn_ty.apply_attrs_callsite(llret); - - // If the function we just called does not use an outpointer, - // store the result into the Rust outpointer. - if !fn_ty.ret.is_indirect() { - if let Some(llretslot) = dest { - fn_ty.ret.store(&bcx, llret, llretslot); - } - } - - if fn_ret.0.is_never() { - bcx.unreachable(); - } -} diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index 4778f368554..b1d5955c18d 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -44,7 +44,20 @@ pub fn trans_exchange_free_dyn<'a, 'tcx>( ) { let def_id = langcall(bcx.tcx(), None, "", ExchangeFreeFnLangItem); let args = [bcx.pointercast(v, Type::i8p(bcx.ccx())), size, align]; - Callee::def(bcx.ccx(), def_id, bcx.tcx().intern_substs(&[])).call(&bcx, &args, None, None) + let callee = Callee::def(bcx.ccx(), def_id, bcx.tcx().intern_substs(&[])); + + let ccx = bcx.ccx(); + let fn_ret = callee.ty.fn_ret(); + let fn_ty = callee.direct_fn_type(ccx, &[]); + + assert!(!fn_ty.ret.is_indirect() && fn_ty.ret.cast.is_none()); + + let llret = bcx.call(callee.reify(ccx), &args[..], None); + fn_ty.apply_attrs_callsite(llret); + + if fn_ret.0.is_never() { + bcx.unreachable(); + } } pub fn trans_exchange_free_ty<'a, 'tcx>( diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index bd8121e2b9c..2fb0e8c24c5 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -96,7 +96,6 @@ mod asm; mod assert_module_sources; mod attributes; mod base; -mod basic_block; mod builder; mod cabi_aarch64; mod cabi_arm; diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index 8a0e5e107a8..496e14ff2d9 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -26,8 +26,6 @@ use syntax::symbol::keywords; use std::iter; -use basic_block::BasicBlock; - use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; @@ -296,12 +294,12 @@ pub fn trans_mir<'a, 'tcx: 'a>(fcx: &'a FunctionContext<'a, 'tcx>, mir: &'a Mir< // Remove blocks that haven't been visited, or have no // predecessors. for bb in mir.basic_blocks().indices() { - let block = mircx.blocks[bb]; - let block = BasicBlock(block); // Unreachable block if !visited.contains(bb.index()) { debug!("trans_mir: block {:?} was not visited", bb); - block.delete(); + unsafe { + llvm::LLVMDeleteBasicBlock(mircx.blocks[bb]); + } } } } diff --git a/src/librustc_trans/value.rs b/src/librustc_trans/value.rs index b314f3ea414..287ad87caac 100644 --- a/src/librustc_trans/value.rs +++ b/src/librustc_trans/value.rs @@ -9,16 +9,11 @@ // except according to those terms. use llvm; -use llvm::{UseRef, ValueRef}; -use basic_block::BasicBlock; -use common::BlockAndBuilder; use std::fmt; -use libc::c_uint; - #[derive(Copy, Clone, PartialEq)] -pub struct Value(pub ValueRef); +pub struct Value(pub llvm::ValueRef); impl fmt::Debug for Value { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -27,152 +22,3 @@ impl fmt::Debug for Value { }).expect("nun-UTF8 value description from LLVM")) } } - -macro_rules! opt_val { ($e:expr) => ( - unsafe { - match $e { - p if !p.is_null() => Some(Value(p)), - _ => None - } - } -) } - -/// Wrapper for LLVM ValueRef -impl Value { - /// Returns the native ValueRef - pub fn get(&self) -> ValueRef { - let Value(v) = *self; v - } - - /// Returns the BasicBlock that contains this value - pub fn get_parent(self) -> Option<BasicBlock> { - unsafe { - match llvm::LLVMGetInstructionParent(self.get()) { - p if !p.is_null() => Some(BasicBlock(p)), - _ => None - } - } - } - - /// Removes this value from its containing BasicBlock - pub fn erase_from_parent(self) { - unsafe { - llvm::LLVMInstructionEraseFromParent(self.get()); - } - } - - /// Returns the single dominating store to this value, if any - /// This only performs a search for a trivially dominating store. The store - /// must be the only user of this value, and there must not be any conditional - /// branches between the store and the given block. - pub fn get_dominating_store(self, bcx: &BlockAndBuilder) -> Option<Value> { - match self.get_single_user().and_then(|user| user.as_store_inst()) { - Some(store) => { - store.get_parent().and_then(|store_bb| { - let mut bb = BasicBlock(bcx.llbb()); - let mut ret = Some(store); - while bb.get() != store_bb.get() { - match bb.get_single_predecessor() { - Some(pred) => bb = pred, - None => { ret = None; break } - } - } - ret - }) - } - _ => None - } - } - - /// Returns the first use of this value, if any - pub fn get_first_use(self) -> Option<Use> { - unsafe { - match llvm::LLVMGetFirstUse(self.get()) { - u if !u.is_null() => Some(Use(u)), - _ => None - } - } - } - - /// Tests if there are no uses of this value - pub fn has_no_uses(self) -> bool { - self.get_first_use().is_none() - } - - /// Returns the single user of this value - /// If there are no users or multiple users, this returns None - pub fn get_single_user(self) -> Option<Value> { - let mut iter = self.user_iter(); - match (iter.next(), iter.next()) { - (Some(first), None) => Some(first), - _ => None - } - } - - /// Returns an iterator for the users of this value - pub fn user_iter(self) -> Users { - Users { - next: self.get_first_use() - } - } - - /// Returns the requested operand of this instruction - /// Returns None, if there's no operand at the given index - pub fn get_operand(self, i: usize) -> Option<Value> { - opt_val!(llvm::LLVMGetOperand(self.get(), i as c_uint)) - } - - /// Returns the Store represent by this value, if any - pub fn as_store_inst(self) -> Option<Value> { - opt_val!(llvm::LLVMIsAStoreInst(self.get())) - } - - /// Tests if this value is a terminator instruction - pub fn is_a_terminator_inst(self) -> bool { - unsafe { - !llvm::LLVMIsATerminatorInst(self.get()).is_null() - } - } -} - -/// Wrapper for LLVM UseRef -#[derive(Copy, Clone)] -pub struct Use(UseRef); - -impl Use { - pub fn get(&self) -> UseRef { - let Use(v) = *self; v - } - - pub fn get_user(self) -> Value { - unsafe { - Value(llvm::LLVMGetUser(self.get())) - } - } - - pub fn get_next_use(self) -> Option<Use> { - unsafe { - match llvm::LLVMGetNextUse(self.get()) { - u if !u.is_null() => Some(Use(u)), - _ => None - } - } - } -} - -/// Iterator for the users of a value -pub struct Users { - next: Option<Use> -} - -impl Iterator for Users { - type Item = Value; - - fn next(&mut self) -> Option<Value> { - let current = self.next; - - self.next = current.and_then(|u| u.get_next_use()); - - current.map(|u| u.get_user()) - } -} |
